Aller au contenu
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.

Matériel et infographie Fork
  • Mis à jour
  • 36
  • C++ · 53.78%
  • GPL-3.0
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.

C++53.78%
53.78%2 312 036 octets
C33.23%
33.23%1 428 795 octets
Java5.69%
5.69%244 691 octets
CMake3.51%
3.51%150 826 octets
Langage%Octets
C++53.78%2 312 036
C33.23%1 428 795
Java5.69%244 691
CMake3.51%150 826
Objective-C++1.95%83 846
Shell0.75%32 086
5 autres langages
Swift0.38%16 275
Python0.35%15 226
GLSL0.34%14 440
Makefile0.02%662
PowerShell0.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.

Diagramme de cas d’utilisation de Artemis-Switch : Jumeler un hôte et diffuser; Régler l’affichage vidéo; Enregistrer des profils; Exporter un banc d’essai; Compiler et tester l’appliArtemis-SwitchJumeler un hôte et diffuserRégler l’affichage vidéoEnregistrer des profilsExporter un banc d’essaiCompiler et tester l’appliJoueur sur SwitchDéveloppeur«système»PC hôte GameStream
Acteurs à gauche (personnes) et à droite (systèmes externes) ; chaque ovale est un cas d’utilisation appuyé par les fichiers cités ci-dessous.
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

  1. Copier Artemis-Switch.nro dans sdmc:/switch/Artemis-Switch/ et lancer hbmenu par redirection de titre.
  2. Ouvrir Artemis Switch, choisir le PC hôte et terminer le jumelage par NIP dans l’interface web de l’hôte.
  3. Créer un profil de flux (par exemple 60 FPS, H.265, Fit avec FSR) et l’associer à cet hôte.
  4. Lancer une application et appuyer ensemble sur - et + pour ouvrir la surcouche.
  5. 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.

README.md · Developer build
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 --parallel
README.md · Developer validation
python 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-failure
README.md · Developer validation
python -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 --parallel
README.md · Developer validation
cmake -S ci/integration -B build/integration -DCMAKE_BUILD_TYPE=Debug
cmake --build build/integration --parallel
ctest --test-dir build/integration --output-on-failure
app/platforms/android-project/README.md · Building
cd android-project
app/platforms/android-project/README.md · Building
./build_libromfs_generator.sh
app/platforms/android-project/README.md · Building
export JAVA_HOME=/Applications/Android\ Studio.app/Contents/jbr/Contents/Home
export ANDROID_SDK_ROOT=~/Library/Android/sdk
./gradlew assembleDebug
./gradlew installDebug

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. Install the Artemis Switch NRO

docs/NRO_INSTALL.md

Use one of these files from dist/nro:

  1. Easy install: extract Artemis-Switch-SD.zip to the root of the Switch SD card.
  2. 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.
Lire les instructions complètes ↗

4.2. Install

docs/source/install.md

Use a file from a GitHub Release or from dist/nro after a local Switch build.
Lire les instructions complètes ↗

4.3. Easy install

docs/source/install.md

Extract Artemis-Switch-SD.zip to the root of the Switch SD card. That ZIP is only the ready-to-copy layout:
Lire les instructions complètes ↗

4.4. Manual install

docs/source/install.md

Copy Artemis-Switch.nro to:
Lire les instructions complètes ↗
Configuration et utilisation

4.5. Recommended host and clients

README.md

Hosts and clients are separate. Pick a server on the PC, then a client on each device. Artemis uses Moonlight/GameStream for pairing and streaming; host administration stays in the selected host’s own web UI.
Lire les instructions complètes ↗

4.6. Client (device)

README.md

ClientDeviceNotes
Artemis Switch (this app)Nintendo SwitchMoonlight-Switch fork with FSR/RCAS, stream profiles, and Switch presentation.
ArtemideAndroidHighly recommended on Android: ultra-low latency (ULL), direct presentation, built-in FSR upscaling. FSR Performance / Balanced / Quality presets inspired this fork.
Artemis (Moonlight Noir)AndroidApollo’s companion client (virtual display / host UX inspiration).
MoonlightPC, Android, iOS, …Official clients.
Moonlight V+AndroidAlternative Android fork (frame-gen and extra host tools).
Lire les instructions complètes ↗
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

PathPurpose
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.
Lire les instructions complètes ↗

4.8. Developer validation

README.md

Lint changed first-party files and run the strict portable C++ analysis surface: The changed-file linter checks UTF-8/text hygiene, JSON and Python syntax, Ruff, and clang-format. Vendored dependencies under extern/ are excluded. Cross-feature integration:
Lire les instructions complètes ↗
Documentation source

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.

Composants du système Contexte
Mermaid Diagramme interactif

Vue générale des composants et des échanges vérifiés dans le dépôt.

Vue statique de l’architecture de Artemis-Switch
Aperçu statique. Le diagramme interactif le remplace après le chargement de Mermaid.
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
Modules et couche principale
ModuleCoucheFichiersTypesExtensions
switch/libavutilDonnées et infrastructure100195.h
srcServices applicatifs5139.cpp
remote_access/tailscaleServices applicatifs4162.cpp .hpp .h
streamingServices applicatifs3732.hpp .cpp
includeServices applicatifs2730.hpp
switch/libavcodecDonnées et infrastructure2530.h
platforms/android-projectServices applicatifs2435.java .xml .gradle
streaming/videoServices applicatifs2416.hpp .glsl .cpp
features/inputServices applicatifs2122.hpp .cpp
resources/xmlPrésentation190.xml
remote_accessServices applicatifs1720.hpp .cpp
features/videoServices applicatifs138.hpp .cpp
switch/curlDonnées et infrastructure1218.h
benchmarkServices applicatifs1113.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
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
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
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
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

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

7.5. Services

Service 25

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éNaturePremiers champs
AVCodecStructure de donnéesname, long_name, type, id, capabilities, max_lowres, supported_framerates, pix_fmts
AVCodecContextStructure de donnéesav_class, log_level_offset, codec_type, codec, codec_id, codec_tag, priv_data, internal
AVCodecDescriptorStructure de donnéesid, type, name, long_name, props, NULL, mime_types, profiles
AVCodecParserContextStructure de donnéespriv_data, parser, frame_offset, cur_offset, next_frame_offset, pict_type, repeat_pict, pts
AVDOVIColorMetadataStructure de donnéesdm_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
AVDOVIDataMappingStructure de donnéesvdr_rpu_id, mapping_color_space, mapping_chroma_format_idc, curves, nlq_method_idc, num_x_partitions, num_y_partitions, nlq
AVDOVIDecoderConfigurationRecordStructure de donnéesdv_version_major, dv_version_minor, dv_profile, dv_level, rpu_present_flag, el_present_flag, bl_present_flag, dv_bl_signal_compatibility_id
AVDOVIDmDataStructure de donnéeslevel, l1, l2, l3, l4, l5, l6, l8
Afficher 6 entités de plus
AVDOVIDmLevel1Structure de donnéesmin_pq, max_pq, avg_pq, target_max_pq, trim_slope, trim_offset, trim_power, trim_chroma_weight
AVDOVIDmLevel10Structure de donnéestarget_display_index, target_max_pq, target_min_pq, target_primary_index, target_display_primaries, content_type, whitepoint, reference_mode_flag
AVDOVIDmLevel11Structure de donnéescontent_type, whitepoint, reference_mode_flag, sharpness, noise_reduction, mpeg_noise_reduction, frame_rate_conversion, brightness
AVDOVIDmLevel2Structure de donnéestarget_max_pq, trim_slope, trim_offset, trim_power, trim_chroma_weight, trim_saturation_gain, ms_weight, min_pq_offset
AVDOVIDmLevel254Structure de donnéesdm_mode, dm_version_index, dm_run_mode, dm_run_version, dm_debug, level, l1, l2
AVDOVIDmLevel255Structure de donnéesdm_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.

Settings Services applicatifs, 157 méthodes
working_dir, set_working_dir, launch_path, set_launch_path, key_dir, boxart_dir
SDLActivity Services applicatifs, 116 méthodes
getMotionListener, main, getMainSharedObject, getMainFunction, getLibraries, loadLibraries
RealWgxBackend Services applicatifs, 37 méthodes
realEgressCallback, sendEgress, toSockaddr, fromSockaddr, discoverLanAddress, startDirectPath
MoonlightSession Services applicatifs, 35 méthodes
set_provider, start, stop, stopForApplicationExit, set_address, setApolloLaunchOptions
AVFrameQueue Services applicatifs, 28 méthodes
push, pushTransferred, recycleWriteFrame, configure, capacityFor, size
AVFrameHolder Services applicatifs, 23 méthodes
push, pushTransferred, get, acquireWriteFrame, recycleWriteFrame, prepare
FramePipelineTelemetry Services applicatifs, 16 méthodes
reset, noteStreamStart, noteFirstPacket, noteDecodedFrame, consumePendingDecodeTiming, noteFrameQueued
TailscaleCore Services applicatifs, 21 méthodes
start, stop, snapshot, resolveRoute, activateRoute, prepareRouteForStreaming
SDLSurface Services applicatifs, 20 méthodes
handlePause, handleResume, getNativeSurface, enableMediaCodecOverlay, surfaceCreated, surfaceDestroyed
TsLwipRelay Services applicatifs, 20 méthodes
start, stop, addTcp, addUdp, isRunning, log

7.8. Base de données et persistance

7.9. Intégrations externes

Clients HTTP

libcurl

Hôtes nommés dans le code

7.10. Stack et dépendances

C/C++ (CMake) CMakeLists.txt 8 à l’exécution

CMake ≥ 3.10

Ouvrir le manifeste

JVM (Gradle) app/platforms/android-project/app/build.gradle

compileSdk Version minSdk Version targetSdk Version

Ouvrir le manifeste

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
Dépendances externes
PaquetVersionUsageRôleRegistre
PkgConfig—exécution—C/C++ (CMake)
MbedTLS—exécution—C/C++ (CMake)
OpenSSL—exécution—C/C++ (CMake)
SDL2—exécutionGraphisme, image et 3DC/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
Workflows, déclencheurs, tâches et cibles
WorkflowDéclencheursTâchesPublie vers
All Builds
.github/workflows/all-builds.yml
This, workflow, fans, out, to, six
  • Nintendo Switch
  • PS Vita
  • Android
  • macOS
  • Windows
  • Linux
—
Android APK
.github/workflows/android-apk.yml
appelé par un workflow
  • build ubuntu-latest
    Check out repository · Fetch vcpkg history and baseline · Set up Java · Set up Android SDK · Install Android SDK components · Install native build tools
—
Build Artemis Switch NRO into dist (one-shot)
.github/workflows/build-dist-once.yml
push
  • build-and-commit ubuntu-latest
    Check out repository · Build Nintendo Switch NRO and capture diagnostics · Publish NRO or failure log to main
—
Build Artemis Switch
.github/workflows/docker-image.yml
lancement manuel, appelé par un workflow
  • build ubuntu-latest
    Check out repository · Remove bundled fonts · Remove conflicting enet package · Configure (compatibility pass) · Configure · Build Nintendo Switch NRO
—
Docs
.github/workflows/docs.yml
push, lancement manuel
  • deploy ubuntu-latest
    actions/checkout · actions/setup-python · Install docs dependencies · Build HTML · Add .nojekyll · Deploy to GitHub Pages
GitHub Pages
Feature and Integration CI
.github/workflows/feature-integration-ci.yml
Topic, branches, run, through, demande de fusion, Keeping
  • Consolidated portable integration ubuntu-latest
    Checkout · Validate localization JSON syntax · Validate Artemis English/French translation coverage · Validate release/CD contract · Validate isolated VPN build contract · Configure unit suite
  • Release source package contract ubuntu-latest
    Checkout repository and submodules · Build dry-run source packages · Inspect source packages
  • ASan + UBSan integration ubuntu-latest
    Checkout · Configure · Build · Test
  • Artemis CI summary ← portable-integration, release-package-contract, sanitizer-integration ubuntu-latest
    Require all integration jobs
—
Lint
.github/workflows/lint.yml
Topic, branches, are, linted, through, demande de fusion
  • Changed-file lint ubuntu-latest
    Checkout full history · Install pinned linters · Select comparison revision · Lint changed first-party files · Lint complete first-party Python surface
  • Portable warnings and clang-tidy ubuntu-latest
    actions/checkout · Install clang-tidy · Configure strict portable build · Build lint surface
—
Linux Builds
.github/workflows/linux.yml
appelé par un workflow, lancement manuel
  • build matrix
    Portable x86_64 · Portable ARM64 · Steam Runtime 4 x86_64 · Steam Runtime 4 ARM64 · Bootstrap checkout dependencies · Check out repository
—

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
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.

DRM_DEV HOME USERPROFILE

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
UML Pipeline CI
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

  1. antoinebou12. (2026, 5 novembre). Artemis-Switch. [Software repository] github.com.
  2. antoinebou12. (2026, 5 novembre). Artemis-Switch: README. [Repository documentation] github.com.
  3. antoinebou12. (2026, 5 novembre). app/src/main.cpp. [Source file] github.com.
  4. antoinebou12. (2026, 5 novembre). app/src/streaming/MoonlightSession.cpp. [Source file] github.com.
  5. antoinebou12. (2026, 5 novembre). app/src/streaming/switch/SwitchMoonlightSessionDecoderAndRenderProvider.cpp. [Source file] github.com.
  6. Boucher, A. (2026, 20 octobre). Artemis Switch : suivre une image du réseau à l’écran. [Project article] antoineboucher.info.
  7. Boucher, A. (2026, 2 septembre). Streaming portable et homebrew — Artemis-Switch, moonlight-N3DS, sm64coopdx-switch. [Project article] antoineboucher.info.
  8. Boucher, A. (2026, 2 septembre). Artemis-Switch. [Project article] antoineboucher.info.
  9. 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.