14 Commits

Author SHA1 Message Date
b8d7a2e405 Transparent controls spritesheet, red focus highlight
Enable alpha blending on the controls texture so sprite icons
float on any background without white cell artifacts. Regenerate
skin template with transparent cells and magenta gutters. Change
focus highlight from blue to red.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 00:29:09 +01:00
8a638acdd8 Skin template system, separate prev sprite, reorganize device scripts
Add tools/gen_skin_template.py to generate a labeled 642x420 PNG template
for creating custom spritesheets. Move rg35xx device scripts from tools/
to device/rg35xx/. Point prev_sprite at its own cell (bottom-center) so
Prev and Next can have distinct icons.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 23:47:21 +01:00
1ea1490e60 Fix power button screen toggle instantly turning back on
Power button events were setting any_activity before the power handler's
continue, causing the generic wake logic to immediately re-enable the screen.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 23:18:42 +01:00
f9fcb9f121 Fix goodbye.png not visible on idle auto-shutdown
The Allwinner /dev/disp driver resets brightness to 0 when the fd is
closed, so the screen monitor's SIGTERM brightness restore was undone
before the wrapper wrote goodbye.png. Restore brightness in the wrapper
itself, right before the framebuffer write.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 23:12:10 +01:00
fbd32d7fb8 Fix screen wake for d-pad, grab inputs while screen off, auto-shutdown on idle
- Broaden wake events beyond EV_KEY so d-pad (EV_ABS) wakes the screen
- Use EVIOCGRAB for exclusive input while screen is off, preventing the
  wake button press from also acting in sdlamp2
- Auto-shutdown after 10 minutes of no input and no audio playback,
  detected by monitoring the audio file's read position via /proc fdinfo

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 22:47:47 +01:00
3fcae8ea5e Fix power button shutdown by consolidating input handling in screen monitor
Both the evtest-based power monitor and the Python screen monitor were
reading /dev/input/event0 simultaneously, causing missed events on the
device's Linux 4.9 kernel. Moved long-press shutdown into the screen
monitor (which already reads event0 directly) and removed the evtest
dependency entirely.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 21:47:48 +01:00
2142ed7629 Add screen idle timeout and power button screen toggle
New Python screen monitor uses Allwinner /dev/disp ioctls to turn off
the display after 15s of no input and toggle it with a short power
button press. Launched by the wrapper alongside sdlamp2.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 21:34:43 +01:00
06daec791e Move shutdown screen to wrapper, reuse stock firmware goodbye.png
The in-app shutdown visual didn't work because SDL cleanup wiped the
framebuffer. Instead of hacking around that, move the shutdown display
to the device wrapper where it belongs. The wrapper now decodes the
stock firmware's goodbye.png with Python3+PIL and writes raw BGRA
pixels directly to /dev/fb0 before calling poweroff.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 21:07:03 +01:00
3728e9499c Implement power button monitor, document device input devices
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 20:07:37 +01:00
0f653d4395 Handle SIGTERM/SIGINT for clean shutdown, add device wrapper script
sdlamp2 now catches SIGTERM and SIGINT via a sig_atomic_t flag checked
in the main loop, ensuring position and volume are saved before exit.
Previously, a kill signal would terminate instantly without saving.

New tools/rg35xx-wrapper.sh replaces sdlamp2 as the dmenu_ln CMD on
the RG35XX Plus. Skeleton includes placeholders for WiFi hotspot and
power button monitoring (TBD after on-device investigation).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 15:49:38 +01:00
52d5bbd971 Move controls.png to assets/ and gitignore all of build/
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 10:31:23 +01:00
7e67589150 Embed controls.png into binary so it can run from any directory
The spritesheet is compiled in as a C byte array. An external
controls.png in cwd still takes precedence for skinning. Includes
tools/embed_png.py to regenerate the header if the asset changes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 10:25:22 +01:00
1a2a7e337b Fix concat tool: handle embedded album art and strip track numbers from chapters
The m4a muxer doesn't support mjpeg as a regular video stream, causing
concatenation to fail when inputs contain album art. Extract art separately
and re-attach it with attached_pic disposition. Also strip leading track
numbers (e.g. "01 ") from chapter titles.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 11:03:38 +01:00
6209a087d7 Add lossless M4A concatenation tool
Shell script to recombine individual story m4a files back into
per-cassette files using ffmpeg concat demuxer (stream copy, no
re-encoding). Generates chapter markers from input filenames and
preserves album art.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 09:45:27 +01:00