Compare commits
No commits in common. "4f6d1de8e2d2e304cf99e5c83c7c2d64cd259490" and "b6728a7482791cec108b3646f1a98b50e5836639" have entirely different histories.
4f6d1de8e2
...
b6728a7482
@ -18,7 +18,7 @@ shell:
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
build: .build
|
build: .build
|
||||||
docker run --platform linux/arm64 --rm -v "$(PROJECT_DIR)":/workspace $(IMAGE_NAME) make clean all
|
docker run --platform linux/arm64 --rm -v "$(PROJECT_DIR)":/workspace $(IMAGE_NAME) make
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
docker rmi $(IMAGE_NAME)
|
docker rmi $(IMAGE_NAME)
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
| Version | 1.0 |
|
| Version | 1.0 |
|
||||||
| Status | Draft |
|
| Status | Draft |
|
||||||
| Created | 2026-02-10 |
|
| Created | 2026-02-10 |
|
||||||
| Updated | 2026-02-13 |
|
| Updated | 2026-02-10 |
|
||||||
|
|
||||||
## 1. Purpose
|
## 1. Purpose
|
||||||
|
|
||||||
@ -43,18 +43,6 @@ This document specifies the functional requirements for an SDL2 based media play
|
|||||||
|
|
||||||
## 6. Changelog
|
## 6. Changelog
|
||||||
|
|
||||||
### 2026-02-13 — Combine Play/Stop, add Previous Cassette button
|
|
||||||
|
|
||||||
- **Play/Stop combined**: The separate Stop and Play buttons are merged into a single toggle button that shows the play icon (▶) when paused and the stop icon (■) when playing.
|
|
||||||
- **Previous Cassette**: A new "Previous Cassette" button is added at the left of the transport controls, mirroring "Next Cassette". Wraps from the first tape to the last.
|
|
||||||
- **New layout**: `[Volume] [Prev] [Rewind] [Play/Stop] [FF] [Next]` — same 6 focusable elements, same positions.
|
|
||||||
|
|
||||||
### 2026-02-13 — Start paused, fix next-tape autoplay, quiet joystick log
|
|
||||||
|
|
||||||
- **Start paused**: The player no longer autoplays on startup; it opens the last file at the saved position but waits for the user to press Play.
|
|
||||||
- **Next tape respects pause state**: `switch_file()` no longer forces playback. Pressing "next tape" while paused switches the file and stays paused; pressing it while playing switches and continues playing.
|
|
||||||
- **Joystick log behind --debug**: The "Joystick: ..." message is now only printed when `--debug` is passed.
|
|
||||||
|
|
||||||
### 2026-02-13 — arm64 Docker build container
|
### 2026-02-13 — arm64 Docker build container
|
||||||
|
|
||||||
- **New build container**: Replaced the broken Buildroot cross-compilation toolchain (`docker/`) with an arm64 Ubuntu 22.04 Docker container (`docker-arm64/`). Runs via QEMU user-mode emulation on x86 hosts and matches the target device exactly (same distro, same glibc, same library versions). The project's native `make` works as-is inside the container — no cross-compilation flags needed.
|
- **New build container**: Replaced the broken Buildroot cross-compilation toolchain (`docker/`) with an arm64 Ubuntu 22.04 Docker container (`docker-arm64/`). Runs via QEMU user-mode emulation on x86 hosts and matches the target device exactly (same distro, same glibc, same library versions). The project's native `make` works as-is inside the container — no cross-compilation flags needed.
|
||||||
|
|||||||
@ -57,15 +57,15 @@ static int current_file_index = 0;
|
|||||||
/* --- Focus / navigation --- */
|
/* --- Focus / navigation --- */
|
||||||
|
|
||||||
#define FOCUS_VOLUME 0
|
#define FOCUS_VOLUME 0
|
||||||
#define FOCUS_PREV 1
|
#define FOCUS_REWIND 1
|
||||||
#define FOCUS_REWIND 2
|
#define FOCUS_STOP 2
|
||||||
#define FOCUS_PLAYSTOP 3
|
#define FOCUS_PLAY 3
|
||||||
#define FOCUS_FF 4
|
#define FOCUS_FF 4
|
||||||
#define FOCUS_NEXT 5
|
#define FOCUS_NEXT 5
|
||||||
#define FOCUS_COUNT 6
|
#define FOCUS_COUNT 6
|
||||||
|
|
||||||
static float volume = 0.5f;
|
static float volume = 0.5f;
|
||||||
static int focus_index = FOCUS_PLAYSTOP;
|
static int focus_index = FOCUS_PLAY;
|
||||||
static SDL_GameController* controller = NULL;
|
static SDL_GameController* controller = NULL;
|
||||||
static SDL_Joystick* joystick = NULL;
|
static SDL_Joystick* joystick = NULL;
|
||||||
static int debug_mode = 0;
|
static int debug_mode = 0;
|
||||||
@ -478,7 +478,8 @@ static void switch_file(int index) {
|
|||||||
snprintf(title, sizeof(title), "SDLamp2 - %s", current_file);
|
snprintf(title, sizeof(title), "SDLamp2 - %s", current_file);
|
||||||
SDL_SetWindowTitle(window, title);
|
SDL_SetWindowTitle(window, title);
|
||||||
|
|
||||||
SDL_PauseAudioDevice(audio_device, paused);
|
paused = SDL_FALSE;
|
||||||
|
SDL_PauseAudioDevice(audio_device, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -494,22 +495,13 @@ static void switch_file(int index) {
|
|||||||
|
|
||||||
static void activate_focused_button(void) {
|
static void activate_focused_button(void) {
|
||||||
switch (focus_index) {
|
switch (focus_index) {
|
||||||
case FOCUS_PREV:
|
|
||||||
if (num_audio_files > 0) {
|
|
||||||
int prev = (current_file_index - 1 + num_audio_files) % num_audio_files;
|
|
||||||
switch_file(prev);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FOCUS_REWIND: {
|
case FOCUS_REWIND: {
|
||||||
double pos = get_current_seconds() - SEEK_SECONDS;
|
double pos = get_current_seconds() - SEEK_SECONDS;
|
||||||
decoder_seek(pos < 0.0 ? 0.0 : pos);
|
decoder_seek(pos < 0.0 ? 0.0 : pos);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FOCUS_PLAYSTOP:
|
case FOCUS_STOP:
|
||||||
if (paused && num_audio_files > 0) {
|
if (!paused) {
|
||||||
paused = SDL_FALSE;
|
|
||||||
SDL_PauseAudioDevice(audio_device, 0);
|
|
||||||
} else if (!paused) {
|
|
||||||
paused = SDL_TRUE;
|
paused = SDL_TRUE;
|
||||||
SDL_PauseAudioDevice(audio_device, 1);
|
SDL_PauseAudioDevice(audio_device, 1);
|
||||||
if (current_file[0]) {
|
if (current_file[0]) {
|
||||||
@ -517,6 +509,12 @@ static void activate_focused_button(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case FOCUS_PLAY:
|
||||||
|
if (paused && num_audio_files > 0) {
|
||||||
|
paused = SDL_FALSE;
|
||||||
|
SDL_PauseAudioDevice(audio_device, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case FOCUS_FF: {
|
case FOCUS_FF: {
|
||||||
double pos = get_current_seconds() + SEEK_SECONDS;
|
double pos = get_current_seconds() + SEEK_SECONDS;
|
||||||
double dur = get_duration_seconds();
|
double dur = get_duration_seconds();
|
||||||
@ -556,22 +554,21 @@ int main(int argc, char** argv) {
|
|||||||
const SDL_Rect volume_bg = {25, 390, 30, 80};
|
const SDL_Rect volume_bg = {25, 390, 30, 80};
|
||||||
|
|
||||||
/* Button positions (bottom of window, centered) */
|
/* Button positions (bottom of window, centered) */
|
||||||
const SDL_Rect prev_btn = {80, 390, 80, 80};
|
const SDL_Rect rewind_btn = {80, 390, 80, 80};
|
||||||
const SDL_Rect rewind_btn = {180, 390, 80, 80};
|
const SDL_Rect stop_btn = {180, 390, 80, 80};
|
||||||
const SDL_Rect playstop_btn = {280, 390, 80, 80};
|
const SDL_Rect play_btn = {280, 390, 80, 80};
|
||||||
const SDL_Rect ff_btn = {380, 390, 80, 80};
|
const SDL_Rect ff_btn = {380, 390, 80, 80};
|
||||||
const SDL_Rect next_btn = {480, 390, 80, 80};
|
const SDL_Rect next_btn = {480, 390, 80, 80};
|
||||||
|
|
||||||
/* Array of focusable rects indexed by FOCUS_* constants */
|
/* Array of focusable rects indexed by FOCUS_* constants */
|
||||||
const SDL_Rect* focus_rects[FOCUS_COUNT] = {&volume_bg, &prev_btn, &rewind_btn,
|
const SDL_Rect* focus_rects[FOCUS_COUNT] = {&volume_bg, &rewind_btn, &stop_btn,
|
||||||
&playstop_btn, &ff_btn, &next_btn};
|
&play_btn, &ff_btn, &next_btn};
|
||||||
|
|
||||||
/* Sprite sheet source rects */
|
/* Sprite sheet source rects */
|
||||||
const SDL_Rect rewind_sprite = {0, 0, 200, 200};
|
const SDL_Rect rewind_sprite = {0, 0, 200, 200};
|
||||||
const SDL_Rect play_sprite = {220, 0, 200, 200};
|
const SDL_Rect play_sprite = {220, 0, 200, 200};
|
||||||
const SDL_Rect ff_sprite = {440, 0, 200, 200};
|
const SDL_Rect ff_sprite = {440, 0, 200, 200};
|
||||||
const SDL_Rect stop_sprite = {0, 220, 200, 200};
|
const SDL_Rect stop_sprite = {0, 220, 200, 200};
|
||||||
const SDL_Rect prev_sprite = {440, 220, 200, 200}; /* same circle as next */
|
|
||||||
const SDL_Rect next_sprite = {440, 220, 200, 200};
|
const SDL_Rect next_sprite = {440, 220, 200, 200};
|
||||||
|
|
||||||
/* Progress bar area */
|
/* Progress bar area */
|
||||||
@ -633,7 +630,7 @@ int main(int argc, char** argv) {
|
|||||||
for (int i = 0; i < num_joy; i++) {
|
for (int i = 0; i < num_joy; i++) {
|
||||||
joystick = SDL_JoystickOpen(i);
|
joystick = SDL_JoystickOpen(i);
|
||||||
if (joystick) {
|
if (joystick) {
|
||||||
if (debug_mode) printf("Joystick: %s\n", SDL_JoystickName(joystick));
|
printf("Joystick: %s\n", SDL_JoystickName(joystick));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -905,10 +902,9 @@ int main(int argc, char** argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Buttons */
|
/* Buttons */
|
||||||
SDL_RenderCopy(renderer, controls_texture, &prev_sprite, &prev_btn);
|
|
||||||
SDL_RenderCopy(renderer, controls_texture, &rewind_sprite, &rewind_btn);
|
SDL_RenderCopy(renderer, controls_texture, &rewind_sprite, &rewind_btn);
|
||||||
SDL_RenderCopy(renderer, controls_texture, paused ? &play_sprite : &stop_sprite,
|
SDL_RenderCopy(renderer, controls_texture, &stop_sprite, &stop_btn);
|
||||||
&playstop_btn);
|
SDL_RenderCopy(renderer, controls_texture, &play_sprite, &play_btn);
|
||||||
SDL_RenderCopy(renderer, controls_texture, &ff_sprite, &ff_btn);
|
SDL_RenderCopy(renderer, controls_texture, &ff_sprite, &ff_btn);
|
||||||
SDL_RenderCopy(renderer, controls_texture, &next_sprite, &next_btn);
|
SDL_RenderCopy(renderer, controls_texture, &next_sprite, &next_btn);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user