HayBox est un micrologiciel modulaire multiplateforme pour les contrôleurs numériques ou mixtes analogiques/numériques, principalement destiné aux contrôleurs de style B0XX.
Les fonctionnalités incluent :
Si vous souhaitez simplement utiliser un micrologiciel prédéfini avec des mappages de broches et une configuration par défaut, reportez-vous à la section sur les binaires prédéfinis. Si vous souhaitez apporter des modifications au code, reportez-vous à la section Création à partir des sources.
.uf2
), mettez-la simplement en mode bootsel tout en la branchant sur votre PC, puis faites glisser et déposez le fichier .uf2
sur le lecteur RPI-RP2 qui apparaît..hex
), vous pouvez utiliser un programme comme QMK Toolbox pour y flasher le fichier .hex
Il existe actuellement trois manières principales de construire HayBox :
Les actions GitHub et les espaces de codes GitHub nécessitent que vous créiez un compte GitHub, mais ne nécessitent pas que vous installiez des dépendances sur votre ordinateur local.
Les dépendances suivantes sont requises lors de la construction locale :
Après avoir installé toutes les exigences, téléchargez et extrayez la dernière version de HayBox, ou clonez le référentiel si git est installé (ce qui facilite l'extraction des mises à jour).
Après cela:
git config --global core.longpaths true
dans n'importe quel terminal (dans VS Code ou cmd/PowerShell normal, tout va bien)config/<environment>/config.cpp
). Tous les boutons que votre contrôleur ne possède pas peuvent simplement être supprimés de la liste.HayBox/.pio/build/<environment>/firmware.uf2
sur le RPI -Lecteur RP2 qui apparaît.C'est probablement le moyen le plus pratique de modifier et de reconstruire HayBox, mais gardez à l'esprit que le niveau gratuit de GitHub impose certaines limitations sur la quantité que vous pouvez utiliser les Codespaces chaque mois. Pour cette raison, vous devez vous assurer de fermer vos espaces de codes lorsque vous ne les utilisez pas, afin de maximiser ce que vous pouvez obtenir de votre quota.
Tout d'abord, créez un compte GitHub ou connectez-vous simplement si vous en avez déjà un, puis forkez ce référentiel et ouvrez votre fork dans un nouvel espace de code en cliquant sur le bouton vert Code -> Codespaces -> Créer un espace de code sur master. Cela devrait ouvrir VS Code dans votre navigateur avec toutes les extensions et dépendances nécessaires préinstallées. À partir de là, le processus est sensiblement le même que celui de la construction locale, sauf que vous ne pouvez pas utiliser le bouton Télécharger pour flasher le micrologiciel. Vous devrez plutôt télécharger le binaire compilé depuis HayBox/.pio/build/<environment>/
et le flasher manuellement (voir ici pour en savoir plus).
Ce référentiel contient une définition de flux de travail GitHub Actions qui crée chaque environnement PlatformIO spécifié dans la matrice à chaque poussée et télécharge les binaires du micrologiciel en tant qu'artefacts que vous pouvez télécharger en cliquant sur un flux de travail spécifique exécuté à partir de l'historique. Vous pouvez créer un fork de ce référentiel et activer les actions en cliquant sur Paramètres -> Actions -> Général -> Sélectionnez « Autoriser toutes les actions et flux de travail réutilisables » -> Enregistrer.
Le moyen le plus rapide d'apporter des modifications si vous souhaitez uniquement créer via GitHub Actions est d'utiliser github.dev. Vous pouvez le faire en appuyant simplement sur .
sur votre clavier pendant que votre fork de ce référentiel est ouvert, et cela ouvrira un éditeur VS Code dans votre navigateur. Cela ne vous offre pas les mêmes capacités de développement que celles que vous obtiendriez dans un Codespace, mais cela vous permet d'apporter des modifications et de les valider directement depuis votre navigateur. Modifiez ce que vous souhaitez, puis utilisez l'onglet Contrôle de source sur la gauche pour ajouter, valider et appliquer vos modifications. Enfin, revenez au référentiel et cliquez sur l'onglet Actions, cliquez sur votre exécution de workflow et attendez qu'il génère l'artefact.
Si vous ajoutez un nouvel environnement de configuration de périphérique/PlatformIO, vous devrez ajouter l'environnement à la matrice pour qu'il soit construit par le workflow GitHub Actions. Vous pouvez également supprimer de la matrice tous les environnements qui ne vous intéressent pas afin de réduire l'utilisation des ressources et potentiellement d'accélérer vos builds.
Pour redémarrer les contrôleurs basés sur Pico en mode bootsel, maintenez Démarrer sur le plugin.
Pour passer en mode carte Brook sur GCCPCB2, GCCMX, B0XX R2 ou LBX, maintenez B sur le plugin.
Les backends de communication sont sélectionnés légèrement différemment selon le type de microcontrôleur utilisé dans le contrôleur.
Sur Pico/RP2040, USB vs GameCube vs Nintendo 64 est détecté automatiquement. S'il n'est pas branché sur une console, la valeur par défaut est XInput , qui devrait fonctionner en plug-and-play avec la plupart des jeux PC. Les autres backends sont sélectionnés en maintenant enfoncé l'un des boutons suivants sur le plugin :
Sur Arduino/AVR, le backend DInput est sélectionné si une connexion USB est détectée. Sinon, la valeur par défaut est le backend GameCube, à moins qu'un autre backend ne soit sélectionné manuellement en maintenant enfoncé l'un des boutons suivants du plugin :
Contrairement à d'autres firmwares similaires, HayBox vous permet par défaut de changer de mode à la volée sans débrancher votre contrôleur. Ceci est principalement utile sur PC, par opposition à la console où vous devez généralement redémarrer la console pour changer de jeu. Il sert également à réduire le nombre de boutons que vous devez tenir d’une seule main lors du branchement.
Les combinaisons de boutons du mode contrôleur par défaut sont :
Combinaisons de boutons du mode clavier par défaut (disponibles uniquement lors de l'utilisation du backend DInput, pas avec XInput) :
HayBox a besoin d'un profil de contrôleur Dolphin différent de celui du micrologiciel officiel B0XX, car il utilise différents mappages DInput qui sont plus logiques pour une utilisation sur plusieurs jeux. Ceux-ci peuvent être trouvés dans le dossier dolphin
du dépôt HayBox. Les fichiers de profil sont nommés pour indiquer à quel backend de communication et système d'exploitation ils sont destinés :
Pour installer le profil :
dolphin
dans HayBox vers le dossier <YourDolphinInstallation>UserConfigProfilesGCPad
(créez-le s'il n'existe pas).%appdata%Slippi LaunchernetplayUserConfigProfilesGCPad
~/.config/SlippiOnline/Config/Profiles/GCPad/
Cmd + Shift + G
et entrez le chemin /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 ne prend en charge que DInput (et pas très bien), donc si vous utilisez un contrôleur basé sur Pico/RP2040, vous devrez forcer le mode DInput en maintenant Z sur le plugin, et même dans ce cas, cela risque de ne pas fonctionner. Je ne peux vraiment rien faire contre la mauvaise prise en charge des contrôleurs d'Apple (qu'ils semblent rompre avec toutes les autres mises à jour) et je ne possède aucun appareil Apple, donc cela sera également considéré comme une utilisation non prise en charge de HayBox.
Le backend de communication (par exemple DInput, GameCube ou N64) est sélectionné en partie par détection automatique et en partie en fonction des boutons maintenus sur le plugin. Ceci est géré dans config/<environment>/config.cpp
, dans la fonction setup()
. La logique est assez simple, et même si vous n'avez pas d'expérience en programmation, cela ne devrait pas être trop difficile de voir ce qui se passe et de changer les choses si vous le souhaitez.
Les dossiers de configuration correspondant aux environnements Arduino sont :
config/arduino_nativeusb/
pour Arduino avec support USB natif (par exemple Leonardo, Micro)config/arduino/
pour Arduino sans support USB natif (par exemple Uno, Nano, Mega 2560) Pour les configurations de périphériques Arduino, vous remarquerez peut-être que le numéro 125 est transmis à GamecubeBackend()
. Cela vous permet de modifier le taux d'interrogation, par exemple si votre bricolage ne prend pas en charge l'USB natif et que vous souhaitez l'utiliser avec un adaptateur de contrôleur GameCube overclocké. Dans cet exemple, vous pouvez passer 1 000 pour synchroniser jusqu'au taux d'interrogation de 1 000 Hz, ou 0 pour désactiver complètement cette correction du décalage. Le taux d'interrogation peut être transmis au constructeur N64Backend de la même manière.
Vous remarquerez peut-être que le taux d'interrogation de 1 000 Hz fonctionne également sur la console. Sachez que même si cela fonctionne, cela entraînera un décalage d'entrée plus important. Le but de définir le taux d'interrogation ici est que le backend GameCube puisse attendre juste avant le prochain sondage avant de lire les entrées, afin que les entrées soient récentes et non obsolètes.
Pour Pico/RP2040, il n'est pas nécessaire de transmettre un taux d'interrogation de la console, car le Pico a suffisamment de puissance de traitement pour lire/traiter les entrées après avoir reçu l'interrogation de la console, il n'est donc pas nécessaire de prédire quand l'interrogation arrivera et de préparer les choses. à l'avance.
Pour configurer les maintiens des boutons pour les modes de saisie (modes contrôleur/clavier), modifiez la fonction select_mode()
dans config/mode_selection.hpp
. Chaque instruction if
est une combinaison de boutons pour sélectionner un mode de saisie.
La plupart des modes d'entrée prennent en charge le passage en mode de nettoyage SOCD, par exemple socd::2IP_NO_REAC
. Voir ici pour les autres modes disponibles.
Pour créer de nouveaux modes de saisie, il est utile de connaître un peu le C++, ou au moins d'avoir une certaine expérience en programmation. Cela dit, vous devriez pouvoir vous en sortir même sans expérience préalable si vous basez simplement votre nouveau mode sur ceux existants et vous y référez comme exemples.
Il existe deux types de modes de saisie : ControllerMode et KeyboardMode
Les modes clavier sont un peu plus simples, alors commençons par là.
Un KeyboardMode se comporte comme un clavier standard et devrait fonctionner avec tout appareil prenant en charge les claviers.
Vous êtes libre d'utiliser les astuces de logique et de programmation de votre choix dans la fonction UpdateKeys()
pour décider des sorties en fonction de l'état d'entrée. Vous pouvez créer des calques d'entrée (comme le calque D-Pad en mode Mêlée qui est activé lorsque vous maintenez Mod X et Mod Y) ou d'autres types d'entrées conditionnelles.
La liste des codes clés disponibles peut être trouvée ici.
N'oubliez pas que les modes clavier ne peuvent être activés que lors de l'utilisation du backend de communication DInput ( et non de XInput).
Un ControllerMode prend un état d’entrée de bouton numérique et le transforme en un état de sortie correspondant à une manette de jeu standard. N’importe quel ControllerMode fonctionnera avec n’importe quel CommunicationBackend. Un CommunicationBackend lit simplement les entrées d'une ou plusieurs sources d'entrée, utilise le ControllerMode actuel pour mettre à jour les sorties en fonction de ces entrées et gère l'envoi des sorties à la console ou au PC.
Pour créer un ControllerMode, il vous suffit d'implémenter les fonctions UpdateDigitalOutputs()
et UpdateAnalogOutputs()
.
UpdateDigitalOutputs()
est très similaire à la fonction UpdateKeys()
dans les modes clavier, à la différence qu'au lieu d'appeler une fonction Press()
pour envoyer immédiatement des entrées, nous définissons simplement l'état de sortie pour cette itération. Comme son nom l'indique, nous ne traiterons que les sorties numériques dans cette fonction.
UpdateAnalogOutputs()
est un peu plus compliqué. Premièrement, il doit appeler UpdateDirections()
avant de faire autre chose. Cette fonction prend des valeurs indiquant si vos sticks gauche et droit pointent vers la gauche/droite/haut/bas. Vous transmettez également les valeurs analogiques minimales, neutres (au centre) et maximales du stick, afin que vous puissiez les configurer par mode. Toutes ces informations sont utilisées pour définir automatiquement les valeurs analogiques du stick en fonction des entrées que vous avez transmises. C'est tout ce que vous devez faire, sauf si vous souhaitez implémenter des modificateurs.
UpdateDirections()
remplit également les directions
variables avec des valeurs indiquant la direction actuelle du stick, qui peut être 1, 0 ou -1 pour les axes X et Y des deux sticks. Ces valeurs facilitent grandement l'écriture de la logique du modificateur.
Après avoir appelé UpdateDirections()
, ajoutez la logique de gestion des modificateurs de votre choix. N'oubliez pas que UpdateDirections()
définit déjà les valeurs par défaut du stick analogique, donc lors de la gestion des modificateurs, il vous suffit de définir manuellement les valeurs des axes qui sont réellement modifiés. En dehors de cela, je ne peux pas vous apprendre à écrire votre logique de modificateur, alors regardez simplement les exemples et jouez.
Enfin, définissez les valeurs de déclenchement analogiques dont vous avez besoin.
Remarque : les sorties de déclenchement analogiques pourraient tout aussi bien être gérées dans UpdateDigitalOutputs()
, mais je pense qu'il semble généralement plus propre de les conserver avec les autres sorties analogiques.
Notez également : vous n'avez pas à vous soucier de réinitialiser l'état de sortie ou d'en effacer quoi que ce soit. Cela se fait automatiquement au début de chaque itération.
Dans le constructeur de chaque mode (pour les modes contrôleur et les modes clavier), vous pouvez configurer des paires d'entrées de sens opposés auxquelles appliquer le nettoyage SOCD.
Par exemple, dans 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},
};
Cela configure gauche/droite, bas/haut, C-Gauche/C-Droite et C-Bas/C-Haut comme des paires de directions cardinales opposées pour lesquelles le nettoyage SOCD sera appliqué. Le nettoyage SOCD est automatiquement effectué avant UpdateDigitalOutputs()
et UpdateAnalogOutputs()
, et vous n'avez pas à vous en préoccuper davantage.
Pour chaque SocdPair
vous pouvez transmettre un SocdType
de votre choix. Par défaut, pour la plupart des modes, cela est transmis sous la forme d'un seul paramètre de constructeur, mais il est possible de transmettre plusieurs paramètres ou simplement d'utiliser une valeur codée en dur. Ces deux approches sont illustrées dans src/modes/FgcMode.cpp
.
SocdType | Description |
---|---|
SOCD_NEUTRAL | Gauche + droite = neutre - la valeur par défaut si aucun SocdType n'est spécifié dans SocdPair |
SOCD_2IP | Deuxième priorité d'entrée - gauche -> gauche + droite = droite, et vice versa. Relâcher la deuxième direction donne la direction d'origine |
SOCD_2IP_NO_REAC | Deuxième priorité d'entrée sans réactivation - comme ci-dessus, sauf que le relâchement de la deuxième direction entraîne le neutre. La direction originale doit être physiquement réactualisée. |
SOCD_DIR1_PRIORITY | Le premier bouton du SocdPair est toujours prioritaire sur le second |
SOCD_DIR2_PRIORITY | Le deuxième bouton du SocdPair est toujours prioritaire sur le premier |
SOCD_NONE | Pas de résolution SOCD - le jeu décide |
Notez que vous n'avez pas besoin d'implémenter une fonction HandleSocd()
comme dans les modes Melee20Button et Melee18Button. Il est uniquement remplacé dans ces modes afin que nous puissions vérifier si la gauche et la droite sont toutes deux maintenues avant le nettoyage SOCD, car lorsqu'elles sont toutes les deux maintenues (sans qu'une direction verticale soit maintenue), nous devons remplacer tous les modificateurs.
Si votre contrôleur n'a pas de boutons de protection contre la lumière, vous souhaiterez peut-être utiliser le Mod X pour le protection contre la lumière et mettre l'inclinaison du bouclier sur R à la place. Vous pouvez le faire en utilisant le mode Melee18Button au lieu de Melee20Button.
Les modes Melee20Button et Melee18Button offrent le choix des coordonnées à utiliser lorsque vous appuyez sur bas + droite. Par défaut, maintenir enfoncé + retour vous permettra d'effectuer des annulations automatiques de jab, ce qui est une technique utile pour certains personnages.
Une autre technique populaire qui utilise la diagonale bas + droite est ce que l'on appelle la sélection d'options accroupie/marche. Cette technique consiste à maintenir + en avant à un certain angle tout en s'accroupissant, de sorte qu'après avoir annulé une attaque, vous commencerez automatiquement à marcher vers votre adversaire au lieu de vous accroupir. Cela peut être très utile pour la chasse technique, mais les coordonnées utilisées pour cette technique ne vous permettent pas d'annuler automatiquement le jab.
Cela peut être configuré comme indiqué dans config/mode_selection.hpp
en définissant l'option crouch_walk_os
sur true :
new Melee20Button(socd::SOCD_2IP_NO_REAC, { .crouch_walk_os = false })
Vous devrez également modifier cela dans votre config/<environment>/config.cpp
pour qu'il soit appliqué sur le plugin, car mode_selection.hpp
contrôle uniquement ce qui se passe lorsque vous changez de mode.
Le mode ProjectM dispose de quelques options supplémentaires pour configurer certains comportements. Comme on le voit dans config/mode_selection.hpp
:
new ProjectM(
socd::SOCD_2IP_NO_REAC,
{ .true_z_press = false, .ledgedash_max_jump_traj = true }
)
Premièrement, l'option ledgedash_max_jump_traj
vous permet d'activer ou de désactiver le comportement emprunté au mode Mêlée où maintenir la gauche et la droite (et aucune direction verticale) donnera un cardinal de 1,0 quels que soient les modificateurs maintenus.
Si vous changez le mode SOCD en 2IP (avec réactivation), vous devez également changer cette option sur false si vous souhaitez une expérience de jeu fluide.
Deuxièmement, l'option true_z_press
existe car Project M/Project+ ne gère pas les presses Z de la même manière que Melee. La mêlée interprète une pression sur Z comme un bouclier lumineux + A, et peut donc être utilisée pour annuler L sans vous exclure des technologies. En PM/P+, une pression sur Z déclenchera une technologie et provoquera ainsi des verrouillages technologiques indésirables si elle est utilisée pour annuler L. Par défaut dans HayBox, le mode ProjectM est configuré pour utiliser une macro de lightshield + A afin de préserver le comportement attendu de Melee. Cependant, cette macro ne vous permet pas d'utiliser des attaques d'attache/grappin ou de récupérer des objets. Pour contourner ce problème, vous pouvez appuyer sur Mod X + Z pour envoyer une véritable entrée Z.
Si cela vous dérange et que vous souhaitez simplement envoyer une entrée true Z par défaut lorsque vous appuyez sur Z, vous pouvez définir l'option true_z_press
sur true.
HayBox prend en charge plusieurs sources d'entrée qui peuvent être lues pour mettre à jour l'état d'entrée :
GpioButtonInput
- Le plus couramment utilisé, pour lire les commutateurs/boutons connectés directement aux broches GPIO. Les mappages d'entrée sont définis par un tableau de GpioButtonMapping
comme on peut le voir dans presque toutes les configurations existantes.SwitchMatrixInput
- Similaire à ce qui précède, mais analyse une matrice de commutateurs de style clavier au lieu de commutateurs individuels. Une configuration pour le modèle C<=53 de Crane est incluse dans config/c53/config.cpp
qui sert d'exemple sur la façon de définir et d'utiliser une source d'entrée de matrice de commutation.NunchukInput
- Lit les entrées d'un Wii Nunchuk à l'aide d'i2c. Cela peut être utilisé pour les contrôleurs à entrées mixtes (par exemple, la main gauche utilise un Nunchuk pour le mouvement et la main droite utilise des boutons pour d'autres commandes)GamecubeControllerInput
- Similaire à ce qui précède, mais lit à partir d'un contrôleur GameCube. Peut être instancié de la même manière que GamecubeBackend. Actuellement implémenté uniquement pour Pico, et vous devez soit l'exécuter sur une instance pio différente (pio0 ou pio1) que toutes les instances de GamecubeBackend, soit vous assurer que les deux utilisent le même décalage de mémoire d'instruction PIO. Chaque source d'entrée a une valeur de « vitesse de balayage » qui indique approximativement le temps qu'il lui faut pour lire les entrées. Les sources d'entrée rapides sont toujours lues au dernier moment possible (au moins sur Pico), ce qui entraîne une latence très faible. À l’inverse, les sources d’entrée lentes sont généralement lues assez longtemps avant d’être nécessaires, car elles sont trop lentes pour être lues en réponse à une interrogation. Pour cette raison, il est plus idéal de lire constamment ces entrées sur un noyau séparé. Cela n'est pas possible sur les MCU AVR car ils sont tous monocœur, mais c'est possible (et facile) sur le Pico/RP2040. Le bas de la configuration Pico par défaut config/pico/config.cpp
illustre cela en utilisant core1 pour lire les entrées Nunchuk tandis que core0 gère tout le reste. Consultez la section suivante pour plus d’informations sur l’utilisation de core1.
Dans la fonction setup()
de chaque configuration, nous construisons un tableau de sources d'entrée, puis le transmettons à un backend de communication. Le backend de communication décide quand lire quelles sources d’entrée, car les entrées doivent être lues à différents moments pour différents backends. Nous construisons également une gamme de backends de communication, permettant d’utiliser plusieurs backends à la fois. Par exemple, dans la plupart des configurations, le backend du visualiseur d'entrée B0XX est utilisé comme backend secondaire chaque fois que le backend DInput est utilisé. À chaque itération, la boucle principale indique à chacun des backends d'envoyer leurs rapports respectifs. À l’avenir, il pourrait y avoir davantage de backends pour des choses comme l’écriture d’informations sur un écran OLED.
Dans chaque configuration, il y a les fonctions setup()
et loop()
, où setup()
s'exécute en premier, puis loop()
s'exécute à plusieurs reprises jusqu'à ce que l'appareil soit éteint.
Sur Pico/RP2040, les fonctions setup()
et loop()
s'exécutent sur core0, et vous pouvez ajouter les fonctions setup1()
et loop1()
afin d'exécuter des tâches sur core1.
Par exemple, pour lire les entrées du contrôleur GameCube sur 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());
}
}
La boucle while
garantit que nous attendons que setup()
sur core0 ait fini de configurer les backends de communication. Nous créons ensuite une source d’entrée pour le contrôleur GameCube avec un taux d’interrogation de 2 500 Hz. Nous l'exécutons également sur pio1
comme moyen simple d'éviter d'interférer avec les backends GameCube/N64, qui utilisent pio0
sauf indication contraire. Dans loop1()
nous supposons que le backend principal est le premier élément du tableau backends
(qui est de toute façon configuré dans le même fichier, donc nous ne supposons pas vraiment quelque chose que nous ne savons pas) et analysons directement le contrôleur GameCube. entrées dans l’état d’entrée du backend.
À titre d'exemple hypothétique un peu plus fou, on pourrait même alimenter toutes les commandes d'une borne d'arcade pour deux personnes en utilisant un seul Pico en créant deux sources d'entrée à matrice de commutation utilisant, disons, 10 broches chacune, et deux backends GameCube, tous deux sur des cœurs séparés. Les possibilités sont infinies.
Si vous utilisez un adaptateur officiel avec un contrôleur basé sur Arduino, vous devrez probablement maintenir A sur le plugin qui désactive l'optimisation de la latence d'interrogation en transmettant un taux d'interrogation de 0 au constructeur GamecubeBackend.
Si vous utilisez un contrôleur basé sur Arduino sans circuit boost, vous aurez besoin d'une alimentation de 5 V, donc pour l'adaptateur Mayflash, vous avez besoin des deux câbles USB branchés, et sur la console, la ligne de grondement doit être intacte. Pico fonctionne nativement avec une alimentation de 3,3 V, ce n'est donc pas un problème.
J'apprécie les contributions et si vous créez un mode de saisie que vous souhaitez partager, n'hésitez pas à faire une pull request. Veuillez installer le plugin au format clang pour VS Code et utilisez-le pour formater tout code que vous souhaitez ajouter.
Nous utilisons SemVer pour le versioning. Pour les versions disponibles, voir les balises sur ce référentiel.
Voir aussi la liste des contributeurs ayant participé à ce projet.
Ce projet est sous licence GNU GPL version 3 - voir le fichier LICENSE pour plus de détails