summaryrefslogtreecommitdiffhomepage
AgeCommit message (Collapse)Author
2026-06-29fix: study-mode checkbox wasn't visible or bound (wrong RmlUi flow)rewriteAdam Malczewski
The checkbox used data-value (binds the element's 'value' string attribute) instead of data-checked (binds the 'checked' bool state) -- per RmlUi docs, checkboxes must use data-checked with a bool. So it neither reflected nor toggled study_mode, and with no explicit styling it rendered invisibly. Fix: wrap the input in a <form> (canonical RmlUi form-control flow), switch data-value -> data-checked, and give #cb-study an explicit visible style (border + background, green fill when :checked). Verified the document loads with no RmlUi parse errors. Note: RmlUi's border shorthand is 'width color' (no 'solid' keyword).
2026-06-29fix: UI time was stuck at 0:00 (flecs ecs_set of iterated component discarded)Adam Malczewski
Root cause: the Input/Update/ApplySeek/Study systems iterated 'with: [playback_state]' AND wrote playback_state back via ecs_set. In this flecs build, an ecs_set on the component a system is currently iterating is deferred and then DISCARDED -- so current_time never committed and the elapsed_str binding always read 0.0 (audio played fine because play/resume are imperative, but the clock and seek/keyboard state never persisted). Fix: each of those systems now iterates 'with: [audio_file]' -- a component the player always has but these systems do NOT mutate -- so their ecs_set on playback_state/study_state is immediate and persists. Verified: current_time now persists across world.progress (0.5, 1.0, 1.499, ...), the elapsed_str getter is re-evaluated every frame, and the app runs clean (no crash, audio loads + streams + shuts down cleanly). Note: LoadSystem still iterates audio_file and mutates it (af[:duration]), so the total-time display stays 0:00 for now -- left for a follow-up to avoid iterating a tag, which crashed the flecs binding.
2026-06-29fix: make audio actually play (four flecs systems were dead: with: [])Adam Malczewski
Same with: [] (zero-term) trap as the drag-and-drop fix, but it silently killed four runtime systems -- so audio loaded but never played and the clock stayed at 0:00: - Update (ON_UPDATE): never called Rl.update_music_stream, so miniaudio never pumped its buffers -> no sound, get_music_time_played stayed 0. - Input (PRE_UPDATE): keyboard controls (space, seek keys, M) dead. - ApplySeek(PRE_UPDATE): seeking dead. - Study (ON_UPDATE): study-mode auto-pause FSM dead. A zero-term system never iterates its block in this flecs build. Gave each a real term (with: [playback_state]) so they match the player entity and run every frame. The play/smart-play buttons already called audio.resume via RmlUi -- they just had no stream pumping behind them. Verified end-to-end (synthetic Xdnd drop + ARGV load): file loads -> plays -> current_time advances 0..duration -> end-of-track auto-pause.
2026-06-29fix: poll drag-and-drop in the main loop (drop events were never read)Adam Malczewski
Root cause: the file-drop check was a flecs system registered with with: [] (zero terms). In this flecs build a zero-term system never iterates its block, so Rl.file_dropped? was never polled and dropped files were silently ignored -- the SDL backend was receiving the Xdnd events fine all along. Moved the IsFileDropped()/LoadDroppedFiles() check into the main loop (before world.progress, so the LoadSystem picks up the file the same frame), matching the original C study-player. Verified end-to-end with a synthetic Xdnd drop: file detected -> loaded as a music stream.
2026-06-29fix: start-apps.sh launches the study player (drag-and-drop was dead)Adam Malczewski
With no script arg, main.c defaults to game/main.rb — the raylib-jamstack HUD demo — which has no file-drop handler. Pass the study-player script explicitly so the CheckFileDrop system (drag-and-drop) is actually loaded.
2026-06-29fix: switch desktop window backend GLFW -> SDL2 (reliable drag-and-drop)Adam Malczewski
The GLFW Wayland drag-and-drop crash fix (previous commit) did NOT resolve drag-and-drop on the real target (labwc), so abandon the GLFW path entirely instead of patching it further. Why SDL: raylib ships a first-class SDL backend (PLATFORM_DESKTOP_SDL) that implements file drop via SDL_DROPFILE. GLFW 3.4 (vendored in raylib 6.0) has broken Wayland drag-and-drop (wl_data_offer NULL source_actions/action listeners -> libwayland wl_abort on drag, glfw/glfw#2835) AND its X11 backend segfaults on WSLg (Mesa GLX). SDL's window/EGL/drag-drop is mature on BOTH real Wayland (labwc) and WSLg, so one backend covers both targets with no vendor patches and no X11/Wayland special-casing. Changes (desktop only; web build stays Emscripten+GLFW, untouched): - build.zig: build raylib PLATFORM=PLATFORM_DESKTOP_SDL (SDL_INCLUDE_PATH/ LIBRARY_PATH = system SDL2); link SDL2 instead of wayland-*/xkbcommon/EGL. - Revert the GLFW patch (patches/glfw-wayland-dnd-crash.patch removed; the build.zig patch-application step removed). - Docs: environment.md / study-player.md / BUILDING.md / SCREENSHOT.md updated to reflect the SDL backend + the SDL2 system dependency. The RmlUi binding is backend-agnostic (rlgl render + raylib IsKeyDown input, zero glfw* calls), so the swap is transparent to it. Prerequisite on the cyberdeck: install SDL2 dev (sudo pacman -S sdl2 or sdl2-compat) before building. Verified on the laptop (WSLg): build green; binary runs under SDL (Platform backend: DESKTOP (SDL)), window opens, no GLX segfault, RmlUi fonts load, mp3 loads from argv (132300 frames), no crash. Interactive drag-drop itself still needs user testing on the cyberdeck (SDL_DROPFILE path).
2026-06-29docs: record GLFW 3.4 Wayland drag-drop crash + patch scar tissueAdam Malczewski
Cross-ref from study-player.md drag-drop section to environment.md so the next agent touching drag-drop finds the real root cause (GLFW/Wayland, not the Ruby CheckFileDrop code).
2026-06-29fix: reliable Wayland drag-and-drop (root cause: GLFW 3.4 wl_data_offer NULL ↵Adam Malczewski
listener) The rewrite builds raylib Wayland-only (X11/GLX segfaults on WSLg), but raylib 6.0 vendors GLFW 3.4 (release) which crashes the moment a file is dragged over the window on Wayland (glfw/glfw#2835, #2562): struct wl_data_offer_listener dataOfferListener = { dataOfferHandleOffer }; // source_actions (opcode 1) + action (opcode 2) handlers are NULL wl_data_offer is v3; modern compositors (labwc/GNOME/KDE) emit source_actions/action during a drag -> libwayland-client wl_abort()s on the NULL listener -> app dies on drag-enter, before any drop registers. This is why drag-and-drop is 'unreliable' in the rewrite but reliable in the original 'dev' app, which uses the X11/Xdnd backend (-D_GLFW_X11) — a separate code path with none of these bugs. Fix: backport the upstream GLFW-master fix as a committed patch applied idempotently in build.zig before (marker = dataOfferHandleAction; forces a lib rebuild when newly applied). Adds no-op source_actions/action handlers so the events are safely consumed (GLFW only needs the mime-types to accept a drop), plus guards two NULL derefs in the same data-device path (dataDeviceHandleEnter / dataDeviceHandleDrop). This keeps the Wayland-only build (no WSLg GLX regression) and fixes the crash on both WSLg and a real Wayland desktop (cyberdeck/labwc). Drop the patch once raylib vendors a GLFW release containing the upstream fix. Verified: build green; desktop binary launches, loads an mp3 from argv (132300 frames), enters the loop with no segfault. Interactive drag-drop itself still needs user testing (it's a user action; the WSLg non-interactive shell stalls the Wayland window before render).
2026-06-29refactor: font-scale targets #body-root element (coherent id alignment)Adam Malczewski
Aligns apply_font_scale to the body element's id across study_player.rb / layout.rb / main.rml (was probing element('body')||element('__body__')). Verified: build green, run clean, player view renders correctly. (these edits were left uncommitted by the Phase 6 agent's timed-out turn; orchestrator verified + committed.)
2026-06-29fix: add F1-F12 symbol keys to Rl:: (phase 6 settings-toggle used :f2)Adam Malczewski
Phase 6's settings panel toggles on F2, but Rl::resolve_key's SYMBOL_KEYS map only had letters/digits/a few named keys — :f2 raised ArgumentError and crashed the loop at frame 1. Added f1..f12 (raylib keycodes 290-301) to the map. The KEY_F* constants aren't all exposed to mruby, so the int values are used. (orchestrator fix — unblocked the final end-to-end verification.)
2026-06-29phase 6: config persistence, layout settings, final end-to-end verificationAdam Malczewski
- Config: INI-style study-player.cfg (forward-compatible with the original C config.c format). Persists window size, study_mode_default, volume, last_audio_path, font_scale. - Layout: UILayout keys mapped to RmlUi element properties (RCSS-tunable). Adapted the C drag-to-reposition editor to RmlUi-appropriate settings (P4: RmlUi uses declarative RCSS, so pixel-drag doesn't map cleanly; persist what's meaningful). load on startup, save on change. - study_player.rb wiring + main.rml/rcss settings panel. (orchestrator-committed: agent completed + built green, but its turn timed out before committing — it was running gen_ai_reference.rb at the timeout.)
2026-06-29phase 5: RmlUi player UI (progress bar, buttons, checkbox, counter, help)Adam Malczewski
2026-06-29phase 4: study mode auto-pause FSM + smart play overrideAdam Malczewski
2026-06-29phase 3: silence detection, speaking portions, portion navigationAdam Malczewski
- mrbgems/study_audio: native C scanner (scan_silence) avoids Ruby array overflow for large audio files; returns normalized silence region pairs directly - Core.detect_silence: pure Ruby algorithm (threshold 0.015, min 0.75s) for testing with synthetic data; pad_silence_regions (0.25s padding) - Core portion navigation: find_silence_at, current_speaking_portion, total_speaking_portions, portion_seek_target (2 frames into padding zone), in_padding_zone?, speaking_portion_start - Input: V/B keys for prev/next portion navigation - Draw: section counter (N/total) displayed below play state - build_config.rb: added study_audio gem to both desktop and web builds - Runtime: silence_regions, raw_silence_regions, analysis_done fields - Load system: triggers C scan_silence after audio load, pads with pure Ruby - Knowledge doc updated with Phase 3 scar tissue (array limits, gem naming, Wayland screenshot gap) Verification: build clean, pure Core smoke test passes (CRuby), game runs with country.mp3 without overflow, load system processes the file.
2026-06-29phase 2: update scar-tissue knowledge with mruby compatibility discoveries ↵Adam Malczewski
(no require, int32_t, keyword_init, ARGV, non-blocking seek)
2026-06-29phase 2: audio core, argv file loading, playback, non-blocking seekAdam Malczewski
(orchestrator-committed: Phase 2 agent (deepseek-v4-pro) completed the work and verified via build+run+screenshot, but its turn timed out before committing.)
2026-06-29phase 1: study-player rewrite plan + scaffoldAdam Malczewski
2026-06-28import template from raylib-jamstackAdam Malczewski
2026-06-27fix: extract help text + checkbox into ui_render_overlayAdam Malczewski
The help text and study-mode checkbox were inside ui_render_player, so they only appeared when an audio file was loaded. In the original single-file main.c they rendered unconditionally (outside the 'if loaded' block). Extracted ui_render_overlay() — renders help text + checkbox — and call it from main.c after either ui_render_player or ui_render_empty, matching the original behavior. Also added a screenshot mode (env STUDY_PLAYER_SCREENSHOT) for automated visual testing: renders to an offscreen RenderTexture, fixes FBO alpha artifacts (ClearBackground doesn't fill alpha on some Mesa drivers), and exports a PNG. Verified all UI elements render correctly.
2026-06-27refactor: split single-file main.c into modular .h/.c pairsAdam Malczewski
Decompose the 778-line src/main.c into 7 focused modules with separate headers for code isolation and parallel agent development: types.h shared types: PlayerState, SilenceRegion, UILayout, constants player.{h,c} audio playback: load, play, pause, seek, update, format_time study.{h,c} study mode: silence detection, portion navigation, auto-pause ui.{h,c} rendering + input: fonts, colors, drawing, keyboard/mouse config.{h,c} UI layout persistence (moved UILayout to types.h) layout_editor.{h,c} layout editor tab (unchanged) main.c thin composition root (main loop, tabs, platform glue) Module boundaries follow the dispatch-project style: - .h files are contracts (self-contained, #pragma once, forward-declare) - .c files are private (static helpers, no cross-module .c includes) - All shared state passed by pointer (PlayerState*/UIState*) - font_data.h (xxd-generated array definition) included in exactly one .c Updated documentation (AGENTS.md, ORCHESTRATOR.md, GLOSSARY.md, README.md, tasks.md) and bin/ scripts (dispatch-style conventions, added bin/build-web). Build: make clean && make -j$(nproc) exits 0 with zero warnings.
2026-06-27V1: preserve pre-refactor state (single-file main.c + harness docs)V1Adam Malczewski
2026-06-08ui: add X-axis positioning to all layout elementscyberdeckAdam Malczewski
- UILayout gains titleX, statusX, helpX, smartPlayX, secNavX - All elements freely draggable in both X and Y in Layout editor - draw_text_centered() now takes centerX parameter - section nav positions relative to secNavX
2026-06-08ui: make smart play button and section nav configurableAdam Malczewski
- UILayout gains smartPlayY and secNavY fields - Smart play HOLD button now uses layout.smartPlayY - Section nav prev/next buttons use layout.secNavY - Both are draggable in Layout editor tab - config_load/config_save handle new fields
2026-06-08ui: add tab bar, layout editor with drag-to-repositionAdam Malczewski
- GuiTabBar from raygui v5.0 for Player/Layout tab switching - Layout tab: 5 draggable element placeholders (Title, Bar, Status, Play button, Help) — press+hold+drag to reposition - Auto-save config file on tab switch from Layout back to Player - config_save() added to config module - raygui include path added to Makefile, warnings suppressed via #pragma for third-party header
2026-06-08config: add key-value config file for UI layout positionsAdam Malczewski
- src/config.h: UILayout struct + config_load() declaration - src/config.c: key=value parser with defaults fallback - src/main.c: replace hardcoded layout constants with config-driven UILayout - Config file loaded from next to binary (study-player.cfg) - Missing config file falls back to hardcoded defaults
2026-06-08build: add Linux native target with static raylib linkingAdam Malczewski
- Default target (make) now builds for Linux native (gcc) - Windows cross-compile preserved as x86_64-w64-mingw32-gcc -std=c99 -O2 -Ibuild -Ideps/raylib/src -Ideps/raylib/src/external/glfw/include -Wall -Wextra -DPLATFORM_DESKTOP -D_GLFW_WIN32 -o build/study-player.exe build/main.o build/libraylib.a -lgdi32 -lwinmm -lcomdlg32 -lole32 - Raylib built from source and statically linked (no .so/.dll) - Font embedded at compile time via xxd (best-effort) - Auto-discovery of src/*.c files via wildcard - Target-specific variables for clean dual-target architecture
2026-04-18rework study modeHEADmainAdam Malczewski
2026-04-18Add screenshotAdam Malczewski
2026-04-18add study modeAdam Malczewski
2026-04-18add a system for marking speaking sectionsAdam Malczewski
2026-04-18final touchesAdam Malczewski
2026-04-18update to working stateAdam Malczewski
2026-04-18initialAdam Malczewski