rb_sdl2 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +31 -0
- data/README.md +1 -1
- data/lib/rb_sdl2/audio/audio.rb +162 -0
- data/lib/rb_sdl2/audio/audio_buffer.rb +12 -19
- data/lib/rb_sdl2/audio/audio_device.rb +17 -23
- data/lib/rb_sdl2/audio/audio_spec.rb +38 -6
- data/lib/rb_sdl2/audio/audio_spec_reader.rb +10 -0
- data/lib/rb_sdl2/clipboard.rb +31 -31
- data/lib/rb_sdl2/cpu_info.rb +34 -17
- data/lib/rb_sdl2/cursor.rb +105 -24
- data/lib/rb_sdl2/display.rb +16 -16
- data/lib/rb_sdl2/display_mode.rb +1 -1
- data/lib/rb_sdl2/error.rb +11 -4
- data/lib/rb_sdl2/errors.rb +7 -0
- data/lib/rb_sdl2/event/event.rb +130 -0
- data/lib/rb_sdl2/event/event_filter.rb +34 -70
- data/lib/rb_sdl2/event/event_pointer.rb +26 -0
- data/lib/rb_sdl2/event/event_queue.rb +97 -120
- data/lib/rb_sdl2/event/event_type.rb +147 -205
- data/lib/rb_sdl2/filesystem.rb +8 -9
- data/lib/rb_sdl2/hint.rb +26 -24
- data/lib/rb_sdl2/keyboard/keyboard.rb +50 -0
- data/lib/rb_sdl2/keyboard/mod_state.rb +68 -0
- data/lib/rb_sdl2/keyboard/state.rb +39 -0
- data/lib/rb_sdl2/message_box.rb +69 -102
- data/lib/rb_sdl2/mouse/global_mouse.rb +10 -3
- data/lib/rb_sdl2/mouse/mouse.rb +64 -0
- data/lib/rb_sdl2/mouse/mouse_button.rb +13 -11
- data/lib/rb_sdl2/mouse/mouse_class.rb +9 -17
- data/lib/rb_sdl2/mouse/mouse_wheel.rb +21 -37
- data/lib/rb_sdl2/mouse/relative_mouse.rb +15 -1
- data/lib/rb_sdl2/palette.rb +12 -12
- data/lib/rb_sdl2/pixel_format_enum.rb +87 -55
- data/lib/rb_sdl2/platform.rb +1 -1
- data/lib/rb_sdl2/power_info.rb +34 -23
- data/lib/rb_sdl2/rect.rb +7 -1
- data/lib/rb_sdl2/ref_count_pointer.rb +25 -10
- data/lib/rb_sdl2/rw_ops/rw_file.rb +19 -0
- data/lib/rb_sdl2/rw_ops/rw_memory.rb +18 -0
- data/lib/rb_sdl2/rw_ops/rw_object.rb +126 -0
- data/lib/rb_sdl2/rw_ops/rw_ops.rb +104 -0
- data/lib/rb_sdl2/rw_ops/rw_ops_pointer.rb +14 -0
- data/lib/rb_sdl2/sdl.rb +67 -28
- data/lib/rb_sdl2/sdl_pointer.rb +22 -0
- data/lib/rb_sdl2/surface/blend_mode.rb +41 -41
- data/lib/rb_sdl2/surface/pixel_format.rb +34 -33
- data/lib/rb_sdl2/surface.rb +280 -265
- data/lib/rb_sdl2/text_input.rb +21 -15
- data/lib/rb_sdl2/timer.rb +36 -31
- data/lib/rb_sdl2/version.rb +3 -3
- data/lib/rb_sdl2/video.rb +17 -5
- data/lib/rb_sdl2/window/accessor.rb +135 -0
- data/lib/rb_sdl2/window/display.rb +8 -8
- data/lib/rb_sdl2/window/flash.rb +22 -0
- data/lib/rb_sdl2/window/hit_test.rb +22 -43
- data/lib/rb_sdl2/window/shape.rb +55 -40
- data/lib/rb_sdl2/window/state.rb +178 -0
- data/lib/rb_sdl2/window/window.rb +149 -0
- data/lib/rb_sdl2.rb +79 -17
- data/rb_sdl2.gemspec +4 -4
- metadata +31 -35
- data/lib/rb_sdl2/audio/audio_allowed_changes.rb +0 -17
- data/lib/rb_sdl2/audio/audio_format.rb +0 -23
- data/lib/rb_sdl2/audio.rb +0 -132
- data/lib/rb_sdl2/cursor/color_cursor.rb +0 -19
- data/lib/rb_sdl2/cursor/cursor_class.rb +0 -24
- data/lib/rb_sdl2/cursor/cursor_pointer.rb +0 -12
- data/lib/rb_sdl2/cursor/default_cursor.rb +0 -18
- data/lib/rb_sdl2/cursor/system_cursor.rb +0 -45
- data/lib/rb_sdl2/event.rb +0 -161
- data/lib/rb_sdl2/keyboard/key_mod.rb +0 -37
- data/lib/rb_sdl2/keyboard/keyboard_state.rb +0 -34
- data/lib/rb_sdl2/keyboard.rb +0 -50
- data/lib/rb_sdl2/mouse/window_mouse.rb +0 -17
- data/lib/rb_sdl2/mouse.rb +0 -74
- data/lib/rb_sdl2/rw_ops/rw_operator.rb +0 -105
- data/lib/rb_sdl2/rw_ops.rb +0 -149
- data/lib/rb_sdl2/screen_saver.rb +0 -11
- data/lib/rb_sdl2/window/dialog.rb +0 -19
- data/lib/rb_sdl2/window/grab.rb +0 -23
- data/lib/rb_sdl2/window/position.rb +0 -38
- data/lib/rb_sdl2/window/size.rb +0 -59
- data/lib/rb_sdl2/window/window_flags.rb +0 -78
- data/lib/rb_sdl2/window.rb +0 -242
@@ -1,53 +1,37 @@
|
|
1
1
|
module RbSDL2
|
2
2
|
module Mouse
|
3
3
|
class MouseWheel
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
@y = event[:y] * a
|
13
|
-
end
|
14
|
-
}
|
15
|
-
|
16
|
-
class << self
|
17
|
-
attr_reader :timestamp, :x, :y
|
18
|
-
|
19
|
-
require_relative '../event'
|
20
|
-
|
21
|
-
def wheel=(bool)
|
22
|
-
@mutex.synchronize do
|
23
|
-
if bool
|
24
|
-
Event.add_watch_callback(MOUSE_WHEEL_EVENT_WATCH)
|
25
|
-
else
|
26
|
-
Event.remove_watch_callback(MOUSE_WHEEL_EVENT_WATCH)
|
27
|
-
end
|
4
|
+
def initialize(window = nil)
|
5
|
+
@wheel_x = @wheel_y = @x = @y = 0
|
6
|
+
window_id = window&.window_id
|
7
|
+
proc = -> (event) do
|
8
|
+
if event.mouse_wheel? && window_id && event[:windowID] == window_id
|
9
|
+
a = event[:direction] == ::SDL::MOUSEWHEEL_FLIPPED ? -1 : 1
|
10
|
+
@x += event[:x] * a
|
11
|
+
@y += event[:y] * a
|
28
12
|
end
|
29
13
|
end
|
14
|
+
@watch = EventFilter.new(proc)
|
30
15
|
end
|
31
16
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
@timestamp = @x = @y = 0
|
17
|
+
def update
|
18
|
+
@wheel_x, @wheel_y = @x, @y
|
19
|
+
@x = @y = 0
|
20
|
+
self
|
37
21
|
end
|
38
22
|
|
39
|
-
def
|
40
|
-
|
41
|
-
|
42
|
-
if @timestamp != MouseWheel.timestamp
|
43
|
-
@x, @y, @timestamp = MouseWheel.x, MouseWheel.y, MouseWheel.timestamp
|
23
|
+
def wheel=(bool)
|
24
|
+
if bool
|
25
|
+
EventFilter.define_watch(@watch)
|
44
26
|
else
|
45
|
-
@
|
27
|
+
EventFilter.undefine_watch(@watch)
|
46
28
|
end
|
47
|
-
|
29
|
+
@wheel_x = @wheel_y = @x = @y = 0
|
48
30
|
end
|
49
31
|
|
50
|
-
|
32
|
+
def wheel_position = [@wheel_x, @wheel_y]
|
33
|
+
|
34
|
+
attr_reader :wheel_x, :wheel_y, :window_id
|
51
35
|
end
|
52
36
|
end
|
53
37
|
end
|
@@ -3,8 +3,22 @@ module RbSDL2
|
|
3
3
|
require_relative 'mouse_class'
|
4
4
|
|
5
5
|
class RelativeMouse < MouseClass
|
6
|
+
require 'singleton'
|
7
|
+
include Singleton
|
8
|
+
|
9
|
+
@_x = ::FFI::MemoryPointer.new(:int)
|
10
|
+
@_y = ::FFI::MemoryPointer.new(:int)
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def update
|
14
|
+
self.button, self.x, self.y =
|
15
|
+
::SDL.GetRelativeMouseState(@_x, @_y), @_x.read_int, @_y.read_int
|
16
|
+
self
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
6
20
|
def update
|
7
|
-
self.
|
21
|
+
self.class.update
|
8
22
|
self
|
9
23
|
end
|
10
24
|
end
|
data/lib/rb_sdl2/palette.rb
CHANGED
@@ -4,9 +4,9 @@ module RbSDL2
|
|
4
4
|
|
5
5
|
class PalettePointer < RefCountPointer
|
6
6
|
class << self
|
7
|
-
def release(ptr) = ::
|
7
|
+
def release(ptr) = ::SDL.FreePalette(ptr)
|
8
8
|
|
9
|
-
def entity_class = ::
|
9
|
+
def entity_class = ::SDL::Palette
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
@@ -18,7 +18,9 @@ module RbSDL2
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def new(num_colors)
|
21
|
-
|
21
|
+
# SDL_AllocPalette() のエラーは引数が < 1、または必要なメモリー領域がない場合。
|
22
|
+
# パレットのカラーは作成時に全て [255, 255, 255, 255] で埋められる。
|
23
|
+
ptr = PalettePointer.new(::SDL.AllocPalette(num_colors))
|
22
24
|
raise RbSDL2Error if ptr.null?
|
23
25
|
super(ptr)
|
24
26
|
end
|
@@ -31,38 +33,36 @@ module RbSDL2
|
|
31
33
|
end
|
32
34
|
|
33
35
|
def initialize(ptr)
|
34
|
-
@st = ::
|
36
|
+
@st = ::SDL::Palette.new(ptr)
|
35
37
|
end
|
36
38
|
|
37
39
|
def ==(other)
|
38
|
-
other.respond_to?(:to_ptr) && to_ptr ==
|
40
|
+
other.respond_to?(:to_ptr) && other.to_ptr == to_ptr
|
39
41
|
end
|
40
42
|
|
41
43
|
def [](nth)
|
42
44
|
raise ArgumentError if nth < 0 || length <= nth
|
43
|
-
::
|
45
|
+
::SDL::Color.new(@st[:colors] + ::SDL::Color.size * nth).values
|
44
46
|
end
|
45
47
|
|
46
48
|
# color 引数には 3要素以上の配列であること。4要素目以降は無視される。
|
47
49
|
# color 引数は内部で splat する。これに対応していれば配列以外のオブジェクトでもよい。
|
48
|
-
# パレットのカラーが描画に使われるときはアルファ値は無視されて不透明(
|
49
|
-
# パレットのカラーは作成時に全て [255, 255, 255, 255] で埋められている。
|
50
|
+
# パレットのカラーが描画に使われるときはアルファ値は無視されて不透明(ALPHA_OPAQUE)として扱う。
|
50
51
|
def []=(nth, color)
|
51
52
|
raise ArgumentError if nth < 0 || length <= nth
|
52
|
-
c = ::
|
53
|
+
c = ::SDL::Color.new
|
53
54
|
c[:r], c[:g], c[:b] = color
|
54
|
-
err = ::
|
55
|
+
err = ::SDL.SetPaletteColors(self, c, nth, 1)
|
55
56
|
raise RbSDL2Error if err < 0
|
56
57
|
end
|
57
58
|
|
58
59
|
def each = length.times { |nth| yield(self[nth]) }
|
59
60
|
|
60
61
|
def inspect
|
61
|
-
"#<#{self.class.name}
|
62
|
+
"#<#{self.class.name} colors=#{length}>"
|
62
63
|
end
|
63
64
|
|
64
65
|
def length = @st[:ncolors]
|
65
|
-
|
66
66
|
alias size length
|
67
67
|
|
68
68
|
def to_a = to_enum.to_a
|
@@ -1,73 +1,105 @@
|
|
1
1
|
module RbSDL2
|
2
2
|
module PixelFormatEnum
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
3
|
+
# SDL の PixelFormatEnum はピクセルフォーマットをビット列にパックしたものである。
|
4
|
+
# ビット操作を通じてピクセルフォーマットを構築、分析できる。
|
5
|
+
# しかし、SDL API は事前に定義されているフォーマット以外を与えるとエラーになる。
|
6
|
+
# ユーザ側で自由なフォーマット定義を行うことはできない。
|
7
|
+
# Ruby 側でフォーマットの詳細を知るため目的に応じたフォーマット集合を作成することにした。
|
8
|
+
# これはコードのメンテナンスを考慮したためである。
|
9
|
+
#
|
10
|
+
# [[sym, num, type, alpha], ...]
|
11
|
+
table = [
|
12
|
+
[:index1lsb, ::SDL::PIXELFORMAT_INDEX1LSB, :indexed, false],
|
13
|
+
[:index1msb, ::SDL::PIXELFORMAT_INDEX1MSB, :indexed, false],
|
14
|
+
[:index4lsb, ::SDL::PIXELFORMAT_INDEX4LSB, :indexed, false],
|
15
|
+
[:index4msb, ::SDL::PIXELFORMAT_INDEX4MSB, :indexed, false],
|
16
|
+
[:index8, ::SDL::PIXELFORMAT_INDEX8, :indexed, false],
|
17
|
+
[:rgb332, ::SDL::PIXELFORMAT_RGB332, :packed, false],
|
18
|
+
[:xrgb4444, ::SDL::PIXELFORMAT_XRGB4444, :packed, false],
|
19
|
+
[:rgb444, ::SDL::PIXELFORMAT_RGB444, :packed, false],
|
20
|
+
[:xbgr4444, ::SDL::PIXELFORMAT_XBGR4444, :packed, false],
|
21
|
+
[:bgr444, ::SDL::PIXELFORMAT_BGR444, :packed, false],
|
22
|
+
[:xrgb1555, ::SDL::PIXELFORMAT_XRGB1555, :packed, false],
|
23
|
+
[:rgb555, ::SDL::PIXELFORMAT_RGB555, :packed, false],
|
24
|
+
[:xbgr1555, ::SDL::PIXELFORMAT_XBGR1555, :packed, false],
|
25
|
+
[:bgr555, ::SDL::PIXELFORMAT_BGR555, :packed, false],
|
26
|
+
[:argb4444, ::SDL::PIXELFORMAT_ARGB4444, :packed, true],
|
27
|
+
[:rgba4444, ::SDL::PIXELFORMAT_RGBA4444, :packed, true],
|
28
|
+
[:abgr4444, ::SDL::PIXELFORMAT_ABGR4444, :packed, true],
|
29
|
+
[:bgra4444, ::SDL::PIXELFORMAT_BGRA4444, :packed, true],
|
30
|
+
[:argb1555, ::SDL::PIXELFORMAT_ARGB1555, :packed, true],
|
31
|
+
[:rgba5551, ::SDL::PIXELFORMAT_RGBA5551, :packed, true],
|
32
|
+
[:abgr1555, ::SDL::PIXELFORMAT_ABGR1555, :packed, true],
|
33
|
+
[:bgra5551, ::SDL::PIXELFORMAT_BGRA5551, :packed, true],
|
34
|
+
[:rgb565, ::SDL::PIXELFORMAT_RGB565, :packed, false],
|
35
|
+
[:bgr565, ::SDL::PIXELFORMAT_BGR565, :packed, false],
|
36
|
+
[:rgb24, ::SDL::PIXELFORMAT_RGB24, :array, false],
|
37
|
+
[:bgr24, ::SDL::PIXELFORMAT_BGR24, :array, false],
|
38
|
+
[:xrgb8888, ::SDL::PIXELFORMAT_XRGB8888, :packed, false],
|
39
|
+
[:rgb888, ::SDL::PIXELFORMAT_RGB888, :packed, false],
|
40
|
+
[:rgbx8888, ::SDL::PIXELFORMAT_RGBX8888, :packed, false],
|
41
|
+
[:xbgr8888, ::SDL::PIXELFORMAT_XBGR8888, :packed, false],
|
42
|
+
[:bgr888, ::SDL::PIXELFORMAT_BGR888, :packed, false],
|
43
|
+
[:bgrx8888, ::SDL::PIXELFORMAT_BGRX8888, :packed, false],
|
44
|
+
[:argb8888, ::SDL::PIXELFORMAT_ARGB8888, :packed, true],
|
45
|
+
[:rgba8888, ::SDL::PIXELFORMAT_RGBA8888, :packed, true],
|
46
|
+
[:abgr8888, ::SDL::PIXELFORMAT_ABGR8888, :packed, true],
|
47
|
+
[:bgra8888, ::SDL::PIXELFORMAT_BGRA8888, :packed, true],
|
48
|
+
[:argb2101010, ::SDL::PIXELFORMAT_ARGB2101010, :packed, true],
|
49
|
+
[:rgba32, ::SDL::PIXELFORMAT_RGBA32, :packed, true],
|
50
|
+
[:argb32, ::SDL::PIXELFORMAT_ARGB32, :packed, true],
|
51
|
+
[:bgra32, ::SDL::PIXELFORMAT_BGRA32, :packed, true],
|
52
|
+
[:abgr32, ::SDL::PIXELFORMAT_ABGR32, :packed, true],
|
53
|
+
[:yv12, ::SDL::PIXELFORMAT_YV12, :fourcc, false],
|
54
|
+
[:iyuv, ::SDL::PIXELFORMAT_IYUV, :fourcc, false],
|
55
|
+
[:yuy2, ::SDL::PIXELFORMAT_YUY2, :fourcc, false],
|
56
|
+
[:uyvy, ::SDL::PIXELFORMAT_UYVY, :fourcc, false],
|
57
|
+
[:yvyu, ::SDL::PIXELFORMAT_YVYU, :fourcc, false],
|
58
|
+
[:nv12, ::SDL::PIXELFORMAT_NV12, :fourcc, false],
|
59
|
+
[:nv21, ::SDL::PIXELFORMAT_NV21, :fourcc, false],
|
60
|
+
[:external_oes, ::SDL::PIXELFORMAT_EXTERNAL_OES, :fourcc, false],
|
61
|
+
]
|
62
|
+
|
63
|
+
FORMAT_MAP = table.map { |sym, n, _, _| [sym, n] }.to_h.freeze
|
64
|
+
|
65
|
+
INDEXED_TYPES = table.inject([]) { |a, (_, n, type, _)| a << n if type == :indexed; a }.freeze
|
66
|
+
|
67
|
+
WITH_ALPHA = table.inject([]) { |a, (_, n, _, alpha)| a << n if alpha; a }.freeze
|
22
68
|
|
23
69
|
class << self
|
24
|
-
def
|
25
|
-
|
26
|
-
def fourcc?(num) = (num >> 28) & 0x0F != 1
|
27
|
-
|
28
|
-
def indexed_type?(num) = !fourcc?(num) && INDEXED_TYPES.include?(to_type(num))
|
29
|
-
|
30
|
-
def packed_type?(num) = !fourcc?(num) && PACKED_TYPES.include?(to_type(num))
|
31
|
-
|
32
|
-
def to_fourcc(num)
|
33
|
-
4.times.inject([]) { |n, i| n << (num >> i * 8) % 0x100 }.pack("c4") if fourcc?
|
70
|
+
def to_name(num)
|
71
|
+
::SDL.GetPixelFormatName(num).read_string.delete_prefix("SDL_PIXELFORMAT_")
|
34
72
|
end
|
35
73
|
|
36
|
-
|
37
|
-
|
38
|
-
# obj は SDL の SDL_PIXELFORMAT_* 定数のどれか、または定数名でもよい。
|
39
|
-
# 定数名は RGBA32 のような短縮した名前でもよい。"UNKNOWN" も受け取れる(値は 0)。
|
40
|
-
# 該当するフォーマットがない場合は 0 (SDL_PIXELFORMAT_UNKNOWN) を戻す。
|
41
|
-
# SDL はオリジナルのフォーマットを処理しないことに注意。
|
74
|
+
# obj に与えたピクセルフォーマットに応じた整数値を戻す。
|
42
75
|
def to_num(obj)
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
def with_alpha?(num)
|
56
|
-
packed_type?(num) && PACKED_ORDERS.include?(to_order(num)) ||
|
57
|
-
array_type?(num) && ARRAY_ORDERS.include?(to_order(num))
|
76
|
+
case obj
|
77
|
+
when Symbol, String
|
78
|
+
sym = obj.to_sym.downcase
|
79
|
+
if FORMAT_MAP.key?(sym)
|
80
|
+
FORMAT_MAP[sym]
|
81
|
+
else
|
82
|
+
raise ArgumentError, "Invalid format name"
|
83
|
+
end
|
84
|
+
else
|
85
|
+
raise ArgumentError
|
86
|
+
end
|
58
87
|
end
|
59
88
|
end
|
60
89
|
|
61
|
-
|
90
|
+
# FOURCC が無い場合は nil を戻す。
|
91
|
+
def fourcc
|
92
|
+
4.times.inject([]) { |n, i| n << (num >> i * 8) % 0x100 }.pack("c4") if fourcc?
|
93
|
+
end
|
62
94
|
|
63
|
-
def fourcc? =
|
95
|
+
def fourcc? = (format >> 28) & 0x0F != 1
|
64
96
|
|
65
|
-
def format_name = PixelFormatEnum.
|
97
|
+
def format_name = PixelFormatEnum.to_num(format)
|
66
98
|
|
67
|
-
def indexed_color? = PixelFormatEnum.
|
99
|
+
def indexed_color? = PixelFormatEnum::INDEXED_TYPES.include?(format)
|
68
100
|
|
69
101
|
def rgb? = !(fourcc? || indexed_color? || rgba?)
|
70
102
|
|
71
|
-
def rgba? = PixelFormatEnum.
|
103
|
+
def rgba? = PixelFormatEnum::WITH_ALPHA.include?(format)
|
72
104
|
end
|
73
105
|
end
|
data/lib/rb_sdl2/platform.rb
CHANGED
data/lib/rb_sdl2/power_info.rb
CHANGED
@@ -1,36 +1,47 @@
|
|
1
1
|
module RbSDL2
|
2
|
-
|
3
|
-
|
2
|
+
class PowerInfo
|
3
|
+
def initialize
|
4
|
+
@battery_time = ::FFI::MemoryPointer.new(:int)
|
5
|
+
@battery_percentage = ::FFI::MemoryPointer.new(:int)
|
6
|
+
update
|
7
|
+
end
|
8
|
+
|
9
|
+
# バッテリーの残り容量(パーセント)を戻します。
|
10
|
+
# 残り容量を特定できない, またはバッテリーで動作していない場合 nil を戻します。
|
11
|
+
def battery_percentage = (num = @battery_percentage.read_int) >= 0 ? num : nil
|
12
|
+
|
13
|
+
# バッテリーの残り時間(秒)を戻します。
|
14
|
+
# 残り時間を特定できない、またはバッテリーで動作していない場合は nil を戻します。
|
15
|
+
def battery_time = (num = @battery_time.read_int) >= 0 ? num : nil
|
4
16
|
|
5
|
-
|
6
|
-
|
17
|
+
# バッテリーが搭載されているか?
|
18
|
+
def battery? = [::SDL::POWERSTATE_CHARGING,
|
19
|
+
::SDL::POWERSTATE_CHARGED,
|
20
|
+
::SDL::POWERSTATE_ON_BATTERY].include?(state)
|
7
21
|
|
8
|
-
|
9
|
-
|
22
|
+
# 電源あり、バッテリー満充電
|
23
|
+
def charged? = ::SDL::POWERSTATE_CHARGED == state
|
10
24
|
|
11
|
-
|
12
|
-
|
25
|
+
# 電源あり、バッテリー充電中
|
26
|
+
def charging? = ::SDL::POWERSTATE_CHARGING == state
|
13
27
|
|
14
|
-
|
15
|
-
|
28
|
+
# 電源あり、バッテリー非搭載(デスクトップパソコンなど)
|
29
|
+
def no_battery? = ::SDL::POWERSTATE_NO_BATTERY == state
|
16
30
|
|
17
|
-
|
18
|
-
|
31
|
+
# 電源なし、バッテリー使用中
|
32
|
+
def on_battery? = ::SDL::POWERSTATE_ON_BATTERY == state
|
19
33
|
|
20
|
-
|
21
|
-
|
34
|
+
# 電源に接続されているか?
|
35
|
+
def plugged_in? = !on_battery?
|
22
36
|
|
23
|
-
|
24
|
-
def plugged_in? = no_battery? || battery_charging? || battery_charged?
|
37
|
+
attr_reader :state
|
25
38
|
|
26
|
-
|
27
|
-
|
28
|
-
@battery_time, @battery_capacity = @secs_ptr.read_int, @pct_ptr.read_int
|
29
|
-
self
|
30
|
-
end
|
39
|
+
# 電源、バッテリーの情報なし
|
40
|
+
def unknown? = ::SDL::POWERSTATE_UNKNOWN == state
|
31
41
|
|
32
|
-
|
33
|
-
|
42
|
+
def update
|
43
|
+
@state = ::SDL.GetPowerInfo(@battery_time, @battery_percentage)
|
44
|
+
self
|
34
45
|
end
|
35
46
|
end
|
36
47
|
end
|
data/lib/rb_sdl2/rect.rb
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
module RbSDL2
|
2
2
|
class Rect
|
3
|
+
class << self
|
4
|
+
def to_ary(ptr)
|
5
|
+
::SDL::Rect.new(ptr).values
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
3
9
|
def initialize(x = 0, y = 0, w = 0, h = 0)
|
4
|
-
@st = ::
|
10
|
+
@st = ::SDL::Rect.new
|
5
11
|
@st[:x], @st[:y], @st[:w], @st[:h] = x, y, w, h
|
6
12
|
end
|
7
13
|
|
@@ -1,20 +1,35 @@
|
|
1
1
|
module RbSDL2
|
2
2
|
class RefCountPointer < ::FFI::AutoPointer
|
3
|
+
# 備考:SDL では参照カウンターを操作する際にロックを行っていない。
|
4
|
+
# SDL_AtomicAdd() を使用した理由はオブジェクトの生成をなるべく行わないようにするため。
|
3
5
|
class << self
|
4
|
-
def entity_class
|
5
|
-
|
6
|
-
|
6
|
+
def entity_class = raise NotImplementedError
|
7
|
+
|
8
|
+
def offset_of_refcount = entity_class.offset_of(:refcount)
|
9
|
+
|
10
|
+
def dec_ref(ptr) = ::SDL.SDL_AtomicAdd(ptr + offset_of_refcount, -1)
|
11
|
+
|
12
|
+
def inc_ref(ptr) = ::SDL.SDL_AtomicAdd(ptr + offset_of_refcount, 1)
|
7
13
|
|
8
14
|
def to_ptr(ptr)
|
9
|
-
|
10
|
-
|
11
|
-
#
|
12
|
-
|
13
|
-
|
15
|
+
obj = new(ptr)
|
16
|
+
|
17
|
+
# ポインターの参照カウントを増加する際に例外が発生すると、
|
18
|
+
# ポインターが GC に回収され refcount が実際の参照数より少なくなる。
|
19
|
+
# 例外を補足してポインターのファイナライザーを解除する。
|
20
|
+
unless ptr.null?
|
21
|
+
begin
|
22
|
+
inc_ref(ptr)
|
23
|
+
rescue => e
|
24
|
+
obj.autorelease = false
|
25
|
+
raise e
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
obj
|
14
30
|
end
|
15
31
|
end
|
16
32
|
|
17
|
-
|
18
|
-
def refcount = self.class.entity_class.new(self)[:refcount]
|
33
|
+
def refcount = get_int(self.class.offset_of_refcount)
|
19
34
|
end
|
20
35
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module RbSDL2
|
2
|
+
require_relative 'rw_ops_pointer'
|
3
|
+
|
4
|
+
class RWFile < RWOps
|
5
|
+
def initialize(path, mode = "r")
|
6
|
+
@path = path
|
7
|
+
ptr = ::SDL.RWFromFile(SDL.str_to_sdl(path), SDL.str_to_sdl(mode))
|
8
|
+
raise RbSDL2Error if ptr.null?
|
9
|
+
super(RWOpsPointer.new(ptr))
|
10
|
+
end
|
11
|
+
|
12
|
+
def inspect
|
13
|
+
"#<#{self.class.name}:#{path}#{closed? ? " (closed)" : nil}>"
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :path
|
17
|
+
alias to_path path
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module RbSDL2
|
2
|
+
require_relative 'rw_ops_pointer'
|
3
|
+
|
4
|
+
class RWMemory < RWOps
|
5
|
+
def initialize(obj, readonly: false, size: nil)
|
6
|
+
raise TypeError, "obj is NULL" if obj.nil? || obj.null?
|
7
|
+
size = size || obj.size
|
8
|
+
ptr = readonly ? ::SDL.RWFromConstMem(obj, size) : ::SDL.RWFromMem(obj, size)
|
9
|
+
raise RbSDL2Error if ptr.null?
|
10
|
+
super(RWOpsPointer.new(ptr))
|
11
|
+
@obj = obj
|
12
|
+
end
|
13
|
+
|
14
|
+
def inspect
|
15
|
+
"#<#{self.class.name}:memory#{closed? ? " (closed)" : nil}>"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
module RbSDL2
|
2
|
+
class RWObject < RWOps
|
3
|
+
class CloseCallback < ::FFI::Function
|
4
|
+
def initialize
|
5
|
+
# int (* close) (struct RWops * context);
|
6
|
+
super(:int, [:pointer]) do |context|
|
7
|
+
yield
|
8
|
+
0
|
9
|
+
rescue => e
|
10
|
+
raise e if $DEBUG
|
11
|
+
Error.last_error_message = e.message
|
12
|
+
-1
|
13
|
+
ensure
|
14
|
+
# SDL_RWclose() の仕様により成功、失敗問わずポインターを開放する。
|
15
|
+
::SDL.FreeRW(context)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class ReadCallback < ::FFI::Function
|
21
|
+
def initialize
|
22
|
+
# size_t (* read) (struct RWops * context, void *ptr, size_t size, size_t maxnum);
|
23
|
+
super(:size_t, [:pointer, :pointer, :size_t, :size_t]) do |_context, ptr, size, max_num|
|
24
|
+
num = size * max_num
|
25
|
+
str = yield(num)
|
26
|
+
next 0 if str.nil? # EOF
|
27
|
+
len = str.size
|
28
|
+
if len > num # 要求より多い文字数を返している。obj.read が壊れている。
|
29
|
+
raise RbSDL2Error, "The return value of read method is corrupted"
|
30
|
+
end
|
31
|
+
ptr.write_bytes(str, 0, len)
|
32
|
+
len / size
|
33
|
+
rescue => e
|
34
|
+
raise e if $DEBUG
|
35
|
+
Error.last_error_message = e.message
|
36
|
+
0
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class SeekCallback < ::FFI::Function
|
42
|
+
def initialize
|
43
|
+
# Sint64 (* seek) (struct RWops * context, Sint64 offset, int whence);
|
44
|
+
super(:int64, [:pointer, :int64, :int]) do |_context, offset, whence|
|
45
|
+
# SDL_RWseek() の仕様によりシーク後の現在位置を戻す必要がある。
|
46
|
+
yield(offset, whence)
|
47
|
+
rescue => e
|
48
|
+
raise e if $DEBUG
|
49
|
+
Error.last_error_message = e.message
|
50
|
+
-1
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class SizeCallback < ::FFI::Function
|
56
|
+
def initialize
|
57
|
+
# Sint64 (* size) (struct RWops * context);
|
58
|
+
super(:int64, [:pointer]) do |_context|
|
59
|
+
# Ruby ではサイズが不明な IO は size メソッドが無い(NoMethodError)。
|
60
|
+
yield
|
61
|
+
rescue => e
|
62
|
+
raise e if $DEBUG
|
63
|
+
Error.last_error_message = e.message
|
64
|
+
# 不明な時は -1。
|
65
|
+
-1
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
class WriteCallback < ::FFI::Function
|
71
|
+
def initialize
|
72
|
+
# size_t (* write) (struct RWops * context, const void *ptr, size_t size, size_t num);
|
73
|
+
super(:size_t, [:pointer, :pointer, :size_t, :size_t]) do |_context, ptr, size, max_num|
|
74
|
+
str = ptr.read_bytes(size * max_num)
|
75
|
+
yield(str) / size
|
76
|
+
rescue => e
|
77
|
+
raise e if $DEBUG
|
78
|
+
Error.last_error_message = e.message
|
79
|
+
0
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
require_relative 'rw_ops_pointer'
|
85
|
+
|
86
|
+
# obj 引数には Ruby の IO オブジェクトのように振る舞うオブジェクトを与える。
|
87
|
+
# 期待される振る舞いは close, read, seek, size, tell, write メソッド呼び出しに応答すること。
|
88
|
+
# メソッドが無い場合やメソッドから例外が出た場合は SDL 側にエラー値を戻す。
|
89
|
+
# autoclose 引数に true を与えた場合 close メソッドの呼び出し、GC の回収時に obj 引数に与えたオブジェクトを
|
90
|
+
# クローズする。
|
91
|
+
# C のスコープへ渡す場合、ポインターが利用されている間 RWOps オブジェクトを生存させる必要がある。
|
92
|
+
def initialize(obj)
|
93
|
+
ptr = ::SDL.AllocRW
|
94
|
+
raise RbSDL2Error if ptr.null?
|
95
|
+
super(
|
96
|
+
begin
|
97
|
+
# メンバーの関数ポインターが NULL であってはならない。
|
98
|
+
@st = ::SDL::RWops.new(ptr)
|
99
|
+
# 引数に与えた proc 内で例外が出たときは SDL へ例外メッセージがセットされエラーを表す戻り値が渡される。
|
100
|
+
# デバッグモードの時は Ruby 側へ例外を出す。
|
101
|
+
# close_proc: 引数はなし。戻り値は無視される。RWops ポインタの開放を行う必要はない。
|
102
|
+
# read_proc: 引数に読み出すバイト数。戻り値は文字列。
|
103
|
+
# seek_proc: 引数に offset, whence。IO#seek を参照。戻り値は現在位置(IO#tell)。
|
104
|
+
# size_proc: 引数はなし。戻り値はバイト数。不明な場合は何らかの例外を出す。
|
105
|
+
# write_proc: 引数に書き込む文字列。戻り値は実際に書き込んだバイト数。
|
106
|
+
@st[:close] = @close_callback = CloseCallback.new {} # obj.close しない。autoclose=false
|
107
|
+
@st[:read] = @read_callback = ReadCallback.new { |length| obj.read(length) }
|
108
|
+
@st[:seek] = @seek_callback = SeekCallback.new { |offset, whence| obj.seek(offset, whence); obj.tell }
|
109
|
+
@st[:size] = @size_callback = SizeCallback.new { obj.size }
|
110
|
+
@st[:write] = @write_callback = WriteCallback.new { |str| obj.write(str) }
|
111
|
+
RWOpsPointer.new(ptr)
|
112
|
+
rescue => e
|
113
|
+
::SDL.FreeRW(ptr)
|
114
|
+
raise e
|
115
|
+
end
|
116
|
+
)
|
117
|
+
@obj = obj
|
118
|
+
end
|
119
|
+
|
120
|
+
def __getobj__ = @obj
|
121
|
+
|
122
|
+
def inspect
|
123
|
+
"#<#{self.class.name}:#{@obj.inspect}#{closed? ? " (closed)" : nil}>"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|