HayBox は、デジタルまたはアナログ/デジタル混合コントローラー用のモジュール式クロスプラットフォーム ファームウェアであり、主に B0XX スタイルのコントローラーを対象としています。
特徴は次のとおりです。
デフォルトのピン マッピングと構成で事前に構築されたファームウェアを単純に使用したい場合は、事前に構築されたバイナリのセクションを参照してください。コードに変更を加えたい場合は、ソースからの構築セクションを参照してください。
.uf2
ファイル) を使用している場合は、PC に接続しているときにブートセル モードにし、表示される RPI-RP2 ドライブに.uf2
ファイルをドラッグ アンド ドロップします。.hex
ファイル) を使用している場合は、QMK Toolbox などのプログラムを使用して.hex
ファイルをフラッシュできます。現在、HayBox を構築するには主に 3 つの方法があります。
GitHub Actions と GitHub Codespaces の両方で、GitHub アカウントを作成する必要がありますが、ローカル マシンに依存関係をインストールする必要はありません。
ローカルでビルドする場合は、次の依存関係が必要です。
すべての要件をインストールした後、最新の HayBox リリースをダウンロードして抽出するか、git がインストールされている場合はリポジトリのクローンを作成します (これにより、更新を取得しやすくなります)。
その後:
git config --global core.longpaths true
を実行します (VS Code 内または通常の cmd/PowerShell はすべて問題ありません)。config/<environment>/config.cpp
) の上部にあるボタンのマッピングとその他のピンを編集できます。コントローラーにないボタンはリストから簡単に削除できます。HayBox/.pio/build/<environment>/firmware.uf2
を RPI にドラッグ アンド ドロップします。 -立ち上がったRP2ドライブ。これはおそらく、HayBox を変更および再構築する最も便利な方法ですが、GitHub の無料利用枠により、毎月の Codespaces の使用量に制限が設けられていることに注意してください。このため、クォータから得られるものを最大化するために、コードスペースを使用していないときは必ずシャットダウンする必要があります。
まず、GitHub アカウントを作成するか、すでにアカウントをお持ちの場合はログインしてから、このリポジトリをフォークし、緑色の [コード] ボタン -> [コードスペース] -> [マスターでコードスペースを作成] をクリックして、新しいコードスペースでフォークを開きます。これにより、必要な拡張機能と依存関係がすべてプリインストールされた状態で、ブラウザーで VS Code が開きます。ここからのプロセスはローカルでビルドする場合とほぼ同じですが、[アップロード] ボタンを使用してファームウェアをフラッシュできない点が異なります。代わりに、コンパイルされたバイナリをHayBox/.pio/build/<environment>/
からダウンロードし、手動でフラッシュする必要があります (詳細については、ここを参照してください)。
このリポジトリには、プッシュごとにマトリックスで指定された各 PlatformIO 環境を構築する GitHub Actions ワークフロー定義が含まれており、履歴から実行された特定のワークフローをクリックすることでダウンロードできるアーティファクトとしてファームウェア バイナリをアップロードします。このリポジトリのフォークを作成し、アクションを有効にするには、[設定] -> [アクション] -> [全般] -> [すべてのアクションと再利用可能なワークフローを許可する] を選択し、[保存] をクリックします。
GitHub Actions 経由でのみビルドする場合に変更を加える最も速い方法は、github.dev を使用することです。を押すだけでこれを行うことができます.
このリポジトリのフォークを開いた状態でキーボードで を押すと、ブラウザで VS Code エディタが開きます。これにより、Codespace で得られるのと同じ開発機能が得られるわけではありませんが、ブラウザから直接変更を加えてコミットすることができます。必要に応じて変更し、左側の [ソース管理] タブを使用して変更を追加、コミット、プッシュします。最後に、リポジトリに戻り、「アクション」タブをクリックし、ワークフローの実行をクリックして、アーティファクトが構築されるのを待ちます。
新しいデバイス構成/PlatformIO 環境を追加する場合、GitHub Actions ワークフローによって環境を構築するには、その環境をマトリックスに追加する必要があります。リソースの使用量を削減し、潜在的にビルドを高速化するために、重要でない環境をマトリックスから削除することもできます。
Pico ベースのコントローラーをブートセル モードで再起動するには、プラグインで [開始] を押し続けます。
GCCPCB2、GCCMX、B0XX R2、または LBX で Brook ボード モードに切り替えるには、プラグインの B を押し続けます。
通信バックエンドの選択は、コントローラーで使用されるマイクロコントローラーの種類に応じて若干異なります。
Pico/RP2040 では、USB 対 GameCube 対 Nintendo 64 が自動的に検出されます。コンソールに接続されていない場合、デフォルトはXInputで、ほとんどの PC ゲームでプラグアンドプレイで動作します。他のバックエンドを選択するには、プラグインで次のいずれかのボタンを押します。
Arduino/AVR では、USB 接続が検出されるとDInputバックエンドが選択されます。それ以外の場合は、プラグインで次のボタンのいずれかを押して別のバックエンドを手動で選択しない限り、デフォルトで GameCube バックエンドになります。
他の同様のファームウェアとは異なり、HayBox ではデフォルトでコントローラーを抜かずにその場でモードを切り替えることができます。ゲームを切り替えるには通常コンソールを再起動する必要があるコンソールとは対照的に、これは主に PC で役立ちます。また、プラグイン中に片手で保持する必要があるボタンの数を減らすという目的もあります。
デフォルトのコントローラー モード ボタンの組み合わせは次のとおりです。
デフォルトのキーボード モード ボタンの組み合わせ (XInput ではなく、DInput バックエンドを使用する場合にのみ使用可能):
HayBox は、複数のゲームで使用するのに適した異なる DInput マッピングを使用するため、公式 B0XX ファームウェアとは異なる Dolphin コントローラー プロファイルが必要です。これらは、HayBox リポジトリのdolphin
フォルダーにあります。プロファイル ファイルには、どの通信バックエンドとオペレーティング システムに対応するかを示す名前が付けられています。
プロファイルをインストールするには:
dolphin
フォルダーからフォルダー<YourDolphinInstallation>UserConfigProfilesGCPad
にコピーします (存在しない場合は作成します)。%appdata%Slippi LaunchernetplayUserConfigProfilesGCPad
~/.config/SlippiOnline/Config/Profiles/GCPad/
Cmd + Shift + G
を押して、パス/Users/<USER>/Library/Application Support/Slippi Launcher/netplay/Slippi Dolphin.app/Contents/Resources/Sys/Config/Profiles/GCPad
を入力します。%userprofile%DocumentsDolphin EmulatorConfigProfilesGCPad
~/.config/dolphin-emu/Profiles/GCPad/
* macOS は DInput のみをサポートします (そしてあまりよくありません)。そのため、Pico/RP2040 ベースのコントローラーを使用している場合は、プラグインで Z を押したままにして DInput モードを強制する必要がありますが、それでも機能しない可能性があります。 Apple の貧弱なコントローラー サポート (更新ごとに機能しなくなるようです) についてはどうすることもできませんし、私は Apple デバイスを所有していないので、これも HayBox のサポート対象外の使用とみなされます。
通信バックエンド (DInput、GameCube、N64 など) は、一部は自動検出によって選択され、一部はプラグインに保持されているボタンに基づいて選択されます。これは、 config/<environment>/config.cpp
のsetup()
関数で処理されます。ロジックは非常に単純で、プログラミングの経験がなくても、何が起こっているかを確認し、必要に応じて変更することはそれほど難しいことではありません。
Arduino 環境に対応する設定フォルダーは次のとおりです。
config/arduino_nativeusb/
(Leonardo、Micro など)config/arduino/
(Uno、Nano、Mega 2560 など) Arduino デバイス構成の場合、数値 125 がGamecubeBackend()
に渡されることに気づくかもしれません。これにより、DIY がネイティブ USB をサポートしておらず、オーバークロックされた GameCube コントローラー アダプターで使用したい場合などに、ポーリング レートを変更できます。この例では、1000 を渡して 1000Hz のポーリング レートまで同期するか、0 を渡してこの遅延修正を完全に無効にすることができます。ポーリング レートは、これと同じ方法で N64Backend コンストラクターに渡すことができます。
1000Hz のポーリング レートがコンソールでも同様に機能することに気づくかもしれません。これは機能しますが、入力遅延が増加することに注意してください。ここでポーリング レートを設定するポイントは、GameCube バックエンドが入力を読み取る前に次のポーリングの直前まで遅延できるようにすることで、入力が新鮮で古くならないようにすることです。
Pico/RP2040 の場合、コンソール ポーリング レートを渡す必要はありません。Pico には、コンソール ポーリングを受信した後に入力を読み取り/処理するのに十分な処理能力があるため、ポーリングがいつ到着するかを予測して準備する必要がありません。あらかじめ。
入力モード (コントローラー/キーボード モード) のボタンのホールドを構成するには、 config/mode_selection.hpp
のselect_mode()
関数を編集します。各if
ステートメントは、入力モードを選択するためのボタンの組み合わせです。
ほとんどの入力モードは、 SOCD クリーニング モードsocd::2IP_NO_REAC
など) での受け渡しをサポートしています。他の利用可能なモードについては、ここを参照してください。
新しい入力モードを作成するには、C++ の知識があるか、少なくともプログラミングの経験があると役に立ちます。とはいえ、既存のモードをベースにして新しいモードを作成し、それらを例として参照すれば、経験がなくてもなんとかできるはずです。
入力モードには、ControllerMode と KeyboardMode の 2 種類があります。
キーボード モードはもう少し簡単なので、そこから始めましょう。
KeyboardMode は標準キーボードとして動作し、キーボードをサポートするあらゆるデバイスで動作する必要があります。
UpdateKeys()
関数で好きなロジックやプログラミング トリックを自由に使用して、入力状態に基づいて出力を決定できます。入力レイヤー (Mod X と Mod Y を押したときにアクティブになる近接モードの D-Pad レイヤーなど) やその他のタイプの条件付き入力を作成できます。
利用可能なキーコードのリストはここにあります。
キーボード モードは、 DInput通信バックエンド (XInputではない) を使用する場合にのみアクティブにできることに注意してください。
ControllerMode は、デジタル ボタンの入力状態を取得し、それを標準のゲームパッドに対応する出力状態に変換します。どのControllerModeもどのCommunicationBackendでも動作します。 CommunicationBackend は、1 つ以上の入力ソースから入力を読み取り、現在の ControllerMode を使用してそれらの入力に基づいて出力を更新し、コンソールまたは PC への出力の送信を処理します。
ControllerMode を作成するには、関数UpdateDigitalOutputs()
とUpdateAnalogOutputs()
を実装するだけです。
UpdateDigitalOutputs()
キーボード モードのUpdateKeys()
関数に非常に似ていますが、 Press()
関数を呼び出して入力をすぐに送信するのではなく、単にこの反復の出力状態を設定しているだけという点が異なります。名前が示すように、この関数ではデジタル出力のみを扱います。
UpdateAnalogOutputs()
はもう少し複雑です。まず、他のことを行う前にUpdateDirections()
を呼び出す必要があります。この関数は、左右のスティックが左/右/上/下を向いているかどうかを示す値を受け取ります。また、スティック アナログの最小値、ニュートラル (中央)、および最大値も渡すので、これらをモードごとに設定できます。これらすべての情報は、渡した入力に基づいてスティックのアナログ値を自動的に設定するために使用されます。モディファイアを実装する場合を除き、必要な操作はこれだけです。
UpdateDirections()
また、現在のスティック方向を示す値を変数directions
に設定します。値は、両方のスティックの X 軸と Y 軸に対して 1、0、または -1 になります。これらの値を使用すると、修飾子ロジックの作成がはるかに簡単になります。
UpdateDirections()
呼び出した後、必要な修飾子処理ロジックを追加します。 UpdateDirections()
デフォルトのアナログ スティック値をすでに設定しているので、モディファイアを処理するときは、実際に変更されている軸の値を手動で設定するだけでよいことに注意してください。これ以外に、修飾子ロジックの書き方を教えることはできないので、例を見て遊んでみてください。
最後に、必要なアナログ トリガー値を設定します。
注: アナログ トリガー出力はUpdateDigitalOutputs()
で処理することもできますが、通常は他のアナログ出力と一緒に保持した方がすっきりすると思います。
また、出力状態をリセットしたり、そこから何かをクリアしたりすることについて心配する必要はありません。これは各反復の開始時に自動的に行われます。
各モードのコンストラクター (コントローラー モードとキーボード モードの場合) で、SOCD クリーニングを適用する反対方向入力のペアを構成できます。
たとえば、 src/modes/Melee20Button.cpp
では次のようになります。
_socd_pair_count = 4;
_socd_pairs = new socd::SocdPair[_socd_pair_count]{
socd::SocdPair{&InputState::left, &InputState::right, socd_type},
socd::SocdPair{ &InputState::down, &InputState::up, socd_type},
socd::SocdPair{ &InputState::c_left, &InputState::c_right, socd_type},
socd::SocdPair{ &InputState::c_down, &InputState::c_up, socd_type},
};
これにより、SOCD クリーニングが適用される対向する基本方向のペアとして、左/右、下/上、C-Left/C-Right、および C-Down/C-Up が設定されます。 SOCD のクリーニングはUpdateDigitalOutputs()
およびUpdateAnalogOutputs()
の前に自動的に行われるため、それ以上心配する必要はありません。
SocdPair
ごとに、選択したSocdType
を渡すことができます。ほとんどのモードのデフォルトでは、これは単一のコンストラクター パラメーターとして渡されますが、複数のパラメーターを渡したり、単にハードコードされた値を使用したりすることも可能です。これらのアプローチはどちらもsrc/modes/FgcMode.cpp
に例示されています。
SocdType | 説明 |
---|---|
SOCD_NEUTRAL | Left + right = ニュートラル - SocdPair でSocdType が指定されていない場合のデフォルト |
SOCD_2IP | 2 番目の入力優先順位 - 左 -> 左 + 右 = 右、またはその逆。 2 番目の方向を解放すると、元の方向になります。 |
SOCD_2IP_NO_REAC | 再アクティブ化なしの 2 番目の入力優先順位 - 2 番目の方向を解放するとニュートラルになることを除いて、上記と同じです。元の方向を物理的に再起動する必要があります。 |
SOCD_DIR1_PRIORITY | SocdPair の最初のボタンは常に 2 番目のボタンよりも優先されます。 |
SOCD_DIR2_PRIORITY | SocdPair の 2 番目のボタンは常に最初のボタンより優先されます。 |
SOCD_NONE | SOCD 解像度なし - ゲームが決める |
Melee20Button モードや Melee18Button モードの場合のように、 HandleSocd()
関数を実装する必要がないことに注意してください。これは、SOCD のクリーニング前に左と右の両方が保持されているかどうかを確認できるように、これらのモードでのみオーバーライドされます。これは、両方が保持されている場合 (垂直方向が保持されていない場合)、すべてのモディファイアをオーバーライドする必要があるためです。
コントローラーにライトシールド ボタンがない場合は、ライトシールドに Mod X を使用し、代わりにシールドの傾きを R に設定するとよいでしょう。これを行うには、Melee20Button の代わりに Melee18Button モードを使用します。
Melee20Button および Melee18Button モードでは、下 + 右を押したときに使用する座標を選択できます。デフォルトでは、+ Back を押し続けると自動ジャブキャンセルが可能になります。これは一部のキャラクターにとっては便利なテクニックです。
下 + 右斜めを使用するもう 1 つの人気のあるテクニックは、いわゆるしゃがむ/歩くオプション選択です。このテクニックでは、しゃがみながら + を一定の角度で前方に押し続けることで、攻撃をしゃがみキャンセルした後、しゃがみ状態に戻るのではなく、自動的に相手に向かって歩き始めます。これはテクチェイスに非常に役立ちますが、このテクニックに使用される座標では自動ジャブキャンセルができません。
これは、 crouch_walk_os
オプションを true に設定することで、 config/mode_selection.hpp
にあるように設定できます。
new Melee20Button(socd::SOCD_2IP_NO_REAC, { .crouch_walk_os = false })
また、 mode_selection.hpp
モードを切り替えたときの動作のみを制御するため、プラグインに適用するには、 config/<environment>/config.cpp
でこれを変更する必要があります。
ProjectM モードには、特定の動作を構成するための追加オプションがいくつかあります。 config/mode_selection.hpp
にあるように:
new ProjectM(
socd::SOCD_2IP_NO_REAC,
{ .true_z_press = false, .ledgedash_max_jump_traj = true }
)
まず、 ledgedash_max_jump_traj
オプションを使用すると、近接モードから借用した動作を有効または無効にできます。この動作では、左右に押し続けると (垂直方向はなし)、保持されているモディファイアに関係なく 1.0 基数が与えられます。
SOCD モードを 2IP (再アクティブ化あり) に変更する場合、スムーズなゲームプレイ エクスペリエンスを得るには、このオプションも false に変更する必要があります。
次に、 true_z_press
オプションが存在するのは、Project M/Project+ が Melee と同じ方法で Z プレスを処理しないためです。近接攻撃は Z 押しをライトシールド + A として解釈するため、テクをロックアウトすることなく L キャンセルに使用できます。 PM/P+ では、Z を押すとテクが発動するため、L キャンセルに使用すると不要なテク ロックアウトが発生します。 HayBox のデフォルトでは、ProjectM モードは、Melee からの予期される動作を維持するために、ライトシールド + A のマクロを使用するように設定されています。ただし、このマクロでは、テザー/グラップル攻撃を使用したり、アイテムを掴んだりすることはできません。これを回避するには、Mod X + Z を押して真の Z 入力を送信します。
これが気になり、Z キーを押したときにデフォルトで true Z 入力を送信したい場合は、 true_z_press
オプションを true に設定できます。
HayBox は、入力状態を更新するために読み取ることができるいくつかの入力ソースをサポートしています。
GpioButtonInput
- GPIO ピンに直接接続されたスイッチ/ボタンを読み取るために最も一般的に使用されます。ほとんどすべての既存の構成で見られるように、入力マッピングはGpioButtonMapping
の配列によって定義されます。SwitchMatrixInput
- 上記と似ていますが、個々のスイッチではなくキーボード スタイルのスイッチ マトリックスをスキャンします。 Crane のモデル C<=53 の構成はconfig/c53/config.cpp
に含まれており、スイッチ マトリックス入力ソースの定義および使用方法の例として機能します。NunchukInput
- i2c を使用して Wii ヌンチャクから入力を読み取ります。これは混合入力コントローラーに使用できます (例: 左手は移動にヌンチャクを使用し、右手は他のコントロールにボタンを使用します)GamecubeControllerInput
- 上記と似ていますが、GameCube コントローラーから読み取ります。 GamecubeBackendと同様にインスタンス化できます。現在のところ、Pico に対してのみ実装されており、GamecubeBackend のインスタンスとは異なる pio インスタンス (pio0 または pio1) で実行するか、両方で同じ PIO 命令メモリ オフセットを使用するようにする必要があります。各入力ソースには、入力の読み取りにかかるおおよその時間を示す「スキャン速度」値があります。高速入力ソースは常に可能な限り最後の瞬間に読み取られるため (少なくとも Pico では)、レイテンシーが非常に低くなります。逆に、遅い入力ソースは、ポーリングに応答して読み取るには遅すぎるため、通常、必要になるかなり前に読み取られます。このため、これらの入力を別のコアで常に読み取ることがより理想的です。これは、AVR MCU ではすべてシングルコアであるため不可能ですが、Pico/RP2040 では可能 (そして簡単) です。デフォルトの Pico 設定config/pico/config.cpp
の下部では、core1 を使用してヌンチャク入力を読み取り、core0 がその他すべてを処理することでこれを示しています。 core1 の使用方法の詳細については、次のセクションを参照してください。
各構成のsetup()
関数では、入力ソースの配列を構築し、それを通信バックエンドに渡します。入力はバックエンドごとに異なる時点で読み取られる必要があるため、通信バックエンドはどの入力ソースをいつ読み取るかを決定します。また、複数のバックエンドを同時に使用できるように、一連の通信バックエンドも構築します。たとえば、ほとんどの構成では、DInput バックエンドが使用されるときは常に、B0XX 入力ビューア バックエンドがセカンダリ バックエンドとして使用されます。各反復で、メイン ループは各バックエンドにそれぞれのレポートを送信するように指示します。将来的には、OLED ディスプレイへの情報の書き込みなどのためのバックエンドがさらに増える可能性があります。
各構成には関数setup()
とloop()
があり、 setup()
が最初に実行され、次に、デバイスの電源がオフになるまで、 loop()
が繰り返し実行されます。
Pico/RP2040 では、 setup()
とloop()
関数は core0 で実行され、core1 でタスクを実行するためにsetup1()
とloop1()
関数を追加できます。
たとえば、core1 の GameCube コントローラ入力を読み取るには:
GamecubeControllerInput *gcc = nullptr;
void setup1() {
while (backends == nullptr) {
tight_loop_contents();
}
gcc = new GamecubeControllerInput(gcc_pin, 2500, pio1);
}
void loop1() {
if (backends != nullptr) {
gcc->UpdateInputs(backends[0]->GetInputs());
}
}
while
ループにより、core0 のsetup()
通信バックエンドのセットアップを完了するまで待機します。次に、ポーリング レート 2500Hz の GameCube コントローラ入力ソースを作成します。また、特に指定がない限りpio0
使用する GameCube/N64 バックエンドとの干渉を避ける簡単な方法として、 pio1
上でも実行します。 loop1()
では、プライマリ バックエンドがbackends
配列の最初の要素であると仮定し (いずれにせよ、同じファイル内で構成されているため、実際に知らないことは何も仮定していません)、ゲームキューブ コントローラーを直接スキャンします。バックエンドの入力状態への入力。
少しクレイジーな仮説の例として、それぞれ 10 ピンを使用する 2 つのスイッチ マトリックス入力ソースと 2 つの GameCube バックエンド (両方とも別々のコア上) を作成することで、1 つの Pico を使用して 2 人用アーケード キャビネットのすべてのコントロールに電力を供給することもできます。可能性は無限大です。
Arduino ベースのコントローラーで公式アダプターを使用している場合は、GamecubeBackend コンストラクターにポーリング レート 0 を渡すことでポーリング レイテンシの最適化を無効にするプラグインで A を押し続ける必要がある可能性があります。
ブースト回路のない Arduino ベースのコントローラーを使用している場合は、5V の電源が必要となるため、Mayflash アダプターの場合は両方の USB ケーブルを接続する必要があり、コンソールではランブル ラインが損なわれていない必要があります。 Pico は 3.3V 電源でネイティブに動作するため、これは問題ありません。
貢献を歓迎します。共有したい入力モードを作成した場合は、お気軽にプルリクエストを行ってください。 VS Code の Clang-format プラグインをインストールし、それを使用して追加するコードをフォーマットしてください。
バージョン管理には SemVer を使用します。利用可能なバージョンについては、このリポジトリのタグを参照してください。
このプロジェクトに参加した貢献者のリストもご覧ください。
このプロジェクトは GNU GPL バージョン 3 に基づいてライセンスされています。詳細については、LICENSE ファイルを参照してください。