HayBox ist eine modulare, plattformübergreifende Firmware für digitale oder gemischt analog/digitale Controller, die hauptsächlich auf Controller im B0XX-Stil ausgerichtet ist.
Zu den Funktionen gehören:
Wenn Sie einfach eine vorgefertigte Firmware mit Standard-Pin-Zuordnungen und -Konfiguration verwenden möchten, lesen Sie den Abschnitt zu vorgefertigten Binärdateien. Wenn Sie Änderungen am Code vornehmen möchten, lesen Sie den Abschnitt „Build from Source“.
.uf2
Datei) verwenden, versetzen Sie ihn einfach in den Bootsel-Modus, während Sie ihn an Ihren PC anschließen, und ziehen Sie die .uf2
Datei per Drag & Drop auf das angezeigte RPI-RP2-Laufwerk.hex
Datei) verwenden, können Sie ein Programm wie QMK Toolbox verwenden, um die .hex
Datei darauf zu flashenDerzeit gibt es drei Hauptmethoden, um HayBox zu erstellen:
Sowohl für GitHub Actions als auch für GitHub Codespaces müssen Sie ein GitHub-Konto erstellen, aber keine Abhängigkeiten auf Ihrem lokalen Computer installieren.
Beim lokalen Erstellen sind folgende Abhängigkeiten erforderlich:
Nachdem Sie alle Anforderungen installiert haben, laden Sie die neueste HayBox-Version herunter und extrahieren Sie sie oder klonen Sie das Repository, wenn Sie Git installiert haben (was Ihnen das Abrufen von Updates erleichtert).
Danach:
git config --global core.longpaths true
in einem beliebigen Terminal aus (innerhalb von VS Code oder normalem cmd/PowerShell ist alles in Ordnung).config/<environment>/config.cpp
). Alle Schaltflächen, die Ihr Controller nicht hat, können einfach aus der Liste gelöscht werden.HayBox/.pio/build/<environment>/firmware.uf2
per Drag & Drop auf das RPI -RP2-Laufwerk, das angezeigt wird.Dies ist wahrscheinlich die bequemste Möglichkeit, HayBox zu ändern und neu zu erstellen. Beachten Sie jedoch, dass das kostenlose Kontingent von GitHub einige Einschränkungen hinsichtlich der monatlichen Nutzung von Codespaces mit sich bringt. Aus diesem Grund sollten Sie sicherstellen, dass Sie Ihre Codespaces herunterfahren, wenn Sie sie nicht verwenden, um das Beste aus Ihrem Kontingent herauszuholen.
Erstellen Sie zunächst ein GitHub-Konto oder melden Sie sich einfach an, wenn Sie bereits eines haben, teilen Sie dann dieses Repository auf und öffnen Sie Ihren Fork in einem neuen Codespace, indem Sie auf die grüne Code-Schaltfläche -> Codespaces -> Codespace auf Master erstellen klicken. Dadurch sollte VS Code in Ihrem Browser geöffnet werden, wobei alle erforderlichen Erweiterungen und Abhängigkeiten vorinstalliert sind. Von hier aus ist der Vorgang weitgehend derselbe wie beim lokalen Erstellen, außer dass Sie die Schaltfläche „Hochladen“ nicht zum Flashen der Firmware verwenden können. Stattdessen müssen Sie die kompilierte Binärdatei von HayBox/.pio/build/<environment>/
herunterladen und manuell flashen (mehr dazu finden Sie hier).
Dieses Repository enthält eine GitHub Actions-Workflow-Definition, die bei jedem Push jede in der Matrix angegebene PlatformIO-Umgebung erstellt und Firmware-Binärdateien als Artefakte hochlädt, die Sie herunterladen können, indem Sie im Verlauf auf eine bestimmte Workflow-Ausführung klicken. Sie können einen Fork dieses Repositorys erstellen und Aktionen aktivieren, indem Sie auf Einstellungen -> Aktionen -> Allgemein -> „Alle Aktionen und wiederverwendbare Workflows zulassen“ -> Speichern klicken.
Der schnellste Weg, Änderungen vorzunehmen, wenn Sie nur über GitHub Actions erstellen möchten, ist die Verwendung von github.dev. Sie können dies tun, indem Sie einfach drücken .
auf Ihrer Tastatur, während Ihr Zweig dieses Repositorys geöffnet ist, und es öffnet sich ein VS-Code-Editor in Ihrem Browser. Dadurch erhalten Sie nicht die gleichen Entwicklungsfunktionen wie in einem Codespace, aber Sie können Änderungen vornehmen und diese direkt über Ihren Browser übernehmen. Ändern Sie, was Sie möchten, und verwenden Sie dann die Registerkarte „Quellcodeverwaltung“ auf der linken Seite, um Ihre Änderungen hinzuzufügen, zu übernehmen und zu übertragen. Gehen Sie abschließend zurück zum Repository und klicken Sie auf die Registerkarte „Aktionen“, klicken Sie auf Ihre Workflow-Ausführung und warten Sie, bis das Artefakt erstellt wird.
Wenn Sie eine neue Gerätekonfigurations-/PlatformIO-Umgebung hinzufügen, müssen Sie die Umgebung zur Matrix hinzufügen, damit sie vom GitHub Actions-Workflow erstellt werden kann. Sie können auch alle Umgebungen aus der Matrix entfernen, die Sie nicht interessieren, um den Ressourcenverbrauch zu reduzieren und Ihre Builds möglicherweise zu beschleunigen.
Um Pico-basierte Controller im Bootsel-Modus neu zu starten, halten Sie „Start“ im Plugin gedrückt.
Um auf GCCPCB2, GCCMX, B0XX R2 oder LBX in den Brook-Board-Modus zu wechseln, halten Sie B am Plugin gedrückt.
Kommunikations-Backends werden je nach Art des im Controller verwendeten Mikrocontrollers leicht unterschiedlich ausgewählt.
Auf Pico/RP2040 wird USB vs. GameCube vs. Nintendo 64 automatisch erkannt. Wenn es nicht an eine Konsole angeschlossen ist, ist die Standardeinstellung XInput , die mit den meisten PC-Spielen per Plug-and-Play funktionieren sollte. Andere Backends werden ausgewählt, indem Sie eine der folgenden Schaltflächen im Plugin gedrückt halten:
Auf Arduino/AVR wird das DInput- Backend ausgewählt, wenn eine USB-Verbindung erkannt wird. Andernfalls wird standardmäßig das GameCube-Backend verwendet, es sei denn, ein anderes Backend wird manuell ausgewählt, indem Sie eine der folgenden Schaltflächen im Plugin gedrückt halten:
Im Gegensatz zu anderen ähnlichen Firmwares können Sie mit HayBox standardmäßig den Modus im Handumdrehen wechseln, ohne den Controller ausstecken zu müssen. Dies ist vor allem auf dem PC nützlich, im Gegensatz zur Konsole, wo man die Konsole normalerweise ohnehin neu starten muss, um das Spiel zu wechseln. Es dient auch dazu, die Anzahl der Tasten zu reduzieren, die Sie beim Anschließen mit einer Hand halten müssen.
Die Standardtastenkombinationen für den Controller-Modus sind:
Standardtastenkombinationen im Tastaturmodus (nur verfügbar bei Verwendung des DInput-Backends, nicht mit XInput):
HayBox benötigt ein anderes Dolphin-Controller-Profil als die offizielle B0XX-Firmware, da es andere DInput-Zuordnungen verwendet, die für die Verwendung in mehreren Spielen sinnvoller sind. Diese finden Sie im dolphin
Ordner im HayBox-Repo. Die Profildateien sind so benannt, dass sie angeben, für welches Kommunikations-Backend und Betriebssystem sie bestimmt sind:
So installieren Sie das Profil:
dolphin
Ordner in HayBox in den Ordner <YourDolphinInstallation>UserConfigProfilesGCPad
(erstellen Sie ihn, falls er nicht vorhanden ist).%appdata%Slippi LaunchernetplayUserConfigProfilesGCPad
~/.config/SlippiOnline/Config/Profiles/GCPad/
Cmd + Shift + G
und geben Sie den Pfad /Users/<USER>/Library/Application Support/Slippi Launcher/netplay/Slippi Dolphin.app/Contents/Resources/Sys/Config/Profiles/GCPad
ein%userprofile%DocumentsDolphin EmulatorConfigProfilesGCPad
~/.config/dolphin-emu/Profiles/GCPad/
* macOS unterstützt nur DInput (und nicht sehr gut). Wenn Sie also einen Pico/RP2040-basierten Controller verwenden, müssen Sie den DInput-Modus erzwingen, indem Sie Z am Plugin gedrückt halten, und selbst dann funktioniert es möglicherweise nicht. Ich kann nicht wirklich etwas gegen die schlechte Controller-Unterstützung von Apple tun (die anscheinend mit jedem anderen Update unterbrochen wird) und ich besitze keine Apple-Geräte, daher wird dies auch als nicht unterstützte Nutzung von HayBox angesehen.
Das Kommunikations-Backend (z. B. DInput, GameCube oder N64) wird teilweise durch automatische Erkennung und teilweise basierend auf den im Plugin gehaltenen Schaltflächen ausgewählt. Dies wird in config/<environment>/config.cpp
in der Funktion setup()
behandelt. Die Logik ist ziemlich einfach, und selbst wenn Sie keine Programmiererfahrung haben, sollte es nicht allzu schwer sein, zu erkennen, was vor sich geht, und bei Bedarf Änderungen vorzunehmen.
Die den Arduino-Umgebungen entsprechenden Konfigurationsordner sind:
config/arduino_nativeusb/
für Arduino mit nativer USB-Unterstützung (z. B. Leonardo, Micro)config/arduino/
für Arduino ohne native USB-Unterstützung (z. B. Uno, Nano, Mega 2560) Bei Arduino-Gerätekonfigurationen stellen Sie möglicherweise fest, dass die Zahl 125 an GamecubeBackend()
übergeben wird. Dadurch können Sie die Abfragerate ändern, wenn Ihr Heimwerker beispielsweise kein natives USB unterstützt und Sie ihn mit einem übertakteten GameCube-Controller-Adapter verwenden möchten. In diesem Beispiel könnten Sie 1000 übergeben, um die Synchronisierung auf die Abfragerate von 1000 Hz zu ermöglichen, oder 0, um diese Verzögerungskorrektur vollständig zu deaktivieren. Die Abfragerate kann auf die gleiche Weise an den N64Backend-Konstruktor übergeben werden.
Möglicherweise stellen Sie fest, dass die Abfragerate von 1000 Hz auch auf der Konsole funktioniert. Beachten Sie, dass dies zwar funktioniert, aber zu einer stärkeren Eingabeverzögerung führt. Der Sinn der Einstellung der Abfragerate besteht hier darin, dass das GameCube-Backend bis kurz vor der nächsten Abfrage warten kann, bevor es die Eingaben liest, sodass die Eingaben aktuell und nicht veraltet sind.
Für Pico/RP2040 ist es nicht erforderlich, eine Konsolenabfragerate zu übergeben, da der Pico über genügend Rechenleistung verfügt, um Eingaben nach dem Empfang der Konsolenabfrage zu lesen/verarbeiten, sodass keine Vorhersage, wann die Abfrage eintrifft, und Vorbereitungen erforderlich sind im voraus.
Um die Tastenbelegung für Eingabemodi (Controller-/Tastaturmodi) zu konfigurieren, bearbeiten Sie die Funktion select_mode()
in config/mode_selection.hpp
. Jede if
-Anweisung ist eine Tastenkombination zur Auswahl eines Eingabemodus.
Die meisten Eingabemodi unterstützen die Übergabe eines SOCD-Reinigungsmodus, z. B. socd::2IP_NO_REAC
. Weitere verfügbare Modi finden Sie hier.
Für die Erstellung neuer Eingabemodi ist es hilfreich, wenn Sie sich mit C++ auskennen oder zumindest etwas Programmiererfahrung haben. Allerdings sollten Sie auch ohne Vorkenntnisse zurechtkommen, wenn Sie Ihren neuen Modus einfach auf den bestehenden aufbauen und diese als Beispiele heranziehen.
Es gibt zwei Arten von Eingabemodi: ControllerMode und KeyboardMode
Die Tastaturmodi sind etwas einfacher, also fangen wir dort an.
Ein KeyboardMode verhält sich wie eine Standardtastatur und sollte mit jedem Gerät funktionieren, das Tastaturen unterstützt.
Es steht Ihnen frei, in der UpdateKeys()
Funktion beliebige Logik- und Programmierungstricks zu verwenden, um die Ausgaben basierend auf dem Eingabestatus zu bestimmen. Sie können Eingabeebenen (wie die D-Pad-Ebene im Nahkampfmodus, die aktiviert wird, wenn Sie Mod X und Mod Y gedrückt halten) oder andere Arten bedingter Eingaben erstellen.
Die Liste der verfügbaren Schlüsselcodes finden Sie hier.
Denken Sie daran, dass Tastaturmodi nur bei Verwendung des DInput- Kommunikations-Backends ( nicht XInput) aktiviert werden können.
Ein ControllerMode nimmt den Eingabezustand einer digitalen Taste und wandelt ihn in einen Ausgabezustand um, der einem Standard-Gamepad entspricht. Jeder ControllerMode funktioniert mit jedem CommunicationBackend. Ein CommunicationBackend liest einfach Eingaben von einer oder mehreren Eingabequellen, verwendet den aktuellen ControllerMode, um die Ausgaben basierend auf diesen Eingaben zu aktualisieren, und kümmert sich um das Senden der Ausgaben an die Konsole oder den PC.
Um einen ControllerMode zu erstellen, müssen Sie lediglich die Funktionen UpdateDigitalOutputs()
und UpdateAnalogOutputs()
implementieren.
UpdateDigitalOutputs()
ist der Funktion UpdateKeys()
im Tastaturmodus sehr ähnlich, mit dem Unterschied, dass wir statt einer Press()
Funktion zum sofortigen Senden von Eingaben einfach den Ausgabestatus für diese Iteration festlegen. Wie der Name schon sagt, beschäftigen wir uns in dieser Funktion nur mit den digitalen Ausgängen.
UpdateAnalogOutputs()
ist etwas komplizierter. Zuerst muss UpdateDirections()
aufgerufen werden, bevor irgendetwas anderes getan werden kann. Diese Funktion nimmt Werte entgegen, die angeben, ob Ihr linker und rechter Stick nach links/rechts/oben/unten zeigen. Sie übergeben auch die minimalen, neutralen (Mitte) und maximalen Stick-Analogwerte, sodass Sie diese für jeden Modus konfigurieren können. Alle diese Informationen werden verwendet, um die Analogwerte des Sticks basierend auf den von Ihnen eingegebenen Eingaben automatisch festzulegen. Dies ist alles, was Sie tun müssen, es sei denn, Sie möchten Modifikatoren implementieren.
UpdateDirections()
füllt außerdem die variablen directions
mit Werten, die die aktuelle Stickrichtung angeben. Diese können 1, 0 oder -1 für die X- und Y-Achsen beider Sticks sein. Diese Werte erleichtern das Schreiben der Modifikatorlogik erheblich.
Fügen Sie nach dem Aufruf von UpdateDirections()
die gewünschte Modifikatorbehandlungslogik hinzu. Denken Sie daran, dass UpdateDirections()
bereits die Standardwerte für den Analogstick festgelegt hat, sodass Sie bei der Handhabung von Modifikatoren nur die Werte für die Achsen manuell festlegen müssen, die tatsächlich geändert werden. Ansonsten kann ich Ihnen nicht beibringen, wie Sie Ihre Modifikatorlogik schreiben, also schauen Sie sich einfach die Beispiele an und spielen Sie herum.
Stellen Sie abschließend alle benötigten analogen Triggerwerte ein.
Hinweis: Analoge Triggerausgänge könnten genauso gut in UpdateDigitalOutputs()
gehandhabt werden, aber ich denke, es sieht normalerweise sauberer aus, sie zusammen mit den anderen analogen Ausgängen zu behalten.
Beachten Sie außerdem: Sie müssen sich keine Gedanken darüber machen, den Ausgabestatus zurückzusetzen oder etwas daraus zu löschen. Dies erfolgt automatisch zu Beginn jeder Iteration.
Im Konstruktor jedes Modus (für Controller-Modi und Tastaturmodi) können Sie Paare von Eingaben mit entgegengesetzter Richtung konfigurieren, auf die die SOCD-Bereinigung angewendet werden soll.
Zum Beispiel in 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},
};
Dadurch werden Links/Rechts, Unten/Oben, C-Links/C-Rechts und C-Unten/C-Oben als Paare entgegengesetzter Himmelsrichtungen eingerichtet, für die die SOCD-Reinigung angewendet wird. Die SOCD-Bereinigung wird automatisch vor UpdateDigitalOutputs()
und UpdateAnalogOutputs()
durchgeführt, und Sie müssen sich darüber nicht weiter kümmern.
Für jedes SocdPair
können Sie einen SocdType
Ihrer Wahl übergeben. Standardmäßig wird dies in den meisten Modi als einzelner Konstruktorparameter übergeben, es ist jedoch möglich, mehrere Parameter zu übergeben oder einfach einen fest codierten Wert zu verwenden. Beide Ansätze werden in src/modes/FgcMode.cpp
veranschaulicht.
SocdType | Beschreibung |
---|---|
SOCD_NEUTRAL | Links + rechts = neutral – die Standardeinstellung, wenn im SocdPair kein SocdType angegeben ist |
SOCD_2IP | Zweite Eingabepriorität – links -> links + rechts = rechts und umgekehrt. Durch Loslassen der zweiten Richtung wird die ursprüngliche Richtung zurückgegeben |
SOCD_2IP_NO_REAC | Zweite Eingangspriorität ohne Reaktivierung – wie oben, außer dass die Freigabe der zweiten Richtung zur Neutralstellung führt. Die ursprüngliche Richtung muss physikalisch reaktiviert werden. |
SOCD_DIR1_PRIORITY | Die erste Schaltfläche im SocdPair hat immer Vorrang vor der zweiten |
SOCD_DIR2_PRIORITY | Die zweite Schaltfläche im SocdPair hat immer Vorrang vor der ersten |
SOCD_NONE | Keine SOCD-Auflösung – das Spiel entscheidet |
Beachten Sie, dass Sie keine HandleSocd()
Funktion wie in den Modi Melee20Button und Melee18Button implementieren müssen. Es wird nur in diesen Modi überschrieben, damit wir vor der SOCD-Reinigung prüfen können, ob links und rechts beide gehalten werden, denn wenn beide gehalten werden (ohne dass eine vertikale Richtung gehalten wird), müssen wir alle Modifikatoren überschreiben.
Wenn Ihr Controller keine Lichtschutztasten hat, können Sie Mod X für den Lichtschutz verwenden und stattdessen die Schildneigung auf R stellen. Sie können dies tun, indem Sie den Melee18Button-Modus anstelle von Melee20Button verwenden.
Die Modi „Melee20Button“ und „Melee18Button“ bieten eine Auswahl an Koordinaten, die beim Drücken von „Nach unten + rechts“ verwendet werden sollen. Wenn Sie die Tasten + Zurück gedrückt halten, können Sie standardmäßig automatische Stoßabbrüche durchführen, was für einige Charaktere eine nützliche Technik ist.
Eine weitere beliebte Technik, die die Abwärts- und Rechtsdiagonale nutzt, ist die sogenannte Crouch/Walk-Optionsauswahl. Bei dieser Technik wird in der Hocke die Taste gedrückt und in einem bestimmten Winkel nach vorne gedrückt, sodass Sie nach dem Abbrechen eines Angriffs durch die Hocke automatisch auf Ihren Gegner zulaufen, anstatt wieder in die Hocke zu gehen. Dies kann beim Tech-Chasing sehr nützlich sein, aber die für diese Technik verwendeten Koordinaten erlauben es nicht, den Stoß automatisch abzubrechen.
Dies kann wie in config/mode_selection.hpp
gezeigt konfiguriert werden, indem die Option crouch_walk_os
auf true gesetzt wird:
new Melee20Button(socd::SOCD_2IP_NO_REAC, { .crouch_walk_os = false })
Sie müssen dies auch in Ihrer config/<environment>/config.cpp
ändern, damit es auf das Plugin angewendet wird, da mode_selection.hpp
nur steuert, was passiert, wenn Sie den Modus wechseln .
Der ProjectM-Modus verfügt über einige zusätzliche Optionen zum Konfigurieren bestimmter Verhaltensweisen. Wie in config/mode_selection.hpp
zu sehen ist:
new ProjectM(
socd::SOCD_2IP_NO_REAC,
{ .true_z_press = false, .ledgedash_max_jump_traj = true }
)
Erstens können Sie mit der Option ledgedash_max_jump_traj
das vom Nahkampfmodus übernommene Verhalten aktivieren oder deaktivieren, bei dem das Halten von links und rechts (und keine vertikalen Richtungen) unabhängig von den gehaltenen Modifikatoren eine Kardinalzahl von 1,0 ergibt.
Wenn Sie den SOCD-Modus auf 2IP (mit Reaktivierung) ändern, sollten Sie diese Option auch auf false ändern, wenn Sie ein reibungsloses Spielerlebnis wünschen.
Zweitens gibt es die Option true_z_press
, weil Project M/Project+ Z-Pressen nicht auf die gleiche Weise verarbeiten wie Melee. Nahkampf interpretiert einen Z-Druck als Lichtschild + A und kann daher zum L-Annullieren verwendet werden, ohne dass Sie von Techs ausgeschlossen werden. In PM/P+ löst ein Z-Druck eine Technologie aus und führt somit zu unerwünschten Tech-Sperren, wenn er zum Abbrechen von L verwendet wird. Standardmäßig ist in HayBox der ProjectM-Modus so eingestellt, dass er ein Makro aus Lichtschutz + A verwendet, um das erwartete Verhalten von Melee beizubehalten. Mit diesem Makro können Sie jedoch keine Halte-/Grapple-Angriffe ausführen oder Gegenstände greifen. Um dieses Problem zu umgehen, können Sie Mod X + Z drücken, um eine echte Z-Eingabe zu senden.
Wenn Sie das stört und Sie beim Drücken von Z standardmäßig nur eine echte Z-Eingabe senden möchten, können Sie die Option true_z_press
auf true setzen.
HayBox unterstützt mehrere Eingabequellen, aus denen gelesen werden kann, um den Eingabestatus zu aktualisieren:
GpioButtonInput
– Wird am häufigsten zum Lesen von Schaltern/Tasten verwendet, die direkt mit GPIO-Pins verbunden sind. Die Eingabezuordnungen werden durch ein Array von GpioButtonMapping
definiert, wie in fast allen vorhandenen Konfigurationen zu sehen ist.SwitchMatrixInput
– Ähnlich wie oben, scannt jedoch eine Schaltermatrix im Tastaturstil anstelle einzelner Schalter. Eine Konfiguration für Cranes Modell C<=53 ist unter config/c53/config.cpp
enthalten und dient als Beispiel für die Definition und Verwendung einer Schaltmatrix-Eingabequelle.NunchukInput
– Liest Eingaben von einem Wii-Nunchuk mit i2c. Dies kann für gemischte Eingabesteuerungen verwendet werden (z. B. verwendet die linke Hand einen Nunchuk für Bewegungen und die rechte Hand verwendet Tasten für andere Steuerungen).GamecubeControllerInput
– Ähnlich wie oben, liest jedoch von einem GameCube-Controller. Kann ähnlich wie GamecubeBackend instanziiert werden. Derzeit nur für Pico implementiert, und Sie müssen es entweder auf einer anderen PIO-Instanz (pio0 oder pio1) als alle Instanzen von GamecubeBackend ausführen oder sicherstellen, dass beide den gleichen PIO-Befehlsspeicheroffset verwenden. Jede Eingabequelle verfügt über einen Wert für die „Scan-Geschwindigkeit“, der ungefähr angibt, wie lange es dauert, Eingaben zu lesen. Schnelle Eingabequellen werden immer im letztmöglichen Moment gelesen (zumindest auf Pico), was zu einer sehr geringen Latenz führt. Umgekehrt werden langsame Eingabequellen typischerweise ziemlich lange vor ihrem Bedarf gelesen, da sie zu langsam sind, um als Reaktion auf eine Abfrage gelesen zu werden. Aus diesem Grund ist es idealer, diese Eingaben ständig auf einem separaten Kern zu lesen. Dies ist bei AVR-MCUs nicht möglich, da sie alle Single-Core-MCUs sind, aber beim Pico/RP2040 ist es möglich (und einfach). Das Ende der standardmäßigen Pico-Konfiguration config/pico/config.cpp
veranschaulicht dies, indem core1 zum Lesen von Nunchuk-Eingaben verwendet wird, während core0 alles andere übernimmt. Weitere Informationen zur Verwendung von core1 finden Sie im nächsten Abschnitt.
In setup()
Funktion jeder Konfiguration erstellen wir ein Array von Eingabequellen und übergeben es dann an ein Kommunikations-Backend. Das Kommunikations-Backend entscheidet, wann welche Eingabequellen gelesen werden, da Eingaben für verschiedene Backends zu unterschiedlichen Zeitpunkten gelesen werden müssen. Wir bauen auch eine Reihe von Kommunikations-Backends auf, sodass mehr als ein Backend gleichzeitig verwendet werden kann. Beispielsweise wird in den meisten Konfigurationen das B0XX-Eingabe-Viewer-Backend als sekundäres Backend verwendet, wenn das DInput-Backend verwendet wird. In jeder Iteration weist die Hauptschleife jedes Backend an, seine jeweiligen Berichte zu senden. In Zukunft könnte es mehr Backends für Dinge wie das Schreiben von Informationen auf ein OLED-Display geben.
In jeder Konfiguration gibt es die Funktionen setup()
und loop()
, wobei setup()
zuerst ausgeführt wird und dann loop()
wiederholt ausgeführt wird, bis das Gerät ausgeschaltet wird.
Auf Pico/RP2040 werden die Funktionen setup()
und loop()
auf core0 ausgeführt, und Sie können die Funktionen setup1()
und loop1()
hinzufügen, um Aufgaben auf core1 auszuführen.
So lesen Sie beispielsweise GameCube-Controller-Eingaben auf core1:
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());
}
}
Die while
-Schleife stellt sicher, dass wir warten, bis setup()
auf core0 die Einrichtung der Kommunikations-Backends abgeschlossen hat. Anschließend erstellen wir eine GameCube-Controller-Eingabequelle mit einer Abfragerate von 2500 Hz. Wir führen es auch auf pio1
aus, um eine Beeinträchtigung von GameCube/N64-Backends zu vermeiden, die pio0
verwenden, sofern nicht anders angegeben. In loop1()
gehen wir davon aus, dass das primäre Backend das erste Element des backends
Arrays ist (das ohnehin in derselben Datei konfiguriert ist, wir gehen also nicht wirklich davon aus, dass wir nichts wissen) und scannen direkt den GameCube-Controller Eingaben in den Eingabestatus des Backends.
Als etwas verrückteres hypothetisches Beispiel könnte man sogar alle Steuerungen für einen Zwei-Personen-Arcade-Schrank mit einem einzigen Pico betreiben, indem man zwei Schaltmatrix-Eingangsquellen mit beispielsweise jeweils 10 Pins und zwei GameCube-Backends erstellt, beide auf separaten Kernen. Die Möglichkeiten sind endlos.
Wenn Sie einen offiziellen Adapter mit einem Arduino-basierten Controller verwenden, müssen Sie wahrscheinlich A im Plugin gedrückt halten, wodurch die Polling-Latenzoptimierung deaktiviert wird, indem eine Polling-Rate von 0 an den GamecubeBackend-Konstruktor übergeben wird.
Wenn Sie einen Arduino-basierten Controller ohne Boost-Schaltung verwenden, benötigen Sie eine 5-V-Stromversorgung. Für den Mayflash-Adapter müssen also beide USB-Kabel eingesteckt sein und auf der Konsole muss die Rumpelleitung intakt sein. Pico arbeitet nativ mit 3,3 V Strom, daher stellt dies kein Problem dar.
Ich freue mich über Beiträge und wenn Sie einen Eingabemodus erstellen, den Sie teilen möchten, können Sie gerne eine Pull-Anfrage stellen. Bitte installieren Sie das Clang-Format-Plugin für VS Code und formatieren Sie damit den Code, den Sie hinzufügen möchten.
Wir verwenden SemVer zur Versionierung. Die verfügbaren Versionen finden Sie in den Tags in diesem Repository.
Siehe auch die Liste der Mitwirkenden, die an diesem Projekt teilgenommen haben.
Dieses Projekt ist unter der GNU GPL Version 3 lizenziert – Einzelheiten finden Sie in der LIZENZ-Datei