rb_sdl2 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +5 -0
- data/LICENSE.txt +17 -0
- data/README.md +40 -0
- data/lib/rb_sdl2/audio/audio_allowed_changes.rb +17 -0
- data/lib/rb_sdl2/audio/audio_buffer.rb +49 -0
- data/lib/rb_sdl2/audio/audio_device.rb +44 -0
- data/lib/rb_sdl2/audio/audio_format.rb +23 -0
- data/lib/rb_sdl2/audio/audio_spec.rb +29 -0
- data/lib/rb_sdl2/audio.rb +132 -0
- data/lib/rb_sdl2/clipboard.rb +44 -0
- data/lib/rb_sdl2/cpu_info.rb +39 -0
- data/lib/rb_sdl2/cursor/color_cursor.rb +19 -0
- data/lib/rb_sdl2/cursor/cursor_class.rb +24 -0
- data/lib/rb_sdl2/cursor/cursor_pointer.rb +12 -0
- data/lib/rb_sdl2/cursor/default_cursor.rb +18 -0
- data/lib/rb_sdl2/cursor/system_cursor.rb +45 -0
- data/lib/rb_sdl2/cursor.rb +39 -0
- data/lib/rb_sdl2/display.rb +103 -0
- data/lib/rb_sdl2/display_mode.rb +35 -0
- data/lib/rb_sdl2/error.rb +9 -0
- data/lib/rb_sdl2/event/event_filter.rb +83 -0
- data/lib/rb_sdl2/event/event_queue.rb +137 -0
- data/lib/rb_sdl2/event/event_type.rb +271 -0
- data/lib/rb_sdl2/event.rb +161 -0
- data/lib/rb_sdl2/filesystem.rb +40 -0
- data/lib/rb_sdl2/hint.rb +24 -0
- data/lib/rb_sdl2/keyboard/key_mod.rb +37 -0
- data/lib/rb_sdl2/keyboard/keyboard_state.rb +34 -0
- data/lib/rb_sdl2/keyboard.rb +50 -0
- data/lib/rb_sdl2/message_box.rb +121 -0
- data/lib/rb_sdl2/mouse/global_mouse.rb +18 -0
- data/lib/rb_sdl2/mouse/mouse_button.rb +24 -0
- data/lib/rb_sdl2/mouse/mouse_class.rb +33 -0
- data/lib/rb_sdl2/mouse/mouse_wheel.rb +53 -0
- data/lib/rb_sdl2/mouse/relative_mouse.rb +12 -0
- data/lib/rb_sdl2/mouse/window_mouse.rb +17 -0
- data/lib/rb_sdl2/mouse.rb +74 -0
- data/lib/rb_sdl2/palette.rb +70 -0
- data/lib/rb_sdl2/pixel_format_enum.rb +73 -0
- data/lib/rb_sdl2/platform.rb +7 -0
- data/lib/rb_sdl2/power_info.rb +36 -0
- data/lib/rb_sdl2/rect.rb +14 -0
- data/lib/rb_sdl2/ref_count_pointer.rb +20 -0
- data/lib/rb_sdl2/rw_ops/rw_operator.rb +102 -0
- data/lib/rb_sdl2/rw_ops.rb +124 -0
- data/lib/rb_sdl2/screen_saver.rb +11 -0
- data/lib/rb_sdl2/sdl.rb +32 -0
- data/lib/rb_sdl2/surface/blend_mode.rb +41 -0
- data/lib/rb_sdl2/surface/pixel_format.rb +89 -0
- data/lib/rb_sdl2/surface.rb +244 -0
- data/lib/rb_sdl2/text_input.rb +15 -0
- data/lib/rb_sdl2/timer.rb +22 -0
- data/lib/rb_sdl2/version.rb +13 -0
- data/lib/rb_sdl2/video.rb +25 -0
- data/lib/rb_sdl2/window/dialog.rb +19 -0
- data/lib/rb_sdl2/window/display.rb +85 -0
- data/lib/rb_sdl2/window/grab.rb +23 -0
- data/lib/rb_sdl2/window/hit_test.rb +52 -0
- data/lib/rb_sdl2/window/position.rb +38 -0
- data/lib/rb_sdl2/window/shape.rb +76 -0
- data/lib/rb_sdl2/window/size.rb +59 -0
- data/lib/rb_sdl2/window/window_flags.rb +78 -0
- data/lib/rb_sdl2/window.rb +242 -0
- data/lib/rb_sdl2.rb +53 -0
- data/rb_sdl2.gemspec +19 -0
- metadata +135 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 101f794f351d219f8cc70180a9f02cd57c11c507e8542fad5d83c2e4635ea7cd
|
4
|
+
data.tar.gz: fc7e00d5985c46af575e81cdbd2bfd177464f14eeb111e2dfae41cdaffb75e51
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0dd39b4cb9da230fd7d63556a3db53be3d28eeee972a5a54aa945cffa246501d3684112d72b8f8b5f3f76cee58d47e21a226998ae791390c4f98d53222aa4cda
|
7
|
+
data.tar.gz: dca9330ed249b66a6b21ad6bc42a42a14cd014f95757529d3f9e14f927f0ca89c9989960e3403511ecb58d315ed28829ca8fa9a61e30a934250ee3cefc22d207
|
data/CHANGELOG.md
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
Copyright (C) 2021 shinokaro
|
2
|
+
|
3
|
+
This software is provided 'as-is', without any express or implied
|
4
|
+
warranty. In no event will the authors be held liable for any damages
|
5
|
+
arising from the use of this software.
|
6
|
+
|
7
|
+
Permission is granted to anyone to use this software for any purpose,
|
8
|
+
including commercial applications, and to alter it and redistribute it
|
9
|
+
freely, subject to the following restrictions:
|
10
|
+
|
11
|
+
1. The origin of this software must not be misrepresented; you must not
|
12
|
+
claim that you wrote the original software. If you use this software
|
13
|
+
in a product, an acknowledgment in the product documentation would be
|
14
|
+
appreciated but is not required.
|
15
|
+
2. Altered source versions must be plainly marked as such, and must not be
|
16
|
+
misrepresented as being the original software.
|
17
|
+
3. This notice may not be removed or altered from any source distribution.
|
data/README.md
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# RbSDL2
|
2
|
+
|
3
|
+
RbSDL2 は [SDL](https://www.libsdl.org) (Simple DirectMedia Layer) の機能を
|
4
|
+
Ruby オブジェクトとして提供します。
|
5
|
+
|
6
|
+
SDL 2.0.16 移行を対象としています。この Gem には SDL は含まれていません。
|
7
|
+
利用する際は環境に合わせて SDL を用意してください。
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
$ gem install rb_sdl2
|
12
|
+
|
13
|
+
## Usage
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
require 'rb_sdl2'
|
17
|
+
|
18
|
+
include RbSDL2
|
19
|
+
|
20
|
+
RbSDL2.load('SDL2 Library path') # SDL を読み込みます。必ず必要です。
|
21
|
+
RbSDL2.init # SDL を初期化します。
|
22
|
+
|
23
|
+
image = Surface.load("image.bmp") # 画像をメモリーに読み込みます。画像形式は BMP のみです。
|
24
|
+
window = Window.new("Title")
|
25
|
+
window.update { |s| s.blit(image) } # Window へ画像を描画します。
|
26
|
+
|
27
|
+
RbSDL2.loop do
|
28
|
+
break if Event.quit? # ユーザがウィンドウを閉じたことを検出します。
|
29
|
+
# キーボードの A キーを押したか調べます。押していればダイアログボックスを表示します。
|
30
|
+
window.info_alert("Message") if Keyboard.key?("A")
|
31
|
+
# マウスのボタン(種類問わず)を押したか調べます。押していればダイアログボックスを表示します。
|
32
|
+
window.error_alert("Message from mouse") if Mouse.any_button?
|
33
|
+
Timer.delay(33) # SDL のタイマーを使用して 33 ミリ秒間、停止します。
|
34
|
+
end
|
35
|
+
# 終了の際に SDL から得たポインターのことは考えなくてよい。 SDL_Quit() も不要。
|
36
|
+
```
|
37
|
+
|
38
|
+
## License
|
39
|
+
|
40
|
+
Zlib
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module RbSDL2
|
2
|
+
class Audio
|
3
|
+
module AudioAllowedChanges
|
4
|
+
class << self
|
5
|
+
def to_num(any_change: false, channels_change: false, format_change: false,
|
6
|
+
frequency_change: false, samples_change: false)
|
7
|
+
0 |
|
8
|
+
(any_change ? ::SDL2::SDL_AUDIO_ALLOW_ANY_CHANGE : 0) |
|
9
|
+
(channels_change ? ::SDL2::SDL_AUDIO_ALLOW_CHANNELS_CHANGE : 0) |
|
10
|
+
(format_change ? ::SDL2::SDL_AUDIO_ALLOW_FORMAT_CHANGE : 0) |
|
11
|
+
(frequency_change ? ::SDL2::SDL_AUDIO_ALLOW_FREQUENCY_CHANGE : 0) |
|
12
|
+
(samples_change ? ::SDL2::SDL_AUDIO_ALLOW_SAMPLES_CHANGE : 0)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module RbSDL2
|
2
|
+
class Audio
|
3
|
+
class AudioBuffer
|
4
|
+
class AudioBufferPointer < ::FFI::AutoPointer
|
5
|
+
def self.release(ptr) = ::SDL2::SDL_FreeWAV(ptr)
|
6
|
+
end
|
7
|
+
|
8
|
+
class << self
|
9
|
+
require_relative '../rw_ops'
|
10
|
+
|
11
|
+
def load(file) = RWOps.new(file, "rb") { |rw| load_rw(rw) }
|
12
|
+
|
13
|
+
require_relative 'audio_spec'
|
14
|
+
|
15
|
+
# load_rw は与えられたオブジェクトをオートクローズしません。
|
16
|
+
def load_rw(rw)
|
17
|
+
spec = AudioSpec.new
|
18
|
+
buf = ::FFI::MemoryPointer.new(:pointer)
|
19
|
+
len = ::FFI::MemoryPointer.new(:uint32)
|
20
|
+
err = ::SDL2::SDL_LoadWAV_RW(rw, 0, spec, buf, len)
|
21
|
+
raise RbSDL2Error if err.null?
|
22
|
+
new(AudioBufferPointer.new(buf.read_pointer), len.read_uint32, spec)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def initialize(ptr, size, spec)
|
27
|
+
@ptr = ptr
|
28
|
+
@size = size
|
29
|
+
@spec = spec
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_reader :size
|
33
|
+
alias length size
|
34
|
+
|
35
|
+
attr_reader :spec
|
36
|
+
|
37
|
+
require 'forwardable'
|
38
|
+
extend Forwardable
|
39
|
+
def_delegators :spec, *%i(channels format frequency)
|
40
|
+
|
41
|
+
require_relative 'audio_format'
|
42
|
+
include AudioFormat
|
43
|
+
|
44
|
+
def to_ptr = @ptr
|
45
|
+
|
46
|
+
def to_str = @ptr.read_bytes(size)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module RbSDL2
|
2
|
+
class Audio
|
3
|
+
class AudioDevice
|
4
|
+
class << self
|
5
|
+
def devices(capture = false)
|
6
|
+
is_capture = IS_CAPTURE.(capture)
|
7
|
+
::SDL2.SDL_GetNumAudioDevices(is_capture).times.map do |num|
|
8
|
+
ptr = ::SDL2.SDL_GetAudioDeviceName(num, is_capture)
|
9
|
+
raise RbSDL2Error if ptr.null?
|
10
|
+
|
11
|
+
spec = AudioSpec.new
|
12
|
+
# SDL_GetAudioDeviceSpec は SDL_GetNumAudioDevices の最新の呼び出しを反映する。
|
13
|
+
err = ::SDL2.SDL_GetAudioDeviceSpec(num, is_capture, spec)
|
14
|
+
raise RbSDL2Error if err != 0
|
15
|
+
|
16
|
+
new(ptr.read_string.force_encoding(Encoding::UTF_8), capture, spec)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize(name, capture, spec)
|
22
|
+
@capture = CAPTURE.(capture)
|
23
|
+
@name = name
|
24
|
+
@spec = spec
|
25
|
+
end
|
26
|
+
|
27
|
+
attr_reader :capture
|
28
|
+
|
29
|
+
attr_reader :name
|
30
|
+
alias to_s name
|
31
|
+
|
32
|
+
attr_reader :spec
|
33
|
+
|
34
|
+
require 'forwardable'
|
35
|
+
extend Forwardable
|
36
|
+
def_delegators :spec, *%i(channels format frequency)
|
37
|
+
|
38
|
+
require_relative 'audio_format'
|
39
|
+
include AudioFormat
|
40
|
+
|
41
|
+
def unknown? = channels == 0 && format == 0 && frequency == 0
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module RbSDL2
|
2
|
+
class Audio
|
3
|
+
module AudioFormat
|
4
|
+
class << self
|
5
|
+
def to_num(signed: true, big_endian: false, bit_size: 16, float: false)
|
6
|
+
num = 0 |
|
7
|
+
(big_endian ? ::SDL2::SDL_AUDIO_MASK_ENDIAN : 0) |
|
8
|
+
(bit_size & ::SDL2::SDL_AUDIO_MASK_BITSIZE) |
|
9
|
+
(signed ? ::SDL2::SDL_AUDIO_MASK_SIGNED : 0)
|
10
|
+
num | (float ? ::SDL2::SDL_AUDIO_MASK_DATATYPE & ::SDL2::SDL_AUDIO_MASK_SIGNED : 0)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def big_endian? = ::SDL2::SDL_AUDIO_MASK_ENDIAN & format != 0
|
15
|
+
|
16
|
+
def bit_size = ::SDL2::SDL_AUDIO_MASK_BITSIZE & format
|
17
|
+
|
18
|
+
def float? = ::SDL2::SDL_AUDIO_MASK_DATATYPE & format != 0
|
19
|
+
|
20
|
+
def signed? = ::SDL2::SDL_AUDIO_MASK_SIGNED & format != 0
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module RbSDL2
|
2
|
+
class Audio
|
3
|
+
class AudioSpec
|
4
|
+
require_relative 'audio_format'
|
5
|
+
|
6
|
+
def initialize(channels: 0, format: 0, freq: 0, frequency: freq, samples: 0)
|
7
|
+
@st = ::SDL2::SDL_AudioSpec.new
|
8
|
+
@st[:channels] = channels
|
9
|
+
@st[:format] = format
|
10
|
+
@st[:freq] = frequency
|
11
|
+
@st[:samples] = samples
|
12
|
+
end
|
13
|
+
|
14
|
+
def size = @st[:size]
|
15
|
+
alias chunk_size size
|
16
|
+
|
17
|
+
def channels = @st[:channels]
|
18
|
+
|
19
|
+
def format = @st[:format]
|
20
|
+
|
21
|
+
def freq = @st[:freq]
|
22
|
+
alias frequency freq
|
23
|
+
|
24
|
+
def samples = @st[:samples]
|
25
|
+
|
26
|
+
def to_ptr = @st.to_ptr
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
module RbSDL2
|
2
|
+
class Audio
|
3
|
+
IS_CAPTURE = -> (capture) { capture ? 1 : 0 }
|
4
|
+
CAPTURE = -> (capture) { capture ? true : false }
|
5
|
+
# AudioStream, AudioCallback の実装は行っていない。
|
6
|
+
# AudioCallback は Ruby 側からまともに使う方法がない。
|
7
|
+
# AudioStream はリアルタイムなリサンプラー、リフォーマッターとして使えるがこれが本当に必要か判らない。
|
8
|
+
class << self
|
9
|
+
def current
|
10
|
+
ptr = ::SDL2.SDL_GetCurrentAudioDriver
|
11
|
+
raise RbSDL2Error, "Audio subsystem has not been initialized" if ptr.null?
|
12
|
+
ptr.read_string
|
13
|
+
end
|
14
|
+
|
15
|
+
require_relative 'audio/audio_device'
|
16
|
+
|
17
|
+
def devices = AudioDevice.devices
|
18
|
+
|
19
|
+
def drivers
|
20
|
+
::SDL2.SDL_GetNumAudioDrivers.times.map do |num|
|
21
|
+
ptr = ::SDL2.SDL_GetAudioDriver(num)
|
22
|
+
raise RbSDL2Error if ptr.null?
|
23
|
+
ptr.read_string
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def init(driver)
|
28
|
+
raise RbSDL2Error if ::SDL2.SDL_AudioInit(driver) < 0
|
29
|
+
end
|
30
|
+
|
31
|
+
require_relative 'audio/audio_buffer'
|
32
|
+
|
33
|
+
def load(...) = AudioBuffer.load(...)
|
34
|
+
|
35
|
+
require_relative 'audio/audio_allowed_changes'
|
36
|
+
require_relative 'audio/audio_format'
|
37
|
+
require_relative 'audio/audio_spec'
|
38
|
+
|
39
|
+
def new(device = nil, capture = false, allowed_changes: {}, channels: 2, format: {},
|
40
|
+
frequency: 48_000, samples: 0)
|
41
|
+
want = AudioSpec.new(channels: channels, format: AudioFormat.to_num(**format),
|
42
|
+
frequency: frequency, samples: samples)
|
43
|
+
have = AudioSpec.new
|
44
|
+
id = ::SDL2.SDL_OpenAudioDevice(device&.to_s, IS_CAPTURE.(capture), want, have,
|
45
|
+
AudioAllowedChanges.to_num(**allowed_changes))
|
46
|
+
raise RbSDL2Error if id == 0
|
47
|
+
super(id, capture, have)
|
48
|
+
end
|
49
|
+
alias open new
|
50
|
+
|
51
|
+
def quit = ::SDL2.SDL_AudioQuit
|
52
|
+
end
|
53
|
+
|
54
|
+
def initialize(id, capture, spec)
|
55
|
+
@capture = CAPTURE.(capture)
|
56
|
+
@closed = false
|
57
|
+
@id = id
|
58
|
+
@spec = spec
|
59
|
+
end
|
60
|
+
|
61
|
+
def capture? = @capture
|
62
|
+
|
63
|
+
def clear
|
64
|
+
raise IOError if closed?
|
65
|
+
::SDL2.SDL_ClearQueuedAudio(self)
|
66
|
+
end
|
67
|
+
|
68
|
+
def close
|
69
|
+
::SDL2.SDL_CloseAudioDevice(id) unless @closed
|
70
|
+
@closed = true
|
71
|
+
nil
|
72
|
+
end
|
73
|
+
|
74
|
+
def closed? = @closed
|
75
|
+
|
76
|
+
attr_reader :id
|
77
|
+
alias to_int id
|
78
|
+
|
79
|
+
def pause
|
80
|
+
raise IOError if closed?
|
81
|
+
::SDL2.SDL_PauseAudioDevice(id, 1)
|
82
|
+
end
|
83
|
+
|
84
|
+
def play
|
85
|
+
raise IOError if closed?
|
86
|
+
::SDL2.SDL_PauseAudioDevice(id, 0)
|
87
|
+
end
|
88
|
+
|
89
|
+
def read(len)
|
90
|
+
raise IOError if closed?
|
91
|
+
ptr = ::FFI::MemoryPointer.new(len)
|
92
|
+
size = ::SDL2.SDL_DequeueAudio(id, ptr, len)
|
93
|
+
ptr.read_bytes(size)
|
94
|
+
end
|
95
|
+
|
96
|
+
def size
|
97
|
+
raise IOError if closed?
|
98
|
+
::SDL2.SDL_GetQueuedAudioSize(id)
|
99
|
+
end
|
100
|
+
alias length size
|
101
|
+
|
102
|
+
attr_reader :spec
|
103
|
+
|
104
|
+
require 'forwardable'
|
105
|
+
extend Forwardable
|
106
|
+
def_delegators :spec, *%i(channels chunk_size format frequency samples)
|
107
|
+
|
108
|
+
require_relative 'audio/audio_format'
|
109
|
+
include AudioFormat
|
110
|
+
|
111
|
+
def status
|
112
|
+
raise IOError if closed?
|
113
|
+
::SDL2.SDL_GetAudioDeviceStatus(id)
|
114
|
+
end
|
115
|
+
|
116
|
+
module AudioStatus
|
117
|
+
def paused? = ::SDL2::SDL_AUDIO_PAUSED == status
|
118
|
+
|
119
|
+
def playing? = ::SDL2::SDL_AUDIO_PLAYING == status
|
120
|
+
|
121
|
+
def stopped? = ::SDL2::SDL_AUDIO_STOPPED == status
|
122
|
+
end
|
123
|
+
include AudioStatus
|
124
|
+
|
125
|
+
def write(data)
|
126
|
+
raise IOError if closed?
|
127
|
+
err = ::SDL2.SDL_QueueAudio(id, data, data.size)
|
128
|
+
raise RbSDL2Error if err < 0
|
129
|
+
data.size
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module RbSDL2
|
2
|
+
module Clipboard
|
3
|
+
class << self
|
4
|
+
def clear = self.text = nil
|
5
|
+
|
6
|
+
# イベントを pump したとき外部からのクリップボード取得が行われる。
|
7
|
+
# その際に SDL_CLIPBOARDUPDATE イベントがキューに入る。これはイベントコールバックで捕獲できる。
|
8
|
+
# 読み出し時にクリップボードの内容はクリアーされない。
|
9
|
+
def text
|
10
|
+
# SDL_GetClipboardText は NULL ポインターを戻さない。返すべき内容がない場合は空の文字列を戻す。
|
11
|
+
::SDL2.SDL_GetClipboardText.read_string.force_encoding(Encoding::UTF_8)
|
12
|
+
ensure
|
13
|
+
# SDL_GetClipboardText は呼び出されるたびに OS から取得したクリップボードの内容を SDL 内部に保存し、
|
14
|
+
# それをさらにコピーしたものを戻す。
|
15
|
+
# アプリケーション側は取得した文字列ポインタを必ず開放しなければならない。
|
16
|
+
::SDL2.SDL_free(ptr)
|
17
|
+
end
|
18
|
+
|
19
|
+
# クリップボードの内容を戻す。text メソッドと違い読み出し後にクリップボードの内容をクリアーする。
|
20
|
+
def text!
|
21
|
+
str = text
|
22
|
+
clear
|
23
|
+
str
|
24
|
+
end
|
25
|
+
|
26
|
+
# クリップボードへ書き込む。クリップボードはパブリックであり他のアプリケーションから取得できる。
|
27
|
+
# 当然、SDL もこの書き込みを補足する。
|
28
|
+
# クリップボードの読み出しを行わずに、大量のクリップボード書き込みを行うと SDL はエラーを戻す。
|
29
|
+
# このエラーは SDL からではなく OS から戻るエラーである。書き込み上限や既に書き込んだ回数を知る方法はない。
|
30
|
+
# また、アプリケーション側でクリップボードを読み出しても制限を回避できない。
|
31
|
+
# (OS に保存されたクリップボードはパブリックなコピーでありユーザが取り出さなければそのコピーは消えないだろう)
|
32
|
+
def text=(obj)
|
33
|
+
raise RbSDL2Error if ::SDL2.SDL_SetClipboardText(obj&.to_s&.encode(Encoding::UTF_8)) < 0
|
34
|
+
end
|
35
|
+
|
36
|
+
# クリップボードに内容があるか確認をする。
|
37
|
+
# これはアプリケーションがクリップボードを読み出しても内容はクリアーされないため、
|
38
|
+
# クリップボードの更新を知るためには実装を工夫する必要がある。
|
39
|
+
# もっとも簡単な方法は、クリップボードの内容を読み込み度に Clipboard.text = nil を実行し、
|
40
|
+
# クリップボードをクリアする。
|
41
|
+
def text? = ::SDL2.SDL_HasClipboardText == ::SDL2::SDL_TRUE
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module RbSDL2
|
2
|
+
module CPUInfo
|
3
|
+
class << self
|
4
|
+
def cpu_count = ::SDL2.SDL_GetCPUCount
|
5
|
+
|
6
|
+
def cpu_cache_line_size = ::SDL2.SDL_GetCPUCacheLineSize
|
7
|
+
|
8
|
+
def system_ram = ::SDL2.SDL_GetSystemRAM
|
9
|
+
|
10
|
+
def rdtsc? = ::SDL2.SDL_HasRDTSC == ::SDL2::SDL_TRUE
|
11
|
+
|
12
|
+
def altivec? = ::SDL2.SDL_HasAltiVec == ::SDL2::SDL_TRUE
|
13
|
+
|
14
|
+
def mmx? = ::SDL2.SDL_HasMMX == ::SDL2::SDL_TRUE
|
15
|
+
|
16
|
+
def _3dnow? = ::SDL2.SDL_Has3DNow == ::SDL2::SDL_TRUE
|
17
|
+
|
18
|
+
def sse? = ::SDL2.SDL_HasSSE == ::SDL2::SDL_TRUE
|
19
|
+
|
20
|
+
def sse2? = ::SDL2.SDL_HasSSE2 == ::SDL2::SDL_TRUE
|
21
|
+
|
22
|
+
def sse3? = ::SDL2.SDL_HasSSE3 == ::SDL2::SDL_TRUE
|
23
|
+
|
24
|
+
def sse41? = ::SDL2.SDL_HasSSE41 == ::SDL2::SDL_TRUE
|
25
|
+
|
26
|
+
def sse42? = ::SDL2.SDL_HasSSE42 == ::SDL2::SDL_TRUE
|
27
|
+
|
28
|
+
def avx? = ::SDL2.SDL_HasAVX == ::SDL2::SDL_TRUE
|
29
|
+
|
30
|
+
def avx2? = ::SDL2.SDL_HasAVX2 == ::SDL2::SDL_TRUE
|
31
|
+
|
32
|
+
def avx512f = ::SDL2.SDL_HasAVX512F == ::SDL2::SDL_TRUE
|
33
|
+
|
34
|
+
def armsimd? = ::SDL2.SDL_HasARMSIMD == ::SDL2::SDL_TRUE
|
35
|
+
|
36
|
+
def neon? = ::SDL2.SDL_HasNEON == ::SDL2::SDL_TRUE
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module RbSDL2
|
2
|
+
module Cursor
|
3
|
+
require_relative 'cursor_class'
|
4
|
+
|
5
|
+
class ColorCursor < CursorClass
|
6
|
+
class << self
|
7
|
+
require_relative 'cursor_pointer'
|
8
|
+
|
9
|
+
def new(surface, hot_x = 0, hot_y = 0)
|
10
|
+
# SDL_CreateColorCursor は与えられた surface をコピーする。
|
11
|
+
# 呼び出し後に引数に与えた surface オブジェクトは安全に開放できる。
|
12
|
+
ptr = CursorPointer.new(::SDL2.SDL_CreateColorCursor(surface, hot_x, hot_y))
|
13
|
+
raise RbSDL2Error if ptr.null?
|
14
|
+
super(ptr)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module RbSDL2
|
2
|
+
module Cursor
|
3
|
+
class CursorClass
|
4
|
+
def initialize(ptr)
|
5
|
+
@ptr = ptr
|
6
|
+
end
|
7
|
+
|
8
|
+
def current! = Cursor.current = self
|
9
|
+
|
10
|
+
def current? = Cursor.current?(self)
|
11
|
+
|
12
|
+
def hide = Cursor.hide
|
13
|
+
|
14
|
+
def show
|
15
|
+
current!
|
16
|
+
Cursor.show
|
17
|
+
end
|
18
|
+
|
19
|
+
def shown? = Cursor.shown? && current?
|
20
|
+
|
21
|
+
def to_ptr = @ptr
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module RbSDL2
|
2
|
+
module Cursor
|
3
|
+
class CursorPointer < ::FFI::AutoPointer
|
4
|
+
class << self
|
5
|
+
# カーソルポインターはいつでも開放してよい。
|
6
|
+
# SDL はカレントカーソルが開放されたときはデフォルトカーソルをカレントカーソルに設定する。
|
7
|
+
# デフォルトカーソルは SDL_FreeCursorを呼び出しても開放されない。
|
8
|
+
def release(ptr) = ::SDL2.SDL_FreeCursor(ptr)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module RbSDL2
|
2
|
+
module Cursor
|
3
|
+
require_relative 'cursor_class'
|
4
|
+
|
5
|
+
class DefaultCursor < CursorClass
|
6
|
+
class << self
|
7
|
+
def new
|
8
|
+
ptr = ::SDL2.SDL_GetDefaultCursor
|
9
|
+
raise RbSDL2Error if ptr.null?
|
10
|
+
super(ptr)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'singleton'
|
15
|
+
include Singleton
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module RbSDL2
|
2
|
+
module Cursor
|
3
|
+
require_relative 'cursor_class'
|
4
|
+
|
5
|
+
class SystemCursor < CursorClass
|
6
|
+
require_relative 'cursor_pointer'
|
7
|
+
|
8
|
+
@cursors = Array.new(::SDL2::SDL_NUM_SYSTEM_CURSORS)
|
9
|
+
|
10
|
+
class << self
|
11
|
+
private def new(id)
|
12
|
+
return @cursors[id] if @cursors[id]
|
13
|
+
|
14
|
+
ptr = CursorPointer.new(::SDL2.SDL_CreateSystemCursor(id))
|
15
|
+
raise RbSDL2Error if ptr.null?
|
16
|
+
@cursors[id] = super(ptr)
|
17
|
+
end
|
18
|
+
|
19
|
+
def arrow_cursor = new(::SDL2::SDL_SYSTEM_CURSOR_ARROW)
|
20
|
+
|
21
|
+
def crosshair_cursor = new(::SDL2::SDL_SYSTEM_CURSOR_CROSSHAIR)
|
22
|
+
|
23
|
+
def hand_cursor = new(::SDL2::SDL_SYSTEM_CURSOR_HAND)
|
24
|
+
|
25
|
+
def i_beam_cursor = new(::SDL2::SDL_SYSTEM_CURSOR_IBEAM)
|
26
|
+
|
27
|
+
def no_cursor = new(::SDL2::SDL_SYSTEM_CURSOR_NO)
|
28
|
+
|
29
|
+
def size_all_cursor = new(SDL_SYSTEM_CURSOR_SIZEALL)
|
30
|
+
|
31
|
+
def size_ne_sw_cursor = new(::SDL2::SDL_SYSTEM_CURSOR_SIZENESW)
|
32
|
+
|
33
|
+
def size_ns_cursor = new(::SDL2::SDL_SYSTEM_CURSOR_SIZENS)
|
34
|
+
|
35
|
+
def size_nw_se_cursor = new(::SDL2::SDL_SYSTEM_CURSOR_SIZENWSE)
|
36
|
+
|
37
|
+
def size_we_cursor = new(::SDL2::SDL_SYSTEM_CURSOR_SIZEWE)
|
38
|
+
|
39
|
+
def wait_cursor = new(::SDL2::SDL_SYSTEM_CURSOR_WAIT)
|
40
|
+
|
41
|
+
def wait_arrow_cursor = new(::SDL2::SDL_SYSTEM_CURSOR_WAITARROW)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module RbSDL2
|
2
|
+
module Cursor
|
3
|
+
# カーソルポインターが外部から設定される場合があるため、現在のカーソルを取得する方法を提供しない。
|
4
|
+
class << self
|
5
|
+
require_relative 'cursor/color_cursor'
|
6
|
+
def color_cursor(...) = ColorCursor.new(...)
|
7
|
+
|
8
|
+
def current=(cursor)
|
9
|
+
::SDL2.SDL_SetCursor(cursor)
|
10
|
+
end
|
11
|
+
|
12
|
+
def current?(cursor)
|
13
|
+
::SDL2.SDL_GetCursor == cursor.to_ptr
|
14
|
+
end
|
15
|
+
|
16
|
+
require_relative 'cursor/default_cursor'
|
17
|
+
def default_cursor = DefaultCursor.instance
|
18
|
+
|
19
|
+
def hide = ::SDL2.SDL_ShowCursor(::SDL2::SDL_DISABLE)
|
20
|
+
|
21
|
+
def show = ::SDL2.SDL_ShowCursor(::SDL2::SDL_ENABLE)
|
22
|
+
|
23
|
+
def shown? = ::SDL2.SDL_ShowCursor(::SDL2::SDL_QUERY) == ::SDL2::SDL_ENABLE
|
24
|
+
|
25
|
+
def update
|
26
|
+
self.current = nil
|
27
|
+
self
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
require 'forwardable'
|
32
|
+
extend SingleForwardable
|
33
|
+
require_relative 'cursor/system_cursor'
|
34
|
+
def_single_delegators :SystemCursor,
|
35
|
+
*%i(arrow_cursor crosshair_cursor hand_cursor i_beam_cursor no_cursor
|
36
|
+
size_all_cursor size_ne_sw_cursor size_ns_cursor size_nw_se_cursor
|
37
|
+
size_we_cursor wait_cursor wait_arrow_cursor)
|
38
|
+
end
|
39
|
+
end
|