r/rocknix

▲ 2 r/rocknix+1 crossposts

In Search Of an Older Version

Recently did the switch for my RGDS to a nightly distribution of Rocknix, using the most recent release. But it seems there are a few broken parts of that version, such as the Quick Menu for the bottom Screen and Azahar support. I'm sure it will be fixed eventually, but in the mean time I've been looking for workarounds and it seems only option is to downgrade back to an older version. However, the most recent version that did not have these issues is no longer on the github. Hoping someone knows we're to safely find the files.

Does anyone still have access to ROCKNIX-RK3566.aarch64-20260622-Specific.img.gz?

reddit.com
u/Th3Und3sir3d — 15 hours ago
▲ 25 r/rocknix+1 crossposts

Rocknix Bottom Screen Quick Menu?

Made the switch from Gamma to Rocknix on the RGDSand so far am pleased with it. Performance on NDS games feels faster and overall, the interface feels like it moves a lot smoother. But I am having trouble with something that Retro Game Corps highlighted in his recent video. Apparently on the newest nightly distribution, when playing a single screen console, you should be able to access a quick menu when you tap the bottom screen. Seems very useful for save state manager. However for me, that does not happen. If tapped, the bottom screen just pauses emulation, which is resumed by tapping the top screen? For anyone else running Rocknix on the rgds, is there a setting I was supposed to turn on to gain this feature? I am on the latest nightly build of Rocknix as of yesterday.

u/Th3Und3sir3d — 1 day ago

Switch Emulation setup guide for Rocknix on Ayn Thor

Because ROCKNIX doesn't include a Switch emulator, the "Switch" category won't even show up in your menus by default. We have to add it manually. Open /storage/.config/emulationstation/es_systems.cfg in a text editor. Scroll to the very bottom, right before the final </systemList> tag, and paste this block:

  <system>
    <name>switch</name>
    <fullname>Nintendo Switch</fullname>
    <path>/storage/roms/switch</path>
    <extension>.nsp .NSP .xci .XCI .nro .NRO .nca .NCA</extension>
    <command>/storage/roms/ports/Ryubing.sh %ROM%</command>
    <platform>switch</platform>
    <theme>switch</theme>
  </system>

Next you'll need the actual emulator. Grab the latest Ryubing.AppImage (make sure it's the ARM64/AArch64 build for the Thor). Create a new folder on your handheld at /storage/ryubing/ and drop the AppImage file in there.

If you launch the emulator now and try to install firmware, your device will completely freeze. We have to do the installation on a PC first to bypass it. Install the normal Ryujinx emulator on your Windows/Mac/Linux PC. Open it, go to File -> Open Ryujinx Folder, and drop your prod.keys and title.keys inside the system folder. Then go to Tools -> Install Firmware -> Install from XCI or ZIP and select your firmware zip file. Once your PC shows the firmware version at the bottom right, the decryption is done and you can close the emulator.

Copy the keys from your PC's Ryujinx system folder into /storage/.config/Ryujinx/system/ on the handheld. Then copy the entire bis/system/Contents/registered/ folder from your PC and overwrite the one at /storage/.config/Ryujinx/bis/system/Contents/registered/ on your handheld. This bypasses the broken file picker entirely and permanently installs your firmware.

Finally, we need the script that EmulationStation uses to actually launch the games:

#!/bin/bash
sysctl -w vm.max_map_count=1048576
. /etc/profile

RYUBING_DIR="/storage/ryubing"
RYUBING_BIN="${RYUBING_DIR}/Ryubing.AppImage"
RYUBING_CONFIG="/storage/.config/ryubing"
RYUBING_DATA="/storage/.local/share/ryubing"
RYUBING_CACHE="/storage/.cache"
RYUBING_LOG="${RYUBING_CACHE}/ryubing_launcher.log"
MOUSE_SCRIPT="${RYUBING_DIR}/ryubing_mouse_layer.py"
QT_CONFIG="${RYUBING_CONFIG}/qt-config.ini"

MAX_ATTEMPTS=3
STARTUP_GRACE=8
RETRY_WAIT=3
GPU_TIMEOUT=10
CONTROLLER_RETRIES=4
MIN_MEM_MB=2048
CLEANUP_TERM_WAIT=3
MOUSE_DETECT_TIMEOUT=3
WM_POLL_INTERVAL=0.5
WM_MAX_FAILURES=20
CRASH_TIME_THRESHOLD=120

RYUBING_EMU_LOG="/storage/.local/share/ryubing/log/ryubing_log.txt"

TOUCHPAD_ID="1356:3302:Sony_Interactive_Entertainment_DualSense_Wireless_Controller_Touchpad"
MOUSE_ID="17229:1:Ryubing_Home_Mouse_Layer"
DISPLAY_OUTPUT="DSI-2"

_log() {
    local level="$1"; shift
    printf '[%s] [%-5s] %s\n' "$(date '+%H:%M:%S.%3N')" "$level" "$*" | tee -a "$RYUBING_LOG" >&2
}
info()  { _log INFO  "$@"; }
warn()  { _log WARN  "$@"; }
err()   { _log ERROR "$@"; }

setup_environment() {
    export HOME=/storage
    export XDG_CONFIG_HOME=/storage/.config
    export XDG_DATA_HOME=/storage/.local/share
    export XDG_CACHE_HOME=/storage/.cache
    export LANG=en_US.UTF-8
    export LC_ALL=en_US.UTF-8

    export QT_SCALE_FACTOR=2
    export QT_AUTO_SCREEN_SCALE_FACTOR=0
    export QT_ENABLE_HIGHDPI_SCALING=1
    export GDK_SCALE=2
    export GDK_DPI_SCALE=1

    export XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/var/run/0-runtime-dir}"
    export WAYLAND_DISPLAY="${WAYLAND_DISPLAY:-wayland-1}"
    export SDL_VIDEODRIVER=x11
    export SWAYSOCK="${SWAYSOCK:-${XDG_RUNTIME_DIR}/sway-ipc.0.sock}"
    export DISPLAY="${DISPLAY:-:0}"
    export AVALONIA_GLOBAL_SCALE_FACTOR=2
    export GTK_USE_PORTAL=0

    mkdir -p "$RYUBING_CONFIG" "$RYUBING_DATA" "$RYUBING_CACHE" \
             "$RYUBING_DATA/nand" "$RYUBING_DATA/sdmc" \
             "$RYUBING_DATA/load" "$RYUBING_DATA/dump" "$RYUBING_DATA/log"
}

preflight() {
    local ok=true
    if [ ! -x "$RYUBING_BIN" ]; then
        err "Ryubing.AppImage missing or not executable: $RYUBING_BIN"
        ok=false
    fi
    $ok
}

_pids_matching() {
    local pid cmdline
    for pid in $(pidof ryubing Ryubing.AppImage dwarfs python3 ryujinx Ryujinx 2>/dev/null || true); do
        [ "$pid" = "$$" ] && continue
        cmdline="$(tr '\0' ' ' <"/proc/${pid}/cmdline" 2>/dev/null || true)"
        for pattern in "$@"; do
            case "$cmdline" in *"$pattern"*) echo "$pid"; break ;; esac
        done
    done
}

cleanup_stale() {
    local patterns=("/storage/ryubing/Ryubing.AppImage" "/tmp/.mount_Ryubing" "dwarfs /storage/ryubing" "Ryujinx" "ryujinx")
    local mouse_patterns=("ryubing_mouse_layer.py" "prism_mouse_layer.py" "chromium_mouse_layer.py" "citron_mouse_layer.py")
    
    local pids="$(_pids_matching "${patterns[@]}")"
    if [ -n "$pids" ]; then
        kill $pids 2>/dev/null || true
        sleep 2
        pids="$(_pids_matching "${patterns[@]}")"
        [ -n "$pids" ] && kill -9 $pids 2>/dev/null || true
    fi

    pids="$(_pids_matching "${mouse_patterns[@]}")"
    [ -n "$pids" ] && kill $pids 2>/dev/null || true

    for mp in /tmp/.mount_Ryubing*; do
        [ -e "$mp" ] || continue
        if grep -qs " ${mp} " /proc/mounts; then
            fusermount -uz "$mp" 2>/dev/null || umount -l "$mp" 2>/dev/null || true
        fi
        rm -rf "$mp" 2>/dev/null || true
    done
}

CRASH_MARKER="${RYUBING_CACHE}/.ryubing_crash_marker"
set_crash_marker()   { touch "$CRASH_MARKER"; }
clear_crash_marker() { rm -f "$CRASH_MARKER"; }

handle_previous_crash() {
    if [ -f "$CRASH_MARKER" ]; then
        nuke_shader_cache
        clear_crash_marker
    fi
}

nuke_shader_cache() {
    local ts="$(date +%Y%m%d-%H%M%S)"
    for target in "${RYUBING_DATA}/shader" "${RYUBING_CONFIG}/pipeline_cache" "${RYUBING_CACHE}/ryubing/shader" "${RYUBING_CACHE}/ryubing/pipeline_cache"; do
        [ -e "$target" ] || continue
        mv "$target" "${target}.bak-${ts}" 2>/dev/null || rm -rf "$target" 2>/dev/null || true
    done
}

setup_controller() {
    command -v inputplumber >/dev/null 2>&1 || return 0
    inputplumber device 0 targets set ds5 keyboard >/dev/null 2>&1 || true
}

_has_sway() { [ -S "$SWAYSOCK" ] && command -v swaymsg >/dev/null 2>&1; }

set_touchpad() {
    _has_sway || return 0
    swaymsg input "$TOUCHPAD_ID" events "$1" >/dev/null 2>&1 || true
}

attach_mouse_seat() {
    _has_sway || return 0
    swaymsg seat seat1 fallback no >/dev/null 2>&1 || true
    swaymsg seat seat0 attach "$MOUSE_ID" >/dev/null 2>&1 || true
    swaymsg seat seat0 attach "$TOUCHPAD_ID" >/dev/null 2>&1 || true
    swaymsg input "$TOUCHPAD_ID" events disabled >/dev/null 2>&1 || true
}

ryubing_window_manager() {
    _has_sway || return 0
    while true; do
        local tree="$(swaymsg -t get_tree 2>/dev/null)" || { sleep 1; continue; }
        local main_ids="$(printf '%s' "$tree" | jq -r '.. | objects | select((.window_properties.class // "") | test("ryubing|ryujinx"; "i")) | select((.window_properties.transient_for == null)) | .id' 2>/dev/null || true)"
        local all_ids="$(printf '%s' "$tree" | jq -r '.. | objects | select(.type == "con" or .type == "floating_con") | select(.pid != null or .window != null or .app_id != null) | .id' 2>/dev/null || true)"
        
        for id in $all_ids; do
            if echo "$main_ids" | grep -qw "$id"; then
                swaymsg "[con_id=${id}]" move workspace 1 >/dev/null 2>&1
                swaymsg "[con_id=${id}]" move window to output "$DISPLAY_OUTPUT" >/dev/null 2>&1
                swaymsg "[con_id=${id}]" floating disable >/dev/null 2>&1
                swaymsg "[con_id=${id}]" fullscreen enable >/dev/null 2>&1
            fi
        done
        sleep "$WM_POLL_INTERVAL"
    done
}

start_mouse_layer() {
    [ -x "$MOUSE_SCRIPT" ] || return 0
    "$MOUSE_SCRIPT" >"${RYUBING_CACHE}/ryubing_mouse_layer.log" 2>&1 &
    _mouse_pid=$!
    sleep 1
    attach_mouse_seat
}

start_helpers() {
    ryubing_window_manager >"${RYUBING_CACHE}/ryubing_window_manager.log" 2>&1 &
    _wm_pid=$!
    set_touchpad disabled
    start_mouse_layer
}

stop_helpers() {
    for pid in $_wm_pid $_mouse_pid; do
        [ -z "$pid" ] && continue
        kill -9 "$pid" 2>/dev/null || true
    done
    set_touchpad enabled
}

launch_ryubing() {
    cleanup_stale
    start_helpers
    set_crash_marker
    
    cd "$RYUBING_DIR" || return 1
    "$RYUBING_BIN" "$@" > "$RYUBING_EMU_LOG" 2>&1 &
    _ryubing_pid=$!

    wait "$_ryubing_pid" 2>/dev/null
    local status=$?
    
    clear_crash_marker
    stop_helpers
    return $status
}

on_exit() {
    [ -n "$_ryubing_pid" ] && kill "$_ryubing_pid" 2>/dev/null || true
    stop_helpers
}

main() {
    trap on_exit EXIT INT TERM
    setup_environment
    preflight || exit 1
    setup_controller
    handle_previous_crash
    launch_ryubing "$@"
    exit $?
}

main "$@"

Place a game in /storage/roms/switch/, restart EmulationStation, and it will boot perfectly.

Should also work on other devices with a bit of tweaking.

reddit.com
u/hellonbye — 4 days ago
▲ 2 r/rocknix+1 crossposts

Absolutely Stumped On MAME / FB NEO Samples

Howdy friends,

I cannot, for the life of me, find where the correct place to put arcade game audio samples in order to get them to play in games (Donkey Kong, Astro Blaster, etc).

I've got the new stable build of ROCKNIX installed on my RGB30.

I'm unable to locate any of the usual spots to place the samples.

Any help is greatly appreciated!

reddit.com
u/ObsidianArcade — 10 days ago
▲ 3 r/rocknix+1 crossposts

Wi-Fi always on at boot; issue fixed in nightly builds?

I updated my Powkiddy RGB30 to the latest stable Rocknix build, but I still have the following issue: Wi-Fi is on at boot (based on indicator next to clock) even though it's configured to be off in the Networking menu and was toggled off on the previous boot.

I'd like to stay on the stable Rocknix build, but would switch to nightly if this (albeit minor) issue were fixed.

For those running Rocknix nightly on their RGB30, has this issue been fixed?

reddit.com
u/stevenc80 — 13 days ago