SDLRuby 0.2.1 → 0.3.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -1
- data/lib/SDLRuby/keyboard.rb +43 -32
- data/lib/SDLRuby/mouse.rb +105 -27
- data/lib/SDLRuby/rw/operational.rb +116 -0
- data/lib/SDLRuby/rw/read_closure.rb +28 -0
- data/lib/SDLRuby/rw/seek_closure.rb +22 -0
- data/lib/SDLRuby/rw/size_closure.rb +21 -0
- data/lib/SDLRuby/rw/write_closure.rb +21 -0
- data/lib/SDLRuby/rw_ops/mem_close.rb +27 -0
- data/lib/SDLRuby/rw_ops/rw_object.rb +34 -128
- data/lib/SDLRuby/rw_ops.rb +91 -216
- data/lib/SDLRuby/sdl/include/SDL_keycode.h.rb +70 -70
- data/lib/SDLRuby/sdl.rb +218 -191
- data/lib/SDLRuby/timer.rb +25 -0
- data/lib/SDLRuby/version.rb +1 -1
- data/lib/SDLRuby/window/surfacer.rb +37 -37
- data/sig/lib/SDLRuby/keyboard.rbs +25 -0
- data/sig/lib/SDLRuby/mouse.rbs +35 -0
- data/sig/lib/SDLRuby/timer.rbs +7 -0
- metadata +12 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fb651b451bbc9fc356e5f3a1ecb08d5855a690fa7b0556f7a9da5f0f11f2d6d4
|
4
|
+
data.tar.gz: 9f53754821bf14951f4cd014f1b776d07a5b3807a81ceee937ce96e6f71e148e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f5cfbf90c23eb97fcec12e34af27a2966e7d5c3fc010186a28ff1ec2c4caaf5a5cefc0ed68863907f9dad417688b1ec9dc61388e4d4723fb199cfcf5b7582553
|
7
|
+
data.tar.gz: b91967cab249f58717362fa4d1241e650d0a38b54ff340167a631a76691a5a17811961fc675a9edfbd0ea8ff2259e4d9c0800c08999cf2273535091f529ce2b4
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
-
## [0.
|
3
|
+
## [0.3.1] - 2023-09-28
|
4
|
+
- Refactored RWOps class.
|
5
|
+
|
6
|
+
## [0.3.0] - 2023-09-19
|
7
|
+
- Implemented Mouse Module.
|
8
|
+
- Implementation of the Timer Module.
|
9
|
+
- Implemented Keyboard Module.
|
10
|
+
- Specification and implementation of SDL.init, SDL.init?, and SDL.quit.
|
11
|
+
|
12
|
+
## [0.2.1] - 2023-09-13
|
4
13
|
|
5
14
|
- Memory leak fix on event retrieval failure.
|
6
15
|
|
data/lib/SDLRuby/keyboard.rb
CHANGED
@@ -3,56 +3,67 @@ module SDLRuby
|
|
3
3
|
module_eval do
|
4
4
|
num_keys = SDL.tmp_value("int")
|
5
5
|
|
6
|
-
# SDL_GetKeyboardState
|
7
|
-
#
|
6
|
+
# The SDL_GetKeyboardState function can be called before SDL_Init.
|
7
|
+
#
|
8
8
|
ptr = SDL.SDL_GetKeyboardState(num_keys)
|
9
9
|
|
10
|
-
#
|
10
|
+
# SDL_GetKeyboardState returns an error when num_keys is NULL.
|
11
|
+
#
|
11
12
|
raise SDLError if ptr.null?
|
12
13
|
|
13
14
|
ptr.size = num_keys.value
|
14
|
-
@
|
15
|
+
@ptr = ptr.freeze
|
15
16
|
end
|
16
17
|
|
17
18
|
class << self
|
18
|
-
|
19
|
-
raise IndexError if idx < 0 || @state.size <= idx
|
20
|
-
@state[idx] != 0
|
21
|
-
end
|
22
|
-
|
23
|
-
def any? = to_a.any?
|
24
|
-
|
25
|
-
def clear = SDL.SDL_ResetKeyboard
|
26
|
-
|
27
|
-
# キー名からキーコードを得る
|
28
|
-
def keycode(s) = SDL.GetKeyFromName(s).nonzero?
|
19
|
+
include SDL
|
29
20
|
|
30
|
-
#
|
31
|
-
|
32
|
-
|
21
|
+
# This method specifies the ability to check for a match with
|
22
|
+
# the characters appearing in the 'when' clause of a 'case' statement.
|
23
|
+
#
|
24
|
+
# see also: String#===
|
25
|
+
#
|
26
|
+
def ==(other)
|
27
|
+
case other
|
28
|
+
when Integer
|
29
|
+
0 <= other && other < @ptr.size && @ptr[other] != 0
|
30
|
+
when String, Symbol
|
31
|
+
(idx = scancode(other)) != 0 && @ptr[idx] != 0
|
32
|
+
else
|
33
|
+
super
|
34
|
+
end
|
33
35
|
end
|
34
36
|
|
35
|
-
|
36
|
-
|
37
|
-
|
37
|
+
def any?
|
38
|
+
# SDL sets a byte to either 0x00 or 0x01 for each scancode.
|
39
|
+
# It does not fill the byte sequence with 0x80, so this should work.
|
40
|
+
#
|
41
|
+
to_str.sum != 0
|
38
42
|
end
|
39
43
|
|
40
|
-
|
41
|
-
|
42
|
-
|
44
|
+
def clear
|
45
|
+
# SDL_ResetKeyboard should be preceded by initializing SDL events since
|
46
|
+
# it sends SDLK_KEYUP events for pressed keys.
|
47
|
+
#
|
48
|
+
# Calling SDL_ResetKeyboard when the SDL event subsystem is not initialized
|
49
|
+
# results in a core dump.
|
50
|
+
#
|
51
|
+
SDL.SDL_ResetKeyboard if SDL.init?(SDL_INIT_EVENTS)
|
43
52
|
end
|
44
53
|
|
45
|
-
|
46
|
-
def scancode(s) = SDL.GetScancodeFromName(s).nonzero?
|
54
|
+
def mod = SDL.SDL_GetModState
|
47
55
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
56
|
+
def scancode(s) = SDL.SDL_GetScancodeFromName(s.to_s)
|
57
|
+
|
58
|
+
def scancode_name(num) = SDL.SDL_GetScancodeName(num).to_s
|
59
|
+
|
60
|
+
def size = @ptr.size
|
61
|
+
|
62
|
+
alias length size
|
52
63
|
|
53
|
-
def to_a =
|
64
|
+
def to_a = size.times.select { |i| @ptr[i] != 0 }
|
54
65
|
|
55
|
-
def to_str = @
|
66
|
+
def to_str = @ptr.to_str
|
56
67
|
end
|
57
68
|
end
|
58
69
|
end
|
data/lib/SDLRuby/mouse.rb
CHANGED
@@ -1,52 +1,130 @@
|
|
1
1
|
module SDLRuby
|
2
2
|
module Mouse
|
3
|
-
@global_x, @global_y = *SDL.tmp_value("int", "int")
|
4
|
-
@relative_x, @relative_y = *SDL.tmp_value("int", "int")
|
5
|
-
@x, @y = *SDL.tmp_value("int", "int")
|
6
|
-
|
7
3
|
class << self
|
8
4
|
include SDL
|
9
5
|
|
10
|
-
def
|
11
|
-
[
|
12
|
-
num & SDL_BUTTON_LMASK != 0,
|
13
|
-
num & SDL_BUTTON_MMASK != 0,
|
14
|
-
num & SDL_BUTTON_RMASK != 0,
|
15
|
-
num & SDL_BUTTON_X1MASK != 0,
|
16
|
-
num & SDL_BUTTON_X2MASK != 0
|
17
|
-
]
|
18
|
-
end
|
6
|
+
def button = button_to_ary(WindowMouse.button)
|
19
7
|
|
8
|
+
# If called without initializing the SDL video subsystem,
|
9
|
+
# even if a mouse is present in the system, it will return an error.
|
10
|
+
#
|
11
|
+
# This method must be called from the main thread.
|
12
|
+
#
|
20
13
|
def capture=(b)
|
21
14
|
err = SDL.SDL_CaptureMouse(b ? 1 : 0)
|
22
15
|
raise SDLError if err < 0
|
23
16
|
end
|
24
17
|
|
18
|
+
def global_button = button_to_ary(GlobalMouse.button)
|
19
|
+
|
20
|
+
def global_pos = GlobalMouse.pos
|
21
|
+
|
22
|
+
# If called without initializing the SDL video subsystem,
|
23
|
+
# even if a mouse is present in the system, it will return an error.
|
24
|
+
#
|
25
25
|
def global_pos=(xy)
|
26
|
-
|
27
|
-
raise SDLError if err < 0
|
26
|
+
GlobalMouse.pos=(xy)
|
28
27
|
end
|
29
28
|
|
30
|
-
def global_state
|
31
|
-
|
32
|
-
|
33
|
-
|
29
|
+
def global_state
|
30
|
+
a = GlobalMouse.state
|
31
|
+
a[0] = button_to_ary(a[0])
|
32
|
+
a
|
33
|
+
end
|
34
34
|
|
35
|
+
def pos = WindowMouse.pos
|
36
|
+
|
37
|
+
def pos=(xy)
|
38
|
+
SDL.SDL_WarpMouseInWindow(nil, *xy)
|
39
|
+
end
|
40
|
+
|
41
|
+
# If called without initializing the SDL video subsystem,
|
42
|
+
# even if a mouse is present in the system, it will return an error.
|
43
|
+
#
|
35
44
|
def relative=(b)
|
36
45
|
err = SDL.SDL_SetRelativeMouseMode(b ? 1 : 0)
|
37
46
|
raise SDLError if err < 0
|
38
47
|
end
|
39
48
|
|
40
|
-
def relative? = SDL.SDL_GetRelativeMouseMode
|
49
|
+
def relative? = SDL.SDL_GetRelativeMouseMode != 0
|
50
|
+
|
51
|
+
def relative_pos = RelativeMouse.pos
|
52
|
+
|
53
|
+
def relative_state
|
54
|
+
a = RelativeMouse.state
|
55
|
+
a[0] = button_to_ary(a[0])
|
56
|
+
a
|
57
|
+
end
|
58
|
+
|
59
|
+
def state
|
60
|
+
a = WindowMouse.state
|
61
|
+
a[0] = button_to_ary(a[0])
|
62
|
+
a
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def button_to_ary(num)
|
68
|
+
[
|
69
|
+
num & SDL_BUTTON_LMASK != 0,
|
70
|
+
num & SDL_BUTTON_MMASK != 0,
|
71
|
+
num & SDL_BUTTON_RMASK != 0,
|
72
|
+
num & SDL_BUTTON_X1MASK != 0,
|
73
|
+
num & SDL_BUTTON_X2MASK != 0,
|
74
|
+
]
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
module GlobalMouse
|
79
|
+
@x, @y = SDL.tmp_value("int", "int")
|
80
|
+
|
81
|
+
class << self
|
82
|
+
def button = SDL.SDL_GetGlobalMouseState(nil, nil)
|
41
83
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
84
|
+
def pos
|
85
|
+
SDL.SDL_GetGlobalMouseState(@x, @y)
|
86
|
+
[@x.value, @y.value]
|
87
|
+
end
|
46
88
|
|
47
|
-
|
48
|
-
|
49
|
-
|
89
|
+
def pos=(xy)
|
90
|
+
err = SDL.SDL_WarpMouseGlobal(*xy)
|
91
|
+
raise SDLError if err < 0
|
92
|
+
end
|
93
|
+
|
94
|
+
def state = [SDL.SDL_GetGlobalMouseState(@x, @y), @x.value, @y.value]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
module RelativeMouse
|
99
|
+
@x, @y = SDL.tmp_value("int", "int")
|
100
|
+
|
101
|
+
class << self
|
102
|
+
def pos
|
103
|
+
SDL.SDL_GetRelativeMouseState(@x, @y)
|
104
|
+
[@x.value, @y.value]
|
105
|
+
end
|
106
|
+
|
107
|
+
def state = [SDL.SDL_GetRelativeMouseState(@x, @y), @x.value, @y.value]
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
module WindowMouse
|
112
|
+
@x, @y = SDL.tmp_value("int", "int")
|
113
|
+
|
114
|
+
class << self
|
115
|
+
def button = SDL.SDL_GetMouseState(nil, nil)
|
116
|
+
|
117
|
+
def pos
|
118
|
+
SDL.SDL_GetMouseState(@x, @y)
|
119
|
+
[@x.value, @y.value]
|
120
|
+
end
|
121
|
+
|
122
|
+
def pos=(xy)
|
123
|
+
SDL.SDL_WarpMouseInWindow(nil, *xy)
|
124
|
+
end
|
125
|
+
|
126
|
+
def state = [SDL.SDL_GetMouseState(@x, @y), @x.value, @y.value]
|
127
|
+
end
|
50
128
|
end
|
51
129
|
end
|
52
130
|
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
module SDLRuby
|
2
|
+
class RW
|
3
|
+
module Operational
|
4
|
+
def close
|
5
|
+
unless closed?
|
6
|
+
err = SDL.SDL_RWclose(to_ptr)
|
7
|
+
|
8
|
+
raise SDLError if err < 0
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def closed? = to_ptr.freed?
|
13
|
+
|
14
|
+
def eof?
|
15
|
+
raise SDLError, "closed and freed rw" if closed?
|
16
|
+
|
17
|
+
s = SDL.SDL_RWsize(to_ptr)
|
18
|
+
raise SDLError if s < 0
|
19
|
+
|
20
|
+
t = SDL.SDL_RWtell(to_ptr)
|
21
|
+
raise SDLError if t < 0
|
22
|
+
|
23
|
+
s == t
|
24
|
+
end
|
25
|
+
|
26
|
+
def read(length = nil, buffer = nil)
|
27
|
+
raise SDLError, "closed and freed rw" if closed?
|
28
|
+
|
29
|
+
if length.nil?
|
30
|
+
len = size - tell
|
31
|
+
else
|
32
|
+
len = Integer.try_convert(length)
|
33
|
+
if len.nil?
|
34
|
+
raise TypeError,
|
35
|
+
"no implicit conversion of #{length.class} into Integer"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
if len < 0
|
40
|
+
raise ArgumentError, "negative length #{len} given"
|
41
|
+
end
|
42
|
+
|
43
|
+
if buffer.nil?
|
44
|
+
buffer = ""
|
45
|
+
else
|
46
|
+
buffer = String.try_convert(buffer)
|
47
|
+
if buffer.nil?
|
48
|
+
raise TypeError,
|
49
|
+
"no implicit conversion of #{buffer.class} into String"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
if eof? || len == 0
|
54
|
+
buffer.clear
|
55
|
+
return len == 0 ? buffer : nil
|
56
|
+
end
|
57
|
+
|
58
|
+
bytesize = buffer.bytesize
|
59
|
+
if len == bytesize
|
60
|
+
buffer
|
61
|
+
elsif len > bytesize
|
62
|
+
buffer.gsub!(/\z/nm, "\x00" * (len - bytesize))
|
63
|
+
elsif len < bytesize
|
64
|
+
buffer.gsub!(/[\x00-\xFF]{#{bytesize - len}}\z/nm, "")
|
65
|
+
end
|
66
|
+
|
67
|
+
n = SDL.SDL_RWread(to_ptr, buffer, 1, len)
|
68
|
+
if n < len
|
69
|
+
buffer.gsub!(/[\x00-\xFF]{#{n}}$/nm, "")
|
70
|
+
end
|
71
|
+
raise SDLError if n == 0
|
72
|
+
|
73
|
+
buffer
|
74
|
+
end
|
75
|
+
|
76
|
+
def seek(offset, whence = IO::SEEK_SET)
|
77
|
+
raise SDLError, "closed and freed rw" if closed?
|
78
|
+
|
79
|
+
n = SDL.SDL_RWseek(to_ptr, offset, whence)
|
80
|
+
raise SDLError if n < 0
|
81
|
+
0
|
82
|
+
end
|
83
|
+
|
84
|
+
alias pos= seek
|
85
|
+
|
86
|
+
def size
|
87
|
+
raise SDLError, "closed and freed rw" if closed?
|
88
|
+
|
89
|
+
n = SDL.SDL_RWsize(to_ptr)
|
90
|
+
raise SDLError if n < 0
|
91
|
+
n
|
92
|
+
end
|
93
|
+
|
94
|
+
def tell
|
95
|
+
raise SDLError, "closed and freed rw" if closed?
|
96
|
+
|
97
|
+
n = SDL.SDL_RWtell(to_ptr)
|
98
|
+
raise SDLError if n < 0
|
99
|
+
n
|
100
|
+
end
|
101
|
+
|
102
|
+
alias pos tell
|
103
|
+
|
104
|
+
def write(obj)
|
105
|
+
raise SDLError, "closed and freed rw" if closed?
|
106
|
+
|
107
|
+
ptr = obj.to_s
|
108
|
+
len = ptr.bytesize
|
109
|
+
|
110
|
+
n = SDL.SDL_RWwrite(to_ptr, ptr, 1, len)
|
111
|
+
raise SDLError if n < len
|
112
|
+
n
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module SDLRuby
|
2
|
+
class RW
|
3
|
+
class ReadClosure < Fiddle::Closure
|
4
|
+
include Fiddle
|
5
|
+
|
6
|
+
def initialize(obj)
|
7
|
+
# size_t (*read) (SDL_RWops *context, void *ptr, size_t size, size_t maxnum)
|
8
|
+
#
|
9
|
+
super(TYPE_SIZE_T, [TYPE_VOIDP, TYPE_VOIDP, TYPE_SIZE_T, TYPE_SIZE_T])
|
10
|
+
@obj = obj
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(_, ptr, size, maxnum)
|
14
|
+
len = size * maxnum
|
15
|
+
return 0 if len.zero?
|
16
|
+
|
17
|
+
s = @obj.read(len)
|
18
|
+
return 0 if s.nil? || s.empty? # EOF
|
19
|
+
|
20
|
+
ptr[0, s.size] = s
|
21
|
+
s.size / size
|
22
|
+
rescue => e
|
23
|
+
SDL.last_error_message = e.message
|
24
|
+
0
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module SDLRuby
|
2
|
+
class RW
|
3
|
+
class SeekClosure < Fiddle::Closure
|
4
|
+
include Fiddle
|
5
|
+
|
6
|
+
def initialize(obj)
|
7
|
+
# Sint64 (*seek) (SDL_RWops *context, Sint64 offset, int whence)
|
8
|
+
#
|
9
|
+
super(TYPE_INT64_T, [TYPE_VOIDP, TYPE_INT64_T, TYPE_INT])
|
10
|
+
@obj = obj
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(_, offset, whence)
|
14
|
+
@obj.seek(offset, whence)
|
15
|
+
@obj.tell
|
16
|
+
rescue => e
|
17
|
+
SDL.last_error_message = e.message
|
18
|
+
-1
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module SDLRuby
|
2
|
+
class RW
|
3
|
+
class SizeClosure < Fiddle::Closure
|
4
|
+
include Fiddle
|
5
|
+
|
6
|
+
def initialize(obj)
|
7
|
+
# Sint64 (*size) (SDL_RWops *context)
|
8
|
+
#
|
9
|
+
super(TYPE_INT64_T, [TYPE_VOIDP])
|
10
|
+
@obj = obj
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(_)
|
14
|
+
@obj.size
|
15
|
+
rescue => e
|
16
|
+
SDL.last_error_message = e.message
|
17
|
+
-1
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module SDLRuby
|
2
|
+
class RW
|
3
|
+
class WriteClosure < Fiddle::Closure
|
4
|
+
include Fiddle
|
5
|
+
|
6
|
+
def initialize(obj)
|
7
|
+
# size_t (*write) (SDL_RWops *context, const void *ptr, size_t size, size_t num)
|
8
|
+
#
|
9
|
+
super(TYPE_SIZE_T, [TYPE_VOIDP, TYPE_VOIDP, TYPE_SIZE_T, TYPE_SIZE_T])
|
10
|
+
@obj = obj
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(_, ptr, size, num)
|
14
|
+
@obj.write(ptr.to_str(size * num)) / size
|
15
|
+
rescue => e
|
16
|
+
SDL.last_error_message = e.message
|
17
|
+
0
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module SDLRuby
|
2
|
+
class RWOps
|
3
|
+
include Fiddle, SDL
|
4
|
+
|
5
|
+
# これはSDL3では不要になります。
|
6
|
+
# SDL3ではメンバーの関数ポインターにNULLを設定できます。
|
7
|
+
# それは”適切な”デフォルトの動作を意味します。
|
8
|
+
#
|
9
|
+
#
|
10
|
+
#
|
11
|
+
# SDL2ではcloseにはC関数ポインターを設定する必要がある。
|
12
|
+
# Rubyのクロージャ―を設定するとGCが動作時に該当のクロージャ―が既に回収されているため
|
13
|
+
# コアダンプする。
|
14
|
+
# また、NULLに設定するとSDL_RWclose関数の呼び出し時にコアダンプする。
|
15
|
+
# ここではSDLをハックしてmem_close関数を割り当てた。
|
16
|
+
# この関数は内部でSDL_FreeRW関数を呼び出すだけである。
|
17
|
+
#
|
18
|
+
# int (*close) (SDL_RWops *context)
|
19
|
+
#
|
20
|
+
MEM_CLOSE = module_eval do
|
21
|
+
ptr = Pointer.malloc(1, RUBY_FREE)
|
22
|
+
rw = SDL.SDL_RWFromMem(ptr, ptr.size)
|
23
|
+
raise SDLError if rw.null?
|
24
|
+
SDL_RWops.new(rw, SDL_FREE_RW)["close"].to_int
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -1,128 +1,34 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
def initialize(obj)
|
37
|
-
super(TYPE_INT64_T, [TYPE_VOIDP, TYPE_INT64_T, TYPE_INT])
|
38
|
-
@obj = obj
|
39
|
-
end
|
40
|
-
|
41
|
-
def call(_, offset, whence)
|
42
|
-
@obj.seek(offset, whence)
|
43
|
-
@obj.tell
|
44
|
-
rescue => e
|
45
|
-
SDL.last_error_message = e.full_message
|
46
|
-
-1
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
# Sint64 (*size) (SDL_RWops *context)
|
51
|
-
#
|
52
|
-
class SizeClosure < Fiddle::Closure
|
53
|
-
include Fiddle
|
54
|
-
|
55
|
-
def initialize(obj)
|
56
|
-
super(TYPE_INT64_T, [TYPE_VOIDP])
|
57
|
-
@obj = obj
|
58
|
-
end
|
59
|
-
|
60
|
-
def call(_)
|
61
|
-
@obj.size
|
62
|
-
rescue => e
|
63
|
-
raise e if $DEBUG
|
64
|
-
SDL.last_error_message = e.full_message
|
65
|
-
-1
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
# size_t (*write) (SDL_RWops *context, const void *ptr, size_t size, size_t num)
|
70
|
-
#
|
71
|
-
class WriteClosure < Fiddle::Closure
|
72
|
-
include Fiddle
|
73
|
-
|
74
|
-
def initialize(obj)
|
75
|
-
super(TYPE_SIZE_T, [TYPE_VOIDP, TYPE_VOIDP, TYPE_SIZE_T, TYPE_SIZE_T])
|
76
|
-
@obj = obj
|
77
|
-
end
|
78
|
-
|
79
|
-
def call(_, ptr, size, num)
|
80
|
-
@obj.write(ptr.to_str(size * num)) / size
|
81
|
-
rescue => e
|
82
|
-
SDL.last_error_message = e.full_message
|
83
|
-
0
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
# closeにはC関数を設定する必要がある。
|
88
|
-
# クロージャ―を設定するとGCによる回収の際に
|
89
|
-
# 該当のクロージャ―が既に回収されているためコアダンプする。
|
90
|
-
# また、NULLに設定するとSDL_RWclose関数の呼び出し時にコアダンプする。
|
91
|
-
# SDLをハックしてmem_close関数を割り当てた。
|
92
|
-
# この関数は内部でSDL_FreeRW関数を呼び出すだけである。
|
93
|
-
#
|
94
|
-
# int (*close) (SDL_RWops *context)
|
95
|
-
#
|
96
|
-
MEM_CLOSE = module_eval do
|
97
|
-
_ptr = Pointer.malloc(1, RUBY_FREE)
|
98
|
-
rw = SDL.SDL_RWFromMem(_ptr, _ptr.size)
|
99
|
-
raise SDLError if rw.null?
|
100
|
-
st = SDL_RWops.new(rw)
|
101
|
-
|
102
|
-
st.close.freeze
|
103
|
-
end
|
104
|
-
|
105
|
-
# 引数 obj に与えたオブジェクトは SDL から close を呼び出されてもクローズしない。
|
106
|
-
# このインスタンスを単独で扱う場合は使い終わったらclose関数を呼び出す必要がある。
|
107
|
-
# そうしなければポインターは開放されずメモリーリークする。
|
108
|
-
#
|
109
|
-
def initialize(obj)
|
110
|
-
ptr = SDL.SDL_AllocRW
|
111
|
-
raise SDLError if ptr.null?
|
112
|
-
|
113
|
-
# SDLではSDL_RWopsポインターの開放はclose関数から行うように実装されている。
|
114
|
-
# これと同じ仕様とするため、このインスタンスではfreeの設定を行わない。
|
115
|
-
#
|
116
|
-
@st = SDL_RWops.new(ptr)
|
117
|
-
|
118
|
-
@st.close = MEM_CLOSE
|
119
|
-
@st.read = @read = ReadClosure.new(obj)
|
120
|
-
@st.seek = @seek = SeekClosure.new(obj)
|
121
|
-
@st.size = @size = SizeClosure.new(obj)
|
122
|
-
@st.write = @write = WriteClosure.new(obj)
|
123
|
-
end
|
124
|
-
|
125
|
-
def to_ptr = @st.to_ptr
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
1
|
+
require_relative '../rw/read_closure'
|
2
|
+
require_relative '../rw/seek_closure'
|
3
|
+
require_relative '../rw/size_closure'
|
4
|
+
require_relative '../rw/write_closure'
|
5
|
+
require_relative 'mem_close'
|
6
|
+
|
7
|
+
module SDLRuby
|
8
|
+
class RWOps
|
9
|
+
class RWObject
|
10
|
+
include Fiddle, SDL
|
11
|
+
|
12
|
+
# 引数objに与えたオブジェクトはSDLからcloseを呼び出されてもクローズしない。
|
13
|
+
# このインスタンスを単独で扱う場合は使い終わったらclose関数を呼び出す必要がある。
|
14
|
+
# そうしなければポインターは開放されずメモリーリークする。
|
15
|
+
#
|
16
|
+
def initialize(obj)
|
17
|
+
ptr = SDL.SDL_AllocRW
|
18
|
+
raise SDLError if ptr.null?
|
19
|
+
|
20
|
+
@st = SDL_RWops.new(ptr)
|
21
|
+
|
22
|
+
# SDLではSDL_RWopsポインターの開放はclose関数ポインターを呼び出して行う仕様となっている。
|
23
|
+
#
|
24
|
+
@st.close = MEM_CLOSE
|
25
|
+
@st.read = @read = RW::ReadClosure.new(obj)
|
26
|
+
@st.seek = @seek = RW::SeekClosure.new(obj)
|
27
|
+
@st.size = @size = RW::SizeClosure.new(obj)
|
28
|
+
@st.write = @write = RW::WriteClosure.new(obj)
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_ptr = @st.to_ptr
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|