Table des matières
Artemis-Switch : Une image du PC à l’écran
Artemis-Switch est un fork de la famille Moonlight. L’hôte exécute le jeu. Le client reçoit la vidéo et l’audio compressés, affiche les images et renvoie les commandes.
- Langages
- 11Répartition du code
- Composants documentés
- 2Explorer les modules
- Documents source
- 6Lire les instructions
Langages du dépôtC++ 53.78%11
Parts calculées à partir des octets GitHub Linguist.
| Langage | % | Octets |
|---|---|---|
| C++ | 2 312 036 | |
| C | 1 428 795 | |
| Java | 244 691 | |
| CMake | 150 826 | |
| Objective-C++ | 83 846 | |
| Shell | 32 086 |
5 autres langages
| Swift | 0.38% | 16 275 |
| Python | 0.35% | 15 226 |
| GLSL | 0.34% | 14 440 |
| Makefile | 0.02% | 662 |
| PowerShell | 0.01% | 271 |
1. Aperçu
1.1. Pourquoi il existe
Client GameStream C++ accéléré matériellement avec calage d'images NVN pour une fluidité sans saccade.
1.2. Cas d’usage
Diffusion de jeux PC vers Nintendo Switch en mode portable avec latence minimale.
2. Cas d’utilisation
Fork de Moonlight-Switch qui diffuse des jeux PC sur Nintendo Switch, avec mise à l’échelle FSR, profils de flux et télémétrie.
- Jumeler un hôte et diffuser
- Joueur sur SwitchPC hôte GameStream
GameStreamClient.cpp et MoonlightSession.cpp gèrent le jumelage par NIP et les sessions avec Sunshine, Apollo, Vibeshine ou Punktfunk ; DiscoverManager trouve les hôtes et WakeOnLanManager peut les réveiller.
- Régler l’affichage vidéo
- Joueur sur Switch
Fit, Fill, Stretch, zoom et panoramique, rotation et plage complète passent par un seul chemin de présentation deko3d, avec mise à l’échelle FSR/EASU, netteté RCAS et tramage après le décodage NVDEC.
- Enregistrer des profils
- Joueur sur SwitchPC hôte GameStream
Les profils nommés enregistrent FPS (30 à 120), résolution, débit, codec et présentation dans profile.json ; on peut les associer à un hôte, les modifier, les importer ou les exporter (StreamProfileStore.cpp, ProfileEditorDialog.cpp).
- Exporter un banc d’essai
- Joueur sur Switch
La page Performance affiche débit, latence, file d’images, temps GPU et fréquences de la Switch ; les commandes Benchmark démarrer, arrêter et enregistrer écrivent un fichier via app/src/benchmark/BenchmarkExport.cpp.
- Compiler et tester l’appli
- Développeur
Avec devkitA64 et CMake, la cible Moonlight.nro construit le binaire Switch, publié par la CI sous le nom Artemis-Switch.nro ; tests/ contient des tests unitaires portables lancés avec ctest, plus des vérifications Python d’i18n et de publication.
2.1. Scénario : Diffuser un jeu PC sur Switch
- Copier Artemis-Switch.nro dans sdmc:/switch/Artemis-Switch/ et lancer hbmenu par redirection de titre.
- Ouvrir Artemis Switch, choisir le PC hôte et terminer le jumelage par NIP dans l’interface web de l’hôte.
- Créer un profil de flux (par exemple 60 FPS, H.265, Fit avec FSR) et l’associer à cet hôte.
- Lancer une application et appuyer ensemble sur - et + pour ouvrir la surcouche.
- Ouvrir Performance pour suivre le débit et la latence du pipeline, puis lancer et enregistrer un Benchmark.
Fichiers consultésREADME.mdapp/src/streaming/GameStreamClient.cppapp/src/streaming/MoonlightSession.cppapp/src/streaming/StreamProfileStore.cppapp/src/benchmark/BenchmarkExport.cpptests/CMakeLists.txtCMakeLists.txt
3. Démarrage
Ces commandes viennent de la documentation du dépôt. Elles n’ont pas été exécutées pendant cette revue.
git clone --recursive https://github.com/antoinebou12/Artemis-Switch.git
cd Artemis-Switch
cmake -B build/switch -DCMAKE_BUILD_TYPE=Release -DPLATFORM_SWITCH=ON -DUSE_DEKO3D=ON
cmake --build build/switch --target Moonlight.nro --parallelpython tests/i18n_consistency_test.py
python tests/release_contract_test.py
cmake -S tests -B build/tests -DCMAKE_BUILD_TYPE=Debug
cmake --build build/tests --parallel
ctest --test-dir build/tests --output-on-failurepython -m pip install ruff==0.12.10
python scripts/lint.py
cmake -S tests -B build/lint -DCMAKE_BUILD_TYPE=Debug -DARTEMIS_STRICT_WARNINGS=ON -DARTEMIS_ENABLE_CLANG_TIDY=ON
cmake --build build/lint --parallelcmake -S ci/integration -B build/integration -DCMAKE_BUILD_TYPE=Debug
cmake --build build/integration --parallel
ctest --test-dir build/integration --output-on-failurecd android-project./build_libromfs_generator.shexport JAVA_HOME=/Applications/Android\ Studio.app/Contents/jbr/Contents/Home
export ANDROID_SDK_ROOT=~/Library/Android/sdk
./gradlew assembleDebug
./gradlew installDebug4. 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. Install the Artemis Switch NRO
docs/NRO_INSTALL.md
Use one of these files from dist/nro:
- Easy install: extract Artemis-Switch-SD.zip to the root of the Switch SD card.
- Manual install: copy Artemis-Switch.nro to sdmc:/switch/Artemis-Switch/Artemis-Switch.nro. Launch the Homebrew Menu with title redirection/full RAM mode, then select Artemis Switch. Applet mode is not supported for reliable streaming. The ZIP contains only the ready-to-copy switch/Artemis-Switch/Artemis-Switch.nro layout. Apollo and Sunshine both use the normal Moonlight/GameStream pairing flow.
4.2. Install
docs/source/install.md
4.3. Easy install
docs/source/install.md
4.4. Manual install
docs/source/install.md
Configuration et utilisation
4.5. Recommended host and clients
README.md
4.6. Client (device)
README.md
| Client | Device | Notes |
|---|---|---|
| Artemis Switch (this app) | Nintendo Switch | Moonlight-Switch fork with FSR/RCAS, stream profiles, and Switch presentation. |
| Artemide | Android | Highly recommended on Android: ultra-low latency (ULL), direct presentation, built-in FSR upscaling. FSR Performance / Balanced / Quality presets inspired this fork. |
| Artemis (Moonlight Noir) | Android | Apollo’s companion client (virtual display / host UX inspiration). |
| Moonlight | PC, Android, iOS, … | Official clients. |
| Moonlight V+ | Android | Alternative Android fork (frame-gen and extra host tools). |
Développement et contributions
4.7. Developer build
README.md
Prerequisites: Git, CMake 3.20 or newer, and a standard devkitPro devkitA64 environment. Clone recursively so every dependency under extern/ is initialized: Repository layout
| Path | Purpose |
|---|---|
| app/src/ | Application, streaming, renderer, input, and feature implementation |
| app/include/ | UI and application declarations |
| resources/ | Borealis XML, images, shaders, and translations |
| tests/ | Portable unit and contract tests |
| ci/integration/ | Cross-feature integration test build |
| docs/ | GitHub Pages source and engineering notes |
| .github/workflows/ | Build, test, sanitizer, and release automation |
| extern/ | Pinned third-party dependencies and Git submodules |
| Keep Switch-specific behavior behind the existing platform and capability gates. | |
| Do not make project-specific changes inside vendored extern/ dependencies. |
4.8. Developer validation
README.md
Documentation source
README.mddocs/README.mddocs/NRO_INSTALL.mddocs/source/install.mdapp/platforms/android-project/README.mdapp/platforms/android-project/README_ZH.md
6 documents lus parmi 6 candidats.
5. Fonctions et composants 2
- Session et interface
- L’interface Borealis gère le choix de l’hôte et les réglages. MoonlightSession coordonne le streaming et son fournisseur Switch choisit les implémentations vidéo et audio. L’interface et le traitement des médias ont des cycles de vie différents.
- Sortie propre à la plateforme
- Le fournisseur construit FFmpegVideoDecoder. Avec BOREALIS_USE_DEKO3D, il choisit ArtemisDKVideoRenderer; d’autres options choisissent d’autres moteurs. L’audio Switch utilise AudrenAudioRenderer. Ces choix sont explicites à la compilation.
6. Architecture
Ouvrez un composant pour suivre ses connexions, ou explorez le diagramme complet.
Hôte GameStream
- Vers Session de streaming
- Depuis Session de streaming
Session de streaming
- Depuis Hôte GameStream
- Vers Décodeur vidéo FFmpeg
- Depuis Commandes manette
- Vers Hôte GameStream
Décodeur vidéo FFmpeg
- Depuis Session de streaming
- Vers Rendu deko3d
Rendu deko3d
- Depuis Décodeur vidéo FFmpeg
- Vers Écran Switch
Écran Switch
- Depuis Rendu deko3d
Commandes manette
- Vers Session de streaming
Mermaid Diagramme interactif
Vue générale des composants et des échanges vérifiés dans le dépôt.

flowchart LR
n0["Hôte GameStream"]
n1["Session de streaming"]
n2["Décodeur vidéo FFmpeg"]
n3["Rendu deko3d"]
n4["Écran Switch"]
n5["Commandes manette"]
n0 --> n1
n1 --> n2
n2 --> n3
n3 --> n4
n5 --> n1
n1 --> n0
Version texte du diagramme
- Hôte GameStream → Session de streaming
- Session de streaming → Décodeur vidéo FFmpeg
- Décodeur vidéo FFmpeg → Rendu deko3d
- Rendu deko3d → Écran Switch
- Commandes manette → Session de streaming
- Session de streaming → Hôte GameStream
Suivre un parcours dans le code
Lisez les méthodes du fournisseur pour identifier le moteur compilé, puis suivez les images décodées vers ce moteur. Les délais réseau, de décodage et d’affichage doivent être mesurés séparément pour expliquer un flux lent.
7. Dossier technique
Établi à partir du code au commit 33e6854 (634 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["resources/xml<br/>19 fichiers"]
presentation_1["features/ui<br/>9 fichiers"]
presentation_2["platforms/android-project<br/>5 fichiers"]
presentation_3["views<br/>2 fichiers"]
end
subgraph L_application["Services applicatifs"]
direction TB
application_0["src<br/>51 fichiers"]
application_1["remote_access/tailscale<br/>41 fichiers"]
application_2["streaming<br/>37 fichiers"]
application_3["include<br/>27 fichiers"]
application_more["+28"]
end
subgraph L_infrastructure["Données et infrastructure"]
direction TB
infrastructure_0["switch/libavutil<br/>100 fichiers"]
infrastructure_1["switch/libavcodec<br/>25 fichiers"]
infrastructure_2["switch/curl<br/>12 fichiers"]
infrastructure_3["remote_access/providers<br/>6 fichiers"]
infrastructure_more["+2"]
end
subgraph L_core["Source principale"]
direction TB
core_0["(root)<br/>1 fichier"]
core_1["docs/source<br/>1 fichier"]
end
subgraph L_tests["Tests"]
direction TB
tests_0["tests<br/>78 fichiers"]
end
subgraph L_hosting["Build, CI et hébergement"]
direction TB
hosting_0[".github<br/>15 fichiers"]
hosting_1["(root)<br/>2 fichiers"]
hosting_2["platforms<br/>2 fichiers"]
hosting_3["ci<br/>1 fichier"]
hosting_more["+2"]
end
L_presentation ~~~ L_application
L_application ~~~ L_infrastructure
L_infrastructure ~~~ L_core
L_core ~~~ L_tests
L_core ~~~ L_hosting
| Module | Couche | Fichiers | Types | Extensions |
|---|---|---|---|---|
switch/libavutil | Données et infrastructure | 100 | 195 | .h |
src | Services applicatifs | 51 | 39 | .cpp |
remote_access/tailscale | Services applicatifs | 41 | 62 | .cpp .hpp .h |
streaming | Services applicatifs | 37 | 32 | .hpp .cpp |
include | Services applicatifs | 27 | 30 | .hpp |
switch/libavcodec | Données et infrastructure | 25 | 30 | .h |
platforms/android-project | Services applicatifs | 24 | 35 | .java .xml .gradle |
streaming/video | Services applicatifs | 24 | 16 | .hpp .glsl .cpp |
features/input | Services applicatifs | 21 | 22 | .hpp .cpp |
resources/xml | Présentation | 19 | 0 | .xml |
remote_access | Services applicatifs | 17 | 20 | .hpp .cpp |
features/video | Services applicatifs | 13 | 8 | .hpp .cpp |
switch/curl | Données et infrastructure | 12 | 18 | .h |
benchmark | Services applicatifs | 11 | 13 | .hpp .cpp |
29 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, "Artemis-Switch", "Artemis-Switch est un fork de la famille Moonlight")
SystemDb(D0, "Active Record")
Rel(P_cli, SYS, "Utilise")
Rel(SYS, D0, "Lit et écrit")
@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, "Artemis-Switch") {
Container(C0, "artemis-switch-build", "Docker")
ContainerDb(DB0, "Active Record", "")
}
Rel(P_cli, C0, "Utilise")
Rel(C0, DB0, "Lit et écrit")
@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-Switch") {
Boundary(L0, "Présentation", "layer") {
Component(M0_0, "resources/xml", ".xml", "19 fichiers")
Component(M0_1, "features/ui", "C++", "9 fichiers")
Component(M0_2, "platforms/android-project", ".xml", "5 fichiers")
Component(M0_3, "views", "C++", "2 fichiers")
Component(M0_4, "docs/_static", ".css", "1 fichiers")
}
Boundary(L1, "Services applicatifs", "layer") {
Component(M1_0, "src", "C++", "51 fichiers")
Component(M1_1, "remote_access/tailscale", "C++, C/C++", "41 fichiers")
Component(M1_2, "streaming", "C++", "37 fichiers")
Component(M1_3, "include", "C++", "27 fichiers")
Component(M1_4, "streaming/video", "C++, .glsl", "24 fichiers")
Component(M1_5, "features/input", "C++", "21 fichiers")
Component(M1_6, "platforms/android-project", "Java, .gradle, .xml", "19 fichiers")
Component(M1_7, "remote_access", "C++", "17 fichiers")
Component(M1_more, "+24 modules", "", "")
}
Boundary(L2, "Données et infrastructure", "layer") {
Component(M2_0, "switch/libavutil", "C/C++", "100 fichiers")
Component(M2_1, "switch/libavcodec", "C/C++", "25 fichiers")
Component(M2_2, "switch/curl", "C/C++", "12 fichiers")
Component(M2_3, "remote_access/providers", "C++", "6 fichiers")
Component(M2_4, "switch/libavformat", "C/C++", "4 fichiers")
Component(M2_5, "switch/libswresample", "C/C++", "3 fichiers")
}
Boundary(L3, "Source principale", "layer") {
Component(M3_0, "(root)", ".sh", "1 fichiers")
Component(M3_1, "docs/source", "Python", "1 fichiers")
}
Boundary(L4, "Tests", "layer") {
Component(M4_0, "tests", "C++, Python", "78 fichiers")
}
Boundary(L5, "Build, CI et hébergement", "layer") {
Component(M5_0, ".github", ".yml, .md", "15 fichiers")
Component(M5_1, "(root)", ".txt, .yml", "2 fichiers")
Component(M5_2, "platforms", ".txt", "2 fichiers")
Component(M5_3, "ci", ".txt", "1 fichiers")
Component(M5_4, "docs", "Makefile", "1 fichiers")
Component(M5_5, "extern", ".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-Switch" {
package "app/src/utils/Settings.hpp" as F0 {
class "Settings" as T0_0 {
working_dir()
set_working_dir()
launch_path()
set_launch_path()
key_dir()
boxart_dir()
}
}
package "app/platforms/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java" as F1 {
class "SDLActivity" as T1_0 {
getMotionListener()
main()
getMainSharedObject()
getMainFunction()
getLibraries()
loadLibraries()
}
}
package "app/src/remote_access/tailscale/TailscaleWgxRoute.cpp" as F2 {
class "RealWgxBackend" as T2_0 {
realEgressCallback()
sendEgress()
toSockaddr()
fromSockaddr()
discoverLanAddress()
startDirectPath()
}
}
package "app/src/streaming/MoonlightSession.hpp" as F3 {
class "MoonlightSession" as T3_0 {
set_provider()
start()
stop()
stopForApplicationExit()
set_address()
setApolloLaunchOptions()
}
}
package "app/src/streaming/AVFrameHolder.hpp" as F4 {
class "AVFrameQueue" as T4_0 {
push()
pushTransferred()
recycleWriteFrame()
configure()
capacityFor()
size()
}
class "AVFrameHolder" as T4_1 {
push()
pushTransferred()
get()
acquireWriteFrame()
recycleWriteFrame()
prepare()
}
}
package "app/src/streaming/FramePipelineTelemetry.hpp" as F5 {
class "FramePipelineTelemetry" as T5_0 {
reset()
noteStreamStart()
noteFirstPacket()
noteDecodedFrame()
consumePendingDecodeTiming()
noteFrameQueued()
}
}
package "app/src/remote_access/tailscale/TailscaleCore.hpp" as F6 {
class "TailscaleCore" as T6_0 {
start()
stop()
snapshot()
resolveRoute()
activateRoute()
prepareRouteForStreaming()
}
}
package "app/platforms/android-project/app/src/main/java/org/libsdl/app/SDLSurface.java" as F7 {
class "SDLSurface" as T7_0 {
handlePause()
handleResume()
getNativeSurface()
enableMediaCodecOverlay()
surfaceCreated()
surfaceDestroyed()
}
}
package "app/src/remote_access/tailscale/relay/TsLwipRelay.hpp" as F8 {
class "TsLwipRelay" as T8_0 {
start()
stop()
addTcp()
addUdp()
isRunning()
log()
}
}
package "lib/switch/include/libavcodec/codec.h" as F9 {
class "AVCodec" as T9_0 {
name
long_name
type
id
capabilities
max_lowres
supported_framerates
pix_fmts
}
}
package "lib/switch/include/libavcodec/avcodec.h" as F10 {
class "AVCodecContext" as T10_0 {
av_class
log_level_offset
codec_type
codec
codec_id
codec_tag
priv_data
internal
}
class "AVCodecParserContext" as T10_1 {
priv_data
parser
frame_offset
cur_offset
next_frame_offset
pict_type
repeat_pict
pts
}
}
package "lib/switch/include/libavcodec/codec_desc.h" as F11 {
class "AVCodecDescriptor" as T11_0 {
id
type
name
long_name
props
NULL
mime_types
profiles
}
}
package "lib/switch/include/libavutil/dovi_meta.h" as F12 {
class "AVDOVIColorMetadata" as T12_0 {
dm_metadata_id
scene_refresh_flag
ycc_to_rgb_matrix
ycc_to_rgb_offset
rgb_to_lms_matrix
signal_eotf
signal_eotf_param0
signal_eotf_param1
}
class "AVDOVIDataMapping" as T12_1 {
vdr_rpu_id
mapping_color_space
mapping_chroma_format_idc
curves
nlq_method_idc
num_x_partitions
num_y_partitions
nlq
}
class "AVDOVIDecoderConfigurationRecord" as T12_2 {
dv_version_major
dv_version_minor
dv_profile
dv_level
rpu_present_flag
el_present_flag
bl_present_flag
dv_bl_signal_compatibility_id
}
class "AVDOVIDmData" as T12_3 {
level
l1
l2
l3
l4
l5
l6
l8
}
class "AVDOVIDmLevel1" as T12_4 {
min_pq
max_pq
avg_pq
target_max_pq
trim_slope
trim_offset
trim_power
trim_chroma_weight
}
class "AVDOVIDmLevel10" as T12_5 {
target_display_index
target_max_pq
target_min_pq
target_primary_index
target_display_primaries
content_type
whitepoint
reference_mode_flag
}
class "AVDOVIDmLevel11" as T12_6 {
content_type
whitepoint
reference_mode_flag
sharpness
noise_reduction
mpeg_noise_reduction
frame_rate_conversion
brightness
}
class "AVDOVIDmLevel2" as T12_7 {
target_max_pq
trim_slope
trim_offset
trim_power
trim_chroma_weight
trim_saturation_gain
ms_weight
min_pq_offset
}
class "AVDOVIDmLevel254" as T12_8 {
dm_mode
dm_version_index
dm_run_mode
dm_run_version
dm_debug
level
l1
l2
}
class "AVDOVIDmLevel255" as T12_9 {
dm_run_mode
dm_run_version
dm_debug
level
l1
l2
l3
l4
}
}
}
@enduml
7.3. Interface publique
Du code extérieur peut utiliser tout ce qui est listé ici. Le projet déclare aussi 637 types publics.
Ligne de commande 2
Points d’entrée
app/src/main.cppfichier d’entrée
En-têtes publics 175
app/include/about_tab.hpp app/include/active_remote_route.hpp app/include/add_host_tab.hpp app/include/app_cell.hpp app/include/app_list_view.hpp app/include/artemis_settings_tab.hpp app/include/button_selecting_dialog.hpp app/include/discovery_candidate.hpp app/include/favorite_tab.hpp app/include/forwarder_maker.hpp
7.4. Interface privée
Ces noms sont internes selon les conventions du langage: tiret bas initial, private, static ou pub(crate).
- Espace de noms anonyme
- 98
- Méthode privée ou interne
- 65
- Fonction static (locale au fichier)
- 35
onDestroyapp/platforms/android-project/app/src/main/java/com/borealis/demo/DemoActivity.java:8getLibrariesapp/platforms/android-project/app/src/main/java/com/borealis/demo/DemoActivity.java:20GattOperationapp/platforms/android-project/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java:82namespace { }app/src/add_host_tab.cpp:18namespace { }app/src/add_host_tab.cpp:252namespace { }app/src/add_host_tab.cpp:516_mbedtls_sha1app/src/crypto/MbedTLSCryptoManager.cpp:21_mbedtls_sha256app/src/crypto/MbedTLSCryptoManager.cpp:30_mbedtls_cert_signatureapp/src/crypto/MbedTLSCryptoManager.cpp:39
7.5. Services
Service 25
HIDDeviceManageracquire, release, getContext et 32 autresMoonlightInputManagerdropInput, resetForNewSession, stopAllRumble et 19 autresRemoteAccessManagerregisterProvider, providers, availableProviders et 18 autresSDLControllerManagernativeSetupJNI, nativeAddJoystick, nativeRemoveJoystick et 16 autresMbedTLSCryptoManagerload_cert_key_pair, generate_new_cert_key_pair, remove_cert_key_pair et 11 autresOpenSSLCryptoManagerload_cert_key_pair, generate_new_cert_key_pair, remove_cert_key_pair et 11 autresWireGuardManagerenable_from_settings, disable, default_config_path et 10 autresD3D11VideoRendererdraw, ensureContext, cleanup et 9 autres
Magasin d’état 13
StreamConfigProfileStoreget, create, rename et 20 autresWakeOnLanOverridesStoreget, set, clear et 3 autresDisplayTransformStoreget, set, setRotation et 3 autresZoomPanStoresetRemember, setState, reset et 3 autresApolloHostOptionsStoreget, set, reload et 2 autresInputSettingsStoresetPointer, setShortcuts, reload et 2 autresVideoScaleStoreget, set, reload et 2 autresSwitchMotionPolicyStoreset, reload, save et 1 autres
Fournisseur 7
NetBirdProviderid, name, available et 18 autresTailscaleProviderid, name, available et 16 autresIRemoteAccessProviderid, name, available et 15 autresWireGuardProviderid, name, available et 12 autresMoonlightShortcutsProviderMoonlightSessionDecoderAndRenderProviderSwitchMoonlightSessionDecoderAndRenderProvider
Gestionnaire 5
SDLJoystickHandlerpollInputDevices, getJoystick, handleMotionEvent et 7 autresSDLHapticHandlerrun, rumble, stop et 2 autresSDLClipboardHandlerclipboardHasText, clipboardGetText, clipboardSetText et 1 autresBorealisHandlerhandleMessageSDLCommandHandlerhandleMessage
Client 2
GameStreamClientserver_data, active_address, start et 18 autresNoiseClientbegin, complete, ready et 7 autres
Contrôleur 1
HIDDeviceBLESteamControllergetIdentifier, getGatt, connectGatt et 37 autres
7.6. Entités et modèle de données 436
Mermaid Diagramme de classes des entités
classDiagram
direction LR
class E0["AVCodec"] {
+char name
+char long_name
+enum type
+enum id
+int capabilities
+uint8_t max_lowres
}
class E1["AVCodecContext"] {
+AVClass av_class
+int log_level_offset
+enum codec_type
+struct codec
+enum codec_id
+unsigned codec_tag
}
class E2["AVCodecDescriptor"] {
+enum id
+enum type
+char name
+char long_name
+int props
+NULL
}
class E3["AVCodecParserContext"] {
+void priv_data
+struct parser
+int64_t frame_offset
+int64_t cur_offset
+int64_t next_frame_offset
+int pict_type
}
class E4["AVDOVIColorMetadata"] {
+uint8_t dm_metadata_id
+uint8_t scene_refresh_flag
+AVRational ycc_to_rgb_matrix
+AVRational ycc_to_rgb_offset
+AVRational rgb_to_lms_matrix
+uint16_t signal_eotf
}
class E5["AVDOVIDataMapping"] {
+uint8_t vdr_rpu_id
+uint8_t mapping_color_space
+uint8_t mapping_chroma_format_idc
+AVDOVIReshapingCurve curves
+enum nlq_method_idc
+uint32_t num_x_partitions
}
class E6["AVDOVIDecoderConfigurationRecord"] {
+uint8_t dv_version_major
+uint8_t dv_version_minor
+uint8_t dv_profile
+uint8_t dv_level
+uint8_t rpu_present_flag
+uint8_t el_present_flag
}
class E7["AVDOVIDmData"] {
+uint8_t level
+AVDOVIDmLevel1 l1
+AVDOVIDmLevel2 l2
+AVDOVIDmLevel3 l3
+AVDOVIDmLevel4 l4
+AVDOVIDmLevel5 l5
}
class E8["AVDOVIDmLevel1"] {
+uint16_t min_pq
+uint16_t max_pq
+uint16_t avg_pq
+uint16_t target_max_pq
+uint16_t trim_slope
+uint16_t trim_offset
}
class E9["AVDOVIDmLevel10"] {
+uint8_t target_display_index
+uint16_t target_max_pq
+uint16_t target_min_pq
+uint8_t target_primary_index
+AVColorPrimariesDesc target_display_primaries
+uint8_t content_type
}
E1 --> E0 : codec
E7 --> E8 : l1
Une flèche relie un champ à l’entité que son type nomme.
| Entité | Nature | Premiers champs |
|---|---|---|
AVCodec | Structure de données | name, long_name, type, id, capabilities, max_lowres, supported_framerates, pix_fmts |
AVCodecContext | Structure de données | av_class, log_level_offset, codec_type, codec, codec_id, codec_tag, priv_data, internal |
AVCodecDescriptor | Structure de données | id, type, name, long_name, props, NULL, mime_types, profiles |
AVCodecParserContext | Structure de données | priv_data, parser, frame_offset, cur_offset, next_frame_offset, pict_type, repeat_pict, pts |
AVDOVIColorMetadata | Structure de données | dm_metadata_id, scene_refresh_flag, ycc_to_rgb_matrix, ycc_to_rgb_offset, rgb_to_lms_matrix, signal_eotf, signal_eotf_param0, signal_eotf_param1 |
AVDOVIDataMapping | Structure de données | vdr_rpu_id, mapping_color_space, mapping_chroma_format_idc, curves, nlq_method_idc, num_x_partitions, num_y_partitions, nlq |
AVDOVIDecoderConfigurationRecord | Structure de données | dv_version_major, dv_version_minor, dv_profile, dv_level, rpu_present_flag, el_present_flag, bl_present_flag, dv_bl_signal_compatibility_id |
AVDOVIDmData | Structure de données | level, l1, l2, l3, l4, l5, l6, l8 |
Afficher 6 entités de plus
AVDOVIDmLevel1 | Structure de données | min_pq, max_pq, avg_pq, target_max_pq, trim_slope, trim_offset, trim_power, trim_chroma_weight |
|---|---|---|
AVDOVIDmLevel10 | Structure de données | target_display_index, target_max_pq, target_min_pq, target_primary_index, target_display_primaries, content_type, whitepoint, reference_mode_flag |
AVDOVIDmLevel11 | Structure de données | content_type, whitepoint, reference_mode_flag, sharpness, noise_reduction, mpeg_noise_reduction, frame_rate_conversion, brightness |
AVDOVIDmLevel2 | Structure de données | target_max_pq, trim_slope, trim_offset, trim_power, trim_chroma_weight, trim_saturation_gain, ms_weight, min_pq_offset |
AVDOVIDmLevel254 | Structure de données | dm_mode, dm_version_index, dm_run_mode, dm_run_version, dm_debug, level, l1, l2 |
AVDOVIDmLevel255 | Structure de données | dm_run_mode, dm_run_version, dm_debug, level, l1, l2, l3, l4 |
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.
SettingsServices applicatifs, 157 méthodesworking_dir, set_working_dir, launch_path, set_launch_path, key_dir, boxart_dirSDLActivityServices applicatifs, 116 méthodesgetMotionListener, main, getMainSharedObject, getMainFunction, getLibraries, loadLibrariesRealWgxBackendServices applicatifs, 37 méthodesrealEgressCallback, sendEgress, toSockaddr, fromSockaddr, discoverLanAddress, startDirectPathMoonlightSessionServices applicatifs, 35 méthodesset_provider, start, stop, stopForApplicationExit, set_address, setApolloLaunchOptionsAVFrameQueueServices applicatifs, 28 méthodespush, pushTransferred, recycleWriteFrame, configure, capacityFor, sizeAVFrameHolderServices applicatifs, 23 méthodespush, pushTransferred, get, acquireWriteFrame, recycleWriteFrame, prepareFramePipelineTelemetryServices applicatifs, 16 méthodesreset, noteStreamStart, noteFirstPacket, noteDecodedFrame, consumePendingDecodeTiming, noteFrameQueuedTailscaleCoreServices applicatifs, 21 méthodesstart, stop, snapshot, resolveRoute, activateRoute, prepareRouteForStreamingSDLSurfaceServices applicatifs, 20 méthodeshandlePause, handleResume, getNativeSurface, enableMediaCodecOverlay, surfaceCreated, surfaceDestroyedTsLwipRelayServices applicatifs, 20 méthodesstart, stop, addTcp, addUdp, isRunning, log
7.8. Base de données et persistance
7.9. Intégrations externes
Clients HTTP
Hôtes nommés dans le code
api.netbird.io2 fichiersapp/src/artemis_settings_tab.cpp:616aomediacodec.github.io1 fichierslib/switch/include/libavutil/iamf.h:27gbatemp.net1 fichiersapp/src/about_tab.cpp:80www.patreon.com1 fichiersapp/src/about_tab.cpp:69
7.10. Stack et dépendances
JVM (Gradle) app/platforms/android-project/app/build.gradle
compileSdk Version minSdk Version targetSdk Version
Dépendances externes
8 paquets déclarés (8 à l’exécution, 0 pour le développement) dans CMakeLists.txt, app/platforms/android-project/app/build.gradle.
Tableau des paquets 8
| Paquet | Version | Usage | Rôle | Registre |
|---|---|---|---|---|
PkgConfig | — | exécution | — | C/C++ (CMake) |
MbedTLS | — | exécution | — | C/C++ (CMake) |
OpenSSL | — | exécution | — | C/C++ (CMake) |
SDL2 | — | exécution | Graphisme, image et 3D | C/C++ (CMake) |
CURL | — | exécution | — | C/C++ (CMake) |
Jansson | — | exécution | — | C/C++ (CMake) |
EXPAT | — | exécution | — | C/C++ (CMake) |
PNG | — | exécution | — | C/C++ (CMake) |
7.11. Pipeline CI/CD
14 workflows GitHub Actions, 27 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["All Builds"]
direction LR
wf0_switch["Nintendo Switch<br/>réutilise docker-image.yml"]
wf0_psvita["PS Vita<br/>réutilise psvita.yml"]
wf0_android["Android<br/>réutilise android-apk.yml"]
wf0_macos["macOS<br/>réutilise macos.yml"]
wf0_windows["Windows<br/>réutilise windows.yml"]
wf0_linux["Linux<br/>réutilise linux.yml"]
end
subgraph wf1["Android APK"]
direction LR
wf1_build["build<br/>ubuntu-latest"]
end
subgraph wf2["Build Artemis Switch NRO into dist (one-sho…"]
direction LR
wf2_build_and_commit[["build-and-commit<br/>ubuntu-latest"]]
end
subgraph wf3["Build Artemis Switch"]
direction LR
wf3_build[["build<br/>ubuntu-latest"]]
end
subgraph wf4["Docs"]
direction LR
wf4_deploy[["deploy<br/>ubuntu-latest"]]
end
subgraph wf5["Feature and Integration CI"]
direction LR
wf5_portable_integration[["Consolidated portable integration<br/>ubuntu-latest"]]
wf5_release_package_contract["Release source package contract<br/>ubuntu-latest"]
wf5_sanitizer_integration["ASan + UBSan integration<br/>ubuntu-latest"]
wf5_ci_summary["Artemis CI summary<br/>ubuntu-latest"]
end
t0(["This · workflow · fans · out · to · six"])
t1(["appelé par un workflow"])
t2(["push"])
t3(["lancement manuel · appelé par un workflow"])
t4(["push · lancement manuel"])
t5(["Topic · branches · run · through · demande …"])
d0[("GitHub Pages")]
t0 --> wf0_switch
t0 --> wf0_psvita
t0 --> wf0_android
t0 --> wf0_macos
t0 --> wf0_windows
t0 --> wf0_linux
t1 --> wf1_build
t2 --> wf2_build_and_commit
t3 --> wf3_build
t4 --> wf4_deploy
wf4_deploy -.-> d0
t5 --> wf5_portable_integration
t5 --> wf5_release_package_contract
t5 --> wf5_sanitizer_integration
wf5_portable_integration --> wf5_ci_summary
wf5_release_package_contract --> wf5_ci_summary
wf5_sanitizer_integration --> wf5_ci_summary
| Workflow | Déclencheurs | Tâches | Publie vers |
|---|---|---|---|
All Builds.github/workflows/all-builds.yml | This, workflow, fans, out, to, six |
| — |
Android APK.github/workflows/android-apk.yml | appelé par un workflow |
| — |
Build Artemis Switch NRO into dist (one-shot).github/workflows/build-dist-once.yml | push |
| — |
Build Artemis Switch.github/workflows/docker-image.yml | lancement manuel, appelé par un workflow |
| — |
Docs.github/workflows/docs.yml | push, lancement manuel |
| GitHub Pages |
Feature and Integration CI.github/workflows/feature-integration-ci.yml | Topic, branches, run, through, demande de fusion, Keeping |
| — |
Lint.github/workflows/lint.yml | Topic, branches, are, linted, through, demande de fusion |
| — |
Linux Builds.github/workflows/linux.yml | appelé par un workflow, lancement manuel |
| — |
6 autres workflows ne sont pas affichés.
7.12. Déploiement
Mermaid Schéma de déploiement
flowchart LR
repo[("Dépôt GitHub")]
ci[["GitHub Actions<br/>14 workflows"]]
pub_GitHub_Pages[("GitHub Pages")]
pub_GitHub_Releases[("Versions GitHub")]
subgraph compose["Docker Compose"]
svc_artemis_switch_build["artemis-switch-build"]
end
repo -->|"push ou demande de fusion"| ci
ci -->|"publie"| pub_GitHub_Pages
ci -->|"publie"| pub_GitHub_Releases
repo -->|"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 "artemis-switch-build" as N0 <<container>>
}
database "Active Record" as DB0
N0 --> DB0
cloud "Pile réseau console (libnx/li…" as E0
N0 ..> E0
cloud "WebSocket" as E1
N0 ..> E1
@enduml
Où il s’exécute
Publié vers
Services Compose
artemis-switch-build
7.13. Supervision
Ce que le code consigne, mesure et expose pour savoir s’il fonctionne.
7.14. Sécurité
Contrôles
Chaîne d’approvisionnement
Variables d’environnement 3
La page reprend les noms sans leurs valeurs et souligne ceux qui ressemblent à des secrets.
7.15. Tests automatisés
- Fichiers de test
- 78
- Fichiers source
- 567
- Tests unitaires
- 75
- Tests performance
- 2
- Tests intégration
- 1
Couverture de code
Aucun rapport chiffré de couverture dans les sources analysées.
Où sont les tests
tests 78
Intégration continue
- Lint
ruff- Unit tests
ctest
UML Pipeline CI
Le workflow GitHub Actions principal suit ces étapes. Les tâches lancées en parallèle sont côte à côte. 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
title Feature and Integration CI
start
fork
partition "Consolidated portable integra…" {
:Checkout;
:Validate localization JSON syntax;
:Validate Artemis English/French translation…;
:Validate release/CD contract;
:Validate isolated VPN build contract;
:Configure unit suite;
:Build unit suite;
:Run unit suite;
}
fork again
partition "Release source package contra…" {
:Checkout repository and submodules;
:Build dry-run source packages;
:Inspect source packages;
}
fork again
partition "ASan + UBSan integration" {
:Checkout;
:Configure;
:Build;
:Test;
}
fork again
partition "Artemis CI summary" {
:Require all integration jobs;
}
end fork
stop
@enduml
8. Types et structure des fichiers
651 types déclarés, dont 12 dans l’aperçu des relations de base.
Diagramme des types
classDiagram
direction TB
class t27b200e5e641["AboutTab"] {
}
class t1d8fa37de9f9["ActiveRemoteRoute"] {
<<struct>>
}
class t76b3bc05a24d["AddHostTab"] {
findHost()
stopSearchHost()
connectHost()
fillSearchBox()
}
class t71f8fd94394b["AppCell"] {
setFavorite()
updateFavoriteAction()
}
class tcb6c23872ee9["AppListView"] {
onLayout()
willAppear()
draw()
blockInput()
}
class t5416fcf29d4d["ArtemisSettingsTab"] {
refreshValues()
editWidth()
editHeight()
refreshRemoteAccessRows()
}
class taa0a005beea4["ButtonSelectingDialog"] {
open()
reloadLabel()
buttonsText()
draw()
}
class t0cab5ff3d09b["DiscoveryCandidate"] {
<<struct>>
isDirect()
}
class t9649c53d1d2d["FavoriteTab"] {
refreshIfNeeded()
setRefreshNeeded()
updateAppList()
}
class tae773a498879["ClickGestureRecognizer"] {
recognitionLoop()
}
class t03d6e2ef334c["FingersGestureRecognizer"] {
recognitionLoop()
}
class t96b64c4eb4d8["TwoFingerScrollState"] {
<<struct>>
}
class b66d2434ea20a["brls::Box"] {
<<unresolved_base>>
}
b66d2434ea20a <|-- t27b200e5e641
class b12e371ab4244["brls::Box"] {
<<unresolved_base>>
}
b12e371ab4244 <|-- t76b3bc05a24d
class b9fb6426c89d6["Box"] {
<<unresolved_base>>
}
b9fb6426c89d6 <|-- t71f8fd94394b
class bd9fae1c39e24["Box"] {
<<unresolved_base>>
}
bd9fae1c39e24 <|-- tcb6c23872ee9
class bc8de2cffa73c["brls::Box"] {
<<unresolved_base>>
}
bc8de2cffa73c <|-- t5416fcf29d4d
class b4629afd0f9ec["Dialog"] {
<<unresolved_base>>
}
b4629afd0f9ec <|-- taa0a005beea4
class b3def5b4c744e["brls::Box"] {
<<unresolved_base>>
}
b3def5b4c744e <|-- t9649c53d1d2d
class b1c2ec6b5bcbd["brls::GestureRecognizer"] {
<<unresolved_base>>
}
b1c2ec6b5bcbd <|-- tae773a498879
class b905c043cc5ee["brls::GestureRecognizer"] {
<<unresolved_base>>
}
b905c043cc5ee <|-- t03d6e2ef334c
Les bases non résolues restent identifiées; les signatures complètes ne sont pas reconstruites.
9. Référence
616 / 616 fichiers admissibles lus (962 dans l’arbre); 0 trop volumineux, 0 échec de lecture et 88 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.
Session
Un état conservé entre plusieurs requêtes, souvent pour suivre un utilisateur connecté. L’authentification et les permissions restent des vérifications distinctes.
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.
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.
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). Artemis-Switch. [Software repository] github.com.
- antoinebou12. (2026, 5 novembre). Artemis-Switch: README. [Repository documentation] github.com.
- antoinebou12. (2026, 5 novembre). app/src/main.cpp. [Source file] github.com.
- antoinebou12. (2026, 5 novembre). app/src/streaming/MoonlightSession.cpp. [Source file] github.com.
- antoinebou12. (2026, 5 novembre). app/src/streaming/switch/SwitchMoonlightSessionDecoderAndRenderProvider.cpp. [Source file] github.com.
- Boucher, A. (2026, 20 octobre). Artemis Switch : suivre une image du réseau à l’écran. [Project article] antoineboucher.info.
- Boucher, A. (2026, 2 septembre). Streaming portable et homebrew — Artemis-Switch, moonlight-N3DS, sm64coopdx-switch. [Project article] antoineboucher.info.
- Boucher, A. (2026, 2 septembre). Artemis-Switch. [Project article] antoineboucher.info.
- Boucher, A. (2026, 23 octobre). Artemis-Switch : Une image du PC à l’écran. [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.