From 4003fd7c5fca8eaae70ba79ad883f93c50baf797 Mon Sep 17 00:00:00 2001 From: Allanis Date: Mon, 10 Mar 2014 20:54:40 +0000 Subject: [PATCH] [Change] FFUUUUU!! Do *NOT* call MIX_* functions from callbacks, especially when locked! Jeezus! --- src/music.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++------ src/music.h | 5 ++-- src/sound.c | 5 ++++ 3 files changed, 73 insertions(+), 11 deletions(-) diff --git a/src/music.c b/src/music.c index f9c88e9..1dc92f6 100644 --- a/src/music.c +++ b/src/music.c @@ -4,6 +4,7 @@ */ #include +#include #include #include "llua.h" @@ -22,9 +23,21 @@ int music_disabled = 0; /**< Whether or not music is disabled. */ +/* Handle if music should run Lua script. Must be locked to ensure same + * behaviour always! + */ +static SDL_mutex* music_lock = NULL; /**< Lock for music_runLua so it doesn't + run twise in a row with weird + results. + DO NOT CALL MIX* FUNCTIONS WHEN + LOCKED!!!! FUCK!!!! */ +static int music_runchoose = 0; /**< Whether or not music should run the choose function. */ +static char music_situation[PATH_MAX]; /**< What situation music is in. */ + /* Global music lua. */ static lua_State* music_lua = NULL; /**< The Lua music control state. */ /* Functions. */ +static int music_runLua(char* situation); static int musicL_load(lua_State* L); static int musicL_play(lua_State* L); static int musicL_stop(lua_State* L); @@ -51,6 +64,41 @@ static void music_rechoose(void); static int music_luaInit(void); static void music_luaQuit(void); +/** + * @brief Update the music. + */ +void music_update(void) { + char buf[PATH_MAX]; + + /* Lock music and see if it needs to update. */ + SDL_mutexP(music_lock); + if(music_runchoose == 0) { + SDL_mutexV(music_lock); + return; + } + + music_runchoose = 0; + strncpy(buf, music_situation, PATH_MAX); + SDL_mutexV(music_lock); + + music_runLua(buf); +} + +/** + * @brief Run the Lua music choose function. + * @param situation Situation in to choose music for. + * @return 0 on success. + */ +static int music_runLua(char* situation) { + /* Run the choose function in Lua. */ + lua_getglobal(music_lua, "choose"); + lua_pushstring(music_lua, situation); + if(lua_pcall(music_lua, 1, 0, 0)) /* Error has occured. */ + WARN("Error while choosing music: %s", (char*)lua_tostring(music_lua, -1)); + + return 0; +} + /** * @fn int music init(void) * @@ -64,6 +112,9 @@ int music_init(void) { if(music_luaInit() < 0) return -1; music_volume(0.8); + /* Create the lock. */ + music_lock = SDL_CreateMutex(); + return 0; } @@ -74,6 +125,12 @@ int music_init(void) { */ void music_exit(void) { music_free(); + + /* Destroy the lock. */ + if(music_lock != NULL) { + SDL_DestroyMutex(music_lock); + music_lock = NULL; + } } /** @@ -303,13 +360,8 @@ int lua_loadMusic(lua_State* L, int read_only) { int music_choose(char* situation) { if(music_disabled) return 0; - lua_getglobal(music_lua, "choose"); - lua_pushstring(music_lua, situation); - if(lua_pcall(music_lua, 1, 0, 0)) { - /* Error occured. */ - WARN("Error while choosing music: %s", (char*)lua_tostring(music_lua, -1)); - return -1; - } + music_runLua(situation); + return 0; } @@ -317,9 +369,15 @@ int music_choose(char* situation) { * @fn static void music_rechoose(void) * * @brief Attempts to rechoose the music. + * + * ARGH! DO NOT CALL MIX_* FUNCTIONS FROM WITHIN THE CALLBACKS! */ static void music_rechoose(void) { - music_choose("idle"); + /* Lock so it doesn't run in between an update. */ + SDL_mutexP(music_lock); + music_runchoose = 1; + strncpy(music_situation, "idle", PATH_MAX); + SDL_mutexV(music_lock); } /* The music lua functions. */ diff --git a/src/music.h b/src/music.h index 6c15edb..b02519f 100644 --- a/src/music.h +++ b/src/music.h @@ -3,9 +3,8 @@ extern int music_disabled; -/* Thread. */ -int music_thread(void* unused); -void music_kill(void); +/* Updating. */ +void music_update(void); /* Init/Exit. */ int music_init(void); diff --git a/src/sound.c b/src/sound.c index 40eddd9..5837980 100644 --- a/src/sound.c +++ b/src/sound.c @@ -345,6 +345,9 @@ int sound_updatePos(int voice, double x, double y) { int sound_update(void) { alVoice* v, *tv; + /* Update music if needed. */ + music_update(); + if(sound_disabled) return 0; if(voice_active == NULL) return 0; @@ -627,6 +630,8 @@ void sound_stopGroup(int group) { * @fn static void voice_markStopped(int channel) * * @brief Mark the voice to which channel belongs to as stopped. + * + * URGH! DO NOT CALL MIX_* FUNCTIONS FROM CALLBACKS! */ static void voice_markStopped(int channel) { alVoice* v;