コントローラの入力
SDLでコントローラの入力を取得するには、下記の関数を使用します。
SDL_NumJoysticks関数
接続したジョイスティックの数を取得します。
宣言
int SDL_NumJoysticks();
戻り値
「接続したジョイスティックの数」を返します。
SDL_IsGameController関数
ジョイスティックがゲームコントローラのインターフェースに対応しているか判別する値を取得します。
宣言
SDL_bool SDL_IsGameController( int joystick_index );
引数
joystick_index | ジョイスティックの番号です。 ※ この番号は 0 から順に数えます。 |
戻り値
「 ゲームコントローラのインターフェースに対応しているか判別する値 」を返します。
SDL_GameControllerOpen関数
ゲームコントローラを有効にします。
宣言
SDL_GameController* SDL_GameControllerOpen( int joystick_index );
引数
joystick_index | ジョイスティックの番号です。 |
戻り値
有効化に成功すると「ゲームコントローラのアドレス」を返し、失敗すると「NULL
」を返します。
SDL_GameControllerClose関数
ゲームコントローラを無効にします。
宣言
void SDL_GameControllerClose( SDL_GameController* gamecontroller );
引数
gamecontroller | ゲームコントローラのアドレスです。 |
SDL_GameControllerGetButton関数
ゲームコントローラのボタンの状態を取得します。
宣言
Uint8 SDL_GameControllerGetButton(
SDL_GameController* gamecontroller,
SDL_GameControllerButton button
);
引数
gamecontroller | ゲームコントローラのアドレスです。 |
button | ボタンの種類です。 |
戻り値
ボタンを押していると「1
」を返し、押していないと「0
」を返します。
SDL_GameControllerGetAxis関数
ゲームコントローラの軸の状態を取得します。
宣言
Sint16 SDL_GameControllerGetAxis(
SDL_GameController* gamecontroller,
SDL_GameControllerAxis axis
);
引数
gamecontroller | ゲームコントローラのアドレスです。 |
axis | 軸の種類です。 |
戻り値
軸の状態を表す数値を返します。この値は、-32768
から32767
までの数になります。
サンプルプログラム
#include <SDL.h>
SDL_Window* g_window = nullptr;
SDL_GameController* g_controller = nullptr;
bool Initialize();
bool Update();
void Finalize();
void OnAddedController( int index );
void OnRemovedController();
void OutputControllerState();
void OutputIfButtonStateIsPushing( SDL_GameControllerButton type, const char name[] );
void OutputIfAxisStateIsTilting( SDL_GameControllerAxis type, const char name[] );
int main( int argc, char* argv[] )
{
if ( !Initialize() )
{
Finalize();
return -1;
}
while ( true )
{
if ( !Update() ) break;
}
Finalize();
return 0;
}
bool Initialize()
{
if ( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER ) )
{
SDL_Log( u8"SDLの初期化処理に失敗しました。エラーメッセージ: %s", SDL_GetError() );
return false;
}
g_window = SDL_CreateWindow(
u8"サンプル",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
1280,
720,
0
);
if ( g_window == nullptr )
{
SDL_Log( u8"ウィンドウの作成に失敗しました。エラーメッセージ: %s", SDL_GetError() );
return false;
}
for ( auto i = 0, joystick_count = SDL_NumJoysticks(); i < joystick_count; i++ )
{
if ( !SDL_IsGameController( i ) ) continue;
g_controller = SDL_GameControllerOpen( i );
if ( g_controller != nullptr ) break;
SDL_Log( u8"コントローラを開くのに失敗しました。エラーメッセージ: %s", SDL_GetError() );
return false;
}
return true;
}
bool Update()
{
auto is_continuing = true;
auto event_info = SDL_Event();
while ( SDL_PollEvent( &event_info ) == 1 )
{
switch ( event_info.type )
{
case SDL_QUIT:
is_continuing = false;
break;
case SDL_CONTROLLERDEVICEADDED:
OnAddedController( event_info.cdevice.which );
if ( g_controller == nullptr ) is_continuing = false;
break;
case SDL_CONTROLLERDEVICEREMOVED:
OnRemovedController();
break;
}
}
OutputControllerState();
SDL_Delay( 33 );
return is_continuing;
}
void Finalize()
{
if ( g_controller != nullptr ) SDL_GameControllerClose( g_controller );
if ( g_window != nullptr ) SDL_DestroyWindow( g_window );
SDL_Quit();
}
void OnAddedController( int index )
{
if ( g_controller != nullptr ) return;
g_controller = SDL_GameControllerOpen( index );
if ( g_controller != nullptr ) return;
SDL_Log( u8"コントローラを開くのに失敗しました。エラーメッセージ: %s", SDL_GetError() );
}
void OnRemovedController()
{
if ( g_controller == nullptr ) return;
SDL_GameControllerClose( g_controller );
g_controller = nullptr;
}
void OutputControllerState()
{
if ( g_controller == nullptr ) return;
OutputIfButtonStateIsPushing( SDL_CONTROLLER_BUTTON_A , u8"A" );
OutputIfButtonStateIsPushing( SDL_CONTROLLER_BUTTON_B , u8"B" );
OutputIfButtonStateIsPushing( SDL_CONTROLLER_BUTTON_X , u8"X" );
OutputIfButtonStateIsPushing( SDL_CONTROLLER_BUTTON_Y , u8"Y" );
OutputIfButtonStateIsPushing( SDL_CONTROLLER_BUTTON_BACK , u8"バック" );
OutputIfButtonStateIsPushing( SDL_CONTROLLER_BUTTON_START , u8"スタート" );
OutputIfButtonStateIsPushing( SDL_CONTROLLER_BUTTON_LEFTSTICK , u8"左スティック" );
OutputIfButtonStateIsPushing( SDL_CONTROLLER_BUTTON_RIGHTSTICK , u8"右スティック" );
OutputIfButtonStateIsPushing( SDL_CONTROLLER_BUTTON_LEFTSHOULDER , u8"左ショルダー" );
OutputIfButtonStateIsPushing( SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, u8"右ショルダー" );
OutputIfButtonStateIsPushing( SDL_CONTROLLER_BUTTON_DPAD_UP , u8"上" );
OutputIfButtonStateIsPushing( SDL_CONTROLLER_BUTTON_DPAD_DOWN , u8"下" );
OutputIfButtonStateIsPushing( SDL_CONTROLLER_BUTTON_DPAD_LEFT , u8"左" );
OutputIfButtonStateIsPushing( SDL_CONTROLLER_BUTTON_DPAD_RIGHT , u8"右" );
OutputIfAxisStateIsTilting( SDL_CONTROLLER_AXIS_LEFTX , u8"左スティックのX軸" );
OutputIfAxisStateIsTilting( SDL_CONTROLLER_AXIS_LEFTY , u8"左スティックのY軸" );
OutputIfAxisStateIsTilting( SDL_CONTROLLER_AXIS_RIGHTX , u8"右スティックのX軸" );
OutputIfAxisStateIsTilting( SDL_CONTROLLER_AXIS_RIGHTY , u8"右スティックのY軸" );
OutputIfAxisStateIsTilting( SDL_CONTROLLER_AXIS_TRIGGERLEFT , u8"左トリガー" );
OutputIfAxisStateIsTilting( SDL_CONTROLLER_AXIS_TRIGGERRIGHT, u8"右トリガー" );
}
void OutputIfButtonStateIsPushing( SDL_GameControllerButton type, const char name[] )
{
if ( SDL_GameControllerGetButton( g_controller, type ) == 0 ) return;
SDL_Log( u8"%sボタンを押しています。", name );
}
void OutputIfAxisStateIsTilting( SDL_GameControllerAxis type, const char name[] )
{
auto value = SDL_GameControllerGetAxis( g_controller, type );
auto threshold = 10000;
if ( SDL_abs( value ) < threshold ) return;
SDL_Log( u8"%sの値は%dです。", name, value );
}