Table des matières
Artemis-N3DS : Le streaming sur un client à deux écrans
Artemis-N3DS adapte Moonlight Embedded à la famille Nintendo 3DS. Le projet réunit découverte et jumelage de l’hôte, interface console, commandes et affichage vidéo. Le parcours matériel de la New 3DS demande une attention particulière.
- Langages
- 6Répartition du code
- Composants documentés
- 2Explorer les modules
- Documents source
- 2Lire les instructions
Langages du dépôtC++ 76.05%6
Parts calculées à partir des octets GitHub Linguist.
| Langage | % | Octets |
|---|---|---|
| C++ | 385 430 | |
| C | 79 616 | |
| CMake | 22 072 | |
| Makefile | 14 414 | |
| Shell | 3 221 | |
| Dockerfile | 2 051 |
1. Aperçu
1.1. Pourquoi il existe
Défi d'ingénierie sous fortes contraintes : streaming 60 FPS sur architecture ARM11 double écran.
1.2. Cas d’usage
Accès distant et jeu PC sur matériel New 3DS.
2. Cas d’utilisation
Fork de Moonlight Embedded qui diffuse les jeux d’un PC Sunshine sur une New 3DS, avec une interface d’aide à l’écran du bas.
- Installer le CIA ou le 3DSX
- Joueur sur 3DS
dist/INSTALL.md explique comment installer artemis.cia depuis le menu HOME avec FBI, ou copier artemis.3dsx dans sd:/3ds/artemis/ pour le Homebrew Launcher ; un firmware modifié est requis.
- Jumeler un hôte
- Joueur sur 3DSPC hôte Sunshine
Le joueur ajoute un hôte par son IP locale (host_discovery.cpp peut aussi balayer le réseau) et choisit pair ; pair_host dans src/n3ds_main.cpp affiche un NIP à saisir dans Sunshine et garde un enregistrement de jumelage.
- Diffuser un jeu ou le bureau
- Joueur sur 3DSPC hôte Sunshine
La vidéo s’affiche à l’écran du haut avec le décodeur H.264 matériel de la New 3DS ; selon le README, les anciens modèles passent au décodage logiciel, avec moins d’images par seconde.
- Changer de mode tactile
- Joueur sur 3DSPC hôte Sunshine
Le menu SELECT de l’écran du bas passe d’un gestionnaire à l’autre dans src/input/touch/ : manette, souris, clavier, loupe et miroir, avec les affichages Fit, Fill, Stretch et le zoom.
- Enregistrer les mesures en CSV
- Joueur sur 3DS
Depuis l’onglet Session, la surcouche de performance affiche la télémétrie ; export_stream_benchmark_csv (src/stream_benchmark.cpp) écrit benchmark_<horodatage>.csv sur la carte SD.
- Compiler avec devkitPro
- Développeur
Le Dockerfile donne une image devkitPro ; make y produit artemis.3dsx, artemis.cia et artemis.elf. Une installation locale de devkitPro 3ds-dev avec bannertool et makerom fonctionne aussi.
2.1. Scénario : Jouer à un jeu PC sur New 3DS en Wi-Fi
- Copier artemis.cia sur la carte SD et l’installer dans FBI avec Install and delete CIA.
- Ouvrir Artemis, appuyer sur A pour ajouter un hôte et saisir l’adresse IP locale du PC.
- Choisir pair et taper dans la page PIN de Sunshine le NIP affiché sur la 3DS.
- Choisir stream puis une application ; la vidéo s’affiche à l’écran du haut.
- Appuyer sur SELECT pour passer en mode Souris ou Loupe, ou ouvrir la surcouche de performance et enregistrer un CSV.
- Quitter depuis l’onglet Session pour terminer la diffusion.
Fichiers consultésREADME.mddist/INSTALL.mddist/SD-DATA.mdsrc/n3ds_main.cppsrc/host_discovery.cppsrc/stream_benchmark.cppsrc/input/touch/stream_bottom_ui.cppDockerfile
3. Démarrage
Ces commandes viennent de la documentation du dépôt. Elles n’ont pas été exécutées pendant cette revue.
makedocker build --network=host -t moonlight-n3ds .
docker run --rm -it -v .:/moonlight-N3DS -w /moonlight-N3DS moonlight-n3ds:latest
make4. 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
README.md
- New 3DS / New 3DS XL / New 2DS XL recommended (hardware H.264 decode)
- Original 3DS / 2DS works with software decode only — expect lower FPS
- PC running Sunshine (or compatible GameStream host) on the same network
- CFW + FBI for CIA install
4.2. Install
README.md
Configuration et utilisation
4.3. Configuration
README.md
Développement et contributions
4.4. Contribute
README.md
- Fork the repo
- Make your changes
- Open a pull request
5. Fonctions et composants 2
- Gestion de la session
- n3ds_main.cpp réunit découverte, jumelage, profils et état de connexion. L’hôte et l’application sélectionnés déterminent la demande de streaming. Le cycle de vie graphique est suivi séparément de la configuration du flux.
- Médias et interaction
- L’audio, les commandes et la vidéo ont leurs modules dans src. Les capacités matérielles influencent les indications affichées. L’interface peut reprendre après un flux, tandis qu’une fermeture système explicite doit terminer l’application.
6. Architecture
Ouvrez un composant pour suivre ses connexions, ou explorez le diagramme complet.
Découverte et jumelage
Application et profil
- Depuis Découverte et jumelage
- Vers Connexion GameStream
Connexion GameStream
- Depuis Application et profil
- Vers Moteurs vidéo et audio
- Depuis Écrans et commandes 3DS
Moteurs vidéo et audio
- Depuis Connexion GameStream
- Vers Écrans et commandes 3DS
Écrans et commandes 3DS
- Depuis Moteurs vidéo et audio
- Vers Connexion GameStream
Mermaid Diagramme interactif
Vue générale des composants et des échanges vérifiés dans le dépôt.

flowchart LR
node_user(("3DS user"))
subgraph group_host["Hosts and pairing"]
node_discovery["Host discovery<br/>[host_discovery.cpp]"]
node_pairing[("Pair records<br/>[pair_record.cpp]")]
node_gamestream["GameStream client<br/>[client.c]"]
node_xml["Protocol XML<br/>[xml.c]"]
end
subgraph group_session["Session coordination"]
node_main["Application flow<br/>[n3ds_main.cpp]"]
node_ui["Console menus<br/>[n3ds_ui.cpp]"]
node_connection["Stream connection"]
node_dispatcher["Message dispatcher<br/>[dispatcher.cpp]"]
end
subgraph group_stream["Stream pipeline"]
node_presentation["Presentation state"]
node_decoder["Video decoders"]
node_mvd["Hardware decode<br/>[n3ds_video_mvd.cpp]"]
node_software["Software decode"]
node_renderer["Screen renderers"]
node_graphics["Graphics lifecycle"]
node_audio["Audio output<br/>[n3ds_audio.cpp]"]
end
subgraph group_interaction["Input and helpers"]
node_input["Console input<br/>[n3ds_input.cpp]"]
node_touch["Touch handlers<br/>[TouchHandler.hpp]"]
node_menuhub["In-stream helper hub"]
node_bottomui["Bottom-screen UI"]
end
subgraph group_state["Settings and telemetry"]
node_config[("Configuration<br/>[config.cpp]")]
node_appcache[("App list cache<br/>[app_list_cache.cpp]")]
node_profiles["Stream profiles<br/>[stream_profile.cpp]"]
node_telemetry[("Stream telemetry")]
node_benchmark["Performance metrics"]
end
node_user -->|"uses"| node_main
node_gamestream -->|"parses responses"| node_xml
node_discovery -->|"uses records"| node_pairing
node_main -->|"shows menus"| node_ui
node_main -->|"starts session"| node_connection
node_main -->|"handles controls"| node_input
node_input -->|"posts events"| node_dispatcher
node_input -->|"owns handlers"| node_touch
node_main -->|"dispatches events"| node_dispatcher
node_user -->|"opens helpers"| node_menuhub
node_menuhub -->|"posts actions"| node_dispatcher
node_menuhub -.->|"draws interface"| node_bottomui
node_user -->|"chooses stream"| node_connection
node_connection -.->|"receives video"| node_decoder
node_decoder -.->|"hardware path"| node_mvd
node_decoder -.->|"software path"| node_software
node_decoder -->|"renders frames"| node_renderer
node_renderer -->|"uses layout state"| node_presentation
node_renderer -->|"uses graphics lifecycle"| node_graphics
node_connection -.->|"streams audio"| node_audio
node_user -->|"views or saves metrics"| node_telemetry
group_session --> group_host
group_session --> group_state
class node_discovery,node_pairing,node_gamestream,node_xml,node_user toneBlue
class node_main,node_ui,node_connection,node_dispatcher toneAmber
class node_presentation,node_decoder,node_mvd,node_software,node_renderer,node_graphics,node_audio toneMint
class node_input,node_touch,node_menuhub,node_bottomui toneRose
class node_config,node_appcache,node_profiles,node_telemetry,node_benchmark toneIndigo
Un client GameStream pour Nintendo 3DS. Les utilisateurs découvrent ou ajoutent un hôte compatible Sunshine, associent la console, choisissent une application et lancent la diffusion par les sous-systèmes de session, vidéo, rendu, entrées et écran inférieur.
- Composants
- 25
- Connexions
- 29
- Liens appuyés par le code
- 23/29
Version texte du diagramme
Le diagramme regroupe les liens parallèles entre groupes : il en montre 23 sur 29. Liste complète :
- 3DS user → Application flow (uses)
- Application flow → Host discovery (finds hosts)
- Application flow → Pair records (pairs host)
- Application flow → GameStream client (manages host)
- GameStream client → Protocol XML (parses responses)
- Host discovery → Pair records (uses records)
- Application flow → Console menus (shows menus)
- Application flow → App list cache (lists apps)
- Application flow → Stream connection (starts session)
- Application flow → Configuration (loads settings)
- Application flow → Stream profiles (selects profile)
- Application flow → Console input (handles controls)
- Console input → Message dispatcher (posts events)
- Console input → Touch handlers (owns handlers)
- Application flow → Message dispatcher (dispatches events)
- 3DS user → In-stream helper hub (opens helpers)
- In-stream helper hub → Message dispatcher (posts actions)
- In-stream helper hub → Bottom-screen UI (draws interface)
- 3DS user → Stream connection (chooses stream)
- Stream connection → Video decoders (receives video)
- Video decoders → Hardware decode (hardware path)
- Video decoders → Software decode (software path)
- Video decoders → Screen renderers (renders frames)
- Screen renderers → Presentation state (uses layout state)
- Screen renderers → Graphics lifecycle (uses graphics lifecycle)
- Stream connection → Audio output (streams audio)
- 3DS user → Stream telemetry (views or saves metrics)
- 3DS user → Performance metrics (views performance)
- Application flow → Stream telemetry (uses telemetry store)
Suivre un parcours dans le code
Suivez SelectedHost et le profil avant d’entrer dans le traitement des médias. Une fermeture système et un retour normal au menu sont deux transitions distinctes; un indicateur explicite évite de les confondre.
7. Dossier technique
Établi à partir du code au commit c5eb020 (104 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_interface["Points d’entrée et API"]
direction TB
interface_0["src<br/>1 fichier"]
end
subgraph L_domain["Domaine et règles métier"]
direction TB
domain_0["input/touch<br/>2 fichiers"]
end
subgraph L_infrastructure["Données et infrastructure"]
direction TB
infrastructure_0["libgamestream<br/>2 fichiers"]
infrastructure_1["src<br/>2 fichiers"]
infrastructure_2["third_party/ilclient<br/>2 fichiers"]
end
subgraph L_core["Source principale"]
direction TB
core_0["src<br/>26 fichiers"]
core_1["third_party/libuuid<br/>17 fichiers"]
core_2["input/touch<br/>16 fichiers"]
core_3["system<br/>12 fichiers"]
core_more["+9"]
end
subgraph L_tests["Tests"]
direction TB
tests_0["tests<br/>1 fichier"]
end
subgraph L_hosting["Build, CI et hébergement"]
direction TB
hosting_0[".github<br/>7 fichiers"]
hosting_1["(root)<br/>3 fichiers"]
hosting_2["libgamestream<br/>1 fichier"]
end
L_interface ~~~ L_domain
L_domain ~~~ L_infrastructure
L_infrastructure ~~~ L_core
L_core ~~~ L_tests
L_core ~~~ L_hosting
| Module | Couche | Fichiers | Types | Extensions |
|---|---|---|---|---|
src | Source principale | 29 | 22 | .hpp .cpp .c |
input/touch | Source principale | 18 | 23 | .cpp .hpp |
third_party/libuuid | Source principale | 17 | 0 | .c .h |
libgamestream | Source principale | 13 | 8 | .h .c |
system | Source principale | 12 | 10 | .hpp .cpp .c |
video/renderer | Source principale | 9 | 9 | .cpp .hpp |
video | Source principale | 8 | 4 | .cpp .hpp .c |
third_party/h264bitstream | Source principale | 6 | 0 | .h .c |
3ds | Source principale | 3 | 0 | .sh |
third_party/ilclient | Données et infrastructure | 3 | 0 | .c .h |
audio | Source principale | 2 | 0 | .h .cpp |
input | Source principale | 2 | 1 | .cpp .hpp |
third_party/libcec | Source principale | 1 | 0 | .h |
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()
System(SYS, "Artemis-N3DS", "Artemis-N3DS adapte Moonlight Embedded à la famille Nintendo 3DS")
@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()
System_Boundary(SYS, "Artemis-N3DS") {
Container(APP, "Artemis-N3DS", "C++")
}
@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, "Artemis-N3DS") {
Boundary(L0, "Points d’entrée et API", "layer") {
Component(M0_0, "src", "C++", "1 fichiers")
}
Boundary(L1, "Domaine et règles métier", "layer") {
Component(M1_0, "input/touch", "C++", "2 fichiers")
}
Boundary(L2, "Données et infrastructure", "layer") {
Component(M2_0, "libgamestream", "C, C/C++", "2 fichiers")
Component(M2_1, "src", "C++", "2 fichiers")
Component(M2_2, "third_party/ilclient", "C, C/C++", "2 fichiers")
}
Boundary(L3, "Source principale", "layer") {
Component(M3_0, "src", "C++, C", "26 fichiers")
Component(M3_1, "third_party/libuuid", "C, C/C++", "17 fichiers")
Component(M3_2, "input/touch", "C++", "16 fichiers")
Component(M3_3, "system", "C++, C", "12 fichiers")
Component(M3_4, "libgamestream", "C/C++, C", "11 fichiers")
Component(M3_5, "video/renderer", "C++", "9 fichiers")
Component(M3_6, "video", "C++, C", "8 fichiers")
Component(M3_7, "third_party/h264bitstream", "C/C++, C", "6 fichiers")
Component(M3_more, "+5 modules", "", "")
}
Boundary(L4, "Tests", "layer") {
Component(M4_0, "tests", "C++", "1 fichiers")
}
Boundary(L5, "Build, CI et hébergement", "layer") {
Component(M5_0, ".github", ".md, .yml", "7 fichiers")
Component(M5_1, "(root)", ".txt, Dockerfile, Makefile", "3 fichiers")
Component(M5_2, "libgamestream", ".txt", "1 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 "Artemis-N3DS" {
package "src/video/renderer/N3dsRenderer.hpp" as F0 {
class "N3dsRendererBase" as T0_0 {
draw_perf_counters()
write_px_to_framebuffer_gpu()
ensure_3d_enabled()
ensure_3d_disabled()
write24()
}
class "N3dsRendererDualScreenMagnify" as T0_1 {
write_px_to_framebuffer()
set_perf_decode_ticks()
set_crop_region()
accept()
}
class "N3dsRendererNormal" as T0_2 {
write_px_to_framebuffer()
set_perf_decode_ticks()
set_bottom_screen()
}
class "N3dsRendererBottom" as T0_3 {
write_px_to_framebuffer()
write_px_to_framebuffer_raw()
}
class "N3dsRendererDualScreenMirror" as T0_4 {
write_px_to_framebuffer()
set_perf_decode_ticks()
}
}
package "src/input/touch/stream_bottom_ui.hpp" as F1 {
class "BottomCanvas" as T1_0 {
ready()
put()
fill()
clear()
round_fill()
glyph()
}
}
package "src/system/n3ds_connection.hpp" as F2 {
class "N3dsConnectionListener" as T2_0 {
accept()
create_instance()
get_instance()
destroy_instance()
connection_terminated()
connection_log_message()
}
}
package "src/input/n3ds_input.hpp" as F3 {
class "N3dsInput" as T3_0 {
accept()
n3dsinput_handle_event()
force_touchscreen_menu()
_add_gamepad()
_remove_gamepad()
_n3ds_to_li_buttons()
}
}
package "src/input/touch/TouchHandler.hpp" as F4 {
class "TouchHandlerBase" as T4_0 {
handle_touch_down()
handle_touch_up()
handle_touch_hold()
captures_gamepad_input()
handle_navigation()
_handle_touch_down()
}
class "KeyInfo" as T4_1 {
min_x
max_x
min_y
max_y
key_px_size
std
}
}
package "src/system/dispatcher.hpp" as F5 {
class "MessageDispatcher" as T5_0 {
get_instance()
subscribe()
unsubscribe()
post_immediate()
post()
dispatch_all()
}
}
package "src/stream_profile.hpp" as F6 {
class "StreamProfilePreset" as T6_0 {
name
width
height
fps
bitrate_kbps
presentation_mode
_CONFIGURATION
PCONFIGURATION
}
}
package "src/config.hpp" as F7 {
class "_CONFIGURATION" as T7_0 {
stream
app
action
address
mapping
platform
audio_device
config_file
}
}
package "libgamestream/client.h" as F8 {
class "_SERVER_DATA" as T8_0 {
gpuType
paired
unsupported
isNvidiaSoftware
currentGame
serverMajorVersion
gsVersion
modes
}
}
package "libgamestream/xml.c" as F9 {
class "xml_query" as T9_0 {
memory
size
start
data
head
tail
current
}
class "xml_applist_query" as T9_1 {
head
tail
current
memory
size
field
}
}
package "libgamestream/xml.h" as F10 {
class "_APP_LIST" as T10_0 {
name
id
next
height
width
refresh
}
class "_DISPLAY_MODE" as T10_1 {
height
width
refresh
next
}
}
package "src/n3ds_ui.cpp" as F11 {
class "VisibleAction" as T11_0 {
kind
key
std
primary
}
class "AnalogNavState" as T11_1 {
std
value
}
}
package "src/input/touch/keycode_map.hpp" as F12 {
class "key_boundary" as T12_0 {
max_x
key_idx
max_y
std
}
}
package "src/input/touch/MenuTouchHandler.cpp" as F13 {
class "MenuTile" as T13_0 {
label
kind
PresentationMode
}
}
package "src/input/touch/ShortcutsTouchHandler.cpp" as F14 {
class "ShortcutDef" as T14_0 {
label
key
modifiers
}
}
package "libgamestream/mkcert.h" as F15 {
class "_CERT_KEY_PAIR" as T15_0 {
x509
pkey
p12
}
}
}
@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 3DS user
participant P1 as Application flow
participant P2 as In-stream helper hub
participant P3 as Stream connection
participant P4 as Stream telemetry
participant P5 as Performance metrics
participant P6 as Host discovery
participant P7 as Pair records
participant P8 as GameStream client
participant P9 as Console menus
participant P10 as App list cache
participant P11 as Configuration
participant P12 as Stream profiles
participant P13 as Console input
participant P14 as Message dispatcher
P0->>P1: uses
P0->>P2: opens helpers
P0->>P3: chooses stream
P0->>P4: views or saves metrics
P0->>P5: views performance
P1->>P6: finds hosts
P1->>P7: pairs host
P1--)P8: manages host
P1->>P9: shows menus
P1->>P10: lists apps
P1->>P3: starts session
P1->>P11: loads settings
P1->>P12: selects profile
P1->>P13: handles controls
P1->>P14: dispatches events
P1->>P4: uses telemetry store
Étapes en texte (+5)
- 3DS user vers Application flow uses
- 3DS user vers In-stream helper hub opens helpers
- 3DS user vers Stream connection chooses stream
- 3DS user vers Stream telemetry views or saves metrics
- 3DS user vers Performance metrics views performance
- Application flow vers Host discovery finds hosts
- Application flow vers Pair records pairs host
- Application flow vers GameStream client manages host
- Application flow vers Console menus shows menus
- Application flow vers App list cache lists apps
- Application flow vers Stream connection starts session
- Application flow vers Configuration loads settings
- Application flow vers Stream profiles selects profile
- Application flow vers Console input handles controls
- Application flow vers Message dispatcher dispatches events
- Application flow vers Stream telemetry uses telemetry store
- In-stream helper hub vers Message dispatcher posts actions
- In-stream helper hub vers Bottom-screen UI draws interface
- Stream connection vers Video decoders receives video
- Stream connection vers Audio output streams audio
- Host discovery vers Pair records uses records
- GameStream client vers Protocol XML parses responses
- Console input vers Message dispatcher posts events
- Console input vers Touch handlers owns handlers
7.4. 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)
- 59
- Espace de noms anonyme
- 25
mkdirtreelibgamestream/client.c:65load_unique_idlibgamestream/client.c:94load_certlibgamestream/client.c:116namespace { }src/app_list_cache.cpp:10namespace { }src/config.cpp:41namespace { }src/graphics_lifecycle.cpp:7
7.5. Services
Gestionnaire 10
KeyboardTouchHandler_handle_touch_down, _handle_touch_up, _handle_touch_hold et 8 autresMenuTouchHandlercaptures_gamepad_input, handle_navigation, _handle_touch_down et 7 autresShortcutsTouchHandlercaptures_gamepad_input, handle_navigation, _handle_touch_down et 6 autresPerformanceTouchHandlercaptures_gamepad_input, handle_navigation, _handle_touch_down et 5 autresMagnifyTouchHandlercaptures_gamepad_input, handle_navigation, _handle_touch_down et 4 autresGamepadTouchHandler_handle_touch_down, _handle_touch_up, _handle_touch_hold et 1 autresDebugTouchHandler_handle_touch_down, _handle_touch_up, _handle_touch_holdMouseTouchHandler_handle_touch_down, _handle_touch_up, _handle_touch_hold
Service 1
IN3dsRendererwrite_px_to_framebuffer, set_perf_decode_ticks
7.6. Entités et modèle de données 37
Mermaid Diagramme de classes des entités
classDiagram
direction LR
class E0["StreamProfilePreset"] {
+char name
+int width
+int height
+int fps
+int bitrate_kbps
+PresentationMode presentation_mode
}
class E1["_CONFIGURATION"] {
+STREAM_CONFIGURATION stream
+char app
+char action
+char address
+char mapping
+char platform
}
class E2["_SERVER_DATA"] {
+char gpuType
+bool paired
+bool unsupported
+bool isNvidiaSoftware
+int currentGame
+int serverMajorVersion
}
class E3["xml_query"] {
+char memory
+size_t size
+int start
+void data
+PAPP_LIST head
+PAPP_LIST tail
}
class E4["KeyInfo"] {
+int min_x
+int max_x
+int min_y
+int max_y
+int key_px_size
+:map std
}
class E5["_APP_LIST"] {
+char name
+int id
+struct next
+unsigned height
+unsigned width
+unsigned refresh
}
class E6["xml_applist_query"] {
+PAPP_LIST head
+PAPP_LIST tail
+PAPP_LIST current
+char memory
+size_t size
+enum field
}
class E7["VisibleAction"] {
+ActionKind kind
+char key
+:vector std
+bool primary
}
class E8["_DISPLAY_MODE"] {
+unsigned height
+unsigned width
+unsigned refresh
+struct next
}
class E9["key_boundary"] {
+u16 max_x
+int key_idx
+u16 max_y
+:vector std
}
E5 --> E8 : next
Une flèche relie un champ à l’entité que son type nomme.
| Entité | Nature | Premiers champs |
|---|---|---|
StreamProfilePreset | Structure de données | name, width, height, fps, bitrate_kbps, presentation_mode, _CONFIGURATION, PCONFIGURATION |
_CONFIGURATION | Structure de données | stream, app, action, address, mapping, platform, audio_device, config_file |
_SERVER_DATA | Structure de données | gpuType, paired, unsupported, isNvidiaSoftware, currentGame, serverMajorVersion, gsVersion, modes |
xml_query | Structure de données | memory, size, start, data, head, tail, current |
KeyInfo | Structure de données | min_x, max_x, min_y, max_y, key_px_size, std |
_APP_LIST | Structure de données | name, id, next, height, width, refresh |
xml_applist_query | Structure de données | head, tail, current, memory, size, field |
VisibleAction | Structure de données | kind, key, std, primary |
Afficher 6 entités de plus
_DISPLAY_MODE | Structure de données | height, width, refresh, next |
|---|---|---|
key_boundary | Structure de données | max_x, key_idx, max_y, std |
MenuTile | Structure de données | label, kind, PresentationMode |
ShortcutDef | Structure de données | label, key, modifiers |
_CERT_KEY_PAIR | Structure de données | x509, pkey, p12 |
AnalogNavState | Structure de données | std, value |
7.7. 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.
N3dsRendererBaseSource principale, 5 méthodesdraw_perf_counters, write_px_to_framebuffer_gpu, ensure_3d_enabled, ensure_3d_disabled, write24BottomCanvasSource principale, 10 méthodesready, put, fill, clear, round_fill, glyphN3dsConnectionListenerSource principale, 10 méthodesaccept, create_instance, get_instance, destroy_instance, connection_terminated, connection_log_messageN3dsRendererDualScreenMagnifySource principale, 4 méthodeswrite_px_to_framebuffer, set_perf_decode_ticks, set_crop_region, acceptN3dsInputSource principale, 9 méthodesaccept, n3dsinput_handle_event, force_touchscreen_menu, _add_gamepad, _remove_gamepad, _n3ds_to_li_buttonsN3dsRendererNormalSource principale, 3 méthodeswrite_px_to_framebuffer, set_perf_decode_ticks, set_bottom_screenN3dsRendererBottomSource principale, 2 méthodeswrite_px_to_framebuffer, write_px_to_framebuffer_rawN3dsRendererDualScreenMirrorSource principale, 2 méthodeswrite_px_to_framebuffer, set_perf_decode_ticksTouchHandlerBaseSource principale, 8 méthodeshandle_touch_down, handle_touch_up, handle_touch_hold, captures_gamepad_input, handle_navigation, _handle_touch_downMessageDispatcherSource principale, 7 méthodesget_instance, subscribe, unsubscribe, post_immediate, post, dispatch_all
7.8. Intégrations externes
Clients HTTP
7.9. Stack et dépendances
C/C++ (CMake) libgamestream/CMakeLists.txt 5 à l’exécution
Dépendances externes
13 paquets déclarés (13 à l’exécution, 0 pour le développement) dans CMakeLists.txt, Makefile, libgamestream/CMakeLists.txt.
Tableau des paquets 13
| Paquet | Version | Usage | Rôle | Registre |
|---|---|---|---|---|
ALSA | — | exécution | — | C/C++ (CMake) |
Opus | — | exécution | — | C/C++ (CMake) |
Broadcom | — | exécution | — | C/C++ (CMake) |
Freescale | — | exécution | — | C/C++ (CMake) |
Amlogic | — | exécution | — | C/C++ (CMake) |
Rockchip | — | exécution | — | C/C++ (CMake) |
PkgConfig | — | exécution | — | C/C++ (CMake) |
MMAL | — | exécution | — | C/C++ (CMake) |
LibUUID | — | exécution | — | C/C++ (CMake) |
Threads | — | exécution | — | C/C++ (CMake) |
CURL | — | exécution | — | C/C++ (CMake) |
OpenSSL | — | exécution | — | C/C++ (CMake) |
EXPAT | — | exécution | — | C/C++ (CMake) |
7.10. Pipeline CI/CD
2 workflows GitHub Actions, 3 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["CI"]
direction LR
wf0_foundation_tests["Foundation tests<br/>ubuntu-latest"]
wf0_build_cia[["Build CIA and 3DSX<br/>ubuntu-latest"]]
end
subgraph wf1["Release"]
direction LR
wf1_release[["Build and publish release<br/>ubuntu-latest"]]
end
t0(["lancement manuel · push · demande de fusion"])
t1(["lancement manuel · push"])
d0[("Versions GitHub")]
t0 --> wf0_foundation_tests
wf0_foundation_tests --> wf0_build_cia
t1 --> wf1_release
wf1_release -.-> d0
| Workflow | Déclencheurs | Tâches | Publie vers |
|---|---|---|---|
CI.github/workflows/build-cia.yml | lancement manuel, push, demande de fusion |
| — |
Release.github/workflows/release.yml | lancement manuel, push |
| Versions GitHub |
7.11. Déploiement
Mermaid Schéma de déploiement
flowchart LR
repo[("Dépôt GitHub")]
ci[["GitHub Actions<br/>2 workflows"]]
image["Image Docker<br/>FROM devkitpro/devkitarm:latest"]
pub_GitHub_Releases[("Versions GitHub")]
repo -->|"push ou demande de fusion"| ci
ci -->|"docker build"| image
ci -->|"publie"| pub_GitHub_Releases
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 "Image Docker" as H {
artifact "Artemis-N3DS" as APP
}
artifact "FROM devkitpro/devkitarm:latest" as IMG0
IMG0 ..> APP : construit
cloud "Pile réseau console (libnx/li…" as E0
APP ..> E0
@enduml
Où il s’exécute
Publié vers
Images Docker de base
7.12. Sécurité
Contrôles
7.13. Tests automatisés
- Fichiers de test
- 1
- Fichiers source
- 123
- Tests unitaires
- 1
Aucun rapport chiffré de couverture dans les sources analysées.
Où sont les tests
tests 1
Rien trouvé pour: Interface publique, Base de données, Supervision.
8. Déploiement et exploitation
Les ports, le stockage et les relations de démarrage ci-dessous viennent de la configuration du dépôt. depends_on indique l’ordre de démarrage, pas la disponibilité du service.
9. Types et structure des fichiers
77 types déclarés, dont 12 dans l’aperçu des relations de base.
Diagramme des types
classDiagram
direction TB
class tc0387bd4c68b["SelectedHost"] {
<<struct>>
}
class t72fa5c6e15be["RemoteApp"] {
<<struct>>
}
class tf7c6d6aec7da["InputLoopContext"] {
<<struct>>
}
class ta7f589e4be09["VideoDecoderBase"] {
accept()
_accept_touch_state_changed()
_accept_keyboard_state_changed()
}
class tb2f58dc75feb["MockVideoDecoder"] {
}
class t391f53097446["SoftVideoDecoder"] {
submit_decode_unit()
_write_yuv_to_framebuffer()
}
class t4ad2ea8a811e["MvdDecoder"] {
submit_decode_unit()
_decode()
}
class t891d7e467987["_SERVER_DATA"] {
<<struct>>
}
class ta59617f1a5fa["cb_ctx"] {
<<struct>>
}
class tcb0c88684e67["_HTTP_DATA"] {
<<struct>>
}
class taa2e3cf225d0["_CERT_KEY_PAIR"] {
<<struct>>
}
class t91f7677e0266["xml_query"] {
<<struct>>
}
class b34b203f09b57["ISubscriber"] {
<<unresolved_base>>
}
b34b203f09b57 <|-- ta7f589e4be09
ta7f589e4be09 <|-- tb2f58dc75feb
ta7f589e4be09 <|-- t391f53097446
ta7f589e4be09 <|-- t4ad2ea8a811e
Les bases non résolues restent identifiées; les signatures complètes ne sont pas reconstruites.
10. Référence
101 / 101 fichiers admissibles lus (174 dans l’arbre); 0 trop volumineux, 0 échec de lecture et 6 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.
12. Fichiers à lire 3
13. 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.
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.
Décodeur vidéo
Un composant qui reconstruit des images à partir d’un flux vidéo compressé. Le décodage et l’affichage sont des étapes distinctes.
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.
14. Références
- antoinebou12. (2026, 5 novembre). Artemis-N3DS. [Software repository] github.com.
- antoinebou12. (2026, 5 novembre). Artemis-N3DS: README. [Repository documentation] github.com.
- antoinebou12. (2026, 5 novembre). src/n3ds_main.cpp. [Source file] github.com.
- antoinebou12. (2026, 5 novembre). src/hardware_capabilities.cpp. [Source file] github.com.
- antoinebou12. (2026, 5 novembre). src/video/video.hpp. [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, 2 septembre). moonlight-N3DS. [Project article] antoineboucher.info.
- Boucher, A. (2026, 23 octobre). Artemis-N3DS : Le streaming sur un client à deux écrans. [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.