【C++】WinMM vs XInput vs SDL3 徹底比較!ゲームコントローラーAPI選びの決定版

サムネイル画像 C++

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を徹底比較

項目WinMMXInputSDL3
導入の手軽さ
Xbox対応
PS4/PS5対応××
Switch対応××
振動機能×
LED/ジャイロ××
クロスプラットフォーム××
DLL配布不要不要必要
推奨度×

どのAPIを選ぶべき?判断基準

条件推奨API理由
Windows + Xbox限定XInput導入簡単、DLL不要、完璧な動作
複数コントローラー対応SDL3Xbox/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に移行するのは本当に大変です(経験談)。

関連記事