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
@@ -1,123 +1,51 @@
1
- = Compiling Rubygame on Windows
1
+ Note: You can view the latest version of this guide online at the
2
+ Rubygame wiki: http://rubygame.org/wiki/Windows_Installation_Guide
2
3
 
3
- (For the most up-to-date version of this document, see the Rubygame wiki:
4
- http://rubygame.wiki.sourceforge.net/win32_compile)
4
+ == Gather Dependencies
5
5
 
6
- This document gives some helpful guidelines to for compiling and installing
7
- Rubygame on Microsoft Windows. However, these instructions are not perfect,
8
- so they might not work for you. If you use this guide, we'd love to hear about
9
- what worked and what didn't; just send a message to the {rubygame-users mailing
10
- list}[https://sourceforge.net/mail/?group_id=172781]!
6
+ * {Ruby}[http://www.ruby-lang.org/en/downloads/], the language itself.
7
+ The easiest option here is the one-click installer. This will
8
+ install Ruby and a number of useful libraries without any hassle.
11
9
 
12
- The usual caveats apply: follow these instructions at your own risk and so
13
- forth. Please direct comments or questions to the {Rubygame user's mailing
14
- list}[http://sourceforge.net/mail/?group_id=172781].
10
+ * {SDL}[http://www.libsdl.org/download-1.2.php].
11
+ Download the Win32 binary package, e.g. "SDL-1.2.14-win32.zip".
15
12
 
16
- == Step 1: Gather Dependencies
13
+ The rest are optional dependencies, but highly recommended. If you
14
+ don't have them, you won't be able to use certain features of
15
+ Rubygame.
17
16
 
18
- - You'll need a build environment for Windows. In this guide, we'll use
19
- {MinGW}[http://www.mingw.org/MinGWiki/index.php/GettingStarted].
20
- - Grab MinGW-NNN.exe (e.g. MinGW-5.12.exe) from the {downloads page}[http://sourceforge.net/project/showfiles.php?group_id=2435&package_id=82721]
21
- and install it. (Note: you might need to expand the "MinGW" section to see
22
- the MinGW-NNN.exe files.)
23
- - Optional, but recommended: install MSYS-NNNN.exe (e.g. MSYS-1.0.10.exe)
24
- from the same page as above. (You might have to expand the MSYS section.)
25
- - Add the full path to the compiler executible to your system PATH if it
26
- isn't there already. You should be able to type <code>gcc -v</code> at a
27
- command line and see a version number.
17
+ * {SDL_image}[http://www.libsdl.org/projects/SDL_image/].
18
+ Grab the Win32 binary package, e.g. "SDL_image-1.2.8-win32.zip".
28
19
 
29
- - {Download Ruby}[http://www.ruby-lang.org/en/downloads/], the language itself.
30
- The easiest option here is the one-click installer. This will install
31
- Ruby and a number of useful libraries without any hassle.
20
+ * {SDL_mixer}[http://www.libsdl.org/projects/SDL_mixer/].
21
+ Just like before, grab the Win32 binary package, e.g.
22
+ "SDL_mixer-1.2.9-win32.zip".
32
23
 
33
- - {SDL}[http://www.libsdl.org/download-1.2.php]. In the <b>Development
34
- Libraries</b> section (near the bottom of the page), grab the
35
- SDL-devel-1.2.??-VC6.zip file. (The VC6 package is just fine, even though
36
- we're using with MinGW to compile.)
24
+ * {SDL_ttf}[http://www.libsdl.org/projects/SDL_ttf/].
25
+ Again, get the Win32 binary package, e.g. "SDL_ttf-2.0.9-win32.zip".
37
26
 
38
- The rest are optional dependencies, but highly recommended. If you don't have
39
- them, you won't be able to use certain features of Rubygame.
27
+ * {SDL_gfx}[http://www.ferzkopp.net/joomla/content/view/19/14/]
28
+ ({compiled version}[http://download.rubygame.org/files/extras/]).
29
+ Many thanks to a generous Rubygame user (bmatthew1) for providing a
30
+ compiled Windows DLL for SDL_gfx!
40
31
 
41
- - {SDL_image}[http://www.libsdl.org/projects/SDL_image/]. Grab the Win32
42
- binary package with 'devel' in the name.
43
- - {SDL_mixer}[http://www.libsdl.org/projects/SDL_mixer/]. Just like before,
44
- grab the Win32 binary package with 'devel' in the name.
45
- - {SDL_ttf}[http://www.libsdl.org/projects/SDL_ttf/]. Again, get the
46
- Win32 binary package with 'devel' in the name
47
- - {SDL_gfx}[http://www.ferzkopp.net/joomla/content/view/19/14/]. This is
48
- the trickiest dependency, because there is currently no official package for
49
- a precompiled version of SDL_gfx. If you are able to compile this yourself,
50
- great! Otherwise, some nice features of Rubygame have to be disabled;
51
- make sure you add the --no-gfx flag when you get to the "Set up environment
52
- variables" section, below.
32
+ Once you have downloaded everything, unzip them and copy the *.dll
33
+ files into the <code>C:\windows\system32\</code> directory. This will
34
+ allow the libraries to be detected and loaded by Rubygame.
53
35
 
54
- Once you have downloaded everything, extract each archive into a convenient
55
- location on your hard drive. You'll thank yourself later if you use a short
56
- path with no spaces in it. For this example, we'll unzip everything under
57
- <code>C:\\src\\</code>.
36
+ == Install Rubygame
58
37
 
59
- Next, copy the *.dll file from each library's folder into
60
- <code>C:\\windows\\system32\\</code>.
61
- This will allow the libraries to be detected properly later on.
38
+ The simplest way to install Rubygame is: <code>gem install rubygame</code>
62
39
 
63
- == Step 2: Get Rubygame
40
+ Or you can {download the source from
41
+ Github}[http://github.com/jacius/rubygame/] and follow the
42
+ installation instructions in README.
64
43
 
65
- If you haven't already, download the latest Rubygame source from the
66
- {download page}[http://rubyforge.org/frs/?group_id=5089].
67
- If you're feeling adventurous, you could try the in-development code from
68
- the {Git repository}[http://github.com/jacius/rubygame].
69
- You can decompress the .tar.bz2 file with either MSYS' <code>tar</code>
70
- (<code>tar xvjf rubygame-2.0.0.tar.bz2</code>) or a program like
71
- {7zip}[http://www.7-zip.org].
44
+ == Conclusion
72
45
 
73
- Extract the source into another folder of your choice, such as
74
- <code>C:\\src\\rubygame</code>.
46
+ If all goes well, you have successfully installed Rubygame. Try to
47
+ execute <code>require 'rubygame'</code> in an irb session and run the
48
+ provided samples to ensure that everything is acceptable.
75
49
 
76
- == Step 3: Set up environment variables
77
-
78
- Environment variables are used to configure the build process for your
79
- system; it helps the compiler to locate the headers and libraries it needs to
80
- compile Rubygame.
81
-
82
- Create a text file in your Rubygame directory called "envsetup.bat".
83
- In it, use code based on the following to set your variables.
84
- Be sure to replace '\src\' (lines 3-7) with the path to where you unpacked
85
- the libraries.
86
-
87
- set CC=gcc
88
- set CFLAGS=-DHAVE_ISINF -D_MSC_VER=1200
89
- set CFLAGS=%CFLAGS% -I \src\SDL-1.2.11\include
90
- set CFLAGS=%CFLAGS% -I \src\SDL_gfx-2.0.15
91
- set CFLAGS=%CFLAGS% -I \src\SDL_image-1.2.5\include
92
- set CFLAGS=%CFLAGS% -I \src\SDL_mixer-1.2.7\include
93
- set CFLAGS=%CFLAGS% -I \src\SDL_ttf-2.0.8\include
94
-
95
- set LDSHARED=gcc -shared
96
- set LINK_FLAGS=-L \windows\system32 -lSDL
97
- set LIBRUBYARG_SHARED=-L \ruby\bin -lmsvcrt-ruby18
98
-
99
- The -L parameter for LIBRUBYARG_SHARED may be different if you installed
100
- Ruby to a path other than C:/ruby.
101
-
102
- == Step 4: Compile and install Rubygame
103
-
104
- Open a command prompt and navigate to the root of your Rubygame source
105
- directory. Type:
106
-
107
- envsetup.bat
108
- rake install
109
-
110
- IMPORTANT: If you are missing an optional library (such as SDL_gfx), you must
111
- disable optional features by passing a "no-???" command to rake before the word
112
- "install". For example, to disable features that depend on SDL_gfx, you would
113
- type this instead of the above:
114
-
115
- envsetup.bat
116
- rake no-sdl-gfx install
117
-
118
- If all goes well, you have built and installed Rubygame.
119
- Try to execute <code>require 'rubygame'</code> in an irb session and run
120
- the provided samples to ensure that everything is acceptable.
121
-
122
- (Thanks to Ash Wilson (smashwilson) for contributing the original version of
123
- these instructions.)
50
+ If you have any trouble installing Rubygame, please post in the
51
+ {forums}[http://rubygame.org/forums/].
@@ -19,38 +19,76 @@
19
19
  #
20
20
  #++
21
21
 
22
- # This file is loaded when you "require 'rubygame'".
23
- # It loads up the compiled C extensions and the rest of
24
- # the Rubygame library modules.
25
22
 
23
+ this_dir = File.expand_path( File.dirname(__FILE__) )
26
24
 
27
- # Prefer local library over global installed version.
28
- $:.unshift( File.join( File.dirname(__FILE__), "..", "lib" ) )
29
- $:.unshift( File.join( File.dirname(__FILE__), "..", "ext", "rubygame" ) )
25
+
26
+ # Require Rubygame files. If these fail, don't rescue.
27
+ # Note: screen.rb is intentionally loaded late.
28
+ %w{ main
29
+ shared
30
+ audio
31
+ clock
32
+ constants
33
+ color
34
+ event
35
+ events
36
+ event_handler
37
+ gl
38
+ joystick
39
+ named_resource
40
+ queue
41
+ rect
42
+ surface
43
+ sprite
44
+ }.each do |f|
45
+ require File.join( this_dir, "rubygame", f )
46
+ end
47
+
48
+
49
+ # SDL_gfx is optional, rescue if it fails.
50
+ begin
51
+ require File.join( this_dir, "rubygame", "gfx" )
52
+ rescue LoadError => e
53
+ puts( "Warning: Could not load SDL_gfx! " +
54
+ "Continuing anyway, but some Surface methods will be missing.\n" +
55
+ "Error message was: #{e.message.inspect}" )
56
+ end
30
57
 
31
58
 
32
- require "rbconfig"
59
+ # SDL_image is optional, rescue if it fails.
60
+ begin
61
+ require File.join( this_dir, "rubygame", "image" )
62
+ rescue LoadError => e
63
+ puts( "Warning: Could not load SDL_image! " +
64
+ "Continuing anyway, but image loading will be missing.\n" +
65
+ "Error message was: #{e.message.inspect}" )
66
+ end
67
+
68
+
69
+ # SDL_mixer is optional, rescue if it fails.
70
+ begin
71
+ require File.join( this_dir, "rubygame", "mixer" )
72
+ rescue LoadError => e
73
+ puts( "Warning: Could not load SDL_mixer! " +
74
+ "Continuing anyway, but audio features will be missing.\n" +
75
+ "Error message was: #{e.message.inspect}" )
76
+ end
33
77
 
34
- require "rubygame_core"
35
78
 
36
- %W{ rubygame_gfx rubygame_image rubygame_ttf rubygame_mixer }.each do |mod|
37
- begin
38
- require mod
39
- rescue LoadError
40
- warn( "Warning: Unable to require optional module: #{mod}.") if $VERBOSE
41
- end
79
+ # SDL_ttf is optional, rescue if it fails.
80
+ begin
81
+ require File.join( this_dir, "rubygame", "ttf" )
82
+ rescue LoadError => e
83
+ puts( "Warning: Could not load SDL_ttf! " +
84
+ "Continuing anyway, but the TTF class will be missing.\n" +
85
+ "Error message was: #{e.message.inspect}" )
42
86
  end
43
87
 
44
- require "rubygame/shared"
45
88
 
46
- require "rubygame/color"
47
- require "rubygame/constants"
89
+ # Loaded late so Screen can undefine some inherited Surface methods.
90
+ require File.join( this_dir, "rubygame", "screen" )
48
91
 
49
- require "rubygame/event"
50
- require "rubygame/events"
51
- require "rubygame/queue"
52
- require "rubygame/event_handler"
53
92
 
54
- require "rubygame/rect"
55
- require "rubygame/sprite"
56
- require "rubygame/clock"
93
+ Rubygame.init
94
+ at_exit { Rubygame.quit }
@@ -0,0 +1,147 @@
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
+ module Rubygame
23
+
24
+ # call-seq:
25
+ # open_audio( options={:buffer=>1024, :channels=>2, :frequency=>22050} )
26
+ #
27
+ # Initializes the audio device using the given settings.
28
+ #
29
+ # NOTE: Audio will be automatically opened when Rubygame::Sound or
30
+ # Rubygame::Music are first used. You only need to open audio
31
+ # manually if you want settings different from the default, or if
32
+ # you are using the older, deprecated Music and Sample classes from
33
+ # the Rubygame::Mixer module.
34
+ #
35
+ # If audio is already open, this method has no effect, and returns false.
36
+ # If you want to change audio settings, you must #close_audio() and
37
+ # then open it again.
38
+ #
39
+ # options:: A Hash of any of the following options. (Hash, optional)
40
+ #
41
+ # :frequency:: output sample rate in audio samples per second
42
+ # (Hz). Affects the quality of the sound output, at
43
+ # the expense of CPU usage. If omitted, the default
44
+ # (22050) is used. The default is recommended for
45
+ # most games.
46
+ #
47
+ # :channels:: output sound channels. Use 2 for stereo, 1 for mono.
48
+ # If omitted, the default (2) is used.
49
+ #
50
+ # :buffer:: size of the sound buffer, in bytes. Must be a
51
+ # power of 2 (e.g. 512, 1024, 2048). If omitted,
52
+ # the default (1024) is used. If your game is
53
+ # fast-paced, you may want to use a smaller value
54
+ # to reduce audio delay, the time between when you
55
+ # play a sound and when it is heard.
56
+ #
57
+ # Returns:: true if the audio was newly opened by this action, or
58
+ # false if it was already open before this action.
59
+ #
60
+ # May raise:: SDLError, if initialization fails.
61
+ # ArgumentError, if an invalid value is given for any option.
62
+ #
63
+ def self.open_audio( options={} )
64
+ return false if audio_open?
65
+
66
+ unless options.kind_of? Hash
67
+ raise TypeError, "invalid options Hash: #{options.inspect}"
68
+ end
69
+
70
+ buff = (options[:buffer] or 1024)
71
+ chan = (options[:channels] or 2)
72
+ freq = (options[:frequency] or SDL::Mixer::DEFAULT_FREQUENCY)
73
+
74
+ # In general, format should always be the default.
75
+ frmt = SDL::Mixer::DEFAULT_FORMAT
76
+
77
+
78
+ buff = if( buff <= 0 )
79
+ raise ArgumentError, "buffer size must be positive (got #{buff})"
80
+ elsif( buff & (buff - 1) != 0 )
81
+ raise( ArgumentError, "buffer size must be a power of 2 "+
82
+ "(e.g. 512, 1024) (got #{buff})" )
83
+ else
84
+ buff.to_i
85
+ end
86
+
87
+
88
+ chan = if( chan != 1 && chan != 2 )
89
+ raise( ArgumentError,
90
+ "channels must be 1 (mono) or 2 (stereo) (got #{chan})" )
91
+ else
92
+ chan.to_i
93
+ end
94
+
95
+
96
+ freq = if( freq <= 0 )
97
+ raise ArgumentError, "frequency must be positive (got #{freq})"
98
+ else
99
+ freq.to_i
100
+ end
101
+
102
+ result = SDL::Mixer.OpenAudio(freq, frmt, chan, buff)
103
+
104
+ if( result < 0 )
105
+ raise Rubygame::SDLError, "Could not open audio: #{SDL.GetError()}"
106
+ end
107
+
108
+ return true
109
+ end
110
+
111
+
112
+
113
+ # Deinitializes and closes the audio device. If audio was not open,
114
+ # this method does nothing, and returns false. See also #open_audio().
115
+ #
116
+ # NOTE: The audio will be automatically closed when the program
117
+ # exits. You only need to close audio manually if you want to
118
+ # call #open_audio with different settings.
119
+ #
120
+ # Returns:: true if the audio was open before this action.
121
+ #
122
+ def self.close_audio
123
+ if audio_open?
124
+ SDL::Mixer.CloseAudio()
125
+ return true
126
+ else
127
+ return false
128
+ end
129
+ end
130
+
131
+
132
+ def self.audio_open? # :nodoc:
133
+ SDL::Mixer.QuerySpec(nil,nil,nil) > 0
134
+ end
135
+
136
+
137
+ # Returns the name of the audio driver that SDL is using.
138
+ # This method opens the audio device if it is not open already.
139
+ #
140
+ # May raise an SDLError if the audio device could not be opened.
141
+ #
142
+ def self.audio_driver
143
+ open_audio
144
+ return SDL.AudioDriverName
145
+ end
146
+
147
+ end
@@ -20,7 +20,8 @@
20
20
  #++
21
21
 
22
22
 
23
- require "rubygame/events/clock_events"
23
+
24
+ require( File.join( File.dirname(__FILE__), "events", "clock_events" ) )
24
25
 
25
26
 
26
27
  module Rubygame
@@ -41,6 +42,168 @@ module Rubygame
41
42
  #
42
43
  class Clock
43
44
 
45
+ class << self
46
+
47
+ # time:: The target delay time, in milliseconds.
48
+ # (Non-negative integer. Required.)
49
+ # gran:: The assumed granularity (in ms) of the system clock.
50
+ # (Non-negative integer. Optional. Default: 12.)
51
+ # nice:: If true, try to let other ruby threads run during the delay.
52
+ # (true or false. Optional. Default: false.)
53
+ #
54
+ # Returns:: The actual delay time, in milliseconds.
55
+ #
56
+ # Pause the program for +time+ milliseconds. This function is more
57
+ # accurate than Clock.wait, but uses slightly more CPU time. Both
58
+ # this function and Clock.wait can be used to slow down the
59
+ # framerate so that the application doesn't use too much CPU time.
60
+ # See also Clock#tick for a good and easy way to limit the
61
+ # framerate.
62
+ #
63
+ # This function uses "busy waiting" during the last part
64
+ # of the delay, for increased accuracy. The value of +gran+ affects
65
+ # how many milliseconds of the delay are spent in busy waiting, and thus
66
+ # how much CPU it uses. A smaller +gran+ value uses less CPU, but if
67
+ # it's smaller than the true system granularity, this function may
68
+ # delay a few milliseconds too long. The default value (12ms) is very
69
+ # safe, but a value of approximately 5ms would give a better balance
70
+ # between accuracy and CPU usage on most modern computers.
71
+ # A granularity of 0ms makes this method act the same as Clock.wait
72
+ # (i.e. no busy waiting at all, very low CPU usage).
73
+ #
74
+ # If +nice+ is true, this function will try to allow other ruby
75
+ # threads to run during this function. Otherwise, other ruby threads
76
+ # will probably also be paused. Setting +nice+ to true is only
77
+ # useful if your application is multithreaded. It's safe (but
78
+ # pointless) to use this feature for single threaded applications.
79
+ #
80
+ # The Rubygame timer system will be initialized when you call this
81
+ # function, if it has not been already. See Clock.runtime.
82
+ #
83
+ def delay( time, gran=12, nice=false )
84
+ _init_sdl_timer
85
+ time = 0 if time < 0
86
+ gran = 0 if gran < 0
87
+ _accurate_delay( time, gran, nice )
88
+ end
89
+
90
+
91
+ # time:: The target wait time, in milliseconds.
92
+ # (Non-negative Integer. Required.)
93
+ # nice:: If true, try to let other ruby threads run during the delay.
94
+ # (true or false. Optional.)
95
+ #
96
+ # Returns:: The actual wait time, in milliseconds.
97
+ #
98
+ # Pause the program for approximately +time+ milliseconds. Both this
99
+ # function and Clock.delay can be used to slow down the framerate so
100
+ # that the application doesn't use too much CPU time. See also
101
+ # Clock#tick for a good and easy way to limit the framerate.
102
+ #
103
+ # The accuracy of this function depends on processor scheduling,
104
+ # which varies with operating system and hardware. The actual delay
105
+ # time may be up to 10ms longer than +time+. If you need more
106
+ # accuracy use Clock.delay, which is more accurate but uses slightly
107
+ # more CPU time.
108
+ #
109
+ # If +nice+ is true, this function will try to allow other ruby
110
+ # threads to run during this function. Otherwise, other ruby threads
111
+ # will probably also be paused. Setting +nice+ to true is only
112
+ # useful if your application is multithreaded. It's safe (but
113
+ # pointless) to use this feature for single threaded applications.
114
+ #
115
+ # The Rubygame timer system will be initialized when you call this
116
+ # function, if it has not been already. See Clock.runtime.
117
+ #
118
+ def wait( time, nice=false )
119
+ _init_sdl_timer
120
+ time = 0 if time < 0
121
+ _threaded_delay( time, nice )
122
+ end
123
+
124
+
125
+ # Return the number of milliseconds since the Rubygame timer
126
+ # system was initialized.
127
+ #
128
+ # The Rubygame timer system will be initialized when you call
129
+ # this function, if it has not been already.
130
+ #
131
+ def runtime
132
+ SDL.GetTicks().to_i
133
+ end
134
+
135
+
136
+
137
+ private
138
+
139
+
140
+ # Initialize the SDL timer system, if it hasn't been already.
141
+ def _init_sdl_timer
142
+ if( SDL.WasInit( SDL::INIT_TIMER ) == 0 )
143
+ if( SDL.InitSubSystem( SDL::INIT_TIMER ) != 0)
144
+ raise( Rubygame::SDLError,
145
+ "Could not initialize timer system: #{SDL.GetError()}" )
146
+ end
147
+ end
148
+ end
149
+
150
+
151
+ # Delays for the given amount of time, but possibly split into
152
+ # small parts. Control is given to ruby between each part, so
153
+ # that other threads can run.
154
+ #
155
+ # delay: How many milliseconds to delay.
156
+ # nice: If true, split the delay into smaller parts and
157
+ # allow other ruby threads to run between each part.
158
+ #
159
+ def _threaded_delay( delay, nice )
160
+ start = SDL.GetTicks()
161
+ stop = start + delay
162
+
163
+ if nice
164
+ while( SDL.GetTicks() < stop )
165
+ SDL.Delay(1)
166
+ end
167
+ else
168
+ SDL.Delay( delay.to_i )
169
+ end
170
+
171
+ return (SDL.GetTicks() - start).to_i
172
+ end
173
+
174
+
175
+ # Based on pygame code, with a few modifications:
176
+ # - takes 'accuracy' argument
177
+ # - ruby syntax for raising exceptions
178
+ # - uses rg_threaded_delay
179
+ #
180
+ def _accurate_delay( ticks, accuracy, nice )
181
+ return _threaded_delay( ticks, nice ) if( accuracy <= 0 )
182
+
183
+ start = SDL.GetTicks()
184
+
185
+ if( ticks >= accuracy )
186
+ delay = ticks - (ticks % accuracy)
187
+ delay -= 2 # Aim low so we don't overshoot.
188
+
189
+ if( delay >= accuracy and delay > 0 )
190
+ _threaded_delay( delay, nice )
191
+ end
192
+ end
193
+
194
+ delay = ticks - (SDL.GetTicks() - start)
195
+ while( delay > 0 )
196
+ delay = ticks - (SDL.GetTicks() - start)
197
+ end
198
+
199
+ return (SDL.GetTicks() - start).to_i
200
+ end
201
+
202
+ end
203
+
204
+
205
+
206
+
44
207
  # The runtime when the Clock was initialized.
45
208
  attr_reader :start
46
209