/*---------------------------------------------------------------------------* Project: Horizon File: hid_PadReader.h Copyright (C)2009 Nintendo Co., Ltd. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Rev: 30621 $ *---------------------------------------------------------------------------*/ /*! @file @brief PadReader クラスを定義します。 */ #ifndef NN_HID_CTR_HID_PADREADER_H_ #define NN_HID_CTR_HID_PADREADER_H_ #include #include #include #include #include #include #include #include #include namespace nn { namespace hid { namespace CTR { const f32 DEFAULT_SCALE_OF_NORMALIZE_STICK = 1.5f; const s16 DEFAULT_THRESHOLD_OF_NORMALIZE_STICK = 141; /*! @brief アナログスティックの円形クランプの遊びとして、適切な最小値です。 */ const s16 MIN_OF_STICK_CLAMP_MODE_CIRCLE = 40; /*! @brief アナログスティックの十字形クランプの遊びとして、適切な最小値です。 */ const s16 MIN_OF_STICK_CLAMP_MODE_CROSS = 36; /*! @brief アナログスティックのクランプの上限です。 */ const s16 LIMIT_OF_STICK_CLAMP_MAX = 145; /*! @brief ゲームパッド(ボタン、アナログスティック)のサンプリングデータを読み込むクラスです。 ゲームパッドは 4 msec 周期でサンプリングされます。 */ class PadReader : private nn::util::NonCopyable { public: /*! @enum StickClampMode @brief SetStickClampMode( ) で設定するアナログスティックのクランプ方法を示す列挙体です。 ・STICK_CLAMP_MODE_CIRCLE ( 円形クランプ )
内側と外側を円形にクランプします。
min と max をそれぞれ SetStickClamp( ) で設定されるクランプの下限値、上限値とした場合
アナログスティックの入力座標 (x, y) の原点 からの距離 d に応じ、以下のようにクランプされた座標 (x', y') を得ます。
d <= min の場合、 (x', y') = (0, 0)
min < d < max の場合、 (x', y') = (d - min) / d * (x, y)
d >= max の 場合、 (x', y') = (max - min) / d * (x, y)

・STICK_CLAMP_MODE_CROSS ( 十字形クランプ )
内側を十字形に、外側を円形にクランプします。
まず、アナログスティックの入力座標 ( x, y ) に対し x, y 個別に 以下のようにクランプします。
x < 0 の場合、 x' = x + min (0 以上になりません)
x >= 0 の場合、 x' = x - min (0以下になりません)
さらに、座標 (x', y') の 原点からの距離 d が max - min より大きい場合は以下のようにクランプされた座標 (x', y') を得ます。
(x', y') = (max - min) / d * (x,' y')

・STICK_CLAMP_MODE_MINIMUM ( 最小クランプ )
内側クランプ領域を最小とするモードです。 内側に関して円形クランプと十字クランプを下限値に設定したときの より小さい方のエリアでのクランプを行います。 形状としては円形の上下左右の一部を直線で切り取ったような形になります。
外側は円形クランプとなり、SetStickClamp( ) で設定されるmax値が反映されます。
*/ typedef enum { /*! @brief 円形クランプです。 詳しくは、本ページの説明を参照してください。 */ STICK_CLAMP_MODE_CIRCLE = 0, /*! @brief 十字形クランプ です。 詳しくは、本ページの説明を参照してください。*/ STICK_CLAMP_MODE_CROSS, /*! @brief 最小クランプ です。 詳しくは、本ページの説明を参照してください。*/ STICK_CLAMP_MODE_MINIMUM } StickClampMode; /*! @brief コンストラクタです。 インスタンスを生成する前に @ref nn::hid::CTR::Initialize( ) で初期化してください。 */ PadReader(Pad& pad=GetPad( )); /*! @brief デストラクタです。 */ ~PadReader( ) {}; /*! @brief ゲームパッドのサンプリングデータを新しいものから順に読み込みます。以前に読み込んだデータは読み込まれません。 アナログスティックは触れていない状態でも入力がありますので、 nn::hid::CTR::PadReader::SetStickClamp( ) で適切な遊びを設定してください。
また、アナログスティックの入力座標と原点間の距離は最大値を得ることができません。これはクランプ処理の際に、丸めが発生するためです。
この最大値を閾値などに使用しないでください。 @param[out] pBufs 新しいものから順にサンプリングデータが読み込まれます。 @param[out] pReadLen 読み込んだサンプリングデータの数です。 @param[in] bufLen pBufs に読み込めるサンプリングデータの数を指定します。 @return なし。 */ void Read(PadStatus* pBufs, s32* pReadLen, s32 bufLen); /*! @brief 最新のゲームパッドのサンプリングデータを読み込みます。 nn::hid::CTR::PadReader::Read( ) とちがい同じサンプリングデータを読み込むことが出来ます。 trigger、release は前回の ReadLatest( ) の読み込み結果に対して生成されます。

アナログスティックは触れていない状態でも入力がありますので、 nn::hid::CTR::PadReader::SetStickClamp( ) で適切な遊びを設定してください。
また、アナログスティックの入力座標と原点間の距離は最大値を得ることができません。これはクランプ処理の際に、丸めが発生するためです。
この最大値を閾値などに使用しないでください。 @param[out] pBuf サンプリングデータが読み込まれます。 @return サンプリングデータの読み込み結果を返します。
true ・・・ 読み込めました。
false ・・・ 読み込めませんでした。(システム起動後あるいはスリープ復帰後の最初のサンプリングが行われ次第、読み込めます。) */ bool ReadLatest(PadStatus* pBuf); /*! @brief アナログスティックのクランプ値の設定を行います。 max値は @ref nn::hid::CTR::LIMIT_OF_STICK_CLAMP_MAX 以下の値を設定してください。
min値は SetStickClampMode() で設定されるクランプ方法によって、指定可能な値が異なります。
円形クランプは @ref nn::hid::CTR::MIN_OF_STICK_CLAMP_MODE_CIRCLE 以上の値が指定できます。
十字形クランプは @ref nn::hid::CTR::MIN_OF_STICK_CLAMP_MODE_CROSS 以上の値が指定できます。
最小クランプ時の min値は @ref nn::hid::CTR::MIN_OF_STICK_CLAMP_MODE_CIRCLE 固定となり設定値は無視されます。
制限値を超える値を指定した場合、制限値に補正され適用されます。
max値及びmin値はクランプ方法毎に別々に管理されます。 @param[in] min クランプの下限です。 デフォルト値は円形クランプの場合 @ref nn::hid::CTR::MIN_OF_STICK_CLAMP_MODE_CIRCLE 、十字クランプの場合 @ref nn::hid::CTR::MIN_OF_STICK_CLAMP_MODE_CROSS です。 @param[in] max クランプの上限です。デフォルト値は @ref nn::hid::CTR::LIMIT_OF_STICK_CLAMP_MAX です。 @return なし */ void SetStickClamp(s16 min, s16 max); /*! @brief アナログスティックの現在のクランプ方法におけるクランプ値を取得します。 @param[out] pMin クランプの下限が返されます。 @param[out] pMax クランプの上限が返されます。 @return なし。 @date 2009/11/20 const メンバ関数に変更しました。 @since 2009/11/01 初版 */ void GetStickClamp(s16* pMin, s16* pMax) const; /*! @brief アナログスティックのクランプ方法を取得します。 @return 現在設定されているクランプ方法を返します。 @date 2009/11/20 const メンバ関数に変更しました。 @since 2009/11/01 初版 */ StickClampMode GetStickClampMode( ) const; /*! @brief アナログスティックのクランプ方法を設定します。 Read( ) と ReadLatest( ) で 得られるアナログスティックの値が設定された方法でクランプされます。クランプの詳細は、@ref nn::hid::CTR::PadReader::StickClampMode を参照してください。
円形クランプ がデフォルトで設定されています。 @param[in] mode 設定するクランプ方法です。 @return なし。 */ void SetStickClampMode(StickClampMode mode); /*! @brief Read( ) と ReadLatest( ) で得られるアナログスティック の値を、-1.0 ~ 1.0 の浮動小数点数に正規化して返します。 クランプの上限と下限の 差を 1.0 とします。 @param[in] x アナログスティックの値 @return 正規化された値 */ f32 NormalizeStick(s16 x); /*! @brief Read( ) と ReadLatest( ) で得られるアナログスティック の値を、-1.0 ~ 1.0 の浮動小数点数に正規化して返します。感度調整機能付きです。 内部では感度を調整するための特殊な処理が行われます。 詳細については SetNormalizeStickScaleSettings( ) の説明を参照してください。 @param[out] normalized_x 正規化後x @param[out] normalized_y 正規化後y @param[in] x 正規化前x @param[in] y 正規化前y @return なし */ void NormalizeStickWithScale( f32* normalized_x, f32* normalized_y, s16 x, s16 y ); /*! @brief NormalizeStickWithScale( ) の設定を行います。 スライドパッドの可動範囲がscale倍あるかのように振る舞います。
スライドパッドの値がthresholdに満たない場合 NormalizeStickWithScale( )
で得られる正規化値は 1/scale になります。
スライドパッドの値がthreshold以上である場合 NormalizeStickWithScale( )
で得られる正規化値は徐々に ±1.0 に近づきます。
thresholdには @ref nn::hid::CTR::LIMIT_OF_STICK_CLAMP_MAX 以下の値を設定してください。 @param[in] scale 感度調整パラメータ(デフォルトは1.5) @param[in] threshold 内部処理閾値 (デフォルトは141) @return なし */ void SetNormalizeStickScaleSettings( f32 scale, s16 threshold ); /*! @brief NormalizeStickWithScale( ) の設定を取得します。 @param[in] scale 感度調整パラメータが返されます。 @param[in] threshold 内部処理閾値が返されます。 @return なし */ void GetNormalizeStickScaleSettings( f32* scale, s16* threshold ) const; protected: Pad& m_Pad; s32 m_IndexOfRead; bit32 m_LatestHold; s16 m_MinOfStickClampCircle; s16 m_MinOfStickClampCross; s16 m_MinOfStickClampMinimum; s16 m_MaxOfStickClampCircle; s16 m_MaxOfStickClampCross; s16 m_MaxOfStickClampMinimum; bool m_IsReadLatestFirst; nn::util::SizedEnum1 m_StickClampMode; s16 m_Threshold; f32 m_Scale; f32 m_Stroke; f32 m_StrokeVelocity; f32 m_LastLength; f32 m_LastDiff; s64 m_TickOfRead; }; // inline 定義 inline void PadReader::GetStickClamp(s16* pMin, s16* pMax) const { if (m_StickClampMode == STICK_CLAMP_MODE_CIRCLE) { *pMin = m_MinOfStickClampCircle; *pMax = m_MaxOfStickClampCircle; } else if (m_StickClampMode == STICK_CLAMP_MODE_CROSS) { *pMin = m_MinOfStickClampCross; *pMax = m_MaxOfStickClampCross; } else { *pMin = m_MinOfStickClampMinimum; *pMax = m_MaxOfStickClampMinimum; } } inline PadReader::StickClampMode PadReader::GetStickClampMode( ) const { return m_StickClampMode; } inline void PadReader::SetStickClampMode(StickClampMode mode) { m_StickClampMode = mode; } } // namespace CTR { } // namespace hid { } // namespace nn { #endif // #ifndef NN_HID_CTR_HID_PADREADER_H_