1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     hid_PadReader.h
4 
5   Copyright (C)2009 Nintendo Co., Ltd.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Rev: 26510 $
14  *---------------------------------------------------------------------------*/
15 
16 /*! @file
17     @brief      PadReader クラスを定義します。
18 
19 */
20 #ifndef NN_HID_CTR_HID_PADREADER_H_
21 #define NN_HID_CTR_HID_PADREADER_H_
22 
23 #include <nn/Handle.h>
24 #include <nn/Result.h>
25 #include <nn/types.h>
26 #include <nn/hid/CTR/hid_Result.h>
27 #include <nn/hid/CTR/hid_Api.h>
28 #include <nn/hid/CTR/hid_pad.h>
29 #include <nn/hid/CTR/hid_DeviceStatus.h>
30 #include <nn/util/util_SizedEnum.h>
31 #include <nn/util/util_NonCopyable.h>
32 
33 namespace nn {
34 namespace hid {
35 namespace CTR {
36 /*!
37   @brief アナログスティックの円形クランプの遊びとして、適切な最小値です。
38 
39   注意 ) 検討中のパラメータのため、将来変更します。
40 */
41 const s16   MIN_OF_STICK_CLAMP_MODE_CIRCLE  = 46;
42 
43 /*!
44   @brief アナログスティックの十字形クランプの遊びとして、適切な最小値です。
45 
46   注意 ) 検討中のパラメータのため、将来変更します。
47 */
48 const s16   MIN_OF_STICK_CLAMP_MODE_CROSS   = 41;
49 
50 /*!
51   @brief アナログスティックのクランプの上限です。
52 
53   注意 ) 検討中のパラメータのため、将来変更します。
54 */
55 const s16   LIMIT_OF_STICK_CLAMP_MAX              = 145;
56 
57 /*! @brief ゲームパッド(ボタン、アナログスティック)のサンプリングデータを読み込むクラスです。
58 
59              ゲームパッドは 4 msec 周期でサンプリングされます。
60 
61 */
62 
63 class PadReader : private nn::util::NonCopyable<PadReader>
64 {
65 public:
66     /*!
67       @enum     StickClampMode
68       @brief    SetStickClampMode( )  で設定するアナログスティックのクランプ方法を示す列挙体です。
69 
70 ・STICK_CLAMP_MODE_CIRCLE ( 円形クランプ )<BR>
71   内側と外側を円形にクランプします。<BR>
72   min と  max をそれぞれ SetStickClamp( ) で設定されるクランプの下限値、上限値とした場合<BR>
73   アナログスティックの入力座標 (x, y) の原点 からの距離 d に応じ、以下のようにクランプされた座標 (x', y') を得ます。 <BR>
74     d <= min の場合、 (x', y') = (0, 0)<BR>
75     min < d < max の場合、 (x', y') =   (d - min) / d * (x, y)<BR>
76     d >= max の 場合、 (x', y') =   (max - min) / d * (x, y)<BR><BR>
77 ・STICK_CLAMP_MODE_CROSS ( 十字形クランプ )<BR>
78   内側を十字形に、外側を円形にクランプします。 <BR>
79    まず、アナログスティックの入力座標 ( x, y ) に対し x, y 個別に 以下のようにクランプします。<BR>
80     x < 0 の場合、 x' = x + min  (0 以上になりません)<BR>
81     x >= 0 の場合、 x' = x - min  (0以下になりません)<BR>
82   さらに、座標 (x', y') の 原点からの距離 d が max - min より大きい場合は以下のようにクランプされた座標 (x', y') を得ます。<BR>
83     (x', y') = (max - min) / d * (x,' y')
84 
85     */
86     typedef enum
87     {
88         /*! @brief 円形クランプです。 詳しくは、本ページの説明を参照してください。 */
89         STICK_CLAMP_MODE_CIRCLE = 0,
90         /*! @brief 十字形クランプ です。 詳しくは、本ページの説明を参照してください。*/
91         STICK_CLAMP_MODE_CROSS
92     } StickClampMode;
93 
94     /*!
95     @brief          コンストラクタです。
96 
97                     インスタンスを生成する前に @ref nn::hid::CTR::Initialize( ) で初期化してください。
98 
99     */
100     PadReader(Pad& pad=GetPad( ));
101 
102     /*!
103     @brief          デストラクタです。
104 
105     */
~PadReader()106     ~PadReader( ) {};
107 
108     /*!
109       @brief        ゲームパッドのサンプリングデータを新しいものから順に読み込みます。以前に読み込んだデータは読み込まれません。
110 
111                     アナログスティックは触れていない状態でも入力がありますので、 nn::hid::CTR::PadReader::SetStickClamp( ) で適切な遊びを設定してください。<BR>
112                     また、アナログスティックの入力座標と原点間の距離は最大値を得ることができません。これはクランプ処理の際に、丸めが発生するためです。<BR>
113                     この最大値を閾値などに使用しないでください。
114 
115       @param[out]   pBufs       新しいものから順にサンプリングデータが読み込まれます。
116       @param[out]   pReadLen    読み込んだサンプリングデータの数です。
117       @param[in]    bufLen      pBufs に読み込めるサンプリングデータの数を指定します。
118       @return       なし。
119 
120     */
121     void Read(PadStatus* pBufs, s32* pReadLen, s32 bufLen);
122 
123     /*!
124       @brief        最新のゲームパッドのサンプリングデータを読み込みます。 nn::hid::CTR::PadReader::Read( ) とちがい同じサンプリングデータを読み込むことが出来ます。
125 
126       trigger、release は前回の ReadLatest( ) の読み込み結果に対して生成されます。<BR><BR>
127                     アナログスティックは触れていない状態でも入力がありますので、 nn::hid::CTR::PadReader::SetStickClamp( ) で適切な遊びを設定してください。<BR>
128                     また、アナログスティックの入力座標と原点間の距離は最大値を得ることができません。これはクランプ処理の際に、丸めが発生するためです。<BR>
129                     この最大値を閾値などに使用しないでください。
130 
131       @param[out]   pBuf        サンプリングデータが読み込まれます。
132       @return       サンプリングデータの読み込み結果を返します。<BR>
133                       true ・・・ 読み込めました。<BR>
134                       false ・・・ 読み込めませんでした。(システム起動後あるいはスリープ復帰後の最初のサンプリングが行われ次第、読み込めます。)
135 
136     */
137     bool ReadLatest(PadStatus* pBuf);
138 
139     /*!
140       @brief        アナログスティックのクランプ値の設定を行います。
141 
142                     max値は @ref nn::hid::CTR::LIMIT_OF_STICK_CLAMP_MAX 以下の値を設定してください。<BR>
143                     min値は SetStickClampMode() で設定されるクランプ方法によって、指定可能な値が異なります。<BR>
144                     円形クランプは @ref nn::hid::CTR::MIN_OF_STICK_CLAMP_MODE_CIRCLE 以上の値が指定できます。<BR>
145                     十字形クランプは @ref nn::hid::CTR::MIN_OF_STICK_CLAMP_MODE_CROSS 以上の値が指定できます。<BR>
146                     制限値を超える値を指定した場合、制限値に補正され適用されます。<BR>
147                     max値及びmin値はクランプ方法毎に別々に管理されます。
148 
149       @param[in]    min   クランプの下限です。 デフォルト値は円形クランプの場合 @ref nn::hid::CTR::MIN_OF_STICK_CLAMP_MODE_CIRCLE 、十字クランプの場合 @ref nn::hid::CTR::MIN_OF_STICK_CLAMP_MODE_CROSS です。
150       @param[in]    max   クランプの上限です。デフォルト値は @ref nn::hid::CTR::LIMIT_OF_STICK_CLAMP_MAX です。
151       @return       なし
152 
153     */
154     void SetStickClamp(s16 min, s16 max);
155 
156     /*!
157       @brief        アナログスティックの現在のクランプ方法におけるクランプ値を取得します。
158 
159       @param[out]   pMin   クランプの下限が返されます。
160       @param[out]   pMax   クランプの上限が返されます。
161       @return       なし。
162 
163       @date         2009/11/20 const メンバ関数に変更しました。
164       @since        2009/11/01 初版
165     */
166     void GetStickClamp(s16* pMin, s16* pMax) const;
167 
168     /*!
169       @brief        アナログスティックのクランプ方法を取得します。
170 
171       @return       現在設定されているクランプ方法を返します。
172 
173       @date         2009/11/20 const メンバ関数に変更しました。
174       @since        2009/11/01 初版
175     */
176     StickClampMode GetStickClampMode( ) const;
177 
178     /*!
179       @brief        アナログスティックのクランプ方法を設定します。
180 
181                     Read( ) と ReadLatest( ) で 得られるアナログスティックの値が設定された方法でクランプされます。クランプの詳細は、@ref nn::hid::CTR::PadReader::StickClampMode を参照してください。<BR>
182                     円形クランプ がデフォルトで設定されています。
183 
184       @param[in]    mode   設定するクランプ方法です。
185       @return       なし。
186 
187     */
188     void SetStickClampMode(StickClampMode mode);
189 
190     /*!
191       @brief        Read( ) と ReadLatest( ) で得られるアナログスティック の値を、-1.0 ~ 1.0 の浮動小数点数に正規化して返します。
192 
193                      クランプの上限と下限の 差を 1.0 とします。
194 
195       @param[in]    x       アナログスティックの値
196       @return       正規化された値
197     */
198     f32 NormalizeStick(s16 x);
199 
200 protected:
201     Pad&                m_Pad;
202     s32                 m_IndexOfRead;
203     bit32               m_LatestHold;
204     s16                 m_MinOfStickClampCircle;
205     s16                 m_MinOfStickClampCross;
206     s16                 m_MaxOfStickClampCircle;
207     s16                 m_MaxOfStickClampCross;
208     bool                m_IsReadLatestFirst;
209     nn::util::SizedEnum1<StickClampMode>      m_StickClampMode;
210     NN_PADDING2;
211     s64                 m_TickOfRead;
212 
213 };
214 
215 
216 // inline 定義
GetStickClamp(s16 * pMin,s16 * pMax)217 inline void PadReader::GetStickClamp(s16* pMin, s16* pMax) const
218 {
219 	if (m_StickClampMode == STICK_CLAMP_MODE_CIRCLE)
220 	{
221  	   *pMin = m_MinOfStickClampCircle;
222        *pMax = m_MaxOfStickClampCircle;
223  	}
224  	else
225  	{
226  	   *pMin = m_MinOfStickClampCross;
227        *pMax = m_MaxOfStickClampCross;
228 	}
229 }
230 
GetStickClampMode()231 inline PadReader::StickClampMode PadReader::GetStickClampMode( ) const
232 {
233     return m_StickClampMode;
234 }
235 
SetStickClampMode(StickClampMode mode)236 inline void PadReader::SetStickClampMode(StickClampMode mode)
237 {
238     m_StickClampMode = mode;
239 }
240 
241 } // namespace CTR {
242 } // namespace hid {
243 } // namespace nn {
244 
245 #endif  // #ifndef NN_HID_CTR_HID_PADREADER_H_
246