ruby-miyako 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) hide show
  1. data/README +1115 -0
  2. data/Rakefile +7 -0
  3. data/defines.h +144 -0
  4. data/extconf.rb +44 -0
  5. data/extern.h +29 -0
  6. data/img/cursor.png +0 -0
  7. data/img/cursors.png +0 -0
  8. data/img/dice.png +0 -0
  9. data/img/wait_cursor.png +0 -0
  10. data/img/win_base.png +0 -0
  11. data/img/window.png +0 -0
  12. data/install_miyako.rb +87 -0
  13. data/lib/Miyako/API/audio.rb +584 -0
  14. data/lib/Miyako/API/basic_data.rb +1026 -0
  15. data/lib/Miyako/API/bitmap.rb +534 -0
  16. data/lib/Miyako/API/choices.rb +481 -0
  17. data/lib/Miyako/API/collision.rb +638 -0
  18. data/lib/Miyako/API/diagram.rb +586 -0
  19. data/lib/Miyako/API/drawing.rb +151 -0
  20. data/lib/Miyako/API/exceptions.rb +105 -0
  21. data/lib/Miyako/API/fixedmap.rb +462 -0
  22. data/lib/Miyako/API/font.rb +430 -0
  23. data/lib/Miyako/API/input.rb +456 -0
  24. data/lib/Miyako/API/layout.rb +644 -0
  25. data/lib/Miyako/API/map.rb +583 -0
  26. data/lib/Miyako/API/map_event.rb +222 -0
  27. data/lib/Miyako/API/modules.rb +357 -0
  28. data/lib/Miyako/API/movie.rb +166 -0
  29. data/lib/Miyako/API/parts.rb +188 -0
  30. data/lib/Miyako/API/plane.rb +205 -0
  31. data/lib/Miyako/API/screen.rb +341 -0
  32. data/lib/Miyako/API/shape.rb +443 -0
  33. data/lib/Miyako/API/sprite.rb +773 -0
  34. data/lib/Miyako/API/sprite_animation.rb +494 -0
  35. data/lib/Miyako/API/sprite_list.rb +1135 -0
  36. data/lib/Miyako/API/spriteunit.rb +168 -0
  37. data/lib/Miyako/API/story.rb +350 -0
  38. data/lib/Miyako/API/textbox.rb +773 -0
  39. data/lib/Miyako/API/utility.rb +419 -0
  40. data/lib/Miyako/API/viewport.rb +190 -0
  41. data/lib/Miyako/API/yuki.rb +1180 -0
  42. data/lib/Miyako/EXT/miyako_cairo.rb +62 -0
  43. data/lib/Miyako/EXT/raster_scroll.rb +138 -0
  44. data/lib/Miyako/EXT/slides.rb +157 -0
  45. data/lib/Miyako/miyako.rb +201 -0
  46. data/lib/Miyako/miyako_require_only.rb +35 -0
  47. data/logo/EGSR_logo.png +0 -0
  48. data/logo/EGSR_logo_bg.png +0 -0
  49. data/logo/EGSR_logo_fg.png +0 -0
  50. data/logo/EGSR_title_banner.png +0 -0
  51. data/logo/EGSR_title_logo.png +0 -0
  52. data/logo/miyako.png +0 -0
  53. data/logo/miyako_banner.png +0 -0
  54. data/logo/space.png +0 -0
  55. data/miyako_basicdata.c +484 -0
  56. data/miyako_bitmap.c +1225 -0
  57. data/miyako_collision.c +403 -0
  58. data/miyako_drawing.c +187 -0
  59. data/miyako_font.c +334 -0
  60. data/miyako_hsv.c +830 -0
  61. data/miyako_input_audio.c +254 -0
  62. data/miyako_layout.c +191 -0
  63. data/miyako_no_katana.c +1086 -0
  64. data/miyako_sprite2.c +431 -0
  65. data/miyako_transform.c +438 -0
  66. data/miyako_utility.c +288 -0
  67. data/sample/Animation1/m1ku.rb +68 -0
  68. data/sample/Animation1/m1ku_arm_0.png +0 -0
  69. data/sample/Animation1/m1ku_arm_1.png +0 -0
  70. data/sample/Animation1/m1ku_arm_2.png +0 -0
  71. data/sample/Animation1/m1ku_arm_3.png +0 -0
  72. data/sample/Animation1/m1ku_back.jpg +0 -0
  73. data/sample/Animation1/m1ku_body.png +0 -0
  74. data/sample/Animation1/m1ku_eye_0.png +0 -0
  75. data/sample/Animation1/m1ku_eye_1.png +0 -0
  76. data/sample/Animation1/m1ku_eye_2.png +0 -0
  77. data/sample/Animation1/m1ku_eye_3.png +0 -0
  78. data/sample/Animation1/m1ku_hair_front.png +0 -0
  79. data/sample/Animation1/m1ku_hair_rear.png +0 -0
  80. data/sample/Animation1/readme.txt +72 -0
  81. data/sample/Animation2/lex.rb +96 -0
  82. data/sample/Animation2/lex_back.png +0 -0
  83. data/sample/Animation2/lex_body.png +0 -0
  84. data/sample/Animation2/lex_roadroller.png +0 -0
  85. data/sample/Animation2/lex_wheel_0.png +0 -0
  86. data/sample/Animation2/lex_wheel_1.png +0 -0
  87. data/sample/Animation2/lex_wheel_2.png +0 -0
  88. data/sample/Animation2/readme.txt +72 -0
  89. data/sample/Animation2/song_title.png +0 -0
  90. data/sample/Diagram_sample/back.png +0 -0
  91. data/sample/Diagram_sample/chr01.png +0 -0
  92. data/sample/Diagram_sample/chr02.png +0 -0
  93. data/sample/Diagram_sample/cursor.png +0 -0
  94. data/sample/Diagram_sample/diagram_sample_yuki2.rb +329 -0
  95. data/sample/Diagram_sample/readme.txt +90 -0
  96. data/sample/Diagram_sample/wait_cursor.png +0 -0
  97. data/sample/Room3/blue.rb +297 -0
  98. data/sample/Room3/ending.rb +180 -0
  99. data/sample/Room3/green.rb +220 -0
  100. data/sample/Room3/image/akamatsu.png +0 -0
  101. data/sample/Room3/image/aoyama.png +0 -0
  102. data/sample/Room3/image/congra.png +0 -0
  103. data/sample/Room3/image/congratulation.png +0 -0
  104. data/sample/Room3/image/congratulation_bg.png +0 -0
  105. data/sample/Room3/image/cursor.png +0 -0
  106. data/sample/Room3/image/midori.png +0 -0
  107. data/sample/Room3/image/mittsu_no_oheya.png +0 -0
  108. data/sample/Room3/image/mittsu_no_oheya_logo.png +0 -0
  109. data/sample/Room3/image/room_blue.png +0 -0
  110. data/sample/Room3/image/room_green.png +0 -0
  111. data/sample/Room3/image/room_red.png +0 -0
  112. data/sample/Room3/image/start.png +0 -0
  113. data/sample/Room3/image/three_doors.png +0 -0
  114. data/sample/Room3/image/wait_cursor.png +0 -0
  115. data/sample/Room3/main.rb +120 -0
  116. data/sample/Room3/main_component.rb +59 -0
  117. data/sample/Room3/readme.txt +76 -0
  118. data/sample/Room3/red.rb +227 -0
  119. data/sample/Room3/room3.rb +25 -0
  120. data/sample/Room3/title.rb +184 -0
  121. data/sample/ball_action_sample.rb +204 -0
  122. data/sample/blit_rop.rb +70 -0
  123. data/sample/cairo_sample.rb +25 -0
  124. data/sample/circle_collision_test.rb +66 -0
  125. data/sample/collision_test.rb +33 -0
  126. data/sample/collision_test2.rb +108 -0
  127. data/sample/fixed_map_test/cursor.png +0 -0
  128. data/sample/fixed_map_test/fixed_map_sample.rb +140 -0
  129. data/sample/fixed_map_test/map.csv +19 -0
  130. data/sample/fixed_map_test/map_01.png +0 -0
  131. data/sample/fixed_map_test/mapchip.csv +23 -0
  132. data/sample/fixed_map_test/monster.png +0 -0
  133. data/sample/fixed_map_test/readme.txt +72 -0
  134. data/sample/map_test/chara.rb +58 -0
  135. data/sample/map_test/chr1.png +0 -0
  136. data/sample/map_test/cursor.png +0 -0
  137. data/sample/map_test/main_parts.rb +69 -0
  138. data/sample/map_test/main_scene.rb +153 -0
  139. data/sample/map_test/map.png +0 -0
  140. data/sample/map_test/map2.png +0 -0
  141. data/sample/map_test/map_layer.csv +127 -0
  142. data/sample/map_test/map_manager.rb +75 -0
  143. data/sample/map_test/map_test.rb +23 -0
  144. data/sample/map_test/mapchip.csv +21 -0
  145. data/sample/map_test/oasis.rb +71 -0
  146. data/sample/map_test/readme.txt +89 -0
  147. data/sample/map_test/route.rb +157 -0
  148. data/sample/map_test/sea.png +0 -0
  149. data/sample/map_test/town.rb +74 -0
  150. data/sample/map_test/wait_cursor.png +0 -0
  151. data/sample/map_test/window.png +0 -0
  152. data/sample/polygon_test.rb +35 -0
  153. data/sample/rasterscroll.rb +25 -0
  154. data/sample/takahashi.rb +42 -0
  155. data/sample/text.png +0 -0
  156. data/sample/textbox_sample.rb +192 -0
  157. data/sample/transform.rb +54 -0
  158. data/sample/utility_test.rb +73 -0
  159. data/sample/utility_test2.rb +61 -0
  160. data/sample/utility_test3.rb +64 -0
  161. data/sample/utility_test4.rb +73 -0
  162. data/uninstall_miyako.rb +19 -0
  163. data/win/miyako_no_katana.so +0 -0
  164. metadata +216 -0
@@ -0,0 +1,584 @@
1
+ # -*- encoding: utf-8 -*-
2
+ =begin
3
+ --
4
+ Miyako v2.1
5
+ Copyright (C) 2007-2009 Cyross Makoto
6
+
7
+ This library is free software; you can redistribute it and/or
8
+ modify it under the terms of the GNU Lesser General Public
9
+ License as published by the Free Software Foundation; either
10
+ version 2.1 of the License, or (at your option) any later version.
11
+
12
+ This library is distributed in the hope that it will be useful,
13
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
+ Lesser General Public License for more details.
16
+
17
+ You should have received a copy of the GNU Lesser General Public
18
+ License along with this library; if not, write to the Free Software
19
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
+ ++
21
+ =end
22
+
23
+ module Miyako
24
+ #==オーディオ管理モジュール
25
+ #オーディオにはBGM,SE(効果音)の2種類あり、扱えるメソッドが少々違う(別クラスになっている)。
26
+ module Audio
27
+ @@initialized = false
28
+
29
+ #===音声関連の初期化処理
30
+ #既に初期化済みの時はMiyakoErrorが発生する
31
+ #_buf_size_:: Audioモジュールで使用するバッファサイズ。単位はバイト。省略時は4096
32
+ #_seq_:: Audioモジュールで使用する音声の再生サンプリング周波数。省略時は44100(44.1kHz)
33
+ def Audio.init(buf_size = 4096, seq = 44100)
34
+ raise MiyakoError, "Already initialized!" if @@initialized
35
+ SDL::Mixer.open(seq, SDL::Mixer::DEFAULT_FORMAT, 2, buf_size) unless $not_use_audio
36
+ @@initialized = true
37
+ end
38
+
39
+ #===音声関係の初期化がされた?
40
+ def Audio.initialized?
41
+ @@initialized
42
+ end
43
+
44
+ #===BGM・効果音の再生情報を更新する
45
+ def Audio.update
46
+ return if $not_use_audio
47
+ Audio::BGM.update
48
+ Audio::SE.update
49
+ end
50
+
51
+ #==BGM管理クラス
52
+ #再生できるBGMは1曲だけ。2つ以上のBGMの同時演奏は不可
53
+ class BGM
54
+ @@playing_bgm = nil
55
+
56
+ #===BGMの再生情報を更新する
57
+ def BGM.update
58
+ return if $not_use_audio
59
+ return unless @@playing_bgm
60
+ if !@@playing_bgm.playing_without_loop? && @@playing_bgm.in_the_loop?
61
+ @@playing_bgm.loop_count_up
62
+ @@playing_bgm = nil if !@@playing_bgm.in_the_loop?
63
+ elsif !@@playing_bgm.playing? && !@@playing_bgm.fade_out?
64
+ @@playing_bgm = nil
65
+ elsif !@@playing_bgm.allow_loop_count_up?
66
+ @@playing_bgm.allow_loop_count_up
67
+ end
68
+ end
69
+
70
+ #===現在の繰り返し回数を取得する
71
+ #繰り返し回数を限定して演奏しているとき、何回目の演奏家を示す。
72
+ #無限に繰り返しているときは常に-1を返す
73
+ #返却値:: ループ回数
74
+ def loop_count
75
+ @loop_cnt
76
+ end
77
+
78
+ #===現在、繰り返し演奏中かどうかを問い合わせる
79
+ #現在、繰り返し回数が指定の回数の範囲内かどうかをtrue・falseで返す。
80
+ #無限に繰り返しているときは常にtrue
81
+ #返却値:: 現在繰り返し演奏中のときはtrue
82
+ def in_the_loop?
83
+ @now_loops == -1 ? true : @loop_cnt <= @now_loops
84
+ end
85
+
86
+ def loop_count_up #:nodoc:
87
+ @loop_cnt = @loop_cnt + 1 if (@now_loops != -1 && @cnt_up_flag)
88
+ @cnt_up_flag = false
89
+ end
90
+
91
+ def allow_loop_count_up #:nodoc:
92
+ @cnt_up_flag = true
93
+ end
94
+
95
+ def allow_loop_count_up? #:nodoc:
96
+ @cnt_up_flag
97
+ end
98
+
99
+ #===インスタンスを生成する
100
+ #_fname_:: 演奏するBGMファイル名。対応ファイルはwav,mp3,ogg,mid等。
101
+ #_loops_:: 演奏の繰り返し回数を指定する。-1を渡すと無限に繰り返す。省略時は-1を渡す。
102
+ #返却値:: 生成したインスタンス
103
+ def initialize(fname, loops = -1)
104
+ return if $not_use_audio
105
+ raise MiyakoValueError.over_range(loops, -1, nil) unless loops >= -1
106
+ raise MiyakoIOError.no_file(fname) unless File.exist?(fname)
107
+ @bgm = SDL::Mixer::Music.load(fname)
108
+ @loops = loops
109
+ @now_loops = loops
110
+ @loop_cnt = 1
111
+ @cnt_up_flag = false
112
+ end
113
+
114
+ #===インスタンスの複写
115
+ #複写すると不都合が多いため、MiyakoCopyException例外が発生する
116
+ def initialize_copy(obj)
117
+ raise MiyakoCopyError.not_copy("BGM")
118
+ end
119
+
120
+ #===音の大きさを設定する
121
+ #_v_:: 音の大きさ。0〜255までの整数。255で最大。
122
+ #返却値:: 自分自身を返す
123
+ def set_volume(v)
124
+ return self if $not_use_audio
125
+ raise MiyakoValueError.over_range(v, 0, 255) unless (0..255).cover?(v)
126
+ SDL::Mixer.set_volume_music(v)
127
+ return self
128
+ end
129
+
130
+ alias_method(:setVolume, :set_volume)
131
+
132
+ #===BGMを演奏する。ブロックが渡されている場合、ブロックの評価中のみ演奏する。
133
+ #音の大きさ・繰り返し回数・演奏時間を指定可能
134
+ #_vol_:: 音の大きさ(省略可能)。0〜255の整数を設定する。nilを渡したときは音の大きさを変更しない。
135
+ #_loops_:: 演奏の繰り返し回数を指定する。-1のときは無限に繰り返す。nilを渡すと元の設定を使う。省略時はnilを渡す。
136
+ #返却値:: 演奏に成功したときはtrue、失敗した問いはfalseを返す
137
+ def start(vol = nil, loops = nil)
138
+ if vol
139
+ raise MiyakoValueError.over_range(vol, 0, 255) unless (0..255).cover?(vol)
140
+ end
141
+ if loops
142
+ raise MiyakoValueError.over_range(loops, -1, nil) unless loops >= -1
143
+ end
144
+ return self.play(vol, loops)
145
+ end
146
+
147
+ #===BGMを演奏する。ブロックが渡されている場合、ブロックの評価中のみ演奏する。
148
+ #音の大きさ・繰り返し回数を指定可能
149
+ #_vol_:: 音の大きさ(省略可能)。0〜255の整数を設定する。nilを渡したときは音の大きさを変更しない。
150
+ #_loops_:: 演奏の繰り返し回数を指定する。-1のときは無限に繰り返す。nilを渡すと元の設定を使う。省略時はnilを渡す。
151
+ #返却値:: 演奏に成功したときはtrue、失敗した問いはfalseを返す
152
+ def play(vol = nil, loops = nil)
153
+ return false if $not_use_audio
154
+ return false if @@playing_bgm && @@playing_bgm != self
155
+ if vol
156
+ raise MiyakoValueError.over_range(vol, 0, 255) unless (0..255).cover?(vol)
157
+ set_volume(vol)
158
+ end
159
+ if loops
160
+ raise MiyakoValueError.over_range(loops, -1, nil) unless loops >= -1
161
+ end
162
+ @now_loops = loops ? loops : @loops
163
+ SDL::Mixer.play_music(@bgm, @now_loops)
164
+ @loop_cnt = 1
165
+ if block_given?
166
+ yield self
167
+ SDL::Mixer.halt_music
168
+ end
169
+ @@playing_bgm = self
170
+ return true
171
+ end
172
+
173
+ #===フェードインしながら演奏する
174
+ #_msec_:: フェードインの時間。ミリ秒単位。デフォルトは5000ミリ秒(5秒)
175
+ #_vol_:: 音の大きさ(省略可能)。0〜255の整数を設定する。nilを渡したときは音の大きさを変更しない。
176
+ #_loops_:: 演奏の繰り返し回数を指定する。-1のときは無限に繰り返す。nilを渡すと元の設定を使う。省略時はnilを渡す。
177
+ #返却値:: 演奏に成功したときはtrue、失敗した問いはfalseを返す
178
+ def fade_in(msec=5000, vol = nil, loops = nil)
179
+ return false if $not_use_audio
180
+ return false if @@playing_bgm && @@playing_bgm != self
181
+ raise MiyakoValueError.over_range(msec, 1, nil) unless msec > 0
182
+ if vol
183
+ raise MiyakoValueError.over_range(vol, 0, 255) unless (0..255).cover?(vol)
184
+ set_volume(vol)
185
+ end
186
+ if loops
187
+ raise MiyakoValueError.over_range(loops, -1, nil) unless loops >= -1
188
+ end
189
+ @now_loops = loops ? loops : @loops
190
+ SDL::Mixer.fade_in_music(@bgm, @now_loops)
191
+ @@playing_bgm = self
192
+ @loop_cnt = 1
193
+ return true
194
+ end
195
+
196
+ alias_method(:fadeIn, :fade_in)
197
+
198
+ #===演奏中を示すフラグ
199
+ #返却値:: 演奏中はtrue、停止(一時停止)中はfalseを返す
200
+ def playing?
201
+ return false if $not_use_audio
202
+ return (SDL::Mixer.play_music? && self.in_the_loop?) || self.fade_out?
203
+ end
204
+
205
+ def playing_without_loop? #:nodoc:
206
+ return false if $not_use_audio
207
+ return SDL::Mixer.play_music?
208
+ end
209
+
210
+ #===演奏停止中を示すフラグ
211
+ #返却値:: 演奏停止中はtrue、演奏中はfalseを返す
212
+ def pausing?
213
+ return false if $not_use_audio
214
+ return SDL::Mixer.pause_music?
215
+ end
216
+
217
+ #===演奏を一時停止する
218
+ #resumeメソッドで一時停止を解除する
219
+ #返却値:: 自分自身を返す
220
+ def pause
221
+ return self if $not_use_audio
222
+ SDL::Mixer.pause_music if SDL::Mixer.play_music?
223
+ return self
224
+ end
225
+
226
+ #==フェードイン中を示すフラグ
227
+ #返却値:: フェードイン中はtrue、そのほかの時はfalseを返す
228
+ def fade_in?
229
+ return false if $not_use_audio
230
+ # return SDL::Mixer.fading_music == SDL::Mixer::FADING_IN
231
+ # なぜかSDL::Mixer::FADING_INが見つからないため、即値で
232
+ # from SDL_Mixer.h
233
+ return SDL::Mixer.fading_music == 2
234
+ end
235
+
236
+ #==フェードアウト中を示すフラグ
237
+ #返却値:: フェードアウト中はtrue、そのほかの時はfalseを返す
238
+ def fade_out?
239
+ return false if $not_use_audio
240
+ # return SDL::Mixer.fading_music == SDL::Mixer::FADING_OUT
241
+ # なぜかSDL::Mixer::FADING_OUTが見つからないため、即値で
242
+ # from SDL_Mixer.h
243
+ return SDL::Mixer.fading_music == 1
244
+ end
245
+
246
+ #===一時停止を解除する
247
+ #返却値:: 自分自身を返す
248
+ def resume
249
+ return self if $not_use_audio
250
+ SDL::Mixer.resume_music if SDL::Mixer.pause_music?
251
+ return self
252
+ end
253
+
254
+ #===演奏を停止する
255
+ #pauseメソッドとは違い、完全に停止するため、resumeメソッドは使えない
256
+ #返却値:: 自分自身を返す
257
+ def stop
258
+ return self if $not_use_audio
259
+ SDL::Mixer.halt_music if SDL::Mixer.play_music?
260
+ @loop_cnt = @now_loops + 1
261
+ @@playing_bgm = nil if @@playing_bgm == self
262
+ return self
263
+ end
264
+
265
+ #===演奏をフェードアウトする
266
+ #_msec_:: フェードアウトする時間。ミリ秒単位。デフォルトは5000ミリ秒
267
+ #_wmode_:: フェードアウトする間、処理を停止するかどうかを示すフラグ。デフォルトはfalse(すぐに次の処理を開始)
268
+ #返却値:: 自分自身を返す
269
+ def fade_out(msec = 5000, wmode = false)
270
+ return self if $not_use_audio
271
+ raise MiyakoValueError.over_range(msec, 1, nil) unless msec > 0
272
+ if SDL::Mixer.play_music?
273
+ SDL::Mixer.fade_out_music(msec)
274
+ SDL::delay(msec) if wmode
275
+ end
276
+ return self
277
+ end
278
+
279
+ #===演奏情報を解放する
280
+ #レシーバをdup/deep_dupなどのメソッドで複製したことがある場合、
281
+ #内部データを共有しているため、呼び出すときには注意すること
282
+ def dispose
283
+ @@playing_bgm = nil if @@playing_bgm == self
284
+ @bgm.destroy
285
+ @bgm = nil
286
+ end
287
+
288
+ alias_method(:fadeOut, :fade_out)
289
+ end
290
+
291
+ #==効果音管理クラス
292
+ class SE
293
+ @@channels = 8
294
+ @@playings = []
295
+
296
+ SDL::Mixer.allocate_channels(@@channels)
297
+
298
+ attr_accessor :priority
299
+
300
+ #===効果音の再生情報を更新する
301
+ def SE.update
302
+ return if $not_use_audio
303
+ @@playings.each{|playing|
304
+ if !playing.playing_without_loop? && playing.in_the_loop?
305
+ playing.loop_count_up
306
+ @@playings.delete(playing) if !playing.in_the_loop?
307
+ elsif !playing.playing? && !playing.fade_out?
308
+ @@playings.delete(playing)
309
+ elsif !playing.allow_loop_count_up?
310
+ playing.allow_loop_count_up
311
+ end
312
+ }
313
+ end
314
+
315
+ #===何かしらの効果音が再生中かどうかを確認する
316
+ #返却値:: 何かしらの効果音が再生中ならtrue、それ以外はfalse
317
+ def SE.playing_any?
318
+ !@@playings.empty?
319
+ end
320
+
321
+ #===同時発音数を取得する
322
+ #返却値:: 同時再生数
323
+ def SE.channels=(channels)
324
+ @@channels
325
+ end
326
+
327
+ #===現在再生している効果音をすべて停止する
328
+ #_msec_:: 停止する時間をミリ秒で指定(msecミリ秒後に停止)。nilを渡すとすぐに停止する。省略時はnilを渡す。
329
+ def SE.stop(msec = nil)
330
+ if msec
331
+ raise MiyakoValueError.over_range(msec, 1, nil) unless msec > 0
332
+ end
333
+ msec ? SDL::Mixer.expire(-1, msec) : SDL::Mixer.halt(-1)
334
+ @@playings.clear
335
+ end
336
+
337
+ #===同時発音数を変更する
338
+ #設定変更は効果音が鳴っていないときに有効。
339
+ #鳴っているときに変更しようとするとfalseが返ってくる。
340
+ #デフォルトの同時発音数は8。
341
+ #_channels_:: 変更するチャネル数。0以下を指定するとエラー
342
+ #返却値:: 変更に成功したときはtrue、失敗したときはfalseを返す
343
+ def SE.channels=(channels)
344
+ return false if $not_use_audio
345
+ return false if SE.playing_any?
346
+ raise MiyakoValueError, "Illegal Channels! : #{channels}" if channels <= 0
347
+ SDL::Mixer.allocate_channels(channels)
348
+ @@channels = channels
349
+ return true
350
+ end
351
+
352
+ #===現在の繰り返し回数を取得する
353
+ #繰り返し回数を限定して演奏しているとき、何回目の演奏家を示す。
354
+ #無限に繰り返しているときは常に-1を返す
355
+ #返却値:: ループ回数
356
+ def loop_count
357
+ @loop_cnt
358
+ end
359
+
360
+ #===現在、繰り返し演奏中かどうかを問い合わせる
361
+ #現在、繰り返し回数が指定の回数の範囲内かどうかをtrue・falseで返す。
362
+ #無限に繰り返しているときは常にtrue
363
+ #返却値:: 現在繰り返し演奏中のときはtrue
364
+ def in_the_loop?
365
+ @now_loops == -1 ? true : @loop_cnt <= @now_loops
366
+ end
367
+
368
+ def loop_count_up #:nodoc:
369
+ @loop_cnt = @loop_cnt + 1 if (@now_loops != -1 && @cnt_up_flag)
370
+ @cnt_up_flag = false
371
+ end
372
+
373
+ def allow_loop_count_up #:nodoc:
374
+ @cnt_up_flag = true
375
+ end
376
+
377
+ def allow_loop_count_up? #:nodoc:
378
+ @cnt_up_flag
379
+ end
380
+
381
+ #===インスタンスを生成する
382
+ #_fname_:: 効果音ファイル名。wavファイルのみ対応
383
+ #_vol_:: 音の大きさ(省略可能)。0〜255の整数を設定する。nilを渡したときは音の大きさを変更しない。
384
+ #_vol_:: 再生優先度(省略可能)。整数を設定する。省略したときは0を渡す。
385
+ #返却値:: 生成したインスタンス
386
+ def initialize(fname, vol = nil, priority = 0)
387
+ return nil if $not_use_audio
388
+ raise MiyakoIOError.no_file(fname) unless File.exist?(fname)
389
+ @wave = SDL::Mixer::Wave.load(fname)
390
+ if vol
391
+ raise MiyakoValueError.over_range(vol, 0, 255) unless (0..255).cover?(vol)
392
+ @wave.set_volume(vol)
393
+ end
394
+ @channel = -1
395
+ @loops = -1
396
+ @now_loops = @loops
397
+ @loop_cnt = 1
398
+ @cnt_up_flag = false
399
+ @priority = priority
400
+ end
401
+
402
+ #===インスタンスの複写
403
+ #複写すると不都合が多いため、MiyakoCopyException例外が発生する
404
+ def initialize_copy(obj)
405
+ raise MiyakoCopyError.not_copy("SE")
406
+ end
407
+
408
+ #===効果音を鳴らす
409
+ #音の大きさ・繰り返し回数・演奏時間を指定可能
410
+ #_vol_:: 音の大きさ(省略可能)。0〜255の整数を設定する。nilを渡したときは音の大きさを変更しない。
411
+ #_loops_:: 演奏の繰り返し回数を指定する。-1のときは無限に繰り返す。省略時は1を渡す。
412
+ #_time_:: 演奏時間。ミリ秒を整数で指定する。省略時は最後まで演奏する。
413
+ #返却値:: 再生に成功したときはtrue、失敗したときはfalseを返す
414
+ def start(vol = nil, loops = 1, time = nil)
415
+ if vol
416
+ raise MiyakoValueError.over_range(vol, 0, 255) unless (0..255).cover?(vol)
417
+ end
418
+ if time
419
+ raise MiyakoValueError.over_range(time, 1, nil) unless msec > 1
420
+ end
421
+ raise MiyakoValueError.over_range(loops, -1, nil) unless loops >= -1
422
+ return self.play(vol, loops, time)
423
+ end
424
+
425
+ #===効果音を鳴らす
426
+ #音の大きさ・繰り返し回数・演奏時間を指定可能
427
+ #鳴らすとき、同時再生数を超えるときは鳴らさずにfalseを返す
428
+ #ただし、自分自身が鳴っているときは、前に鳴っていた音を止めて再び鳴らす
429
+ #_vol_:: 音の大きさ(省略可能)。0〜255の整数を設定する。nilを渡したときは音の大きさを変更しない。
430
+ #_loops_:: 演奏の繰り返し回数を指定する。-1のときは無限に繰り返す。省略時は1を渡す。
431
+ #_time_:: 演奏時間。ミリ秒を整数で指定する。省略時は最後まで演奏する。
432
+ #返却値:: 再生に成功したときはtrue、失敗したときはfalseを返す
433
+ def play(vol = nil, loops = 1, time = nil)
434
+ return false if $not_use_audio
435
+ if (@@playings.length == @@channels && !@@playings.include?(self))
436
+ sorted = @@playings.sort{|a,b| a.priority <=> b.priority}
437
+ sorted[0].stop
438
+ elsif @@playings.include?(self)
439
+ self.stop
440
+ end
441
+ if vol
442
+ raise MiyakoValueError.over_range(vol, 0, 255) unless (0..255).cover?(vol)
443
+ set_volume(vol)
444
+ end
445
+ if time
446
+ raise MiyakoValueError.over_range(time, 1, nil) unless time > 0
447
+ end
448
+ raise MiyakoValueError.over_range(loops, -1, nil) unless loops >= -1
449
+ @now_loops = loops ? loops : @loops
450
+ @loop_cnt = 1
451
+ lp = @now_loops == -1 ? -1 : @now_loops - 1
452
+ @channel = time ? SDL::Mixer.play_channel_timed(-1, @wave, lp, time) : SDL::Mixer.play_channel(-1, @wave, lp)
453
+ @@playings << self
454
+ if block_given?
455
+ yield self
456
+ SDL::Mixer.halt(@channel)
457
+ end
458
+ SE.update
459
+ return true
460
+ end
461
+
462
+ #===効果音が鳴っているかを示すフラグ
463
+ #返却値:: 効果音が鳴っているときはtrue、鳴っていないときはfalseを返す
464
+ def playing?
465
+ return false if $not_use_audio
466
+ return @channel != -1 ? (SDL::Mixer.play?(@channel) && self.in_the_loop?) || self.fade_out? : false
467
+ end
468
+
469
+ def playing_without_loop? #:nodoc:
470
+ return false if $not_use_audio
471
+ return @channel != -1 ? SDL::Mixer.play?(@channel) : false
472
+ end
473
+
474
+ #===効果音を停止する
475
+ #_msec_:: 停止する時間をミリ秒で指定(msecミリ秒後に停止)。nilを渡すとすぐに停止する。省略時はnilを渡す。
476
+ #返却値:: 自分自身を返す
477
+ def stop(msec = nil)
478
+ return self if $not_use_audio
479
+ return self if !@@playings.include?(self)
480
+ if msec
481
+ raise MiyakoValueError.over_range(msec, 1, nil) unless msec > 0
482
+ end
483
+ return self if @channel == -1
484
+ return self unless SDL::Mixer.play?(@channel)
485
+ msec ? SDL::Mixer.expire(@channel, msec) : SDL::Mixer.halt(@channel)
486
+ @loop_cnt = @now_loops + 1
487
+ @@playings.delete(self)
488
+ @channe = -1
489
+ return self
490
+ end
491
+
492
+ #===フェードインしながら演奏する
493
+ #_msec_:: フェードインの時間。ミリ秒単位。デフォルトは5000ミリ秒(5秒)
494
+ #_loops_:: 演奏の繰り返し回数を指定する。-1のときは無限に繰り返す。省略時は1を渡す。
495
+ #_vol_:: 音の大きさ(省略可能)。0〜255の整数を設定する。nilを渡したときは音の大きさを変更しない。
496
+ #_time_:: 演奏時間。ミリ秒を整数で指定する。省略時は最後まで演奏する。
497
+ #返却値:: 演奏に成功したときはtrue、失敗した問いはfalseを返す
498
+ def fade_in(msec=5000, loops = 1, vol = nil, time = nil)
499
+ return false if $not_use_audio
500
+ if (@@playings.length == @@channels && !@@playings.include?(self))
501
+ sorted = @@playings.sort{|a,b| a.priority <=> b.priority}
502
+ sorted[0].stop
503
+ elsif @@playings.include?(self)
504
+ self.stop
505
+ end
506
+ if vol
507
+ raise MiyakoValueError.over_range(vol, 0, 255) unless (0..255).cover?(vol)
508
+ set_volume(vol)
509
+ end
510
+ if time
511
+ raise MiyakoValueError.over_range(time, 1, nil) unless time > 0
512
+ end
513
+ raise MiyakoValueError.over_range(loops, -1, nil) unless loops >= -1
514
+ @now_loops = loops ? loops : @loops
515
+ @loop_cnt = 1
516
+ lp = @now_loops == -1 ? -1 : @now_loops - 1
517
+ @channel = time ? SDL::Mixer.fade_in_channel_timed(-1, @wave, lp, msec, time) : SDL::Mixer.fade_in_channel(-1, @wave, lp, msec)
518
+ @@playings << self
519
+ SE.update
520
+ return true
521
+ end
522
+
523
+ #===演奏をフェードアウトする
524
+ #_msec_:: フェードアウトする時間。ミリ秒単位。デフォルトは5000ミリ秒
525
+ #_wmode_:: フェードアウトする間、処理を停止するかどうかを示すフラグ。デフォルトはfalse(すぐに次の処理を開始)
526
+ #返却値:: 自分自身を返す
527
+ def fade_out(msec = 5000, wmode = false)
528
+ return self if $not_use_audio
529
+ return self if !@@playings.include?(self)
530
+ if msec
531
+ raise MiyakoValueError.over_range(msec, 1, nil) unless msec > 0
532
+ end
533
+ if self.playing?
534
+ SDL::Mixer.fade_out(@channel, msec)
535
+ SDL::delay(msec) if wmode
536
+ end
537
+ return self
538
+ end
539
+
540
+ #==フェードイン中を示すフラグ
541
+ #返却値:: フェードイン中はtrue、そのほかの時はfalseを返す
542
+ def fade_in?
543
+ return false if $not_use_audio
544
+ return false if @channel == -1
545
+ # なぜかSDL::Mixer::FADING_INが見つからないため、即値で
546
+ # from SDL_Mixer.h
547
+ # return SDL::Mixer.fading(@channel) == SDL::Mixer::FADING_IN
548
+ return SDL::Mixer.fading(@channel) == 2
549
+ end
550
+
551
+ #==フェードアウト中を示すフラグ
552
+ #返却値:: フェードアウト中はtrue、そのほかの時はfalseを返す
553
+ def fade_out?
554
+ return false if $not_use_audio
555
+ return false if @channel == -1
556
+ # なぜかSDL::Mixer::FADING_INが見つからないため、即値で
557
+ # from SDL_Mixer.h
558
+ # return SDL::Mixer.fading(@channel) == SDL::Mixer::FADING_OUT
559
+ return SDL::Mixer.fading(@channel) == 1
560
+ end
561
+
562
+
563
+ #===効果音の大きさを設定する
564
+ #_v_:: 音の大きさ。0から255までの整数で示す。
565
+ #返却値:: 自分自身を返す
566
+ def set_volume(v)
567
+ return self if $not_use_audio
568
+ raise MiyakoValueError.over_range(v, 0, 255) unless (0..255).cover?(v)
569
+ @wave.set_volume(v)
570
+ return self
571
+ end
572
+
573
+ #===演奏情報を解放する
574
+ #レシーバをdup/deep_dupなどのメソッドで複製したことがある場合、
575
+ #内部データを共有しているため、呼び出すときには注意すること
576
+ def dispose
577
+ @wave.destroy
578
+ @wave = nil
579
+ end
580
+
581
+ alias_method(:setVolume, :set_volume)
582
+ end
583
+ end
584
+ end