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.
Files changed (94) hide show
  1. data/CREDITS +60 -0
  2. data/LICENSE +504 -0
  3. data/NEWS +201 -0
  4. data/README +139 -0
  5. data/ROADMAP +43 -0
  6. data/Rakefile +409 -0
  7. data/doc/extended_readme.rdoc +49 -0
  8. data/doc/getting_started.rdoc +47 -0
  9. data/doc/macosx_install.rdoc +70 -0
  10. data/doc/windows_install.rdoc +123 -0
  11. data/ext/rubygame/MANIFEST +25 -0
  12. data/ext/rubygame/rubygame_core.so +0 -0
  13. data/ext/rubygame/rubygame_event.c +644 -0
  14. data/ext/rubygame/rubygame_event.h +48 -0
  15. data/ext/rubygame/rubygame_event.o +0 -0
  16. data/ext/rubygame/rubygame_gfx.c +942 -0
  17. data/ext/rubygame/rubygame_gfx.h +101 -0
  18. data/ext/rubygame/rubygame_gfx.o +0 -0
  19. data/ext/rubygame/rubygame_gfx.so +0 -0
  20. data/ext/rubygame/rubygame_gl.c +154 -0
  21. data/ext/rubygame/rubygame_gl.h +32 -0
  22. data/ext/rubygame/rubygame_gl.o +0 -0
  23. data/ext/rubygame/rubygame_image.c +108 -0
  24. data/ext/rubygame/rubygame_image.h +41 -0
  25. data/ext/rubygame/rubygame_image.o +0 -0
  26. data/ext/rubygame/rubygame_image.so +0 -0
  27. data/ext/rubygame/rubygame_joystick.c +247 -0
  28. data/ext/rubygame/rubygame_joystick.h +41 -0
  29. data/ext/rubygame/rubygame_joystick.o +0 -0
  30. data/ext/rubygame/rubygame_main.c +155 -0
  31. data/ext/rubygame/rubygame_main.h +33 -0
  32. data/ext/rubygame/rubygame_main.o +0 -0
  33. data/ext/rubygame/rubygame_mixer.c +764 -0
  34. data/ext/rubygame/rubygame_mixer.h +62 -0
  35. data/ext/rubygame/rubygame_mixer.o +0 -0
  36. data/ext/rubygame/rubygame_mixer.so +0 -0
  37. data/ext/rubygame/rubygame_screen.c +448 -0
  38. data/ext/rubygame/rubygame_screen.h +43 -0
  39. data/ext/rubygame/rubygame_screen.o +0 -0
  40. data/ext/rubygame/rubygame_shared.c +209 -0
  41. data/ext/rubygame/rubygame_shared.h +60 -0
  42. data/ext/rubygame/rubygame_shared.o +0 -0
  43. data/ext/rubygame/rubygame_surface.c +1147 -0
  44. data/ext/rubygame/rubygame_surface.h +62 -0
  45. data/ext/rubygame/rubygame_surface.o +0 -0
  46. data/ext/rubygame/rubygame_time.c +183 -0
  47. data/ext/rubygame/rubygame_time.h +32 -0
  48. data/ext/rubygame/rubygame_time.o +0 -0
  49. data/ext/rubygame/rubygame_ttf.c +599 -0
  50. data/ext/rubygame/rubygame_ttf.h +69 -0
  51. data/ext/rubygame/rubygame_ttf.o +0 -0
  52. data/ext/rubygame/rubygame_ttf.so +0 -0
  53. data/lib/rubygame/MANIFEST +12 -0
  54. data/lib/rubygame/clock.rb +128 -0
  55. data/lib/rubygame/color/models/base.rb +106 -0
  56. data/lib/rubygame/color/models/hsl.rb +153 -0
  57. data/lib/rubygame/color/models/hsv.rb +149 -0
  58. data/lib/rubygame/color/models/rgb.rb +78 -0
  59. data/lib/rubygame/color/palettes/css.rb +49 -0
  60. data/lib/rubygame/color/palettes/palette.rb +100 -0
  61. data/lib/rubygame/color/palettes/x11.rb +177 -0
  62. data/lib/rubygame/color.rb +79 -0
  63. data/lib/rubygame/constants.rb +238 -0
  64. data/lib/rubygame/event.rb +313 -0
  65. data/lib/rubygame/ftor.rb +370 -0
  66. data/lib/rubygame/hotspot.rb +265 -0
  67. data/lib/rubygame/keyconstants.rb +237 -0
  68. data/lib/rubygame/mediabag.rb +94 -0
  69. data/lib/rubygame/queue.rb +288 -0
  70. data/lib/rubygame/rect.rb +612 -0
  71. data/lib/rubygame/sfont.rb +223 -0
  72. data/lib/rubygame/sprite.rb +511 -0
  73. data/lib/rubygame.rb +41 -0
  74. data/samples/FreeSans.ttf +0 -0
  75. data/samples/GPL.txt +340 -0
  76. data/samples/README +40 -0
  77. data/samples/chimp.bmp +0 -0
  78. data/samples/chimp.rb +313 -0
  79. data/samples/demo_gl.rb +151 -0
  80. data/samples/demo_gl_tex.rb +197 -0
  81. data/samples/demo_music.rb +75 -0
  82. data/samples/demo_rubygame.rb +284 -0
  83. data/samples/demo_sfont.rb +52 -0
  84. data/samples/demo_ttf.rb +193 -0
  85. data/samples/demo_utf8.rb +53 -0
  86. data/samples/fist.bmp +0 -0
  87. data/samples/load_and_blit.rb +22 -0
  88. data/samples/panda.png +0 -0
  89. data/samples/punch.wav +0 -0
  90. data/samples/ruby.png +0 -0
  91. data/samples/song.ogg +0 -0
  92. data/samples/term16.png +0 -0
  93. data/samples/whiff.wav +0 -0
  94. 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
+