gosu 0.11.3.1 → 0.11.4.pre1
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/Version.hpp +1 -1
- data/Gosu/Window.hpp +8 -2
- data/rdoc/gosu.rb +25 -19
- data/src/Audio.cpp +46 -21
- data/src/AudioToolboxFile.hpp +5 -5
- data/src/Color.cpp +11 -4
- data/src/Input.cpp +110 -148
- data/src/MPEGFile.hpp +90 -0
- data/src/Macro.hpp +1 -1
- data/src/OggFile.hpp +16 -30
- data/src/RubyGosu.cxx +67 -1
- data/src/RubyGosu.h +1 -0
- data/src/SndFile.hpp +5 -5
- data/src/Window.cpp +18 -6
- metadata +5 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 71567bcb35b320a552723bfa654ee71669158f00
|
|
4
|
+
data.tar.gz: ad465f70e02208f4077acd1487121b65190430bc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3e5b404362d89c536ec9df111bbb0cd705813f9b4bfd8b1940bb1fa39cea94656b9dfba02c2be3f9682f5eff8e718183ec7a9063d8705fbfe45f863ae9d5c987
|
|
7
|
+
data.tar.gz: 8782527c80c0cb9b300587ec8aaa69bc4c08fa3aabf337ed706f37867590c7e564dd1033c308b017565de0ced432f38096843285672b7c300eef48d6960b05bc
|
data/Gosu/Version.hpp
CHANGED
data/Gosu/Window.hpp
CHANGED
|
@@ -67,6 +67,7 @@ namespace Gosu
|
|
|
67
67
|
//! receives calls to draw, update etc.
|
|
68
68
|
virtual void show();
|
|
69
69
|
|
|
70
|
+
//! EXPERIMENTAL - MAY DISAPPEAR WITHOUT WARNING.
|
|
70
71
|
//! Performs a single mainloop step.
|
|
71
72
|
//! This method is only useful if you want to integrate Gosu with another library that has
|
|
72
73
|
//! its own main loop.
|
|
@@ -107,14 +108,19 @@ namespace Gosu
|
|
|
107
108
|
virtual void release_memory() {}
|
|
108
109
|
|
|
109
110
|
//! Called before update when the user presses a button while the window has the focus.
|
|
110
|
-
//! By default, this will toggle fullscreen mode if the user presses
|
|
111
|
+
//! By default, this will toggle fullscreen mode if the user presses Alt+Enter (Windows,
|
|
111
112
|
//! Linux) or cmd+F (macOS).
|
|
112
113
|
//! To support these shortcuts in your application, make sure to call Window::button_down
|
|
113
114
|
//! in your implementation.
|
|
114
115
|
virtual void button_down(Gosu::Button);
|
|
115
116
|
|
|
116
|
-
//! Same as button_down. Called
|
|
117
|
+
//! Same as button_down. Called when the user releases a button.
|
|
117
118
|
virtual void button_up(Gosu::Button) {}
|
|
119
|
+
|
|
120
|
+
//! Called when a file is dropped onto the window.
|
|
121
|
+
//! \param path The filename of the dropped file. When multiple files are dropped, this
|
|
122
|
+
//! method will be called several times.
|
|
123
|
+
virtual void drop(const std::string& filename) {}
|
|
118
124
|
|
|
119
125
|
// Ignore when SWIG is wrapping this class for Ruby/Gosu.
|
|
120
126
|
#ifndef SWIG
|
data/rdoc/gosu.rb
CHANGED
|
@@ -113,15 +113,15 @@ module Gosu
|
|
|
113
113
|
attr_accessor :blue
|
|
114
114
|
|
|
115
115
|
##
|
|
116
|
-
# @return [
|
|
116
|
+
# @return [Float] the color's hue in the range [0.0; 360.0).
|
|
117
117
|
attr_accessor :hue
|
|
118
118
|
|
|
119
119
|
##
|
|
120
|
-
# @return [Float] the color's saturation in the range
|
|
120
|
+
# @return [Float] the color's saturation in the range [0.0; 1.0].
|
|
121
121
|
attr_accessor :saturation
|
|
122
122
|
|
|
123
123
|
##
|
|
124
|
-
# @return [Float] the color's value in the range
|
|
124
|
+
# @return [Float] the color's value in the range [0.0; 1.0].
|
|
125
125
|
attr_accessor :value
|
|
126
126
|
|
|
127
127
|
# @!group Creating colors.
|
|
@@ -131,10 +131,10 @@ module Gosu
|
|
|
131
131
|
# @param argb [Integer] an integer of the form 0xAARRGGBB.
|
|
132
132
|
#
|
|
133
133
|
# @overload initialize(a, r, g, b)
|
|
134
|
-
# @param a [Integer] the color's alpha channel in the range
|
|
135
|
-
# @param r [Integer] the color's red channel in the range
|
|
136
|
-
# @param g [Integer] the color's green channel in the range
|
|
137
|
-
# @param b [Integer] the color's blue channel in the range
|
|
134
|
+
# @param a [Integer] the color's alpha channel in the range [0; 255].
|
|
135
|
+
# @param r [Integer] the color's red channel in the range [0; 255].
|
|
136
|
+
# @param g [Integer] the color's green channel in the range [0; 255].
|
|
137
|
+
# @param b [Integer] the color's blue channel in the range [0; 255].
|
|
138
138
|
#
|
|
139
139
|
# @see from_hsv
|
|
140
140
|
# @see from_ahsv
|
|
@@ -149,10 +149,10 @@ module Gosu
|
|
|
149
149
|
# @param argb [Integer] an integer of the form 0xRRGGBBAA.
|
|
150
150
|
#
|
|
151
151
|
# @overload rgba(r, g, b, a)
|
|
152
|
-
# @param
|
|
153
|
-
# @param
|
|
154
|
-
# @param
|
|
155
|
-
# @param
|
|
152
|
+
# @param a [Integer] the color's alpha channel in the range [0; 255].
|
|
153
|
+
# @param r [Integer] the color's red channel in the range [0; 255].
|
|
154
|
+
# @param g [Integer] the color's green channel in the range [0; 255].
|
|
155
|
+
# @param b [Integer] the color's blue channel in the range [0; 255].
|
|
156
156
|
#
|
|
157
157
|
# @see #initialize
|
|
158
158
|
# @see argb
|
|
@@ -171,9 +171,9 @@ module Gosu
|
|
|
171
171
|
# Converts an HSV triplet to an opaque color.
|
|
172
172
|
#
|
|
173
173
|
# @return [Color] a color corresponding to the HSV triplet.
|
|
174
|
-
# @param h [
|
|
175
|
-
# @param s [Float] the color's saturation in the range
|
|
176
|
-
# @param v [Float] the color's value in the range
|
|
174
|
+
# @param h [Float] the color's hue in the range [0.0; 360.0).
|
|
175
|
+
# @param s [Float] the color's saturation in the range [0.0; 1.0].
|
|
176
|
+
# @param v [Float] the color's value in the range [0.0; 1.0].
|
|
177
177
|
#
|
|
178
178
|
# @see from_ahsv
|
|
179
179
|
def self.from_hsv(h, s, v); end
|
|
@@ -181,7 +181,7 @@ module Gosu
|
|
|
181
181
|
# Converts an HSV triplet to a color with the alpha channel set to a given value.
|
|
182
182
|
#
|
|
183
183
|
# @return (see from_hsv)
|
|
184
|
-
# @param a [Integer] the color's opacity in the range
|
|
184
|
+
# @param a [Integer] the color's opacity in the range [0; 255].
|
|
185
185
|
# @param (see from_hsv)
|
|
186
186
|
#
|
|
187
187
|
# @see from_hsv
|
|
@@ -516,7 +516,7 @@ module Gosu
|
|
|
516
516
|
# Playback speed is limited only by the underlying audio library, and both very large and very small values should work just fine.
|
|
517
517
|
#
|
|
518
518
|
# @return [SampleInstance]
|
|
519
|
-
# @param volume [Float] the playback volume, in the range
|
|
519
|
+
# @param volume [Float] the playback volume, in the range [0.0; 1.0], where 0 is completely silent and 1 is full volume.
|
|
520
520
|
# @param speed [Float] the playback speed.
|
|
521
521
|
# @param looping [true, false] whether the sample should play in a loop.
|
|
522
522
|
#
|
|
@@ -529,7 +529,7 @@ module Gosu
|
|
|
529
529
|
# @note Samples played with this method will not be as loud as those played with {#play}, even if `pan` is 0. This is due to a limitation in the way panning works.
|
|
530
530
|
#
|
|
531
531
|
# @return [SampleInstance]
|
|
532
|
-
# @param pan [Float] the amount of panning. 0 is centered.
|
|
532
|
+
# @param pan [Float] the amount of panning. 0.0 is centered.
|
|
533
533
|
# @param (see #play)
|
|
534
534
|
#
|
|
535
535
|
# @see #play
|
|
@@ -814,7 +814,7 @@ module Gosu
|
|
|
814
814
|
##
|
|
815
815
|
# This method is called before {#update} if a button is pressed while the window has focus.
|
|
816
816
|
#
|
|
817
|
-
# By default, this method will toggle fullscreen mode if the user presses
|
|
817
|
+
# By default, this method will toggle fullscreen mode if the user presses Alt+Enter (Windows,
|
|
818
818
|
# Linux) or cmd+F (macOS).
|
|
819
819
|
# To support these shortcuts in your application, make sure to call super in your
|
|
820
820
|
# implementation.
|
|
@@ -836,6 +836,12 @@ module Gosu
|
|
|
836
836
|
# @see Gosu.button_down?
|
|
837
837
|
def button_up(id); end
|
|
838
838
|
|
|
839
|
+
##
|
|
840
|
+
# Called when a file is dropped onto the window.
|
|
841
|
+
#
|
|
842
|
+
# @param filename [String] the filename of the dropped file. When multiple files are dropped, this method will be called several times.
|
|
843
|
+
def drop(filename); end
|
|
844
|
+
|
|
839
845
|
# @!endgroup
|
|
840
846
|
end
|
|
841
847
|
|
|
@@ -1131,7 +1137,7 @@ module Gosu
|
|
|
1131
1137
|
def self.char_to_button_id(char); end
|
|
1132
1138
|
|
|
1133
1139
|
##
|
|
1134
|
-
# @return [Float] a random number in the range
|
|
1140
|
+
# @return [Float] a random number in the range [min; max).
|
|
1135
1141
|
# @param min [Float] the minimum value, inclusive.
|
|
1136
1142
|
# @param max [Float] the maximum value, exclusive.
|
|
1137
1143
|
def random(min, max); end
|
data/src/Audio.cpp
CHANGED
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
#else
|
|
22
22
|
#include <AL/al.h>
|
|
23
23
|
#include <AL/alc.h>
|
|
24
|
+
#include "MPEGFile.hpp"
|
|
24
25
|
#include "SndFile.hpp"
|
|
25
26
|
#define WAVE_FILE SndFile
|
|
26
27
|
#endif
|
|
@@ -175,9 +176,8 @@ Gosu::Sample::Sample(const std::string& filename)
|
|
|
175
176
|
CONSTRUCTOR_BEGIN;
|
|
176
177
|
|
|
177
178
|
if (is_ogg_file(filename)) {
|
|
178
|
-
Gosu::
|
|
179
|
-
|
|
180
|
-
OggFile ogg_file(buffer.front_reader());
|
|
179
|
+
Gosu::File file(filename);
|
|
180
|
+
OggFile ogg_file(file.front_reader());
|
|
181
181
|
data.reset(new SampleData(ogg_file));
|
|
182
182
|
}
|
|
183
183
|
else {
|
|
@@ -197,8 +197,19 @@ Gosu::Sample::Sample(Reader reader)
|
|
|
197
197
|
data.reset(new SampleData(ogg_file));
|
|
198
198
|
}
|
|
199
199
|
else {
|
|
200
|
-
|
|
201
|
-
|
|
200
|
+
try {
|
|
201
|
+
WAVE_FILE audio_file(reader);
|
|
202
|
+
data.reset(new SampleData(audio_file));
|
|
203
|
+
}
|
|
204
|
+
catch (const std::runtime_error& ex) {
|
|
205
|
+
if (std::string(ex.what()).find("unknown format") != std::string::npos) {
|
|
206
|
+
MPEGFile mpeg_file(reader);
|
|
207
|
+
data.reset(new SampleData(mpeg_file));
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
throw ex;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
202
213
|
}
|
|
203
214
|
|
|
204
215
|
CONSTRUCTOR_END;
|
|
@@ -221,7 +232,6 @@ Gosu::SampleInstance Gosu::Sample::play_pan(double pan, double volume, double sp
|
|
|
221
232
|
channel_and_token.second);
|
|
222
233
|
assert (source != ALChannelManagement::NO_SOURCE);
|
|
223
234
|
alSourcei(source, AL_BUFFER, data->buffer);
|
|
224
|
-
// TODO: This is not the old panning behavior!
|
|
225
235
|
alSource3f(source, AL_POSITION, pan * 10, 0, 0);
|
|
226
236
|
alSourcef(source, AL_GAIN, volume);
|
|
227
237
|
alSourcef(source, AL_PITCH, speed);
|
|
@@ -281,7 +291,7 @@ public:
|
|
|
281
291
|
player = [[AVAudioPlayer alloc] initWithContentsOfURL:URL error:nil];
|
|
282
292
|
}
|
|
283
293
|
|
|
284
|
-
void play(bool looping)
|
|
294
|
+
void play(bool looping) override
|
|
285
295
|
{
|
|
286
296
|
if (paused()) {
|
|
287
297
|
stop();
|
|
@@ -290,28 +300,28 @@ public:
|
|
|
290
300
|
[player play];
|
|
291
301
|
}
|
|
292
302
|
|
|
293
|
-
void pause()
|
|
303
|
+
void pause() override
|
|
294
304
|
{
|
|
295
305
|
[player pause];
|
|
296
306
|
}
|
|
297
307
|
|
|
298
|
-
void resume()
|
|
308
|
+
void resume() override
|
|
299
309
|
{
|
|
300
310
|
[player play];
|
|
301
311
|
}
|
|
302
312
|
|
|
303
|
-
bool paused() const
|
|
313
|
+
bool paused() const override
|
|
304
314
|
{
|
|
305
315
|
return !player.playing;
|
|
306
316
|
};
|
|
307
317
|
|
|
308
|
-
void stop()
|
|
318
|
+
void stop() override
|
|
309
319
|
{
|
|
310
320
|
[player stop];
|
|
311
321
|
player.currentTime = 0;
|
|
312
322
|
}
|
|
313
323
|
|
|
314
|
-
void update()
|
|
324
|
+
void update() override
|
|
315
325
|
{
|
|
316
326
|
}
|
|
317
327
|
};
|
|
@@ -323,7 +333,7 @@ class Gosu::Song::StreamData : public BaseData
|
|
|
323
333
|
std::unique_ptr<AudioFile> file;
|
|
324
334
|
ALuint buffers[2];
|
|
325
335
|
|
|
326
|
-
void apply_volume()
|
|
336
|
+
void apply_volume() override
|
|
327
337
|
{
|
|
328
338
|
int source = lookup_source();
|
|
329
339
|
if (source != ALChannelManagement::NO_SOURCE) {
|
|
@@ -360,7 +370,15 @@ public:
|
|
|
360
370
|
file.reset(new OggFile(source_file.front_reader()));
|
|
361
371
|
}
|
|
362
372
|
else {
|
|
363
|
-
|
|
373
|
+
try {
|
|
374
|
+
file.reset(new WAVE_FILE(filename));
|
|
375
|
+
}
|
|
376
|
+
catch (const std::runtime_error& ex) {
|
|
377
|
+
if (std::string(ex.what()).find("unknown format") != std::string::npos) {
|
|
378
|
+
Gosu::File source_file(filename);
|
|
379
|
+
file.reset(new MPEGFile(source_file.front_reader()));
|
|
380
|
+
}
|
|
381
|
+
}
|
|
364
382
|
}
|
|
365
383
|
alGenBuffers(2, buffers);
|
|
366
384
|
}
|
|
@@ -371,7 +389,14 @@ public:
|
|
|
371
389
|
file.reset(new OggFile(reader));
|
|
372
390
|
}
|
|
373
391
|
else {
|
|
374
|
-
|
|
392
|
+
try {
|
|
393
|
+
file.reset(new WAVE_FILE(reader));
|
|
394
|
+
}
|
|
395
|
+
catch (const std::runtime_error& ex) {
|
|
396
|
+
if (std::string(ex.what()).find("unknown format") != std::string::npos) {
|
|
397
|
+
file.reset(new MPEGFile(reader));
|
|
398
|
+
}
|
|
399
|
+
}
|
|
375
400
|
}
|
|
376
401
|
alGenBuffers(2, buffers);
|
|
377
402
|
}
|
|
@@ -383,7 +408,7 @@ public:
|
|
|
383
408
|
}
|
|
384
409
|
}
|
|
385
410
|
|
|
386
|
-
void play(bool looping)
|
|
411
|
+
void play(bool looping) override
|
|
387
412
|
{
|
|
388
413
|
int source = lookup_source();
|
|
389
414
|
if (source != ALChannelManagement::NO_SOURCE) {
|
|
@@ -402,7 +427,7 @@ public:
|
|
|
402
427
|
}
|
|
403
428
|
}
|
|
404
429
|
|
|
405
|
-
void stop()
|
|
430
|
+
void stop() override
|
|
406
431
|
{
|
|
407
432
|
int source = lookup_source();
|
|
408
433
|
if (source != ALChannelManagement::NO_SOURCE) {
|
|
@@ -422,7 +447,7 @@ public:
|
|
|
422
447
|
file->rewind();
|
|
423
448
|
}
|
|
424
449
|
|
|
425
|
-
void pause()
|
|
450
|
+
void pause() override
|
|
426
451
|
{
|
|
427
452
|
int source = lookup_source();
|
|
428
453
|
if (source != ALChannelManagement::NO_SOURCE) {
|
|
@@ -430,7 +455,7 @@ public:
|
|
|
430
455
|
}
|
|
431
456
|
}
|
|
432
457
|
|
|
433
|
-
void resume()
|
|
458
|
+
void resume() override
|
|
434
459
|
{
|
|
435
460
|
int source = lookup_source();
|
|
436
461
|
if (source != ALChannelManagement::NO_SOURCE) {
|
|
@@ -438,7 +463,7 @@ public:
|
|
|
438
463
|
}
|
|
439
464
|
}
|
|
440
465
|
|
|
441
|
-
bool paused() const
|
|
466
|
+
bool paused() const override
|
|
442
467
|
{
|
|
443
468
|
int source = lookup_source();
|
|
444
469
|
if (source == ALChannelManagement::NO_SOURCE) {
|
|
@@ -449,7 +474,7 @@ public:
|
|
|
449
474
|
return state == AL_PAUSED;
|
|
450
475
|
}
|
|
451
476
|
|
|
452
|
-
void update()
|
|
477
|
+
void update() override
|
|
453
478
|
{
|
|
454
479
|
int source = lookup_source();
|
|
455
480
|
|
data/src/AudioToolboxFile.hpp
CHANGED
|
@@ -175,7 +175,7 @@ namespace Gosu
|
|
|
175
175
|
init();
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
-
~AudioToolboxFile()
|
|
178
|
+
~AudioToolboxFile() override
|
|
179
179
|
{
|
|
180
180
|
ExtAudioFileDispose(file_);
|
|
181
181
|
|
|
@@ -184,22 +184,22 @@ namespace Gosu
|
|
|
184
184
|
}
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
-
ALenum format() const
|
|
187
|
+
ALenum format() const override
|
|
188
188
|
{
|
|
189
189
|
return format_;
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
-
ALuint sample_rate() const
|
|
192
|
+
ALuint sample_rate() const override
|
|
193
193
|
{
|
|
194
194
|
return sample_rate_;
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
-
void rewind()
|
|
197
|
+
void rewind() override
|
|
198
198
|
{
|
|
199
199
|
CHECK_OS(ExtAudioFileSeek(file_, 0 + seek_offset_));
|
|
200
200
|
}
|
|
201
201
|
|
|
202
|
-
std::size_t read_data(void* dest, size_t length)
|
|
202
|
+
std::size_t read_data(void* dest, size_t length) override
|
|
203
203
|
{
|
|
204
204
|
AudioBufferList abl;
|
|
205
205
|
abl.mNumberBuffers = 1;
|
data/src/Color.cpp
CHANGED
|
@@ -14,21 +14,25 @@ namespace
|
|
|
14
14
|
|
|
15
15
|
double min = std::min(std::min(r, g), b);
|
|
16
16
|
double max = std::max(std::max(r, g), b);
|
|
17
|
+
double delta = max - min;
|
|
17
18
|
|
|
18
19
|
if (max == 0) {
|
|
19
20
|
HSV hsv = { 0, 0, 0 };
|
|
20
21
|
return hsv;
|
|
21
22
|
}
|
|
22
23
|
|
|
24
|
+
HSV hsv;
|
|
25
|
+
|
|
23
26
|
// Value.
|
|
24
|
-
|
|
27
|
+
hsv.v = max;
|
|
25
28
|
|
|
26
29
|
// Saturation.
|
|
27
|
-
double delta = max - min;
|
|
28
30
|
hsv.s = delta / max;
|
|
29
31
|
|
|
30
32
|
// Hue.
|
|
31
|
-
if (
|
|
33
|
+
if (delta == 0) {
|
|
34
|
+
hsv.h = 0;
|
|
35
|
+
} else if (r == max) {
|
|
32
36
|
hsv.h = (g - b) / delta + (g < b ? 6 : 0);
|
|
33
37
|
}
|
|
34
38
|
else if (g == max) {
|
|
@@ -55,8 +59,11 @@ Gosu::Color Gosu::Color::from_ahsv(Channel alpha, double h, double s, double v)
|
|
|
55
59
|
return Color(alpha, v * 255, v * 255, v * 255);
|
|
56
60
|
}
|
|
57
61
|
|
|
58
|
-
// Normalize hue
|
|
62
|
+
// Normalize hue so that is always in the [0, 360) range and wraps around.
|
|
59
63
|
h = normalize_angle(h);
|
|
64
|
+
// Clamp s and v for consistency with the Ruby/Gosu ARGB getters/setters.
|
|
65
|
+
s = clamp(s, 0.0, 1.0);
|
|
66
|
+
v = clamp(v, 0.0, 1.0);
|
|
60
67
|
|
|
61
68
|
int sector = h / 60;
|
|
62
69
|
double factorial = h / 60 - sector;
|
data/src/Input.cpp
CHANGED
|
@@ -10,42 +10,62 @@
|
|
|
10
10
|
#include <algorithm>
|
|
11
11
|
#include <array>
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
static void require_sdl_video()
|
|
14
14
|
{
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
if (!initialized) {
|
|
21
|
-
SDL_InitSubSystem(SDL_INIT_VIDEO);
|
|
22
|
-
initialized = true;
|
|
23
|
-
std::atexit(cleanup);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
void cleanup()
|
|
28
|
-
{
|
|
29
|
-
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
|
15
|
+
static bool initialized = false;
|
|
16
|
+
if (!initialized) {
|
|
17
|
+
SDL_InitSubSystem(SDL_INIT_VIDEO);
|
|
18
|
+
initialized = true;
|
|
19
|
+
std::atexit([] { SDL_QuitSubSystem(SDL_INIT_VIDEO); });
|
|
30
20
|
}
|
|
31
|
-
|
|
32
|
-
std::array<bool, Gosu::NUM_BUTTONS> button_states = { { false } };
|
|
33
21
|
}
|
|
22
|
+
|
|
23
|
+
static std::array<bool, Gosu::NUM_BUTTONS> button_states = { { false } };
|
|
34
24
|
|
|
35
25
|
struct Gosu::Input::Impl
|
|
36
26
|
{
|
|
37
27
|
Input& input;
|
|
38
28
|
SDL_Window* window;
|
|
39
|
-
|
|
29
|
+
|
|
30
|
+
TextInput* text_input = nullptr;
|
|
40
31
|
double mouse_x, mouse_y;
|
|
41
|
-
double mouse_scale_x
|
|
42
|
-
double
|
|
32
|
+
double mouse_scale_x = 1;
|
|
33
|
+
double mouse_scale_y = 1;
|
|
34
|
+
double mouse_offset_x = 0;
|
|
35
|
+
double mouse_offset_y = 0;
|
|
43
36
|
|
|
44
37
|
Impl(Input& input, SDL_Window* window)
|
|
45
|
-
: input(input), window(window)
|
|
38
|
+
: input(input), window(window)
|
|
39
|
+
{
|
|
40
|
+
require_sdl_video();
|
|
41
|
+
|
|
42
|
+
SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER);
|
|
43
|
+
|
|
44
|
+
int num_gamepads = std::min<int>(Gosu::NUM_GAMEPADS, SDL_NumJoysticks());
|
|
45
|
+
|
|
46
|
+
for (int i = 0; i < num_gamepads; ++i) {
|
|
47
|
+
// Prefer the SDL_GameController API...
|
|
48
|
+
if (SDL_IsGameController(i)) {
|
|
49
|
+
if (SDL_GameController* game_controller = SDL_GameControllerOpen(i)) {
|
|
50
|
+
game_controllers.push_back(game_controller);
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// ...but fall back on the good, old SDL_Joystick API.
|
|
55
|
+
if (SDL_Joystick* joystick = SDL_JoystickOpen(i)) {
|
|
56
|
+
joysticks.push_back(joystick);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
~Impl()
|
|
46
62
|
{
|
|
47
|
-
|
|
48
|
-
|
|
63
|
+
std::for_each(joysticks.begin(), joysticks.end(), &SDL_JoystickClose);
|
|
64
|
+
joysticks.clear();
|
|
65
|
+
std::for_each(game_controllers.begin(), game_controllers.end(), &SDL_GameControllerClose);
|
|
66
|
+
game_controllers.clear();
|
|
67
|
+
|
|
68
|
+
SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER);
|
|
49
69
|
}
|
|
50
70
|
|
|
51
71
|
void update_mouse_position()
|
|
@@ -83,59 +103,40 @@ struct Gosu::Input::Impl
|
|
|
83
103
|
#endif
|
|
84
104
|
}
|
|
85
105
|
|
|
86
|
-
|
|
87
|
-
{
|
|
88
|
-
event_queue.push_back(down ? id : ~id);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
void dispatch_enqueued_events()
|
|
106
|
+
bool feed_sdl_event(const SDL_Event* e)
|
|
92
107
|
{
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
else if (!down && input.on_button_up) {
|
|
102
|
-
input.on_button_up(button);
|
|
108
|
+
switch (e->type) {
|
|
109
|
+
case SDL_KEYDOWN:
|
|
110
|
+
case SDL_KEYUP: {
|
|
111
|
+
if (e->key.repeat == 0 && e->key.keysym.scancode <= KB_RANGE_END) {
|
|
112
|
+
enqueue_event(e->key.keysym.scancode, e->type == SDL_KEYDOWN);
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
break;
|
|
103
116
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
{
|
|
110
|
-
SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER);
|
|
111
|
-
|
|
112
|
-
int num_gamepads = std::min<int>(Gosu::NUM_GAMEPADS, SDL_NumJoysticks());
|
|
113
|
-
|
|
114
|
-
for (int i = 0; i < num_gamepads; ++i) {
|
|
115
|
-
// Prefer the SDL_GameController API...
|
|
116
|
-
if (SDL_IsGameController(i)) {
|
|
117
|
-
SDL_GameController* game_controller = SDL_GameControllerOpen(i);
|
|
118
|
-
if (game_controller) {
|
|
119
|
-
game_controllers.push_back(game_controller);
|
|
120
|
-
continue;
|
|
117
|
+
case SDL_MOUSEBUTTONDOWN:
|
|
118
|
+
case SDL_MOUSEBUTTONUP: {
|
|
119
|
+
if (e->button.button >= 1 && e->button.button <= 3) {
|
|
120
|
+
enqueue_event(MS_LEFT + e->button.button - 1, e->type == SDL_MOUSEBUTTONDOWN);
|
|
121
|
+
return true;
|
|
121
122
|
}
|
|
123
|
+
break;
|
|
122
124
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
125
|
+
case SDL_MOUSEWHEEL: {
|
|
126
|
+
if (e->wheel.y > 0) {
|
|
127
|
+
enqueue_event(MS_WHEEL_UP, true);
|
|
128
|
+
enqueue_event(MS_WHEEL_UP, false);
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
else if (e->wheel.y < 0) {
|
|
132
|
+
enqueue_event(MS_WHEEL_DOWN, true);
|
|
133
|
+
enqueue_event(MS_WHEEL_DOWN, false);
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
break;
|
|
127
137
|
}
|
|
128
138
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
void release_gamepads()
|
|
132
|
-
{
|
|
133
|
-
std::for_each(joysticks.begin(), joysticks.end(), &SDL_JoystickClose);
|
|
134
|
-
joysticks.clear();
|
|
135
|
-
std::for_each(game_controllers.begin(), game_controllers.end(), &SDL_GameControllerClose);
|
|
136
|
-
game_controllers.clear();
|
|
137
|
-
|
|
138
|
-
SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER);
|
|
139
|
+
return false;
|
|
139
140
|
}
|
|
140
141
|
|
|
141
142
|
typedef std::array<bool, GP_NUM_PER_GAMEPAD> GamepadBuffer;
|
|
@@ -192,17 +193,38 @@ struct Gosu::Input::Impl
|
|
|
192
193
|
}
|
|
193
194
|
}
|
|
194
195
|
|
|
196
|
+
void dispatch_enqueued_events()
|
|
197
|
+
{
|
|
198
|
+
for (int event : event_queue) {
|
|
199
|
+
bool down = (event >= 0);
|
|
200
|
+
Button button(down ? event : ~event);
|
|
201
|
+
|
|
202
|
+
button_states[button.id()] = down;
|
|
203
|
+
if (down && input.on_button_down) {
|
|
204
|
+
input.on_button_down(button);
|
|
205
|
+
}
|
|
206
|
+
else if (!down && input.on_button_up) {
|
|
207
|
+
input.on_button_up(button);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
event_queue.clear();
|
|
211
|
+
}
|
|
212
|
+
|
|
195
213
|
private:
|
|
196
214
|
// For button down event: Button name value (>= 0)
|
|
197
215
|
// For button up event: ~Button name value (< 0)
|
|
198
216
|
std::vector<int> event_queue;
|
|
217
|
+
|
|
218
|
+
void enqueue_event(int id, bool down)
|
|
219
|
+
{
|
|
220
|
+
event_queue.push_back(down ? id : ~id);
|
|
221
|
+
}
|
|
199
222
|
|
|
200
223
|
std::vector<SDL_Joystick*> joysticks;
|
|
201
224
|
std::vector<SDL_GameController*> game_controllers;
|
|
202
225
|
|
|
203
|
-
// SDL returns axis values in the range -2^15 through 2^15-1, so we consider
|
|
204
|
-
//
|
|
205
|
-
|
|
226
|
+
// SDL returns axis values in the range -2^15 through 2^15-1, so we consider -2^14 through
|
|
227
|
+
// 2^14 (half of that range) the dead zone.
|
|
206
228
|
enum { DEAD_ZONE = (1 << 14) };
|
|
207
229
|
|
|
208
230
|
void poll_game_controller(SDL_GameController* controller, GamepadBuffer& gamepad)
|
|
@@ -228,7 +250,7 @@ private:
|
|
|
228
250
|
SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_RIGHTY) > +DEAD_ZONE;
|
|
229
251
|
|
|
230
252
|
int button = 0;
|
|
231
|
-
for (
|
|
253
|
+
for (; button < SDL_CONTROLLER_BUTTON_DPAD_UP; ++button) {
|
|
232
254
|
gamepad[GP_BUTTON_0 + button - GP_RANGE_BEGIN] =
|
|
233
255
|
SDL_GameControllerGetButton(controller, (SDL_GameControllerButton) button);
|
|
234
256
|
}
|
|
@@ -241,47 +263,27 @@ private:
|
|
|
241
263
|
void poll_joystick(SDL_Joystick* joystick, GamepadBuffer& gamepad)
|
|
242
264
|
{
|
|
243
265
|
int axes = SDL_JoystickNumAxes(joystick);
|
|
244
|
-
int hats = SDL_JoystickNumHats(joystick);
|
|
245
|
-
int buttons = std::min<int>(GP_NUM_PER_GAMEPAD - 4, SDL_JoystickNumButtons(joystick));
|
|
246
|
-
|
|
247
266
|
for (int axis = 0; axis < axes; ++axis) {
|
|
248
267
|
Sint16 value = SDL_JoystickGetAxis(joystick, axis);
|
|
249
268
|
|
|
250
269
|
if (value < -DEAD_ZONE) {
|
|
251
|
-
|
|
252
|
-
gamepad[GP_LEFT - GP_RANGE_BEGIN] = true;
|
|
253
|
-
}
|
|
254
|
-
else {
|
|
255
|
-
gamepad[GP_UP - GP_RANGE_BEGIN] = true;
|
|
256
|
-
}
|
|
270
|
+
gamepad[(axis % 2 ? GP_UP : GP_LEFT) - GP_RANGE_BEGIN] = true;
|
|
257
271
|
}
|
|
258
272
|
else if (value > +DEAD_ZONE) {
|
|
259
|
-
|
|
260
|
-
gamepad[GP_RIGHT - GP_RANGE_BEGIN] = true;
|
|
261
|
-
}
|
|
262
|
-
else {
|
|
263
|
-
gamepad[GP_DOWN - GP_RANGE_BEGIN] = true;
|
|
264
|
-
}
|
|
273
|
+
gamepad[(axis % 2 ? GP_DOWN : GP_RIGHT) - GP_RANGE_BEGIN] = true;
|
|
265
274
|
}
|
|
266
275
|
}
|
|
267
276
|
|
|
277
|
+
int hats = SDL_JoystickNumHats(joystick);
|
|
268
278
|
for (int hat = 0; hat < hats; ++hat) {
|
|
269
279
|
Uint8 value = SDL_JoystickGetHat(joystick, hat);
|
|
270
|
-
|
|
271
|
-
if (value &
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
if (value & SDL_HAT_RIGHT) {
|
|
275
|
-
gamepad[GP_RIGHT - GP_RANGE_BEGIN] = true;
|
|
276
|
-
}
|
|
277
|
-
if (value & SDL_HAT_UP) {
|
|
278
|
-
gamepad[GP_UP - GP_RANGE_BEGIN] = true;
|
|
279
|
-
}
|
|
280
|
-
if (value & SDL_HAT_DOWN) {
|
|
281
|
-
gamepad[GP_DOWN - GP_RANGE_BEGIN] = true;
|
|
282
|
-
}
|
|
280
|
+
if (value & SDL_HAT_LEFT) gamepad[GP_LEFT - GP_RANGE_BEGIN] = true;
|
|
281
|
+
if (value & SDL_HAT_RIGHT) gamepad[GP_RIGHT - GP_RANGE_BEGIN] = true;
|
|
282
|
+
if (value & SDL_HAT_UP) gamepad[GP_UP - GP_RANGE_BEGIN] = true;
|
|
283
|
+
if (value & SDL_HAT_DOWN) gamepad[GP_DOWN - GP_RANGE_BEGIN] = true;
|
|
283
284
|
}
|
|
284
285
|
|
|
286
|
+
int buttons = std::min<int>(GP_NUM_PER_GAMEPAD - 4, SDL_JoystickNumButtons(joystick));
|
|
285
287
|
for (int button = 0; button < buttons; ++button) {
|
|
286
288
|
if (SDL_JoystickGetButton(joystick, button)) {
|
|
287
289
|
gamepad[GP_BUTTON_0 + button - GP_RANGE_BEGIN] = true;
|
|
@@ -293,56 +295,16 @@ private:
|
|
|
293
295
|
Gosu::Input::Input(void* window)
|
|
294
296
|
: pimpl(new Impl(*this, (SDL_Window*)window))
|
|
295
297
|
{
|
|
296
|
-
require_sdl_video();
|
|
297
|
-
|
|
298
|
-
pimpl->initialize_gamepads();
|
|
299
298
|
}
|
|
300
299
|
|
|
301
300
|
Gosu::Input::~Input()
|
|
302
301
|
{
|
|
303
|
-
pimpl->release_gamepads();
|
|
304
302
|
}
|
|
305
303
|
|
|
306
304
|
bool Gosu::Input::feed_sdl_event(void* event)
|
|
307
305
|
{
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
if (pimpl->text_input && pimpl->text_input->feed_sdl_event(event)) {
|
|
311
|
-
return true;
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
switch (e->type) {
|
|
315
|
-
case SDL_KEYDOWN:
|
|
316
|
-
case SDL_KEYUP: {
|
|
317
|
-
if (e->key.repeat == 0 && e->key.keysym.scancode <= KB_RANGE_END) {
|
|
318
|
-
pimpl->enqueue_event(e->key.keysym.scancode, e->type == SDL_KEYDOWN);
|
|
319
|
-
return true;
|
|
320
|
-
}
|
|
321
|
-
break;
|
|
322
|
-
}
|
|
323
|
-
case SDL_MOUSEBUTTONDOWN:
|
|
324
|
-
case SDL_MOUSEBUTTONUP: {
|
|
325
|
-
if (e->button.button >= 1 && e->button.button <= 3) {
|
|
326
|
-
pimpl->enqueue_event(MS_LEFT + e->button.button - 1, e->type == SDL_MOUSEBUTTONDOWN);
|
|
327
|
-
return true;
|
|
328
|
-
}
|
|
329
|
-
break;
|
|
330
|
-
}
|
|
331
|
-
case SDL_MOUSEWHEEL: {
|
|
332
|
-
if (e->wheel.y > 0) {
|
|
333
|
-
pimpl->enqueue_event(MS_WHEEL_UP, true);
|
|
334
|
-
pimpl->enqueue_event(MS_WHEEL_UP, false);
|
|
335
|
-
return true;
|
|
336
|
-
}
|
|
337
|
-
else if (e->wheel.y < 0) {
|
|
338
|
-
pimpl->enqueue_event(MS_WHEEL_DOWN, true);
|
|
339
|
-
pimpl->enqueue_event(MS_WHEEL_DOWN, false);
|
|
340
|
-
return true;
|
|
341
|
-
}
|
|
342
|
-
break;
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
return false;
|
|
306
|
+
return (pimpl->text_input && pimpl->text_input->feed_sdl_event(event)) ||
|
|
307
|
+
pimpl->feed_sdl_event(static_cast<SDL_Event*>(event));
|
|
346
308
|
}
|
|
347
309
|
|
|
348
310
|
std::string Gosu::Input::id_to_char(Button btn)
|
|
@@ -366,7 +328,7 @@ std::string Gosu::Input::id_to_char(Button btn)
|
|
|
366
328
|
// Convert to lower case to be consistent with previous versions of Gosu.
|
|
367
329
|
// German umlauts are already reported in lower-case by SDL, anyway.
|
|
368
330
|
// (This should handle Turkish i/I just fine because it uses the current locale.)
|
|
369
|
-
wname[0] = (wchar_t)std::towlower((int)wname[0]);
|
|
331
|
+
wname[0] = (wchar_t) std::towlower((int) wname[0]);
|
|
370
332
|
return wstring_to_utf8(wname);
|
|
371
333
|
}
|
|
372
334
|
|
|
@@ -411,7 +373,7 @@ void Gosu::Input::set_mouse_factors(double scale_x, double scale_y,
|
|
|
411
373
|
|
|
412
374
|
const Gosu::Touches& Gosu::Input::current_touches() const
|
|
413
375
|
{
|
|
414
|
-
//
|
|
376
|
+
// We could use the SDL 2 touch API to implement this.
|
|
415
377
|
|
|
416
378
|
static Gosu::Touches none;
|
|
417
379
|
return none;
|
|
@@ -435,8 +397,8 @@ double Gosu::Input::accelerometer_z() const
|
|
|
435
397
|
void Gosu::Input::update()
|
|
436
398
|
{
|
|
437
399
|
pimpl->update_mouse_position();
|
|
438
|
-
pimpl->dispatch_enqueued_events();
|
|
439
400
|
pimpl->poll_gamepads();
|
|
401
|
+
pimpl->dispatch_enqueued_events();
|
|
440
402
|
}
|
|
441
403
|
|
|
442
404
|
Gosu::TextInput* Gosu::Input::text_input() const
|
data/src/MPEGFile.hpp
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "AudioFile.hpp"
|
|
4
|
+
#include <Gosu/IO.hpp>
|
|
5
|
+
#include <algorithm>
|
|
6
|
+
#include <stdexcept>
|
|
7
|
+
#include <string>
|
|
8
|
+
|
|
9
|
+
#include <mpg123.h>
|
|
10
|
+
|
|
11
|
+
namespace Gosu
|
|
12
|
+
{
|
|
13
|
+
class MPEGFile : public AudioFile
|
|
14
|
+
{
|
|
15
|
+
Gosu::Buffer contents_;
|
|
16
|
+
off_t position_ = 0;
|
|
17
|
+
mpg123_handle* handle_;
|
|
18
|
+
|
|
19
|
+
enum {
|
|
20
|
+
SAMPLE_RATE = 44100,
|
|
21
|
+
INPUT_SIZE = 16384
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
public:
|
|
25
|
+
MPEGFile(Gosu::Reader reader)
|
|
26
|
+
{
|
|
27
|
+
contents_.resize(reader.resource().size() - reader.position());
|
|
28
|
+
reader.read(contents_.data(), contents_.size());
|
|
29
|
+
|
|
30
|
+
static int init_error = mpg123_init();
|
|
31
|
+
if (init_error != MPG123_OK) {
|
|
32
|
+
throw std::runtime_error("Cannot initialize mpg123: " +
|
|
33
|
+
std::string(mpg123_plain_strerror(init_error)));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
int new_error;
|
|
37
|
+
handle_ = mpg123_new(nullptr, &new_error);
|
|
38
|
+
if (handle_ == nullptr) {
|
|
39
|
+
throw std::runtime_error("Cannot initialize mpg123 decoder: " +
|
|
40
|
+
std::string(mpg123_plain_strerror(new_error)));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
mpg123_param(handle_, MPG123_FORCE_RATE, SAMPLE_RATE, 0);
|
|
44
|
+
mpg123_param(handle_, MPG123_FLAGS, MPG123_FORCE_STEREO, 0);
|
|
45
|
+
|
|
46
|
+
mpg123_open_feed(handle_);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
~MPEGFile() override
|
|
50
|
+
{
|
|
51
|
+
mpg123_delete(handle_);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
ALenum format() const override
|
|
55
|
+
{
|
|
56
|
+
return AL_FORMAT_STEREO16;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
ALuint sample_rate() const override
|
|
60
|
+
{
|
|
61
|
+
return SAMPLE_RATE;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
std::size_t read_data(void* dest, std::size_t length) override
|
|
65
|
+
{
|
|
66
|
+
std::size_t written = 0;
|
|
67
|
+
int error = 0;
|
|
68
|
+
|
|
69
|
+
error = mpg123_read(handle_, static_cast<unsigned char*>(dest), length, &written);
|
|
70
|
+
while (written == 0
|
|
71
|
+
&& (error == MPG123_NEED_MORE || error == MPG123_NEW_FORMAT)
|
|
72
|
+
&& position_ != contents_.size()) {
|
|
73
|
+
auto bytes = std::min<std::size_t>(contents_.size() - position_, INPUT_SIZE);
|
|
74
|
+
// (Not sure what to do about the return value of mpg123_feed here.)
|
|
75
|
+
mpg123_feed(handle_, static_cast<unsigned char*>(contents_.data()) + position_,
|
|
76
|
+
bytes);
|
|
77
|
+
position_ += bytes;
|
|
78
|
+
error = mpg123_read(handle_, static_cast<unsigned char*>(dest), length, &written);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return written;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
void rewind() override
|
|
85
|
+
{
|
|
86
|
+
mpg123_feedseek(handle_, 0, SEEK_SET, &position_);
|
|
87
|
+
assert (position_ >= 0 && position_ <= contents_.size());
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
}
|
data/src/Macro.hpp
CHANGED
|
@@ -18,7 +18,7 @@ public:
|
|
|
18
18
|
|
|
19
19
|
void draw(double x1, double y1, Color c1, double x2, double y2, Color c2,
|
|
20
20
|
double x3, double y3, Color c3, double x4, double y4, Color c4, ZPos z,
|
|
21
|
-
AlphaMode mode) const;
|
|
21
|
+
AlphaMode mode) const override;
|
|
22
22
|
|
|
23
23
|
const Gosu::GLTexInfo* gl_tex_info() const override;
|
|
24
24
|
|
data/src/OggFile.hpp
CHANGED
|
@@ -2,33 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
#include "AudioFile.hpp"
|
|
4
4
|
#include <Gosu/IO.hpp>
|
|
5
|
-
#include <algorithm>
|
|
6
5
|
#include <stdexcept>
|
|
7
6
|
#include <string>
|
|
8
7
|
|
|
9
8
|
#define STB_VORBIS_HEADER_ONLY
|
|
10
9
|
#include "stb_vorbis.c"
|
|
11
10
|
|
|
12
|
-
// Based on the Drama Sound Engine for D
|
|
13
|
-
|
|
14
11
|
namespace Gosu
|
|
15
12
|
{
|
|
16
13
|
class OggFile : public AudioFile
|
|
17
14
|
{
|
|
18
15
|
Gosu::Buffer contents_;
|
|
19
|
-
Gosu::Buffer buffer_;
|
|
20
16
|
int channels_;
|
|
21
17
|
ALenum sample_rate_;
|
|
22
18
|
stb_vorbis* stream_;
|
|
23
19
|
|
|
24
|
-
|
|
20
|
+
public:
|
|
21
|
+
OggFile(Gosu::Reader reader)
|
|
25
22
|
{
|
|
23
|
+
contents_.resize(reader.resource().size() - reader.position());
|
|
24
|
+
reader.read(contents_.data(), contents_.size());
|
|
25
|
+
|
|
26
26
|
int error = 0;
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
auto data = static_cast<const unsigned char*>(contents_.data());
|
|
29
|
+
auto size = static_cast<int>(contents_.size());
|
|
30
|
+
stream_ = stb_vorbis_open_memory(data, size, &error, 0);
|
|
30
31
|
|
|
31
|
-
if (stream_ ==
|
|
32
|
+
if (stream_ == nullptr) {
|
|
32
33
|
throw std::runtime_error("Cannot open Ogg Vorbis file, error code: " +
|
|
33
34
|
std::to_string(error));
|
|
34
35
|
}
|
|
@@ -36,43 +37,28 @@ namespace Gosu
|
|
|
36
37
|
stb_vorbis_info info = stb_vorbis_get_info(stream_);
|
|
37
38
|
channels_ = info.channels;
|
|
38
39
|
sample_rate_ = info.sample_rate;
|
|
39
|
-
buffer_.resize(info.temp_memory_required);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
~OggFile() override
|
|
43
43
|
{
|
|
44
44
|
stb_vorbis_close(stream_);
|
|
45
|
-
stream_ =
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
public:
|
|
49
|
-
OggFile(Gosu::Reader reader)
|
|
50
|
-
{
|
|
51
|
-
contents_.resize(reader.resource().size() - reader.position());
|
|
52
|
-
reader.read(contents_.data(), contents_.size());
|
|
53
|
-
|
|
54
|
-
open();
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
~OggFile()
|
|
58
|
-
{
|
|
59
|
-
close();
|
|
45
|
+
stream_ = nullptr;
|
|
60
46
|
}
|
|
61
47
|
|
|
62
|
-
ALenum format() const
|
|
48
|
+
ALenum format() const override
|
|
63
49
|
{
|
|
64
50
|
return (channels_ == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16);
|
|
65
51
|
}
|
|
66
52
|
|
|
67
|
-
ALuint sample_rate() const
|
|
53
|
+
ALuint sample_rate() const override
|
|
68
54
|
{
|
|
69
55
|
return sample_rate_;
|
|
70
56
|
}
|
|
71
57
|
|
|
72
|
-
std::size_t read_data(void* dest, std::size_t length)
|
|
58
|
+
std::size_t read_data(void* dest, std::size_t length) override
|
|
73
59
|
{
|
|
74
60
|
int samples = 0;
|
|
75
|
-
int max_samples = length / sizeof(short);
|
|
61
|
+
int max_samples = static_cast<int>(length / sizeof(short));
|
|
76
62
|
|
|
77
63
|
while (samples < max_samples) {
|
|
78
64
|
int samples_per_channel =
|
|
@@ -88,7 +74,7 @@ namespace Gosu
|
|
|
88
74
|
return samples * sizeof(short);
|
|
89
75
|
}
|
|
90
76
|
|
|
91
|
-
void rewind()
|
|
77
|
+
void rewind() override
|
|
92
78
|
{
|
|
93
79
|
stb_vorbis_seek_start(stream_);
|
|
94
80
|
}
|
data/src/RubyGosu.cxx
CHANGED
|
@@ -3342,6 +3342,15 @@ void SwigDirector_Window::button_up(Gosu::Button arg0) {
|
|
|
3342
3342
|
}
|
|
3343
3343
|
|
|
3344
3344
|
|
|
3345
|
+
void SwigDirector_Window::drop(std::string const &filename) {
|
|
3346
|
+
VALUE obj0 = Qnil ;
|
|
3347
|
+
VALUE SWIGUNUSED result;
|
|
3348
|
+
|
|
3349
|
+
obj0 = SWIG_From_std_string(static_cast< std::string >(filename));
|
|
3350
|
+
result = rb_funcall(swig_get_self(), rb_intern("drop"), 1,obj0);
|
|
3351
|
+
}
|
|
3352
|
+
|
|
3353
|
+
|
|
3345
3354
|
SWIGINTERN VALUE
|
|
3346
3355
|
_wrap_milliseconds(int argc, VALUE *argv, VALUE self) {
|
|
3347
3356
|
unsigned long result;
|
|
@@ -9571,6 +9580,62 @@ fail:
|
|
|
9571
9580
|
}
|
|
9572
9581
|
|
|
9573
9582
|
|
|
9583
|
+
SWIGINTERN VALUE
|
|
9584
|
+
_wrap_Window_drop(int argc, VALUE *argv, VALUE self) {
|
|
9585
|
+
Gosu::Window *arg1 = (Gosu::Window *) 0 ;
|
|
9586
|
+
std::string *arg2 = 0 ;
|
|
9587
|
+
void *argp1 = 0 ;
|
|
9588
|
+
int res1 = 0 ;
|
|
9589
|
+
int res2 = SWIG_OLDOBJ ;
|
|
9590
|
+
Swig::Director *director = 0;
|
|
9591
|
+
bool upcall = false;
|
|
9592
|
+
|
|
9593
|
+
if ((argc < 1) || (argc > 1)) {
|
|
9594
|
+
rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)",argc); SWIG_fail;
|
|
9595
|
+
}
|
|
9596
|
+
res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_Gosu__Window, 0 | 0 );
|
|
9597
|
+
if (!SWIG_IsOK(res1)) {
|
|
9598
|
+
SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "Gosu::Window *","drop", 1, self ));
|
|
9599
|
+
}
|
|
9600
|
+
arg1 = reinterpret_cast< Gosu::Window * >(argp1);
|
|
9601
|
+
{
|
|
9602
|
+
std::string *ptr = (std::string *)0;
|
|
9603
|
+
res2 = SWIG_AsPtr_std_string(argv[0], &ptr);
|
|
9604
|
+
if (!SWIG_IsOK(res2)) {
|
|
9605
|
+
SWIG_exception_fail(SWIG_ArgError(res2), Ruby_Format_TypeError( "", "std::string const &","drop", 2, argv[0] ));
|
|
9606
|
+
}
|
|
9607
|
+
if (!ptr) {
|
|
9608
|
+
SWIG_exception_fail(SWIG_ValueError, Ruby_Format_TypeError("invalid null reference ", "std::string const &","drop", 2, argv[0]));
|
|
9609
|
+
}
|
|
9610
|
+
arg2 = ptr;
|
|
9611
|
+
}
|
|
9612
|
+
director = dynamic_cast<Swig::Director *>(arg1);
|
|
9613
|
+
upcall = (director && (director->swig_get_self() == self));
|
|
9614
|
+
try {
|
|
9615
|
+
{
|
|
9616
|
+
try {
|
|
9617
|
+
if (upcall) {
|
|
9618
|
+
(arg1)->Gosu::Window::drop((std::string const &)*arg2);
|
|
9619
|
+
} else {
|
|
9620
|
+
(arg1)->drop((std::string const &)*arg2);
|
|
9621
|
+
}
|
|
9622
|
+
}
|
|
9623
|
+
catch (const std::exception& e) {
|
|
9624
|
+
SWIG_exception(SWIG_RuntimeError, e.what());
|
|
9625
|
+
}
|
|
9626
|
+
}
|
|
9627
|
+
} catch (Swig::DirectorException& e) {
|
|
9628
|
+
rb_exc_raise(e.getError());
|
|
9629
|
+
SWIG_fail;
|
|
9630
|
+
}
|
|
9631
|
+
if (SWIG_IsNewObj(res2)) delete arg2;
|
|
9632
|
+
return Qnil;
|
|
9633
|
+
fail:
|
|
9634
|
+
if (SWIG_IsNewObj(res2)) delete arg2;
|
|
9635
|
+
return Qnil;
|
|
9636
|
+
}
|
|
9637
|
+
|
|
9638
|
+
|
|
9574
9639
|
SWIGINTERN VALUE
|
|
9575
9640
|
_wrap_Window_widthe___(int argc, VALUE *argv, VALUE self) {
|
|
9576
9641
|
Gosu::Window *arg1 = (Gosu::Window *) 0 ;
|
|
@@ -11574,7 +11639,7 @@ SWIGEXPORT void Init_gosu(void) {
|
|
|
11574
11639
|
rb_define_const(mGosu, "LICENSES", SWIG_From_std_string(static_cast< std::string >(Gosu::LICENSES)));
|
|
11575
11640
|
rb_define_const(mGosu, "MAJOR_VERSION", SWIG_From_int(static_cast< int >(0)));
|
|
11576
11641
|
rb_define_const(mGosu, "MINOR_VERSION", SWIG_From_int(static_cast< int >(11)));
|
|
11577
|
-
rb_define_const(mGosu, "POINT_VERSION", SWIG_From_int(static_cast< int >(
|
|
11642
|
+
rb_define_const(mGosu, "POINT_VERSION", SWIG_From_int(static_cast< int >(4)));
|
|
11578
11643
|
rb_define_module_function(mGosu, "milliseconds", VALUEFUNC(_wrap_milliseconds), -1);
|
|
11579
11644
|
rb_define_module_function(mGosu, "random", VALUEFUNC(_wrap_random), -1);
|
|
11580
11645
|
rb_define_module_function(mGosu, "degrees_to_radians", VALUEFUNC(_wrap_degrees_to_radians), -1);
|
|
@@ -11985,6 +12050,7 @@ SWIGEXPORT void Init_gosu(void) {
|
|
|
11985
12050
|
rb_define_method(SwigClassWindow.klass, "release_memory", VALUEFUNC(_wrap_Window_release_memory), -1);
|
|
11986
12051
|
rb_define_method(SwigClassWindow.klass, "button_down", VALUEFUNC(_wrap_Window_button_down), -1);
|
|
11987
12052
|
rb_define_method(SwigClassWindow.klass, "button_up", VALUEFUNC(_wrap_Window_button_up), -1);
|
|
12053
|
+
rb_define_method(SwigClassWindow.klass, "drop", VALUEFUNC(_wrap_Window_drop), -1);
|
|
11988
12054
|
rb_define_method(SwigClassWindow.klass, "width=", VALUEFUNC(_wrap_Window_widthe___), -1);
|
|
11989
12055
|
rb_define_method(SwigClassWindow.klass, "height=", VALUEFUNC(_wrap_Window_heighte___), -1);
|
|
11990
12056
|
rb_define_method(SwigClassWindow.klass, "fullscreen=", VALUEFUNC(_wrap_Window_fullscreene___), -1);
|
data/src/RubyGosu.h
CHANGED
data/src/SndFile.hpp
CHANGED
|
@@ -137,14 +137,14 @@ namespace Gosu
|
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
~SndFile()
|
|
140
|
+
~SndFile() override
|
|
141
141
|
{
|
|
142
142
|
if (file) {
|
|
143
143
|
sf_close(file);
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
-
ALenum format() const
|
|
147
|
+
ALenum format() const override
|
|
148
148
|
{
|
|
149
149
|
switch (info.channels) {
|
|
150
150
|
case 1:
|
|
@@ -156,18 +156,18 @@ namespace Gosu
|
|
|
156
156
|
};
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
-
ALuint sample_rate() const
|
|
159
|
+
ALuint sample_rate() const override
|
|
160
160
|
{
|
|
161
161
|
return info.samplerate;
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
std::size_t read_data(void* dest, std::size_t length)
|
|
164
|
+
std::size_t read_data(void* dest, std::size_t length) override
|
|
165
165
|
{
|
|
166
166
|
int frame_size = sizeof(short) * info.channels;
|
|
167
167
|
return sf_readf_short(file, (short*)dest, length / frame_size) * frame_size;
|
|
168
168
|
}
|
|
169
169
|
|
|
170
|
-
void rewind()
|
|
170
|
+
void rewind() override
|
|
171
171
|
{
|
|
172
172
|
sf_seek(file, 0, SEEK_SET);
|
|
173
173
|
}
|
data/src/Window.cpp
CHANGED
|
@@ -43,6 +43,7 @@ namespace Gosu
|
|
|
43
43
|
if (window == nullptr) {
|
|
44
44
|
throw_sdl_error("Could not create window");
|
|
45
45
|
}
|
|
46
|
+
SDL_EventState(SDL_DROPFILE, SDL_ENABLE);
|
|
46
47
|
}
|
|
47
48
|
return window;
|
|
48
49
|
}
|
|
@@ -253,11 +254,22 @@ bool Gosu::Window::tick()
|
|
|
253
254
|
|
|
254
255
|
SDL_Event e;
|
|
255
256
|
while (SDL_PollEvent(&e)) {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
257
|
+
switch (e.type) {
|
|
258
|
+
case (SDL_QUIT): {
|
|
259
|
+
close();
|
|
260
|
+
break;
|
|
261
|
+
}
|
|
262
|
+
case (SDL_DROPFILE): {
|
|
263
|
+
char* dropped_filedir = e.drop.file;
|
|
264
|
+
if (dropped_filedir == nullptr) break;
|
|
265
|
+
drop(std::string(dropped_filedir));
|
|
266
|
+
SDL_free(dropped_filedir);
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
default: {
|
|
270
|
+
input().feed_sdl_event(&e);
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
261
273
|
}
|
|
262
274
|
}
|
|
263
275
|
|
|
@@ -306,7 +318,7 @@ void Gosu::Window::button_down(Button button)
|
|
|
306
318
|
!Input::down(KB_LEFT_SHIFT) && !Input::down(KB_RIGHT_SHIFT) &&
|
|
307
319
|
!Input::down(KB_LEFT_ALT) && !Input::down(KB_RIGHT_ALT);
|
|
308
320
|
#else
|
|
309
|
-
//
|
|
321
|
+
// Alt+Enter and Alt+Return toggle fullscreen mode on all other platforms.
|
|
310
322
|
toggle_fullscreen = (button == KB_RETURN || button == KB_ENTER) &&
|
|
311
323
|
(Input::down(KB_LEFT_ALT) || Input::down(KB_RIGHT_ALT)) &&
|
|
312
324
|
!Input::down(KB_LEFT_CONTROL) && !Input::down(KB_RIGHT_CONTROL) &&
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: gosu
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.11.
|
|
4
|
+
version: 0.11.4.pre1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Julian Raschke
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-
|
|
11
|
+
date: 2017-04-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: |2
|
|
14
14
|
2D game development library.
|
|
@@ -95,6 +95,7 @@ files:
|
|
|
95
95
|
- src/Inspection.cpp
|
|
96
96
|
- src/LargeImageData.cpp
|
|
97
97
|
- src/LargeImageData.hpp
|
|
98
|
+
- src/MPEGFile.hpp
|
|
98
99
|
- src/Macro.cpp
|
|
99
100
|
- src/Macro.hpp
|
|
100
101
|
- src/Math.cpp
|
|
@@ -151,9 +152,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
151
152
|
version: 1.8.2
|
|
152
153
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
153
154
|
requirements:
|
|
154
|
-
- - "
|
|
155
|
+
- - ">"
|
|
155
156
|
- !ruby/object:Gem::Version
|
|
156
|
-
version:
|
|
157
|
+
version: 1.3.1
|
|
157
158
|
requirements: []
|
|
158
159
|
rubyforge_project:
|
|
159
160
|
rubygems_version: 2.6.8
|