C++でゲームコントローラーを実装するとき、「WinMM・XInput・SDL3のどれを使えばいいの?」と迷っていませんか?それぞれ対応機種も機能も全く違うため、プロジェクトに合ったAPIを選ばないと後で大変なことになります。この記事では、3つのAPIを徹底比較し、あなたのプロジェクトに最適な選択肢を提示します。
各APIの特徴
WinMM(Windows Multimedia API)
WinMMは、Windows標準の古いAPIで、DirectInput以前から存在します。Xboxコントローラーも一応動きますが、ボタンマッピングが不安定で、振動機能も使えません。レガシーコードの保守以外で選ぶ理由はほぼないです。
- ✅ Windows標準搭載(追加ライブラリ不要)
- ✅ 古い環境でも動作
- ❌ 振動機能なし
- ❌ ボタンマッピングが機種ごとにバラバラ
- ❌ Xbox以外のコントローラーで動作が不安定
XInput
XInputは、MicrosoftがXbox 360時代に作ったAPIで、Xbox系コントローラー専用設計です。ボタン配置が完全に統一されていて、振動・トリガー値・バッテリー情報など必要な機能は全部揃っています。実装もシンプルで、Windows + Xboxなら最適解です。
詳しい使い方は【C++】XInputでゲームコントローラー入力を取得する方法で解説しています。
- ✅ Xbox系コントローラーで完璧に動作
- ✅ 導入が簡単(ヘッダとlibだけ)
- ✅ DLL配布不要
- ✅ 振動・トリガー・バッテリー情報対応
- ❌ PlayStation/Switchは非対応
- ❌ Windows専用(Mac/Linux不可)
SDL3(Simple DirectMedia Layer 3)
SDL3は、クロスプラットフォームのゲーム開発ライブラリです。コントローラー対応が非常に広く、Xbox/PlayStation/Nintendo Switch/汎用コントローラー全部対応しています。LED・ジャイロ・タッチパッドなど最新機能にも対応していますが、ライブラリの導入とDLLの配布が必要です。
実装方法は【C++】SDL3だけでコントローラー全機種対応する方法で詳しく解説しています。
- ✅ Xbox/PS4/PS5/Switch/汎用コントローラー全対応
- ✅ Windows/Mac/Linuxで動作
- ✅ 振動・LED・ジャイロ・タッチパッド対応
- ✅ オープンソース(zlibライセンス)
- ❌ ライブラリ導入が必要
- ❌ DLL配布が必要
【重要】私が実際にAPI選択で困った体験談
体験談1:WinMMで実装したらまさかのプロコン非対応
以前、Windows向けの簡単なゲームを作ったときの話です。
当時は深く考えず、昔からある入力APIという理由だけで
WinMM(Windows Multimedia API)を使ってコントローラー対応を実装していました。
手元の環境では問題なく動作していたのですが、
いざNintendo SwitchのProコントローラー(いわゆるプロコン)を接続してみると……
まったく反応しない。
設定の問題かと思って色々試しましたが改善せず、
最終的に「そもそも相性や取得情報の問題がある」ことが判明。
結局どうしたかというと……
急遽、3COINSでUSBコントローラーを買う羽目になりました。
完全に想定外の出費です。
この経験で、「古いAPIを安易に選ぶと痛い目を見る」ことを強く実感しました。
体験談2:XInputで作ったゲームを配ったら大事故
次にやらかしたのが XInput です。
「今度は公式APIだから大丈夫だろう」と思い、
XInput を使ってコントローラー入力を実装したゲームを作りました。
自分のXboxコントローラーでは当然正常動作。
問題ないと判断して友人に配布したところ……
しばらくして返ってきた感想がこちら。
「コントローラー動かないんだけど?」
話を聞いてみると、
友人が使っていたのは PlayStation コントローラー。
ここで初めて、
XInput は基本的に Xbox 系コントローラー専用
という仕様を痛感しました。
開発者側からすると常識でも、
ユーザー環境ではまったく通用しません。
この時点で設計ミス確定です。
API選択時のよくあるエラーと対処法
エラー1: 「このコントローラーは対応していません」と言われる
原因: XInputを使っているが、PlayStation/Switchコントローラーを接続している
対処法: SDL3に移行するか、XInputとSDL3を併用する実装に切り替えてください。
エラー2: 振動機能が全く動かない
原因: WinMMを使っている(振動API自体が存在しない)
対処法: XInputまたはSDL3に移行してください。WinMMには振動機能がありません。
エラー3: Mac/Linuxでビルドエラーが出る
原因: WinMMやXInputはWindows専用API
対処法: クロスプラットフォーム対応したい場合は、最初からSDL3で実装してください。
3つのAPIを徹底比較
| 項目 | WinMM | XInput | SDL3 |
|---|---|---|---|
| 導入の手軽さ | ◎ | ◎ | △ |
| Xbox対応 | △ | ◎ | ◎ |
| PS4/PS5対応 | × | × | ◎ |
| Switch対応 | × | × | ◎ |
| 振動機能 | × | ◎ | ◎ |
| LED/ジャイロ | × | × | ◎ |
| クロスプラットフォーム | × | × | ◎ |
| DLL配布 | 不要 | 不要 | 必要 |
| 推奨度 | × | ○ | ◎ |
どのAPIを選ぶべき?判断基準
| 条件 | 推奨API | 理由 |
|---|---|---|
| Windows + Xbox限定 | XInput | 導入簡単、DLL不要、完璧な動作 |
| 複数コントローラー対応 | SDL3 | Xbox/PS/Switch全対応 |
| Mac/Linux対応 | SDL3 | クロスプラットフォーム対応 |
| レガシー保守 | WinMM | 既存コードが動いているなら |
| Steamで配信予定 | SDL3 | ユーザーの40%がXbox以外 |
私の結論
WinMMは選ばない
正直、2026年の今からWinMMを選ぶメリットはありません。XInputより機能が少なく、安定性も劣ります。「既存コードがWinMMで書かれている」以外の理由で採用する場面が思いつきません。
XInputの立ち位置
Windows + Xbox限定なら最強です。導入が簡単(ヘッダとlibだけ)、DLL配布不要、ドキュメントも豊富。学校の課題やWindows専用ゲームならこれで十分です。
基本的な実装方法はDebugビルドとReleaseビルドの違いを理解した上で進めると、開発がスムーズです。
SDL3を選ぶ基準
「将来的にPS/Switch対応したいかも」「Mac/Linux対応したいかも」と少しでも思うならSDL3にしておく方が後悔しません。XInputからSDL3への移行は結構面倒なので、最初から全機種対応を見据えた設計にしておくべきです。
実装例の比較
それぞれのAPIで「Aボタンが押されたら振動する」処理を実装してみます。
▼ XInputの実装例
#include <windows.h>
#include <xinput.h>
#pragma comment(lib, "xinput.lib")
int main() {
XINPUT_STATE state;
while (true) {
if (XInputGetState(0, &state) == ERROR_SUCCESS) {
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_A) {
XINPUT_VIBRATION vib = {0};
vib.wLeftMotorSpeed = 32767;
vib.wRightMotorSpeed = 32767;
XInputSetState(0, &vib);
}
}
}
return 0;
}実行結果:
Xbox Oneコントローラーで動作確認
Aボタン押下 → 振動開始
PlayStation 5コントローラー → 認識されず
▼ SDL3の実装例
#include <SDL3/SDL.h>
#pragma comment(lib, "SDL3.lib")
int main() {
SDL_Init(SDL_INIT_GAMEPAD);
int count;
SDL_JoystickID* ids = SDL_GetGamepads(&count);
SDL_Gamepad* gp = SDL_OpenGamepad(ids[0]);
while (true) {
SDL_Event e;
SDL_PollEvent(&e);
if (SDL_GetGamepadButton(gp, SDL_GAMEPAD_BUTTON_SOUTH)) {
SDL_RumbleGamepad(gp, 32767, 32767, 500);
}
}
SDL_CloseGamepad(gp);
SDL_Quit();
return 0;
}実行結果:
Xbox Oneコントローラー → 動作OK
PlayStation 5コントローラー → 動作OK
Nintendo Switch Proコントローラー → 動作OK
汎用Logicoolコントローラー → 動作OK
このように、SDL3は全機種で同じコードが動作します。
注意点
- ⚠️ WinMMは非推奨: 新規プロジェクトで採用する理由がありません
- ⚠️ XInputは将来性に注意: PlayStation/Switch対応予定があるならSDL3を選んでください
- ⚠️ SDL3はDLL配布必須: ゲーム配布時に
SDL3.dllを同梱する必要があります - ⚠️ ライセンス確認: SDL3はzlibライセンスで商用利用可能ですが、念のため確認してください
まとめ
- ✅ WinMMは過去の遺産: 振動なし、マッピング不安定で新規採用はNG
- ✅ XInputはWindows + Xbox専用の堅実な選択: 学校課題やWindows専用ゲームならベスト
- ✅ SDL3は将来性を考えるならベスト: 全機種対応、クロスプラットフォーム対応
- ✅ Steam配信予定ならSDL3一択: ユーザーの40%がXbox以外のコントローラーを使用
- ✅ 途中でAPIを変更するのは大変: 最初の選択が重要
新規プロジェクトなら、少しでも複数機種対応の可能性があるならSDL3を選びましょう。XInputで作った後にSDL3に移行するのは本当に大変です(経験談)。

