Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ jobs:
"git"
"lld"
"llvm"
"nasm"
)
moonlight_dependencies=(
)
Expand All @@ -92,6 +93,7 @@ jobs:
"coreutils"
"lld"
"llvm"
"nasm"
)
moonlight_dependencies=(
)
Expand All @@ -115,6 +117,7 @@ jobs:
mingw-w64-x86_64-lld
mingw-w64-x86_64-llvm
mingw-w64-x86_64-make
mingw-w64-x86_64-nasm

- name: Setup python
id: setup-python
Expand Down Expand Up @@ -157,14 +160,17 @@ jobs:

- name: Run tests
id: test
working-directory: ${{ env.CMAKE_BUILD }}/tests
run: ./test_moonlight --gtest_color=yes --gtest_output=xml:test_results.xml
run: |
ctest --test-dir "${CMAKE_BUILD}" --output-on-failure \
--output-junit "${PWD}/${CMAKE_BUILD}/tests/test_results.xml"

- name: Generate gcov report
id: test_report
# The Windows Clang host build does not enable gcov instrumentation.
# any except canceled or skipped
if: >-
always() &&
runner.os != 'Windows' &&
(steps.test.outcome == 'success' || steps.test.outcome == 'failure')
env:
MSYS2_PATH_TYPE: inherit
Expand All @@ -188,7 +194,7 @@ jobs:
# any except canceled or skipped
if: >-
always() &&
(steps.test.outcome == 'success' || steps.test.outcome == 'failure') &&
steps.test_report.outcome == 'success' &&
startsWith(github.repository, 'SunshineStream/')
uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1
with:
Expand Down
125 changes: 108 additions & 17 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,120 @@
On Windows we use msys2 and mingw64 to compile.
You need to prefix commands with `C:\msys64\msys2_shell.cmd -defterm -here -no-start -mingw64 -c`.
# Agent instructions

Prefix build directories with `cmake-build-`.
## Global instructions

The xbox build uses Unix Makefiles.
Before working on a task, read `~/.agents/skills/AGENTS.md`, expanding `~` to the current user's home directory.
If that file is unavailable, report that the shared global instructions could not be loaded.

The host native tests will use MinGW Makefiles on Windows, but Unix Makefiles on other platforms.
## Repository boundaries

The project uses gtest as a test framework.
This repository is the original Xbox Moonlight client, using nxdk, SDL and FFmpeg. The adjacent Sunshine
checkout is a separate project; use it as a reference when relevant, and keep changes in this checkout
unless the task explicitly includes another repository.

Always add or update doxygen documentation.
Preserve unrelated working-tree changes. Treat `third-party/` as vendored dependencies. Apply Xbox
compatibility adaptations through the project's adapters and build-copy mechanisms rather than editing
generated SDK copies or dependency outputs. Keep generated files and local emulator support data under
their existing build or ignored directories.

The project requires that everything be documented in doxygen or the build will fail.
## Build

Primary doxygen comments should be done like so:
On Windows, compile with MSYS2 MinGW64. Prefix Windows build and test commands with
`C:\msys64\msys2_shell.cmd -defterm -here -no-start -mingw64 -c`.

Prefix local build directories with `cmake-build-`. Host builds and native tests use MinGW Makefiles on
Windows and Unix Makefiles on other platforms. Xbox builds use Unix Makefiles on every platform.

The normal top-level configure uses the host toolchain and delegates Xbox compilation to an nxdk child
build. Use `CMakePresets.json` and the README's build instructions; keep the Xbox toolchain separate from
host-native tests. The normal release ISO is `cmake-build-release/xbox/Moonlight.iso`, with the packaged
Xbox executable at `cmake-build-release/xbox/xbe/default.xbe`.

Video experiment builds are opt-in through `MOONLIGHT_BUILD_VIDEO_EXPERIMENTS`. Keep their instructions
with the probes in `experiments/README.md`.

## Tests and validation

The project uses GoogleTest. Tests must include `<lizardbyte/common/testing.h>` instead of including
GoogleTest directly. This supplies the shared test support and output capture; Sunshine's
`tests/tests_common.h` is not part of this repository.

Group test includes under `// test includes`, then `// standard includes`, `// lib includes` and
`// local includes`, with blank lines between groups and no empty groups. Keep platform-specific headers
inside their preprocessor guards. Preserve and explain intentional include-order dependencies.

Add or update meaningful regression tests for new or changed source behavior. Target full coverage of
changed testable source code. Keep platform-neutral logic accessible to native tests and document any
validation limits that require an emulator or console.

Run tests with `ctest --test-dir <build-directory> --output-on-failure` so every registered test executable
is included. Native test executables, including `test_moonlight` and `test_pvideo_presenter`, are under the
build directory's `tests/` folder. A host-only configuration can disable Xbox builds with `BUILD_XBOX=OFF`.

Build-system changes require appropriate configuration, build and lint checks rather than dedicated
build-system regression projects or fixtures. Documentation-only edits require a strict documentation
build and relevant formatting/link checks, rather than new source tests.

For presentation changes, check GPU and software paths. Distinguish native test results, emulator
behavior and real-console validation; emulator output does not establish console performance or GPU
image correctness. Preserve software fallback when GPU presentation cannot be used.

## Python tooling and formatting

From the repository root, use `uv sync --locked` to refresh `.venv` from `pyproject.toml` and `uv.lock`.
Re-sync after switching branches or changing those files or `third-party/lizardbyte-common`. Update the
lockfile with `uv lock` when changing dependency declarations or the shared dependency revision.

Follow `.clang-format` for C and C++. After native source changes, run
`uv run --locked lb-update-clang-format` from the repository root and inspect the diff for unrelated
formatting changes. Format changed C/C++ files in `experiments/` separately: the shared formatter does
not traverse that directory. Centrally managed style files should be updated through their owning
configuration repository rather than changed locally.

## Code documentation

Always add or update Doxygen documentation for source changes. Document new or changed functions,
classes, structures, members, test fixtures and tests. The strict documentation build fails on missing
required documentation.

Use primary Doxygen comments in this form:

```cpp
/**
* @brief Describe the function, structure, etc.
*
* @param my_param Describe the parameter.
* @return Describe the return.
*/
/**
* @brief Describe the function, structure, etc.
*
* @param my_param Describe the parameter.
* @return Describe the return.
*/
```

Inline doxygen comments should use `///< ...` instead of `/**< ... */`.
Use `///< ...` for inline Doxygen comments, rather than `/**< ... */`.

Keep implementation constraints and reasons for compatibility workarounds beside the code that depends
on them. Keep user guidance in the README and metric definitions in the corresponding API documentation.
Published documentation should describe supported behavior and operating instructions, rather than
debugging chronologies, session-specific frame counts or research transcripts.

Documentation is built through Dockle and Doxygen using `dockle.toml`. Validate documentation edits with
the strict `api` build; a CMake build configured with `BUILD_DOCS=ON` provides the `docs` target.

## Markdown style

Align the pipes in Markdown tables in the source. Pad each column to a consistent width across the
header, separator and body rows, preserving any column-alignment markers. Apply this to all first-party
Markdown files, including READMEs and this file.

Use relative repository links for local documentation. Do not add decorative separator comments or
dashed banners to group tests; use descriptive names and code structure.

## Issues, pull requests and reviews

Use applicable repository or inherited organization templates when creating issues or pull requests,
following the shared global instructions. For an issue-only request, investigate enough to verify and
describe the observed behavior, expected behavior and reproduction steps. Investigate root causes and
implement fixes fully when those are requested.

Always follow the style guidelines defined in .clang-format for c/c++ code.
Review the current pull request head and verify mergeability against its target branch. Report concrete
introduced problems with their trigger, impact, location and a practical fix. Keep workflow status and
validation limitations separate from code findings. Pending maintainer approval or checks that have not
run are verification limits, not defects for the contributor to fix. Review actual failed checks for
change-related problems. An approval does not need an additional comment solely to announce it.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE BOOL "Export compile commands for IDE

set(MOONLIGHT_BUILD_KIND "HOST" CACHE STRING "Internal Moonlight build mode")
set_property(CACHE MOONLIGHT_BUILD_KIND PROPERTY STRINGS HOST XBOX)
option(MOONLIGHT_BUILD_VIDEO_EXPERIMENTS "Build standalone GPU presentation and MPEG-2 sampling experiments" OFF)
option(MOONLIGHT_ENABLE_GPU_PRESENTATION "Enable experimental NV2A overlay presentation before software fallback" ON)
option(MOONLIGHT_INPUT_DIAGNOSTICS "Display digital controller state while diagnosing stream input" OFF)

if(MOONLIGHT_BUILD_KIND STREQUAL "XBOX")
Expand Down
36 changes: 31 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,26 @@
![Apps Screen](./docs/images/screenshots/03-apps.png)


## Streaming controls
## Streaming controls and statistics

To quit a stream, press **Back/Select + Black + White (LB + RB)** together on any connected controller.
The client displays **Stopping stream...** before returning to the menu. If the end-of-stream statistics
summary is enabled, release the buttons and press a button to dismiss it.
The client displays **Stopping stream...**, then a stream summary. Release the buttons, then press a
button to return to the menu.

The opt-in CMake option `MOONLIGHT_INPUT_DIAGNOSTICS` displays controller state and event counters
for troubleshooting; it is disabled by default.
Enable **Settings → Display → Performance Stats** for a live panel during playback and additional
performance details in the summary. The panel works with GPU and software presentation, refreshes
once per second, and shows `N/A` for unavailable measurements. It includes measured incoming,
decoded and rendered FPS, video bitrate, timing, frame drops, buffering and the presentation path.
The stream header shows the requested FPS; the three FPS counters show measured rates.
Network latency is round-trip time. Present measures CPU frame preparation and submission,
including any scanout wait.

Video decoding runs on the CPU. Optional experimental GPU presentation accelerates color conversion
and scaling, with software fallback for unsupported frames or presentation failures. GPU
presentation is enabled by default; the build options below control its use.

Every stream summary reports GPU and software frame counts. **SOFTWARE FALLBACK USED** includes
the reason software presentation was selected, even when Performance Stats is disabled.

## 🛠️ Build

Expand Down Expand Up @@ -61,6 +73,7 @@ nxdk_dependencies=(
"mingw-w64-x86_64-lld"
"mingw-w64-x86_64-llvm"
"mingw-w64-x86_64-make"
"mingw-w64-x86_64-nasm"
)
moonlight_dependencies=(
"mingw-w64-x86_64-doxygen"
Expand All @@ -83,6 +96,7 @@ nxdk_dependencies=(
"git"
"lld"
"llvm"
"nasm"
)
moonlight_dependencies=(
"doxygen"
Expand All @@ -101,6 +115,7 @@ nxdk_dependencies=(
"coreutils"
"lld"
"llvm"
"nasm"
)
moonlight_dependencies=(
"doxygen"
Expand All @@ -121,6 +136,17 @@ For host and Xbox builds, CMake checks whether the compiler supports Clang's `un
cmake -S . -B cmake-build-release -DBUILD_DOCS=OFF -DCMAKE_BUILD_TYPE=Release
```

Video build settings:

| CMake option | Default | Purpose |
| ----------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `MOONLIGHT_ENABLE_GPU_PRESENTATION` | `ON` | Enable experimental NV2A color conversion and scaling with software fallback. |
| `MOONLIGHT_BUILD_VIDEO_EXPERIMENTS` | `OFF` | Build the standalone probes described in [Video experiments](experiments/README.md). |
| `MOONLIGHT_INPUT_DIAGNOSTICS` | `OFF` | Show controller state and event counters for troubleshooting. Requires GPU presentation to be disabled so the strip is visible. |

Pass options when configuring, for example `-DMOONLIGHT_ENABLE_GPU_PRESENTATION=OFF` for software-only
presentation. Existing build directories retain their cached settings until explicitly reconfigured.

### Build

```bash
Expand Down
Loading
Loading