summary refs log tree commit diff
diff options
context:
space:
mode:
authorzlago2024-08-31 19:00:41 +0200
committerzlago2024-08-31 19:07:37 +0200
commiteb068a88abe0f685309cb1a977f363c7d8708cad (patch)
tree68e1b14acf1fe611cc24cde1632531b8c4cef50d
initial commit
-rw-r--r--.gitignore1
-rw-r--r--GNUmakefile36
-rw-r--r--src/sdl.c150
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};
+}