diff --git a/Makefile b/Makefile index c8f08f5d..1530ee87 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,7 @@ endif # Default platforms to build (can be overridden with PLATFORMS=...) ifeq (,$(PLATFORMS)) -PLATFORMS = miyoomini trimuismart rg35xx rg35xxplus my355 tg5040 zero28 rgb30 m17 my282 magicmini rk3566 +PLATFORMS = miyoomini trimuismart rg35xx rg35xxplus my355 tg5040 zero28 rgb30 m17 my282 magicmini endif ########################################################### @@ -208,26 +208,35 @@ dev-run-16x9: # Usage: make dev-deploy - Deploy all platforms # make dev-deploy PLATFORM=X - Deploy single platform dev-deploy: - @if [ -n "$(PLATFORM)" ]; then \ - ./scripts/dev-deploy.sh --platform $(PLATFORM); \ + @DEPLOY_ARGS=""; \ + if [ -n "$(DEPLOY_PATH)" ]; then \ + DEPLOY_ARGS="--path $(DEPLOY_PATH)"; \ + fi; \ + if [ -n "$(PLATFORM)" ]; then \ + ./scripts/dev-deploy.sh --platform $(PLATFORM) $$DEPLOY_ARGS; \ else \ - ./scripts/dev-deploy.sh; \ + ./scripts/dev-deploy.sh $$DEPLOY_ARGS; \ fi # Build and deploy in one shot for dev iteration (always debug build) # Uses 'stage' to prepare files without compression (faster than full 'all') -# Usage: make dev-build-deploy - Build all platforms and deploy -# make dev-build-deploy PLATFORM=miyoomini - Build and deploy single platform +# Usage: make dev-build-deploy - Build all platforms and deploy +# make dev-build-deploy PLATFORM=miyoomini - Build and deploy single platform +# make dev-build-deploy DEPLOY_PATH=/Volumes/LESSUI - Override SD card path # Note: Single-platform requires 'make setup' to have been run first dev-build-deploy: - @if [ -n "$(PLATFORM)" ]; then \ + @DEPLOY_ARGS=""; \ + if [ -n "$(DEPLOY_PATH)" ]; then \ + DEPLOY_ARGS="--path $(DEPLOY_PATH)"; \ + fi; \ + if [ -n "$(PLATFORM)" ]; then \ if [ ! -d ./build/SYSTEM ]; then \ echo "Error: build/SYSTEM not found. Run 'make setup' first."; \ exit 1; \ fi; \ - $(MAKE) common PLATFORM=$(PLATFORM) DEBUG=1 && $(MAKE) stage && ./scripts/dev-deploy.sh --platform $(PLATFORM); \ + $(MAKE) common PLATFORM=$(PLATFORM) DEBUG=1 && $(MAKE) stage && ./scripts/dev-deploy.sh --platform $(PLATFORM) $$DEPLOY_ARGS; \ else \ - $(MAKE) setup DEBUG=1 && $(MAKE) $(PLATFORMS) DEBUG=1 && $(MAKE) special && $(MAKE) stage && ./scripts/dev-deploy.sh; \ + $(MAKE) setup DEBUG=1 && $(MAKE) $(PLATFORMS) DEBUG=1 && $(MAKE) special && $(MAKE) stage && ./scripts/dev-deploy.sh $$DEPLOY_ARGS; \ fi # Build all components for a specific platform (in Docker) diff --git a/Makefile.toolchain b/Makefile.toolchain index 11b81b85..04f509ac 100644 --- a/Makefile.toolchain +++ b/Makefile.toolchain @@ -16,10 +16,14 @@ # specific architectures (e.g., trimuismart and tg5040 need amd64). # # Adding a new platform: -# 1. Fork the union--toolchain repo to lessui-hq org -# 2. Add .github/workflows/build-container.yml to the fork -# 3. Trigger the workflow to build and publish container -# 4. Add platform entry to toolchains.json with appropriate architecture +# 1. Choose approach: +# a) Reuse existing toolchain: Add to toolchains.json with "toolchain" field +# (e.g., rgb30 reuses rk3566 toolchain) +# b) New toolchain: Fork union--toolchain repo to lessui-hq org +# 2. If creating new toolchain: +# - Add .github/workflows/build-container.yml to the fork +# - Trigger workflow to build and publish container +# 3. Add platform entry to toolchains.json with appropriate architecture # # DO NOT call this makefile directly unless debugging toolchain issues. # Use the main makefile's 'shell' and 'build' targets instead. @@ -43,7 +47,11 @@ GUEST_WORKSPACE = /root/workspace # Pre-built container registry CONTAINER_REGISTRY = ghcr.io CONTAINER_ORG = lessui-hq -CONTAINER_NAME = union-$(PLATFORM)-toolchain + +# Read toolchain name from toolchains.json (defaults to platform name) +# Allows platforms to share toolchains (e.g., rgb30 uses rk3566 toolchain) +TOOLCHAIN_NAME = $(shell jq -r --arg p "$(PLATFORM)" '.toolchains[$$p].toolchain // $$p' toolchains.json 2>/dev/null || echo "$(PLATFORM)") +CONTAINER_NAME = union-$(TOOLCHAIN_NAME)-toolchain CONTAINER_TAG = latest CONTAINER_IMAGE = $(CONTAINER_REGISTRY)/$(CONTAINER_ORG)/$(CONTAINER_NAME):$(CONTAINER_TAG) @@ -52,7 +60,7 @@ CONTAINER_IMAGE = $(CONTAINER_REGISTRY)/$(CONTAINER_ORG)/$(CONTAINER_NAME):$(CON DOCKER_PLATFORM = $(shell jq -r --arg p "$(PLATFORM)" '.toolchains[$$p].platform // "linux/arm64"' toolchains.json 2>/dev/null || echo "linux/arm64") # Common docker run options -DOCKER_RUN = docker run --rm --platform=$(DOCKER_PLATFORM) -e LOG_FLAGS="$(LOG_FLAGS)" -e OPT_FLAGS="$(OPT_FLAGS)" -e BUILD_HASH="$(BUILD_HASH)" -v $(HOST_WORKSPACE):$(GUEST_WORKSPACE) +DOCKER_RUN = docker run --rm --platform=$(DOCKER_PLATFORM) -e PLATFORM="$(PLATFORM)" -e LOG_FLAGS="$(LOG_FLAGS)" -e OPT_FLAGS="$(OPT_FLAGS)" -e BUILD_HASH="$(BUILD_HASH)" -v $(HOST_WORKSPACE):$(GUEST_WORKSPACE) # Default target: launch interactive shell (pulls image if missing) all: @@ -71,9 +79,15 @@ pull: echo "❌ Container not found: $(CONTAINER_IMAGE)" && \ echo "" && \ echo "To add support for $(PLATFORM):" && \ - echo " 1. Fork the union-$(PLATFORM)-toolchain to lessui-hq org" && \ - echo " 2. Add .github/workflows/build-container.yml" && \ - echo " 3. Trigger workflow to build and publish container" && \ + echo " Option A: Reuse existing toolchain" && \ + echo " 1. Add \"toolchain\": \"\" to toolchains.json" && \ + echo " 2. Specify platform architecture (linux/amd64 or linux/arm64)" && \ + echo "" && \ + echo " Option B: Create new toolchain" && \ + echo " 1. Fork union--toolchain to lessui-hq org" && \ + echo " 2. Add .github/workflows/build-container.yml" && \ + echo " 3. Trigger workflow to build and publish container" && \ + echo " 4. Add platform entry to toolchains.json" && \ echo "" && \ exit 1) @echo "✓ Updated to latest" diff --git a/scripts/dev-deploy.sh b/scripts/dev-deploy.sh index ace93913..0f91322b 100755 --- a/scripts/dev-deploy.sh +++ b/scripts/dev-deploy.sh @@ -4,6 +4,7 @@ # Usage: ./scripts/dev-deploy.sh [options] # # Options: +# --path PATH Override SD card path (default: /Volumes/LESSUI_DEV) # --no-update Skip .tmp_update (won't trigger update on device boot) # --platform X Only sync specific platform (e.g., miyoomini) # --no-eject Don't eject the SD card after sync @@ -20,7 +21,7 @@ set -e SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" -SD_CARD="/Volumes/LESSUI_DEV" +SD_CARD="/Volumes/LESSUI_DEV" # Default, can be overridden PAYLOAD_DIR="$PROJECT_ROOT/build/PAYLOAD" BASE_DIR="$PROJECT_ROOT/build/BASE" @@ -31,6 +32,14 @@ DO_EJECT=true while [[ $# -gt 0 ]]; do case $1 in + --path) + if [[ -z "${2:-}" || "$2" == --* ]]; then + echo "Error: --path requires a value" + exit 1 + fi + SD_CARD="$2" + shift 2 + ;; --no-update) SYNC_UPDATE=false shift @@ -54,7 +63,7 @@ while [[ $# -gt 0 ]]; do ;; *) echo "Error: Unknown option: $1" - echo "Usage: $0 [--no-update] [--platform ] [--no-eject]" + echo "Usage: $0 [--path ] [--no-update] [--platform ] [--no-eject]" exit 1 ;; esac diff --git a/skeleton/BOOT/common/updater b/skeleton/BOOT/common/updater index 8977f93c..3795b744 100755 --- a/skeleton/BOOT/common/updater +++ b/skeleton/BOOT/common/updater @@ -2,9 +2,23 @@ # NOTE: becomes .tmp_update/updater -# LessOS provides platform directly via environment variable -if [ -n "$LESSOS_PLATFORM" ]; then - PLATFORM=$(echo "$LESSOS_PLATFORM" | tr '[:upper:]' '[:lower:]') +# LessOS provides device name - map to LessUI platform +if [ -n "$LESSOS_DEVICE" ]; then + case "$LESSOS_DEVICE" in + *"RGB30"*) + PLATFORM="rgb30" + ;; + *"RG353P"*|*"RG353V"*|*"RG353M"*|*"RG353"*) + # Future: map to rg353 platform if/when we add it + # For now, unsupported + echo "LessUI: Device $LESSOS_DEVICE not yet supported" + PLATFORM="" + ;; + *) + echo "LessUI: Unknown LessOS device: $LESSOS_DEVICE" + PLATFORM="" + ;; + esac else # Stock OS - detect platform from cpuinfo INFO=$(cat /proc/cpuinfo 2>/dev/null) diff --git a/skeleton/SYSTEM/rk3566/bin/shutdown b/skeleton/SYSTEM/rk3566/bin/shutdown deleted file mode 100755 index 46ebe7c2..00000000 --- a/skeleton/SYSTEM/rk3566/bin/shutdown +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -if [ -n "$DATETIME_PATH" ]; then - echo `date +'%F %T'` > "$DATETIME_PATH" - sync -fi - -cat /dev/zero > /dev/fb0 -poweroff -# echo s > /proc/sysrq-trigger -# echo u > /proc/sysrq-trigger -# echo o > /proc/sysrq-trigger diff --git a/skeleton/SYSTEM/rk3566/cores/.keep b/skeleton/SYSTEM/rk3566/cores/.keep deleted file mode 100644 index e69de29b..00000000 diff --git a/skeleton/SYSTEM/rk3566/dat/.keep b/skeleton/SYSTEM/rk3566/dat/.keep deleted file mode 100644 index e69de29b..00000000 diff --git a/skeleton/SYSTEM/rk3566/lib/.keep b/skeleton/SYSTEM/rk3566/lib/.keep deleted file mode 100644 index e69de29b..00000000 diff --git a/skeleton/SYSTEM/rk3566/system.cfg b/skeleton/SYSTEM/rk3566/system.cfg deleted file mode 100644 index f2e1550f..00000000 --- a/skeleton/SYSTEM/rk3566/system.cfg +++ /dev/null @@ -1,2 +0,0 @@ --player_screen_sharpness = Crisp - diff --git a/toolchains.json b/toolchains.json index d1795ee3..be87624d 100644 --- a/toolchains.json +++ b/toolchains.json @@ -6,8 +6,9 @@ "tg5040": { "platform": "linux/amd64" }, - "rk3566": { - "platform": "linux/amd64" + "rgb30": { + "platform": "linux/amd64", + "toolchain": "rk3566" } } } diff --git a/workspace/all/common/gl_video.c b/workspace/all/common/gl_video.c index e7dc64e1..38518e49 100644 --- a/workspace/all/common/gl_video.c +++ b/workspace/all/common/gl_video.c @@ -1872,10 +1872,7 @@ void GLVideo_uploadFrame(const void* data, unsigned width, unsigned height, size } void GLVideo_presentSurface(SDL_Surface* surface) { - LOG_debug("presentSurface: enter"); - if (!gl_state.context_ready || gl_state.shutdown_prepared) { - LOG_debug("presentSurface: context not ready, returning"); return; } @@ -1884,28 +1881,21 @@ void GLVideo_presentSurface(SDL_Surface* surface) { return; } - LOG_debug("presentSurface: surface %dx%d", surface->w, surface->h); - SDL_Window* window = PLAT_getWindow(); if (!window) { LOG_error("GL video: no window for surface presentation"); return; } - LOG_debug("presentSurface: calling makeCurrent"); GLVideo_makeCurrent(); - LOG_debug("presentSurface: makeCurrent done"); // Bind backbuffer - LOG_debug("presentSurface: binding FBO 0"); glBindFramebuffer(GL_FRAMEBUFFER, 0); - LOG_debug("presentSurface: FBO 0 bound"); // Get screen dimensions int screen_w = 0; int screen_h = 0; SDL_GetWindowSize(window, &screen_w, &screen_h); - LOG_debug("presentSurface: screen %dx%d", screen_w, screen_h); if (screen_w <= 0 || screen_h <= 0) { LOG_error("GL video: invalid window size %dx%d", screen_w, screen_h); return; @@ -1917,8 +1907,6 @@ void GLVideo_presentSurface(SDL_Surface* surface) { if (!gl_state.ui_texture || gl_state.ui_texture_width != surf_w || gl_state.ui_texture_height != surf_h) { - LOG_debug("presentSurface: creating UI texture %ux%u", surf_w, surf_h); - if (gl_state.ui_texture) { glDeleteTextures(1, &gl_state.ui_texture); } @@ -1934,21 +1922,16 @@ void GLVideo_presentSurface(SDL_Surface* surface) { gl_state.ui_texture_width = surf_w; gl_state.ui_texture_height = surf_h; - - LOG_debug("presentSurface: UI texture created (id=%u)", gl_state.ui_texture); } - LOG_debug("presentSurface: uploading pixels"); glBindTexture(GL_TEXTURE_2D, gl_state.ui_texture); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, surf_w, surf_h, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, surface->pixels); - LOG_debug("presentSurface: setting viewport and clearing"); glViewport(0, 0, screen_w, screen_h); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); - LOG_debug("presentSurface: using shader program"); glUseProgram(gl_state.present_program); glActiveTexture(GL_TEXTURE0); @@ -1973,13 +1956,10 @@ void GLVideo_presentSurface(SDL_Surface* surface) { glVertexAttribPointer(gl_state.loc_position, 2, GL_FLOAT, GL_FALSE, 0, verts); glVertexAttribPointer(gl_state.loc_texcoord, 2, GL_FLOAT, GL_FALSE, 0, texco); - LOG_debug("presentSurface: drawing quad"); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDisableVertexAttribArray(gl_state.loc_position); glDisableVertexAttribArray(gl_state.loc_texcoord); - - LOG_debug("presentSurface: done"); } void GLVideo_swapBuffers(void) { diff --git a/workspace/all/paks/LessUI/platforms/magicmini/init.sh b/workspace/all/paks/LessUI/platforms/magicmini/init.sh index c5381ecb..aae2e5bc 100644 --- a/workspace/all/paks/LessUI/platforms/magicmini/init.sh +++ b/workspace/all/paks/LessUI/platforms/magicmini/init.sh @@ -1,21 +1,12 @@ #!/bin/sh # magicmini initialization -# CPU/GPU/DMC governors +# CPU/GPU/DMC governors (CPU speed controlled by frontend) echo userspace >/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor echo performance >/sys/devices/platform/ff400000.gpu/devfreq/ff400000.gpu/governor echo performance >/sys/devices/platform/dmc/devfreq/dmc/governor -CPU_PATH=/sys/devices/system/cpu/cpufreq/policy0/scaling_setspeed -CPU_SPEED_PERF=1608000 - -cpu_restore() { - echo $CPU_SPEED_PERF >$CPU_PATH -} -cpu_restore - -# SDL audio -export SDL_AUDIODRIVER=alsa +# Audio setup amixer cset name='Playback Path' SPK # Clear framebuffer diff --git a/workspace/all/paks/LessUI/platforms/miyoomini/init.sh b/workspace/all/paks/LessUI/platforms/miyoomini/init.sh index 99b53c53..74ae831e 100644 --- a/workspace/all/paks/LessUI/platforms/miyoomini/init.sh +++ b/workspace/all/paks/LessUI/platforms/miyoomini/init.sh @@ -1,19 +1,9 @@ #!/bin/sh # miyoomini initialization -# CPU governor +# CPU governor (speed controlled by frontend) echo userspace >/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor -# CPU speeds for player -export CPU_SPEED_MENU=504000 -export CPU_SPEED_GAME=1296000 -export CPU_SPEED_PERF=1488000 - -cpu_restore() { - overclock.elf $CPU_SPEED_PERF -} -cpu_restore - # Detect Mini Plus if [ -f /customer/app/axp_test ]; then IS_PLUS=true diff --git a/workspace/all/paks/LessUI/platforms/my282/init.sh b/workspace/all/paks/LessUI/platforms/my282/init.sh index d168b75a..e02e8131 100644 --- a/workspace/all/paks/LessUI/platforms/my282/init.sh +++ b/workspace/all/paks/LessUI/platforms/my282/init.sh @@ -4,11 +4,8 @@ # LED off echo 0 >/sys/class/leds/led1/brightness -# CPU speed control via reclock -cpu_restore() { - overclock.elf userspace 2 1344 384 1080 0 -} -cpu_restore +# CPU governor (speed controlled by frontend) +overclock.elf userspace 2 1344 384 1080 0 # Clean up tee and update log killall -9 tee diff --git a/workspace/all/paks/LessUI/platforms/my355/init.sh b/workspace/all/paks/LessUI/platforms/my355/init.sh index 82552802..a34c27e8 100644 --- a/workspace/all/paks/LessUI/platforms/my355/init.sh +++ b/workspace/all/paks/LessUI/platforms/my355/init.sh @@ -5,15 +5,8 @@ export PATH="$PATH:/usr/miyoo/bin:/usr/miyoo/sbin" export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/miyoo/lib" -# CPU setup +# CPU governor (speed controlled by frontend) echo userspace >/sys/devices/system/cpu/cpufreq/policy0/scaling_governor -CPU_PATH=/sys/devices/system/cpu/cpufreq/policy0/scaling_setspeed -CPU_SPEED_PERF=1992000 - -cpu_restore() { - echo $CPU_SPEED_PERF >$CPU_PATH -} -cpu_restore # Headphone jack GPIO echo 150 >/sys/class/gpio/export diff --git a/workspace/all/paks/LessUI/platforms/rg35xx/init.sh b/workspace/all/paks/LessUI/platforms/rg35xx/init.sh index be7ab22a..619fb0a8 100644 --- a/workspace/all/paks/LessUI/platforms/rg35xx/init.sh +++ b/workspace/all/paks/LessUI/platforms/rg35xx/init.sh @@ -1,18 +1,9 @@ #!/bin/sh # rg35xx initialization -# CPU setup +# CPU governor (speed controlled by frontend) echo userspace >/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor -export CPU_SPEED_MENU=504000 -export CPU_SPEED_GAME=1296000 -export CPU_SPEED_PERF=1488000 - -cpu_restore() { - overclock.elf $CPU_SPEED_PERF -} -cpu_restore - # Storage scheduler optimization echo noop >/sys/devices/b0238000.mmc/mmc_host/mmc0/emmc_boot_card/block/mmcblk0/queue/scheduler echo noop >/sys/devices/b0230000.mmc/mmc_host/mmc1/sd_card/block/mmcblk1/queue/scheduler diff --git a/workspace/all/paks/LessUI/platforms/rgb30/init.sh b/workspace/all/paks/LessUI/platforms/rgb30/init.sh index 9ab19c27..39f10d9a 100644 --- a/workspace/all/paks/LessUI/platforms/rgb30/init.sh +++ b/workspace/all/paks/LessUI/platforms/rgb30/init.sh @@ -1,22 +1,10 @@ #!/bin/sh -# rgb30 initialization +# RGB30 platform initialization (LessOS) +# Device: PowKiddy RGB30 (Rockchip RK3566) +# OS: LessOS (ROCKNIX-based) -# CPU setup -echo userspace >/sys/devices/system/cpu/cpufreq/policy0/scaling_governor -CPU_PATH=/sys/devices/system/cpu/cpufreq/policy0/scaling_setspeed -CPU_SPEED_PERF=1992000 - -cpu_restore() { - echo $CPU_SPEED_PERF >$CPU_PATH -} -cpu_restore - -# Clean up JELOS filesystem check litter -rm -f "$SDCARD_PATH"/FSCK*.REC - -# SDL environment for sdl12-compat -export SDL_VIDEODRIVER=kmsdrm -export SDL_AUDIODRIVER=alsa +# CPU governor (speed controlled by frontend) +echo userspace >/sys/devices/system/cpu/cpufreq/policy0/scaling_governor 2>/dev/null # Start keymon LOG_FILE="$LOGS_PATH/keymon.log" keymon.elf & diff --git a/workspace/all/paks/LessUI/platforms/rk3566/init.sh b/workspace/all/paks/LessUI/platforms/rk3566/init.sh deleted file mode 100644 index 2573b940..00000000 --- a/workspace/all/paks/LessUI/platforms/rk3566/init.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh -# RK3566 platform initialization (LessOS) -# Supports: RGB30, RG353P/M/V/VS, and other RK3566 devices - -type log_info >/dev/null 2>&1 && log_info "RK3566 platform init starting" - -# CPU setup -echo userspace >/sys/devices/system/cpu/cpufreq/policy0/scaling_governor 2>/dev/null -CPU_PATH=/sys/devices/system/cpu/cpufreq/policy0/scaling_setspeed -CPU_SPEED_PERF=1992000 - -cpu_restore() { - echo "$CPU_SPEED_PERF" >"$CPU_PATH" 2>/dev/null -} -cpu_restore -type log_info >/dev/null 2>&1 && log_info "CPU governor set to userspace" - -# SDL environment -export SDL_AUDIODRIVER=alsa -type log_info >/dev/null 2>&1 && log_info "SDL_AUDIODRIVER=$SDL_AUDIODRIVER" - -# Start keymon -type log_info >/dev/null 2>&1 && log_info "Starting keymon..." -LOG_FILE="$LOGS_PATH/keymon.log" keymon.elf & -KEYMON_PID=$! -type log_info >/dev/null 2>&1 && log_info "keymon started (PID: $KEYMON_PID)" diff --git a/workspace/all/paks/LessUI/platforms/tg5040/init.sh b/workspace/all/paks/LessUI/platforms/tg5040/init.sh index cf1b50c8..11b4ba39 100644 --- a/workspace/all/paks/LessUI/platforms/tg5040/init.sh +++ b/workspace/all/paks/LessUI/platforms/tg5040/init.sh @@ -68,15 +68,8 @@ trimui_inputd & # Start stock hardware daemon hardwareservice & -# CPU setup +# CPU governor (speed controlled by frontend) echo userspace >/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor -CPU_PATH=/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed -CPU_SPEED_PERF=2000000 - -cpu_restore() { - echo $CPU_SPEED_PERF >$CPU_PATH -} -cpu_restore # Disable network killall MtpDaemon diff --git a/workspace/all/paks/LessUI/platforms/trimuismart/init.sh b/workspace/all/paks/LessUI/platforms/trimuismart/init.sh index a02ff520..2036a6f2 100644 --- a/workspace/all/paks/LessUI/platforms/trimuismart/init.sh +++ b/workspace/all/paks/LessUI/platforms/trimuismart/init.sh @@ -8,15 +8,9 @@ export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/trimui/lib" # Button configuration echo A,B,X,Y,L,R >/sys/module/gpio_keys_polled/parameters/button_config -# CPU setup +# CPU governor (speed controlled by frontend) echo userspace >/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor CPU_PATH=/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed -CPU_SPEED_PERF=1536000 - -cpu_restore() { - echo $CPU_SPEED_PERF >$CPU_PATH -} -cpu_restore # LED off leds_off diff --git a/workspace/all/paks/LessUI/platforms/zero28/init.sh b/workspace/all/paks/LessUI/platforms/zero28/init.sh index 811b488e..d23b34af 100644 --- a/workspace/all/paks/LessUI/platforms/zero28/init.sh +++ b/workspace/all/paks/LessUI/platforms/zero28/init.sh @@ -6,15 +6,8 @@ mkdir -p "$BIOS_PATH" mkdir -p "$SDCARD_PATH/Roms" mkdir -p "$SAVES_PATH" -# CPU setup +# CPU governor (speed controlled by frontend) echo userspace >/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor -CPU_PATH=/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed -CPU_SPEED_PERF=1800000 - -cpu_restore() { - echo $CPU_SPEED_PERF >$CPU_PATH -} -cpu_restore # Backlight fix bl_disable && bl_enable diff --git a/workspace/all/paks/Tools/System Report/pak.json b/workspace/all/paks/Tools/System Report/pak.json index 67d724ec..8667f0e3 100644 --- a/workspace/all/paks/Tools/System Report/pak.json +++ b/workspace/all/paks/Tools/System Report/pak.json @@ -13,7 +13,6 @@ "tg5040", "zero28", "rgb30", - "rk3566", "m17", "my282", "magicmini" diff --git a/workspace/all/paks/config/platforms.json b/workspace/all/paks/config/platforms.json index cad1c7d6..6e514c66 100644 --- a/workspace/all/paks/config/platforms.json +++ b/workspace/all/paks/config/platforms.json @@ -50,14 +50,7 @@ "nice_prefix": "" }, "rgb30": { - "description": "Powkiddy RGB30", - "arch": "arm64", - "sdcard_path": "/storage/roms", - "shutdown_cmd": "shutdown", - "nice_prefix": "" - }, - "rk3566": { - "description": "Rockchip RK3566 devices (LessOS)", + "description": "Powkiddy RGB30 (LessOS)", "arch": "arm64", "sdcard_path": "/storage", "shutdown_cmd": "poweroff", diff --git a/workspace/all/player/player.c b/workspace/all/player/player.c index 09c463af..66914eb8 100644 --- a/workspace/all/player/player.c +++ b/workspace/all/player/player.c @@ -2446,12 +2446,12 @@ static void retro_log_callback(enum retro_log_level level, const char* fmt, ...) va_end(args); // Map libretro levels to our levels and log + // Note: Core DEBUG/INFO logs are demoted to LOG_debug to avoid huge log files + // in release builds. Only WARN/ERROR from cores are shown in release logs. switch (level) { case RETRO_LOG_DEBUG: - LOG_debug("%s", msg_buffer); - break; case RETRO_LOG_INFO: - LOG_info("%s", msg_buffer); + LOG_debug("%s", msg_buffer); break; case RETRO_LOG_WARN: LOG_warn("%s", msg_buffer); diff --git a/workspace/all/player/player_loop_vsync.inc b/workspace/all/player/player_loop_vsync.inc index 0d1a880e..743bef4f 100644 --- a/workspace/all/player/player_loop_vsync.inc +++ b/workspace/all/player/player_loop_vsync.inc @@ -98,9 +98,7 @@ static void run_main_loop(void) { // Measure frame execution time for auto CPU scaling uint64_t frame_start = getMicroseconds(); GLVideo_bindFBO(); - LOG_debug("Main loop: calling core.run()"); core.run(); - LOG_debug("Main loop: core.run() returned"); uint64_t frame_time = getMicroseconds() - frame_start; // Store frame time for auto CPU scaling analysis @@ -130,19 +128,14 @@ static void run_main_loop(void) { input_poll_callback(); if (show_menu) { - LOG_debug("Main loop: show_menu=1, entering Menu_loop"); Menu_loop(); - LOG_debug("Main loop: returned from Menu_loop, show_menu=%d", show_menu); // Rebind FBO for HW cores after menu (menu uses FBO 0) if (GLVideo_isEnabled()) { - LOG_debug("Main loop: re-binding FBO after menu exit"); GLVideo_bindFBO(); } } - LOG_debug("Main loop: about to call hdmimon"); hdmimon(); - LOG_debug("Main loop: hdmimon returned, continuing loop"); } } diff --git a/workspace/all/player/player_menu.c b/workspace/all/player/player_menu.c index 7ed02001..add91bca 100644 --- a/workspace/all/player/player_menu.c +++ b/workspace/all/player/player_menu.c @@ -467,8 +467,6 @@ static void Menu_afterSleep(void) { } static void Menu_loop_ctx(PlayerContext* ctx) { - LOG_debug("Menu_loop_ctx: enter, HW=%d", GLVideo_isEnabled()); - PlayerMenuState* m = ctx->menu; GFX_Renderer* r = (GFX_Renderer*)ctx->renderer; struct Game* g = ctx->game; @@ -786,10 +784,8 @@ static void Menu_loop_ctx(PlayerContext* ctx) { // Use GL presentation when HW rendering is active to avoid SDL/GL conflicts if (GLVideo_isEnabled()) { - LOG_debug("Menu: about to call GLVideo_presentSurface"); GLVideo_presentSurface(*scr); GLVideo_swapBuffers(); - LOG_debug("Menu: returned from GLVideo_presentSurface"); } else { GFX_present(NULL); } diff --git a/workspace/rgb30/Makefile b/workspace/rgb30/Makefile index 6b6cd31b..524b002c 100644 --- a/workspace/rgb30/Makefile +++ b/workspace/rgb30/Makefile @@ -10,33 +10,19 @@ endif ########################################################### -REQUIRES_COMMANDER = other/DinguxCommander -REQUIRES_SDLCOMPAT = other/sdl12-compat +# LessOS provides SDL2 natively - no sdl12-compat needed # keymon.elf is now built in workspace/all/utils +# LessOS doesn't need DinguxCommander (file manager for stock firmware) all: readmes show .PHONY: show show: @$(MAKE) -C show -early: $(REQUIRES_COMMANDER) $(REQUIRES_SDLCOMPAT)/build - @cd $(REQUIRES_COMMANDER) && $(MAKE) -s - @cd $(REQUIRES_SDLCOMPAT) && cmake --build build >/dev/null +# No early dependencies for rgb30 +early: clean: - @cd $(REQUIRES_COMMANDER) && $(MAKE) -s clean - @cd $(REQUIRES_SDLCOMPAT) && rm -rf build - -########################################################### - -$(REQUIRES_COMMANDER): - git clone --depth 1 --branch minui-rgb30 https://github.com/shauninman/DinguxCommander.git $(REQUIRES_COMMANDER) - -$(REQUIRES_SDLCOMPAT): - git clone --depth 1 --branch minui-rgb30 https://github.com/shauninman/sdl12-compat.git $(REQUIRES_SDLCOMPAT) - -$(REQUIRES_SDLCOMPAT)/build: $(REQUIRES_SDLCOMPAT) - cd $(REQUIRES_SDLCOMPAT) && cmake --toolchain ./toolchain.cmake -Bbuild -DCMAKE_BUILD_TYPE=Release . include ../all/readmes/Makefile \ No newline at end of file diff --git a/workspace/rgb30/README.md b/workspace/rgb30/README.md index e5343c0a..5a143e5f 100644 --- a/workspace/rgb30/README.md +++ b/workspace/rgb30/README.md @@ -1,349 +1,73 @@ -# Anbernic RGB30 +# RGB30 Platform -Platform implementation for the Anbernic RGB30 retro handheld device. +Platform implementation for the PowKiddy RGB30 running LessOS. -## Hardware Specifications +## Device -### Display -- **Resolution**: 720x720 (square display, 1:1 aspect ratio) -- **Color Depth**: 16-bit RGB565 -- **UI Scale**: 2x (uses `assets@2x.png`) -- **HDMI Output**: 1280x720 (720p) with automatic switching +- **PowKiddy RGB30** - Rockchip RK3566 (Cortex-A55), 720x720 square display +- **OS**: LessOS (ROCKNIX-based) -### Input -- **D-Pad**: Up, Down, Left, Right -- **Face Buttons**: A, B, X, Y -- **Shoulder Buttons**: L1, R1, L2, R2 -- **Analog Sticks**: L3, R3 (clickable, used as menu modifiers) -- **System Buttons**: - - Two MENU buttons (primary and alternate via L3/R3) - - POWER button - - Dedicated PLUS/MINUS volume buttons - - SELECT and START buttons +## Hardware -### Input Method -- **Primary**: Evdev input events (direct reading from `/dev/input/event*`) -- **Implementation**: Reads raw `input_event` structures for all input -- **Notable**: Bypasses SDL input APIs entirely +| Feature | Specification | +|---------|---------------| +| Display | 720x720 (1:1 square), 16-bit RGB565, 2x UI scale | +| GPU | Mali-G52 (OpenGL ES 2.0) | +| HDMI | 1280x720 output with auto-detection | +| Input | D-pad, A/B/X/Y, L1/R1/L2/R2, dual analog sticks (L3/R3) | +| Audio | ALSA, headphone jack detection, HDMI audio | +| Storage | `/storage` (LessOS default) | -### CPU & Performance -- ARM processor with NEON SIMD support -- No overclocking support +## Input -### Power Management -- Power button detection via SDL keyboard (SDLK_POWER) -- Sleep/wake functionality +Uses `rocknix-singleadc-joypad` kernel driver via evdev. -### Audio/Video -- **Headphone Jack**: Automatic detection and audio routing -- **HDMI Output**: Automatic detection with video/audio switching -- **Volume Range**: 0-20 (raw: 0-100 via amixer) -- **Brightness Range**: 0-10 (raw: 0-255) - -### Storage -- SD card mounted at `/storage/roms` - -## Platform Architecture - -The RGB30 uses a **hybrid input system** that combines: -- SDL2 joystick for gamepad buttons (D-Pad, face buttons, shoulders) -- Minimal SDL keyboard for power button -- Evdev codes for volume control and L3/R3 menu modifiers - -This approach allows hardware volume buttons to work independently while maintaining standard gamepad compatibility. +| Combination | Function | +|-------------|----------| +| PLUS/MINUS | Volume | +| MENU + PLUS/MINUS | Brightness | +| POWER | Sleep/wake | ## Directory Structure ``` rgb30/ -├── platform/ Platform-specific hardware definitions -│ └── platform.h Button mappings, display specs, HDMI support -├── keymon/ Hardware button monitoring daemon -│ └── keymon.c Volume/brightness + headphone/HDMI detection -├── libmsettings/ Settings library with audio/video routing -│ ├── msettings.c Shared memory settings management -│ └── msettings.h Settings API (volume, brightness, jack, HDMI) -├── show/ Boot splash screen utility -│ ├── show.c SDL2-based image display (supports HDMI) -│ └── makefile Build configuration -├── cores/ Libretro cores (submodules + builds) -└── other/ Third-party dependencies - ├── DinguxCommander/ File manager (branch: launcher-rgb30) - └── sdl12-compat/ SDL 1.2 compatibility layer (branch: launcher-rgb30) +├── platform/ Platform definitions and render backend +├── keymon/ Button monitoring daemon (prebuilt) +├── libmsettings/ Settings library (volume, brightness, HDMI) +├── show/ Boot splash display +└── install/ Boot script ``` -## Input System - -The RGB30 uses a **joystick-first input architecture**: - -1. **SDL Joystick API**: Primary gamepad input (D-Pad, face buttons, shoulders, Start/Select) -2. **SDL Keyboard**: Power button only (SDLK_POWER) -3. **Evdev Codes**: Volume buttons (114/115) and L3/R3 menu modifiers (317/318) - -### Joystick Button Mappings - -| Physical Button | Joystick Index | -|----------------|----------------| -| D-Pad Up/Down/Left/Right | 13/14/15/16 | -| A, B, X, Y | 1, 0, 2, 3 | -| L1, R1 | 4, 5 | -| L2, R2 | 6, 7 | -| SELECT, START | 8, 9 | -| MENU (primary) | 11 | -| MENU ALT (secondary) | 12 | - -### Input Event Devices - -The keymon daemon monitors multiple input devices: -- **event0-4**: Gamepad and button input -- **js0**: Joystick device - -### Button Combinations - -| Combination | Function | -|-------------|----------| -| PLUS | Increase volume | -| MINUS | Decrease volume | -| L3/R3 + PLUS | Increase brightness | -| L3/R3 + MINUS | Decrease brightness | -| POWER | Sleep/wake device | -| X (in launcher) | Resume from save state | - -### Hardware Monitoring - -The keymon daemon runs a background thread to monitor: -- **Headphone jack state**: `/sys/bus/platform/devices/singleadc-joypad/hp` -- **HDMI connection state**: `/sys/class/extcon/hdmi/cable.0/state` - -Audio and video routing automatically switches when headphones or HDMI are connected/disconnected. - ## Building -### Prerequisites -Requires Docker with RGB30 cross-compilation toolchain. - -### Build Commands - ```bash -# Enter platform build environment make PLATFORM=rgb30 shell - -# Inside container: build all platform components cd /root/workspace/rgb30 make - -# This builds (in early target): -# - DinguxCommander (file manager) -# - sdl12-compat (SDL 1.2 compatibility layer) -# -# And (in all target): -# - show.elf (boot splash display) -# - All libretro cores in cores/ ``` -### Dependencies - -The platform automatically clones required dependencies on first build: -- **DinguxCommander**: `github.com/shauninman/DinguxCommander.git` (branch: `launcher-rgb30`) -- **sdl12-compat**: `github.com/shauninman/sdl12-compat.git` (branch: `launcher-rgb30`) - -Both dependencies use custom toolchain configurations for the RGB30 hardware. +Uses the `rk3566` toolchain (shared via `toolchains.json`). ## Installation -### File System Layout - -LessUI installs to the SD card with the following structure: - -``` -/storage/roms/ -├── .system/ -│ ├── rgb30/ Platform-specific binaries -│ │ ├── bin/ Utilities (keymon, show, etc.) -│ │ └── paks/ Applications and emulators -│ │ └── LessUI.pak/ Main launcher -│ └── res/ Shared UI assets -│ ├── assets@2x.png UI sprite sheet (2x scale) -│ └── InterTight-Bold.ttf -├── .userdata/ User settings and save data -│ └── rgb30/ Platform-specific settings -│ └── msettings.bin Volume/brightness preferences -├── Roms/ ROM files organized by system -└── LessUI.7z Update package (if present) -``` - -### Settings Management - -The RGB30 uses shared memory for settings synchronization between processes: - -**Settings Stored**: -- Brightness level (0-10) -- Speaker volume (0-20) -- Headphone volume (0-20, separate from speaker) -- Jack state (headphones connected/disconnected) -- HDMI state (HDMI connected/disconnected) - -**Persistence**: Settings are saved to `$USERDATA_PATH/msettings.bin` and persist across reboots. - -## Platform-Specific Features +LessOS handles boot via `/storage/lessos/init.sh`. LessUI installs to: -### Square Display - -The 720x720 square display (1:1 aspect ratio) requires UI adjustments: - -| Parameter | Value | Notes | -|-----------|-------|-------| -| `MAIN_ROW_COUNT` | 8 rows | More rows visible than standard 640x480 | -| `PADDING` | 40px | Larger padding for square layout | - -These settings maximize content visibility while maintaining comfortable spacing. - -### HDMI Output Support - -The platform includes full HDMI support: - -**Output Resolution**: 1280x720 (720p) - -**Automatic Behavior**: -- Video output switches to HDMI when connected -- Audio routing changes to HDMI audio -- Volume locked at 100% on HDMI (brightness control disabled) -- Automatically reverts to internal display/speaker when disconnected - -**Implementation**: Background thread in keymon polls HDMI state every second. - -### Audio Routing - -Smart audio routing based on connected devices: - -1. **Internal Speaker**: Default audio output -2. **Headphones**: Auto-detected, switches to headphone output, uses separate volume level -3. **HDMI**: Auto-detected, switches to HDMI audio, locks volume at 100% - -**amixer Commands**: -- Playback path: `amixer cset name='Playback Path' 'SPK'|'HP'` -- Volume: `amixer sset -M 'Master' N%` - -### Brightness Control - -Hardware brightness via sysfs: -- **Path**: `/sys/class/backlight/backlight/brightness` -- **Range**: 0-255 (raw), mapped from 0-10 user scale -- **Disabled on HDMI**: Brightness adjustments ignored when HDMI connected - -**Brightness Curve** (non-linear for better low-end visibility): ``` -Level 0: 4 Level 1: 6 Level 2: 10 Level 3: 16 -Level 4: 32 Level 5: 48 Level 6: 64 Level 7: 96 -Level 8: 128 Level 9: 192 Level 10: 255 +/storage/ +├── .system/rgb30/ Platform binaries and paks +├── .userdata/rgb30/ User settings +└── Roms/ ROM files ``` -### Volume Button Quirks - -The platform has hardware volume buttons with evdev codes: -- **CODE_PLUS**: 129 (Volume up) - **swapped from kernel default** -- **CODE_MINUS**: 128 (Volume down) - **swapped from kernel default** - -These codes are swapped in platform.h to correct the hardware mapping. - -### Repeat Functionality - -Volume and brightness buttons support repeat: -- **Initial delay**: 300ms before repeat starts -- **Repeat interval**: 100ms between repeats -- **Ignores stale input**: After system sleep (>1 second gap), input ignored to prevent spurious events - -## Supported Emulator Cores - -The RGB30 platform includes these libretro cores: - -| Core | Systems | Notes | -|------|---------|-------| -| **fceumm** | NES, Famicom | Nintendo Entertainment System | -| **gambatte** | Game Boy, Game Boy Color | Accuracy-focused | -| **gpsp** | Game Boy Advance | Fast, requires BIOS | -| **pcsx_rearmed** | PlayStation | Optimized ARM port | -| **picodrive** | Genesis, Mega Drive, 32X, Sega CD | Multi-system | -| **snes9x2005_plus** | SNES | Lightweight, Blargg APU | -| **pokemini** | Pokemon Mini | Niche handheld | -| **fake-08** | PICO-8 | Fantasy console | -| **mednafen_pce_fast** | PC Engine, TurboGrafx-16 | Fast variant | -| **mednafen_vb** | Virtual Boy | Nintendo VR handheld | -| **mednafen_supafaust** | SNES | High accuracy | -| **mgba** | Game Boy Advance | High accuracy | -| **race** | Neo Geo Pocket, Neo Geo Pocket Color | SNK handheld | - -## Included Tools - -### Files.pak -DinguxCommander-based file manager (custom RGB30 build): -- Full file operations (copy, cut, paste, delete, rename) -- Directory navigation -- Image preview support -- Integrated with LessUI launcher - -## Known Issues / Quirks - -### Hardware Quirks -1. **Joystick-first input**: Unlike keyboard-based platforms, uses SDL joystick API primarily -2. **Dual menu buttons**: L3/R3 analog stick clicks act as menu modifiers (codes 317/318) -3. **Volume code swap**: Hardware volume button codes swapped in software to correct mapping -4. **HDMI volume lock**: Volume/brightness controls disabled when HDMI connected -5. **Audio crackling**: Light crackling reported in some cores (fceumm, snes9x2005_plus) - likely SDL2 audio pipeline issue - -### Development Notes -1. **SDL2**: Platform uses SDL2 (not SDL 1.2), requiring sdl12-compat for legacy cores -2. **Shared memory settings**: libmsettings uses `/SharedSettings` SHM for IPC -3. **Settings host**: keymon is always the settings "host" (first to create SHM) -4. **HDMI polling**: Background thread polls HDMI state at 1Hz (every second) -5. **60Hz input polling**: Main keymon loop runs at 60Hz (16.6ms sleep) - -### Input Limitations -- **No L3/R3 for games**: L3/R3 reserved for system menu modifier, not available to cores -- **Evdev overhead**: Volume buttons require evdev monitoring (can't use SDL alone) - -### Audio Buffer Size -Default audio buffer: `SAMPLES 400` (balanced latency vs stability) - -## Testing - -When testing changes: -1. Verify joystick input works correctly (D-Pad, face buttons, shoulders) -2. Test HDMI detection and automatic video/audio switching -3. Check headphone jack detection and audio routing -4. Verify volume control with PLUS/MINUS buttons -5. Test brightness control with L3/R3 + PLUS/MINUS -6. Confirm settings persist across reboots (msettings.bin) -7. Test on both internal display and HDMI output -8. Verify square display UI layout (720x720) - -## Related Documentation - -- Main project docs: `../../README.md` -- Platform abstraction: `../../all/common/defines.h` -- Shared code: `../../all/launcher/launcher.c` (launcher), `../../all/player/player.c` (libretro frontend) -- Build system: `../../Makefile` (host), `./makefile` (platform) -- Platform header: `./platform/platform.h` (all hardware definitions) - -## Maintainer Notes - -This platform demonstrates several advanced LessUI features: +## Platform Features -**Unique Characteristics**: -- Square display (720x720) - unique aspect ratio among LessUI platforms -- HDMI output support with automatic switching -- Dual menu modifier buttons (L3/R3) -- Hybrid input system (joystick + keyboard + evdev) -- Background hardware monitoring threads -- Shared memory settings management -- Separate volume levels for speaker vs headphones +- **OpenGL ES**: Hardware-accelerated rendering (`HAS_OPENGLES 1`) +- **HDMI**: Auto-detection with video/audio routing +- **Overscan**: Supported (`PLAT_supportsOverscan`) +- **Effects**: Grid/line overlays via OpenGL -**Reference Implementation For**: -- HDMI output detection and switching -- Headphone jack detection -- Multi-device audio routing -- Non-standard display aspect ratios -- SDL2-based platforms -- Joystick-first input handling +## Related -Changes to this platform should be tested with HDMI output and headphone jack to ensure automatic switching continues to work correctly. +- Platform header: `platform/platform.h` +- Shared code: `../all/launcher/`, `../all/player/` diff --git a/workspace/rk3566/install/boot.sh b/workspace/rgb30/install/boot.sh similarity index 97% rename from workspace/rk3566/install/boot.sh rename to workspace/rgb30/install/boot.sh index 15adc2b8..a4fc0eb1 100755 --- a/workspace/rk3566/install/boot.sh +++ b/workspace/rgb30/install/boot.sh @@ -1,7 +1,7 @@ #!/bin/sh -# NOTE: becomes .tmp_update/rk3566.sh +# NOTE: becomes .tmp_update/rgb30.sh -PLATFORM="rk3566" +PLATFORM="rgb30" # Use LessOS storage path if set, otherwise default SDCARD_PATH="${LESSOS_STORAGE:-/storage}" UPDATE_PATH="$SDCARD_PATH/LessUI.7z" diff --git a/workspace/rgb30/platform/Makefile.copy b/workspace/rgb30/platform/Makefile.copy index 812731e9..76da13e3 100644 --- a/workspace/rgb30/platform/Makefile.copy +++ b/workspace/rgb30/platform/Makefile.copy @@ -1,5 +1,13 @@ $(PLATFORM): # $@ + cp ./workspace/$@/keymon/keymon.elf ./build/SYSTEM/$@/bin/ # show.elf (platform-specific build) cp ./workspace/$@/show/show.elf ./build/SYSTEM/$@/bin/ - rsync -a ./workspace/$@/other/sdl12-compat/build/libSDL-1.2.so.1.2.69 ./build/SYSTEM/$@/lib/libSDL-1.2.so.0 \ No newline at end of file + # LessOS provides SDL2 natively - no sdl12-compat needed + # installer + rsync -a ./workspace/$@/install/boot.sh ./build/BOOT/common/$@.sh + mkdir -p ./build/BOOT/common/$@/ + cp ./workspace/$@/show/show.elf ./build/BOOT/common/$@/ + # boot assets + rsync -a ./skeleton/SYSTEM/res/installing@3x.png ./build/BOOT/common/$@/installing.png + rsync -a ./skeleton/SYSTEM/res/updating@3x.png ./build/BOOT/common/$@/updating.png \ No newline at end of file diff --git a/workspace/rgb30/platform/Makefile.env b/workspace/rgb30/platform/Makefile.env index b5d3e2b3..70ba8f64 100644 --- a/workspace/rgb30/platform/Makefile.env +++ b/workspace/rgb30/platform/Makefile.env @@ -1,4 +1,4 @@ -# rgb30 +# rgb30 - LessOS toolchain ARCH = -mtune=cortex-a55 -march=armv8.2-a -O3 -LIBS = -flto -lrga +LIBS = -flto -lrga -ldrm -lstdc++ -lasound -lfreetype -ljpeg -lpng16 -lbz2 SDL = SDL2 \ No newline at end of file diff --git a/workspace/rgb30/platform/platform.c b/workspace/rgb30/platform/platform.c index 8203f6fc..d05a2dcf 100644 --- a/workspace/rgb30/platform/platform.c +++ b/workspace/rgb30/platform/platform.c @@ -1,19 +1,22 @@ /** - * platform.c - Powkiddy RGB30 platform implementation + * platform.c - PowKiddy RGB30 platform implementation * * REFACTORED VERSION - Uses shared render_sdl2 backend * - * Platform-specific code for the Powkiddy RGB30 handheld device. + * Platform-specific code for PowKiddy RGB30 handheld. + * Device: PowKiddy RGB30 (Rockchip RK3566, Cortex-A55) + * OS: LessOS (ROCKNIX-based) + * * Key features: + * - 720x720 square display * - Dual analog sticks with swapped right stick axes (X/Y reversed) * - WiFi support with status monitoring * - Grid and line visual effects for retro aesthetics - * - Rotation support for display output - * - Dynamic device model detection from device tree + * - HDMI output with rotation support + * - Uses rocknix-singleadc-joypad kernel driver * - Overscan support (PLAT_supportsOverscan returns 1) * - * The RGB30 uses the Rockchip RK3566 SoC with 720x720 display. - * Input events are read directly from /dev/input/event* devices. + * Input is read directly from /dev/input/event* devices via evdev. */ #include @@ -33,6 +36,7 @@ #include "platform.h" #include "utils.h" +#include "gl_video.h" #include "render_sdl2.h" #include "scaler.h" @@ -80,11 +84,13 @@ void PLAT_setSharpness(int sharpness) { } void PLAT_setEffect(int effect) { - SDL2_setEffect(&vid_ctx, effect); + // Only GL path is used on GLES platforms (SDL2 effect state is unused) + GLVideo_setEffect(effect); } void PLAT_setEffectColor(int color) { - SDL2_setEffectColor(&vid_ctx, color); + // Only GL path is used on GLES platforms (SDL2 effect state is unused) + GLVideo_setEffectColor(color); } void PLAT_vsync(int remaining) { @@ -99,6 +105,14 @@ void PLAT_present(GFX_Renderer* renderer) { SDL2_present(&vid_ctx, renderer); } +SDL_Window* PLAT_getWindow(void) { + return SDL2_getWindow(&vid_ctx); +} + +int PLAT_getRotation(void) { + return SDL2_getRotation(&vid_ctx); +} + int PLAT_supportsOverscan(void) { return 1; } diff --git a/workspace/rgb30/platform/platform.h b/workspace/rgb30/platform/platform.h index a2ce5587..189df017 100644 --- a/workspace/rgb30/platform/platform.h +++ b/workspace/rgb30/platform/platform.h @@ -1,19 +1,18 @@ /** * rgb30/platform/platform.h - Platform definitions for PowKiddy RGB30 * - * Supported devices (Rockchip RK3566, Cortex-A55): - * - PowKiddy RGB30: 4.0" 720x720 display + * Device: PowKiddy RGB30 (Rockchip RK3566, Cortex-A55) + * OS: LessOS (ROCKNIX-based) * * Hardware features: * - 720x720 square display (1:1 aspect ratio) * - 1280x720 HDMI output support * - D-pad and face buttons (A/B/X/Y) * - Shoulder buttons (L1/R1/L2/R2) - * - Menu buttons (primary and alternate) - * - Uses hybrid input (minimal SDL keyboard + joystick) - * - Larger UI with increased row count and padding + * - Dual analog sticks with L3/R3 clicks + * - Uses rocknix-singleadc-joypad kernel driver * - * @note Power button uses SDL keyboard mapping, volume controls use evdev codes + * @note Input handled via LessOS's standardized joypad driver */ #ifndef PLATFORM_H @@ -25,6 +24,12 @@ #define PLATFORM "rgb30" +/////////////////////////////// +// Hardware Capabilities +/////////////////////////////// + +#define HAS_OPENGLES 1 // Mali-G52 GPU supports OpenGL ES 2.0 + /////////////////////////////// // Audio Configuration /////////////////////////////// @@ -182,7 +187,8 @@ // Platform-Specific Paths and Settings /////////////////////////////// -#define SDCARD_PATH "/storage/roms" // Path to SD card mount point +#define SDCARD_PATH \ + "/storage" // Path to SD card mount point (LessOS default, overridden by LESSOS_STORAGE) #define MUTE_VOLUME_RAW 0 // Raw value for muted volume /////////////////////////////// @@ -191,8 +197,8 @@ #define KEYMON_BUTTON_MENU 317 #define KEYMON_BUTTON_MENU_ALT 318 -#define KEYMON_BUTTON_PLUS 114 -#define KEYMON_BUTTON_MINUS 115 +#define KEYMON_BUTTON_PLUS 115 // KEY_VOLUMEUP +#define KEYMON_BUTTON_MINUS 114 // KEY_VOLUMEDOWN #define KEYMON_HAS_HDMI 1 #define KEYMON_HDMI_STATE_PATH "/sys/class/extcon/hdmi/cable.0/state" diff --git a/workspace/rgb30/show/Makefile b/workspace/rgb30/show/Makefile index ce34deef..03195e74 100755 --- a/workspace/rgb30/show/Makefile +++ b/workspace/rgb30/show/Makefile @@ -6,7 +6,7 @@ TARGET = show PRODUCT = $(TARGET).elf CC = $(CROSS_COMPILE)gcc -FLAGS = -Os -lSDL2 -lSDL2_image -lrt -ldl -Wl,--gc-sections -s +FLAGS = -Os $(CFLAGS) $(LDFLAGS) -lSDL2 -lSDL2_image -lrt -ldl -Wl,--gc-sections -s all: $(CC) $(TARGET).c -o $(PRODUCT) $(FLAGS) diff --git a/workspace/rgb30/show/show.c b/workspace/rgb30/show/show.c index 0f512752..debbecd8 100644 --- a/workspace/rgb30/show/show.c +++ b/workspace/rgb30/show/show.c @@ -9,36 +9,75 @@ SDL_Window* window; SDL_Surface* screen; -int main(int argc , char* argv[]) { - if (argc<2) { - puts("Usage: show.elf image.png delay"); - return 0; +int main(int argc, char* argv[]) { + if (argc < 2) { + fprintf(stderr, "Usage: show.elf image.png [delay]\n"); + return 1; } - + char path[256]; snprintf(path, sizeof(path), "%s", argv[1]); - if (access(path, F_OK)!=0) return 0; // nothing to show :( - - int delay = argc>2 ? atoi(argv[2]) : 2; - - SDL_Init(SDL_INIT_VIDEO); + if (access(path, F_OK) != 0) { + fprintf(stderr, "show.elf: Image not found: %s\n", path); + return 1; + } + + int delay = argc > 2 ? atoi(argv[2]) : 2; + + fprintf(stderr, "show.elf: Initializing SDL2...\n"); + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + fprintf(stderr, "show.elf: SDL_Init failed: %s\n", SDL_GetError()); + return 1; + } + SDL_ShowCursor(0); - - int w = 720; - int h = 720; - window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w,h, SDL_WINDOW_SHOWN); - - screen = SDL_GetWindowSurface(window); + + // Use 0,0 to let SDL auto-detect display size (like tg5040) + fprintf(stderr, "show.elf: Creating window...\n"); + window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 0, 0, SDL_WINDOW_SHOWN); + if (!window) { + fprintf(stderr, "show.elf: SDL_CreateWindow failed: %s\n", SDL_GetError()); + SDL_Quit(); + return 1; + } + + screen = SDL_GetWindowSurface(window); + if (!screen) { + fprintf(stderr, "show.elf: SDL_GetWindowSurface failed: %s\n", SDL_GetError()); + SDL_DestroyWindow(window); + SDL_Quit(); + return 1; + } + + fprintf(stderr, "show.elf: Window size: %dx%d\n", screen->w, screen->h); SDL_FillRect(screen, NULL, 0); - - SDL_Surface* img = IMG_Load(path); - SDL_BlitSurface(img, NULL, screen, &(SDL_Rect){(screen->w-img->w)/2,(screen->h-img->h)/2}); - - SDL_UpdateWindowSurface(window); + + fprintf(stderr, "show.elf: Loading image: %s\n", path); + SDL_Surface* img = IMG_Load(path); + if (!img) { + fprintf(stderr, "show.elf: IMG_Load failed: %s\n", IMG_GetError()); + SDL_DestroyWindow(window); + SDL_Quit(); + return 1; + } + + fprintf(stderr, "show.elf: Image size: %dx%d\n", img->w, img->h); + + // Center the image on screen + SDL_Rect dst = {(screen->w - img->w) / 2, (screen->h - img->h) / 2, img->w, img->h}; + SDL_BlitSurface(img, NULL, screen, &dst); + + if (SDL_UpdateWindowSurface(window) < 0) { + fprintf(stderr, "show.elf: SDL_UpdateWindowSurface failed: %s\n", SDL_GetError()); + } + + fprintf(stderr, "show.elf: Displaying for %d seconds...\n", delay); sleep(delay); - + SDL_FreeSurface(img); SDL_DestroyWindow(window); SDL_Quit(); + + fprintf(stderr, "show.elf: Done\n"); return 0; } diff --git a/workspace/rk3566/Makefile b/workspace/rk3566/Makefile deleted file mode 100644 index 9274d056..00000000 --- a/workspace/rk3566/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -########################################################### - -ifeq (,$(PLATFORM)) -PLATFORM = $(UNION_PLATFORM) -endif - -ifeq (,$(PLATFORM)) -$(error please specify PLATFORM, eg. PLATFORM=rk3566 make) -endif - -########################################################### - -# LessOS provides SDL2 natively - no sdl12-compat needed - -# keymon.elf is now built in workspace/all/utils -# LessOS doesn't need DinguxCommander (file manager for stock firmware) -all: readmes show - -.PHONY: show -show: - @$(MAKE) -C show - -# No early dependencies for rk3566 -early: - -clean: - -include ../all/readmes/Makefile \ No newline at end of file diff --git a/workspace/rk3566/README.md b/workspace/rk3566/README.md deleted file mode 100644 index fbadd354..00000000 --- a/workspace/rk3566/README.md +++ /dev/null @@ -1,330 +0,0 @@ -# Rockchip RK3566 Platform - -Platform implementation for Rockchip RK3566-based retro handheld devices (LessOS). - -## Supported Devices -- PowKiddy RGB30 -- Anbernic RG353P/M/V/VS (future) - -## Hardware Specifications - -### Display -- **Resolution**: 720x720 (square display, 1:1 aspect ratio) -- **Color Depth**: 16-bit RGB565 -- **UI Scale**: 2x (uses `assets@2x.png`) -- **HDMI Output**: 1280x720 (720p) with automatic switching - -### Input -- **D-Pad**: Up, Down, Left, Right -- **Face Buttons**: A, B, X, Y -- **Shoulder Buttons**: L1, R1, L2, R2 -- **Analog Sticks**: L3, R3 (clickable, used as menu modifiers) -- **System Buttons**: - - Two MENU buttons (primary and alternate via L3/R3) - - POWER button - - Dedicated PLUS/MINUS volume buttons - - SELECT and START buttons - -### Input Method -- **Primary**: Evdev input events (direct reading from `/dev/input/event*`) -- **Implementation**: Reads raw `input_event` structures for all input -- **Notable**: Bypasses SDL input APIs entirely - -### CPU & Performance -- ARM processor with NEON SIMD support -- No overclocking support - -### Power Management -- Power button detection via SDL keyboard (SDLK_POWER) -- Sleep/wake functionality - -### Audio/Video -- **Headphone Jack**: Automatic detection and audio routing -- **HDMI Output**: Automatic detection with video/audio switching -- **Volume Range**: 0-20 (raw: 0-100 via amixer) -- **Brightness Range**: 0-10 (raw: 0-255) - -### Storage -- SD card mounted at `/storage` (LessOS) - -## Platform Architecture - -RK3566 devices use a **hybrid input system** that combines: -- SDL2 joystick for gamepad buttons (D-Pad, face buttons, shoulders) -- Minimal SDL keyboard for power button -- Evdev codes for volume control and L3/R3 menu modifiers - -This approach allows hardware volume buttons to work independently while maintaining standard gamepad compatibility. - -## Directory Structure - -``` -RK3566/ -├── platform/ Platform-specific hardware definitions -│ └── platform.h Button mappings, display specs, HDMI support -├── keymon/ Hardware button monitoring daemon -│ └── keymon.c Volume/brightness + headphone/HDMI detection -├── libmsettings/ Settings library with audio/video routing -│ ├── msettings.c Shared memory settings management -│ └── msettings.h Settings API (volume, brightness, jack, HDMI) -├── show/ Boot splash screen utility -│ ├── show.c SDL2-based image display (supports HDMI) -│ └── makefile Build configuration -└── cores/ Libretro cores (submodules + builds) -``` - -## Input System - -RK3566 devices use a **joystick-first input architecture**: - -1. **SDL Joystick API**: Primary gamepad input (D-Pad, face buttons, shoulders, Start/Select) -2. **SDL Keyboard**: Power button only (SDLK_POWER) -3. **Evdev Codes**: Volume buttons (114/115) and L3/R3 menu modifiers (317/318) - -### Joystick Button Mappings - -| Physical Button | Joystick Index | -|----------------|----------------| -| D-Pad Up/Down/Left/Right | 13/14/15/16 | -| A, B, X, Y | 1, 0, 2, 3 | -| L1, R1 | 4, 5 | -| L2, R2 | 6, 7 | -| SELECT, START | 8, 9 | -| MENU (primary) | 11 | -| MENU ALT (secondary) | 12 | - -### Input Event Devices - -The keymon daemon monitors multiple input devices: -- **event0-4**: Gamepad and button input -- **js0**: Joystick device - -### Button Combinations - -| Combination | Function | -|-------------|----------| -| PLUS | Increase volume | -| MINUS | Decrease volume | -| L3/R3 + PLUS | Increase brightness | -| L3/R3 + MINUS | Decrease brightness | -| POWER | Sleep/wake device | -| X (in launcher) | Resume from save state | - -### Hardware Monitoring - -The keymon daemon runs a background thread to monitor: -- **Headphone jack state**: `/sys/bus/platform/devices/singleadc-joypad/hp` -- **HDMI connection state**: `/sys/class/extcon/hdmi/cable.0/state` - -Audio and video routing automatically switches when headphones or HDMI are connected/disconnected. - -## Building - -### Prerequisites -Requires Docker with RK3566 cross-compilation toolchain. - -### Build Commands - -```bash -# Enter platform build environment -make PLATFORM=rk3566 shell - -# Inside container: build all platform components -cd /root/workspace/rk3566 -make - -# This builds: -# - show.elf (boot splash display) -``` - -## Installation - -### File System Layout - -LessUI installs to the SD card with the following structure: - -``` -/storage/ -├── lessos/ LessOS bootstrap -│ └── init.sh Entry point -├── .system/ -│ ├── RK3566/ Platform-specific binaries -│ │ ├── bin/ Utilities (keymon, show, etc.) -│ │ └── paks/ Applications and emulators -│ │ └── LessUI.pak/ Main launcher -│ └── res/ Shared UI assets -│ ├── assets@2x.png UI sprite sheet (2x scale) -│ └── InterTight-Bold.ttf -├── .userdata/ User settings and save data -│ └── RK3566/ Platform-specific settings -│ └── msettings.bin Volume/brightness preferences -├── Roms/ ROM files organized by system -└── LessUI.7z Update package (if present) -``` - -### Settings Management - -RK3566 devices use shared memory for settings synchronization between processes: - -**Settings Stored**: -- Brightness level (0-10) -- Speaker volume (0-20) -- Headphone volume (0-20, separate from speaker) -- Jack state (headphones connected/disconnected) -- HDMI state (HDMI connected/disconnected) - -**Persistence**: Settings are saved to `$USERDATA_PATH/msettings.bin` and persist across reboots. - -## Platform-Specific Features - -### Square Display - -The 720x720 square display (1:1 aspect ratio) requires UI adjustments: - -| Parameter | Value | Notes | -|-----------|-------|-------| -| `MAIN_ROW_COUNT` | 8 rows | More rows visible than standard 640x480 | -| `PADDING` | 40px | Larger padding for square layout | - -These settings maximize content visibility while maintaining comfortable spacing. - -### HDMI Output Support - -The platform includes full HDMI support: - -**Output Resolution**: 1280x720 (720p) - -**Automatic Behavior**: -- Video output switches to HDMI when connected -- Audio routing changes to HDMI audio -- Volume locked at 100% on HDMI (brightness control disabled) -- Automatically reverts to internal display/speaker when disconnected - -**Implementation**: Background thread in keymon polls HDMI state every second. - -### Audio Routing - -Smart audio routing based on connected devices: - -1. **Internal Speaker**: Default audio output -2. **Headphones**: Auto-detected, switches to headphone output, uses separate volume level -3. **HDMI**: Auto-detected, switches to HDMI audio, locks volume at 100% - -**amixer Commands**: -- Playback path: `amixer cset name='Playback Path' 'SPK'|'HP'` -- Volume: `amixer sset -M 'Master' N%` - -### Brightness Control - -Hardware brightness via sysfs: -- **Path**: `/sys/class/backlight/backlight/brightness` -- **Range**: 0-255 (raw), mapped from 0-10 user scale -- **Disabled on HDMI**: Brightness adjustments ignored when HDMI connected - -**Brightness Curve** (non-linear for better low-end visibility): -``` -Level 0: 4 Level 1: 6 Level 2: 10 Level 3: 16 -Level 4: 32 Level 5: 48 Level 6: 64 Level 7: 96 -Level 8: 128 Level 9: 192 Level 10: 255 -``` - -### Volume Button Quirks - -The platform has hardware volume buttons with evdev codes: -- **CODE_PLUS**: 129 (Volume up) - **swapped from kernel default** -- **CODE_MINUS**: 128 (Volume down) - **swapped from kernel default** - -These codes are swapped in platform.h to correct the hardware mapping. - -### Repeat Functionality - -Volume and brightness buttons support repeat: -- **Initial delay**: 300ms before repeat starts -- **Repeat interval**: 100ms between repeats -- **Ignores stale input**: After system sleep (>1 second gap), input ignored to prevent spurious events - -## Supported Emulator Cores - -The RK3566 platform includes these libretro cores: - -| Core | Systems | Notes | -|------|---------|-------| -| **fceumm** | NES, Famicom | Nintendo Entertainment System | -| **gambatte** | Game Boy, Game Boy Color | Accuracy-focused | -| **gpsp** | Game Boy Advance | Fast, requires BIOS | -| **pcsx_rearmed** | PlayStation | Optimized ARM port | -| **picodrive** | Genesis, Mega Drive, 32X, Sega CD | Multi-system | -| **snes9x2005_plus** | SNES | Lightweight, Blargg APU | -| **pokemini** | Pokemon Mini | Niche handheld | -| **fake-08** | PICO-8 | Fantasy console | -| **mednafen_pce_fast** | PC Engine, TurboGrafx-16 | Fast variant | -| **mednafen_vb** | Virtual Boy | Nintendo VR handheld | -| **mednafen_supafaust** | SNES | High accuracy | -| **mgba** | Game Boy Advance | High accuracy | -| **race** | Neo Geo Pocket, Neo Geo Pocket Color | SNK handheld | - -## Known Issues / Quirks - -### Hardware Quirks -1. **Joystick-first input**: Unlike keyboard-based platforms, uses SDL joystick API primarily -2. **Dual menu buttons**: L3/R3 analog stick clicks act as menu modifiers (codes 317/318) -3. **Volume code swap**: Hardware volume button codes swapped in software to correct mapping -4. **HDMI volume lock**: Volume/brightness controls disabled when HDMI connected -5. **Audio crackling**: Light crackling reported in some cores (fceumm, snes9x2005_plus) - likely SDL2 audio pipeline issue - -### Development Notes -1. **SDL2**: Platform uses SDL2 natively (LessOS provides SDL2) -2. **Shared memory settings**: libmsettings uses `/SharedSettings` SHM for IPC -3. **Settings host**: keymon is always the settings "host" (first to create SHM) -4. **HDMI polling**: Background thread polls HDMI state at 1Hz (every second) -5. **60Hz input polling**: Main keymon loop runs at 60Hz (16.6ms sleep) - -### Input Limitations -- **No L3/R3 for games**: L3/R3 reserved for system menu modifier, not available to cores -- **Evdev overhead**: Volume buttons require evdev monitoring (can't use SDL alone) - -### Audio Buffer Size -Default audio buffer: `SAMPLES 400` (balanced latency vs stability) - -## Testing - -When testing changes: -1. Verify joystick input works correctly (D-Pad, face buttons, shoulders) -2. Test HDMI detection and automatic video/audio switching -3. Check headphone jack detection and audio routing -4. Verify volume control with PLUS/MINUS buttons -5. Test brightness control with L3/R3 + PLUS/MINUS -6. Confirm settings persist across reboots (msettings.bin) -7. Test on both internal display and HDMI output -8. Verify square display UI layout (720x720) - -## Related Documentation - -- Main project docs: `../../README.md` -- Platform abstraction: `../../all/common/defines.h` -- Shared code: `../../all/launcher/launcher.c` (launcher), `../../all/player/player.c` (libretro frontend) -- Build system: `../../Makefile` (host), `./makefile` (platform) -- Platform header: `./platform/platform.h` (all hardware definitions) - -## Maintainer Notes - -This platform demonstrates several advanced LessUI features: - -**Unique Characteristics**: -- Square display (720x720) - unique aspect ratio among LessUI platforms -- HDMI output support with automatic switching -- Dual menu modifier buttons (L3/R3) -- Hybrid input system (joystick + keyboard + evdev) -- Background hardware monitoring threads -- Shared memory settings management -- Separate volume levels for speaker vs headphones - -**Reference Implementation For**: -- HDMI output detection and switching -- Headphone jack detection -- Multi-device audio routing -- Non-standard display aspect ratios -- SDL2-based platforms -- Joystick-first input handling - -Changes to this platform should be tested with HDMI output and headphone jack to ensure automatic switching continues to work correctly. diff --git a/workspace/rk3566/libmsettings/Makefile b/workspace/rk3566/libmsettings/Makefile deleted file mode 100644 index bc879d7b..00000000 --- a/workspace/rk3566/libmsettings/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif -ifeq (,$(PREFIX)) -$(error missing PREFIX for this toolchain) -endif - -TARGET = msettings - -.PHONY: build -.PHONY: clean - -CC = $(CROSS_COMPILE)gcc - -SYSROOT := $(shell $(CC) --print-sysroot) - -INCLUDEDIR = $(SYSROOT)/usr/include -# OPT_FLAGS from parent makefile (-O3 for release, -O0 -g for debug) -OPT_FLAGS ?= -O3 -CFLAGS = -I$(INCLUDEDIR) $(OPT_FLAGS) -LDFLAGS = -ldl -lrt -s - -build: - @$(CC) -c -Werror -fpic "$(TARGET).c" -Wl,--no-as-needed $(CFLAGS) - @$(CC) -shared -o "lib$(TARGET).so" "$(TARGET).o" $(LDFLAGS) - @cp "$(TARGET).h" "$(PREFIX)/include" - @cp "lib$(TARGET).so" "$(PREFIX)/lib" -clean: - rm -f *.o - rm -f "lib$(TARGET).so" - rm -f $(PREFIX)/include/$(TARGET).h - rm -f $(PREFIX)/lib/lib$(TARGET).so \ No newline at end of file diff --git a/workspace/rk3566/libmsettings/msettings.c b/workspace/rk3566/libmsettings/msettings.c deleted file mode 100644 index ab87f4b1..00000000 --- a/workspace/rk3566/libmsettings/msettings.c +++ /dev/null @@ -1,203 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "msettings.h" - -/////////////////////////////////////// - -#define SETTINGS_VERSION 2 -typedef struct Settings { - int version; // future proofing - int brightness; - int headphones; - int speaker; - int unused[2]; // for future use - // NOTE: doesn't really need to be persisted but still needs to be shared - int jack; - int hdmi; -} Settings; -static Settings DefaultSettings = { - .version = SETTINGS_VERSION, - .brightness = 2, - .headphones = 4, - .speaker = 8, - .jack = 0, - .hdmi = 0, -}; -static Settings* settings; - -#define SHM_KEY "/SharedSettings" -static char SettingsPath[256]; -static int shm_fd = -1; -static int is_host = 0; -static int shm_size = sizeof(Settings); - -#define BACKLIGHT_PATH "/sys/class/backlight/backlight/bl_power" -#define BRIGHTNESS_PATH "/sys/class/backlight/backlight/brightness" -#define JACK_STATE_PATH "/sys/bus/platform/devices/singleadc-joypad/hp" -#define HDMI_STATE_PATH "/sys/class/extcon/hdmi/cable.0/state" - -int getInt(char* path) { - int i = 0; - FILE *file = fopen(path, "r"); - if (file!=NULL) { - fscanf(file, "%i", &i); - fclose(file); - } - return i; -} - - -void InitSettings(void) { - sprintf(SettingsPath, "%s/msettings.bin", getenv("USERDATA_PATH")); - - shm_fd = shm_open(SHM_KEY, O_RDWR | O_CREAT | O_EXCL, 0644); // see if it exists - if (shm_fd==-1 && errno==EEXIST) { // already exists - puts("Settings client"); - shm_fd = shm_open(SHM_KEY, O_RDWR, 0644); - settings = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); - } - else { // host - puts("Settings host"); // should always be keymon - is_host = 1; - // we created it so set initial size and populate - ftruncate(shm_fd, shm_size); - settings = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); - - int fd = open(SettingsPath, O_RDONLY); - if (fd>=0) { - read(fd, settings, shm_size); - // TODO: use settings->version for future proofing? - close(fd); - } - else { - // load defaults - memcpy(settings, &DefaultSettings, shm_size); - } - - // these shouldn't be persisted - // settings->jack = 0; - // settings->hdmi = 0; - } - - int jack = getInt(JACK_STATE_PATH); - int hdmi = getInt(HDMI_STATE_PATH); - printf("brightness: %i (hdmi: %i)\nspeaker: %i (jack: %i)\n", settings->brightness, hdmi, settings->speaker, jack); fflush(stdout); - - // both of these set volume - SetJack(jack); - SetHDMI(hdmi); - - SetBrightness(GetBrightness()); - // system("echo $(< " BRIGHTNESS_PATH ")"); -} -void QuitSettings(void) { - munmap(settings, shm_size); - if (is_host) shm_unlink(SHM_KEY); -} -static inline void SaveSettings(void) { - int fd = open(SettingsPath, O_CREAT|O_WRONLY, 0644); - if (fd>=0) { - write(fd, settings, shm_size); - close(fd); - sync(); - } -} - -int GetBrightness(void) { // 0-10 - return settings->brightness; -} -void SetBrightness(int value) { - if (settings->hdmi) return; - - int raw; - switch (value) { - // TODO: redo, range is 0-255 - case 0: raw=4; break; // 0 - case 1: raw=6; break; // 2 - case 2: raw=10; break; // 4 - case 3: raw=16; break; // 6 - case 4: raw=32; break; // 16 - case 5: raw=48; break; // 16 - case 6: raw=64; break; // 16 - case 7: raw=96; break; // 32 - case 8: raw=128; break; // 32 - case 9: raw=192; break; // 64 - case 10: raw=255; break; // 64 - } - SetRawBrightness(raw); - settings->brightness = value; - SaveSettings(); -} - -int GetVolume(void) { // 0-20 - return settings->jack ? settings->headphones : settings->speaker; -} -void SetVolume(int value) { - if (settings->hdmi) return; - - if (settings->jack) settings->headphones = value; - else settings->speaker = value; - - int raw = value * 5; - SetRawVolume(raw); - SaveSettings(); -} - -void SetRawBrightness(int val) { // 0 - 255 - if (settings->hdmi) return; - - // printf("SetRawBrightness(%i)\n", val); fflush(stdout); - int fd = open(BRIGHTNESS_PATH, O_WRONLY); - if (fd>=0) { - dprintf(fd,"%d",val); - close(fd); - } -} -void SetRawVolume(int val) { // 0 - 100 - // printf("SetRawVolume(%i)\n", val); fflush(stdout); - char cmd[256]; - sprintf(cmd, "amixer sset -M 'Master' %i%% &> /dev/null", val); - // puts(cmd); fflush(stdout); - system(cmd); -} - -// monitored and set by thread in keymon -int GetJack(void) { - return settings->jack; -} -void SetJack(int value) { - // printf("SetJack(%i)\n", value); fflush(stdout); - - char cmd[256]; - sprintf(cmd, "amixer cset name='Playback Path' '%s' &> /dev/null", value?"HP":"SPK"); - system(cmd); - - settings->jack = value; - SetVolume(GetVolume()); -} - -int GetHDMI(void) { - // printf("GetHDMI() %i\n", settings->hdmi); fflush(stdout); - return settings->hdmi; -} -void SetHDMI(int value) { - // printf("SetHDMI(%i)\n", value); fflush(stdout); - - // if (settings->hdmi!=value) system("/usr/lib/autostart/common/055-hdmi-check"); - - settings->hdmi = value; - if (value) SetRawVolume(100); // max - else SetVolume(GetVolume()); // restore -} - -int GetMute(void) { return 0; } -void SetMute(int value) { } \ No newline at end of file diff --git a/workspace/rk3566/libmsettings/msettings.h b/workspace/rk3566/libmsettings/msettings.h deleted file mode 100644 index 47e5fb00..00000000 --- a/workspace/rk3566/libmsettings/msettings.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef __msettings_h__ -#define __msettings_h__ - -void InitSettings(void); -void QuitSettings(void); - -int GetBrightness(void); -int GetVolume(void); - -void SetRawBrightness(int value); // 0-1024 -void SetRawVolume(int value); // 0-40 - -void SetBrightness(int value); // 0-10 -void SetVolume(int value); // 0-20 - -int GetJack(void); -void SetJack(int value); // 0-1 - -int GetHDMI(void); -void SetHDMI(int value); // 0-1 - -int GetMute(void); -void SetMute(int value); // 0-1 - -#endif // __msettings_h__ diff --git a/workspace/rk3566/other/.keep b/workspace/rk3566/other/.keep deleted file mode 100644 index e69de29b..00000000 diff --git a/workspace/rk3566/platform/Makefile.copy b/workspace/rk3566/platform/Makefile.copy deleted file mode 100644 index 76da13e3..00000000 --- a/workspace/rk3566/platform/Makefile.copy +++ /dev/null @@ -1,13 +0,0 @@ -$(PLATFORM): - # $@ - cp ./workspace/$@/keymon/keymon.elf ./build/SYSTEM/$@/bin/ - # show.elf (platform-specific build) - cp ./workspace/$@/show/show.elf ./build/SYSTEM/$@/bin/ - # LessOS provides SDL2 natively - no sdl12-compat needed - # installer - rsync -a ./workspace/$@/install/boot.sh ./build/BOOT/common/$@.sh - mkdir -p ./build/BOOT/common/$@/ - cp ./workspace/$@/show/show.elf ./build/BOOT/common/$@/ - # boot assets - rsync -a ./skeleton/SYSTEM/res/installing@3x.png ./build/BOOT/common/$@/installing.png - rsync -a ./skeleton/SYSTEM/res/updating@3x.png ./build/BOOT/common/$@/updating.png \ No newline at end of file diff --git a/workspace/rk3566/platform/Makefile.env b/workspace/rk3566/platform/Makefile.env deleted file mode 100644 index 32bd0932..00000000 --- a/workspace/rk3566/platform/Makefile.env +++ /dev/null @@ -1,4 +0,0 @@ -# rk3566 - LessOS toolchain -ARCH = -mtune=cortex-a55 -march=armv8.2-a -O3 -LIBS = -flto -lrga -ldrm -lstdc++ -lasound -lfreetype -ljpeg -lpng16 -lbz2 -SDL = SDL2 \ No newline at end of file diff --git a/workspace/rk3566/platform/platform.c b/workspace/rk3566/platform/platform.c deleted file mode 100644 index 435b454f..00000000 --- a/workspace/rk3566/platform/platform.c +++ /dev/null @@ -1,406 +0,0 @@ -/** - * platform.c - Rockchip RK3566 platform implementation - * - * REFACTORED VERSION - Uses shared render_sdl2 backend - * - * Platform-specific code for Rockchip RK3566-based handheld devices. - * Supported devices: PowKiddy RGB30, Anbernic RG353P/M/V/VS - * - * Key features: - * - Dual analog sticks with swapped right stick axes (X/Y reversed) - * - WiFi support with status monitoring - * - Grid and line visual effects for retro aesthetics - * - Rotation support for display output - * - Dynamic device model detection from device tree - * - Overscan support (PLAT_supportsOverscan returns 1) - * - * RK3566 devices use 720x720 displays and read input events directly - * from /dev/input/event* devices. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include "api.h" -#include "defines.h" -#include "platform.h" -#include "utils.h" - -#include "gl_video.h" -#include "render_sdl2.h" -#include "scaler.h" - -/////////////////////////////// -// Video - Using shared SDL2 backend -/////////////////////////////// - -static SDL2_RenderContext vid_ctx; - -static const SDL2_Config vid_config = { - // No rotation needed (square 720x720 display) - .auto_rotate = 0, - .rotate_cw = 0, - .rotate_null_center = 0, - // Display features - .has_hdmi = 1, - .default_sharpness = SHARPNESS_SOFT, -}; - -SDL_Surface* PLAT_initVideo(void) { - return SDL2_initVideo(&vid_ctx, FIXED_WIDTH, FIXED_HEIGHT, &vid_config); -} - -void PLAT_quitVideo(void) { - SDL2_quitVideo(&vid_ctx); -} - -void PLAT_clearVideo(SDL_Surface* screen) { - SDL2_clearVideo(&vid_ctx); -} - -void PLAT_clearAll(void) { - SDL2_clearAll(&vid_ctx); -} - -SDL_Surface* PLAT_resizeVideo(int w, int h, int p) { - return SDL2_resizeVideo(&vid_ctx, w, h, p); -} - -void PLAT_setVideoScaleClip(int x, int y, int width, int height) {} -void PLAT_setNearestNeighbor(int enabled) {} - -void PLAT_setSharpness(int sharpness) { - SDL2_setSharpness(&vid_ctx, sharpness); -} - -void PLAT_setEffect(int effect) { - // Only GL path is used on GLES platforms (SDL2 effect state is unused) - GLVideo_setEffect(effect); -} - -void PLAT_setEffectColor(int color) { - // Only GL path is used on GLES platforms (SDL2 effect state is unused) - GLVideo_setEffectColor(color); -} - -void PLAT_vsync(int remaining) { - SDL2_vsync(remaining); -} - -scaler_t PLAT_getScaler(GFX_Renderer* renderer) { - return SDL2_getScaler(&vid_ctx, renderer); -} - -void PLAT_present(GFX_Renderer* renderer) { - SDL2_present(&vid_ctx, renderer); -} - -SDL_Window* PLAT_getWindow(void) { - return SDL2_getWindow(&vid_ctx); -} - -int PLAT_getRotation(void) { - return SDL2_getRotation(&vid_ctx); -} - -int PLAT_supportsOverscan(void) { - return 1; -} - -/////////////////////////////// -// Input Handling -/////////////////////////////// - -#define RAW_UP 544 -#define RAW_DOWN 545 -#define RAW_LEFT 546 -#define RAW_RIGHT 547 -#define RAW_A 305 -#define RAW_B 304 -#define RAW_X 307 -#define RAW_Y 308 -#define RAW_START 315 -#define RAW_SELECT 314 -#define RAW_MENU 139 -#define RAW_L1 310 -#define RAW_L2 312 -#define RAW_L3 317 -#define RAW_R1 311 -#define RAW_R2 313 -#define RAW_R3 318 -#define RAW_PLUS 115 -#define RAW_MINUS 114 -#define RAW_POWER 116 -#define RAW_HATY 17 -#define RAW_HATX 16 -#define RAW_LSY 1 -#define RAW_LSX 0 -#define RAW_RSY 3 -#define RAW_RSX 4 - -#define RAW_MENU1 RAW_L3 -#define RAW_MENU2 RAW_R3 - -#define INPUT_COUNT 4 -static int inputs[INPUT_COUNT]; - -void PLAT_initInput(void) { - inputs[0] = open("/dev/input/event0", O_RDONLY | O_NONBLOCK | O_CLOEXEC); - inputs[1] = open("/dev/input/event1", O_RDONLY | O_NONBLOCK | O_CLOEXEC); - inputs[2] = open("/dev/input/event2", O_RDONLY | O_NONBLOCK | O_CLOEXEC); - inputs[3] = open("/dev/input/event3", O_RDONLY | O_NONBLOCK | O_CLOEXEC); - - for (int i = 0; i < INPUT_COUNT; i++) { - if (inputs[i] < 0) - LOG_warn("Failed to open /dev/input/event%d\n", i); - } -} - -void PLAT_quitInput(void) { - for (int i = 0; i < INPUT_COUNT; i++) { - close(inputs[i]); - } -} - -struct input_event { - struct timeval time; - __u16 type; - __u16 code; - __s32 value; -}; -#define EV_KEY 0x01 -#define EV_ABS 0x03 - -void PLAT_pollInput(void) { - uint32_t tick = SDL_GetTicks(); - PAD_beginPolling(); - PAD_handleRepeat(tick); - - int input; - static struct input_event event; - for (int i = 0; i < INPUT_COUNT; i++) { - input = inputs[i]; - while (read(input, &event, sizeof(event)) == sizeof(event)) { - if (event.type != EV_KEY && event.type != EV_ABS) - continue; - - int btn = BTN_NONE; - int pressed = 0; - int type = event.type; - int code = event.code; - int value = event.value; - - if (type == EV_KEY) { - if (value > 1) - continue; - pressed = value; - if (code == RAW_UP) { - btn = BTN_DPAD_UP; - } else if (code == RAW_DOWN) { - btn = BTN_DPAD_DOWN; - } else if (code == RAW_LEFT) { - btn = BTN_DPAD_LEFT; - } else if (code == RAW_RIGHT) { - btn = BTN_DPAD_RIGHT; - } else if (code == RAW_A) { - btn = BTN_A; - } else if (code == RAW_B) { - btn = BTN_B; - } else if (code == RAW_X) { - btn = BTN_X; - } else if (code == RAW_Y) { - btn = BTN_Y; - } else if (code == RAW_START) { - btn = BTN_START; - } else if (code == RAW_SELECT) { - btn = BTN_SELECT; - } else if (code == RAW_MENU) { - btn = BTN_MENU; - } else if (code == RAW_MENU1) { - btn = BTN_MENU; - } else if (code == RAW_MENU2) { - btn = BTN_MENU; - } else if (code == RAW_L1) { - btn = BTN_L1; - } else if (code == RAW_L2) { - btn = BTN_L2; - } else if (code == RAW_L3) { - btn = BTN_L3; - } else if (code == RAW_R1) { - btn = BTN_R1; - } else if (code == RAW_R2) { - btn = BTN_R2; - } else if (code == RAW_R3) { - btn = BTN_R3; - } else if (code == RAW_PLUS) { - btn = BTN_PLUS; - } else if (code == RAW_MINUS) { - btn = BTN_MINUS; - } else if (code == RAW_POWER) { - btn = BTN_POWER; - } - } else if (type == EV_ABS) { - if (code == RAW_LSX) { - pad.laxis.x = (value * 32767) / 1800; - PAD_setAnalog(BTN_ID_ANALOG_LEFT, BTN_ID_ANALOG_RIGHT, pad.laxis.x, - tick + PAD_REPEAT_DELAY); - } else if (code == RAW_LSY) { - pad.laxis.y = (value * 32767) / 1800; - PAD_setAnalog(BTN_ID_ANALOG_UP, BTN_ID_ANALOG_DOWN, pad.laxis.y, - tick + PAD_REPEAT_DELAY); - // Right stick axes are swapped in hardware - } else if (code == RAW_RSX) { - pad.raxis.y = (value * 32767) / 1800; - } else if (code == RAW_RSY) { - pad.raxis.x = (value * 32767) / 1800; - } - btn = BTN_NONE; - } - - PAD_updateButton(btn, pressed, tick); - } - } -} - -int PLAT_shouldWake(void) { - int input; - static struct input_event event; - for (int i = 0; i < INPUT_COUNT; i++) { - input = inputs[i]; - while (read(input, &event, sizeof(event)) == sizeof(event)) { - if (event.type == EV_KEY && event.code == RAW_POWER && event.value == 0) - return 1; - } - } - return 0; -} - -/////////////////////////////// -// Power Management -/////////////////////////////// - -static int online = 0; - -void PLAT_getBatteryStatus(int* is_charging, int* charge) { - *is_charging = getInt("/sys/class/power_supply/ac/online"); - - int i = getInt("/sys/class/power_supply/battery/capacity"); - if (i > 80) - *charge = 100; - else if (i > 60) - *charge = 80; - else if (i > 40) - *charge = 60; - else if (i > 20) - *charge = 40; - else if (i > 10) - *charge = 20; - else - *charge = 10; - - char status[16]; - getFile("/sys/class/net/wlan0/operstate", status, 16); - online = prefixMatch("up", status); -} - -void PLAT_enableBacklight(int enable) { - putInt("/sys/class/backlight/backlight/bl_power", - enable ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN); -} - -void PLAT_powerOff(void) { - sleep(2); - SetRawVolume(MUTE_VOLUME_RAW); - PLAT_enableBacklight(0); - SND_quit(); - VIB_quit(); - PWR_quit(); - GFX_quit(); - system("shutdown"); - while (1) - pause(); -} - -double PLAT_getDisplayHz(void) { - return SDL2_getDisplayHz(); -} - -uint32_t PLAT_measureVsyncInterval(void) { - return SDL2_measureVsyncInterval(&vid_ctx); -} - -#define GOVERNOR_PATH "/sys/devices/system/cpu/cpufreq/policy0/scaling_setspeed" - -void PLAT_setCPUSpeed(int speed) { - int freq = 0; - switch (speed) { - case CPU_SPEED_IDLE: - freq = 408000; // 20% of max (408 MHz) - break; - case CPU_SPEED_POWERSAVE: - freq = 1104000; // 55% of max (1104 MHz) - break; - case CPU_SPEED_NORMAL: - freq = 1608000; // 80% of max (1608 MHz) - break; - case CPU_SPEED_PERFORMANCE: - freq = 1992000; // 100% (1992 MHz) - break; - } - putInt(GOVERNOR_PATH, freq); -} - -/** - * Gets available CPU frequencies from sysfs. - * - * @param frequencies Output array to fill with frequencies (in kHz) - * @param max_count Maximum number of frequencies to return - * @return Number of frequencies found - */ -int PLAT_getAvailableCPUFrequencies(int* frequencies, int max_count) { - return PWR_getAvailableCPUFrequencies_sysfs(frequencies, max_count); -} - -/** - * Sets CPU frequency directly via sysfs. - * - * @param freq_khz Target frequency in kHz - * @return 0 on success, -1 on failure - */ -int PLAT_setCPUFrequency(int freq_khz) { - return PWR_setCPUFrequency_sysfs(freq_khz); -} - -void PLAT_setRumble(int strength) {} - -int PLAT_pickSampleRate(int requested, int max) { - return MIN(requested, max); -} - -static char model[256]; -char* PLAT_getModel(void) { - char buffer[256]; - getFile("/proc/device-tree/model", buffer, 256); - char* tmp = strrchr(buffer, ' '); - if (tmp) { - strncpy(model, tmp + 1, sizeof(model) - 1); - model[sizeof(model) - 1] = '\0'; - } else { - strncpy(model, "RGB30", sizeof(model) - 1); - model[sizeof(model) - 1] = '\0'; - } - return model; -} - -int PLAT_isOnline(void) { - return online; -} diff --git a/workspace/rk3566/platform/platform.h b/workspace/rk3566/platform/platform.h deleted file mode 100644 index 443c1403..00000000 --- a/workspace/rk3566/platform/platform.h +++ /dev/null @@ -1,222 +0,0 @@ -/** - * RK3566/platform/platform.h - Platform definitions for Rockchip RK3566 devices - * - * Supported devices (Rockchip RK3566, Cortex-A55): - * - PowKiddy RGB30: 4.0" 720x720 display - * - Anbernic RG353P/M/V/VS: Various display configurations - * - * Hardware features: - * - 720x720 square display (1:1 aspect ratio) - * - 1280x720 HDMI output support - * - D-pad and face buttons (A/B/X/Y) - * - Shoulder buttons (L1/R1/L2/R2) - * - Menu buttons (primary and alternate) - * - Uses hybrid input (minimal SDL keyboard + joystick) - * - Larger UI with increased row count and padding - * - * @note Power button uses SDL keyboard mapping, volume controls use evdev codes - */ - -#ifndef PLATFORM_H -#define PLATFORM_H - -/////////////////////////////// -// Platform Identification -/////////////////////////////// - -#define PLATFORM "rk3566" - -/////////////////////////////// -// Hardware Capabilities -/////////////////////////////// - -#define HAS_OPENGLES 1 // Mali-G52 GPU supports OpenGL ES 2.0 - -/////////////////////////////// -// Audio Configuration -/////////////////////////////// - -// Uses default SND_RATE_CONTROL_D (0.012f) for standard timing - -/////////////////////////////// -// Video Buffer Scaling -/////////////////////////////// - -// Uses default BUFFER_SCALE_FACTOR (1.0f) - GPU hardware scaler handles all scaling - -/////////////////////////////// -// UI Scaling -/////////////////////////////// - -// Uses default SCALE_MODIFIER (1.0f) and EDGE_PADDING (10) for standard layout - -/////////////////////////////// -// Dependencies -/////////////////////////////// - -#include "sdl.h" - -/////////////////////////////// -// Platform Variant Detection -/////////////////////////////// - -// No device variants (single hardware configuration) - -/////////////////////////////// -// SDL Keyboard Button Mappings -// RK3566 devices use minimal SDL keyboard input (power button only) -/////////////////////////////// - -#define BUTTON_UP BUTTON_NA -#define BUTTON_DOWN BUTTON_NA -#define BUTTON_LEFT BUTTON_NA -#define BUTTON_RIGHT BUTTON_NA - -#define BUTTON_SELECT BUTTON_NA -#define BUTTON_START BUTTON_NA - -#define BUTTON_A BUTTON_NA -#define BUTTON_B BUTTON_NA -#define BUTTON_X BUTTON_NA -#define BUTTON_Y BUTTON_NA - -#define BUTTON_L1 BUTTON_NA -#define BUTTON_R1 BUTTON_NA -#define BUTTON_L2 BUTTON_NA -#define BUTTON_R2 BUTTON_NA -#define BUTTON_L3 BUTTON_NA -#define BUTTON_R3 BUTTON_NA - -#define BUTTON_MENU BUTTON_NA -#define BUTTON_MENU_ALT BUTTON_NA -#define BUTTON_POWER SDLK_POWER // Power key mapped to SDL -#define BUTTON_PLUS BUTTON_NA // Available but not used (commented: SDLK_RSUPER) -#define BUTTON_MINUS BUTTON_NA // Available but not used (commented: SDLK_LSUPER) - -/////////////////////////////// -// Evdev/Keyboard Input Codes -// Hardware keycodes from kernel input subsystem -/////////////////////////////// - -#define CODE_UP CODE_NA -#define CODE_DOWN CODE_NA -#define CODE_LEFT CODE_NA -#define CODE_RIGHT CODE_NA - -#define CODE_SELECT CODE_NA -#define CODE_START CODE_NA - -#define CODE_A CODE_NA -#define CODE_B CODE_NA -#define CODE_X CODE_NA -#define CODE_Y CODE_NA - -#define CODE_L1 CODE_NA -#define CODE_R1 CODE_NA -#define CODE_L2 CODE_NA -#define CODE_R2 CODE_NA -#define CODE_L3 CODE_NA -#define CODE_R3 CODE_NA - -#define CODE_MENU CODE_NA -#define CODE_MENU_ALT CODE_NA -#define CODE_POWER 102 // KEY_HOME - -#define CODE_PLUS 129 // Volume up (swapped from keymon) -#define CODE_MINUS 128 // Volume down (swapped from keymon) - -/////////////////////////////// -// Joystick Button Mappings -// Hardware joystick indices -/////////////////////////////// - -#define JOY_UP 13 -#define JOY_DOWN 14 -#define JOY_LEFT 15 -#define JOY_RIGHT 16 - -#define JOY_SELECT 8 -#define JOY_START 9 - -#define JOY_A 1 -#define JOY_B 0 -#define JOY_X 2 -#define JOY_Y 3 - -#define JOY_L1 4 -#define JOY_R1 5 -#define JOY_L2 6 -#define JOY_R2 7 -#define JOY_L3 JOY_NA -#define JOY_R3 JOY_NA - -#define JOY_MENU 11 -#define JOY_MENU_ALT 12 // Secondary menu button -#define JOY_POWER JOY_NA -#define JOY_PLUS JOY_NA -#define JOY_MINUS JOY_NA - -/////////////////////////////// -// Function Button Mappings -// System-level button combinations -/////////////////////////////// - -#define BTN_RESUME BTN_X // Button to resume from save state -#define BTN_SLEEP BTN_POWER // Button to enter sleep mode -#define BTN_WAKE BTN_POWER // Button to wake from sleep -#define BTN_MOD_VOLUME BTN_NONE // Modifier for volume control (none - direct buttons) -#define BTN_MOD_BRIGHTNESS BTN_MENU // Hold MENU for brightness control -#define BTN_MOD_PLUS BTN_PLUS // Increase with PLUS -#define BTN_MOD_MINUS BTN_MINUS // Decrease with MINUS - -/////////////////////////////// -// Display Specifications -/////////////////////////////// - -#define SCREEN_DIAGONAL 4.0f // Physical screen diagonal in inches -#define FIXED_WIDTH 720 // Screen width in pixels (square display) -#define FIXED_HEIGHT 720 // Screen height in pixels (1:1 aspect ratio) - -/////////////////////////////// -// HDMI Output Specifications -/////////////////////////////// - -#define HAS_HDMI 1 // HDMI output supported -#define HDMI_WIDTH 1280 // HDMI width in pixels -#define HDMI_HEIGHT 720 // HDMI height in pixels (720p) - -/////////////////////////////// -// Platform-Specific Paths and Settings -/////////////////////////////// - -#define SDCARD_PATH \ - "/storage" // Path to SD card mount point (LessOS default, overridden by LESSOS_STORAGE) -#define MUTE_VOLUME_RAW 0 // Raw value for muted volume - -/////////////////////////////// -// Keymon Configuration -/////////////////////////////// - -#define KEYMON_BUTTON_MENU 317 -#define KEYMON_BUTTON_MENU_ALT 318 -#define KEYMON_BUTTON_PLUS 114 -#define KEYMON_BUTTON_MINUS 115 - -#define KEYMON_HAS_HDMI 1 -#define KEYMON_HDMI_STATE_PATH "/sys/class/extcon/hdmi/cable.0/state" - -#define KEYMON_HAS_JACK 1 -#define KEYMON_JACK_STATE_PATH "/sys/bus/platform/devices/singleadc-joypad/hp" - -// Uses event0-4 plus js0 (joystick) for menu button detection -#define KEYMON_INPUT_COUNT 6 -#define KEYMON_INPUT_DEVICE_0 "/dev/input/event0" -#define KEYMON_INPUT_DEVICE_1 "/dev/input/event1" -#define KEYMON_INPUT_DEVICE_2 "/dev/input/event2" -#define KEYMON_INPUT_DEVICE_3 "/dev/input/event3" -#define KEYMON_INPUT_DEVICE_4 "/dev/input/event4" -#define KEYMON_INPUT_DEVICE_5 "/dev/input/js0" - -/////////////////////////////// - -#endif diff --git a/workspace/rk3566/show/Makefile b/workspace/rk3566/show/Makefile deleted file mode 100755 index 03195e74..00000000 --- a/workspace/rk3566/show/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -TARGET = show -PRODUCT = $(TARGET).elf - -CC = $(CROSS_COMPILE)gcc -FLAGS = -Os $(CFLAGS) $(LDFLAGS) -lSDL2 -lSDL2_image -lrt -ldl -Wl,--gc-sections -s - -all: - $(CC) $(TARGET).c -o $(PRODUCT) $(FLAGS) -clean: - rm -rf $(PRODUCT) \ No newline at end of file diff --git a/workspace/rk3566/show/show.c b/workspace/rk3566/show/show.c deleted file mode 100644 index d095d569..00000000 --- a/workspace/rk3566/show/show.c +++ /dev/null @@ -1,83 +0,0 @@ -// rk3566 - Display an image on screen during boot/install/update -#include -#include -#include -#include -#include -#include - -SDL_Window* window; -SDL_Surface* screen; - -int main(int argc, char* argv[]) { - if (argc < 2) { - fprintf(stderr, "Usage: show.elf image.png [delay]\n"); - return 1; - } - - char path[256]; - snprintf(path, sizeof(path), "%s", argv[1]); - if (access(path, F_OK) != 0) { - fprintf(stderr, "show.elf: Image not found: %s\n", path); - return 1; - } - - int delay = argc > 2 ? atoi(argv[2]) : 2; - - fprintf(stderr, "show.elf: Initializing SDL2...\n"); - if (SDL_Init(SDL_INIT_VIDEO) < 0) { - fprintf(stderr, "show.elf: SDL_Init failed: %s\n", SDL_GetError()); - return 1; - } - - SDL_ShowCursor(0); - - // Use 0,0 to let SDL auto-detect display size (like tg5040) - fprintf(stderr, "show.elf: Creating window...\n"); - window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 0, 0, SDL_WINDOW_SHOWN); - if (!window) { - fprintf(stderr, "show.elf: SDL_CreateWindow failed: %s\n", SDL_GetError()); - SDL_Quit(); - return 1; - } - - screen = SDL_GetWindowSurface(window); - if (!screen) { - fprintf(stderr, "show.elf: SDL_GetWindowSurface failed: %s\n", SDL_GetError()); - SDL_DestroyWindow(window); - SDL_Quit(); - return 1; - } - - fprintf(stderr, "show.elf: Window size: %dx%d\n", screen->w, screen->h); - SDL_FillRect(screen, NULL, 0); - - fprintf(stderr, "show.elf: Loading image: %s\n", path); - SDL_Surface* img = IMG_Load(path); - if (!img) { - fprintf(stderr, "show.elf: IMG_Load failed: %s\n", IMG_GetError()); - SDL_DestroyWindow(window); - SDL_Quit(); - return 1; - } - - fprintf(stderr, "show.elf: Image size: %dx%d\n", img->w, img->h); - - // Center the image on screen - SDL_Rect dst = {(screen->w - img->w) / 2, (screen->h - img->h) / 2, img->w, img->h}; - SDL_BlitSurface(img, NULL, screen, &dst); - - if (SDL_UpdateWindowSurface(window) < 0) { - fprintf(stderr, "show.elf: SDL_UpdateWindowSurface failed: %s\n", SDL_GetError()); - } - - fprintf(stderr, "show.elf: Displaying for %d seconds...\n", delay); - sleep(delay); - - SDL_FreeSurface(img); - SDL_DestroyWindow(window); - SDL_Quit(); - - fprintf(stderr, "show.elf: Done\n"); - return 0; -}