Table des matières
sm64coopdx-switch-N3DS : Isoler un port derrière les interfaces de plateforme
Ce fork explore les cibles Switch et New 3DS de sm64coopdx. Le code commun du jeu et de la coopération repose sur des couches graphiques, audio et d’entrée propres aux plateformes. La sonde de plateforme a un périmètre plus étroit que le jeu complet.
- Langages
- 13Répartition du code
- Composants documentés
- 2Explorer les modules
- Documents source
- 6Lire les instructions
Langages du dépôtC 82.89%13
Parts calculées à partir des octets GitHub Linguist.
| Langage | % | Octets |
|---|---|---|
| C | 26 541 138 | |
| C++ | 3 478 712 | |
| Lua | 1 281 479 | |
| Python | 460 864 | |
| Assembly | 156 333 | |
| Shell | 42 404 |
7 autres langages
| Pawn | 0.11% | 34 727 |
| Go Template | 0.04% | 11 678 |
| Makefile | 0.03% | 9 211 |
| Dockerfile | 0% | 1 534 |
| Linker Script | 0% | 257 |
| PHP | 0% | 200 |
| BitBake | 0% | 59 |
1. Aperçu
1.1. Pourquoi il existe
Portage système en C bas niveau optimisant le réseau multithread et la mémoire pour consoles portables.
1.2. Cas d’usage
Jeu multijoueur coopératif portable sur consoles Switch et New 3DS.
2. Cas d’utilisation
Portage homebrew non officiel de sm64coopdx (coop en ligne) pour Switch, avec une cible New 3DS en chantier ; ROM non fournie.
- Installer avec sa propre ROM
- Joueur Switch
docs/SWITCH_INSTALL.md : extraire le ZIP à la racine de la carte SD, ajouter une ROM US sous switch/sm64coopdx/baserom.us.z64 conforme à sm64.us.sha1, puis lancer sm64coopdx.nro en mode application complète.
- Rejoindre un salon CoopNet
- Joueur SwitchSalons CoopNet
La version Switch envoie l’empreinte réelle du NRO et liste les salons de l’espace sm64coop-android, comme l’explique docs/switch.md ; le client se trouve sous src/pc/network/coopnet.
- Jouer en sans-fil local
- Joueur Switch
src/pc/network/socket/socket_ldn.c ajoute un transport sans fil local et src/pc/djui/djui_panel_ldn_browser.c liste les sessions à proximité.
- Saisir un mot de passe
- Joueur SwitchSalons CoopNet
Les mots de passe des salons privés passent par le clavier intégré au jeu (src/pc/djui/djui_panel_switch_text_entry.c) plutôt que par le clavier natif de la Switch.
- Compiler et empaqueter le NRO
- Développeur du portage
Dans l’image Docker devkitpro/devkita64, make -f Makefile.switch-sdmc SWITCH_COOPNET=1 switch-nro compile le NRO et switch-dist vérifie l’en-tête et les empreintes puis écrit le ZIP ; build-switch-game.yml exécute en CI des contrôles sans ROM.
- Compiler la cible New 3DS
- Développeur du portage
Makefile.new3ds compile une coquille de plateforme et Makefile.new3ds-game le moteur complet avec rendu Citro3D et audio NDSP ; docs/new3ds-port.md précise que le jeu n’est pas encore vérifié sur console.
2.1. Scénario : Jouer en coop en ligne depuis une Switch
- Extraire le ZIP Switch de sm64coopdx à la racine de la carte SD, ce qui crée switch/sm64coopdx/.
- Copier votre propre ROM US dans switch/sm64coopdx/baserom.us.z64.
- Maintenir R en lançant un jeu pour ouvrir le menu homebrew en mode application complète, puis lancer SM64CoopDX.
- Ouvrir le menu de connexion, choisir un salon CoopNet public et taper son mot de passe sur le clavier du jeu s’il est privé.
- En cas d’échec, lire startup.log, coopnet.log et exception.log sous switch/sm64coopdx/logs/.
Fichiers consultésREADME.mddocs/SWITCH_INSTALL.mddocs/switch.mddocs/new3ds-port.mdMakefile.switch-sdmc.github/workflows/build-switch-game.ymlsrc/pc/network/socket/socket_ldn.csrc/pc/djui/djui_panel_ldn_browser.csrc/pc/djui/djui_panel_switch_text_entry.c
3. Démarrage
Ces commandes viennent de la documentation du dépôt. Elles n’ont pas été exécutées pendant cette revue.
4. Références du dépôt
Extraits des guides du dépôt, dans leur langue d’origine. Les liens ouvrent la version du code consultée.
Prérequis et premier essai
4.1. Requirements
docs/SWITCH_INSTALL.md
- A homebrew-capable Nintendo Switch with a current Homebrew Menu setup.
- The SM64CoopDX Switch distribution ZIP.
- Your own legally obtained North American Super Mario 64 ROM matching the SHA-1 recorded in sm64.us.sha1 in the source repository. The ROM is copyrighted data and is not included in the distribution. Do not download, upload, or redistribute it.
4.2. Install
docs/SWITCH_INSTALL.md
- Shut down the Switch before removing its SD card, or use a safe USB/FTP transfer method.
- Extract the distribution ZIP directly to the root of the SD card. It creates switch/sm64coopdx/.
- Copy your ROM to switch/sm64coopdx/baserom.us.z64.
- Confirm this layout:
- Put the SD card back in the Switch and start the Homebrew Menu in full application mode. With common Atmosphere setups, hold R while launching an installed game until Homebrew Menu opens. Album/applet mode has less memory and is not recommended.
- Launch SM64CoopDX.
Exploitation et dépannage
4.3. Updating
docs/SWITCH_INSTALL.md
4.4. Troubleshooting and logs
docs/SWITCH_INSTALL.md
- If startup reports a missing or invalid ROM, verify its filename, region, and SHA-1.
- If the game freezes or runs out of memory, confirm it was launched in full application mode rather than Album/applet mode.
- Private-lobby passwords use the in-game Switch keypad; that flow should not open the native software keyboard.
- Switch public discovery uses the Android lobby list. It will not show lobbies published only in the desktop namespace.
- If a particular server rejects the Switch build, share switch-coopnet-identity.txt with that server’s operator; do not replace the genuine hash with another executable’s identity.
- Runtime diagnostics are written under switch/sm64coopdx/logs/, including startup.log, coopnet.log, checkpoints, and exception.log. When sharing diagnostics, remove lobby passwords, TURN credentials, and other private information first.
Documentation source
README.mdsound/README.mddocs/SWITCH_INSTALL.mdlib/coopnet/README.mdtools/n64graphics_ci_dir/README.mdsrc/pc/gfx/README-n64-fast32-engine.md
6 documents lus parmi 6 candidats.
5. Fonctions et composants 2
- Exécution commune et moteurs
- src/pc sépare les commandes, l’audio, le rendu, le réseau et la plateforme. Le port peut remplacer un moteur en conservant le comportement commun. Les options de compilation et makefiles déterminent les implémentations liées.
- La sonde de plateforme
- Makefile.switch-platform compile une sonde avec le cycle de vie Switch, les commandes et les journaux de crash, puis produit un NRO avec devkitPro. Sa liste de sources est plus petite que celle du jeu complet.
6. Architecture
Ouvrez un composant pour suivre ses connexions, ou explorez le diagramme complet.
Jeu et coopération communs
Interfaces de plateforme
- Depuis Jeu et coopération communs
- Vers Moteur graphique
- Vers Commandes et audio
Moteur graphique
- Depuis Interfaces de plateforme
- Vers Exécution console
Commandes et audio
- Depuis Interfaces de plateforme
- Vers Exécution console
Exécution console
- Depuis Moteur graphique
- Depuis Commandes et audio
Mermaid Diagramme interactif
Vue générale des composants et des échanges vérifiés dans le dépôt.

flowchart LR
node_player(("Player"))
subgraph group_mods["Mods and UI"]
node_lua["Lua Mod API"]
node_mod_storage[("Mod Storage<br/>[mod_storage.cpp]")]
node_djui["DJUI"]
end
subgraph group_runtime["Game Runtime"]
node_game["Game Runtime<br/>[main.c]"]
node_game_init["Game Initialization<br/>[main.c]"]
node_gameplay["Gameplay World<br/>[types.h]"]
node_render["Rendering<br/>[pc_main.h]"]
node_lighting["Lighting Engine"]
node_audio["Audio Runtime"]
end
subgraph group_multiplayer["Shared Play"]
node_network["Multiplayer Sync"]
node_coopnet["CoopNet"]
node_local_wireless["Local Wireless"]
end
subgraph group_platform["Platform I/O"]
node_config["Game Configuration<br/>[configfile.h]"]
node_controller["Controller Input<br/>[controller_sdl.c]"]
node_window["Window Manager"]
node_switch_window["Switch Backend"]
node_new3ds_window["New 3DS Backend"]
end
subgraph group_assets["Game Content"]
node_rom_assets["ROM Asset Loading<br/>[rom_assets.h]"]
node_actor_models["Character Assets<br/>[model.inc.c]"]
node_level_content["Level Content<br/>[scripts.c]"]
end
node_player -->|"provides input"| node_controller
node_game -->|"initializes"| node_game_init
node_game -.->|"updates"| node_gameplay
node_gameplay -.->|"synchronizes world"| node_network
node_network -->|"supports online play"| node_coopnet
node_network -->|"supports local play"| node_local_wireless
node_gameplay -.->|"presents"| node_render
node_render -.->|"uses lighting"| node_lighting
node_game -->|"coordinates audio"| node_audio
node_game -.->|"loads assets"| node_rom_assets
node_actor_models -->|"queues assets"| node_rom_assets
node_level_content -.->|"defines levels"| node_gameplay
node_lua -->|"reads and writes"| node_mod_storage
node_mod_storage -->|"returns values"| node_lua
node_mod_storage -.->|"uses filesystem settings"| node_config
node_controller -->|"reads bindings"| node_config
node_window -->|"dispatches keyboard events"| node_controller
group_platform --> group_runtime
group_platform --> group_mods
class node_game,node_game_init,node_gameplay,node_render,node_lighting,node_audio toneBlue
class node_network,node_coopnet,node_local_wireless toneAmber
class node_lua,node_mod_storage,node_djui toneMint
class node_config,node_controller,node_window,node_switch_window,node_new3ds_window toneRose
class node_rom_assets,node_actor_models,node_level_content,node_player toneIndigo
Un portage PC de Super Mario 64 centré sur le multijoueur en ligne, le monde partagé et les mods Lua, avec des moteurs Switch et New 3DS. Les entrées rejoignent le runtime, qui coordonne le jeu, le rendu et l’audio pendant que les adaptateurs de plateforme gèrent les images et la saisie de texte.
- Composants
- 21
- Connexions
- 23
- Liens appuyés par le code
- 13/23
Version texte du diagramme
Le diagramme regroupe les liens parallèles entre groupes : il en montre 19 sur 23. Liste complète :
- Player → Controller Input (provides input)
- Controller Input → Game Runtime (feeds controls)
- Game Runtime → Game Initialization (initializes)
- Game Runtime → Gameplay World (updates)
- Gameplay World → Multiplayer Sync (synchronizes world)
- Multiplayer Sync → CoopNet (supports online play)
- Multiplayer Sync → Local Wireless (supports local play)
- Gameplay World → Rendering (presents)
- Rendering → Lighting Engine (uses lighting)
- Game Runtime → Audio Runtime (coordinates audio)
- Game Runtime → ROM Asset Loading (loads assets)
- Character Assets → ROM Asset Loading (queues assets)
- Level Content → Gameplay World (defines levels)
- Lua Mod API → Mod Storage (reads and writes)
- Mod Storage → Lua Mod API (returns values)
- Mod Storage → Game Configuration (uses filesystem settings)
- Controller Input → Game Configuration (reads bindings)
- Controller Input → DJUI (notifies interactables)
- Window Manager → Controller Input (dispatches keyboard events)
- Switch Backend → DJUI (opens text entry)
- New 3DS Backend → DJUI (handles text entry)
- Switch Backend → Rendering (selects backend)
- New 3DS Backend → Rendering (owns frame lifecycle)
Suivre un parcours dans le code
Lisez SOURCES dans le makefile de la sonde avant d’interpréter une compilation réussie. Elle exerce certains modules, sans prouver que tous les sous-systèmes, le rendu et la coopération fonctionnent sur console.
7. Dossier technique
Établi à partir du code au commit 567fd71 (3601 fichiers). Chaque élément vient d’une correspondance de motif dans le code: ouvrez le fichier lié avant de vous y fier.
7.1. Couches et modules
Les dossiers sont classés par couche selon leur nom, de l’interface utilisateur jusqu’à l’accès aux données. Comme le classement repose sur les noms seulement, le diagramme ne dit rien des appels entre couches.
Mermaid Vue en couches
flowchart TB
subgraph L_presentation["Présentation"]
direction TB
presentation_0["assets/anims<br/>193 fichiers"]
end
subgraph L_interface["Points d’entrée et API"]
direction TB
interface_0["tools<br/>49 fichiers"]
interface_1["bin<br/>28 fichiers"]
interface_2["tools/switch<br/>16 fichiers"]
interface_3["tools/sdk-tools<br/>14 fichiers"]
interface_more["+19"]
end
subgraph L_application["Services applicatifs"]
direction TB
application_0["engine<br/>18 fichiers"]
application_1["pc/gfx<br/>2 fichiers"]
end
subgraph L_domain["Domaine et règles métier"]
direction TB
domain_0["game/behaviors<br/>226 fichiers"]
domain_1["game<br/>113 fichiers"]
domain_2["levels/castle_inside<br/>58 fichiers"]
domain_3["levels/bbh<br/>47 fichiers"]
domain_more["+170"]
end
subgraph L_infrastructure["Données et infrastructure"]
direction TB
infrastructure_0["pc/network<br/>79 fichiers"]
infrastructure_1["data<br/>55 fichiers"]
infrastructure_2["pc/platform<br/>47 fichiers"]
infrastructure_3["src<br/>19 fichiers"]
infrastructure_more["+8"]
end
subgraph L_core["Source principale"]
direction TB
core_0["pc/djui<br/>135 fichiers"]
core_1["docs/lua<br/>76 fichiers"]
core_2["levels/ttm<br/>67 fichiers"]
core_3["levels/wf<br/>67 fichiers"]
core_more["+203"]
end
subgraph L_tests["Tests"]
direction TB
tests_0["tools<br/>11 fichiers"]
end
subgraph L_hosting["Build, CI et hébergement"]
direction TB
hosting_0[".github<br/>8 fichiers"]
hosting_1["scripts<br/>5 fichiers"]
hosting_2["tools<br/>5 fichiers"]
hosting_3["(root)<br/>2 fichiers"]
hosting_more["+1"]
end
L_presentation ~~~ L_interface
L_interface ~~~ L_application
L_application ~~~ L_domain
L_domain ~~~ L_infrastructure
L_infrastructure ~~~ L_core
L_core ~~~ L_tests
L_core ~~~ L_hosting
| Module | Couche | Fichiers | Types | Extensions |
|---|---|---|---|---|
game/behaviors | Domaine et règles métier | 226 | 13 | .c |
assets/anims | Présentation | 193 | 0 | .c |
pc/djui | Source principale | 140 | 47 | .c .h |
game | Domaine et règles métier | 113 | 101 | .h .c |
levels/rr | Source principale | 99 | 0 | .c .h |
docs/lua | Source principale | 97 | 0 | .c .lua .tex |
levels/ttm | Source principale | 93 | 0 | .c .h |
levels/lll | Source principale | 90 | 0 | .c .h |
levels/wf | Source principale | 90 | 0 | .c .h |
levels/castle_inside | Domaine et règles métier | 89 | 0 | .c .h |
levels/bitfs | Source principale | 84 | 0 | .c .h |
levels/bits | Source principale | 84 | 0 | .c .h |
pc/network | Données et infrastructure | 79 | 20 | .c .h |
levels/bbh | Domaine et règles métier | 73 | 0 | .c .h |
223 modules plus petits ne sont pas affichés.
7.2. Modèle C4
Du contexte du système aux déclarations du code. Chaque niveau conserve les limites des sources disponibles.
UML 1 · Contexte du système
La vue C4 la plus large : qui utilise le projet et sur quels systèmes et stockages externes il s’appuie. Rendu avec uml-mcp.
Source PlantUML
@startuml
!include <C4/C4_Context>
LAYOUT_LEFT_RIGHT()
Person(P_cli, "Utilisateur CLI")
System(SYS, "sm64coopdx-switch-N3DS", "Ce fork explore les cibles Switch et New 3DS de sm64coopdx")
System_Ext(E0, "Portail de données ouvertes (…")
Rel(P_cli, SYS, "Utilise")
Rel(SYS, E0, "Appelle")
@enduml
UML 2 · Conteneurs
Un niveau plus près : les parties qui s’exécutent séparément dans le projet, leur langage principal et le chemin des appels entre elles. Rendu avec uml-mcp.
Source PlantUML
@startuml
!include <C4/C4_Container>
LAYOUT_LEFT_RIGHT()
Person(P_cli, "Utilisateur CLI")
System_Boundary(SYS, "sm64coopdx-switch-N3DS") {
Container(C0, "new3ds-shell", "Docker")
Container(C1, "new3ds-integration", "Docker")
Container(C2, "new3ds-full-3dsx", "Docker")
Container(C3, "switch-portability", "Docker")
Container(C4, "switch-full-nro", "Docker")
}
System_Ext(E0, "Portail de données ouvertes (…")
Rel(P_cli, C0, "Utilise")
Rel(C0, E0, "Appelle")
@enduml
UML 3 · Composants et couches
Modules regroupés par couche du code. Les limites indiquent l’organisation, sans affirmer une isolation à l’exécution ni des appels. Rendu avec uml-mcp.
Source PlantUML
@startuml
!include <C4/C4_Component>
LAYOUT_TOP_DOWN()
System_Boundary(SYS, "sm64coopdx-switch-N3DS") {
Boundary(L0, "Présentation", "layer") {
Component(M0_0, "assets/anims", "C", "193 fichiers")
}
Boundary(L1, "Points d’entrée et API", "layer") {
Component(M1_0, "tools", "Python, C, .sh", "49 fichiers")
Component(M1_1, "bin", "C", "28 fichiers")
Component(M1_2, "tools/switch", "Python, C, .sh", "16 fichiers")
Component(M1_3, "tools/sdk-tools", "C, C/C++", "14 fichiers")
Component(M1_4, "docs/lua", ".lua", "12 fichiers")
Component(M1_5, "tools/new3ds", ".sh, Python, C/C++", "10 fichiers")
Component(M1_6, "tools/ido5.3_recomp", "C/C++, C, C++", "6 fichiers")
Component(M1_7, "tools/n64graphics_ci_dir", "C, C/C++", "6 fichiers")
Component(M1_more, "+15 modules", "", "")
}
Boundary(L2, "Services applicatifs", "layer") {
Component(M2_0, "engine", "C/C++, C, C++", "18 fichiers")
Component(M2_1, "pc/gfx", "C, C/C++", "2 fichiers")
}
Boundary(L3, "Domaine et règles métier", "layer") {
Component(M3_0, "game/behaviors", "C", "226 fichiers")
Component(M3_1, "game", "C/C++, C", "113 fichiers")
Component(M3_2, "levels/castle_inside", "C", "58 fichiers")
Component(M3_3, "levels/bbh", "C", "47 fichiers")
Component(M3_4, "levels/hmc", "C", "39 fichiers")
Component(M3_5, "levels/lll", "C", "35 fichiers")
Component(M3_6, "levels/rr", "C", "35 fichiers")
Component(M3_7, "levels/bits", "C", "32 fichiers")
Component(M3_more, "+166 modules", "", "")
}
Boundary(L4, "Données et infrastructure", "layer") {
Component(M4_0, "pc/network", "C, C/C++", "79 fichiers")
Component(M4_1, "data", "C++, C/C++, C", "55 fichiers")
Component(M4_2, "pc/platform", "C, C/C++", "47 fichiers")
Component(M4_3, "src", "C, C/C++", "19 fichiers")
Component(M4_4, "lua/include", "C/C++, C++", "5 fichiers")
Component(M4_5, "pc/mods", "C/C++, C, C++", "4 fichiers")
Component(M4_6, "docs/lua", "C, .lua", "2 fichiers")
Component(M4_7, "pc/djui", "C, C/C++", "2 fichiers")
Component(M4_more, "+4 modules", "", "")
}
Boundary(L5, "Source principale", "layer") {
Component(M5_0, "pc/djui", "C, C/C++", "135 fichiers")
Component(M5_1, "levels/ttm", "C, C/C++", "67 fichiers")
Component(M5_2, "levels/wf", "C, C/C++", "67 fichiers")
Component(M5_3, "actors", "C, C/C++", "66 fichiers")
Component(M5_4, "docs/lua", "C, .lua, C/C++", "64 fichiers")
Component(M5_5, "levels/rr", "C, C/C++", "64 fichiers")
Component(M5_6, "levels/lll", "C, C/C++", "55 fichiers")
Component(M5_7, "levels/bitfs", "C, C/C++", "53 fichiers")
Component(M5_more, "+198 modules", "", "")
}
Boundary(L6, "Tests", "layer") {
Component(M6_0, "tools", "Python, C, C++", "11 fichiers")
}
Boundary(L7, "Build, CI et hébergement", "layer") {
Component(M7_0, ".github", ".yml, .md, .yaml", "8 fichiers")
Component(M7_1, "scripts", ".sh", "5 fichiers")
Component(M7_2, "tools", "Makefile", "5 fichiers")
Component(M7_3, "(root)", "Dockerfile, Makefile", "2 fichiers")
Component(M7_4, "docker", "Dockerfile", "2 fichiers")
}
}
@enduml
UML 4 · Code
Déclarations, champs et méthodes sélectionnés, regroupés par fichier source. Aucun héritage ni appel n’est déduit. Rendu avec uml-mcp.
Source PlantUML
@startuml
skinparam backgroundColor transparent
skinparam shadowing false
skinparam roundCorner 10
skinparam defaultFontName Arial
skinparam defaultFontSize 13
skinparam ArrowColor #4e6070
skinparam ArrowFontColor #3d4f5f
skinparam titleFontSize 14
skinparam actorBorderColor #006a62
skinparam actorBackgroundColor #e9f3f4
skinparam usecaseBorderColor #006a62
skinparam usecaseBackgroundColor #e9f3f4
skinparam componentBorderColor #006a62
skinparam componentBackgroundColor #e9f3f4
skinparam interfaceBorderColor #006a62
skinparam interfaceBackgroundColor #ffffff
skinparam nodeBorderColor #4e6070
skinparam nodeBackgroundColor #f4f8fb
skinparam databaseBorderColor #006a62
skinparam databaseBackgroundColor #ffffff
skinparam cloudBorderColor #4e6070
skinparam cloudBackgroundColor #f0f5fa
skinparam artifactBorderColor #006a62
skinparam artifactBackgroundColor #ffffff
skinparam rectangleBorderColor #b0c2d3
skinparam activityBorderColor #006a62
skinparam activityBackgroundColor #e9f3f4
skinparam partitionBorderColor #b0c2d3
skinparam stereotypeCBackgroundColor #ffffff
top to bottom direction
hide empty members
package "sm64coopdx-switch-N3DS" {
package "tools/audiofile/audiofile.cpp" as F0 {
class "_AFfilehandle" as T0_0 {
copyTracksFromSetup()
copyInstrumentsFromSetup()
copyMiscellaneousFromSetup()
getVersion()
readInit()
writeInit()
}
class "AIFFFile" as T0_1 {
recognizeAIFF()
recognizeAIFFC()
completeSetup()
getVersion()
readInit()
writeInit()
}
class "WAVEFile" as T0_2 {
recognize()
completeSetup()
readInit()
writeInit()
update()
isInstrumentParameterValid()
}
class "Module" as T0_3 {
setSink()
setSource()
inChunk()
setInChunk()
outChunk()
setOutChunk()
}
class "ModuleState" as T0_4 {
isDirty()
setDirty()
setup()
reset()
sync()
numModules()
}
}
package "src/pc/utils/json.hpp" as F1 {
class "binary_writer" as T1_0 {
write_bson()
write_cbor()
write_msgpack()
write_ubjson()
calc_bson_entry_header_size()
write_bson_entry_header()
}
class "binary_reader" as T1_1 {
parse_bson_internal()
get_bson_cstr()
parse_bson_element_internal()
parse_bson_element_list()
parse_bson_array()
parse_cbor_internal()
}
class "json_sax_dom_callback_parser" as T1_2 {
null()
boolean()
number_integer()
number_unsigned()
number_float()
string()
}
}
package "tools/asm_processor/asm-processor.py" as F2 {
class "Section" as T2_0 {
from_parts()
lookup_str()
add_str()
is_rel()
header_to_bin()
late_init()
}
}
package "data/dynos.cpp.h" as F3 {
class "String" as T3_0 {
Add()
Remove()
RemoveAll()
Clear()
Find()
FindLast()
}
}
package "tools/switch/coopnet_identity.py" as F4 {
class "NroAssetInfo" as T4_0 {
nro_size
aset_offset
icon_offset
icon_size
icon_sha256
}
}
package "include/types.h" as F5 {
class "AnimInfo" as T5_0 {
curAnim
prevAnimPtr
animID
prevAnimID
animFrame
prevAnimFrame
prevAnimFrameTimestamp
animFrameAccelAssist
}
class "Animation" as T5_1 {
flags
animYTransDivisor
startFrame
loopStart
loopEnd
unusedBoneCount
values
index
}
class "AnimationTable" as T5_2 {
count
anims
_guard1
prev
next
parent
children
georef
}
class "Controller" as T5_3 {
port
stickX
stickY
stickMag
rawStickX
rawStickY
extStickX
extStickY
}
}
package "src/game/hardcoded.h" as F6 {
class "BehaviorDialogs" as T6_0 {
BobombBuddyBob1Dialog
BobombBuddyBob2Dialog
BobombBuddyOther1Dialog
BobombBuddyOther2Dialog
Bowser1DefeatedDialog
Bowser1Dialog
Bowser2DefeatedDialog
Bowser2Dialog
}
class "BehaviorTrajectories" as T6_1 {
KoopaBobTrajectory
KoopaThiTrajectory
UnagiTrajectory
Unagi2Trajectory
SnowmanHeadTrajectory
RacingPenguinTrajectory
BowlingBallBobTrajectory
BowlingBallBob2Trajectory
}
class "BehaviorValues" as T6_2 {
KoopaBobAgility
KoopaCatchupAgility
KoopaThiAgility
RacingPenguinBigHeight
RacingPenguinBigRadius
RacingPenguinHeight
RacingPenguinRadius
ToadStar1Requirement
}
}
package "src/game/ingame_menu.c" as F7 {
class "CachedChar" as T7_0 {
sDialogOffsetPos
sDialogRotationPos
sDialogZoomPos
sDialogOffset
sDialogOffsetPrev
sDialogScale
sDialogScalePrev
sDialogRotation
}
}
package "src/game/camera.h" as F8 {
class "CameraTrigger" as T8_0 {
area
event
centerX
centerY
centerZ
boundsX
boundsY
boundsZ
}
}
package "src/game/object_helpers.h" as F9 {
class "ChainSegment" as T9_0 {
posX
posY
posZ
pitch
yaw
roll
flags
model
}
}
package "src/game/characters.h" as F10 {
class "Character" as T10_0 {
type
name
hudHead
hudHeadTexture
cameraHudHead
modelId
capModelId
capMetalModelId
}
}
package "src/game/level_update.h" as F11 {
class "CreditsEntry" as T11_0 {
gCurrCreditsEntry
gMarioStates
gMarioState
sCurrPlayMode
sTransitionTimer
gChangeLevel
gChangeActNum
gDelayedInitSound
}
}
package "src/game/game_init.h" as F12 {
class "DemoInput" as T12_0 {
timer
rawStickX
rawStickY
buttonMask
gControllers
gControllerStatuses
gControllerPads
gGameVblankQueue
}
}
}
@enduml
7.3. Flux de données
Les appels du diagramme GitDiagram, dans l’ordre où on les rencontre depuis les points d’entrée. GitDiagram produit ce graphe par IA; les chemins de fichiers cités ont été comparés à l’arbre du dépôt.
Mermaid Diagramme de séquence
sequenceDiagram
autonumber
participant P0 as Window Manager
participant P1 as Controller Input
participant P2 as Switch Backend
participant P3 as DJUI
participant P4 as Rendering
participant P5 as New 3DS Backend
participant P6 as Character Assets
participant P7 as ROM Asset Loading
participant P8 as Level Content
participant P9 as Gameplay World
participant P10 as Player
participant P11 as Game Runtime
participant P12 as Game Configuration
participant P13 as Lighting Engine
participant P14 as Multiplayer Sync
participant P15 as Game Initialization
P0->>P1: dispatches keyboard events
P2->>P3: opens text entry
P2->>P4: selects backend
P5->>P3: handles text entry
P5->>P4: owns frame lifecycle
P6->>P7: queues assets
P8--)P9: defines levels
P10->>P1: provides input
P1->>P11: feeds controls
P1->>P12: reads bindings
P1->>P3: notifies interactables
P4--)P13: uses lighting
P9--)P14: synchronizes world
P9--)P4: presents
P11->>P15: initializes
P11--)P9: updates
Étapes en texte
- Window Manager vers Controller Input dispatches keyboard events
- Switch Backend vers DJUI opens text entry
- Switch Backend vers Rendering selects backend
- New 3DS Backend vers DJUI handles text entry
- New 3DS Backend vers Rendering owns frame lifecycle
- Character Assets vers ROM Asset Loading queues assets
- Level Content vers Gameplay World defines levels
- Player vers Controller Input provides input
- Controller Input vers Game Runtime feeds controls
- Controller Input vers Game Configuration reads bindings
- Controller Input vers DJUI notifies interactables
- Rendering vers Lighting Engine uses lighting
- Gameplay World vers Multiplayer Sync synchronizes world
- Gameplay World vers Rendering presents
- Game Runtime vers Game Initialization initializes
- Game Runtime vers Gameplay World updates
- Game Runtime vers Audio Runtime coordinates audio
- Game Runtime vers ROM Asset Loading loads assets
- Multiplayer Sync vers CoopNet supports online play
- Multiplayer Sync vers Local Wireless supports local play
- Lua Mod API vers Mod Storage reads and writes
- Mod Storage vers Lua Mod API returns values
- Mod Storage vers Game Configuration uses filesystem settings
7.4. Interface publique
Du code extérieur peut utiliser tout ce qui est listé ici. Le projet déclare aussi 914 types publics.
Ligne de commande 32
--post-process--assembler--asm-prelude--input-enc--output-enc-framepointer-g3-O1-O2-g--root--version--switch-dist--new3ds-dist--build-dir--sound-bin-dir--3dsx--cia
Points d’entrée
src/game/main.cfichier d’entrée
En-têtes publics 88
include/GL/eglew.h include/GL/glew.h include/GL/glxew.h include/GL/wglew.h include/PR/abi.h include/PR/gbi.h include/PR/gbi_extension.h include/PR/gs2dex.h include/PR/gu.h include/PR/libaudio.h
7.5. Interface privée
Ces noms sont internes selon les conventions du langage: tiret bas initial, private, static ou pub(crate).
- Fonction static (locale au fichier)
- 3775
- Espace de noms anonyme
- 3
- Assistant préfixé _
- 1
DynOS_Actor_WriteBinarydata/dynos_bin_actor.cpp:16DynOS_Actor_Generatedata/dynos_bin_actor.cpp:145ScanAnimationDataFiledata/dynos_bin_animation.cpp:7namespace { }src/pc/gfx/gfx_direct3d11.cpp:40namespace { }tools/new3ds/coopnet_new3ds_identity.cpp:9_mix_blocktools/switch/coopnet_identity.py:18namespace { }tools/switch/coopnet_switch_identity.cpp:9
7.6. Services
Service 12
Client 3
Gestionnaire 2
Contrôleur 1
Magasin d’état 1
7.7. Entités et modèle de données 762
Mermaid Diagramme de classes des entités
classDiagram
direction LR
class E0["NroAssetInfo"] {
+int nro_size
+int aset_offset
+int icon_offset
+int icon_size
+str icon_sha256
}
class E1["AnimInfo"] {
+struct curAnim
+struct prevAnimPtr
+s16 animID
+s16 prevAnimID
+s16 animFrame
+s16 prevAnimFrame
}
class E2["Animation"] {
+s16 flags
+s16 animYTransDivisor
+s16 startFrame
+s16 loopStart
+s16 loopEnd
+s16 unusedBoneCount
}
class E3["AnimationTable"] {
+u32 count
+struct anims
+uintptr_t _guard1
+struct prev
+struct next
+struct parent
}
class E4["BehaviorDialogs"] {
+enum BobombBuddyBob1Dialog
+enum BobombBuddyBob2Dialog
+enum BobombBuddyOther1Dialog
+enum BobombBuddyOther2Dialog
+enum Bowser1DefeatedDialog
+enum Bowser1Dialog
}
class E5["BehaviorTrajectories"] {
+Trajectory KoopaBobTrajectory
+Trajectory KoopaThiTrajectory
+Trajectory UnagiTrajectory
+Trajectory Unagi2Trajectory
+Trajectory SnowmanHeadTrajectory
+Trajectory RacingPenguinTrajectory
}
class E6["BehaviorValues"] {
+f32 KoopaBobAgility
+f32 KoopaCatchupAgility
+f32 KoopaThiAgility
+f32 RacingPenguinBigHeight
+f32 RacingPenguinBigRadius
+f32 RacingPenguinHeight
}
class E7["CachedChar"] {
+static sDialogOffsetPos
+static sDialogRotationPos
+static sDialogZoomPos
+static sDialogOffset
+static sDialogOffsetPrev
+static sDialogScale
}
class E8["CameraTrigger"] {
+s8 area
+CameraEvent event
+s16 centerX
+s16 centerY
+s16 centerZ
+s16 boundsX
}
class E9["ChainSegment"] {
+f32 posX
+f32 posY
+f32 posZ
+s16 pitch
+s16 yaw
+s16 roll
}
E1 --> E2 : curAnim
E1 --> E2 : prevAnimPtr
E3 --> E2 : anims
Une flèche relie un champ à l’entité que son type nomme.
| Entité | Nature | Premiers champs |
|---|---|---|
NroAssetInfo | Enregistrement ou interface | nro_size, aset_offset, icon_offset, icon_size, icon_sha256 |
AnimInfo | Structure de données | curAnim, prevAnimPtr, animID, prevAnimID, animFrame, prevAnimFrame, prevAnimFrameTimestamp, animFrameAccelAssist |
Animation | Structure de données | flags, animYTransDivisor, startFrame, loopStart, loopEnd, unusedBoneCount, values, index |
AnimationTable | Structure de données | count, anims, _guard1, prev, next, parent, children, georef |
BehaviorDialogs | Structure de données | BobombBuddyBob1Dialog, BobombBuddyBob2Dialog, BobombBuddyOther1Dialog, BobombBuddyOther2Dialog, Bowser1DefeatedDialog, Bowser1Dialog, Bowser2DefeatedDialog, Bowser2Dialog |
BehaviorTrajectories | Structure de données | KoopaBobTrajectory, KoopaThiTrajectory, UnagiTrajectory, Unagi2Trajectory, SnowmanHeadTrajectory, RacingPenguinTrajectory, BowlingBallBobTrajectory, BowlingBallBob2Trajectory |
BehaviorValues | Structure de données | KoopaBobAgility, KoopaCatchupAgility, KoopaThiAgility, RacingPenguinBigHeight, RacingPenguinBigRadius, RacingPenguinHeight, RacingPenguinRadius, ToadStar1Requirement |
CachedChar | Structure de données | sDialogOffsetPos, sDialogRotationPos, sDialogZoomPos, sDialogOffset, sDialogOffsetPrev, sDialogScale, sDialogScalePrev, sDialogRotation |
Afficher 6 entités de plus
CameraTrigger | Structure de données | area, event, centerX, centerY, centerZ, boundsX, boundsY, boundsZ |
|---|---|---|
ChainSegment | Structure de données | posX, posY, posZ, pitch, yaw, roll, flags, model |
Character | Structure de données | type, name, hudHead, hudHeadTexture, cameraHudHead, modelId, capModelId, capMetalModelId |
Controller | Structure de données | port, stickX, stickY, stickMag, rawStickX, rawStickY, extStickX, extStickY |
CreditsEntry | Structure de données | gCurrCreditsEntry, gMarioStates, gMarioState, sCurrPlayMode, sTransitionTimer, gChangeLevel, gChangeActNum, gDelayedInitSound |
DemoInput | Structure de données | timer, rawStickX, rawStickY, buttonMask, gControllers, gControllerStatuses, gControllerPads, gGameVblankQueue |
7.8. Logique métier
Une fois écartés le code d’interface et les services et entités ci-dessus, ces classes ont le plus de méthodes.
_AFfilehandlePoints d’entrée et API, 34 méthodescopyTracksFromSetup, copyInstrumentsFromSetup, copyMiscellaneousFromSetup, getVersion, readInit, writeInitbinary_writerSource principale, 30 méthodeswrite_bson, write_cbor, write_msgpack, write_ubjson, calc_bson_entry_header_size, write_bson_entry_headerAIFFFilePoints d’entrée et API, 27 méthodesrecognizeAIFF, recognizeAIFFC, completeSetup, getVersion, readInit, writeInitWAVEFilePoints d’entrée et API, 27 méthodesrecognize, completeSetup, readInit, writeInit, update, isInstrumentParameterValidbinary_readerSource principale, 26 méthodesparse_bson_internal, get_bson_cstr, parse_bson_element_internal, parse_bson_element_list, parse_bson_array, parse_cbor_internaljson_sax_dom_callback_parserSource principale, 13 méthodesnull, boolean, number_integer, number_unsigned, number_float, stringSectionPoints d’entrée et API, 12 méthodesfrom_parts, lookup_str, add_str, is_rel, header_to_bin, late_initModulePoints d’entrée et API, 17 méthodessetSink, setSource, inChunk, setInChunk, outChunk, setOutChunkModuleStatePoints d’entrée et API, 16 méthodesisDirty, setDirty, setup, reset, sync, numModulesStringDonnées et infrastructure, 15 méthodesAdd, Remove, RemoveAll, Clear, Find, FindLast
7.9. Base de données et persistance
Tables et collections 2
7.10. Intégrations externes
Clients HTTP
Hôtes nommés dans le code
www.lua.org2 fichierstools/new3ds/build-lua53.sh:15mods.sm64coopdx.com1 fichierssrc/pc/djui/djui_panel_host_mods.c:235
7.11. Pipeline CI/CD
6 workflows GitHub Actions, 9 tâches. Chaque boîte est une tâche ; les boîtes à double bord publient ou déploient, et les flèches suivent les dépendances needs.
Mermaid Déroulement du pipeline
flowchart LR
subgraph wf0["Build New 3DS CoopNet"]
direction LR
wf0_build_new3ds_coopnet[["devkitARM / CoopNet compile-only<br/>ubuntu-latest"]]
end
subgraph wf1["Build New 3DS Port"]
direction LR
wf1_build_new3ds_shell[["devkitARM / shell + platform smoke<br/>ubuntu-latest"]]
wf1_build_new3ds_integration["devkitARM / shared integration compile<br/>ubuntu-latest"]
wf1_build_new3ds_game["devkitARM / full CoopDX .3dsx + CIA<br/>ubuntu-latest"]
end
subgraph wf2["Switch CoopNet Full NRO"]
direction LR
wf2_full_nro["Full Horizon CoopNet NRO<br/>ubuntu-latest"]
end
subgraph wf3["Switch CoopNet Port CI"]
direction LR
wf3_coopnet_portability["CoopNet Horizon portability<br/>ubuntu-latest"]
end
subgraph wf4["Switch CI"]
direction LR
wf4_portability[["Horizon portability gates<br/>ubuntu-latest"]]
wf4_full_nro["Full Horizon game NRO<br/>ubuntu-latest"]
end
subgraph wf5["Switch crash logger CI"]
direction LR
wf5_compile["compile<br/>ubuntu-latest"]
end
t0(["lancement manuel"])
t1(["push · demande de fusion · lancement manuel"])
t2(["push · lancement manuel"])
t0 --> wf0_build_new3ds_coopnet
t1 --> wf1_build_new3ds_shell
wf1_build_new3ds_shell --> wf1_build_new3ds_integration
wf1_build_new3ds_integration --> wf1_build_new3ds_game
t2 --> wf2_full_nro
t1 --> wf3_coopnet_portability
t1 --> wf4_portability
wf4_portability --> wf4_full_nro
t1 --> wf5_compile
| Workflow | Déclencheurs | Tâches | Publie vers |
|---|---|---|---|
Build New 3DS CoopNet.github/workflows/build-new3ds-coopnet.yml | lancement manuel |
| — |
Build New 3DS Port.github/workflows/build-new3ds.yml | push, demande de fusion, lancement manuel |
| — |
Switch CoopNet Full NRO.github/workflows/build-switch-coopnet-full.yml | push, lancement manuel |
| — |
Switch CoopNet Port CI.github/workflows/build-switch-coopnet.yml | push, demande de fusion, lancement manuel |
| — |
Switch CI.github/workflows/build-switch-game.yml | push, demande de fusion, lancement manuel |
| — |
Switch crash logger CI.github/workflows/switch-crash-logging.yml | push, demande de fusion, lancement manuel |
| — |
7.12. Déploiement
Mermaid Schéma de déploiement
flowchart LR
repo[("Dépôt GitHub")]
ci[["GitHub Actions<br/>6 workflows"]]
image["Image Docker<br/>FROM ubuntu:jammy"]
subgraph compose["Docker Compose"]
svc_new3ds_shell["new3ds-shell"]
svc_new3ds_integration["new3ds-integration"]
svc_new3ds_full_3dsx["new3ds-full-3dsx"]
svc_switch_portability["switch-portability"]
svc_switch_full_nro["switch-full-nro"]
end
repo -->|"push ou demande de fusion"| ci
ci -->|"docker build"| image
image -->|"docker compose up"| compose
UML Déploiement
Le nœud extérieur est l’endroit où le code s’exécute. Chaque image de base pointe vers ce qu’elle construit, les flèches pleines mènent aux bases de données et les pointillées aux services externes. Rendu avec uml-mcp.
Source PlantUML
@startuml
skinparam backgroundColor transparent
skinparam shadowing false
skinparam roundCorner 10
skinparam defaultFontName Arial
skinparam defaultFontSize 13
skinparam ArrowColor #4e6070
skinparam ArrowFontColor #3d4f5f
skinparam titleFontSize 14
skinparam actorBorderColor #006a62
skinparam actorBackgroundColor #e9f3f4
skinparam usecaseBorderColor #006a62
skinparam usecaseBackgroundColor #e9f3f4
skinparam componentBorderColor #006a62
skinparam componentBackgroundColor #e9f3f4
skinparam interfaceBorderColor #006a62
skinparam interfaceBackgroundColor #ffffff
skinparam nodeBorderColor #4e6070
skinparam nodeBackgroundColor #f4f8fb
skinparam databaseBorderColor #006a62
skinparam databaseBackgroundColor #ffffff
skinparam cloudBorderColor #4e6070
skinparam cloudBackgroundColor #f0f5fa
skinparam artifactBorderColor #006a62
skinparam artifactBackgroundColor #ffffff
skinparam rectangleBorderColor #b0c2d3
skinparam activityBorderColor #006a62
skinparam activityBackgroundColor #e9f3f4
skinparam partitionBorderColor #b0c2d3
skinparam stereotypeCBackgroundColor #ffffff
node "Docker Compose" as H {
node "new3ds-shell" as N0 <<container>>
node "new3ds-integration" as N1 <<container>>
node "new3ds-full-3dsx" as N2 <<container>>
node "switch-portability" as N3 <<container>>
node "switch-full-nro" as N4 <<container>>
}
artifact "FROM ubuntu:jammy" as IMG0
IMG0 ..> N0 : construit
artifact "FROM devkitpro/devkitarm:latest" as IMG1
IMG1 ..> N0 : construit
artifact "FROM devkitpro/devkita64:latest" as IMG2
IMG2 ..> N0 : construit
cloud "Pile réseau console (libnx/li…" as E0
N0 ..> E0
cloud "Portail de données ouvertes (…" as E1
N0 ..> E1
@enduml
Où il s’exécute
Services Compose
new3ds-shell new3ds-integration new3ds-full-3dsx switch-portability switch-full-nro
Images Docker de base
ubuntu:jammy devkitpro/devkitarm:latest devkitpro/devkita64:latest
7.13. Sécurité
Variables d’environnement 3
La page reprend les noms sans leurs valeurs et souligne ceux qui ressemblent à des secrets.
7.14. Tests automatisés
- Fichiers de test
- 11
- Fichiers source
- 3711
- Cas de test, environ
- 33
- Tests unitaires
- 11
Aucun rapport chiffré de couverture dans les sources analysées.
Où sont les tests
Rien trouvé pour: Stack et dépendances, Supervision.
8. Types et structure des fichiers
938 types déclarés, dont 12 dans l’aperçu des relations de base.
Diagramme des types
classDiagram
direction TB
class td46db2c67d89["SwitchMainThreadContext"] {
<<struct>>
}
class t8aa16fcaf4e8["BehaviorTableEntry"] {
<<struct>>
}
class t967c531c3987["BinFile"] {
Grow()
Size()
Offset()
EoF()
}
class t600bad59e95a["Array"] {
Array()
Resize()
Add()
Remove()
}
class t0f95fccc28fc["String"] {
String()
Add()
Remove()
RemoveAll()
}
class t86e8898abb40["NoCopy"] {
NoCopy()
}
class t5781fa224570["TexData"] {
<<struct>>
}
class t2525940954f7["AnimData"] {
<<struct>>
}
class t47b9608239dd["DataNode"] {
<<struct>>
}
class tdd2833761514["DataNodes"] {
Find()
FindExact()
}
class ta18b7a1fb439["GfxContext"] {
<<struct>>
}
class t4d433eaff897["GfxData"] {
<<struct>>
}
t86e8898abb40 <|-- t5781fa224570
t86e8898abb40 <|-- t2525940954f7
t86e8898abb40 <|-- t47b9608239dd
t86e8898abb40 <|-- t4d433eaff897
Les bases non résolues restent identifiées; les signatures complètes ne sont pas reconstruites.
9. Référence
3589 / 3589 fichiers admissibles lus (4720 dans l’arbre); 0 trop volumineux, 0 échec de lecture et 509 diagnostic de syntaxe.
Ce que couvre l’analyse
Les dossiers connus de dépendances et de compilation, les fichiers d’identifiants et les binaires sont exclus. La collecte couvre les README, les manifestes reconnus et les fichiers source pris en charge.
Les statistiques Linguist couvrent l’ensemble du dépôt et peuvent inclure d’autres langages.
11. Fichiers à lire 3
12. Glossaire
Dépôt
Les fichiers source, la configuration et l’historique versionné d’un projet.
README
Le document d’entrée du dépôt, qui présente généralement son rôle et son installation.
Dépendance
Une bibliothèque, un outil ou un service nécessaire à la compilation ou à l’exécution d’un composant.
HTTP
Un protocole de requête et réponse utilisé par les navigateurs et services web. Une requête comprend une méthode, un chemin, des en-têtes et parfois un corps.
Session
Un état conservé entre plusieurs requêtes, souvent pour suivre un utilisateur connecté. L’authentification et les permissions restent des vérifications distinctes.
Conteneur
Un environnement de processus isolé créé à partir d’une image. Les données persistantes nécessitent un stockage hors de son système de fichiers temporaire.
Port publié
Un port de l’hôte associé au port d’un service dans un conteneur. Sa publication peut rendre le service accessible hors du réseau des conteneurs.
Interface en ligne de commande
Une interface textuelle où les commandes et arguments choisissent les opérations. Les codes de retour permettent aux scripts de détecter un succès ou un échec.
Compilation
Les étapes qui transforment les sources et dépendances en programme exécutable ou en livrable distribuable.
GPU
Un processeur conçu pour les calculs parallèles, dont le rendu graphique et de nombreuses opérations numériques.
Shader
Un programme exécuté à une étape d’un pipeline graphique ou de calcul, par exemple pour transformer des sommets ou calculer la couleur des pixels.
Backend
Une implémentation derrière une interface commune. Selon le contexte, il peut s’agir d’un service côté serveur ou d’une implémentation graphique, d’entrée ou de stockage.
Micrologiciel
Un logiciel exécuté sur un appareil ou microcontrôleur pour contrôler son matériel et ses communications.
Fork
Un dépôt distinct dérivé d’un autre projet. Une modification du fork ne devient pas automatiquement une modification du projet amont.
13. Références
- antoinebou12. (2026, 5 novembre). sm64coopdx-switch-N3DS. [Software repository] github.com.
- antoinebou12. (2026, 5 novembre). sm64coopdx-switch-N3DS: README. [Repository documentation] github.com.
- antoinebou12. (2026, 5 novembre). Makefile.switch-platform. [Source file] github.com.
- antoinebou12. (2026, 5 novembre). src/pc/platform/switch/switch_platform.c. [Source file] github.com.
- antoinebou12. (2026, 5 novembre). Makefile.new3ds. [Source file] github.com.
- Boucher, A. (2026, 2 septembre). Streaming portable et homebrew — Artemis-Switch, moonlight-N3DS, sm64coopdx-switch. [Project article] antoineboucher.info.
- Boucher, A. (2026, 20 octobre). Porter sm64coopdx sur Switch et New 3DS : isoler les plateformes. [Project article] antoineboucher.info.
- Boucher, A. (2026, 23 octobre). sm64coopdx-switch-N3DS : Isoler un port derrière les interfaces de plateforme. [Project article] antoineboucher.info.
- Boucher, A. (2026, 2 septembre). sm64coopdx-switch. [Project article] antoineboucher.info.
Les sources sans date de publication indiquent la date de leur dernière vérification, le 5 novembre 2026. Les liens des fichiers conservent la révision inspectée lorsqu’elle est disponible.