rubygame 2.2.0-i586-linux
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.
- data/CREDITS +60 -0
- data/LICENSE +504 -0
- data/NEWS +201 -0
- data/README +139 -0
- data/ROADMAP +43 -0
- data/Rakefile +409 -0
- data/doc/extended_readme.rdoc +49 -0
- data/doc/getting_started.rdoc +47 -0
- data/doc/macosx_install.rdoc +70 -0
- data/doc/windows_install.rdoc +123 -0
- data/ext/rubygame/MANIFEST +25 -0
- data/ext/rubygame/rubygame_core.so +0 -0
- data/ext/rubygame/rubygame_event.c +644 -0
- data/ext/rubygame/rubygame_event.h +48 -0
- data/ext/rubygame/rubygame_event.o +0 -0
- data/ext/rubygame/rubygame_gfx.c +942 -0
- data/ext/rubygame/rubygame_gfx.h +101 -0
- data/ext/rubygame/rubygame_gfx.o +0 -0
- data/ext/rubygame/rubygame_gfx.so +0 -0
- data/ext/rubygame/rubygame_gl.c +154 -0
- data/ext/rubygame/rubygame_gl.h +32 -0
- data/ext/rubygame/rubygame_gl.o +0 -0
- data/ext/rubygame/rubygame_image.c +108 -0
- data/ext/rubygame/rubygame_image.h +41 -0
- data/ext/rubygame/rubygame_image.o +0 -0
- data/ext/rubygame/rubygame_image.so +0 -0
- data/ext/rubygame/rubygame_joystick.c +247 -0
- data/ext/rubygame/rubygame_joystick.h +41 -0
- data/ext/rubygame/rubygame_joystick.o +0 -0
- data/ext/rubygame/rubygame_main.c +155 -0
- data/ext/rubygame/rubygame_main.h +33 -0
- data/ext/rubygame/rubygame_main.o +0 -0
- data/ext/rubygame/rubygame_mixer.c +764 -0
- data/ext/rubygame/rubygame_mixer.h +62 -0
- data/ext/rubygame/rubygame_mixer.o +0 -0
- data/ext/rubygame/rubygame_mixer.so +0 -0
- data/ext/rubygame/rubygame_screen.c +448 -0
- data/ext/rubygame/rubygame_screen.h +43 -0
- data/ext/rubygame/rubygame_screen.o +0 -0
- data/ext/rubygame/rubygame_shared.c +209 -0
- data/ext/rubygame/rubygame_shared.h +60 -0
- data/ext/rubygame/rubygame_shared.o +0 -0
- data/ext/rubygame/rubygame_surface.c +1147 -0
- data/ext/rubygame/rubygame_surface.h +62 -0
- data/ext/rubygame/rubygame_surface.o +0 -0
- data/ext/rubygame/rubygame_time.c +183 -0
- data/ext/rubygame/rubygame_time.h +32 -0
- data/ext/rubygame/rubygame_time.o +0 -0
- data/ext/rubygame/rubygame_ttf.c +599 -0
- data/ext/rubygame/rubygame_ttf.h +69 -0
- data/ext/rubygame/rubygame_ttf.o +0 -0
- data/ext/rubygame/rubygame_ttf.so +0 -0
- data/lib/rubygame/MANIFEST +12 -0
- data/lib/rubygame/clock.rb +128 -0
- data/lib/rubygame/color/models/base.rb +106 -0
- data/lib/rubygame/color/models/hsl.rb +153 -0
- data/lib/rubygame/color/models/hsv.rb +149 -0
- data/lib/rubygame/color/models/rgb.rb +78 -0
- data/lib/rubygame/color/palettes/css.rb +49 -0
- data/lib/rubygame/color/palettes/palette.rb +100 -0
- data/lib/rubygame/color/palettes/x11.rb +177 -0
- data/lib/rubygame/color.rb +79 -0
- data/lib/rubygame/constants.rb +238 -0
- data/lib/rubygame/event.rb +313 -0
- data/lib/rubygame/ftor.rb +370 -0
- data/lib/rubygame/hotspot.rb +265 -0
- data/lib/rubygame/keyconstants.rb +237 -0
- data/lib/rubygame/mediabag.rb +94 -0
- data/lib/rubygame/queue.rb +288 -0
- data/lib/rubygame/rect.rb +612 -0
- data/lib/rubygame/sfont.rb +223 -0
- data/lib/rubygame/sprite.rb +511 -0
- data/lib/rubygame.rb +41 -0
- data/samples/FreeSans.ttf +0 -0
- data/samples/GPL.txt +340 -0
- data/samples/README +40 -0
- data/samples/chimp.bmp +0 -0
- data/samples/chimp.rb +313 -0
- data/samples/demo_gl.rb +151 -0
- data/samples/demo_gl_tex.rb +197 -0
- data/samples/demo_music.rb +75 -0
- data/samples/demo_rubygame.rb +284 -0
- data/samples/demo_sfont.rb +52 -0
- data/samples/demo_ttf.rb +193 -0
- data/samples/demo_utf8.rb +53 -0
- data/samples/fist.bmp +0 -0
- data/samples/load_and_blit.rb +22 -0
- data/samples/panda.png +0 -0
- data/samples/punch.wav +0 -0
- data/samples/ruby.png +0 -0
- data/samples/song.ogg +0 -0
- data/samples/term16.png +0 -0
- data/samples/whiff.wav +0 -0
- metadata +152 -0
@@ -0,0 +1,764 @@
|
|
1
|
+
/*
|
2
|
+
* Interface to SDL_mixer, for audio playback and mixing.
|
3
|
+
*--
|
4
|
+
* Rubygame -- Ruby code and bindings to SDL to facilitate game creation
|
5
|
+
* Copyright (C) 2004-2007 John Croisant
|
6
|
+
*
|
7
|
+
* This library is free software; you can redistribute it and/or
|
8
|
+
* modify it under the terms of the GNU Lesser General Public
|
9
|
+
* License as published by the Free Software Foundation; either
|
10
|
+
* version 2.1 of the License, or (at your option) any later version.
|
11
|
+
*
|
12
|
+
* This library is distributed in the hope that it will be useful,
|
13
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15
|
+
* Lesser General Public License for more details.
|
16
|
+
*
|
17
|
+
* You should have received a copy of the GNU Lesser General Public
|
18
|
+
* License along with this library; if not, write to the Free Software
|
19
|
+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
20
|
+
*++
|
21
|
+
*/
|
22
|
+
|
23
|
+
#include "rubygame_shared.h"
|
24
|
+
#include "rubygame_mixer.h"
|
25
|
+
|
26
|
+
void Init_rubygame_mixer();
|
27
|
+
VALUE mMixer;
|
28
|
+
|
29
|
+
VALUE rbgm_mixer_openaudio(int, VALUE*, VALUE);
|
30
|
+
VALUE rbgm_mixer_closeaudio(VALUE);
|
31
|
+
VALUE rbgm_mixer_getmixchans();
|
32
|
+
VALUE rbgm_mixer_setmixchans(VALUE, VALUE);
|
33
|
+
VALUE rbgm_mixer_getdrivername(VALUE);
|
34
|
+
|
35
|
+
VALUE cSample;
|
36
|
+
VALUE rbgm_sample_new(VALUE, VALUE);
|
37
|
+
VALUE rbgm_mixchan_play( VALUE, VALUE, VALUE, VALUE );
|
38
|
+
VALUE rbgm_mixchan_stop( VALUE, VALUE );
|
39
|
+
VALUE rbgm_mixchan_pause( VALUE, VALUE );
|
40
|
+
VALUE rbgm_mixchan_resume( VALUE, VALUE );
|
41
|
+
|
42
|
+
VALUE cMusic;
|
43
|
+
VALUE rbgm_mixmusic_setcommand(VALUE, VALUE);
|
44
|
+
VALUE rbgm_mixmusic_new(VALUE, VALUE);
|
45
|
+
|
46
|
+
VALUE rbgm_mixmusic_play(int, VALUE*, VALUE);
|
47
|
+
VALUE rbgm_mixmusic_stop(VALUE);
|
48
|
+
VALUE rbgm_mixmusic_resume(VALUE);
|
49
|
+
VALUE rbgm_mixmusic_pause(VALUE);
|
50
|
+
VALUE rbgm_mixmusic_rewind(VALUE);
|
51
|
+
VALUE rbgm_mixmusic_jump(VALUE, VALUE);
|
52
|
+
VALUE rbgm_mixmusic_paused(VALUE);
|
53
|
+
VALUE rbgm_mixmusic_playing(VALUE);
|
54
|
+
|
55
|
+
VALUE rbgm_mixmusic_getvolume(VALUE);
|
56
|
+
VALUE rbgm_mixmusic_setvolume(VALUE, VALUE);
|
57
|
+
VALUE rbgm_mixmusic_fadein(int, VALUE*, VALUE);
|
58
|
+
VALUE rbgm_mixmusic_fadeout(VALUE, VALUE);
|
59
|
+
VALUE rbgm_mixmusic_fading(int, VALUE*, VALUE);
|
60
|
+
|
61
|
+
|
62
|
+
/* --
|
63
|
+
* SETUP AND INITIALIZATION
|
64
|
+
* ++
|
65
|
+
*/
|
66
|
+
|
67
|
+
/* call-seq:
|
68
|
+
* open_audio( frequency=nil, format=nil, channels=nil, buffer=nil)
|
69
|
+
*
|
70
|
+
* Initializes the audio device. You must call this before using the other
|
71
|
+
* mixer functions. See also #close_audio().
|
72
|
+
*
|
73
|
+
* Returns nil. May raise an SDLError if initialization fails.
|
74
|
+
*
|
75
|
+
* This method takes these arguments:
|
76
|
+
*
|
77
|
+
* frequency:: output sample rate in audio samples per second (Hz).
|
78
|
+
* Affects the quality of the sound output, at the expense of
|
79
|
+
* CPU usage. If nil, the default (22050) is used. 22050 is
|
80
|
+
* recommended for most games. For reference, 44100 is CD quality.
|
81
|
+
* The larger the value, the more processing required.
|
82
|
+
*
|
83
|
+
* format:: output sample format. If nil, the default recommended system
|
84
|
+
* format is used. It's _highly_ recommended you leave this nil!
|
85
|
+
*
|
86
|
+
* But if you're feeling reckless, you can use one of these
|
87
|
+
* constants located in the Rubygame::Mixer module:
|
88
|
+
*
|
89
|
+
* AUDIO_U16SYS:: unsigned 16-bit samples.
|
90
|
+
* AUDIO_S16SYS:: signed 16-bit samples.
|
91
|
+
* AUDIO_U8:: unsigned 8-bit samples.
|
92
|
+
* AUDIO_S8:: signed 8-bit samples.
|
93
|
+
*
|
94
|
+
* channels:: output sound channels. Use 2 for stereo, 1 for mono.
|
95
|
+
* If nil, the default (2) is used.
|
96
|
+
* This option is not related to mixing channels.
|
97
|
+
*
|
98
|
+
* buffer:: size of the sound buffer, in bytes. If nil, the default (1024)
|
99
|
+
* is used. Larger values have more delay before playing a
|
100
|
+
* sound, but require less CPU usage (and have less skipping
|
101
|
+
* on slow systems).
|
102
|
+
*
|
103
|
+
*/
|
104
|
+
VALUE rbgm_mixer_openaudio(int argc, VALUE *argv, VALUE module)
|
105
|
+
{
|
106
|
+
VALUE vfreq, vformat, vchannels, vbuffer;
|
107
|
+
int freq = MIX_DEFAULT_FREQUENCY;
|
108
|
+
Uint16 format = MIX_DEFAULT_FORMAT;
|
109
|
+
int channels = 2;
|
110
|
+
int buffer = 1024;
|
111
|
+
|
112
|
+
rb_scan_args(argc, argv, "04", &vfreq, &vformat, &vchannels, &vbuffer);
|
113
|
+
|
114
|
+
if( RTEST(vfreq) )
|
115
|
+
{
|
116
|
+
freq = NUM2INT(vfreq);
|
117
|
+
}
|
118
|
+
|
119
|
+
if( RTEST(vformat) )
|
120
|
+
{
|
121
|
+
format = NUM2UINT(vformat);
|
122
|
+
}
|
123
|
+
|
124
|
+
if( RTEST(vchannels) )
|
125
|
+
{
|
126
|
+
channels = NUM2INT(vchannels);
|
127
|
+
}
|
128
|
+
|
129
|
+
if( RTEST(vbuffer) )
|
130
|
+
{
|
131
|
+
buffer = NUM2INT(vbuffer);
|
132
|
+
}
|
133
|
+
|
134
|
+
if ( Mix_OpenAudio(freq, format, channels, buffer) < 0 )
|
135
|
+
{
|
136
|
+
rb_raise(eSDLError, "Error initializing SDL_mixer: %s", Mix_GetError());
|
137
|
+
}
|
138
|
+
|
139
|
+
return Qnil;
|
140
|
+
}
|
141
|
+
|
142
|
+
/* call-seq:
|
143
|
+
* close_audio()
|
144
|
+
*
|
145
|
+
* Close the audio device being used by the mixer. You should not use any
|
146
|
+
* mixer functions after this function, unless you use #open_audio() to
|
147
|
+
* re-open the audio device. See also #open_audio().
|
148
|
+
*
|
149
|
+
* Returns nil.
|
150
|
+
*/
|
151
|
+
VALUE rbgm_mixer_closeaudio(VALUE module)
|
152
|
+
{
|
153
|
+
Mix_CloseAudio();
|
154
|
+
return Qnil;
|
155
|
+
}
|
156
|
+
|
157
|
+
/* call-seq:
|
158
|
+
* #mix_channels() -> integer
|
159
|
+
*
|
160
|
+
* Returns the number of mixing channels currently allocated.
|
161
|
+
* See also #mix_channels=().
|
162
|
+
*/
|
163
|
+
VALUE rbgm_mixer_getmixchans(VALUE module)
|
164
|
+
{
|
165
|
+
int result;
|
166
|
+
result = Mix_AllocateChannels(-1);
|
167
|
+
|
168
|
+
return INT2NUM(result);
|
169
|
+
}
|
170
|
+
|
171
|
+
/* call-seq:
|
172
|
+
* #mix_channels = num_channels
|
173
|
+
*
|
174
|
+
* Set the number of mixer channels, allocating or deallocating channels as
|
175
|
+
* needed. This can be called many times, even during audio playback. If this
|
176
|
+
* call reduces the number of channels allocated, the excess channels will
|
177
|
+
* be stopped automatically. See also #mix_channels()
|
178
|
+
*
|
179
|
+
* Returns the number of mixing channels allocated.
|
180
|
+
*
|
181
|
+
* Note that 8 mixing channels are allocated when #open_audio() is called.
|
182
|
+
* This method only needs to be called if you want a different number (either
|
183
|
+
* greater or fewer) of mixing channels.
|
184
|
+
*
|
185
|
+
* This method takes this argument:
|
186
|
+
* num_channels:: desired number of mixing channels, an integer.
|
187
|
+
* Negative values will cause this method to behave as
|
188
|
+
* #mix_channels(), returning the number of channels currently
|
189
|
+
* allocated, without changing it.
|
190
|
+
*/
|
191
|
+
VALUE rbgm_mixer_setmixchans(VALUE module, VALUE channelsv)
|
192
|
+
{
|
193
|
+
int desired;
|
194
|
+
int allocated;
|
195
|
+
|
196
|
+
desired = NUM2INT(channelsv);
|
197
|
+
allocated = Mix_AllocateChannels(desired);
|
198
|
+
|
199
|
+
return INT2NUM(allocated);
|
200
|
+
}
|
201
|
+
|
202
|
+
/* call-seq:
|
203
|
+
* driver_name -> string
|
204
|
+
*
|
205
|
+
* Returns the name of the audio driver that SDL is using.
|
206
|
+
*
|
207
|
+
* May raise an SDLError if initialization fails.
|
208
|
+
*/
|
209
|
+
|
210
|
+
VALUE rbgm_mixer_getdrivername(VALUE module)
|
211
|
+
{
|
212
|
+
char driver_name[1024];
|
213
|
+
if(SDL_AudioDriverName(driver_name, sizeof(driver_name)) == NULL)
|
214
|
+
{
|
215
|
+
rb_raise(eSDLError, "Error fetrching audio driver name: %s", SDL_GetError());
|
216
|
+
}
|
217
|
+
return rb_str_new2(driver_name);
|
218
|
+
}
|
219
|
+
|
220
|
+
|
221
|
+
|
222
|
+
/* --
|
223
|
+
* SAMPLES
|
224
|
+
* ++
|
225
|
+
*/
|
226
|
+
|
227
|
+
/* call-seq:
|
228
|
+
* load_audio( filename ) -> Sample
|
229
|
+
*
|
230
|
+
* Load an audio sample (a "chunk", to use SDL_mixer's term) from a file.
|
231
|
+
* Only WAV files are supported at this time.
|
232
|
+
*
|
233
|
+
* Raises SDLError if the sample could not be loaded.
|
234
|
+
*/
|
235
|
+
VALUE rbgm_sample_new(VALUE class, VALUE filev)
|
236
|
+
{
|
237
|
+
VALUE self;
|
238
|
+
Mix_Chunk* sample;
|
239
|
+
|
240
|
+
sample = Mix_LoadWAV( StringValuePtr(filev) );
|
241
|
+
|
242
|
+
if( sample == NULL )
|
243
|
+
{
|
244
|
+
rb_raise(eSDLError, "Error loading audio Sample from file `%s': %s",
|
245
|
+
StringValuePtr(filev), Mix_GetError());
|
246
|
+
}
|
247
|
+
self = Data_Wrap_Struct( cSample, 0, Mix_FreeChunk, sample );
|
248
|
+
|
249
|
+
//rb_obj_call_init(self,argc,argv);
|
250
|
+
|
251
|
+
return self;
|
252
|
+
}
|
253
|
+
|
254
|
+
/* call-seq:
|
255
|
+
* play(sample, channel_num, repeats ) -> integer
|
256
|
+
*
|
257
|
+
* Play an audio Sample on a mixing channel, repeating a certain number
|
258
|
+
* of extra times. Returns the number of the channel that the sample
|
259
|
+
* is being played on.
|
260
|
+
*
|
261
|
+
* Raises SDLError if something goes wrong.
|
262
|
+
*
|
263
|
+
* This method takes these arguments:
|
264
|
+
* sample:: what Sample to play
|
265
|
+
* channel_num:: which mixing channel to play the sample on.
|
266
|
+
* Use -1 to play on the first unreserved channel.
|
267
|
+
* repeats:: how many extra times to repeat the sample.
|
268
|
+
* Can be -1 to repeat forever until it is stopped.
|
269
|
+
*/
|
270
|
+
VALUE rbgm_mixchan_play( VALUE self, VALUE samplev, VALUE chanv, VALUE loopsv )
|
271
|
+
{
|
272
|
+
Mix_Chunk* sample;
|
273
|
+
int loops, channel, result;
|
274
|
+
|
275
|
+
channel = NUM2INT(chanv);
|
276
|
+
Data_Get_Struct( samplev, Mix_Chunk, sample );
|
277
|
+
loops = NUM2INT(loopsv);
|
278
|
+
|
279
|
+
result = Mix_PlayChannel(channel, sample, loops);
|
280
|
+
|
281
|
+
if ( result < 0 )
|
282
|
+
{
|
283
|
+
rb_raise(eSDLError, "Error playing sample on channel %d: %s",
|
284
|
+
channel, Mix_GetError());
|
285
|
+
}
|
286
|
+
|
287
|
+
return INT2NUM( result );
|
288
|
+
}
|
289
|
+
|
290
|
+
/* call-seq:
|
291
|
+
* stop( channel_num )
|
292
|
+
*
|
293
|
+
* Stop playback of a playing or paused mixing channel.
|
294
|
+
* Unlike #pause, playback cannot be resumed from the current point.
|
295
|
+
* See also #play.
|
296
|
+
*/
|
297
|
+
VALUE rbgm_mixchan_stop( VALUE self, VALUE chanv )
|
298
|
+
{
|
299
|
+
Mix_HaltChannel(NUM2INT(chanv));
|
300
|
+
return Qnil;
|
301
|
+
}
|
302
|
+
|
303
|
+
/* call-seq:
|
304
|
+
* pause( channel_num )
|
305
|
+
*
|
306
|
+
* Pause playback of a currently-playing mixing channel.
|
307
|
+
* Playback can be resumed from the current point with #resume.
|
308
|
+
* See also #stop.
|
309
|
+
*/
|
310
|
+
VALUE rbgm_mixchan_pause( VALUE self, VALUE chanv )
|
311
|
+
{
|
312
|
+
Mix_Pause(NUM2INT(chanv));
|
313
|
+
return Qnil;
|
314
|
+
}
|
315
|
+
|
316
|
+
/* call-seq:
|
317
|
+
* resume( channel_num )
|
318
|
+
*
|
319
|
+
* Resume playback of a paused mixing channel. The channel must have been
|
320
|
+
* paused (via the #pause method) for this to have any effect. Playback will
|
321
|
+
* resume from the point where the channel was paused.
|
322
|
+
*
|
323
|
+
*/
|
324
|
+
VALUE rbgm_mixchan_resume( VALUE self, VALUE chanv )
|
325
|
+
{
|
326
|
+
Mix_Resume(NUM2INT(chanv));
|
327
|
+
return Qnil;
|
328
|
+
}
|
329
|
+
|
330
|
+
|
331
|
+
/* --
|
332
|
+
* MUSIC
|
333
|
+
* ++
|
334
|
+
*/
|
335
|
+
|
336
|
+
/* call-seq:
|
337
|
+
* set_music_command(command) -> integer
|
338
|
+
*
|
339
|
+
* Sets the external command used to play music.
|
340
|
+
*
|
341
|
+
* Raises SDLError if something goes wrong.
|
342
|
+
*
|
343
|
+
* This method takes these arguments:
|
344
|
+
* command:: what command to use to play the music.
|
345
|
+
*
|
346
|
+
*/
|
347
|
+
VALUE rbgm_mixmusic_setcommand(VALUE class, VALUE commandv)
|
348
|
+
{
|
349
|
+
int result;
|
350
|
+
result = Mix_SetMusicCMD(StringValuePtr(commandv));
|
351
|
+
if( result < 0 )
|
352
|
+
{
|
353
|
+
rb_raise(eSDLError, "Error setting music player commando to `%s': %s",
|
354
|
+
StringValuePtr(commandv), Mix_GetError());
|
355
|
+
}
|
356
|
+
return INT2NUM( result );
|
357
|
+
}
|
358
|
+
|
359
|
+
/* call-seq:
|
360
|
+
* load_audio( filename ) -> Music
|
361
|
+
*
|
362
|
+
* Load music from a file. Supports WAVE, MOD, MIDI, OGG, and MP3 formats.
|
363
|
+
*
|
364
|
+
* Raises SDLError if the music could not be loaded.
|
365
|
+
*/
|
366
|
+
VALUE rbgm_mixmusic_new(VALUE class, VALUE filev)
|
367
|
+
{
|
368
|
+
VALUE self;
|
369
|
+
Mix_Music* music;
|
370
|
+
|
371
|
+
music = Mix_LoadMUS( StringValuePtr(filev) );
|
372
|
+
|
373
|
+
if( music == NULL )
|
374
|
+
{
|
375
|
+
rb_raise(eSDLError, "Error loading audio music from file `%s': %s",
|
376
|
+
StringValuePtr(filev), Mix_GetError());
|
377
|
+
}
|
378
|
+
self = Data_Wrap_Struct( cMusic, 0, Mix_FreeMusic, music );
|
379
|
+
|
380
|
+
//rb_obj_call_init(self,argc,argv);
|
381
|
+
|
382
|
+
return self;
|
383
|
+
}
|
384
|
+
|
385
|
+
/* call-seq:
|
386
|
+
* play( repeats = 0 ) -> self
|
387
|
+
*
|
388
|
+
* Play music, repeating a certain number of extra times. If
|
389
|
+
* any music was already playing, that music will be stopped
|
390
|
+
* first, and this music will start.
|
391
|
+
*
|
392
|
+
* Raises SDLError if something goes wrong.
|
393
|
+
*
|
394
|
+
* This method takes these arguments:
|
395
|
+
* repeats:: how many extra times to play the music.
|
396
|
+
* Can be -1 to repeat forever until it is stopped.
|
397
|
+
*/
|
398
|
+
VALUE rbgm_mixmusic_play(int argc, VALUE *argv, VALUE self)
|
399
|
+
{
|
400
|
+
Mix_Music* music;
|
401
|
+
int reps, result;
|
402
|
+
VALUE repsv;
|
403
|
+
|
404
|
+
Data_Get_Struct( self, Mix_Music, music );
|
405
|
+
|
406
|
+
rb_scan_args(argc, argv, "01", &repsv);
|
407
|
+
|
408
|
+
if( RTEST(repsv) )
|
409
|
+
{
|
410
|
+
reps = NUM2INT(repsv);
|
411
|
+
}
|
412
|
+
else
|
413
|
+
{
|
414
|
+
reps = 0;
|
415
|
+
}
|
416
|
+
|
417
|
+
if( reps > -1 )
|
418
|
+
{
|
419
|
+
/* Adjust so repeats means the same as it does for Samples */
|
420
|
+
reps += 1;
|
421
|
+
}
|
422
|
+
|
423
|
+
result = Mix_PlayMusic(music, reps);
|
424
|
+
|
425
|
+
if ( result < 0 )
|
426
|
+
{
|
427
|
+
rb_raise(eSDLError, "Error playing music: %s",
|
428
|
+
Mix_GetError());
|
429
|
+
}
|
430
|
+
|
431
|
+
return self;
|
432
|
+
}
|
433
|
+
|
434
|
+
/* call-seq:
|
435
|
+
* stop() -> self
|
436
|
+
*
|
437
|
+
* Stop playback of music.
|
438
|
+
* See also #play
|
439
|
+
*/
|
440
|
+
VALUE rbgm_mixmusic_stop(VALUE self)
|
441
|
+
{
|
442
|
+
Mix_HaltMusic();
|
443
|
+
return self;
|
444
|
+
}
|
445
|
+
|
446
|
+
/* call-seq:
|
447
|
+
* pause() -> self
|
448
|
+
*
|
449
|
+
* Pause playback of the playing music. You can later #resume
|
450
|
+
* playback from the point where you paused.
|
451
|
+
* Safe to use on already-paused music.
|
452
|
+
* See also #play_music.
|
453
|
+
*/
|
454
|
+
VALUE rbgm_mixmusic_pause(VALUE self)
|
455
|
+
{
|
456
|
+
Mix_PauseMusic();
|
457
|
+
return self;
|
458
|
+
}
|
459
|
+
|
460
|
+
/* call-seq:
|
461
|
+
* resume() -> self
|
462
|
+
*
|
463
|
+
* Resume playback of paused music from the point it was paused.
|
464
|
+
* Safe to use on already-playing music.
|
465
|
+
* See also #play.
|
466
|
+
*/
|
467
|
+
VALUE rbgm_mixmusic_resume(VALUE self)
|
468
|
+
{
|
469
|
+
Mix_ResumeMusic();
|
470
|
+
return self;
|
471
|
+
}
|
472
|
+
|
473
|
+
/* call-seq:
|
474
|
+
* rewind() -> self
|
475
|
+
*
|
476
|
+
* Rewind the music to the start. This is safe to use on stopped, paused, and playing music.
|
477
|
+
* Only works for MOD, OGG, MP3, and MIDI (but not WAV).
|
478
|
+
*
|
479
|
+
*/
|
480
|
+
VALUE rbgm_mixmusic_rewind(VALUE self)
|
481
|
+
{
|
482
|
+
Mix_RewindMusic();
|
483
|
+
return self;
|
484
|
+
}
|
485
|
+
|
486
|
+
/* call-seq:
|
487
|
+
* jump( time ) -> self
|
488
|
+
*
|
489
|
+
* Jump to a certain time in the music.
|
490
|
+
* Only works when music is playing or paused (but not stopped).
|
491
|
+
* Only works for OGG and MP3 files.
|
492
|
+
*
|
493
|
+
* Raises SDLError if something goes wrong, or if the music type does not
|
494
|
+
* support setting the position.
|
495
|
+
*
|
496
|
+
* time:: Time to jump to, in seconds from the beginning.
|
497
|
+
*
|
498
|
+
*/
|
499
|
+
VALUE rbgm_mixmusic_jump(VALUE self, VALUE vtime)
|
500
|
+
{
|
501
|
+
double time = NUM2DBL(vtime);
|
502
|
+
|
503
|
+
switch( Mix_GetMusicType(NULL) )
|
504
|
+
{
|
505
|
+
case MUS_OGG:
|
506
|
+
case MUS_MP3:
|
507
|
+
Mix_RewindMusic(); // Needed for MP3, and OK with OGG
|
508
|
+
|
509
|
+
int result = Mix_SetMusicPosition(time);
|
510
|
+
if( result < 0 )
|
511
|
+
{
|
512
|
+
rb_raise(eSDLError, "Error jumping to time in music: %s", Mix_GetError());
|
513
|
+
}
|
514
|
+
|
515
|
+
return self;
|
516
|
+
|
517
|
+
case MUS_NONE:
|
518
|
+
rb_raise(eSDLError, "Cannot jump when no music is playing.");
|
519
|
+
|
520
|
+
default:
|
521
|
+
rb_raise(eSDLError, "Music type does not support jumping.");
|
522
|
+
}
|
523
|
+
}
|
524
|
+
|
525
|
+
/* call-seq:
|
526
|
+
* playing? -> true or false
|
527
|
+
*
|
528
|
+
* Returns true if the music is currently playing.
|
529
|
+
*
|
530
|
+
*/
|
531
|
+
VALUE rbgm_mixmusic_playing(VALUE self)
|
532
|
+
{
|
533
|
+
return Mix_PlayingMusic() ? Qtrue : Qfalse;
|
534
|
+
}
|
535
|
+
|
536
|
+
/* call-seq:
|
537
|
+
* paused? -> true or false
|
538
|
+
*
|
539
|
+
* Returns true if the music is currently paused.
|
540
|
+
*
|
541
|
+
*/
|
542
|
+
VALUE rbgm_mixmusic_paused(VALUE self)
|
543
|
+
{
|
544
|
+
return Mix_PausedMusic() ? Qtrue : Qfalse;
|
545
|
+
}
|
546
|
+
|
547
|
+
/* call-seq:
|
548
|
+
* volume
|
549
|
+
*
|
550
|
+
* Returns the current volume level of the music.
|
551
|
+
* 0.0 is total silence, 1.0 is maximum volume.
|
552
|
+
*/
|
553
|
+
VALUE rbgm_mixmusic_getvolume(VALUE self)
|
554
|
+
{
|
555
|
+
return rb_float_new( (double)(Mix_VolumeMusic(-1)) / MIX_MAX_VOLUME );
|
556
|
+
}
|
557
|
+
|
558
|
+
/* call-seq:
|
559
|
+
* volume = new_volume
|
560
|
+
*
|
561
|
+
* Sets the volume level of the music.
|
562
|
+
* 0.0 is total silence, 1.0 is maximum volume.
|
563
|
+
*/
|
564
|
+
VALUE rbgm_mixmusic_setvolume(VALUE self, VALUE volumev)
|
565
|
+
{
|
566
|
+
double volume = NUM2DBL(volumev);
|
567
|
+
Mix_VolumeMusic( (int)(volume * MIX_MAX_VOLUME) );
|
568
|
+
return volumev;
|
569
|
+
}
|
570
|
+
|
571
|
+
/* call-seq:
|
572
|
+
* fade_in( fade_time, repeats=0, start=0 ) -> self
|
573
|
+
*
|
574
|
+
* Play the music, fading in and repeating a certain number of times.
|
575
|
+
* See also #play.
|
576
|
+
*
|
577
|
+
* Raises SDLError if something goes wrong.
|
578
|
+
*
|
579
|
+
* fade_time:: Time in seconds for the fade-in effect to complete.
|
580
|
+
* repeats:: Number of extra times to play through the music.
|
581
|
+
* -1 plays the music forever until it is stopped.
|
582
|
+
* Defaults to 0, play only once (no repeats).
|
583
|
+
* start:: Time to start from, in seconds since the beginning.
|
584
|
+
* Defaults to 0, the beginning of the song.
|
585
|
+
* Non-zero values only work for OGG and MP3; other
|
586
|
+
* music types will raise SDLError.
|
587
|
+
*/
|
588
|
+
VALUE rbgm_mixmusic_fadein(int argc, VALUE *argv, VALUE self)
|
589
|
+
{
|
590
|
+
VALUE fadev, repsv, startv;
|
591
|
+
rb_scan_args(argc, argv, "12", &fadev, &repsv, &startv);
|
592
|
+
|
593
|
+
Mix_Music* music;
|
594
|
+
Data_Get_Struct( self, Mix_Music, music );
|
595
|
+
|
596
|
+
int fade, reps, result;
|
597
|
+
fade = (int)(NUM2DBL(fadev) * 1000); /* convert to milliseconds */
|
598
|
+
|
599
|
+
if( RTEST(repsv) )
|
600
|
+
{
|
601
|
+
reps = NUM2INT(repsv);
|
602
|
+
}
|
603
|
+
else
|
604
|
+
{
|
605
|
+
reps = 0;
|
606
|
+
}
|
607
|
+
|
608
|
+
if( reps > -1 )
|
609
|
+
{
|
610
|
+
/* Adjust so repeats means the same as it does for Samples */
|
611
|
+
reps += 1;
|
612
|
+
}
|
613
|
+
|
614
|
+
if( !RTEST(startv) || NUM2DBL(startv) == 0.0 )
|
615
|
+
{
|
616
|
+
result = Mix_FadeInMusic(music, reps, fade);
|
617
|
+
}
|
618
|
+
else
|
619
|
+
{
|
620
|
+
result = Mix_FadeInMusicPos(music, reps, fade, NUM2DBL(startv));
|
621
|
+
}
|
622
|
+
|
623
|
+
if( result < 0 )
|
624
|
+
{
|
625
|
+
rb_raise(eSDLError, "Error fading in music: %s", Mix_GetError());
|
626
|
+
}
|
627
|
+
|
628
|
+
return self;
|
629
|
+
}
|
630
|
+
|
631
|
+
/* call-seq:
|
632
|
+
* fade_out( fade_time ) -> self
|
633
|
+
*
|
634
|
+
* Gradually fade the music to silence over +fade_length+ seconds.
|
635
|
+
* After the fade is complete, the music will be automatically stopped.
|
636
|
+
*
|
637
|
+
* Raises SDLError if something goes wrong.
|
638
|
+
*
|
639
|
+
* fade_time:: Time until the music is totally silent, in seconds.
|
640
|
+
*/
|
641
|
+
VALUE rbgm_mixmusic_fadeout(VALUE self, VALUE fadev)
|
642
|
+
{
|
643
|
+
int fade = (int)(NUM2DBL(fadev) * 1000);
|
644
|
+
int result = Mix_FadeOutMusic(fade);
|
645
|
+
|
646
|
+
if ( result < 0 )
|
647
|
+
{
|
648
|
+
rb_raise(eSDLError, "Error fading out music: %s", Mix_GetError());
|
649
|
+
}
|
650
|
+
return self;
|
651
|
+
}
|
652
|
+
|
653
|
+
/* call-seq:
|
654
|
+
* fading?( direction = nil ) -> true or false
|
655
|
+
*
|
656
|
+
* True if the music is fading in or out (or either). You can
|
657
|
+
* specify +direction+ as :in/:out to check only fading in/out;
|
658
|
+
* otherwise, it will return true if it's fading either way.
|
659
|
+
*
|
660
|
+
* direction:: :in, :out, or nil if you don't care which.
|
661
|
+
* Returns:: true if the music is fading in the given direction.
|
662
|
+
*/
|
663
|
+
VALUE rbgm_mixmusic_fading(int argc, VALUE *argv, VALUE self)
|
664
|
+
{
|
665
|
+
VALUE dirv;
|
666
|
+
rb_scan_args(argc, argv, "01", &dirv);
|
667
|
+
|
668
|
+
if( dirv == make_symbol("in") )
|
669
|
+
{
|
670
|
+
return ( (Mix_FadingMusic() == MIX_FADING_IN) ? Qtrue : Qfalse );
|
671
|
+
}
|
672
|
+
else if( dirv == make_symbol("out") )
|
673
|
+
{
|
674
|
+
return ( (Mix_FadingMusic() == MIX_FADING_OUT) ? Qtrue : Qfalse );
|
675
|
+
}
|
676
|
+
else
|
677
|
+
{
|
678
|
+
return ( (Mix_FadingMusic() != MIX_NO_FADING) ? Qtrue : Qfalse );
|
679
|
+
}
|
680
|
+
}
|
681
|
+
|
682
|
+
|
683
|
+
void Init_rubygame_mixer()
|
684
|
+
{
|
685
|
+
|
686
|
+
#if 0
|
687
|
+
mRubygame = rb_define_module("Rubygame");
|
688
|
+
#endif
|
689
|
+
|
690
|
+
Init_rubygame_shared();
|
691
|
+
|
692
|
+
rb_hash_aset(rb_ivar_get(mRubygame,rb_intern("VERSIONS")),
|
693
|
+
ID2SYM(rb_intern("sdl_mixer")),
|
694
|
+
rb_ary_new3(3,
|
695
|
+
INT2NUM(SDL_MIXER_MAJOR_VERSION),
|
696
|
+
INT2NUM(SDL_MIXER_MINOR_VERSION),
|
697
|
+
INT2NUM(SDL_MIXER_PATCHLEVEL)));
|
698
|
+
|
699
|
+
/*
|
700
|
+
* The Mixer module provides access to the SDL_mixer library for audio
|
701
|
+
* playback and mixing. This module is still very basic, but it is
|
702
|
+
* good enough to load and play WAV files on multiple mix channels.
|
703
|
+
*
|
704
|
+
* See the Sample class for loading audio files.
|
705
|
+
* See the Music class for streaming music from a file.
|
706
|
+
*/
|
707
|
+
mMixer = rb_define_module_under(mRubygame, "Mixer");
|
708
|
+
|
709
|
+
rb_define_const(mMixer,"AUDIO_U8", INT2NUM(AUDIO_U8));
|
710
|
+
rb_define_const(mMixer,"AUDIO_S8", INT2NUM(AUDIO_S8));
|
711
|
+
rb_define_const(mMixer,"AUDIO_U16SYS", INT2NUM(AUDIO_U16SYS));
|
712
|
+
rb_define_const(mMixer,"AUDIO_S16SYS", INT2NUM(AUDIO_S16SYS));
|
713
|
+
|
714
|
+
rb_define_module_function(mMixer,"open_audio",rbgm_mixer_openaudio, -1);
|
715
|
+
rb_define_module_function(mMixer,"close_audio",rbgm_mixer_closeaudio, 0);
|
716
|
+
rb_define_module_function(mMixer,"mix_channels",rbgm_mixer_getmixchans, 0);
|
717
|
+
rb_define_module_function(mMixer,"mix_channels=",rbgm_mixer_setmixchans, 1);
|
718
|
+
rb_define_module_function(mMixer,"driver_name", rbgm_mixer_getdrivername, 0);
|
719
|
+
|
720
|
+
|
721
|
+
|
722
|
+
/* Stores audio data to play with Mixer.play() */
|
723
|
+
cSample = rb_define_class_under(mMixer, "Sample", rb_cObject);
|
724
|
+
rb_define_singleton_method(cSample, "load_audio", rbgm_sample_new, 1);
|
725
|
+
rb_define_module_function(mMixer,"play", rbgm_mixchan_play, 3);
|
726
|
+
rb_define_module_function(mMixer,"stop", rbgm_mixchan_stop, 1);
|
727
|
+
rb_define_module_function(mMixer,"pause", rbgm_mixchan_pause, 1);
|
728
|
+
rb_define_module_function(mMixer,"resume", rbgm_mixchan_resume, 1);
|
729
|
+
|
730
|
+
|
731
|
+
/* The Music class is used for playing music from a file. It supports
|
732
|
+
* WAVE, MOD, MIDI, OGG, and MP3 files. There are two important differences
|
733
|
+
* between Music and Sample:
|
734
|
+
*
|
735
|
+
* 1. Music streams the music from disk, which means it can start faster and
|
736
|
+
* uses less memory than Sample, which loads the entire file into memory.
|
737
|
+
* This is especially important for music files, which are often several
|
738
|
+
* minutes long.
|
739
|
+
* 2. There can only be one Music instance playing at once, while there can
|
740
|
+
* be many Samples playing at once. If you play a second Music while one
|
741
|
+
* is already playing, the first one will be stopped. See #play.
|
742
|
+
*/
|
743
|
+
cMusic = rb_define_class_under(mMixer, "Music", rb_cObject);
|
744
|
+
rb_define_singleton_method(cMusic, "load_audio", rbgm_mixmusic_new, 1);
|
745
|
+
|
746
|
+
//rb_define_singleton_method(cMusic, "set_command", rbgm_mixmusic_setcommand, 1);
|
747
|
+
|
748
|
+
rb_define_method(cMusic, "play", rbgm_mixmusic_play, -1);
|
749
|
+
rb_define_method(cMusic, "stop", rbgm_mixmusic_stop, 0);
|
750
|
+
rb_define_method(cMusic, "pause", rbgm_mixmusic_pause, 0);
|
751
|
+
rb_define_method(cMusic, "resume", rbgm_mixmusic_resume, 0);
|
752
|
+
rb_define_method(cMusic, "rewind", rbgm_mixmusic_rewind, 0);
|
753
|
+
rb_define_method(cMusic, "jump", rbgm_mixmusic_jump, 1);
|
754
|
+
rb_define_method(cMusic, "paused?", rbgm_mixmusic_paused, 0);
|
755
|
+
rb_define_method(cMusic, "playing?", rbgm_mixmusic_playing, 0);
|
756
|
+
|
757
|
+
rb_define_method(cMusic, "volume", rbgm_mixmusic_getvolume, 0);
|
758
|
+
rb_define_method(cMusic, "volume=", rbgm_mixmusic_setvolume, 1);
|
759
|
+
rb_define_method(cMusic, "fade_in", rbgm_mixmusic_fadein, -1);
|
760
|
+
rb_define_method(cMusic, "fade_out", rbgm_mixmusic_fadeout, 1);
|
761
|
+
rb_define_method(cMusic, "fading?", rbgm_mixmusic_fading, -1);
|
762
|
+
}
|
763
|
+
|
764
|
+
|