rubygame 2.5.3 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. data/CREDITS +6 -4
  2. data/NEWS +79 -0
  3. data/README +55 -72
  4. data/ROADMAP +20 -13
  5. data/doc/custom_sdl_load_paths.rdoc +79 -0
  6. data/doc/getting_started.rdoc +65 -36
  7. data/doc/keyboard_symbols.rdoc +243 -0
  8. data/doc/macosx_install.rdoc +49 -35
  9. data/doc/windows_install.rdoc +36 -108
  10. data/lib/rubygame.rb +62 -24
  11. data/lib/rubygame/audio.rb +147 -0
  12. data/lib/rubygame/clock.rb +164 -1
  13. data/lib/rubygame/color.rb +40 -7
  14. data/lib/rubygame/color/models/hsl.rb +1 -1
  15. data/lib/rubygame/color/models/hsv.rb +1 -1
  16. data/lib/rubygame/color/models/rgb.rb +1 -1
  17. data/lib/rubygame/color/palettes/css.rb +1 -3
  18. data/lib/rubygame/color/palettes/x11.rb +1 -2
  19. data/lib/rubygame/constants.rb +297 -0
  20. data/lib/rubygame/deprecated_mixer.rb +555 -0
  21. data/lib/rubygame/event.rb +122 -6
  22. data/lib/rubygame/event_handler.rb +3 -1
  23. data/lib/rubygame/event_hook.rb +6 -2
  24. data/lib/rubygame/event_triggers.rb +1 -1
  25. data/lib/rubygame/events.rb +416 -1
  26. data/lib/rubygame/ftor.rb +1 -7
  27. data/lib/rubygame/gfx.rb +583 -0
  28. data/lib/rubygame/gl.rb +107 -0
  29. data/lib/rubygame/image.rb +140 -0
  30. data/lib/rubygame/joystick.rb +184 -0
  31. data/lib/rubygame/main.rb +82 -0
  32. data/lib/rubygame/mediabag.rb +1 -1
  33. data/lib/rubygame/mixer.rb +30 -0
  34. data/lib/rubygame/music.rb +493 -0
  35. data/lib/rubygame/queue.rb +3 -1
  36. data/lib/rubygame/rect.rb +9 -9
  37. data/lib/rubygame/screen.rb +357 -0
  38. data/lib/rubygame/shared.rb +40 -4
  39. data/lib/rubygame/sound.rb +428 -0
  40. data/lib/rubygame/surface.rb +626 -0
  41. data/lib/rubygame/ttf.rb +311 -0
  42. data/samples/FreeSans.ttf +0 -0
  43. data/samples/README +6 -5
  44. data/samples/demo_draw.rb +1 -1
  45. data/samples/demo_gl.rb +3 -1
  46. data/samples/demo_gl_tex.rb +4 -2
  47. data/samples/demo_rubygame.rb +114 -105
  48. data/samples/demo_sfont.rb +1 -1
  49. data/samples/demo_ttf.rb +3 -1
  50. data/samples/demo_utf8.rb +1 -1
  51. data/samples/image_viewer.rb +118 -0
  52. data/samples/load_and_blit.rb +1 -1
  53. data/samples/rubygame.png +0 -0
  54. metadata +34 -40
  55. data/Rakefile +0 -537
  56. data/doc/extended_readme.rdoc +0 -49
  57. data/ext/body/rubygame_body.so +0 -0
  58. data/ext/rubygame/rubygame_clock.c +0 -301
  59. data/ext/rubygame/rubygame_clock.h +0 -32
  60. data/ext/rubygame/rubygame_event.c +0 -760
  61. data/ext/rubygame/rubygame_event.h +0 -48
  62. data/ext/rubygame/rubygame_event2.c +0 -661
  63. data/ext/rubygame/rubygame_event2.h +0 -29
  64. data/ext/rubygame/rubygame_gfx.c +0 -942
  65. data/ext/rubygame/rubygame_gfx.h +0 -101
  66. data/ext/rubygame/rubygame_gl.c +0 -154
  67. data/ext/rubygame/rubygame_gl.h +0 -32
  68. data/ext/rubygame/rubygame_image.c +0 -252
  69. data/ext/rubygame/rubygame_image.h +0 -41
  70. data/ext/rubygame/rubygame_joystick.c +0 -336
  71. data/ext/rubygame/rubygame_joystick.h +0 -41
  72. data/ext/rubygame/rubygame_main.c +0 -158
  73. data/ext/rubygame/rubygame_main.h +0 -36
  74. data/ext/rubygame/rubygame_mixer.c +0 -1024
  75. data/ext/rubygame/rubygame_mixer.h +0 -36
  76. data/ext/rubygame/rubygame_music.c +0 -1017
  77. data/ext/rubygame/rubygame_music.h +0 -29
  78. data/ext/rubygame/rubygame_screen.c +0 -572
  79. data/ext/rubygame/rubygame_screen.h +0 -45
  80. data/ext/rubygame/rubygame_shared.c +0 -269
  81. data/ext/rubygame/rubygame_shared.h +0 -69
  82. data/ext/rubygame/rubygame_sound.c +0 -863
  83. data/ext/rubygame/rubygame_sound.h +0 -29
  84. data/ext/rubygame/rubygame_surface.c +0 -1153
  85. data/ext/rubygame/rubygame_surface.h +0 -62
  86. data/ext/rubygame/rubygame_ttf.c +0 -599
  87. data/ext/rubygame/rubygame_ttf.h +0 -69
  88. data/samples/keys.rb +0 -52
@@ -17,7 +17,7 @@
17
17
  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
18
  #++
19
19
 
20
- require "rubygame"
20
+
21
21
 
22
22
  #--
23
23
  # MediaBag is DEPRECATED and will be removed in Rubygame 3.0!
@@ -0,0 +1,30 @@
1
+ #--
2
+ # Rubygame -- Ruby code and bindings to SDL to facilitate game creation
3
+ # Copyright (C) 2004-2009 John Croisant
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License as published by the Free Software Foundation; either
8
+ # version 2.1 of the License, or (at your option) any later version.
9
+ #
10
+ # This library is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ # Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public
16
+ # License along with this library; if not, write to the Free Software
17
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
+ #++
19
+
20
+
21
+
22
+ require "ruby-sdl-ffi/mixer"
23
+
24
+ Rubygame::VERSIONS[:sdl_mixer] = SDL::Mixer.Linked_Version.to_ary
25
+
26
+
27
+ # Load sound.rb, music.rb, and deprecated_mixer.rb
28
+ %w{ sound music deprecated_mixer }.each do |f|
29
+ require File.join( File.dirname(__FILE__), f )
30
+ end
@@ -0,0 +1,493 @@
1
+ #--
2
+ # Rubygame -- Ruby code and bindings to SDL to facilitate game creation
3
+ # Copyright (C) 2004-2009 John Croisant
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License as published by the Free Software Foundation; either
8
+ # version 2.1 of the License, or (at your option) any later version.
9
+ #
10
+ # This library is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ # Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public
16
+ # License along with this library; if not, write to the Free Software
17
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
+ #++
19
+
20
+
21
+
22
+ # *IMPORTANT*: this class only exists if SDL_mixer is available!
23
+ # Your code should check "defined?(Rubygame::Music) != nil" to see if
24
+ # you can use this class, or be prepared to rescue from NameError.
25
+ #
26
+ # Music holds a song, streamed from an audio file (see #load for
27
+ # supported formats). There are two important differences between
28
+ # the Music and Sound classes:
29
+ #
30
+ # 1. Only one Music can be playing. If you try to play
31
+ # a second song, the first one will be stopped.
32
+ #
33
+ # 2. Music doesn't load the entire audio file, so it can begin
34
+ # quickly and doesn't use much memory. This is good, because
35
+ # music files are usually much longer than sound effects!
36
+ #
37
+ # Music can #play, #pause/#unpause, #stop, #rewind, #jump_to another
38
+ # time, adjust #volume, and #fade_out (fade in by passing an option
39
+ # to #play).
40
+ #
41
+ # Music includes the Rubygame::NamedResource mixin module, which
42
+ # can perform autoloading of music on demand, among other things.
43
+ #
44
+ class Rubygame::Music
45
+
46
+ include Rubygame::NamedResource
47
+
48
+ class << self
49
+
50
+ # Searches each directory in Music.autoload_dirs for a file with
51
+ # the given filename. If it finds that file, loads it and returns
52
+ # a Music instance. If it doesn't find the file, returns nil.
53
+ #
54
+ # See Rubygame::NamedResource for more information about this
55
+ # functionality.
56
+ #
57
+ def autoload( filename )
58
+ path = find_file( filename )
59
+
60
+ if( path )
61
+ return load( path )
62
+ else
63
+ return nil
64
+ end
65
+ end
66
+
67
+
68
+ # Load the given audio file.
69
+ # Supported file formats are WAVE, MOD, MIDI, OGG, and MP3.
70
+ #
71
+ # filename:: Full or relative path to the file. (String, required)
72
+ #
73
+ # Returns:: The new Music instance. (Music)
74
+ # May raise:: SDLError, if the music file could not be loaded.
75
+ #
76
+ def load( filename )
77
+ Rubygame.open_audio
78
+
79
+ music = SDL::Mixer.LoadMUS( filename )
80
+
81
+ if( music.pointer.null? )
82
+ raise( Rubygame::SDLError, "Could not load Music file '%s': %s"%
83
+ [filename, SDL.GetError()] )
84
+ end
85
+
86
+ return new( music )
87
+ end
88
+
89
+
90
+ def current_music
91
+ @current_music
92
+ end
93
+
94
+ def __current_music=( music ) # :nodoc:
95
+ @current_music = music
96
+ end
97
+
98
+ end
99
+
100
+
101
+ # call-seq:
102
+ # new
103
+ #
104
+ # **NOTE**: Don't use this method. Use Music.load.
105
+ #
106
+ # Raises NotImplementedError.
107
+ #
108
+ def initialize( music=nil )
109
+ if( music.instance_of? SDL::Mixer::Music )
110
+ @struct = music
111
+ @volume = 1
112
+ @repeats = 0
113
+ else
114
+ raise( NotImplementedError, "Music.new is not implemented. "+
115
+ "Use Music.load to load a music file." )
116
+ end
117
+ end
118
+
119
+
120
+ attr_reader :struct # :nodoc:
121
+ protected :struct
122
+
123
+
124
+ # call-seq:
125
+ # clone( other ) -> music
126
+ # dup( other ) -> music
127
+ #
128
+ # Create a copy of the given Music instance. More efficient than
129
+ # using #load to load the music file again.
130
+ #
131
+ # other:: An existing Music instance. (Music, required)
132
+ #
133
+ # Returns:: The new Music instance. (Music)
134
+ #
135
+ # **NOTE**: #clone and #dup do slightly different things; #clone
136
+ # will copy the 'frozen' state of the object, while #dup will create
137
+ # a fresh, un-frozen object.
138
+ #
139
+ def initialize_copy( other )
140
+ @struct = other.struct
141
+ @volume = other.volume
142
+ @repeats = other.repeats
143
+ end
144
+
145
+
146
+
147
+ # call-seq:
148
+ # play( options={:fade_in => 0, :repeats => 0, :start_at => 0} )
149
+ #
150
+ # Play the Music, optionally fading in, repeating a certain number
151
+ # of times (or forever), and/or starting at a certain position in
152
+ # the song.
153
+ #
154
+ # See also #pause and #stop.
155
+ #
156
+ # options:: Hash of options, listed below. (Hash, required)
157
+ #
158
+ # :fade_in:: Fade in from silence over the given number of
159
+ # seconds. Default: 0. (Numeric, optional)
160
+ # :repeats:: Repeat the music the given number of times, or
161
+ # forever (or until stopped) if -1. Default: 0.
162
+ # (Integer, optional)
163
+ # :start_at:: Start playing the music at the given time in the
164
+ # song, in seconds. Default: 0. (Numeric, optional)
165
+ # **NOTE**: Non-zero start times only work for
166
+ # OGG and MP3 formats! Please refer to #jump.
167
+ #
168
+ #
169
+ # Returns:: The receiver (self).
170
+ # May raise:: SDLError, if the audio device could not be opened, or
171
+ # if the music file could not be played, or if you used
172
+ # :start_at with an unsupported format.
173
+ #
174
+ #
175
+ # **NOTE**: Only one music can be playing at once. If any music is
176
+ # already playing (or paused), it will be stopped before playing the
177
+ # new music.
178
+ #
179
+ # Example:
180
+ # # Fade in over 2 seconds, play 4 times (1 + 3 repeats),
181
+ # # starting at 60 seconds since the beginning of the song.
182
+ # music.play( :fade_in => 2, :repeats => 3, :start_at => 60 );
183
+ #
184
+ def play( options={} )
185
+
186
+ fade_in = (options[:fade_in] or 0)
187
+ repeats = (options[:repeats] or 0)
188
+ start_at = (options[:start_at] or 0)
189
+
190
+
191
+ fade_in =
192
+ if( fade_in < 0 )
193
+ raise ArgumentError, ":fade_in cannot be negative (got %.2f)"%fade_in
194
+ elsif( fade_in < 0.05 )
195
+ # Work-around for a bug with SDL_mixer not working with small
196
+ # non-zero fade-ins
197
+ 0
198
+ else
199
+ (fade_in * 1000).to_i
200
+ end
201
+
202
+
203
+ repeats =
204
+ if( repeats < -1 )
205
+ raise( ArgumentError,
206
+ ":repeats cannot be negative, except -1 (got #{repeats})" )
207
+ elsif( repeats > -1 )
208
+ # Adjust so repeats means the same as it does for Sound
209
+ (repeats + 1).to_i
210
+ else
211
+ -1
212
+ end
213
+
214
+
215
+ start_at =
216
+ if( start_at < 0 )
217
+ raise( ArgumentError,
218
+ ":start_at cannot be negative, (got %.2f)"%start_at )
219
+ else
220
+ start_at.to_f
221
+ end
222
+
223
+
224
+ Rubygame.open_audio
225
+
226
+
227
+ # Doing a little restart dance to please the SDL_mixer gods.
228
+ SDL::Mixer.PlayMusic( @struct, 0 )
229
+ SDL::Mixer.HaltMusic()
230
+
231
+ # Set music channel volume before we play
232
+ SDL::Mixer.VolumeMusic( (SDL::Mixer::MAX_VOLUME * @volume).to_i )
233
+
234
+
235
+ @repeats = repeats
236
+
237
+ result = SDL::Mixer.FadeInMusicPos( @struct, repeats, fade_in, start_at )
238
+
239
+ if( result == -1 )
240
+ raise Rubygame::SDLError, "Could not play Music: #{SDL.GetError()}"
241
+ end
242
+
243
+ self.class.__current_music = self
244
+
245
+ return self
246
+
247
+ end
248
+
249
+
250
+ # True if the Music is currently playing (not paused and not stopped).
251
+ # See also #paused? and #stopped?.
252
+ #
253
+ def playing?
254
+ current? and
255
+ SDL::Mixer.PlayingMusic() == 1 and
256
+ SDL::Mixer.PausedMusic() == 0
257
+ end
258
+
259
+
260
+
261
+ # Pause the Music. Unlike #stop, it can be unpaused later to resume
262
+ # from where it was paused. See also #unpause and #paused?.
263
+ #
264
+ # Returns:: The receiver (self).
265
+ #
266
+ # **NOTE**: Does nothing if the music is not currently playing.
267
+ #
268
+ def pause
269
+ if current?
270
+ SDL::Mixer.PauseMusic()
271
+ end
272
+
273
+ return self
274
+ end
275
+
276
+
277
+ # Unpause the Music, if it is currently paused. Resumes from
278
+ # where it was paused. See also #pause and #paused?.
279
+ #
280
+ # Returns:: The receiver (self).
281
+ #
282
+ # **NOTE**: Does nothing if the music is not currently paused.
283
+ #
284
+ def unpause
285
+ if current?
286
+ SDL::Mixer.ResumeMusic()
287
+ end
288
+
289
+ return self
290
+ end
291
+
292
+
293
+ # True if the Music is currently paused (not playing and not stopped).
294
+ # See also #playing? and #stopped?.
295
+ #
296
+ def paused?
297
+ current? and
298
+ SDL::Mixer.PlayingMusic() == 1 and
299
+ SDL::Mixer.PausedMusic() == 1
300
+ end
301
+
302
+
303
+
304
+ # Stop the Music. Unlike #pause, the music must be played again from
305
+ # the beginning, it cannot be resumed from it was stopped.
306
+ #
307
+ # Returns:: The receiver (self).
308
+ #
309
+ # **NOTE**: Does nothing if the music is not currently playing or paused.
310
+ #
311
+ def stop
312
+ if current?
313
+ SDL::Mixer.HaltMusic()
314
+ end
315
+
316
+ return self
317
+ end
318
+
319
+
320
+ # True if the Music is currently stopped (not playing and not paused).
321
+ # See also #playing? and #paused?.
322
+ #
323
+ def stopped?
324
+ (not current?) or (SDL::Mixer.PlayingMusic() == 0)
325
+ end
326
+
327
+
328
+
329
+ # Fade out to silence over the given number of seconds. Once the music
330
+ # is silent, it is automatically stopped.
331
+ #
332
+ # Returns:: The receiver (self).
333
+ #
334
+ # **NOTE**: If the music is currently paused, the fade will start,
335
+ # but you won't be able to hear it happening unless you #unpause during
336
+ # the fade.
337
+ #
338
+ # Does nothing if the music is currently stopped.
339
+ #
340
+ def fade_out( fade_time )
341
+ if( fade_time < 0 )
342
+ raise ArgumentError, "fade time cannot be negative (got %.2f)"%fade_time
343
+ end
344
+
345
+ if current?
346
+ result = SDL::Mixer.FadeOutMusic( (fade_time * 1000).to_i )
347
+ if( result < 0 )
348
+ raise Rubygame::SDLError, "Error fading out music: #{SDL.GetError()}"
349
+ end
350
+ end
351
+
352
+ return self
353
+ end
354
+
355
+
356
+ # True if the Music is currently fading in or out.
357
+ # See also #play and #fade_out.
358
+ #
359
+ # direction:: Check if it is fading :in, :out, or :either.
360
+ # (Symbol, required)
361
+ #
362
+ def fading?( direction=:either )
363
+ return false unless current?
364
+
365
+ case direction
366
+ when :in
367
+ SDL::Mixer.FadingMusic() == SDL::Mixer::FADING_IN
368
+ when :out
369
+ SDL::Mixer.FadingMusic() == SDL::Mixer::FADING_OUT
370
+ else
371
+ SDL::Mixer.FadingMusic() != SDL::Mixer::NO_FADING
372
+ end
373
+ end
374
+
375
+
376
+
377
+ # Return the volume level of the music.
378
+ # 0.0 is totally silent, 1.0 is full volume.
379
+ #
380
+ # **NOTE**: Ignores fading in or out.
381
+ #
382
+ def volume
383
+ @volume
384
+ end
385
+
386
+
387
+ # Set the new #volume level of the music.
388
+ # 0.0 is totally silent, 1.0 is full volume.
389
+ # The new volume will be clamped to this range if it is too small or
390
+ # too large.
391
+ #
392
+ # Volume cannot be set while the music is fading in or out.
393
+ # Be sure to check #fading? or rescue from SDLError when
394
+ # using this method.
395
+ #
396
+ # May raise:: SDLError if the music is fading in or out.
397
+ #
398
+ def volume=( new_vol )
399
+ # Clamp it to valid range
400
+ new_vol = if new_vol < 0.0; 0.0
401
+ elsif new_vol > 1.0; 1.0
402
+ else; new_vol
403
+ end
404
+
405
+ if current?
406
+ if fading?
407
+ raise Rubygame::SDLError, "cannot set Music volume while fading"
408
+ else
409
+ SDL::Mixer.VolumeMusic( (SDL::Mixer::MAX_VOLUME * new_vol).to_i )
410
+ end
411
+ end
412
+
413
+ @volume = new_vol
414
+ end
415
+
416
+
417
+
418
+ def repeats # :nodoc:
419
+ @repeats
420
+ end
421
+
422
+
423
+
424
+ # Rewind the Music to the beginning. If the Music was paused, it
425
+ # will still be paused after the rewind. Does nothing if the Music
426
+ # is stopped.
427
+ #
428
+ def rewind
429
+ if current? and not stopped?
430
+ was_paused = paused?
431
+
432
+ SDL::Mixer.HaltMusic()
433
+ result = SDL::Mixer.PlayMusic(@struct, @repeats)
434
+
435
+ if( result == -1 )
436
+ raise Rubygame::SDLError, "Could not rewind music: #{SDL.GetError()}"
437
+ end
438
+
439
+ SDL::Mixer.PauseMusic() if was_paused
440
+ end
441
+
442
+ return self
443
+ end
444
+
445
+
446
+ # Jump to any time in the Music, in seconds since the beginning.
447
+ # If the Music was paused, it will still be paused again after the
448
+ # jump. Does nothing if the Music was stopped.
449
+ #
450
+ # **NOTE**: Only works for OGG and MP3 formats! Other formats (e.g.
451
+ # WAV) will usually raise SDLError.
452
+ #
453
+ # time:: the time to jump to, in seconds since the beginning
454
+ # of the song. (Numeric, required)
455
+ #
456
+ # May raise:: SDLError if something goes wrong, or if the music
457
+ # type does not support jumping.
458
+ #
459
+ # **CAUTION**: This method may be unreliable (and could even crash!)
460
+ # if you jump to a time after the end of the song. Unfortunately,
461
+ # SDL_Mixer does not provide a way to find the song's length, so
462
+ # Rubygame cannot warn you if you go off the end. Be careful!
463
+ #
464
+ def jump_to( time )
465
+ if current? and not stopped?
466
+ was_paused = paused?
467
+
468
+ if( time < 0 )
469
+ raise Rubygame::SDLError, "cannot jump to negative time (got #{time})"
470
+ end
471
+
472
+ result = SDL::Mixer.SetMusicPosition( time.to_f )
473
+
474
+ if( result == -1)
475
+ raise Rubygame::SDLError, "could not jump music: #{SDL.GetError()}"
476
+ end
477
+
478
+ SDL::Mixer.PauseMusic() if was_paused
479
+ end
480
+
481
+ return self
482
+ end
483
+
484
+
485
+
486
+ private
487
+
488
+
489
+ def current? # :nodoc:
490
+ self.class.current_music == self
491
+ end
492
+
493
+ end