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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 60ab089f8e71037fce4c4f2a46cf5586db4af65f
4
- data.tar.gz: cd50c7524713298ed2ad850d637a46f0c20d6347
3
+ metadata.gz: bcb36c1f56cfd2a4ad4920222e9713619e23355a
4
+ data.tar.gz: ef6c799ffadf4caa0d4d5a443e402f0391a47085
5
5
  SHA512:
6
- metadata.gz: 8322d3174b86096df92c9fd2127b54604c3ef9e99a4f1c055bb56570e0e986bcd93fd8d576bd7d444daac7bca497162b5f0aea94eac8e5c58c113d62797034ea
7
- data.tar.gz: 028e8e3b02c672c1fb45796bb21bdc8cb25f369b9cf34f8861e816f099f3a56277d7003ac5256efcbd697f7f88ed96299b41cbe4ebb0c6e1dd89c6ed0ba35d30
6
+ metadata.gz: 8d77dfe92939dab7ae53edb27a8b96c04941a951c0ce8aa6a9578767483becfb08c1ca85bc99c8c072cd3f034a4ebaeb929869f8fa98d2839694574986e73c59
7
+ data.tar.gz: 9a5b0026a3b60ee4b95af4f6011dc81f6c68c358e254df2c55bc41b000114d09c142f86c81c05d97b8fbedaa40eda30cec7c824363797a75eb31193e2c68f305
data/README.md CHANGED
@@ -2,11 +2,12 @@
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/sdl2_ffi.png)](http://badge.fury.io/rb/sdl2_ffi)
4
4
 
5
- This is a simple interface to SDL2 for Ruby using FFI.
6
- It also supports SDL_image and SDL_ttf.
7
- While a lot of the SDLlib, SDL_image, and SDL_ttf are linked, not all prototypes
8
- have been tested. Large sections, such as "SDL_opengl<x>.h" have not been translated
9
- at all.
5
+ The sdl2_ffi makes SDL2 fun and easy, eventually. This is still a new project
6
+ and I am still implementing major sections of it. Check out the
7
+ [approvals](https://github.com/BadQuanta/sdl2_ffi/tree/master/spec/fixtures/approvals)
8
+ to get an idea of how much is working. These are screen-shots of SDL generated
9
+ content. Approval testing is used to validate functionality.
10
+
10
11
 
11
12
  The "Object Oriented" part of this interface has barely started.
12
13
 
@@ -19,47 +20,6 @@ Otherwise, you can use RDoc to generate current source documentation.
19
20
 
20
21
  # How to start:
21
22
 
22
- The GEM is organized to the same structure as the SDL header files. Where in C/C++ you would need to:
23
-
24
- include 'SDL'
25
- include 'SDL_image'
26
- include 'SDL_ttf'
27
-
28
- with this rubygem, you would instead:
29
-
30
- require 'sdl2'
31
- require 'sdl2/image'
32
- require 'sdl2/ttf'
33
-
34
- The SDL2 module is defined and it is where the raw SDL API is loaded and linked. The Raw API can be called like so:
35
-
36
- SDL2.init!(:EVERYTHING)
37
- SDL2.was_init?(:EVERYTHING)
38
-
39
- ## More Examples:
40
-
41
- As a means of validating functionality, I am in the process of translating
42
- existing SDL Examples into Minitest [functional tests](https://github.com/BadQuanta/sdl2_ffi/tree/master/test/functional/examples).
43
-
44
-
45
- ## Dependencies
46
-
47
- * Obviously, ruby
48
- * SDL2 Runtime (Development files are not needed.)
49
-
50
- ## Installation
51
-
52
- Add this line to your application's Gemfile:
53
-
54
- gem 'sdl2_ffi'
55
-
56
- And then execute:
57
-
58
- $ bundle
59
-
60
- Or install it yourself as:
61
-
62
- $ gem install sdl2_ffi
63
23
 
64
24
  ## Testing
65
25
 
@@ -67,30 +27,32 @@ Minitests are being written to validate functionality. Not SDL's functionality,
67
27
 
68
28
  Run the tests with rake:
69
29
 
70
- $ rake test
30
+ $ rake spec
31
+
32
+ Or:
33
+
34
+ $ ./bin/rspec ./spec -fd
71
35
 
72
- Verbose options are nice:
36
+ ### Approval Testing
73
37
 
74
- $ rake test TESTOPTS="--verbose"
38
+ This project now uses Approval testing. At the moment, I'm using a custom
39
+ 'approvals' gem which is specified in the Gemfile, as opposed to the Gemspec.
40
+ This is only temporary. The approved specifications are in the repository
41
+ and can act as a repository of screen shots. :)
75
42
 
76
43
 
77
44
  ### Testing Under *nix & X11
78
45
 
79
46
  If you are testing under some kind of unix system with X11 and have Xnest available,
80
47
  I'd recommend starting up Xnest and changing your testing terminal DISPLAY value
81
- so that the tests do not throw around a bunch of Windows on your scren.
82
-
83
-
84
-
85
- ### I need your help!
86
-
87
- I'm just starting to implement the Object Oriented Wrapper. I'll need help identifying mistakes, especially in memory management. Bug-reports submitted with tests will be looked at before bug-reports without tests, as a way to encourage tests being written.
88
-
89
- Thanks for reading this!
48
+ so that the tests do not throw around a bunch of Windows on your screen.
90
49
 
91
50
  ## Usage
92
51
 
93
- The interface is intended to be modular and follows (roughly) SDL's header files.
52
+ When you `require 'sdl2'`, it should give you the same things that
53
+ include 'SDL.h' would have done. See the specs for examples. There are C/C++
54
+ tutorials that have been translated as a means of validating functionality.
55
+
94
56
 
95
57
  ## Contributing
96
58
 
data/lib/sdl2.rb CHANGED
@@ -51,7 +51,7 @@ module SDL2
51
51
  # FFI::Struct class with some useful additions.
52
52
  class Struct < FFI::Struct
53
53
  extend StructHelper
54
-
54
+
55
55
  # Allows creation and use within block, automatically freeing pointer after block.
56
56
  def initialize(*args, &block)
57
57
  super(*args)
@@ -61,12 +61,23 @@ module SDL2
61
61
  self.class.release(self.pointer)
62
62
  end
63
63
  end
64
+
65
+ # Placeholder for Structs that need to initialize values.
66
+ def self.create(values = {})
67
+ created = self.new
68
+ created.update_members(values)
69
+ created
70
+ end
64
71
 
65
72
  # A default release scheme is defined, but should be redefined where appropriate.
66
73
  def self.release(pointer)
67
74
  pointer.free
68
75
  end
69
76
 
77
+ def free()
78
+ self.pointer.free
79
+ end
80
+
70
81
  # A human-readable representation of the struct and it's values.
71
82
  #def inspect
72
83
  # return 'nil' if self.null?
@@ -82,6 +93,8 @@ module SDL2
82
93
  # end
83
94
 
84
95
  # Compare two structures by class and values.
96
+ # This will return true if compared to a "partial hash",
97
+ # if all the keys the hash defines equal
85
98
  def ==(other)
86
99
  if PrintDebug
87
100
  @@rec ||= -1
@@ -93,22 +106,28 @@ module SDL2
93
106
  end
94
107
 
95
108
  result = catch(:result) do
96
- unless self.class == other.class
109
+ unless self.class == other.class or other.kind_of? Hash
97
110
  puts "Class Mismatch" if PrintDebug
98
111
  throw :result, false
99
112
  end
100
113
 
101
- if self.null? or other.null?
114
+ if (other.kind_of? Hash) and (other.keys - members).any?
115
+ puts "Extra Keys: #{other.keys-members}"
116
+ thorw :result, false
117
+ end
118
+
119
+ if (other.respond_to?:null?) and (self.null? or other.null?)
102
120
  unless self.null? and other.null?
103
121
  puts "AHHHAOne is null and the other is not" if PrintDebug
104
122
  throw :result, false
105
123
  end
106
124
  else
107
- self.class.members.each do |field|
125
+ fields = other.kind_of?(Hash) ? members & other.keys : members
126
+ fields.each do |field|
108
127
  print "#{pad} #{field}:#{self[field].class} = " if PrintDebug
109
128
 
110
129
  unless self[field] == other[field]
111
- binding.pry
130
+
112
131
  puts "NO MATCH: #{self[field].to_s} #{other[field].to_s}" if PrintDebug
113
132
  throw :result, false
114
133
  end
@@ -129,23 +148,41 @@ module SDL2
129
148
 
130
149
  # Default cast handler
131
150
  def self.cast(something)
151
+
132
152
  if something.kind_of? self
153
+
133
154
  return something
155
+
134
156
  elsif something.kind_of? Hash
135
- common = (self.members & something.keys)
136
- if common.empty?
137
- raise "#{self} can't cast this Hash: #{something.inspect}"
138
- else
139
- tmp = self.new
140
- common.each do |field|
141
- tmp[field] = something[field]
142
- end
143
- return tmp
144
- end
157
+
158
+ return self.create(something)
159
+
145
160
  elsif something.nil?
161
+
146
162
  return something #TODO: Assume NUL is ok?
163
+
147
164
  else
165
+
148
166
  raise "#{self} can't cast #{something.insepct}"
167
+
168
+ end
169
+ end
170
+
171
+ # Set members to values contained within hash.
172
+ def update_members(values)
173
+ if values.kind_of? Array
174
+ raise "#{self} has less fields then #{values.inspect}" if values.count > members.count
175
+ members.first(values.count).each_with_index do |field, idx|
176
+ self[field] = values[idx]
177
+ end
178
+
179
+ elsif values.kind_of? Hash
180
+ common = (self.members & values.keys)
181
+ common.each do |field|
182
+ self[field] = values[field]
183
+ end
184
+ else
185
+ raise "#{self}#update_members unable to update from #{values.inspect}"
149
186
  end
150
187
  end
151
188
  end
@@ -0,0 +1,71 @@
1
+ require 'sdl2/engine/engines'
2
+
3
+ module SDL2
4
+
5
+ # A Top-Level SDL Application:
6
+ # An application
7
+
8
+
9
+ class Application < Engine::Engines
10
+
11
+ attr_accessor :window
12
+
13
+ def initialize(opts = {})
14
+ super(opts)
15
+
16
+ title = opts[:title] || self.to_s
17
+ x = opts[:x] || :CENTERED
18
+ y = opts[:y] || :CENTERED
19
+ w = opts[:w] || 640
20
+ h = opts[:h] || 480
21
+ flags = opts[:flags] || :SHOWN
22
+
23
+ @window = Window.create(title, x, y, w, h, flags)
24
+ @window.surface.fill_rect(@window.surface.rect, [0,0,0,SDL2::ALPHA_OPAQUE])
25
+
26
+ # Default ON handler for :QUIT events:
27
+ self.on({type: :QUIT}) do |event|
28
+ @quit_loop = true
29
+ end
30
+
31
+ end
32
+
33
+ def quit()
34
+ @window.free
35
+ super()
36
+ end
37
+
38
+ attr_accessor :poll_count_limit
39
+
40
+ # What makes an engine an "Application" is that it takes control of event
41
+ # polling. There should only ever be one "Application"
42
+ def poll(cnt = poll_count_limit)
43
+ puts "Poll Start" if SDL2::PrintDebug
44
+ times = 0
45
+ while (event = Event.poll()) and (cnt.nil? or (times+=1 < cnt))
46
+ puts "GOT: #{event.type}"if SDL2::PrintDebug
47
+ handle_event(event)
48
+ end
49
+
50
+ puts "Poll End"if SDL2::PrintDebug
51
+ end
52
+
53
+ attr_accessor :loop_count_limit
54
+
55
+ def loop(cnt = loop_count_limit, opts ={})
56
+ @quit_loop = false
57
+ times = 0
58
+ while (cnt.nil?) or ((times+=1) <= cnt)
59
+ puts ">>> Loop##{times}" if SDL2::PrintDebug
60
+ poll # Process input
61
+ break if @quit_loop
62
+ # Update the surface when we are painted to
63
+ @window.update_surface if paint_to(@window.surface)
64
+ puts "<<< Loop##{times}" if SDL2::PrintDebug
65
+ delay(opts[:delay]) if opts.has_key? :delay
66
+ end
67
+ end
68
+
69
+ end
70
+
71
+ end
data/lib/sdl2/audio.rb CHANGED
@@ -98,45 +98,93 @@ module SDL2
98
98
  callback :audio_callback, [:pointer, :pointer, :int], :void
99
99
  callback :audio_filter, [Audio::CVT.by_ref, :audio_format], :void
100
100
 
101
- api :SDL_GetNumAudioDrivers, [], :int
102
- api :SDL_GetAudioDriver, [:int], :string
103
- api :SDL_AudioInit, [:string], :int
104
- api :SDL_AudioQuit, [], :void
105
- api :SDL_GetCurrentAudioDriver, [], :string
106
- api :SDL_OpenAudio, [Audio::Spec.by_ref, Audio::Spec.by_ref], :int
101
+ ##
102
+ #
103
+ api :SDL_GetNumAudioDrivers, [], :int
104
+ ##
105
+ #
106
+ api :SDL_GetAudioDriver, [:int], :string
107
+ ##
108
+ #
109
+ api :SDL_AudioInit, [:string], :int
110
+ ##
111
+ #
112
+ api :SDL_AudioQuit, [], :void
113
+ ##
114
+ #
115
+ api :SDL_GetCurrentAudioDriver, [], :string
116
+ ##
117
+ #
118
+ api :SDL_OpenAudio, [Audio::Spec.by_ref, Audio::Spec.by_ref], :int
107
119
 
108
120
  typedef :uint32, :audio_device_id
109
121
 
110
- api :SDL_GetNumAudioDevices, [:int], :int
111
- api :SDL_GetAudioDeviceName, [:int, :int], :string
112
- api :SDL_OpenAudioDevice, [:string, :int, Audio::Spec.by_ref, Audio::Spec.by_ref, :int], :audio_device_id
122
+ ##
123
+ #
124
+ api :SDL_GetNumAudioDevices, [:int], :int
125
+ ##
126
+ #
127
+ api :SDL_GetAudioDeviceName, [:int, :int], :string
128
+ ##
129
+ #
130
+ api :SDL_OpenAudioDevice, [:string, :int, Audio::Spec.by_ref, Audio::Spec.by_ref, :int], :audio_device_id
113
131
 
114
132
  enum :audio_status, [:STOPPED, 0, :PLAYING, :PAUSED]
115
133
 
116
- api :SDL_GetAudioStatus, [], :audio_status
117
- api :SDL_PauseAudio, [:int], :void
118
- api :SDL_PauseAudioDevice, [:audio_device_id, :int], :void
119
- api :SDL_LoadWAV_RW, [RWops.by_ref, :int, Audio::Spec.by_ref, :pointer, :pointer], Audio::Spec.by_ref
134
+ ##
135
+ #
136
+ api :SDL_GetAudioStatus, [], :audio_status
137
+ ##
138
+ #
139
+ api :SDL_PauseAudio, [:int], :void
140
+ ##
141
+ #
142
+ api :SDL_PauseAudioDevice, [:audio_device_id, :int], :void
143
+ ##
144
+ #
145
+ api :SDL_LoadWAV_RW, [RWops.by_ref, :int, Audio::Spec.by_ref, :pointer, :pointer], Audio::Spec.by_ref
120
146
 
121
147
  def self.load_wav(file, spec, audio_buf, audio_len)
122
148
  load_wav_rw(rw_from_file)
123
149
  end
124
150
 
125
- api :SDL_FreeWAV, [:pointer], :void
126
- api :SDL_BuildAudioCVT, [Audio::CVT.by_ref, :audio_format, :uint8, :int, :audio_format, :uint8, :int], :int
127
- api :SDL_ConvertAudio, [Audio::CVT.by_ref], :int
151
+ ##
152
+ #
153
+ api :SDL_FreeWAV, [:pointer], :void
154
+ ##
155
+ #
156
+ api :SDL_BuildAudioCVT, [Audio::CVT.by_ref, :audio_format, :uint8, :int, :audio_format, :uint8, :int], :int
157
+ ##
158
+ #
159
+ api :SDL_ConvertAudio, [Audio::CVT.by_ref], :int
128
160
 
129
161
  MIX_MAXVOLUME = 128
130
162
 
131
- api :SDL_MixAudio, [:pointer, :pointer, :uint32, :int], :void
132
- api :SDL_MixAudioFormat, [:pointer, :pointer, :audio_format, :uint32, :int], :void
133
- api :SDL_LockAudio, [], :void
134
- api :SDL_LockAudioDevice, [:audio_device_id], :void
135
- api :SDL_UnlockAudio, [], :void
136
- api :SDL_UnlockAudioDevice, [:audio_device_id], :void
163
+ ##
164
+ #
165
+ api :SDL_MixAudio, [:pointer, :pointer, :uint32, :int], :void
166
+ ##
167
+ #
168
+ api :SDL_MixAudioFormat, [:pointer, :pointer, :audio_format, :uint32, :int], :void
169
+ ##
170
+ #
171
+ api :SDL_LockAudio, [], :void
172
+ ##
173
+ #
174
+ api :SDL_LockAudioDevice, [:audio_device_id], :void
175
+ ##
176
+ #
177
+ api :SDL_UnlockAudio, [], :void
178
+ ##
179
+ #
180
+ api :SDL_UnlockAudioDevice, [:audio_device_id], :void
137
181
 
138
- api :SDL_CloseAudio, [], :void
139
- api :SDL_CloseAudioDevice, [:audio_device_id], :void
182
+ ##
183
+ #
184
+ api :SDL_CloseAudio, [], :void
185
+ ##
186
+ #
187
+ api :SDL_CloseAudioDevice, [:audio_device_id], :void
140
188
 
141
189
 
142
190
  end
@@ -21,7 +21,13 @@ module SDL2
21
21
  end
22
22
  end
23
23
 
24
- api :SDL_SetClipboardText, [:string], :int
25
- api :SDL_GetClipboardText, [], :string
26
- api :SDL_HasClipboardText, [], :bool
24
+ ##
25
+ #
26
+ api :SDL_SetClipboardText, [:string], :int
27
+ ##
28
+ #
29
+ api :SDL_GetClipboardText, [], :string
30
+ ##
31
+ #
32
+ api :SDL_HasClipboardText, [], :bool
27
33
  end