gosu 0.7.26.1 → 0.7.27
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING.txt +3 -2
- data/Gosu/Audio.hpp +17 -13
- data/Gosu/Gosu.hpp +1 -0
- data/Gosu/Inspection.hpp +14 -0
- data/Gosu/Version.hpp +2 -2
- data/GosuImpl/Audio/AudioAudiere.cpp +443 -0
- data/GosuImpl/Audio/AudioOpenAL.mm +2 -2
- data/GosuImpl/Audio/AudioSDL.cpp +1 -1
- data/GosuImpl/Graphics/Color.cpp +1 -1
- data/GosuImpl/Graphics/GosuView.mm +10 -1
- data/GosuImpl/Inspection.cpp +27 -0
- data/GosuImpl/RubyGosu.swg +7 -1
- data/GosuImpl/RubyGosu_DllMain.cxx +3 -2
- data/GosuImpl/RubyGosu_wrap.cxx +26 -4
- data/GosuImpl/WindowMac.mm +9 -3
- data/GosuImpl/WindowTouch.mm +2 -1
- data/GosuImpl/WindowWin.cpp +7 -3
- data/GosuImpl/WindowX.cpp +6 -0
- data/linux/extconf.rb +5 -5
- metadata +9 -8
- data/GosuImpl/AudioFmod.cpp +0 -493
data/COPYING.txt
CHANGED
@@ -26,5 +26,6 @@ http://www.libgosu.org/
|
|
26
26
|
|
27
27
|
***
|
28
28
|
|
29
|
-
This does NOT apply to
|
30
|
-
|
29
|
+
This does NOT apply to audiere.dll shipped with the Windows versions of
|
30
|
+
Gosu. Audiere is a separate library licensed under the Lesser General
|
31
|
+
Public License. Please consult audiere.sf.net for more details.
|
data/Gosu/Audio.hpp
CHANGED
@@ -96,8 +96,10 @@ namespace Gosu
|
|
96
96
|
|
97
97
|
|
98
98
|
// Deprecated.
|
99
|
-
|
100
|
-
Sample(Audio& audio,
|
99
|
+
#ifndef SWIG
|
100
|
+
GOSU_DEPRECATED Sample(Audio& audio, const std::wstring& filename);
|
101
|
+
GOSU_DEPRECATED Sample(Audio& audio, Reader reader);
|
102
|
+
#endif
|
101
103
|
};
|
102
104
|
|
103
105
|
//! Songs are less flexible than samples in that they can only be played
|
@@ -110,14 +112,6 @@ namespace Gosu
|
|
110
112
|
boost::scoped_ptr<BaseData> data;
|
111
113
|
|
112
114
|
public:
|
113
|
-
//! There are two types of songs that can be loaded as a Song: Streamed
|
114
|
-
//! songs (like OGG) and modules (like MOD or XM).
|
115
|
-
enum Type
|
116
|
-
{
|
117
|
-
stStream,
|
118
|
-
stModule
|
119
|
-
};
|
120
|
-
|
121
115
|
//! Constructs a song that can be played on the provided audio system
|
122
116
|
//! and loads the song from a file. The type is determined from the
|
123
117
|
//! filename.
|
@@ -125,7 +119,7 @@ namespace Gosu
|
|
125
119
|
|
126
120
|
//! Constructs a song of the specified type that can be played on the
|
127
121
|
//! provided audio system and loads the song data from a stream.
|
128
|
-
Song(
|
122
|
+
explicit Song(Reader reader);
|
129
123
|
|
130
124
|
~Song();
|
131
125
|
|
@@ -157,8 +151,18 @@ namespace Gosu
|
|
157
151
|
static void update();
|
158
152
|
|
159
153
|
// Deprecated.
|
160
|
-
|
161
|
-
|
154
|
+
#ifndef SWIG
|
155
|
+
//! There are two types of songs that can be loaded as a Song: Streamed
|
156
|
+
//! songs (like OGG) and modules (like MOD or XM).
|
157
|
+
enum Type
|
158
|
+
{
|
159
|
+
stStream,
|
160
|
+
stModule
|
161
|
+
};
|
162
|
+
|
163
|
+
GOSU_DEPRECATED Song(Audio&, const std::wstring& filename);
|
164
|
+
GOSU_DEPRECATED Song(Audio&, Type type, Reader reader);
|
165
|
+
#endif
|
162
166
|
};
|
163
167
|
}
|
164
168
|
|
data/Gosu/Gosu.hpp
CHANGED
data/Gosu/Inspection.hpp
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
//! \file Inspection.hpp
|
2
|
+
//! A special set of functions designed for tuning Gosu games.
|
3
|
+
|
4
|
+
#ifndef GOSU_INSPECTION_HPP
|
5
|
+
#define GOSU_INSPECTION_HPP
|
6
|
+
|
7
|
+
namespace Gosu
|
8
|
+
{
|
9
|
+
//! Returns the current framerate, as determined by an unspecified and possibly
|
10
|
+
//! horrible algorithm.
|
11
|
+
int fps();
|
12
|
+
}
|
13
|
+
|
14
|
+
#endif
|
data/Gosu/Version.hpp
CHANGED
@@ -0,0 +1,443 @@
|
|
1
|
+
#include <Gosu/Audio.hpp>
|
2
|
+
#include <Gosu/Math.hpp>
|
3
|
+
#include <Gosu/IO.hpp>
|
4
|
+
#include <boost/foreach.hpp>
|
5
|
+
#include <algorithm>
|
6
|
+
#include <stdexcept>
|
7
|
+
#include <vector>
|
8
|
+
|
9
|
+
#include <audiere.h>
|
10
|
+
using namespace audiere;
|
11
|
+
|
12
|
+
namespace Gosu
|
13
|
+
{
|
14
|
+
namespace
|
15
|
+
{
|
16
|
+
Song* curSong = 0;
|
17
|
+
|
18
|
+
// Gosu::Buffer-based implementation of Audiere's File interface.
|
19
|
+
// Provided since Audiere uses stdio to open files, which may not support Unicode
|
20
|
+
// filenames outside of the current codepage on Windows(?).
|
21
|
+
class MemoryBuffer : boost::noncopyable
|
22
|
+
{
|
23
|
+
Gosu::Buffer buffer;
|
24
|
+
FilePtr file;
|
25
|
+
|
26
|
+
public:
|
27
|
+
MemoryBuffer(Gosu::Reader reader)
|
28
|
+
{
|
29
|
+
buffer.resize(reader.resource().size() - reader.position());
|
30
|
+
reader.read(buffer.data(), buffer.size());
|
31
|
+
file = audiere::CreateMemoryFile(buffer.data(), buffer.size());
|
32
|
+
}
|
33
|
+
|
34
|
+
MemoryBuffer(const std::wstring& filename)
|
35
|
+
{
|
36
|
+
Gosu::loadFile(buffer, filename);
|
37
|
+
file = audiere::CreateMemoryFile(buffer.data(), buffer.size());
|
38
|
+
}
|
39
|
+
|
40
|
+
operator const FilePtr&()
|
41
|
+
{
|
42
|
+
return file;
|
43
|
+
}
|
44
|
+
};
|
45
|
+
|
46
|
+
class StreamRegistry : public RefImplementation<StopCallback>, boost::noncopyable
|
47
|
+
{
|
48
|
+
struct NumberedStream
|
49
|
+
{
|
50
|
+
int extra;
|
51
|
+
OutputStreamPtr stream;
|
52
|
+
};
|
53
|
+
std::vector<NumberedStream> streams;
|
54
|
+
|
55
|
+
ADR_METHOD(void) streamStopped(StopEvent* event)
|
56
|
+
{
|
57
|
+
if (event->getReason() == StopEvent::STREAM_ENDED)
|
58
|
+
if (!clear(event->getOutputStream()) && curSong)
|
59
|
+
curSong = 0;
|
60
|
+
}
|
61
|
+
|
62
|
+
public:
|
63
|
+
StreamRegistry()
|
64
|
+
{
|
65
|
+
streams.reserve(100);
|
66
|
+
}
|
67
|
+
|
68
|
+
OutputStreamPtr get(int handle, int extra) const
|
69
|
+
{
|
70
|
+
if (handle < streams.size() && streams[handle].extra == extra)
|
71
|
+
return streams[handle].stream;
|
72
|
+
return OutputStreamPtr();
|
73
|
+
}
|
74
|
+
|
75
|
+
void put(OutputStreamPtr stream, int& handle, int& extra)
|
76
|
+
{
|
77
|
+
handle = 0;
|
78
|
+
for (handle; handle < streams.size(); ++handle)
|
79
|
+
if (!streams[handle].stream)
|
80
|
+
{
|
81
|
+
streams[handle].stream = stream;
|
82
|
+
extra = ++streams[handle].extra;
|
83
|
+
return;
|
84
|
+
}
|
85
|
+
// handle == streams.size() <3
|
86
|
+
NumberedStream newStream = { extra = 0, stream };
|
87
|
+
streams.push_back(newStream);
|
88
|
+
}
|
89
|
+
|
90
|
+
void clear(int handle)
|
91
|
+
{
|
92
|
+
streams.at(handle).stream = 0;
|
93
|
+
}
|
94
|
+
|
95
|
+
bool clear(OutputStreamPtr stream)
|
96
|
+
{
|
97
|
+
BOOST_FOREACH (NumberedStream& numberedStream, streams)
|
98
|
+
if (numberedStream.stream == stream)
|
99
|
+
{
|
100
|
+
numberedStream.stream = 0;
|
101
|
+
return true;
|
102
|
+
}
|
103
|
+
return false;
|
104
|
+
}
|
105
|
+
};
|
106
|
+
|
107
|
+
// Intentionally leak. Let Windows clean up on program exit.
|
108
|
+
StreamRegistry& streams = *(new StreamRegistry);
|
109
|
+
|
110
|
+
// Since audiere::OpenDevice is (contains) the first call to audiere.dll, we wrap
|
111
|
+
// the call in error handling code to see if the lazily linked DLL is there.
|
112
|
+
bool getDevice(AudioDevice*& device)
|
113
|
+
{
|
114
|
+
#ifdef GOSU_IS_WIN
|
115
|
+
// Copied and pasted from MSDN.
|
116
|
+
#define FACILITY_VISUALCPP ((LONG)0x6d)
|
117
|
+
#define VcppException(sev,err) ((sev) | (FACILITY_VISUALCPP<<16) | err)
|
118
|
+
#define BAD_MOD VcppException(ERROR_SEVERITY_ERROR, ERROR_MOD_NOT_FOUND)
|
119
|
+
|
120
|
+
__try
|
121
|
+
{
|
122
|
+
#endif
|
123
|
+
return (device = OpenDevice());
|
124
|
+
#ifdef GOSU_IS_WIN
|
125
|
+
}
|
126
|
+
__except ((GetExceptionCode() == BAD_MOD) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
|
127
|
+
{
|
128
|
+
return false;
|
129
|
+
}
|
130
|
+
#undef BAD_MOD
|
131
|
+
#undef VcppException
|
132
|
+
#undef FACILITY_VISUALCPP
|
133
|
+
#endif
|
134
|
+
}
|
135
|
+
|
136
|
+
AudioDevice* device()
|
137
|
+
{
|
138
|
+
static AudioDevice* device = 0;
|
139
|
+
if (device == 0)
|
140
|
+
{
|
141
|
+
if (!getDevice(device))
|
142
|
+
throw std::runtime_error("Could not initialize audiere or library not found");
|
143
|
+
|
144
|
+
device->registerCallback(&streams);
|
145
|
+
|
146
|
+
// Never free. Especially important in Ruby version, where GC order is undefined
|
147
|
+
device->ref();
|
148
|
+
}
|
149
|
+
return device;
|
150
|
+
}
|
151
|
+
|
152
|
+
}
|
153
|
+
}
|
154
|
+
|
155
|
+
Gosu::SampleInstance::SampleInstance(int handle, int extra)
|
156
|
+
: handle(handle), extra(extra)
|
157
|
+
{
|
158
|
+
}
|
159
|
+
|
160
|
+
bool Gosu::SampleInstance::playing() const
|
161
|
+
{
|
162
|
+
OutputStreamPtr stream = streams.get(handle, extra);
|
163
|
+
return stream && stream->isPlaying();
|
164
|
+
}
|
165
|
+
|
166
|
+
bool Gosu::SampleInstance::paused() const
|
167
|
+
{
|
168
|
+
OutputStreamPtr stream = streams.get(handle, extra);
|
169
|
+
return stream && !stream->isPlaying();
|
170
|
+
}
|
171
|
+
|
172
|
+
void Gosu::SampleInstance::pause()
|
173
|
+
{
|
174
|
+
if (OutputStreamPtr stream = streams.get(handle, extra))
|
175
|
+
stream->stop();
|
176
|
+
}
|
177
|
+
|
178
|
+
void Gosu::SampleInstance::resume()
|
179
|
+
{
|
180
|
+
if (OutputStreamPtr stream = streams.get(handle, extra))
|
181
|
+
stream->play();
|
182
|
+
}
|
183
|
+
|
184
|
+
void Gosu::SampleInstance::stop()
|
185
|
+
{
|
186
|
+
if (OutputStreamPtr stream = streams.get(handle, extra))
|
187
|
+
stream->stop(), streams.clear(handle);
|
188
|
+
}
|
189
|
+
|
190
|
+
void Gosu::SampleInstance::changeVolume(double volume)
|
191
|
+
{
|
192
|
+
if (OutputStreamPtr stream = streams.get(handle, extra))
|
193
|
+
stream->setVolume(volume);
|
194
|
+
}
|
195
|
+
|
196
|
+
void Gosu::SampleInstance::changePan(double pan)
|
197
|
+
{
|
198
|
+
if (OutputStreamPtr stream = streams.get(handle, extra))
|
199
|
+
stream->setPan(clamp<float>(pan, -1.f, +1.f));
|
200
|
+
}
|
201
|
+
|
202
|
+
void Gosu::SampleInstance::changeSpeed(double speed)
|
203
|
+
{
|
204
|
+
if (OutputStreamPtr stream = streams.get(handle, extra))
|
205
|
+
stream->setPitchShift(clamp<float>(speed, 0.5f, 2.0f));
|
206
|
+
}
|
207
|
+
|
208
|
+
struct Gosu::Sample::SampleData : boost::noncopyable
|
209
|
+
{
|
210
|
+
SampleBufferPtr buffer;
|
211
|
+
};
|
212
|
+
|
213
|
+
Gosu::Sample::Sample(const std::wstring& filename)
|
214
|
+
: data(new SampleData)
|
215
|
+
{
|
216
|
+
device(); // Implicitly open audio device
|
217
|
+
|
218
|
+
SampleSourcePtr source = OpenSampleSource(MemoryBuffer(filename), FF_AUTODETECT);
|
219
|
+
data->buffer = CreateSampleBuffer(source);
|
220
|
+
}
|
221
|
+
|
222
|
+
Gosu::Sample::Sample(Reader reader)
|
223
|
+
{
|
224
|
+
device(); // Implicitly open audio device
|
225
|
+
|
226
|
+
SampleSourcePtr source = audiere::OpenSampleSource(MemoryBuffer(reader), FF_AUTODETECT);
|
227
|
+
data->buffer = CreateSampleBuffer(source);
|
228
|
+
}
|
229
|
+
|
230
|
+
Gosu::SampleInstance Gosu::Sample::play(double volume, double speed,
|
231
|
+
bool looping) const
|
232
|
+
{
|
233
|
+
OutputStreamPtr stream = device()->openStream(data->buffer->openStream());
|
234
|
+
int handle, extra;
|
235
|
+
streams.put(stream, handle, extra);
|
236
|
+
|
237
|
+
SampleInstance instance(handle, extra);
|
238
|
+
instance.changeVolume(volume);
|
239
|
+
instance.changeSpeed(speed);
|
240
|
+
stream->setRepeat(looping);
|
241
|
+
stream->play();
|
242
|
+
return instance;
|
243
|
+
}
|
244
|
+
|
245
|
+
Gosu::SampleInstance Gosu::Sample::playPan(double pan, double volume,
|
246
|
+
double speed, bool looping) const
|
247
|
+
{
|
248
|
+
OutputStreamPtr stream = device()->openStream(data->buffer->openStream());
|
249
|
+
int handle, extra;
|
250
|
+
streams.put(stream, handle, extra);
|
251
|
+
|
252
|
+
SampleInstance instance(handle, extra);
|
253
|
+
instance.changePan(pan);
|
254
|
+
instance.changeVolume(volume);
|
255
|
+
instance.changeSpeed(speed);
|
256
|
+
stream->setRepeat(looping);
|
257
|
+
stream->play();
|
258
|
+
return instance;
|
259
|
+
}
|
260
|
+
|
261
|
+
class Gosu::Song::BaseData : boost::noncopyable
|
262
|
+
{
|
263
|
+
double volume_;
|
264
|
+
|
265
|
+
protected:
|
266
|
+
BaseData() : volume_(1) {}
|
267
|
+
virtual void applyVolume() = 0;
|
268
|
+
|
269
|
+
public:
|
270
|
+
virtual ~BaseData() {}
|
271
|
+
|
272
|
+
virtual void play(bool looping) = 0;
|
273
|
+
virtual bool playing() const = 0;
|
274
|
+
virtual void pause() = 0;
|
275
|
+
virtual void stop() = 0;
|
276
|
+
|
277
|
+
double volume() const
|
278
|
+
{
|
279
|
+
return volume_;
|
280
|
+
}
|
281
|
+
|
282
|
+
void changeVolume(double volume)
|
283
|
+
{
|
284
|
+
volume_ = clamp(volume, 0.0, 1.0);
|
285
|
+
applyVolume();
|
286
|
+
}
|
287
|
+
};
|
288
|
+
|
289
|
+
class Gosu::Song::StreamData : public BaseData
|
290
|
+
{
|
291
|
+
MemoryBuffer buffer;
|
292
|
+
OutputStreamPtr stream;
|
293
|
+
SampleInstance instance;
|
294
|
+
bool loop;
|
295
|
+
|
296
|
+
void init()
|
297
|
+
{
|
298
|
+
int handle, extra;
|
299
|
+
stream = OpenSound(device(), buffer, true);
|
300
|
+
streams.put(stream, handle, extra);
|
301
|
+
instance = SampleInstance(handle, extra);
|
302
|
+
loop = false;
|
303
|
+
}
|
304
|
+
|
305
|
+
public:
|
306
|
+
StreamData(Gosu::Reader reader)
|
307
|
+
: buffer(reader), instance(-1, -1)
|
308
|
+
{
|
309
|
+
init();
|
310
|
+
}
|
311
|
+
|
312
|
+
StreamData(const std::wstring& filename)
|
313
|
+
: buffer(filename), instance(-1, -1)
|
314
|
+
{
|
315
|
+
init();
|
316
|
+
}
|
317
|
+
|
318
|
+
void play(bool looping)
|
319
|
+
{
|
320
|
+
applyVolume();
|
321
|
+
if (looping != loop)
|
322
|
+
stream->setRepeat(loop = looping);
|
323
|
+
stream->play();
|
324
|
+
}
|
325
|
+
|
326
|
+
bool playing() const
|
327
|
+
{
|
328
|
+
return instance.playing();
|
329
|
+
}
|
330
|
+
|
331
|
+
void pause()
|
332
|
+
{
|
333
|
+
instance.pause();
|
334
|
+
}
|
335
|
+
|
336
|
+
void stop()
|
337
|
+
{
|
338
|
+
instance.pause();
|
339
|
+
stream->reset();
|
340
|
+
}
|
341
|
+
|
342
|
+
void applyVolume()
|
343
|
+
{
|
344
|
+
instance.changeVolume(volume());
|
345
|
+
}
|
346
|
+
};
|
347
|
+
|
348
|
+
Gosu::Song::Song(const std::wstring& filename)
|
349
|
+
: data(new StreamData(filename))
|
350
|
+
{
|
351
|
+
}
|
352
|
+
|
353
|
+
Gosu::Song::Song(Reader reader)
|
354
|
+
: data(new StreamData(reader))
|
355
|
+
{
|
356
|
+
}
|
357
|
+
|
358
|
+
Gosu::Song::~Song()
|
359
|
+
{
|
360
|
+
}
|
361
|
+
|
362
|
+
Gosu::Song* Gosu::Song::currentSong()
|
363
|
+
{
|
364
|
+
if (curSong)
|
365
|
+
return curSong;
|
366
|
+
return 0;
|
367
|
+
}
|
368
|
+
|
369
|
+
void Gosu::Song::play(bool looping)
|
370
|
+
{
|
371
|
+
if (Gosu::Song* cur = currentSong())
|
372
|
+
if (cur != this)
|
373
|
+
{
|
374
|
+
cur->stop();
|
375
|
+
assert (currentSong() == 0);
|
376
|
+
}
|
377
|
+
|
378
|
+
data->play(looping); // May be redundant
|
379
|
+
curSong = this; // May be redundant
|
380
|
+
}
|
381
|
+
|
382
|
+
void Gosu::Song::pause()
|
383
|
+
{
|
384
|
+
if (curSong == this && data->playing())
|
385
|
+
data->pause();
|
386
|
+
}
|
387
|
+
|
388
|
+
bool Gosu::Song::paused() const
|
389
|
+
{
|
390
|
+
return curSong == this && !data->playing();
|
391
|
+
}
|
392
|
+
|
393
|
+
void Gosu::Song::stop()
|
394
|
+
{
|
395
|
+
if (curSong == this)
|
396
|
+
{
|
397
|
+
data->stop();
|
398
|
+
curSong = 0;
|
399
|
+
}
|
400
|
+
}
|
401
|
+
|
402
|
+
bool Gosu::Song::playing() const
|
403
|
+
{
|
404
|
+
assert (!(curSong != this && data->playing()));
|
405
|
+
return data->playing();
|
406
|
+
}
|
407
|
+
|
408
|
+
double Gosu::Song::volume() const
|
409
|
+
{
|
410
|
+
return data->volume();
|
411
|
+
}
|
412
|
+
|
413
|
+
void Gosu::Song::changeVolume(double volume)
|
414
|
+
{
|
415
|
+
data->changeVolume(volume);
|
416
|
+
}
|
417
|
+
|
418
|
+
void Gosu::Song::update()
|
419
|
+
{
|
420
|
+
device()->update();
|
421
|
+
}
|
422
|
+
|
423
|
+
// Deprecated constructors.
|
424
|
+
|
425
|
+
Gosu::Sample::Sample(Audio& audio, const std::wstring& filename)
|
426
|
+
{
|
427
|
+
Sample(filename).data.swap(data);
|
428
|
+
}
|
429
|
+
|
430
|
+
Gosu::Sample::Sample(Audio& audio, Reader reader)
|
431
|
+
{
|
432
|
+
Sample(reader).data.swap(data);
|
433
|
+
}
|
434
|
+
|
435
|
+
Gosu::Song::Song(Audio& audio, const std::wstring& filename)
|
436
|
+
{
|
437
|
+
Song(filename).data.swap(data);
|
438
|
+
}
|
439
|
+
|
440
|
+
Gosu::Song::Song(Audio& audio, Type type, Reader reader)
|
441
|
+
{
|
442
|
+
Song(reader).data.swap(data);
|
443
|
+
}
|
@@ -506,7 +506,7 @@ Gosu::Song::Song(const std::wstring& filename)
|
|
506
506
|
}
|
507
507
|
}
|
508
508
|
|
509
|
-
Gosu::Song::Song(
|
509
|
+
Gosu::Song::Song(Reader reader)
|
510
510
|
{
|
511
511
|
CONSTRUCTOR_COMMON;
|
512
512
|
|
@@ -601,5 +601,5 @@ Gosu::Song::Song(Audio& audio, const std::wstring& filename)
|
|
601
601
|
|
602
602
|
Gosu::Song::Song(Audio& audio, Type type, Reader reader)
|
603
603
|
{
|
604
|
-
Song(
|
604
|
+
Song(reader).data.swap(data);
|
605
605
|
}
|
data/GosuImpl/Audio/AudioSDL.cpp
CHANGED
data/GosuImpl/Graphics/Color.cpp
CHANGED
@@ -53,7 +53,7 @@ Gosu::Color Gosu::Color::fromAHSV(Channel alpha, double h, double s, double v)
|
|
53
53
|
return Color(alpha, v * 255, v * 255, v * 255);
|
54
54
|
|
55
55
|
// Normalize hue
|
56
|
-
h = (
|
56
|
+
h = normalizeAngle(h);
|
57
57
|
|
58
58
|
int sector = h / 60;
|
59
59
|
double factorial = h / 60 - sector;
|
@@ -8,6 +8,14 @@
|
|
8
8
|
|
9
9
|
Gosu::Window& windowInstance();
|
10
10
|
|
11
|
+
namespace Gosu
|
12
|
+
{
|
13
|
+
namespace FPS
|
14
|
+
{
|
15
|
+
void registerFrame();
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
11
19
|
int Gosu::clipRectBaseFactor()
|
12
20
|
{
|
13
21
|
static int result = 0;
|
@@ -46,7 +54,6 @@ int Gosu::clipRectBaseFactor()
|
|
46
54
|
|
47
55
|
@end
|
48
56
|
|
49
|
-
|
50
57
|
@implementation GosuView
|
51
58
|
|
52
59
|
@synthesize context;
|
@@ -78,6 +85,8 @@ int Gosu::clipRectBaseFactor()
|
|
78
85
|
if (not windowInstance().needsRedraw())
|
79
86
|
return;
|
80
87
|
|
88
|
+
Gosu::FPS::registerFrame();
|
89
|
+
|
81
90
|
[EAGLContext setCurrentContext:context];
|
82
91
|
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
|
83
92
|
glViewport(0, 0, backingWidth, backingHeight);
|
@@ -0,0 +1,27 @@
|
|
1
|
+
#include <Gosu/Inspection.hpp>
|
2
|
+
#include <Gosu/Timing.hpp>
|
3
|
+
|
4
|
+
namespace Gosu
|
5
|
+
{
|
6
|
+
namespace FPS
|
7
|
+
{
|
8
|
+
int fps, accum, sec;
|
9
|
+
|
10
|
+
void registerFrame()
|
11
|
+
{
|
12
|
+
++accum;
|
13
|
+
int newSec = Gosu::milliseconds() / 1000;
|
14
|
+
if (sec != newSec)
|
15
|
+
{
|
16
|
+
sec = newSec;
|
17
|
+
fps = accum;
|
18
|
+
accum = 0;
|
19
|
+
}
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
int fps()
|
24
|
+
{
|
25
|
+
return FPS::fps;
|
26
|
+
}
|
27
|
+
}
|
data/GosuImpl/RubyGosu.swg
CHANGED
@@ -158,6 +158,7 @@
|
|
158
158
|
#include <Gosu/Graphics.hpp>
|
159
159
|
#include <Gosu/Image.hpp>
|
160
160
|
#include <Gosu/ImageData.hpp>
|
161
|
+
#include <Gosu/Inspection.hpp>
|
161
162
|
#include <Gosu/Input.hpp>
|
162
163
|
#include <Gosu/IO.hpp>
|
163
164
|
#include <Gosu/Math.hpp>
|
@@ -501,6 +502,11 @@ namespace Gosu {
|
|
501
502
|
}
|
502
503
|
}
|
503
504
|
|
505
|
+
// Inspection:
|
506
|
+
|
507
|
+
%include "../Gosu/Inspection.hpp"
|
508
|
+
|
509
|
+
|
504
510
|
// Audio:
|
505
511
|
|
506
512
|
%ignore Gosu::Audio;
|
@@ -510,7 +516,7 @@ namespace Gosu {
|
|
510
516
|
%ignore Gosu::Sample::Sample(Reader reader);
|
511
517
|
%ignore Gosu::Song::Song(Audio& audio, const std::wstring& filename);
|
512
518
|
%ignore Gosu::Song::Song(Audio& audio, Type type, Reader reader);
|
513
|
-
%ignore Gosu::Song::Song(
|
519
|
+
%ignore Gosu::Song::Song(Reader reader);
|
514
520
|
%rename("playing?") playing;
|
515
521
|
%rename("paused?") paused;
|
516
522
|
%rename("volume=") changeVolume;
|
@@ -4,8 +4,9 @@ using namespace std;
|
|
4
4
|
|
5
5
|
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
6
6
|
{
|
7
|
-
// Append .so parent folder to PATH to make extensions (e.g.
|
8
|
-
|
7
|
+
// Append .so parent folder to PATH to make extensions (e.g. audiere.dll) loadable.
|
8
|
+
// TODO: This sounds like a risky thing wrt security, but does this matter?
|
9
|
+
|
9
10
|
if (fdwReason == DLL_PROCESS_ATTACH)
|
10
11
|
{
|
11
12
|
TCHAR buffer[MAX_PATH+1];
|