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.
- checksums.yaml +4 -4
- data/README.md +21 -59
- data/lib/sdl2.rb +52 -15
- data/lib/sdl2/application.rb +71 -0
- data/lib/sdl2/audio.rb +72 -24
- data/lib/sdl2/clipboard.rb +9 -3
- data/lib/sdl2/color.rb +8 -3
- data/lib/sdl2/cpuinfo.rb +30 -10
- data/lib/sdl2/engine.rb +52 -0
- data/lib/sdl2/engine/block_engine.rb +27 -0
- data/lib/sdl2/engine/engines.rb +46 -0
- data/lib/sdl2/error.rb +9 -3
- data/lib/sdl2/events.rb +68 -6
- data/lib/sdl2/gamecontroller.rb +60 -20
- data/lib/sdl2/gem_version.rb +1 -1
- data/lib/sdl2/gesture.rb +12 -4
- data/lib/sdl2/haptic.rb +90 -30
- data/lib/sdl2/hints.rb +12 -4
- data/lib/sdl2/image.rb +85 -3
- data/lib/sdl2/init.rb +15 -5
- data/lib/sdl2/joystick.rb +63 -21
- data/lib/sdl2/keyboard.rb +101 -17
- data/lib/sdl2/keycode.rb +72 -72
- data/lib/sdl2/library.rb +7 -0
- data/lib/sdl2/log.rb +78 -21
- data/lib/sdl2/mixer.rb +651 -0
- data/lib/sdl2/mixer/chunk.rb +47 -0
- data/lib/sdl2/mixer/lib_paths.rb +8 -0
- data/lib/sdl2/mouse.rb +39 -13
- data/lib/sdl2/pixels.rb +39 -13
- data/lib/sdl2/point.rb +29 -0
- data/lib/sdl2/power.rb +3 -1
- data/lib/sdl2/rect.rb +94 -19
- data/lib/sdl2/render.rb +156 -52
- data/lib/sdl2/rwops.rb +60 -20
- data/lib/sdl2/surface.rb +85 -28
- data/lib/sdl2/syswm.rb +3 -1
- data/lib/sdl2/timer.rb +18 -6
- data/lib/sdl2/touch.rb +12 -4
- data/lib/sdl2/ttf.rb +153 -59
- data/lib/sdl2/ttf/font.rb +21 -5
- data/lib/sdl2/version.rb +9 -3
- data/lib/sdl2/video.rb +210 -70
- data/lib/sdl2/window.rb +9 -3
- data/spec/fixtures/approvals/lazyfoonet_lesson_07_true_type_fonts/draws_the_message_to_the_screen.approved.png +0 -0
- data/spec/fixtures/approvals/lazyfoonet_lesson_07_true_type_fonts/writes_a_message_to_a_surface.approved.png +0 -0
- data/spec/fixtures/approvals/lazyfoonet_lesson_09_mouse_events/defaults_to_mouse_out.approved.png +0 -0
- data/spec/fixtures/approvals/lazyfoonet_lesson_09_mouse_events/has_a_button_sheet.approved.png +0 -0
- data/spec/fixtures/approvals/lazyfoonet_lesson_09_mouse_events/shows_mouse_down.approved.png +0 -0
- data/spec/fixtures/approvals/lazyfoonet_lesson_09_mouse_events/shows_mouse_in.approved.png +0 -0
- data/spec/fixtures/approvals/lazyfoonet_lesson_09_mouse_events/shows_mouse_out.approved.png +0 -0
- data/spec/fixtures/approvals/lazyfoonet_lesson_09_mouse_events/shows_mouse_up.approved.png +0 -0
- data/spec/fixtures/images/button_sheet.png +0 -0
- data/spec/functional/lazy_foo_tutorial/lazy_foo_01_hello_world_spec.rb +9 -2
- data/spec/functional/lazy_foo_tutorial/lazy_foo_03_extension_libraries_spec.rb +1 -0
- data/spec/functional/lazy_foo_tutorial/lazy_foo_04_event_driven_programming_spec.rb +4 -3
- data/spec/functional/lazy_foo_tutorial/lazy_foo_05_color_keying_spec.rb +1 -1
- data/spec/functional/lazy_foo_tutorial/lazy_foo_06_clip_blitting_and_sprite_sheets_spec.rb +4 -3
- data/spec/functional/lazy_foo_tutorial/lazy_foo_07_true_type_fonts_spec.rb +4 -2
- data/spec/functional/lazy_foo_tutorial/lazy_foo_08_key_presses_spec.rb +10 -22
- data/spec/functional/lazy_foo_tutorial/lazy_foo_09_mouse_events_spec.rb +121 -0
- data/spec/functional/lazy_foo_tutorial/lazy_foo_10_key_states_spec.rb +30 -0
- data/spec/functional/lazy_foo_tutorial/lazy_foo_11_playing_sounds_spec.rb +116 -0
- data/spec/functional/lazy_foo_tutorial/lazy_foo_12_timing_spec.rb +57 -0
- data/spec/spec_helper.rb +3 -1
- metadata +31 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bcb36c1f56cfd2a4ad4920222e9713619e23355a
|
4
|
+
data.tar.gz: ef6c799ffadf4caa0d4d5a443e402f0391a47085
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
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
|
30
|
+
$ rake spec
|
31
|
+
|
32
|
+
Or:
|
33
|
+
|
34
|
+
$ ./bin/rspec ./spec -fd
|
71
35
|
|
72
|
-
|
36
|
+
### Approval Testing
|
73
37
|
|
74
|
-
|
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
|
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
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
136
|
-
|
137
|
-
|
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
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
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
|
-
|
111
|
-
|
112
|
-
|
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
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
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
|
-
|
126
|
-
|
127
|
-
|
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
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
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
|
-
|
139
|
-
|
182
|
+
##
|
183
|
+
#
|
184
|
+
api :SDL_CloseAudio, [], :void
|
185
|
+
##
|
186
|
+
#
|
187
|
+
api :SDL_CloseAudioDevice, [:audio_device_id], :void
|
140
188
|
|
141
189
|
|
142
190
|
end
|
data/lib/sdl2/clipboard.rb
CHANGED
@@ -21,7 +21,13 @@ module SDL2
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
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
|