diff options
author | zlago | 2024-08-31 19:00:41 +0200 |
---|---|---|
committer | zlago | 2024-08-31 19:07:37 +0200 |
commit | eb068a88abe0f685309cb1a977f363c7d8708cad (patch) | |
tree | 68e1b14acf1fe611cc24cde1632531b8c4cef50d |
initial commit
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | GNUmakefile | 36 | ||||
-rw-r--r-- | src/sdl.c | 150 |
3 files changed, 187 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6a3417b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/out/ diff --git a/GNUmakefile b/GNUmakefile new file mode 100644 index 0000000..09bd738 --- /dev/null +++ b/GNUmakefile @@ -0,0 +1,36 @@ +#!/usr/bin/env -S gmake -f + +GLAD ?= glad +MKDIR ?= mkdir -p + +libs ::= SDL2 +cflags ::= -I . -g -Og ${CFLAGS} +ldflags ::= -Wl,--rpath,'$$ORIGIN' $(addprefix -l,${libs}) ${LDFLAGS} + +srcs ::= $(wildcard src/*.c) +objs ::= $(addprefix out/,$(notdir ${srcs:.c=.o})) +deps ::= $(addprefix out/,$(notdir ${srcs:.c=.d})) + +.PHONY: all run clean + +all: out/mu-sdl + +run: out/mu-sdl + ./$< + +clean: + ${RM} -r out/ + +out/: + ${MKDIR} $@ + +out/%.o: src/%.c out/%.d | out/ + ${CC} -c -o $@ $< ${cflags} + +out/%.d: src/%.c | out/ + ${CC} ${cflags} ${CPPFLAGS} -MM -MG -MF $@ -MT "${@:.d=.o} $@" $< + +out/mu-sdl: ${objs} | out/ + ${CC} -o $@ $^ ${cflags} ${ldflags} + +include ${deps} diff --git a/src/sdl.c b/src/sdl.c new file mode 100644 index 0000000..0072c87 --- /dev/null +++ b/src/sdl.c @@ -0,0 +1,150 @@ +#define SDL_MAIN_HANDLED +#include <SDL2/SDL.h> + +#include <stdbool.h> +#include <stdlib.h> +#include <stdio.h> + +#include <libopenmpt/libopenmpt.h> + +#define eprintf(...) fprintf(stderr, __VA_ARGS__) + +static const int WINDOW_WIDTH = 160, WINDOW_HEIGHT = 90; + +struct blob { + void *data; + size_t size; +}; + +SDL_Window *window = NULL; + +struct blob load_file(char const *const name); + +struct userdata { + SDL_AudioCallback callback; + void *user; +} userdata = { + .callback = NULL, + .user = NULL, +}; + +void audio_callback(void *userdata_void, unsigned char *stream_void, int const length) { + struct userdata *user = userdata_void; + float *stream = (float *) stream_void; + if (user->callback == NULL) { + for (int i = 0; i < length / sizeof (float); i++) { + stream[i] = 0.0; + } + } else { + user->callback(user->user, stream_void, length); + } +} + +int main(void) { + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)) { + eprintf("failed to init SDL: %s\n"); + return EXIT_FAILURE; + } + + SDL_StopTextInput(); + + if ((window = SDL_CreateWindow("mu-sdl", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE)) == NULL) { + eprintf("failed to create a window: %s\n"); + SDL_Quit(); + return EXIT_FAILURE; + } + + SDL_AudioSpec desired = { + .freq = 48000, + .format = AUDIO_F32SYS, + .channels = 2, + .samples = 8096, + .callback = audio_callback, + .userdata = &userdata, + }; + SDL_AudioDeviceID audio = SDL_OpenAudioDevice(NULL, 0, &desired, NULL, 0); + + SDL_PauseAudioDevice(audio, 0); + while (true) { + SDL_Event evt; + while (SDL_PollEvent(&evt)) { + switch (evt.type) { + case SDL_QUIT: + goto done; + + case SDL_KEYDOWN: + // ^Q + if (evt.key.keysym.sym == SDLK_q && evt.key.keysym.mod & KMOD_CTRL) { + goto done; + } + // ESC + if (evt.key.keysym.sym == SDLK_ESCAPE) { + goto done; + } + break; + + case SDL_DROPFILE: + puts(evt.drop.file); + struct blob file = load_file(evt.drop.file); + if (file.data == NULL) { + perror(evt.drop.file); + SDL_free(evt.drop.file); + break; + } + SDL_free(evt.drop.file); + //SDL_LockAudioDevice(audio); + //openmpt_module *mod = openmpt_module_create_from_memory2(file.data, file.size, &libopenmpt_example_logfunc, NULL, &libopenmpt_example_errfunc, NULL, &mod_err, &mod_err_str, NULL); + //SDL_UnlockAudioDevice(audio); + free(file.data); + break; + + default: + } + } + } + done: + + SDL_DestroyWindow(window); + + SDL_CloseAudioDevice(audio); + + SDL_Quit(); + + return EXIT_SUCCESS; +} + +struct blob load_file(char const *const name) { + const size_t START_SIZE = 1; + FILE *file = fopen(name, "rb"); + if (file == NULL) { + return (struct blob) {.data = NULL}; + } + void *data = malloc(START_SIZE); + size_t allocated = START_SIZE; + size_t used = 0; + while (1) { + size_t read = fread(data + used, 1, allocated - used, file); + if (read != allocated - used) { + used += read; + break; + } + used += read; + allocated *= 2; + void *const newdata = realloc(data, allocated); + if (newdata == NULL) { + goto realloc_error; + } + data = newdata; + } + void *const newdata = realloc(data, used); + if (newdata == NULL) { + goto realloc_error; + } + fclose(file); + return (struct blob) {.data = newdata, .size = used}; + + realloc_error: + free(data); + fclose(file); + return (struct blob) {.data = NULL}; +} |