rubygame 2.5.3 → 2.6.0

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 (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