// clang $(pkg-config --cflags SDL2_mixer) $(pkg-config --libs SDL2_mixer) -shared -o sdl2-mixer-module.so sdl2-mixer-module.c #include #include "SDL_mixer.h" int plugin_is_GPL_compatible; static char* copy_lisp_string(emacs_env *env, emacs_value arg) { ptrdiff_t len; char *buf; if (!env->copy_string_contents(env, arg, NULL, &len)) { return NULL; } buf = malloc(len); if (!buf) { return NULL; } if (!env->copy_string_contents(env, arg, buf, &len)) { return NULL; } return buf; } static void bind_function(emacs_env *env, const char *name, emacs_value Sfun) { emacs_value Qfset = env->intern(env, "fset"); emacs_value Qsym = env->intern(env, name); emacs_value args[] = { Qsym, Sfun }; env->funcall(env, Qfset, 2, args); } static void provide(emacs_env *env, const char *feature) { emacs_value Qfeat = env->intern(env, feature); emacs_value Qprovide = env->intern (env, "provide"); emacs_value args[] = { Qfeat }; env->funcall(env, Qprovide, 1, args); } #include static emacs_value Fsdl2_mixer_enable_bg_music(emacs_env *env, ptrdiff_t nargs, emacs_value args[], void *data) { char *path = copy_lisp_string(env, args[0]); Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 4096); Mix_AllocateChannels(2); Mix_Music *music = Mix_LoadMUS(path); Mix_PlayMusic(music, -1); return NULL; } int emacs_module_init(struct emacs_runtime *ert) { emacs_env *env = ert->get_environment(ert); bind_function(env, "sdl2-mixer-enable-bg-music", env->make_function(env, 1, 1, Fsdl2_mixer_enable_bg_music, NULL, NULL)); provide(env, "sdl2-mixer-module"); return 0; }