diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/sdl.c | 150 |
1 files changed, 150 insertions, 0 deletions
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}; +} |