WIP: controls

This commit is contained in:
Michael Smith 2026-01-16 17:58:00 +01:00
parent c1deafb7dd
commit 333ab8f82d
3 changed files with 125 additions and 20 deletions

View File

@ -1,5 +1,11 @@
#!/bin/sh
pushd build
gcc -o sdlamp2 -Wall -O0 -ggdb3 ../src/sdlamp2.c `sdl2-config --cflags --libs`
gcc -Wall -O0 -ggdb3 \
-o sdlamp2 \
`sdl2-config --cflags --libs` \
-lSDL2_image \
../src/sdlamp2.c
popd

BIN
build/controls.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View File

@ -1,9 +1,17 @@
#include "SDL.h"
#include "SDL_image.h"
static SDL_AudioDeviceID audio_device = 0;
static SDL_Window *window = NULL;
static SDL_Renderer *renderer = NULL;
static SDL_AudioDeviceID audio_device = 0;
static Uint8 *wavbuf = NULL;
static Uint32 wavlen = 0;
static SDL_AudioSpec wavspec;
static SDL_AudioStream *stream = NULL;
// static SDL_bool paused = SDL_TRUE;
static SDL_bool paused = SDL_FALSE;
static void panic_and_abort(const char *title, const char *text) {
fprintf(stderr, "PANIC: %s ... %s\n", title, text);
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, title, text, window);
@ -11,10 +19,53 @@ static void panic_and_abort(const char *title, const char *text) {
exit(1);
}
static SDL_bool load_audio_file(const char *fname) {
SDL_FreeAudioStream(stream);
stream = NULL;
SDL_FreeWAV(wavbuf);
wavbuf = NULL;
wavlen = 0;
if (SDL_LoadWAV(fname, &wavspec, &wavbuf, &wavlen) == NULL) {
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't load wav file!",
SDL_GetError(), window);
return SDL_FALSE;
}
stream = SDL_NewAudioStream(wavspec.format, wavspec.channels, wavspec.freq,
AUDIO_F32, 2, 48000);
if (!stream) {
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
"Couldn't create audio stream!", SDL_GetError(),
window);
SDL_FreeWAV(wavbuf);
wavbuf = NULL;
wavlen = 0;
}
if (SDL_AudioStreamPut(stream, wavbuf, wavlen) ==
-1) { // FIXME(m): graceful handling.
panic_and_abort("Audio stream put failed!", SDL_GetError());
}
SDL_AudioStreamFlush(stream); // FIXME(m): error handling.
SDL_PauseAudioDevice(audio_device, paused);
return SDL_TRUE;
}
int main(int argc, char **argv) {
Uint8 *wavbuf = NULL;
Uint32 wavlen = 0;
SDL_AudioSpec wavspec;
SDL_AudioSpec desired;
SDL_bool running = SDL_TRUE;
const SDL_Rect rewind_rect = {10, 10, 100, 100};
const SDL_Rect stop_rect = {120, 10, 100, 100};
const SDL_Rect play_pause_rect = {230, 10, 100, 100};
const SDL_Rect fast_forward_rect = {340, 10, 100, 100};
const SDL_Rect rewind_symbol_rect = {0, 0, 200, 200};
const SDL_Rect play_symbol_rect = {220, 0, 200, 200};
const SDL_Rect fast_forward_symbol_rect = {440, 0, 200, 200};
const SDL_Rect stop_symbol_rect = {0, 220, 200, 200};
const SDL_Rect pause_symbol_rect = {220, 220, 200, 200};
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) != 0) {
panic_and_abort("SDL_Init failed!", SDL_GetError());
@ -31,23 +82,35 @@ int main(int argc, char **argv) {
panic_and_abort("SDL_CreateRenderer failed!", SDL_GetError());
}
if (SDL_LoadWAV("music.wav", &wavspec, &wavbuf, &wavlen) == NULL) {
panic_and_abort("Couldn't load wav file!", SDL_GetError());
}
audio_device = SDL_OpenAudioDevice(NULL, 0, &wavspec, NULL, 0);
SDL_zero(desired);
desired.freq = 48000;
desired.format = AUDIO_F32;
desired.channels = 2;
desired.samples = 4096;
desired.callback = NULL;
audio_device = SDL_OpenAudioDevice(NULL, 0, &desired, NULL, 0);
if (audio_device == 0) {
panic_and_abort("Could not open audio device!", SDL_GetError());
}
SDL_QueueAudio(audio_device, wavbuf, wavlen);
SDL_bool paused = SDL_TRUE;
const SDL_Rect rewind_rect = {100, 100, 100, 100};
const SDL_Rect pause_rect = {400, 100, 100, 100};
load_audio_file("music.wav");
SDL_Surface *controls_surface = IMG_Load("controls.png");
if (controls_surface == NULL) {
panic_and_abort("Could not load controls asset!", SDL_GetError());
}
SDL_Texture *controls_texture =
SDL_CreateTextureFromSurface(renderer, controls_surface);
SDL_FreeSurface(controls_surface);
if (controls_texture == NULL) {
panic_and_abort("Could not load controls asset!", SDL_GetError());
}
SDL_bool running = SDL_TRUE;
SDL_Event e;
while (running) {
// Event loop
while (SDL_PollEvent(&e)) {
switch (e.type) {
case SDL_QUIT:
@ -56,10 +119,17 @@ int main(int argc, char **argv) {
case SDL_MOUSEBUTTONDOWN: {
const SDL_Point pt = {e.button.x, e.button.y};
if (SDL_PointInRect(&pt, &rewind_rect)) {
if (SDL_PointInRect(&pt, &rewind_rect)) { // Pressed the "rewind" button
SDL_ClearQueuedAudio(audio_device);
SDL_QueueAudio(audio_device, wavbuf, wavlen);
} else if (SDL_PointInRect(&pt, &pause_rect)) {
SDL_AudioStreamClear(stream);
if (SDL_AudioStreamPut(stream, wavbuf, wavlen) ==
-1) { // FIXME(m): graceful handling.
panic_and_abort("Audio stream put failed!", SDL_GetError());
}
SDL_AudioStreamFlush(stream); // FIXME(m): error handling.
} else if (SDL_PointInRect(
&pt,
&play_pause_rect)) { // Pressed the "pause" button
paused = paused ? SDL_FALSE : SDL_TRUE;
SDL_PauseAudioDevice(audio_device, paused);
}
@ -68,16 +138,45 @@ int main(int argc, char **argv) {
}
}
SDL_SetRenderDrawColor(renderer, 0, 0xFF, 0, 0xFF);
// Deal with audio
if (SDL_GetQueuedAudioSize(audio_device) < 8192) {
const int bytes_remaining = SDL_AudioStreamAvailable(stream);
if (bytes_remaining > 0) {
const int new_bytes = SDL_min(bytes_remaining, 32 * 1024);
static Uint8 converted_buffer[32 * 1024];
SDL_AudioStreamGet(stream, converted_buffer,
new_bytes); // FIXME(m): error handling.
SDL_QueueAudio(audio_device, converted_buffer, new_bytes);
}
}
// Deal with drawing to screen
SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
SDL_RenderFillRect(renderer, &rewind_rect);
SDL_RenderFillRect(renderer, &pause_rect);
SDL_RenderFillRect(renderer, &stop_rect);
SDL_RenderFillRect(renderer, &play_pause_rect);
SDL_RenderFillRect(renderer, &fast_forward_rect);
SDL_RenderCopy(renderer, controls_texture, &rewind_symbol_rect,
&rewind_rect);
SDL_RenderCopy(renderer, controls_texture, &stop_symbol_rect, &stop_rect);
if (paused) {
SDL_RenderCopy(renderer, controls_texture, &play_symbol_rect,
&play_pause_rect);
} else {
SDL_RenderCopy(renderer, controls_texture, &pause_symbol_rect,
&play_pause_rect);
}
SDL_RenderCopy(renderer, controls_texture, &fast_forward_symbol_rect,
&fast_forward_rect);
SDL_RenderPresent(renderer);
}
// Clean up
SDL_FreeWAV(wavbuf);
SDL_CloseAudioDevice(audio_device);
SDL_DestroyRenderer(renderer);