Skip to content

Feat/handheld UI - #3

Merged
Producdevity merged 12 commits into
masterfrom
feat/handheld-ui
Aug 31, 2026
Merged

Feat/handheld UI#3
Producdevity merged 12 commits into
masterfrom
feat/handheld-ui

Conversation

@Producdevity

@Producdevity Producdevity commented Aug 30, 2026

Copy link
Copy Markdown
Owner

What does this change?

  • Adds a controller-first library with search, favorites, artwork, settings, Xbox/Nintendo button layouts, and sign out.
  • Requests streams for the device display and letterboxes games that return 16:9.
  • Adds H700 hardware decoding on ROCKNIX through V4L2 Request and bundled Cedrus modules loaded only while GreenOvercast is running.
  • Moves product logic to Zig where it does not require a codec, kernel, or library C boundary.
  • Consolidates dependency builds and PortMaster packaging in build.zig.
  • Fixes the Xbox quit flow, certificate discovery across firmware, and persistent credential storage.

How did you test it?

  • tools/zig.sh build
  • tools/zig.sh build test
  • tools/zig.sh build fmt-check
  • PORTMASTER_NEW=/path/to/PortMaster-New tools/zig.sh build package
  • PortMaster installation, frontend launch, hardware-decoded playback, controls, and clean shutdown on:
    • RG35XX-H — muOS 2508.4
    • RG40XX-H — Knulli (Batocera 42)
    • RG40XX-H — ROCKNIX 20260801
    • Miyoo Flip — SpruceOS 4.2.0
  • RK3326 MPP playback was also verified on an R36S running AmberELEC 20250515_1801.

Summary by cubic

Migrates the runtime from C to Zig and adds a controller-first handheld UI alongside ROCKNIX H700 support via a new V4L2 Request decoder. Streams now match the device display resolution instead of requesting fixed 720p.

New Features

  • Adds library search, favorites, per-title Xbox or Nintendo face button layout (defaulting to the firmware's system mapping with corrected button labels), cached game artwork, and sign-out from settings.
  • Adds a V4L2 Request decoder that loads bundled ROCKNIX H700 kernel modules only on the matching firmware and unloads them on exit.
  • Fixes the Xbox quit flow, certificate discovery across firmware, and makes Knulli credentials persist across reboots.

Build and dependencies

  • Replaces the separate C build and packaging scripts with a single build.zig build using pinned dependency commits and hash checks; ROCKNIX module builds now stop when patches fail and are covered by a regression test.
  • Upgrades FFmpeg from 4.4.8 to 9.0, removes the vendored SDL2 and FFmpeg headers, and adds AmberELEC (R36S) validation.

Written for commit abb3a6c. Summary will update on new commits.

Review in cubic

@gitguardian

gitguardian Bot commented Aug 30, 2026

Copy link
Copy Markdown

️✅ There are no secrets present in this pull request anymore.

If these secrets were true positive and are still valid, we highly recommend you to revoke them.
While these secrets were previously flagged, we no longer have a reference to the
specific commits where they were detected. Once a secret has been leaked into a git
repository, you should consider it compromised, even if it was deleted immediately.
Find here more information about risks.


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

@coderabbitai

coderabbitai Bot commented Aug 30, 2026

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 192 files, which is 92 over the limit of 100.

To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch.

Upgrade to a paid plan to raise the limit.

This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 6e6e6314-e47e-4852-9dd2-2ad810df7a90

📥 Commits

Reviewing files that changed from the base of the PR and between 3ea87c5 and abb3a6c.

⛔ Files ignored due to path filters (2)
  • packaging/portmaster/greenovercast/screenshot.png is excluded by !**/*.png
  • vendor/manifest.lock is excluded by !**/*.lock
📒 Files selected for processing (192)
  • README.md
  • THIRDPARTY.md
  • build.zig
  • packaging/portmaster/greenovercast/GreenOvercast.sh
  • packaging/portmaster/greenovercast/README.md
  • packaging/portmaster/greenovercast/greenovercast/CEDAR-SOURCE.md
  • packaging/portmaster/greenovercast/greenovercast/FFMPEG-SOURCE.md
  • packaging/portmaster/greenovercast/greenovercast/ROCKNIX-H700-SOURCE.md
  • packaging/portmaster/greenovercast/greenovercast/licenses/LICENSE.Linux.txt
  • packaging/portmaster/greenovercast/greenovercast/licenses/LICENSE.libudev-zero.txt
  • packaging/portmaster/greenovercast/greenovercast/rocknix/h700/cedrus-modules
  • packaging/portmaster/greenovercast/greenovercast/rocknix/h700/greenovercast_h700_overlay.ko
  • packaging/portmaster/greenovercast/greenovercast/rocknix/h700/sunxi-cedrus.ko
  • src/app/release.zig
  • src/app/state.zig
  • src/auth/token_store_adapter.c
  • src/auth/token_store_adapter.h
  • src/auth/xbox_auth.h
  • src/auth/xbox_auth.zig
  • src/catalog/catalog_parser.h
  • src/catalog/catalog_parser.zig
  • src/catalog/catalog_search.h
  • src/catalog/catalog_search.zig
  • src/catalog/service.zig
  • src/input/controller.h
  • src/input/controller.zig
  • src/input/guide_chord.zig
  • src/input/wire_encoder.h
  • src/input/wire_encoder.zig
  • src/main.zig
  • src/media/audio/audio_pipeline.c
  • src/media/audio/audio_pipeline.zig
  • src/media/audio/opus_adapter.c
  • src/media/audio/opus_adapter.h
  • src/media/rtp/packet.h
  • src/media/rtp/packet.zig
  • src/media/video/cedar_loader.c
  • src/media/video/cedar_loader.zig
  • src/media/video/mpp_loader.c
  • src/media/video/mpp_loader.zig
  • src/media/video/video_decoder.h
  • src/media/video/video_decoder.zig
  • src/media/video/video_decoder_cedar.c
  • src/media/video/video_decoder_cedar.zig
  • src/media/video/video_decoder_mpp.c
  • src/media/video/video_decoder_mpp.zig
  • src/media/video/video_decoder_selection.zig
  • src/media/video/video_decoder_v4l2_request.c
  • src/media/video/video_pipeline.c
  • src/media/video/video_pipeline.h
  • src/media/video/video_pipeline.zig
  • src/net/form_writer.h
  • src/net/form_writer.zig
  • src/net/http_client.c
  • src/net/http_client.h
  • src/net/json_reader.h
  • src/net/json_reader.zig
  • src/net/json_writer.h
  • src/net/json_writer.zig
  • src/platform/sdl_platform.c
  • src/platform/sdl_platform.zig
  • src/session/cloud_session.zig
  • src/session/message_protocol.zig
  • src/session/webrtc_session.c
  • src/session/webrtc_session.zig
  • src/smoke/abi_smoke.zig
  • src/ui/artwork_decoder.c
  • src/ui/artwork_decoder.h
  • src/ui/artwork_loader.zig
  • src/ui/handheld_ui.h
  • src/ui/handheld_ui.zig
  • src/ui/keyboard.zig
  • src/ui/library_view.zig
  • src/ui/navigation_repeat.zig
  • src/ui/persistent_settings.zig
  • src/ui/pixel_font.c
  • src/ui/pixel_font.h
  • src/ui/pixel_font.zig
  • src/ui/settings_view.zig
  • src/ui/stream_dimensions.zig
  • src/ui/view_style.zig
  • tests/rocknix_build_regression_test.sh
  • tests/video_decoder_selection_test.c
  • tests/video_decoder_test.c
  • tools/build-cedarx.sh
  • tools/build-dependencies.sh
  • tools/build-mpp.sh
  • tools/build-release.sh
  • tools/build-rocknix-h700-cedrus.sh
  • tools/deploy.sh
  • tools/package-portmaster.sh
  • tools/video-diagnostics.sh
  • vendor/headers/README.md
  • vendor/headers/SDL2/SDL.h
  • vendor/headers/SDL2/SDL_assert.h
  • vendor/headers/SDL2/SDL_atomic.h
  • vendor/headers/SDL2/SDL_audio.h
  • vendor/headers/SDL2/SDL_blendmode.h
  • vendor/headers/SDL2/SDL_clipboard.h
  • vendor/headers/SDL2/SDL_config.h
  • vendor/headers/SDL2/SDL_config_minimal.h
  • vendor/headers/SDL2/SDL_copying.h
  • vendor/headers/SDL2/SDL_cpuinfo.h
  • vendor/headers/SDL2/SDL_endian.h
  • vendor/headers/SDL2/SDL_error.h
  • vendor/headers/SDL2/SDL_events.h
  • vendor/headers/SDL2/SDL_filesystem.h
  • vendor/headers/SDL2/SDL_gamecontroller.h
  • vendor/headers/SDL2/SDL_gesture.h
  • vendor/headers/SDL2/SDL_guid.h
  • vendor/headers/SDL2/SDL_haptic.h
  • vendor/headers/SDL2/SDL_hidapi.h
  • vendor/headers/SDL2/SDL_hints.h
  • vendor/headers/SDL2/SDL_joystick.h
  • vendor/headers/SDL2/SDL_keyboard.h
  • vendor/headers/SDL2/SDL_keycode.h
  • vendor/headers/SDL2/SDL_loadso.h
  • vendor/headers/SDL2/SDL_locale.h
  • vendor/headers/SDL2/SDL_log.h
  • vendor/headers/SDL2/SDL_main.h
  • vendor/headers/SDL2/SDL_messagebox.h
  • vendor/headers/SDL2/SDL_metal.h
  • vendor/headers/SDL2/SDL_misc.h
  • vendor/headers/SDL2/SDL_mouse.h
  • vendor/headers/SDL2/SDL_mutex.h
  • vendor/headers/SDL2/SDL_pixels.h
  • vendor/headers/SDL2/SDL_platform.h
  • vendor/headers/SDL2/SDL_power.h
  • vendor/headers/SDL2/SDL_quit.h
  • vendor/headers/SDL2/SDL_rect.h
  • vendor/headers/SDL2/SDL_render.h
  • vendor/headers/SDL2/SDL_rwops.h
  • vendor/headers/SDL2/SDL_scancode.h
  • vendor/headers/SDL2/SDL_sensor.h
  • vendor/headers/SDL2/SDL_shape.h
  • vendor/headers/SDL2/SDL_stdinc.h
  • vendor/headers/SDL2/SDL_surface.h
  • vendor/headers/SDL2/SDL_system.h
  • vendor/headers/SDL2/SDL_thread.h
  • vendor/headers/SDL2/SDL_timer.h
  • vendor/headers/SDL2/SDL_touch.h
  • vendor/headers/SDL2/SDL_version.h
  • vendor/headers/SDL2/SDL_video.h
  • vendor/headers/SDL2/begin_code.h
  • vendor/headers/SDL2/close_code.h
  • vendor/headers/curl/curl.h
  • vendor/headers/curl/curlver.h
  • vendor/headers/curl/easy.h
  • vendor/headers/curl/header.h
  • vendor/headers/curl/mprintf.h
  • vendor/headers/curl/multi.h
  • vendor/headers/curl/options.h
  • vendor/headers/curl/system.h
  • vendor/headers/curl/urlapi.h
  • vendor/headers/curl/websockets.h
  • vendor/headers/libavcodec/avcodec.h
  • vendor/headers/libavcodec/bsf.h
  • vendor/headers/libavcodec/codec.h
  • vendor/headers/libavcodec/codec_desc.h
  • vendor/headers/libavcodec/codec_id.h
  • vendor/headers/libavcodec/codec_par.h
  • vendor/headers/libavcodec/packet.h
  • vendor/headers/libavcodec/version.h
  • vendor/headers/libavutil/attributes.h
  • vendor/headers/libavutil/avconfig.h
  • vendor/headers/libavutil/avutil.h
  • vendor/headers/libavutil/buffer.h
  • vendor/headers/libavutil/channel_layout.h
  • vendor/headers/libavutil/common.h
  • vendor/headers/libavutil/cpu.h
  • vendor/headers/libavutil/dict.h
  • vendor/headers/libavutil/error.h
  • vendor/headers/libavutil/frame.h
  • vendor/headers/libavutil/hwcontext.h
  • vendor/headers/libavutil/intfloat.h
  • vendor/headers/libavutil/log.h
  • vendor/headers/libavutil/macros.h
  • vendor/headers/libavutil/mathematics.h
  • vendor/headers/libavutil/mem.h
  • vendor/headers/libavutil/pixfmt.h
  • vendor/headers/libavutil/rational.h
  • vendor/headers/libavutil/samplefmt.h
  • vendor/headers/libavutil/version.h
  • vendor/headers/libswscale/swscale.h
  • vendor/headers/libswscale/version.h
  • vendor/headers/rtc/rtc.h
  • vendor/headers/rtc/version.h
  • vendor/patches/ffmpeg-9.0-v4l2-request-portable.patch
  • vendor/rocknix-h700-cedrus/cedrus-h616-match.patch
  • vendor/rocknix-h700-cedrus/cedrus-h616-sram.patch
  • vendor/rocknix-h700-cedrus/greenovercast_h700_overlay.c
  • vendor/rocknix-h700-cedrus/greenovercast_h700_ve.dts

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 192 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread src/platform/sdl_platform.zig Outdated
Comment thread tools/build-rocknix-h700-cedrus.sh Outdated
Comment thread src/ui/library_view.zig
Comment thread src/ui/settings_view.zig
Comment thread tools/video-diagnostics.sh Outdated
Comment thread src/session/webrtc_session.zig
Comment thread packaging/portmaster/greenovercast/GreenOvercast.sh
Comment thread packaging/portmaster/greenovercast/greenovercast/rocknix/h700/cedrus-modules Outdated
Comment thread src/media/video/mpp_loader.zig
Comment thread src/ui/persistent_settings.zig Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 19 files (changes from recent commits).

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread tools/build-rocknix-h700-cedrus.sh Outdated
Comment thread packaging/portmaster/greenovercast/GreenOvercast.sh Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 5 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread src/ui/settings_view.zig Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 6 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread tests/rocknix_build_regression_test.sh

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 1 file (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="tests/rocknix_build_regression_test.sh">

<violation number="1" location="tests/rocknix_build_regression_test.sh:147">
P3: The fake `make` appends to `$MAKE_MARKER` with `>>`, so the count accumulates across build invocations within the same test process. The success-path assertion `wc -l = 2` only passes because the failure run never reaches `make` and leaves the marker uncreated. If the failure path ever invokes `make` (or the test is reordered), this count silently becomes wrong and the assertion reports a misleading failure. Reset the marker before the success run to keep the two build steps independent.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

"$ROOT/tools/build-rocknix-h700-cedrus.sh" "$kernel_tree" "$success_output" \
>"$TEST_ROOT/success.log" 2>&1 || fail "ROCKNIX module build rejected a valid build"

[ "$(wc -l <"$make_marker" | tr -d ' ')" = 2 ] || fail "ROCKNIX module build did not run both make steps"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: The fake make appends to $MAKE_MARKER with >>, so the count accumulates across build invocations within the same test process. The success-path assertion wc -l = 2 only passes because the failure run never reaches make and leaves the marker uncreated. If the failure path ever invokes make (or the test is reordered), this count silently becomes wrong and the assertion reports a misleading failure. Reset the marker before the success run to keep the two build steps independent.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At tests/rocknix_build_regression_test.sh, line 147:

<comment>The fake `make` appends to `$MAKE_MARKER` with `>>`, so the count accumulates across build invocations within the same test process. The success-path assertion `wc -l = 2` only passes because the failure run never reaches `make` and leaves the marker uncreated. If the failure path ever invokes `make` (or the test is reordered), this count silently becomes wrong and the assertion reports a misleading failure. Reset the marker before the success run to keep the two build steps independent.</comment>

<file context>
@@ -78,4 +118,40 @@ grep -q "failed to apply patch" "$build_output" || fail "ROCKNIX patch failure w
+  "$ROOT/tools/build-rocknix-h700-cedrus.sh" "$kernel_tree" "$success_output" \
+  >"$TEST_ROOT/success.log" 2>&1 || fail "ROCKNIX module build rejected a valid build"
+
+[ "$(wc -l <"$make_marker" | tr -d ' ')" = 2 ] || fail "ROCKNIX module build did not run both make steps"
+[ -e "$dtc_marker" ] || fail "ROCKNIX module build did not compile the device-tree overlay"
+[ -e "$xxd_marker" ] || fail "ROCKNIX module build did not embed the device-tree overlay"
</file context>

@Producdevity
Producdevity merged commit d47a642 into master Aug 31, 2026
5 checks passed
@Producdevity
Producdevity deleted the feat/handheld-ui branch August 31, 2026 15:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant