rb_sdl2 0.1.0 → 0.2.0

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.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +69 -0
  3. data/README.md +15 -1
  4. data/lib/rb_sdl2/audio/audio.rb +162 -0
  5. data/lib/rb_sdl2/audio/audio_buffer.rb +12 -19
  6. data/lib/rb_sdl2/audio/audio_device.rb +17 -23
  7. data/lib/rb_sdl2/audio/audio_spec.rb +38 -6
  8. data/lib/rb_sdl2/audio/audio_spec_reader.rb +10 -0
  9. data/lib/rb_sdl2/clipboard.rb +31 -31
  10. data/lib/rb_sdl2/cpu_info.rb +34 -17
  11. data/lib/rb_sdl2/cursor.rb +105 -24
  12. data/lib/rb_sdl2/display.rb +16 -16
  13. data/lib/rb_sdl2/display_mode.rb +1 -1
  14. data/lib/rb_sdl2/error.rb +14 -3
  15. data/lib/rb_sdl2/errors.rb +7 -0
  16. data/lib/rb_sdl2/event/event.rb +130 -0
  17. data/lib/rb_sdl2/event/event_filter.rb +34 -70
  18. data/lib/rb_sdl2/event/event_pointer.rb +26 -0
  19. data/lib/rb_sdl2/event/event_queue.rb +97 -120
  20. data/lib/rb_sdl2/event/event_type.rb +147 -205
  21. data/lib/rb_sdl2/filesystem.rb +8 -9
  22. data/lib/rb_sdl2/hint.rb +26 -24
  23. data/lib/rb_sdl2/keyboard/keyboard.rb +50 -0
  24. data/lib/rb_sdl2/keyboard/mod_state.rb +68 -0
  25. data/lib/rb_sdl2/keyboard/state.rb +39 -0
  26. data/lib/rb_sdl2/message_box.rb +69 -102
  27. data/lib/rb_sdl2/mouse/global_mouse.rb +10 -3
  28. data/lib/rb_sdl2/mouse/mouse.rb +64 -0
  29. data/lib/rb_sdl2/mouse/mouse_button.rb +13 -11
  30. data/lib/rb_sdl2/mouse/mouse_class.rb +9 -17
  31. data/lib/rb_sdl2/mouse/mouse_wheel.rb +21 -37
  32. data/lib/rb_sdl2/mouse/relative_mouse.rb +15 -1
  33. data/lib/rb_sdl2/palette.rb +15 -11
  34. data/lib/rb_sdl2/pixel_format_enum.rb +87 -55
  35. data/lib/rb_sdl2/platform.rb +3 -1
  36. data/lib/rb_sdl2/power_info.rb +34 -23
  37. data/lib/rb_sdl2/rect.rb +7 -1
  38. data/lib/rb_sdl2/ref_count_pointer.rb +25 -10
  39. data/lib/rb_sdl2/rw_ops/rw_file.rb +19 -0
  40. data/lib/rb_sdl2/rw_ops/rw_memory.rb +18 -0
  41. data/lib/rb_sdl2/rw_ops/rw_object.rb +126 -0
  42. data/lib/rb_sdl2/rw_ops/rw_ops.rb +104 -0
  43. data/lib/rb_sdl2/rw_ops/rw_ops_pointer.rb +14 -0
  44. data/lib/rb_sdl2/sdl.rb +72 -21
  45. data/lib/rb_sdl2/sdl_pointer.rb +22 -0
  46. data/lib/rb_sdl2/surface/blend_mode.rb +41 -41
  47. data/lib/rb_sdl2/surface/pixel_format.rb +34 -33
  48. data/lib/rb_sdl2/surface.rb +280 -244
  49. data/lib/rb_sdl2/text_input.rb +21 -15
  50. data/lib/rb_sdl2/timer.rb +36 -22
  51. data/lib/rb_sdl2/version.rb +5 -3
  52. data/lib/rb_sdl2/video.rb +17 -5
  53. data/lib/rb_sdl2/window/accessor.rb +135 -0
  54. data/lib/rb_sdl2/window/display.rb +8 -8
  55. data/lib/rb_sdl2/window/flash.rb +22 -0
  56. data/lib/rb_sdl2/window/hit_test.rb +22 -43
  57. data/lib/rb_sdl2/window/shape.rb +55 -40
  58. data/lib/rb_sdl2/window/state.rb +178 -0
  59. data/lib/rb_sdl2/window/window.rb +149 -0
  60. data/lib/rb_sdl2.rb +79 -17
  61. data/rb_sdl2.gemspec +12 -4
  62. metadata +38 -37
  63. data/lib/rb_sdl2/audio/audio_allowed_changes.rb +0 -17
  64. data/lib/rb_sdl2/audio/audio_format.rb +0 -23
  65. data/lib/rb_sdl2/audio.rb +0 -132
  66. data/lib/rb_sdl2/cursor/color_cursor.rb +0 -19
  67. data/lib/rb_sdl2/cursor/cursor_class.rb +0 -24
  68. data/lib/rb_sdl2/cursor/cursor_pointer.rb +0 -12
  69. data/lib/rb_sdl2/cursor/default_cursor.rb +0 -18
  70. data/lib/rb_sdl2/cursor/system_cursor.rb +0 -45
  71. data/lib/rb_sdl2/event.rb +0 -161
  72. data/lib/rb_sdl2/keyboard/key_mod.rb +0 -37
  73. data/lib/rb_sdl2/keyboard/keyboard_state.rb +0 -34
  74. data/lib/rb_sdl2/keyboard.rb +0 -50
  75. data/lib/rb_sdl2/mouse/window_mouse.rb +0 -17
  76. data/lib/rb_sdl2/mouse.rb +0 -74
  77. data/lib/rb_sdl2/rw_ops/rw_operator.rb +0 -102
  78. data/lib/rb_sdl2/rw_ops.rb +0 -124
  79. data/lib/rb_sdl2/screen_saver.rb +0 -11
  80. data/lib/rb_sdl2/window/dialog.rb +0 -19
  81. data/lib/rb_sdl2/window/grab.rb +0 -23
  82. data/lib/rb_sdl2/window/position.rb +0 -38
  83. data/lib/rb_sdl2/window/size.rb +0 -59
  84. data/lib/rb_sdl2/window/window_flags.rb +0 -78
  85. data/lib/rb_sdl2/window.rb +0 -242
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 101f794f351d219f8cc70180a9f02cd57c11c507e8542fad5d83c2e4635ea7cd
4
- data.tar.gz: fc7e00d5985c46af575e81cdbd2bfd177464f14eeb111e2dfae41cdaffb75e51
3
+ metadata.gz: f1a9691e0a9183d9ab18c54b3082684680479e993b94b8d4671c36a4a7607554
4
+ data.tar.gz: d92d27fba832167ee810572136eefb2f5eab51ba6d7c0c2ef5d434dbc2d69fd5
5
5
  SHA512:
6
- metadata.gz: 0dd39b4cb9da230fd7d63556a3db53be3d28eeee972a5a54aa945cffa246501d3684112d72b8f8b5f3f76cee58d47e21a226998ae791390c4f98d53222aa4cda
7
- data.tar.gz: dca9330ed249b66a6b21ad6bc42a42a14cd014f95757529d3f9e14f927f0ca89c9989960e3403511ecb58d315ed28829ca8fa9a61e30a934250ee3cefc22d207
6
+ metadata.gz: 1935c67fec1c889641e3e47dabd95ca1770239804fcb40d4930f6d1509496a27dfbeed0ddef48460abbcaa03e5afe9bc66db7ae434941085d59b35b83daa7a17
7
+ data.tar.gz: bd86b878ce15b8663bcc0a0056b8e0ddd700192ba93f39257fb7707fdc5ed032662395df3e13c087297eb25e4e8751626202db34afdc3ad306c91f54ff97fc0c
data/CHANGELOG.md CHANGED
@@ -1,5 +1,74 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.2.0] - 2022-05-08
4
+
5
+ ### Added
6
+ - Error.last_error_message= - SDL のエラーメッセージを設定する。
7
+ - Event - SDL_TEXTEDITING_EXT, SDL_POLLSENTINEL イベントを追加。
8
+ - RbSDL2 - クラスメソッドへ CPUInfo, Keyboard, Platform, SDL, Timer, Version のメソッドを追加した。
9
+ - RbSDL2.alert, error_alert, info_alert, warn_alert - シンプルなメッセージボックスを開く。
10
+ - RbSDL2.confirm, confirm? - Ok, Cancel のボタンがあるメッセージボックスを開く。
11
+ - RbSDL2.clipboard_text, RbSDL2.clipboard_text= - テキストクリップボードの読み書き。
12
+ - RbSDL2.hide_cursor, show_cursor - マウスカーソルの表示状態を変更する。
13
+ - RbSDL2.open_rw - ファイル、メモリー、IO オブジェクトを RWOps インスタンスで開く。Surface.load などで使用する。
14
+ - RbSDL2.open_url - アプリケーションからブラウザーを起動できる。
15
+ - RbSDL2.power_info - システムの電源状態を取得する。
16
+ - RbSDL2.screen_saver?, screen_saver= - スクリーンセーバー起動の可否状態を取得、設定する。
17
+ - RWFile, RWMemory, RWObject - SDL の SDL_RWops コンストラクターに応じてクラスを分けた。RWOps を継承している。
18
+ - SDL.ptr_to_str, SDL.str_to_sdl - Ruby 文字列と SDL 文字列の相互変換。
19
+ - SDLPointer - SDL のメモリーアロケーターを使用したメモリー領域を扱うためのクラス。
20
+ - Surface#pixel_color - 指定座標のピクセルのカラーを戻す。
21
+ - Surface#pixel - 指定座標のピクセル値を戻す。
22
+ - Window#mouse_rect, mouse_rect= - ウィンドウ内のマウス移動範囲を指定する。
23
+
24
+ ### Changed
25
+ - Ruby のバージョン要求を 3.1 以上に変更した。
26
+ - sdl2-bindings v0.1.1 に対応した。以前のバージョンは使用できない。
27
+ - Audio, Cursor, Event, Keyboard, Mouse, Window - リファクタリング。再設計した。
28
+ - Error.message -> Error.last_error_message
29
+ - RbSDL2.loop - ループごとに Event.clear を呼び出すのをやめた。これはイベントを握りつぶさないようにするため。
30
+ - RWOps - SDL_RWops コンストラクタ毎に子クラスへ分けた。実際に利用する際には RbSDL2.open_rw を使うこと。
31
+ - SDL.init, SDL.init? - 引数の形式を変更。
32
+ - Window#popup -> Window#current!
33
+
34
+ ### Deprecated
35
+
36
+ ### Fixed
37
+
38
+ ### Removed
39
+ - AudioBuffer.load_rw - load に取り込まれた。
40
+ - PixelFormatEnum - パックされたフォーマットの解析メソッドを削除。実装を変更し不要になった。
41
+ - Surface.load_rw - load に取り込まれた。
42
+ - Surface#save_rw - save に取り込まれた。
43
+
44
+ ### Security
45
+
46
+ ## [0.1.2] - 2021-10-19
47
+
48
+ ### Added
49
+ - RWOps#inspect - Return Ruby File#inspect like string.
50
+
51
+ ### Changed
52
+ - RWOps - The constructor can accept blocks.
53
+ - RWOperator - Code cleanup.
54
+
55
+ ### Fixed
56
+ - RWOps - some bugs.
57
+ - RWOperator - some bugs.
58
+
59
+ ### Removed
60
+ - RWOps.to_ptr - There is no use case.
61
+
62
+ ## [0.1.1] - 2021-10-11
63
+
64
+ ### Added
65
+ - Added metadata to gemspec.
66
+ - Added document to Error, Platform, SDL, Surface, Timer, and Version.
67
+ - Added description to README.md.
68
+
69
+ ### Changed
70
+ - Changed the contents of Palette#inspect to something meaningful.
71
+
3
72
  ## [0.1.0] - 2021-10-10
4
73
 
5
74
  - Initial release
data/README.md CHANGED
@@ -3,9 +3,23 @@
3
3
  RbSDL2 は [SDL](https://www.libsdl.org) (Simple DirectMedia Layer) の機能を
4
4
  Ruby オブジェクトとして提供します。
5
5
 
6
- SDL 2.0.16 移行を対象としています。この Gem には SDL は含まれていません。
6
+ SDL 2.0.22 以降を対象としています。この Gem には SDL は含まれていません。
7
7
  利用する際は環境に合わせて SDL を用意してください。
8
8
 
9
+ ## Description
10
+
11
+ RbSDL2 は SDL の機能やポインターを Ruby オブジェクトとして扱います。
12
+ ポインター管理を RbSDL2 が行っているのでメモリー管理を気にせずに SDL の機能を使うことができます。
13
+ 最低限のマネージ機能も用意しています。例えばコールバック関数を設定した場合はそのオブジェクトを保持します。
14
+ スコープを外れてもコアダンプすることはありません。
15
+
16
+ [sdl2-bindings](https://rubygems.org/gems/sdl2-bindings) を基に構築していますので、
17
+ オブジェクトの仕様や性能が気に入らない場合は直接(そして全ての) SDL 関数を呼び出すこともできます。
18
+ 各オブジェクトは外部からのポインターから作成することができます。
19
+ C で書いたライブラリとの部分的な連携に利用することもできます。
20
+
21
+ SDL の仕様や機能について知っている必要はありますが Ruby のコードを読めれば使えるようになっています。
22
+
9
23
  ## Installation
10
24
 
11
25
  $ gem install rb_sdl2
@@ -0,0 +1,162 @@
1
+ module RbSDL2
2
+ class Audio
3
+ SDL_AUDIO_ALLOW_FREQUENCY_CHANGE = 0x00000001
4
+ SDL_AUDIO_ALLOW_FORMAT_CHANGE = 0x00000002
5
+ SDL_AUDIO_ALLOW_CHANNELS_CHANGE = 0x00000004
6
+ SDL_AUDIO_ALLOW_SAMPLES_CHANGE = 0x00000008
7
+ SDL_AUDIO_ALLOW_ANY_CHANGE = SDL_AUDIO_ALLOW_FREQUENCY_CHANGE | SDL_AUDIO_ALLOW_FORMAT_CHANGE |
8
+ SDL_AUDIO_ALLOW_CHANNELS_CHANGE | SDL_AUDIO_ALLOW_SAMPLES_CHANGE
9
+
10
+ SDL_AUDIO_STOPPED = 0
11
+ SDL_AUDIO_PLAYING = 1
12
+ SDL_AUDIO_PAUSED = 2
13
+
14
+ IS_CAPTURE = -> (capture) { capture ? 1 : 0 }
15
+
16
+ class << self
17
+ require_relative 'audio_device'
18
+
19
+ def devices = AudioDevice.devices
20
+
21
+ def driver
22
+ ptr = ::SDL.GetCurrentAudioDriver
23
+ raise RbSDL2Error, "Audio subsystem has not been initialized" if ptr.null?
24
+ ptr.read_string
25
+ end
26
+
27
+ def drivers
28
+ ::SDL.GetNumAudioDrivers.times.map do |num|
29
+ ptr = ::SDL.GetAudioDriver(num)
30
+ raise RbSDL2Error if ptr.null?
31
+ ptr.read_string
32
+ end
33
+ end
34
+
35
+ def init(driver)
36
+ raise RbSDL2Error if ::SDL.AudioInit(driver) < 0
37
+ end
38
+
39
+ require_relative 'audio_buffer'
40
+
41
+ def load(...) = AudioBuffer.load(...)
42
+
43
+ def open(...)
44
+ obj = new(...)
45
+ return obj unless block_given?
46
+ begin
47
+ yield(obj)
48
+ ensure
49
+ obj.close
50
+ end
51
+ end
52
+
53
+ def play(path)
54
+ buffer = load(path)
55
+ obj = Audio.new(spec: buffer.spec)
56
+ obj.write(buffer)
57
+ obj.play
58
+ obj
59
+ end
60
+
61
+ def quit = ::SDL.AudioQuit
62
+ end
63
+
64
+ require_relative 'audio_spec'
65
+
66
+ def initialize(device = nil, capture = false, allow_any_change: false,
67
+ allow_channels_change: false, allow_frequency_change: false,
68
+ allow_format_change: false, allow_samples_change: false,
69
+ autoclose: true, spec: nil, **opts)
70
+ @capture = capture ? true : false
71
+ @spec = AudioSpec.new
72
+ allowed_changes = if allow_any_change
73
+ SDL_AUDIO_ALLOW_ANY_CHANGE
74
+ else
75
+ 0 |
76
+ (allow_channels_change ? SDL_AUDIO_ALLOW_CHANNELS_CHANGE : 0) |
77
+ (allow_frequency_change ? SDL_AUDIO_ALLOW_FREQUENCY_CHANGE : 0) |
78
+ (allow_format_change ? SDL_AUDIO_ALLOW_FORMAT_CHANGE : 0) |
79
+ (allow_samples_change ? SDL_AUDIO_ALLOW_SAMPLES_CHANGE : 0)
80
+ end
81
+ @id = ::SDL.OpenAudioDevice(device ? SDL.str_to_sdl(device) : nil, IS_CAPTURE.(capture),
82
+ spec || AudioSpec.new(**opts), @spec, allowed_changes)
83
+ raise RbSDL2Error if @id == 0
84
+ self.autoclose = autoclose
85
+ end
86
+
87
+ class Releaser
88
+ def initialize(num) = @id = num
89
+
90
+ def call(_id) = ::SDL.CloseAudioDevice(@id)
91
+ end
92
+
93
+ def autoclose=(bool)
94
+ return if closed?
95
+ if bool
96
+ ObjectSpace.define_finalizer(self, Releaser.new(@id))
97
+ else
98
+ ObjectSpace.undefine_finalizer(self)
99
+ end
100
+ @autoclose = bool ? true : false
101
+ end
102
+
103
+ def autoclose? = @autoclose
104
+
105
+ def capture? = @capture
106
+
107
+ def clear = closed? ? nil : ::SDL.ClearQueuedAudio(self)
108
+
109
+ def close
110
+ unless closed?
111
+ self.autoclose = false
112
+ @id = ::SDL.CloseAudioDevice(@id)
113
+ end
114
+ nil
115
+ end
116
+
117
+ def closed? = SDL_AUDIO_STOPPED == ::SDL.GetAudioDeviceStatus(@id) || !@id
118
+
119
+ def id
120
+ raise IOError if closed?
121
+ @id
122
+ end
123
+ alias audio_id id
124
+
125
+ def inspect
126
+ "#<#{self.class.name}:#{audio_id}#{closed? ? " (closed)" : nil}>"
127
+ end
128
+
129
+ def pause = closed? ? nil : ::SDL.PauseAudioDevice(id, 1)
130
+
131
+ def paused? = closed? ? false : SDL_AUDIO_PAUSED == ::SDL.GetAudioDeviceStatus(id)
132
+
133
+ def play = closed? ? nil : ::SDL.PauseAudioDevice(id, 0)
134
+
135
+ def playing? = closed? ? false : SDL_AUDIO_PLAYING == ::SDL.GetAudioDeviceStatus(id)
136
+
137
+ def read(len)
138
+ raise IOError if closed?
139
+ ptr = ::FFI::MemoryPointer.new(len)
140
+ size = ::SDL.DequeueAudio(id, ptr, len)
141
+ ptr.read_bytes(size)
142
+ end
143
+
144
+ def size
145
+ raise IOError if closed?
146
+ ::SDL.GetQueuedAudioSize(id)
147
+ end
148
+ alias length size
149
+
150
+ attr_reader :spec
151
+
152
+ require_relative 'audio_spec_reader'
153
+ include AudioSpecReader
154
+
155
+ def write(data)
156
+ raise IOError if closed?
157
+ err = ::SDL.QueueAudio(id, data, data.size)
158
+ raise RbSDL2Error if err < 0
159
+ data.size
160
+ end
161
+ end
162
+ end
@@ -2,24 +2,21 @@ module RbSDL2
2
2
  class Audio
3
3
  class AudioBuffer
4
4
  class AudioBufferPointer < ::FFI::AutoPointer
5
- def self.release(ptr) = ::SDL2::SDL_FreeWAV(ptr)
5
+ def self.release(ptr) = ::SDL::FreeWAV(ptr)
6
6
  end
7
7
 
8
8
  class << self
9
- require_relative '../rw_ops'
10
-
11
- def load(file) = RWOps.new(file, "rb") { |rw| load_rw(rw) }
12
-
13
9
  require_relative 'audio_spec'
14
10
 
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)
11
+ def load(obj)
12
+ RbSDL2.open_rw(obj) do |rw|
13
+ spec = AudioSpec.new
14
+ buf = ::FFI::MemoryPointer.new(:pointer)
15
+ len = ::FFI::MemoryPointer.new(:uint32)
16
+ err = ::SDL::LoadWAV_RW(rw, 0, spec, buf, len)
17
+ raise RbSDL2Error if err.null?
18
+ new(AudioBufferPointer.new(buf.read_pointer), len.read_uint32, spec)
19
+ end
23
20
  end
24
21
  end
25
22
 
@@ -34,12 +31,8 @@ module RbSDL2
34
31
 
35
32
  attr_reader :spec
36
33
 
37
- require 'forwardable'
38
- extend Forwardable
39
- def_delegators :spec, *%i(channels format frequency)
40
-
41
- require_relative 'audio_format'
42
- include AudioFormat
34
+ require_relative 'audio_spec_reader'
35
+ include AudioSpecReader
43
36
 
44
37
  def to_ptr = @ptr
45
38
 
@@ -3,42 +3,36 @@ module RbSDL2
3
3
  class AudioDevice
4
4
  class << self
5
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
6
+ ::SDL.GetNumAudioDevices(IS_CAPTURE.(capture)).times.map { |num| new(num, capture) }
18
7
  end
19
8
  end
20
9
 
21
- def initialize(name, capture, spec)
22
- @capture = CAPTURE.(capture)
23
- @name = name
10
+ def initialize(num, capture)
11
+ is_capture = IS_CAPTURE.(capture)
12
+ ptr = ::SDL.GetAudioDeviceName(num, is_capture)
13
+ raise RbSDL2Error if ptr.null?
14
+
15
+ spec = AudioSpec.new
16
+ # GetAudioDeviceSpec は GetNumAudioDevices の最新の呼び出しを反映する。
17
+ err = ::SDL.GetAudioDeviceSpec(num, is_capture, spec)
18
+ raise RbSDL2Error if err != 0
19
+
20
+ @capture = capture ? true : false
21
+ @name = SDL.ptr_to_str(ptr)
24
22
  @spec = spec
25
23
  end
26
24
 
27
- attr_reader :capture
25
+ def capture? = @capture
28
26
 
29
27
  attr_reader :name
30
28
  alias to_s name
31
29
 
32
30
  attr_reader :spec
33
31
 
34
- require 'forwardable'
35
- extend Forwardable
36
- def_delegators :spec, *%i(channels format frequency)
37
-
38
- require_relative 'audio_format'
39
- include AudioFormat
32
+ require_relative 'audio_spec_reader'
33
+ include AudioSpecReader
40
34
 
41
- def unknown? = channels == 0 && format == 0 && frequency == 0
35
+ def unknown? = spec.unknown?
42
36
  end
43
37
  end
44
38
  end
@@ -1,29 +1,61 @@
1
1
  module RbSDL2
2
2
  class Audio
3
3
  class AudioSpec
4
- require_relative 'audio_format'
4
+ module Reader
5
+ require 'forwardable'
6
+ extend Forwardable
7
+ def_delegators :spec,
8
+ *%i(big_endian? bitsize float? signed? channels format frequency samples)
9
+ end
10
+
11
+ SDL_AUDIO_MASK_BITSIZE = 0xFF
12
+ SDL_AUDIO_MASK_DATATYPE = 1 << 8
13
+ SDL_AUDIO_MASK_ENDIAN = 1 << 12
14
+ SDL_AUDIO_MASK_SIGNED = 1 << 15
5
15
 
6
- def initialize(channels: 0, format: 0, freq: 0, frequency: freq, samples: 0)
7
- @st = ::SDL2::SDL_AudioSpec.new
16
+ def initialize(big_endian: false, bitsize: 16, float: false, signed: true,
17
+ channels: 0, format: nil, frequency: 0, samples: 0)
18
+ @st = ::SDL::AudioSpec.new
8
19
  @st[:channels] = channels
9
- @st[:format] = format
20
+ @st[:format] = format || 0 |
21
+ (big_endian ? SDL_AUDIO_MASK_ENDIAN : 0) |
22
+ (bitsize & SDL_AUDIO_MASK_BITSIZE) |
23
+ (float ? SDL_AUDIO_MASK_DATATYPE & SDL_AUDIO_MASK_SIGNED : 0) |
24
+ (signed ? SDL_AUDIO_MASK_SIGNED : 0)
10
25
  @st[:freq] = frequency
11
26
  @st[:samples] = samples
12
27
  end
13
28
 
14
- def size = @st[:size]
15
- alias chunk_size size
29
+ def big_endian? = SDL_AUDIO_MASK_ENDIAN & format != 0
16
30
 
31
+ def bitsize = SDL_AUDIO_MASK_BITSIZE & format
32
+
33
+ # チャンネル数
17
34
  def channels = @st[:channels]
18
35
 
36
+ def float? = SDL_AUDIO_MASK_DATATYPE & format != 0
37
+
38
+ # 音声フォーマット
19
39
  def format = @st[:format]
20
40
 
41
+ # サンプルレート
21
42
  def freq = @st[:freq]
22
43
  alias frequency freq
23
44
 
45
+ # 音声バッファのサンプル数。2のべき乗。
24
46
  def samples = @st[:samples]
25
47
 
48
+ def signed? = SDL_AUDIO_MASK_SIGNED & format != 0
49
+
50
+ # 音量レベル0の値。8ビットフォーマットの際に使用する(と思われる。型が Uint8 であるため)。SDL が決定する。
51
+ def silence = @st[:silence]
52
+
53
+ # 音声バッファのサイズ(Byte)。SDL が決定する。
54
+ def size = @st[:size]
55
+
26
56
  def to_ptr = @st.to_ptr
57
+
58
+ def unknown? = channels == 0 && format == 0 && frequency == 0
27
59
  end
28
60
  end
29
61
  end
@@ -0,0 +1,10 @@
1
+ module RbSDL2
2
+ class Audio
3
+ module AudioSpecReader
4
+ require 'forwardable'
5
+ extend Forwardable
6
+ def_delegators :spec,
7
+ *%i(big_endian? bitsize float? signed? channels format frequency samples)
8
+ end
9
+ end
10
+ end
@@ -1,44 +1,44 @@
1
1
  module RbSDL2
2
2
  module Clipboard
3
3
  class << self
4
- def clear = self.text = nil
4
+ # クリップボードの内容をクリアします。
5
+ def clear = ::SDL.SetClipboardText(nil)
5
6
 
6
- # イベントを pump したとき外部からのクリップボード取得が行われる。
7
- # その際に SDL_CLIPBOARDUPDATE イベントがキューに入る。これはイベントコールバックで捕獲できる。
8
- # 読み出し時にクリップボードの内容はクリアーされない。
7
+ require_relative 'sdl_pointer'
8
+
9
+ # テキストクリップボードの内容を戻します。文字エンコードは UTF-8 です。
10
+ # このメソッドを使用する前に video sub-system を初期化しておく必要があります。
11
+ # クリップボードの取得ができない場合(video sub-system が初期化されていない)場合はエラー通知します。
12
+ # 読み出し時にクリップボードの内容はクリアーされません。
13
+ # クリップボードの状態が変化したかどうか知りたい場合はイベントを監視してください。
14
+ # その場合はイベントを受け取るためウィンドウを表示します。
15
+ # 次にそのウィンドウがフォーカスされた時に SDL_CLIPBOARDUPDATE イベントを受け取ることができます。
9
16
  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
- # それをさらにコピーしたものを戻す。
17
+ # SDL_GetClipboardText() は NULL ポインターを戻さない。返すべき内容がない場合は空文字列を戻す。
18
+ # 取得できないとき(video sub-system が初期化されていない)も空文字列を戻す。
19
+ # SDL は OS から取得したクリップボードの内容を SDL 内部に保存し、それをさらにコピーしたものを戻す。
15
20
  # アプリケーション側は取得した文字列ポインタを必ず開放しなければならない。
16
- ::SDL2.SDL_free(ptr)
17
- end
18
-
19
- # クリップボードの内容を戻す。text メソッドと違い読み出し後にクリップボードの内容をクリアーする。
20
- def text!
21
- str = text
22
- clear
23
- str
21
+ ptr = SDLPointer.new(::SDL.GetClipboardText)
22
+ s = ptr.to_s
23
+ # クリップボードが空の時(OS 起動直後など)およびエラーの際も空文字列を戻す。
24
+ raise RbSDL2Error if s.empty? && !SDL.init?(:video)
25
+ s
24
26
  end
25
27
 
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
28
+ # テキストクリップボードへ書き込みます。書き込んだ内容は外部アプリケーションから取得できます。
29
+ # 書き込みを行った場合 SDL は SDL_CLIPBOARDUPDATE イベントを発生させます。
30
+ # 繰り返しクリップボード書き込みを行うとエラーを戻します。この上限は OS 側にあるため事前に知る方法はありません。
31
+ # その場合は Clipboard.clear を実行すると書き込みができるようになります。
32
+ def text=(s)
33
+ raise RbSDL2Error if ::SDL.SetClipboardText(SDL.str_to_sdl(s)) < 0
34
34
  end
35
35
 
36
- # クリップボードに内容があるか確認をする。
37
- # これはアプリケーションがクリップボードを読み出しても内容はクリアーされないため、
38
- # クリップボードの更新を知るためには実装を工夫する必要がある。
39
- # もっとも簡単な方法は、クリップボードの内容を読み込み度に Clipboard.text = nil を実行し、
40
- # クリップボードをクリアする。
41
- def text? = ::SDL2.SDL_HasClipboardText == ::SDL2::SDL_TRUE
36
+ # クリップボードに内容があるか確認します。
37
+ # 取得できないとき(video sub-system が初期化されていない)も false を戻します。
38
+ # 外部アプリケーションがクリップボードを読み出しても内容はクリアーされません。
39
+ # クリップボードのクリアを行った場合、または外部アプリケーションからテキスト以外の内容がクリップボードにセット
40
+ # された場合 false になります。
41
+ def exist? = ::SDL.HasClipboardText == ::SDL::TRUE
42
42
  end
43
43
  end
44
44
  end
@@ -1,39 +1,56 @@
1
1
  module RbSDL2
2
2
  module CPUInfo
3
3
  class << self
4
- def cpu_count = ::SDL2.SDL_GetCPUCount
4
+ # Power CPU の AltiVec 拡張命令セット
5
+ def altivec? = ::SDL.HasAltiVec == ::SDL::TRUE
5
6
 
6
- def cpu_cache_line_size = ::SDL2.SDL_GetCPUCacheLineSize
7
+ # AMD x86 CPU の 3DNow! 拡張命令セット
8
+ def amd3dnow? = ::SDL.Has3DNow == ::SDL::TRUE
7
9
 
8
- def system_ram = ::SDL2.SDL_GetSystemRAM
10
+ # Arm CPU の SIMD 命令セット
11
+ def armsimd? = ::SDL.HasARMSIMD == ::SDL::TRUE
9
12
 
10
- def rdtsc? = ::SDL2.SDL_HasRDTSC == ::SDL2::SDL_TRUE
13
+ # x86 CPU AVX 命令セット
14
+ def avx = ::SDL.HasAVX == ::SDL::TRUE
11
15
 
12
- def altivec? = ::SDL2.SDL_HasAltiVec == ::SDL2::SDL_TRUE
16
+ # x86 CPU AVX2 命令セット
17
+ def avx2 = ::SDL.HasAVX2 == ::SDL::TRUE
13
18
 
14
- def mmx? = ::SDL2.SDL_HasMMX == ::SDL2::SDL_TRUE
19
+ # x86 CPU AVX-512F 命令セット
20
+ def avx512f? = ::SDL.HasAVX512F == ::SDL::TRUE
15
21
 
16
- def _3dnow? = ::SDL2.SDL_Has3DNow == ::SDL2::SDL_TRUE
22
+ # CPU L1 キャッシュラインサイズ(Byte)
23
+ def cpu_cache_line_size = ::SDL.GetCPUCacheLineSize
17
24
 
18
- def sse? = ::SDL2.SDL_HasSSE == ::SDL2::SDL_TRUE
25
+ # 論理 CPU コアの総数
26
+ def cpu_count = ::SDL.GetCPUCount
19
27
 
20
- def sse2? = ::SDL2.SDL_HasSSE2 == ::SDL2::SDL_TRUE
28
+ # x86 CPU MMX 命令セット
29
+ def mmx? = ::SDL.HasMMX == ::SDL::TRUE
21
30
 
22
- def sse3? = ::SDL2.SDL_HasSSE3 == ::SDL2::SDL_TRUE
31
+ # Arm CPU NEON 命令セット
32
+ def neon? = ::SDL.HasNEON == ::SDL::TRUE
23
33
 
24
- def sse41? = ::SDL2.SDL_HasSSE41 == ::SDL2::SDL_TRUE
34
+ # x86 CPU RDTSC 命令
35
+ def rdtsc? = ::SDL.HasRDTSC == ::SDL::TRUE
25
36
 
26
- def sse42? = ::SDL2.SDL_HasSSE42 == ::SDL2::SDL_TRUE
37
+ # x86 CPU SSE 命令セット
38
+ def sse? = ::SDL.HasSSE == ::SDL::TRUE
27
39
 
28
- def avx? = ::SDL2.SDL_HasAVX == ::SDL2::SDL_TRUE
40
+ # x86 CPU SSE2 命令セット
41
+ def sse2 = ::SDL.HasSSE2 == ::SDL::TRUE
29
42
 
30
- def avx2? = ::SDL2.SDL_HasAVX2 == ::SDL2::SDL_TRUE
43
+ # x86 CPU SSE3 命令セット
44
+ def sse3 = ::SDL.HasSSE3 == ::SDL::TRUE
31
45
 
32
- def avx512f = ::SDL2.SDL_HasAVX512F == ::SDL2::SDL_TRUE
46
+ # x86 CPU の SSE4.1 命令セット
47
+ def sse41? = ::SDL.HasSSE41 == ::SDL::TRUE
33
48
 
34
- def armsimd? = ::SDL2.SDL_HasARMSIMD == ::SDL2::SDL_TRUE
49
+ # x86 CPU の SSE4.2 命令セット
50
+ def sse42? = ::SDL.HasSSE42 == ::SDL::TRUE
35
51
 
36
- def neon? = ::SDL2.SDL_HasNEON == ::SDL2::SDL_TRUE
52
+ # システム RAM のサイズ(MB)
53
+ def system_ram = ::SDL.GetSystemRAM
37
54
  end
38
55
  end
39
56
  end