sdl2_ffi 0.0.5 → 0.0.6

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