1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     snd_AnimSound.h
4 
5   Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain proprietary
8   information of Nintendo and/or its licensed developers and are protected by
9   national and international copyright laws. They may not be disclosed to third
10   parties or copied or duplicated in any form, in whole or in part, without the
11   prior written consent of Nintendo.
12 
13   The content herein is highly confidential and should be handled accordingly.
14 
15   $Revision: $
16  *---------------------------------------------------------------------------*/
17 
18 /**
19  * :include nw/snd/snd_AnimSound.h
20  *
21  * @file snd_AnimSound.h
22  */
23 
24 #ifndef NW_SND_ANIM_SOUND_H_
25 #define NW_SND_ANIM_SOUND_H_
26 
27 #include <nn/types.h>
28 #include <nw/snd/snd_AnimSoundImpl.h>
29 #include <nw/snd/snd_AnimEventPlayer.h>
30 
31 namespace nw {
32 namespace snd {
33 
34 class SoundStartable;
35 class SoundArchive;
36 
37 //---------------------------------------------------------------------------
38 //! :private
39 //!
40 //! @brief  アニメーションサウンドを再生させるテンプレートクラスです。
41 //!
42 //!         アニメーションサウンドとは、アニメーションサウンドデータ (*.bcasd ファイル)
43 //!         を使うことで、アニメーションの再生に合わせて自動的にサウンドが再生される機能です。
44 //!
45 //!         アニメーションサウンドデータには、サウンドのラベル文字列と、
46 //!         そのサウンドを再生するフレーム位置が定義されたイベントが含まれています。
47 //!         @ref UpdateFrame を呼び出しアニメーションサウンドのフレーム位置を進めると、
48 //!         通過したフレーム位置にあるイベントのサウンドが再生されます。
49 //!
50 //!         アニメーションサウンドでは、ラベル文字列を使用してサウンドを再生します。
51 //!         そのため、アニメーションサウンドで再生するサウンドを、
52 //!         文字列で再生できる状態にしておく必要があります。
53 //!         ROM サウンドアーカイブを使用してる場合は、
54 //!         サウンドのラベル文字列変換テーブルとサウンドデータが、
55 //!         メモリ上にロードされている必要があります。
56 //!         ラベル文字列変換テーブルのロードには
57 //!         @ref RomSoundArchive::LoadLabelStringData を呼び出します。
58 //!
59 //!         テンプレート引数 EVENT_PLAYER_NUM は、
60 //!         同時に扱うことができるイベントの上限数が書きこまれます。
61 //!         イベントとは、AnimSoundMaker でアニメーションサウンドを編集する画面における
62 //!         リストの「各行」が該当します。
63 //!
64 //!         イベントの上限数以上のイベントを扱おうとした場合、
65 //!         実行中のイベントで再生しているサウンドのうち、
66 //!         一番プレイヤー優先度の低いサウンドを再生しているイベントが停止され、
67 //!         新しいイベントが実行されます。
68 //!
69 //!         通常、メモリが足りないなどの問題が無い場合は、
70 //!         @ref AnimSound クラスをご利用ください。
71 //!
72 //! @tparam EVENT_PLAYER_NUM    同時に扱うことのできるるイベントの上限数です。
73 //!
74 //! @see AnimSound クラス
75 //!
76 //! @date 2011/01/07 初版
77 //---------------------------------------------------------------------------
78 template< int EVENT_PLAYER_NUM >
79 class TAnimSound
80 {
81 public:
82     //---------------------------------------------------------------------------
83     //! @brief  再生方向を表す列挙型です。
84     //!
85     //!         @ref UpdateFrame でアニメーションサウンドを再生する際の、
86     //!         再生方向を表現します。
87     //!
88     //! @see UpdateFrame
89     //!
90     //! @date 2011/01/07 初版
91     //---------------------------------------------------------------------------
92     enum PlayDirection
93     {
94         //! 順方向への再生を表します。
95         PLAY_DIRECTION_FORWARD  = internal::AnimSoundImpl::PLAY_DIRECTION_FORWARD,
96         //! 逆方向への再生を表します。
97         PLAY_DIRECTION_BACKWARD = internal::AnimSoundImpl::PLAY_DIRECTION_BACKWARD
98     };
99 
100     //---------------------------------------------------------------------------
101     //! @brief  イベントの種類を表す列挙型です。
102     //!
103     //!         @ref EventCallback の引数で取得することができます。
104     //!
105     //!         イベントにはトリガイベントとレンジイベントの 2 種類があります。
106     //!         トリガイベントは、開始フレームを通過したときにサウンドの再生が始まり、
107     //!         終了フレームを通過したときにサウンドの再生が停止します。
108     //!         レンジイベントは、
109     //!         フレームの現在位置が開始フレームと終了フレームの間にある場合に
110     //!         サウンドを再生し続けます。
111     //!
112     //! @see EventCallback
113     //!
114     //! @date 2011/01/07 初版
115     //---------------------------------------------------------------------------
116     enum EventType
117     {
118         //! トリガイベントの開始を表します。
119         EVENT_TYPE_TRIGGER_START = internal::AnimSoundImpl::EVENT_TYPE_TRIGGER_START,
120         //! トリガイベントの終了を表します。
121         EVENT_TYPE_TRIGGER_STOP  = internal::AnimSoundImpl::EVENT_TYPE_TRIGGER_STOP,
122         //! レンジイベントの開始を表します。
123         EVENT_TYPE_RANGE_START   = internal::AnimSoundImpl::EVENT_TYPE_RANGE_START,
124         //! レンジイベントの終了を表します。
125         EVENT_TYPE_RANGE_STOP    = internal::AnimSoundImpl::EVENT_TYPE_RANGE_STOP
126     };
127 
128     //---------------------------------------------------------------------------
129     //! @brief  アニメーションサウンドのイベント発生時に呼び出されるコールバック関数の型です。
130     //!
131     //!         どのようなイベントが発生したかは type で知ることができます。
132     //!
133     //! @param[in] type     イベントの種類です。
134     //! @param[in] frame    イベントの発生したフレーム位置です。
135     //! @param[in] soundLabel   イベントで再生されるサウンドのラベル文字列です。
136     //! @param[in] userParam    イベントのユーザーパラメータです。
137     //! @param[in] arg      @ref SetEventCallback で設定されたユーザー引数です。
138     //!
139     //! @see SetEventCallback
140     //! @see EventType
141     //!
142     //! @date 2011/01/07 初版
143     //---------------------------------------------------------------------------
144     typedef void (*EventCallback)(
145         EventType type,
146         s32 frame,
147         const char* soundLabel,
148         u32 userParam,
149         void* arg );
150 
151     //----------------------------------------
152     //! @name コンストラクタ
153     //@{
154 
155     //---------------------------------------------------------------------------
156     //! @brief  コンストラクタです。
157     //!
158     //!         starter で、アニメーションサウンド内のサウンド再生に使用する
159     //!         再生インターフェイスを指定します。
160     //!         再生インターフェイスには、@ref SoundArchivePlayer または
161     //!         @ref Sound3DActor 等を指定することができます。
162     //!
163     //! @param[in] starter  サウンド再生インターフェイスです。
164     //!
165     //! @see SoundStartable クラス
166     //! @see SoundArchivePlayer クラス
167     //! @see Sound3DActor クラス
168     //!
169     //! @date 2011/01/07 初版
170     //---------------------------------------------------------------------------
TAnimSound(SoundStartable & starter)171     TAnimSound( SoundStartable& starter )
172     : m_Impl( starter, m_EventPlayers, EVENT_PLAYER_NUM )
173     {}
174     //@}
175 
176     //----------------------------------------
177     //! @name 初期化処理、終了処理
178     //@{
179 
180     //---------------------------------------------------------------------------
181     //! @brief  アニメーションサウンドを初期化します。
182     //!
183     //!         アニメーションサウンドで使用するデータ (*.bcasd ファイル) を
184     //!         bcasdFile に渡します。
185     //!
186     //!         本関数で初期化後、@ref ConvertSoundId 関数を呼ばない場合は、
187     //!         サウンドを再生するごとにラベル文字列からサウンド ID への変換が行われます。
188     //!         @ref ConvertSoundId 関数を読んでおくと、
189     //!         当該 bcasd ファイルに含まれるサウンドのラベル文字列を、
190     //!         あらかじめまとめてサウンド ID に変換しておくことができます。
191     //!
192     //! @param[in] bcasdFile    アニメーションサウンドデータです。
193     //!
194     //! @return 初期化に成功すると true、失敗すると false を返します。
195     //!
196     //! @see ConvertSoundId
197     //! @see Finalize
198     //!
199     //! @date 2011/01/07 初版
200     //---------------------------------------------------------------------------
Initialize(const void * bcasdFile)201     bool Initialize( const void* bcasdFile ) { return m_Impl.Initialize( bcasdFile ); }
202 
203     //---------------------------------------------------------------------------
204     //! @brief  アニメーションサウンドを破棄します。
205     //!
206     //!         AnimSoundMaker で「アニメ切替時再生継続」にチェックが入っていると、
207     //!         本関数が呼び出されても、該当サウンドは停止しません。
208     //!         チェックが入っていないサウンドは、本関数が呼び出されると停止します。
209     //!
210     //! @see Initialize
211     //!
212     //! @date 2011/01/07 初版
213     //---------------------------------------------------------------------------
Finalize()214     void Finalize() { m_Impl.Finalize(); }
215 
216     //---------------------------------------------------------------------------
217     //! @brief  アニメーションサウンドデータ内で使用されているサウンド文字列を、
218     //!         サウンドID に変換します。
219     //!
220     //!         @ref Initialize 後に呼び出しておくと、
221     //!         アニメーションサウンド再生時に、
222     //!         逐次サウンド文字列からサウンドID に変換する処理を省くことができます。
223     //!
224     //! @param[in] arc  当該アニメーションサウンドで鳴らすサウンドが属している
225     //!                 サウンドアーカイブです。
226     //!
227     //! @return     変換に成功すると true、失敗すると false を返します。
228     //!
229     //! @see Initialize
230     //!
231     //! @date 2011/01/07 初版
232     //---------------------------------------------------------------------------
ConvertSoundId(const SoundArchive & arc)233     bool ConvertSoundId( const SoundArchive& arc ) { return m_Impl.ConvertSoundId( arc ); }
234     //@}
235 
236     //----------------------------------------
237     //! @name フレーム処理
238     //@{
239     //---------------------------------------------------------------------------
240     //! @brief  アニメーションサウンドのフレームを進めます。
241     //!
242     //!         アニメーションサウンドの再生を、現在のフレーム位置から frame まで進めます。
243     //!         その際、通過したフレーム位置にあるサウンドが再生されます
244     //!         (frame のフレーム位置にあるサウンドを含みます)。
245     //!         現在のフレーム位置は @ref GetCurrentFrame で取得できます。
246     //!
247     //!         direction には、フレーム数が増えていく方向の再生の場合
248     //!         PLAY_DIRECTION_FORWARD を、
249     //!         減っていく方向の場合 PLAY_DIRECTION_BACKWARD を指定します。
250     //!         省略時は PLAY_DIRECTION_FORWARD です。
251     //!
252     //!         再生方向が順方向で、frame が現在位置より小さい場合は、
253     //!         アニメーションサウンドデータの終端でループして再生されます。
254     //!         アニメーションサウンドデータのフレーム数は
255     //!         @ref GetFrameSize で取得できます。
256     //!
257     //! @param[in] frame        再生を進めるフレーム位置です。
258     //! @param[in] direction    再生方向です。
259     //!
260     //! @see PlayDirection
261     //! @see GetCurrentFrame
262     //! @see GetFrameSize
263     //! @see SetBaseStep
264     //!
265     //! @date 2011/01/07 初版
266     //---------------------------------------------------------------------------
267     void UpdateFrame( f32 frame, PlayDirection direction = PLAY_DIRECTION_FORWARD )
268     {
269         m_Impl.UpdateFrame(
270                 frame, static_cast<internal::AnimSoundImpl::PlayDirection>( direction ) );
271     }
272     //---------------------------------------------------------------------------
273     //! @brief  アニメーションサウンドの現在のフレーム位置を設定します。
274     //!
275     //!         この関数による現在位置の更新では、サウンドは再生されません。
276     //!         frame のフレーム位置にあるサウンドは、
277     //!         次に @ref UpdateFrame が呼び出された際に再生されます。
278     //!
279     //! @param[in] frame    設定するフレーム位置です。
280     //!
281     //! @see UpdateFrame
282     //!
283     //! @date 2011/01/07 初版
284     //---------------------------------------------------------------------------
ResetFrame(f32 frame)285     void ResetFrame( f32 frame ) { m_Impl.ResetFrame( frame, 0 ); }
286 
287     //---------------------------------------------------------------------------
288     //! @brief  アニメーションサウンドの通常のフレーム更新間隔を設定します。
289     //!
290     //!         デフォルト値として、あらかじめ 1.0f が設定されています。
291     //!
292     //!         アニメーションサウンドの再生速度を決めるための、
293     //!         通常のフレーム更新間隔を設定します。
294     //!         @ref UpdateFrame 関数で、 1.0f ずつ大きな値を設定する場合は、
295     //!         1.0f を設定します。
296     //!         アプリケーション実行中に FPS を変更した場合などで、
297     //!         2.0f ずつ大きな値を設定する場合は、2.0f を設定します。
298     //!
299     //!         ここで設定する値は、AnimSound インスタンス内で保持される
300     //!         「再生速度」の算出に用いられます。
301     //!         たとえば、下記のような場合は、
302     //!         再生速度は「(4.0f - 2.0f) ÷ 1.0f = 2.0f」と算出されます。
303     //!
304     //!         ・【通常のフレーム更新間隔 (本関数で設定)】を 1.0f @n
305     //!         ・【前回の UpdateFrame 関数で設定されたフレーム位置】を 2.0f @n
306     //!         ・【今回の UpdateFrame 関数で設定されたフレーム位置】を 4.0f
307     //!
308     //!         フレーム位置を 4.0f → 2.0f のように逆方向に設定すると、
309     //!         再生速度は負値を取ります。
310     //!
311     //!         ここで算出された「再生速度」を 100 倍し、
312     //!         かつ、-32768~32767 の範囲でクランプした値が、
313     //!         AnimSoundMaker の「再生速度反映変数」で設定したシーケンス変数に反映されます。
314     //!         反映タイミングは、該当サウンドが再生されるときです。
315     //!
316     //!         また、「再生速度反映変数」がグローバル変数の場合、
317     //!         該当サウンドがシーケンスサウンドでなくても値が反映されます。
318     //!         「再生速度反映変数」がローカル変数の場合は、
319     //!         該当サウンドがシーケンスサウンドでないと値は反映されません。
320     //!
321     //! @param[in] baseStep     通常のフレーム更新間隔です。
322     //! @see UpdateFrame
323     //!
324     //! @date 2011/01/07 初版
325     //---------------------------------------------------------------------------
326     void SetBaseStep( f32 baseStep = 1.0f ) { m_Impl.SetBaseStep( baseStep ); }
327     //@}
328 
329     //----------------------------------------
330     //! @name 情報取得
331     //@{
332     //---------------------------------------------------------------------------
333     //! @brief  アニメーションサウンドが使用可能な状態かどうかを取得します。
334     //!
335     //!         アニメーションサウンドは、
336     //!         @ref Initialize が true を返してから、@ref Finalize を呼び出すまで、
337     //!         使用可能です。
338     //!
339     //! @return 使用可能な場合 true、不可能な場合 false を返します。
340     //!
341     //! @see Initialize
342     //! @see Finalize
343     //!
344     //! @date 2011/01/07 初版
345     //---------------------------------------------------------------------------
IsAvailable()346     bool IsAvailable() const { return m_Impl.IsAvailable(); }
347 
348     //---------------------------------------------------------------------------
349     //! @brief  アニメーションサウンドデータのフレーム数を取得します。
350     //!
351     //!         アニメーションサウンドが使用可能でない場合は、 0 を返します。
352     //!
353     //! @return アニメーションサウンドデータのフレーム数を返します。
354     //!
355     //! @see IsAvailable
356     //!
357     //! @date 2011/01/07 初版
358     //---------------------------------------------------------------------------
GetFrameSize()359     u32 GetFrameSize() const { return m_Impl.GetFrameSize(); }
360 
361     //---------------------------------------------------------------------------
362     //! @brief  現在のフレーム位置を取得します。
363     //!
364     //!         アニメーションサウンドが使用可能でない場合は、 0.0f を返します。
365     //!
366     //! @return 現在のフレーム位置を返します。
367     //!
368     //! @see IsAvailable
369     //!
370     //! @date 2011/01/07 初版
371     //---------------------------------------------------------------------------
GetCurrentFrame()372     f32 GetCurrentFrame() const { return m_Impl.GetCurrentFrame(); }
373     //@}
374 
375     //---------------------------------------------------------------------------
376     //! @brief  アニメーションサウンドで再生中のすべてのイベントの発音を停止します。
377     //!
378     //! @date 2011/01/07 初版
379     //---------------------------------------------------------------------------
StopAllSound()380     void StopAllSound() { m_Impl.StopAllSound(); }
381 
382     //---------------------------------------------------------------------------
383     //! @brief  アニメーションサウンドにイベントコールバックを設定します。
384     //!
385     //!         イベントコールバックは、フレームがイベントを通過し、
386     //!         イベントの処理が発生したときに呼び出されます。
387     //!
388     //! @param[in] callback イベントコールバックです。
389     //! @param[in] arg      イベントコールバックに渡されるユーザー引数です。
390     //!
391     //! @see EventCallback
392     //!
393     //! @date 2011/01/07 初版
394     //---------------------------------------------------------------------------
SetEventCallback(EventCallback callback,void * arg)395     void SetEventCallback( EventCallback callback, void* arg )
396     {
397         m_Impl.SetEventCallback( callback, arg );
398     }
399 
400     //! @details :private
detail_GetLoopCount()401     int detail_GetLoopCount() const { return m_Impl.GetLoopCount(); }
402 
403 private:
404     internal::AnimSoundImpl m_Impl;
405     internal::AnimEventPlayer m_EventPlayers[ EVENT_PLAYER_NUM ];
406 };
407 
408 //---------------------------------------------------------------------------
409 //! :private
410 //!
411 //! @brief  アニメーションサウンドを再生させるクラスです。
412 //!
413 //!         詳しくは @ref TAnimSound クラスの説明をご参照ください。
414 //!
415 //!         メモリが足りないなどの問題がない場合は、@ref TAnimSound クラスではなく、
416 //!         本クラスをご利用ください。
417 //!
418 //! @see TAnimSound クラス
419 //!
420 //! @date 2011/01/07 初版
421 //---------------------------------------------------------------------------
422 typedef TAnimSound<8> AnimSound;
423 
424 } // namespace nw::snd
425 } // namespace nw
426 
427 
428 #endif /* NW_SND_ANIM_SOUND_H_ */
429 
430