sdl2_ffi 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +21 -59
  3. data/lib/sdl2.rb +52 -15
  4. data/lib/sdl2/application.rb +71 -0
  5. data/lib/sdl2/audio.rb +72 -24
  6. data/lib/sdl2/clipboard.rb +9 -3
  7. data/lib/sdl2/color.rb +8 -3
  8. data/lib/sdl2/cpuinfo.rb +30 -10
  9. data/lib/sdl2/engine.rb +52 -0
  10. data/lib/sdl2/engine/block_engine.rb +27 -0
  11. data/lib/sdl2/engine/engines.rb +46 -0
  12. data/lib/sdl2/error.rb +9 -3
  13. data/lib/sdl2/events.rb +68 -6
  14. data/lib/sdl2/gamecontroller.rb +60 -20
  15. data/lib/sdl2/gem_version.rb +1 -1
  16. data/lib/sdl2/gesture.rb +12 -4
  17. data/lib/sdl2/haptic.rb +90 -30
  18. data/lib/sdl2/hints.rb +12 -4
  19. data/lib/sdl2/image.rb +85 -3
  20. data/lib/sdl2/init.rb +15 -5
  21. data/lib/sdl2/joystick.rb +63 -21
  22. data/lib/sdl2/keyboard.rb +101 -17
  23. data/lib/sdl2/keycode.rb +72 -72
  24. data/lib/sdl2/library.rb +7 -0
  25. data/lib/sdl2/log.rb +78 -21
  26. data/lib/sdl2/mixer.rb +651 -0
  27. data/lib/sdl2/mixer/chunk.rb +47 -0
  28. data/lib/sdl2/mixer/lib_paths.rb +8 -0
  29. data/lib/sdl2/mouse.rb +39 -13
  30. data/lib/sdl2/pixels.rb +39 -13
  31. data/lib/sdl2/point.rb +29 -0
  32. data/lib/sdl2/power.rb +3 -1
  33. data/lib/sdl2/rect.rb +94 -19
  34. data/lib/sdl2/render.rb +156 -52
  35. data/lib/sdl2/rwops.rb +60 -20
  36. data/lib/sdl2/surface.rb +85 -28
  37. data/lib/sdl2/syswm.rb +3 -1
  38. data/lib/sdl2/timer.rb +18 -6
  39. data/lib/sdl2/touch.rb +12 -4
  40. data/lib/sdl2/ttf.rb +153 -59
  41. data/lib/sdl2/ttf/font.rb +21 -5
  42. data/lib/sdl2/version.rb +9 -3
  43. data/lib/sdl2/video.rb +210 -70
  44. data/lib/sdl2/window.rb +9 -3
  45. data/spec/fixtures/approvals/lazyfoonet_lesson_07_true_type_fonts/draws_the_message_to_the_screen.approved.png +0 -0
  46. data/spec/fixtures/approvals/lazyfoonet_lesson_07_true_type_fonts/writes_a_message_to_a_surface.approved.png +0 -0
  47. data/spec/fixtures/approvals/lazyfoonet_lesson_09_mouse_events/defaults_to_mouse_out.approved.png +0 -0
  48. data/spec/fixtures/approvals/lazyfoonet_lesson_09_mouse_events/has_a_button_sheet.approved.png +0 -0
  49. data/spec/fixtures/approvals/lazyfoonet_lesson_09_mouse_events/shows_mouse_down.approved.png +0 -0
  50. data/spec/fixtures/approvals/lazyfoonet_lesson_09_mouse_events/shows_mouse_in.approved.png +0 -0
  51. data/spec/fixtures/approvals/lazyfoonet_lesson_09_mouse_events/shows_mouse_out.approved.png +0 -0
  52. data/spec/fixtures/approvals/lazyfoonet_lesson_09_mouse_events/shows_mouse_up.approved.png +0 -0
  53. data/spec/fixtures/images/button_sheet.png +0 -0
  54. data/spec/functional/lazy_foo_tutorial/lazy_foo_01_hello_world_spec.rb +9 -2
  55. data/spec/functional/lazy_foo_tutorial/lazy_foo_03_extension_libraries_spec.rb +1 -0
  56. data/spec/functional/lazy_foo_tutorial/lazy_foo_04_event_driven_programming_spec.rb +4 -3
  57. data/spec/functional/lazy_foo_tutorial/lazy_foo_05_color_keying_spec.rb +1 -1
  58. data/spec/functional/lazy_foo_tutorial/lazy_foo_06_clip_blitting_and_sprite_sheets_spec.rb +4 -3
  59. data/spec/functional/lazy_foo_tutorial/lazy_foo_07_true_type_fonts_spec.rb +4 -2
  60. data/spec/functional/lazy_foo_tutorial/lazy_foo_08_key_presses_spec.rb +10 -22
  61. data/spec/functional/lazy_foo_tutorial/lazy_foo_09_mouse_events_spec.rb +121 -0
  62. data/spec/functional/lazy_foo_tutorial/lazy_foo_10_key_states_spec.rb +30 -0
  63. data/spec/functional/lazy_foo_tutorial/lazy_foo_11_playing_sounds_spec.rb +116 -0
  64. data/spec/functional/lazy_foo_tutorial/lazy_foo_12_timing_spec.rb +57 -0
  65. data/spec/spec_helper.rb +3 -1
  66. metadata +31 -2
data/lib/sdl2/keycode.rb CHANGED
@@ -3,7 +3,7 @@ require 'sdl2/scancode'
3
3
 
4
4
  module SDL2
5
5
 
6
- typedef :int32, :keycode
6
+ #typedef :int32, :keycode
7
7
  typedef :int32, :scancode
8
8
 
9
9
  # TODO: Review if I translated lines 44~45 right.
@@ -17,76 +17,76 @@ module SDL2
17
17
  include EnumerableConstants
18
18
  UNKNOWN = 0
19
19
 
20
- RETURN = '\r'
21
- ESCAPE = '\033'
22
- BACKSPACE = '\b'
23
- TAB = '\t'
24
- SPACE = ' '
25
- EXCLAIM = '!'
26
- QUOTEDBL = '"'
27
- HASH = '#'
28
- PERCENT = '%'
29
- DOLLAR = '$'
30
- AMPERSAND = '&'
31
- QUOTE = '\''
32
- LEFTPAREN = '('
33
- RIGHTPAREN = ')'
34
- ASTERISK = '*'
35
- PLUS = '+'
36
- COMMA = ','
37
- MINUS = '-'
38
- PERIOD = '.'
39
- SLASH = '/'
40
- N0 = '0'
41
- N1 = '1'
42
- N2 = '2'
43
- N3 = '3'
44
- N4 = '4'
45
- N5 = '5'
46
- N6 = '6'
47
- N7 = '7'
48
- N8 = '8'
49
- N9 = '9'
50
- COLON = ':'
51
- SEMICOLON = ';'
52
- LESS = '<'
53
- EQUALS = '='
54
- GREATER = '>'
55
- QUESTION = '?'
56
- AT = '@'
20
+ RETURN = '\r'.codepoints()[0]
21
+ ESCAPE = '\033'.codepoints()[0]
22
+ BACKSPACE = '\b'.codepoints()[0]
23
+ TAB = '\t'.codepoints()[0]
24
+ SPACE = ' '.codepoints()[0]
25
+ EXCLAIM = '!'.codepoints()[0]
26
+ QUOTEDBL = '"'.codepoints()[0]
27
+ HASH = '#'.codepoints()[0]
28
+ PERCENT = '%'.codepoints()[0]
29
+ DOLLAR = '$'.codepoints()[0]
30
+ AMPERSAND = '&'.codepoints()[0]
31
+ QUOTE = '\''.codepoints()[0]
32
+ LEFTPAREN = '('.codepoints()[0]
33
+ RIGHTPAREN = ')'.codepoints()[0]
34
+ ASTERISK = '*'.codepoints()[0]
35
+ PLUS = '+'.codepoints()[0]
36
+ COMMA = ','.codepoints()[0]
37
+ MINUS = '-'.codepoints()[0]
38
+ PERIOD = '.'.codepoints()[0]
39
+ SLASH = '/'.codepoints()[0]
40
+ N0 = '0'.codepoints()[0]
41
+ N1 = '1'.codepoints()[0]
42
+ N2 = '2'.codepoints()[0]
43
+ N3 = '3'.codepoints()[0]
44
+ N4 = '4'.codepoints()[0]
45
+ N5 = '5'.codepoints()[0]
46
+ N6 = '6'.codepoints()[0]
47
+ N7 = '7'.codepoints()[0]
48
+ N8 = '8'.codepoints()[0]
49
+ N9 = '9'.codepoints()[0]
50
+ COLON = ':'.codepoints()[0]
51
+ SEMICOLON = ';'.codepoints()[0]
52
+ LESS = '<'.codepoints()[0]
53
+ EQUALS = '='.codepoints()[0]
54
+ GREATER = '>'.codepoints()[0]
55
+ QUESTION = '?'.codepoints()[0]
56
+ AT = '@'.codepoints()[0]
57
57
 
58
- LEFTBRACKET = '['
59
- BACKSLASH = '\\'
60
- RIGHTBRACKET = ']'
61
- CARET = '^'
62
- UNDERSCORE = '_'
63
- BACKQUOTE = '`'
64
- a = 'a'
65
- b = 'b'
66
- c = 'c'
67
- d = 'd'
68
- e = 'e'
69
- f = 'f'
70
- g = 'g'
71
- h = 'h'
72
- i = 'i'
73
- j = 'j'
74
- k = 'k'
75
- l = 'l'
76
- m = 'm'
77
- n = 'n'
78
- o = 'o'
79
- p = 'p'
80
- q = 'q'
81
- r = 'r'
82
- s = 's'
83
- t = 't'
84
- u = 'u'
85
- v = 'v'
86
- w = 'w'
87
- x = 'x'
88
- y = 'y'
89
- z = 'z'
58
+ LEFTBRACKET = '['.codepoints()[0]
59
+ BACKSLASH = '\\'.codepoints()[0]
60
+ RIGHTBRACKET = ']'.codepoints()[0]
61
+ CARET = '^'.codepoints()[0]
62
+ UNDERSCORE = '_'.codepoints()[0]
63
+ BACKQUOTE = '`'.codepoints()[0]
64
+ A = 'a'.codepoints()[0]
65
+ B = 'b'.codepoints()[0]
66
+ C = 'c'.codepoints()[0]
67
+ D = 'd'.codepoints()[0]
68
+ E = 'e'.codepoints()[0]
69
+ F = 'f'.codepoints()[0]
70
+ G = 'g'.codepoints()[0]
71
+ H = 'h'.codepoints()[0]
72
+ I = 'i'.codepoints()[0]
73
+ J = 'j'.codepoints()[0]
74
+ K = 'k'.codepoints()[0]
75
+ L = 'l'.codepoints()[0]
76
+ M = 'm'.codepoints()[0]
77
+ N = 'n'.codepoints()[0]
78
+ O = 'o'.codepoints()[0]
79
+ P = 'p'.codepoints()[0]
80
+ Q = 'q'.codepoints()[0]
81
+ R = 'r'.codepoints()[0]
82
+ S = 's'.codepoints()[0]
83
+ T = 't'.codepoints()[0]
84
+ U = 'u'.codepoints()[0]
85
+ V = 'v'.codepoints()[0]
86
+ W = 'w'.codepoints()[0]
87
+ X = 'x'.codepoints()[0]
88
+ Y = 'y'.codepoints()[0]
89
+ Z = 'z'.codepoints()[0]
90
90
 
91
91
  CAPSLOCK = SDL2.scancode_to_keycode(SCANCODE::CAPSLOCK)
92
92
 
@@ -109,7 +109,7 @@ module SDL2
109
109
  INSERT = SDL2.scancode_to_keycode(SCANCODE::INSERT)
110
110
  HOME = SDL2.scancode_to_keycode(SCANCODE::HOME)
111
111
  PAGEUP = SDL2.scancode_to_keycode(SCANCODE::PAGEUP)
112
- DELETE = '\177'
112
+ DELETE = '\177'.codepoints()[0]
113
113
  END_ = SDL2.scancode_to_keycode(SCANCODE::END_)
114
114
  PAGEDOWN = SDL2.scancode_to_keycode(SCANCODE::PAGEDOWN)
115
115
  RIGHT = SDL2.scancode_to_keycode(SCANCODE::RIGHT)
@@ -264,7 +264,7 @@ module SDL2
264
264
  KBDILLUMUP = SDL2.scancode_to_keycode(SCANCODE::KBDILLUMUP)
265
265
  EJECT = SDL2.scancode_to_keycode(SCANCODE::EJECT)
266
266
  SLEEP = SDL2.scancode_to_keycode(SCANCODE::SLEEP)
267
- end
267
+ end
268
268
 
269
269
  enum :keycode, KEYCODE.flatten_consts
270
270
 
data/lib/sdl2/library.rb CHANGED
@@ -22,6 +22,8 @@ module SDL2
22
22
  "IMG_"
23
23
  when "SDL2::TTF"
24
24
  "TTF_"
25
+ when "SDL2::Mixer"
26
+ "Mix_"
25
27
  else
26
28
  $stderr.puts("Library#api does not know how to handle module: #{self.to_s}")
27
29
  /[A-Z][A-Z|0-9]*_/
@@ -31,6 +33,11 @@ module SDL2
31
33
  methodName = ActiveSupport::Inflector.underscore(camelCaseName).to_sym
32
34
 
33
35
  attach_function methodName, func_name, args, type
36
+
37
+ metaclass.instance_eval do
38
+ alias_method func_name, methodName
39
+ end
40
+ alias_method func_name, methodName
34
41
 
35
42
  if options[:error]
36
43
  returns_error(methodName, options[:filter])
data/lib/sdl2/log.rb CHANGED
@@ -2,69 +2,126 @@ require 'sdl2'
2
2
 
3
3
  module SDL2
4
4
 
5
- class Log
6
- private_class_method :new # Disable creation
5
+ module Log
7
6
 
7
+ module PRIORITY
8
+ include EnumerableConstants
9
+
10
+ VERBOSE = 1
11
+ DEBUG = next_const_value
12
+ INFO = next_const_value
13
+ WARN = next_const_value
14
+ ERROR = next_const_value
15
+ CRITICAL= next_const_value
16
+
17
+ end
18
+
19
+ module CATEGORY
20
+ include EnumerableConstants
21
+ APPLICATION = next_const_value
22
+ ERROR = next_const_value
23
+ ASSERT = next_const_value
24
+ SYSTEM = next_const_value
25
+ AUDIO = next_const_value
26
+ VIDEO = next_const_value
27
+ RENDER = next_const_value
28
+ INPUT = next_const_value
29
+ TEST = next_const_value
30
+ RESERVED1 = next_const_value
31
+ RESERVED2 = next_const_value
32
+ RESERVED3 = next_const_value
33
+ RESERVED4 = next_const_value
34
+ RESERVED5 = next_const_value
35
+ RESERVED6 = next_const_value
36
+ RESERVED7 = next_const_value
37
+ RESERVED8 = next_const_value
38
+ RESERVED9 = next_const_value
39
+ RESERVED10 = next_const_value
40
+ CUSTOM = next_const_value
41
+ end
8
42
  def self.<<(msg, *args)
9
43
  SDL2.log(msg, *args)
10
44
  end
11
-
45
+
12
46
  def self.critical(category, msg, *args)
13
47
  SDL2.log_critical(category, msg, *args)
14
48
  end
15
-
49
+
16
50
  def self.debug(category, msg, *args)
17
51
  SDL2.log_debug(category, msg, *args)
18
52
  end
19
-
53
+
20
54
  def self.error(category, msg, *args)
21
55
  SDL2.log_error(category, msg, *args)
22
56
  end
23
-
57
+
24
58
  def self.warn(category, msg, *args)
25
- SDL2.log_warn(category, msg, *args)
59
+ SDL2.log_warn(category, msg, *args)
26
60
  end
27
-
61
+
28
62
  def self.verbose(category, msg, *args)
29
63
  SDL2.log_verbose(category, msg, *args)
30
64
  end
31
-
65
+
32
66
  def self.set_priority(category, priority)
33
67
  SDL2.log_set_priority(category, priority)
34
68
  end
35
-
69
+
36
70
  def self.get_priority(category)
37
71
  SDL2.log_get_priority(category)
38
72
  end
39
73
  end
40
74
 
41
- enum :log_priority, [:verbose, 1, :debug, :info, :warn, :error, :critical]
42
-
43
- enum :log_category, [
44
- :application, :error, :assert, :system, :audio, :video, :render, :input, :test,
45
- :reserved1,:reserved2,:reserved3,:reserved4,:reserved5,
46
- :reserved6,:reserved7,:reserved8,:reserved9,:reserved10,
47
- :custom
48
- ]
49
-
50
-
51
-
75
+ enum :log_priority, Log::PRIORITY.flatten_consts
76
+
77
+ enum :log_category, Log::CATEGORY.flatten_consts
78
+
52
79
  callback :log_output_function, [:pointer, :log_category, :log_priority, :string], :void
53
80
 
81
+ ##
82
+ #
54
83
  api :SDL_Log, [:string, :varargs], :void
84
+ ##
85
+ #
55
86
  api :SDL_LogCritical, [:log_category, :string, :varargs], :void
87
+ ##
88
+ #
56
89
  api :SDL_LogDebug, [:log_category, :string, :varargs], :void
90
+ ##
91
+ #
57
92
  api :SDL_LogError, [:log_category, :string, :varargs], :void
93
+ ##
94
+ #
58
95
  api :SDL_LogInfo, [:log_category, :string, :varargs], :void
96
+ ##
97
+ #
59
98
  api :SDL_LogVerbose, [:log_category, :string, :varargs], :void
99
+ ##
100
+ #
60
101
  api :SDL_LogWarn, [:log_category, :string, :varargs], :void
102
+ ##
103
+ #
61
104
  api :SDL_LogMessage, [:log_category, :log_priority, :string, :varargs], :void
105
+ ##
106
+ #
62
107
  api :SDL_LogMessageV, [:log_category, :log_priority, :string, :varargs], :void
108
+ ##
109
+ #
63
110
  api :SDL_LogResetPriorities, [], :void
111
+ ##
112
+ #
64
113
  api :SDL_LogSetAllPriority, [:log_priority], :void
114
+ ##
115
+ #
65
116
  api :SDL_LogGetOutputFunction, [:log_output_function, :pointer], :void
117
+ ##
118
+ #
66
119
  api :SDL_LogSetOutputFunction, [:log_output_function, :pointer], :void
120
+ ##
121
+ #
67
122
  api :SDL_LogSetPriority, [:log_category, :log_priority], :void
123
+ ##
124
+ #
68
125
  api :SDL_LogGetPriority, [:log_category], :log_priority
69
126
 
70
127
  end
data/lib/sdl2/mixer.rb ADDED
@@ -0,0 +1,651 @@
1
+ require 'sdl2'
2
+ require 'sdl2/version'
3
+ require 'sdl2/rwops'
4
+ require 'sdl2/mixer/lib_paths'
5
+ require 'sdl2/mixer/chunk'
6
+
7
+ module SDL2
8
+
9
+ # Interface for "SDL_mixer.h"
10
+ module Mixer
11
+ extend FFI::Library
12
+ extend SDL2::Library
13
+ ffi_lib Mixer::LibPaths
14
+
15
+ # Good default values for a PC soundcard
16
+ DEFAULT_FREQUENCY = 22050
17
+ DEFAULT_FORMAT = Audio::S16LSB
18
+ DEFAULT_CHANNELS = 2
19
+ MAX_VOLUME = 128
20
+ # The default mixer has 8 simultaneous mixing channels
21
+ CHANNELS = 8
22
+
23
+ # Values to be combined and used with Mixer::init()
24
+ module INIT
25
+ include EnumerableConstants
26
+
27
+ FLAC = 0x00000001
28
+ MOD = 0x00000002
29
+ MODPLUG = 0x00000004
30
+ MP3 = 0x00000008
31
+ OGG = 0x00000010
32
+ FLUIDSYNTH = 0x00000020
33
+
34
+ end
35
+ ##
36
+ # This function gets the version of the dynamically linked SDL_mixer library.
37
+ # :method: linked_version
38
+ api :Mix_Linked_Version, [], Version.auto_ptr
39
+
40
+ enum :init_flags, INIT.flatten_consts
41
+
42
+ ##
43
+ # Loads dynamic libraries and prepares them for use. Flags should be
44
+ # one or more flags from MIX_InitFlags OR'd together.
45
+ # It returns the flags successfully initialized, or 0 on failure.
46
+ # :call-seq:
47
+ # Mix_Init(flags)
48
+ # init(flags)
49
+ # init!(flags)
50
+ api :Mix_Init, [:init_flags], :int, {error: true, filter: TRUE_WHEN_NOT_ZERO}
51
+
52
+ ##
53
+ # Unloads libraries loaded with Mix_Init
54
+ # :call-seq:
55
+ # Mix_Quit()
56
+ # quit()
57
+ api :Mix_Quit, [], :void
58
+
59
+ module FADING
60
+ include EnumerableConstants
61
+ NO = next_const_value
62
+ OUT = next_const_value
63
+ IN = next_const_value
64
+ end
65
+
66
+ enum :fading, FADING.flatten_consts
67
+
68
+ class Music < Struct
69
+
70
+ module TYPE
71
+ include EnumerableConstants
72
+ NONE = next_const_value
73
+ CMD = next_const_value
74
+ WAV = next_const_value
75
+ MOD = next_const_value
76
+ MID = next_const_value
77
+ OGG = next_const_value
78
+ MP3 = next_const_value
79
+ MP3_MAD = next_const_value
80
+ FLAC = next_const_value
81
+ MODPLUG = next_const_value
82
+ end
83
+ end
84
+ enum :music_type, Music::TYPE.flatten_consts
85
+
86
+ class Music
87
+ layout :type, :music_type,
88
+ :data, :pointer,
89
+ :fading, :fading,
90
+ :fade_step, :int,
91
+ :fade_steps, :int,
92
+ :error, :int
93
+
94
+ def self.load(filepath)
95
+ Mixer::load_mus!(filepath)
96
+ end
97
+
98
+ def self.playing?
99
+ Mixer::playing_music?
100
+ end
101
+
102
+ def self.paused?
103
+ Mixer::paused_music?
104
+ end
105
+
106
+ def self.resume
107
+ Mixer::resume_music
108
+ end
109
+
110
+ def self.pause
111
+ Mixer::pause_music
112
+ end
113
+ end
114
+
115
+ ##
116
+ # Open the mixer with a certain audio format
117
+ # :call-seq:
118
+ # open_audio(frequency, format, channels, chunksize)
119
+ # open_audio!(frequency, format, channels, chunksize)
120
+ #
121
+ api :Mix_OpenAudio, [:int, :uint16, :int, :int], :int, {error: true}
122
+
123
+ ##
124
+ # Dynamically change the number of channels managed by the mixer.
125
+ # If decreasing the number of channels, the upper channels are
126
+ # stopped.
127
+ # This function returns the new number of allocated channels.
128
+ # :call-seq:
129
+ # allocate_channels(numchans)
130
+ api :Mix_AllocateChannels, [:int], :int
131
+
132
+ ##
133
+ # Find out what the actual audio device parameters are.
134
+ # This function returns 1 if the audio has been opened, 0 otherwise.
135
+ # :call-seq:
136
+ # query_spec(freq_ptr, format_ptr, channels_ptr)
137
+ api :Mix_QuerySpec, [:pointer, :pointer, :pointer], :int
138
+
139
+ ##
140
+ # Load a wave file
141
+ # :call-seq:
142
+ # load_wav_rw(src_rwops, freesrc)
143
+ api :Mix_LoadWAV_RW, [RWops.by_ref, :int], Chunk.auto_ptr
144
+
145
+ ##
146
+ # Load a wave file or a music (.mod .s3m .it .xm) file
147
+ def self.load_wav(filename)
148
+ Mixer::load_wav_rw(RWops.from_file(filename, "rb"), 1)
149
+ end
150
+
151
+ returns_error :load_wav, TRUE_WHEN_NOT_NULL
152
+
153
+ ##
154
+ # Load a wave file or a music (.mod .s3m .it .xm) file
155
+ # :call-seq:
156
+ # load_mus(filepath)
157
+ api :Mix_LoadMUS, [:string], Music.auto_ptr, {error: true, filter: TRUE_WHEN_NOT_NULL}
158
+
159
+ ##
160
+ # Load a music file from an SDL_RWop object (Ogg and MikMod specific currently)
161
+ # Matt Campbell (matt@campbellhome.dhs.org) April 2000
162
+ api :Mix_LoadMUS_RW, [RWops.by_ref, :int], Music.auto_ptr
163
+
164
+ ##
165
+ # Load a music file from an SDL_RWop object assuming a specific format
166
+ api :Mix_LoadMUSType_RW, [RWops.by_ref, :music_type, :int], Music.auto_ptr
167
+
168
+ ##
169
+ # Load a wave file of the mixer format from a memory buffer
170
+ api :Mix_QuickLoad_WAV, [:pointer], Chunk.auto_ptr
171
+
172
+ ##
173
+ # Load raw audio data of the mixer format from a memory buffer
174
+ api :Mix_QuickLoad_RAW, [:pointer, :uint32], Chunk.auto_ptr
175
+
176
+ ##
177
+ # Free an audio chunk previously loaded
178
+ api :Mix_FreeChunk, [Chunk.by_ref], :void
179
+
180
+ ##
181
+ # Free music previously loaded
182
+ api :Mix_FreeMusic, [Music.by_ref], :void
183
+
184
+ ##
185
+ # Get a list of chunk/music decoders that this build of SDL_mixer provides.
186
+ # This list can change between builds AND runs of the program, if external
187
+ # libraries that add functionality become available.
188
+ # You must successfully call Mix_OpenAudio() before calling these functions.
189
+ # This API is only available in SDL_mixer 1.2.9 and later.
190
+ #
191
+ # // usage...
192
+ # int i;
193
+ # const int total = Mix_GetNumChunkDecoders();
194
+ # for (i = 0; i < total; i++)
195
+ # printf("Supported chunk decoder: [%s]\n", Mix_GetChunkDecoder(i));
196
+ #
197
+ # Appearing in this list doesn't promise your specific audio file will
198
+ # decode...but it's handy to know if you have, say, a functioning Timidity
199
+ # install.
200
+ #
201
+ # These return values are static, read-only data; do not modify or free it.
202
+ # The pointers remain valid until you call Mix_CloseAudio().
203
+ #
204
+ api :Mix_GetNumChunkDecoders, [], :int
205
+ api :Mix_GetChunkDecoder, [:int], :string
206
+ api :Mix_GetNumMusicDecoders, [], :int
207
+ api :Mix_GetMusicDecoder, [:int], :string
208
+
209
+ ##
210
+ # Find out the music format of a mixer music, or the currently playing
211
+ # music, if 'music' is NULL.
212
+ api :Mix_GetMusicType, [Music.by_ref], :music_type
213
+
214
+ callback :mix_func, [:pointer, :pointer, :int], :void
215
+
216
+ ##
217
+ # Set a function that is called after all mixing is performed.
218
+ # This can be used to provide real-time visual display of the audio stream
219
+ # or add a custom mixer filter for the stream data.
220
+ # :call-seq:
221
+ # set_post_mix(Proc.new{|user_data_ptr, stream_ptr, length| ... })
222
+ api :Mix_SetPostMix, [:mix_func], :void
223
+
224
+ ##
225
+ # Add your own music player or additional mixer function.
226
+ # If 'mix_func' is NULL, the default music player is re-enabled.
227
+ # :call-seq:
228
+ # set_hook_music(Proc.new{|user_data_ptr, stream_ptr, length| ... })
229
+ api :Mix_HookMusic, [:mix_func], :void
230
+
231
+ ##
232
+ # Callback: music_finished
233
+ callback :music_finished, [], :void
234
+
235
+ ##
236
+ # Add your own callback when the music has finsihed playing.
237
+ # This callback is only called if the music finishes naturally.
238
+ # :call-seq:
239
+ # hook_music_finished(Proc.new {|| ...})
240
+ api :Mix_HookMusicFinished, [:music_finished], :void
241
+
242
+ ##
243
+ # Get a pointer to the user data for the current music hook
244
+ api :Mix_GetMusicHookData, [], :pointer
245
+
246
+ ##
247
+ # Add your own callback when a channel has finished playing. NULL
248
+ # to disable callback. The callback may be called from the mixer's audio
249
+ # callback or it could be called as a result of Mix_HaltChannel(), etc.
250
+ # do not call SDL_LockAudio() from this callback; you will either be
251
+ # inside the audio callback, or SDL_mixer will explicitly lock the audio
252
+ # before calling your callback.
253
+ api :Mix_ChannelFinished, [:pointer, :int], :void
254
+
255
+ # Special Effects API by ryan c. gordon.....
256
+ CHANNEL_POST = -2
257
+
258
+ ##
259
+ # This is the format of a special effect callback:
260
+ #
261
+ # myeffect(int chan, void *stream, int len, void *udata);
262
+ #
263
+ # (chan) is the channel number that your effect is affecting. (stream) is
264
+ # the buffer of data to work upon. (len) is the size of (stream), and
265
+ # (udata) is a user-defined bit of data, which you pass as the last arg of
266
+ # Mix_RegisterEffect(), and is passed back unmolested to your callback.
267
+ # Your effect changes the contents of (stream) based on whatever parameters
268
+ # are significant, or just leaves it be, if you prefer. You can do whatever
269
+ # you like to the buffer, though, and it will continue in its changed state
270
+ # down the mixing pipeline, through any other effect functions, then finally
271
+ # to be mixed with the rest of the channels and music for the final output
272
+ # stream.
273
+ #
274
+ # DO NOT EVER call SDL_LockAudio() from your callback function!
275
+ #
276
+ callback :effect_func, [:int, :pointer, :int, :pointer], :void
277
+
278
+ ##
279
+ # This is a callback that signifies that a channel has finished all its
280
+ # loops and has completed playback. This gets called if the buffer
281
+ # plays out normally, or if you call Mix_HaltChannel(), implicitly stop
282
+ # a channel via Mix_AllocateChannels(), or unregister a callback while
283
+ # it's still playing.
284
+ #
285
+ # DO NOT EVER call SDL_LockAudio() from your callback function!
286
+ callback :effect_done, [:int, :pointer], :void
287
+
288
+ ##
289
+ # Register a special effect function. At mixing time, the channel data is
290
+ # copied into a buffer and passed through each registered effect function.
291
+ # After it passes through all the functions, it is mixed into the final
292
+ # output stream. The copy to buffer is performed once, then each effect
293
+ # function performs on the output of the previous effect. Understand that
294
+ # this extra copy to a buffer is not performed if there are no effects
295
+ # registered for a given chunk, which saves CPU cycles, and any given
296
+ # effect will be extra cycles, too, so it is crucial that your code run
297
+ # fast. Also note that the data that your function is given is in the
298
+ # format of the sound device, and not the format you gave to Mix_OpenAudio(),
299
+ # although they may in reality be the same. This is an unfortunate but
300
+ # necessary speed concern. Use Mix_QuerySpec() to determine if you can
301
+ # handle the data before you register your effect, and take appropriate
302
+ # actions.
303
+ # You may also specify a callback (Mix_EffectDone_t) that is called when
304
+ # the channel finishes playing. This gives you a more fine-grained control
305
+ # than Mix_ChannelFinished(), in case you need to free effect-specific
306
+ # resources, etc. If you don't need this, you can specify NULL.
307
+ # You may set the callbacks before or after calling Mix_PlayChannel().
308
+ # Things like Mix_SetPanning() are just internal special effect functions,
309
+ # so if you are using that, you've already incurred the overhead of a copy
310
+ # to a separate buffer, and that these effects will be in the queue with
311
+ # any functions you've registered. The list of registered effects for a
312
+ # channel is reset when a chunk finishes playing, so you need to explicitly
313
+ # set them with each call to Mix_PlayChannel*().
314
+ # You may also register a special effect function that is to be run after
315
+ # final mixing occurs. The rules for these callbacks are identical to those
316
+ # in Mix_RegisterEffect, but they are run after all the channels and the
317
+ # music have been mixed into a single stream, whereas channel-specific
318
+ # effects run on a given channel before any other mixing occurs. These
319
+ # global effect callbacks are call "posteffects". Posteffects only have
320
+ # their Mix_EffectDone_t function called when they are unregistered (since
321
+ # the main output stream is never "done" in the same sense as a channel).
322
+ # You must unregister them manually when you've had enough. Your callback
323
+ # will be told that the channel being mixed is (MIX_CHANNEL_POST) if the
324
+ # processing is considered a posteffect.
325
+ #
326
+ # After all these effects have finished processing, the callback registered
327
+ # through Mix_SetPostMix() runs, and then the stream goes to the audio
328
+ # device.
329
+ #
330
+ # DO NOT EVER call SDL_LockAudio() from your callback function!
331
+ #
332
+ # returns zero if error (no such channel), nonzero if added.
333
+ # Error messages can be retrieved from Mix_GetError().
334
+ api :Mix_RegisterEffect, [:int, :effect_func, :effect_done, :pointer], :int
335
+
336
+ ##
337
+ # You may not need to call this explicitly, unless you need to stop an
338
+ # effect from processing in the middle of a chunk's playback.
339
+ # Posteffects are never implicitly unregistered as they are for channels,
340
+ # but they may be explicitly unregistered through this function by
341
+ # specifying MIX_CHANNEL_POST for a channel.
342
+ # returns zero if error (no such channel or effect), nonzero if removed.
343
+ # Error messages can be retrieved from Mix_GetError().
344
+ api :Mix_UnregisterEffect, [:int, :effect_func], :int
345
+
346
+ ##
347
+ # You may not need to call this explicitly, unless you need to stop all
348
+ # effects from processing in the middle of a chunk's playback. Note that
349
+ # this will also shut off some internal effect processing, since
350
+ # Mix_SetPanning() and others may use this API under the hood. This is
351
+ # called internally when a channel completes playback.
352
+ # Posteffects are never implicitly unregistered as they are for channels,
353
+ # but they may be explicitly unregistered through this function by
354
+ # specifying MIX_CHANNEL_POST for a channel.
355
+ # returns zero if error (no such channel), nonzero if all effects removed.
356
+ # Error messages can be retrieved from Mix_GetError().
357
+ api :Mix_UnregisterAllEffects, [:int], :int
358
+
359
+ EFFECTSMAXSPEED = "MIX_EFFECTSMAXSPEED"
360
+
361
+ #
362
+ # These are the internally-defined mixing effects. They use the same API that
363
+ # effects defined in the application use, but are provided here as a
364
+ # convenience. Some effects can reduce their quality or use more memory in
365
+ # the name of speed; to enable this, make sure the environment variable
366
+ # MIX_EFFECTSMAXSPEED (see above) is defined before you call
367
+ # Mix_OpenAudio().
368
+ #
369
+
370
+ ##
371
+ # Set the panning of a channel. The left and right channels are specified
372
+ # as integers between 0 and 255, quietest to loudest, respectively.
373
+ #
374
+ # Technically, this is just individual volume control for a sample with
375
+ # two (stereo) channels, so it can be used for more than just panning.
376
+ # If you want real panning, call it like this:
377
+ #
378
+ # Mix_SetPanning(channel, left, 255 - left);
379
+ #
380
+ # ...which isn't so hard.
381
+ #
382
+ # Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and
383
+ # the panning will be done to the final mixed stream before passing it on
384
+ # to the audio device.
385
+ #
386
+ # This uses the Mix_RegisterEffect() API internally, and returns without
387
+ # registering the effect function if the audio device is not configured
388
+ # for stereo output. Setting both (left) and (right) to 255 causes this
389
+ # effect to be unregistered, since that is the data's normal state.
390
+ #
391
+ # returns zero if error (no such channel or Mix_RegisterEffect() fails),
392
+ # nonzero if panning effect enabled. Note that an audio device in mono
393
+ # mode is a no-op, but this call will return successful in that case.
394
+ # Error messages can be retrieved from Mix_GetError().
395
+ #
396
+ api :Mix_SetPanning, [:int, :uint8, :uint8], :int
397
+
398
+ ##
399
+ # Set the position of a channel. (angle) is an integer from 0 to 360, that
400
+ # specifies the location of the sound in relation to the listener. (angle)
401
+ # will be reduced as neccesary (540 becomes 180 degrees, -100 becomes 260).
402
+ # Angle 0 is due north, and rotates clockwise as the value increases.
403
+ # For efficiency, the precision of this effect may be limited (angles 1
404
+ # through 7 might all produce the same effect, 8 through 15 are equal, etc).
405
+ # (distance) is an integer between 0 and 255 that specifies the space
406
+ # between the sound and the listener. The larger the number, the further
407
+ # away the sound is. Using 255 does not guarantee that the channel will be
408
+ # culled from the mixing process or be completely silent. For efficiency,
409
+ # the precision of this effect may be limited (distance 0 through 5 might
410
+ # all produce the same effect, 6 through 10 are equal, etc). Setting (angle)
411
+ # and (distance) to 0 unregisters this effect, since the data would be
412
+ # unchanged.
413
+ #
414
+ # If you need more precise positional audio, consider using OpenAL for
415
+ # spatialized effects instead of SDL_mixer. This is only meant to be a
416
+ # basic effect for simple "3D" games.
417
+ #
418
+ # If the audio device is configured for mono output, then you won't get
419
+ # any effectiveness from the angle; however, distance attenuation on the
420
+ # channel will still occur. While this effect will function with stereo
421
+ # voices, it makes more sense to use voices with only one channel of sound,
422
+ # so when they are mixed through this effect, the positioning will sound
423
+ # correct. You can convert them to mono through SDL before giving them to
424
+ # the mixer in the first place if you like.
425
+ #
426
+ # Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and
427
+ # the positioning will be done to the final mixed stream before passing it
428
+ # on to the audio device.
429
+ #
430
+ # This is a convenience wrapper over Mix_SetDistance() and Mix_SetPanning().
431
+ #
432
+ # returns zero if error (no such channel or Mix_RegisterEffect() fails),
433
+ # nonzero if position effect is enabled.
434
+ # Error messages can be retrieved from Mix_GetError().
435
+ #
436
+ api :Mix_SetPosition, [:int, :int16, :uint8], :int
437
+
438
+ ##
439
+ # Set the "distance" of a channel. (distance) is an integer from 0 to 255
440
+ # that specifies the location of the sound in relation to the listener.
441
+ # Distance 0 is overlapping the listener, and 255 is as far away as possible
442
+ # A distance of 255 does not guarantee silence; in such a case, you might
443
+ # want to try changing the chunk's volume, or just cull the sample from the
444
+ # mixing process with Mix_HaltChannel().
445
+ # For efficiency, the precision of this effect may be limited (distances 1
446
+ # through 7 might all produce the same effect, 8 through 15 are equal, etc).
447
+ # (distance) is an integer between 0 and 255 that specifies the space
448
+ # between the sound and the listener. The larger the number, the further
449
+ # away the sound is.
450
+ # Setting (distance) to 0 unregisters this effect, since the data would be
451
+ # unchanged.
452
+ # If you need more precise positional audio, consider using OpenAL for
453
+ # spatialized effects instead of SDL_mixer. This is only meant to be a
454
+ # basic effect for simple "3D" games.
455
+ #
456
+ # Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and
457
+ # the distance attenuation will be done to the final mixed stream before
458
+ # passing it on to the audio device.
459
+ #
460
+ # This uses the Mix_RegisterEffect() API internally.
461
+ #
462
+ # returns zero if error (no such channel or Mix_RegisterEffect() fails),
463
+ # nonzero if position effect is enabled.
464
+ # Error messages can be retrieved from Mix_GetError().
465
+ #
466
+ api :Mix_SetDistance, [:int, :uint8], :int
467
+
468
+ ##
469
+ # Causes a channel to reverse its stereo. This is handy if the user has his
470
+ # speakers hooked up backwards, or you would like to have a minor bit of
471
+ # psychedelia in your sound code. :) Calling this function with (flip)
472
+ # set to non-zero reverses the chunks's usual channels. If (flip) is zero,
473
+ # the effect is unregistered.
474
+ #
475
+ # This uses the Mix_RegisterEffect() API internally, and thus is probably
476
+ # more CPU intensive than having the user just plug in his speakers
477
+ # correctly. Mix_SetReverseStereo() returns without registering the effect
478
+ # function if the audio device is not configured for stereo output.
479
+ #
480
+ # If you specify MIX_CHANNEL_POST for (channel), then this the effect is used
481
+ # on the final mixed stream before sending it on to the audio device (a
482
+ # posteffect).
483
+ #
484
+ # returns zero if error (no such channel or Mix_RegisterEffect() fails),
485
+ # nonzero if reversing effect is enabled. Note that an audio device in mono
486
+ # mode is a no-op, but this call will return successful in that case.
487
+ # Error messages can be retrieved from Mix_GetError().
488
+
489
+ api :Mix_SetReverseStereo, [:int, :int], :int
490
+
491
+ ##
492
+ # Reserve the first channels (0 -> n-1) for the application, i.e. don't allocate
493
+ # them dynamically to the next sample if requested with a -1 value below.
494
+ # Returns the number of reserved channels.
495
+ api :Mix_ReserveChannels, [:int], :int
496
+
497
+ ##
498
+ # Attach a tag to a channel. A tag can be assigned to several mixer
499
+ # channels, to form groups of channels.
500
+ # If 'tag' is -1, the tag is removed (actually -1 is the tag used to
501
+ # represent the group of all the channels).
502
+ # Returns true if everything was OK.
503
+ api :Mix_GroupChannel, [:int, :int], :int
504
+
505
+ ##
506
+ # Assign several consecutive channels to a group
507
+ api :Mix_GroupChannels, [:int, :int, :int], :int
508
+
509
+ ##
510
+ # Finds the first available channel in a group of channels,
511
+ # @returns -1 if none are available.
512
+ api :Mix_GroupAvailable, [:int], :int
513
+
514
+ ##
515
+ # Returns the number of channels in a group. This is also a subtle way
516
+ # to get the total number of channels when 'tag' is -1
517
+ api :Mix_GroupCount, [:int], :int
518
+
519
+ ##
520
+ # Finds the "oldest" sample playing in a group of channels
521
+ api :Mix_GroupOldest, [:int], :int
522
+
523
+ ##
524
+ # Finds the "most recent" (i.e. last) sample playing in a group of channels
525
+ api :Mix_GroupNewer, [:int], :int
526
+
527
+ # Play an audio chunk on a specific channel.
528
+ # If the specified channel is -1, play on the first free channel.
529
+ # If 'loops' is greater than zero, loop the sound that many times.
530
+ # If 'loops' is -1, loop inifinitely (~65000 times).
531
+ # Returns which channel was used to play the sound.
532
+ def self.play_channel(channel,chunk,loops=-1)
533
+ Mixer::play_channel_timed(channel,chunk,loops,-1)
534
+ end
535
+
536
+ ##
537
+ # The same as above, but the sound is played at most 'ticks' milliseconds
538
+ api :Mix_PlayChannelTimed, [:int, Chunk.by_ref, :int, :int], :int
539
+
540
+ ##
541
+ #
542
+ api :Mix_PlayMusic, [Music.by_ref, :int], :int, {error: true}
543
+
544
+ ##
545
+ # Fade in music or a channel over "ms" milliseconds, same semantics as the "Play" functions
546
+ api :Mix_FadeInMusic, [Music.by_ref, :int, :int], :int
547
+ ##
548
+ #
549
+ api :Mix_FadeInMusicPos, [Music.by_ref, :int, :int, :double], :int
550
+ ##
551
+ #
552
+ api :Mix_FadeInChannelTimed, [:int, Chunk.by_ref, :int, :int], :int
553
+
554
+ ##
555
+ # Set the volume in the range of 0-128 of a specific channel or chunk.
556
+ # If the specified channel is -1, set volume for all channels.
557
+ # Returns the original volume.
558
+ # If the specified volume is -1, just return the current volume.
559
+ api :Mix_Volume, [:int, :int], :int
560
+ api :Mix_VolumeChunk, [Chunk.by_ref, :int], :int
561
+ api :Mix_VolumeMusic, [:int], :int
562
+
563
+ ##
564
+ # Halt the playing of a particular channel
565
+ api :Mix_HaltChannel, [:int], :int, {error: true}
566
+ api :Mix_HaltGroup, [:int], :int, {error: true}
567
+ api :Mix_HaltMusic, [], :int, {error: true}
568
+
569
+ ##
570
+ # Change the expiration delay for a particular channel.
571
+ # The sample will stop playing after the 'ticks' milliseconds have elapsed,
572
+ # or remove the expiration if 'ticks' is -1
573
+ api :Mix_ExpireChannel, [:int, :int], :int
574
+
575
+ ##
576
+ # Halt a channel, fading it out progressively till it's silent
577
+ # The ms parameter indicates the number of milliseconds the fading
578
+ # will take.
579
+ api :Mix_FadeOutChannel, [:int, :int], :int
580
+ api :Mix_FadeOutGroup, [:int, :int], :int
581
+ api :Mix_FadeOutMusic, [:int], :int
582
+
583
+ ##
584
+ # Query the fading status of a channel
585
+ api :Mix_FadingMusic, [], :fading
586
+ api :Mix_FadingChannel, [:int], :fading
587
+
588
+ ##
589
+ # Pause/Resume a particular channel
590
+ api :Mix_Pause, [:int], :void
591
+ api :Mix_Resume, [:int], :void
592
+ api :Mix_Paused, [:int], :int
593
+
594
+ ##
595
+ # Pause/Resume the music stream
596
+ api :Mix_PauseMusic, [], :void
597
+ api :Mix_ResumeMusic, [], :void
598
+ api :Mix_RewindMusic, [], :void
599
+ api :Mix_PausedMusic, [], :int
600
+ boolean? :paused_music, TRUE_WHEN_NOT_ZERO
601
+
602
+
603
+ ##
604
+ # Set the current position in the music stream.
605
+ # This returns 0 if successful, or -1 if it failed or isn't implemented.
606
+ # This function is only implemented for MOD music formats (set pattern
607
+ # order number) and for OGG, FLAC, MP3_MAD, and MODPLUG music (set
608
+ # position in seconds), at the moment.
609
+ api :Mix_SetMusicPosition, [:double], :int
610
+
611
+ ##
612
+ # Check the status of a specific channel.
613
+ # If the specified channel is -1, check all channels.
614
+ api :Mix_Playing, [:int], :int
615
+ boolean? :playing, TRUE_WHEN_ONE
616
+
617
+ api :Mix_PlayingMusic, [], :int
618
+ boolean? :playing_music, TRUE_WHEN_ONE
619
+
620
+ ##
621
+ # Stop music and set external music playback command
622
+ api :Mix_SetMusicCMD, [:string], :int
623
+
624
+ ##
625
+ # Synchro value is set by MikMod from modules while playing
626
+ api :Mix_SetSynchroValue, [:int], :int
627
+ api :Mix_GetSynchroValue, [], :int
628
+
629
+ ##
630
+ # Set/Get/Iterate SoundFonts paths to use by supported MIDI backends
631
+ api :Mix_SetSoundFonts, [:string], :int
632
+ api :Mix_GetSoundFonts, [],:string
633
+ callback :each_sound_font, [:string, :pointer], :int
634
+ api :Mix_EachSoundFont, [:each_sound_font], :int
635
+
636
+ ##
637
+ # Get the Chunk currently associated with a mixer channel
638
+ api :Mix_GetChunk, [:int], Chunk.by_ref
639
+
640
+ ##
641
+ # Close the mixer, halting all playing audio
642
+ api :Mix_CloseAudio, [], :void
643
+
644
+ end
645
+
646
+ # Alias for constants like, ex: MIX_DEFAULT_FORMAT -> MIX::DEFAULT_FORMAT
647
+ MIX = Mixer
648
+ # Alias for method calls
649
+ Mix = Mixer
650
+
651
+ end