#include <stdlib.h>
#include <string.h>
#include <pthread.h>
-#include <semaphore.h>
#include <assert.h>
#include <unistd.h> //pread
#include <curses.h>
#endif
+#include "ux_sema.h"
#include "ux_frotz.h"
#include "ux_audio.h"
f_setup_t f_setup;
-sem_t sound_done; /* 1 if the sound is done */
+ux_sem_t sound_done; /* 1 if the sound is done */
#ifndef NO_SOUND
sound_state_t voices[NUM_VOICES]; /* Max concurrent sound effects/music*/
/*Event (one is process per frame of audio)*/
- sem_t ev_free; /*1 if an event can be submitted*/
- sem_t ev_pending; /*1 if there's an event ready to be processed*/
+ ux_sem_t ev_free; /*1 if an event can be submitted*/
+ ux_sem_t ev_pending; /*1 if there's an event ready to be processed*/
sound_event_t event;
} sound_engine_t;
{
int i;
/*Handle event*/
- if(sem_trywait(&e->ev_pending) == 0) {
+ if(ux_sem_trywait(&e->ev_pending) == 0) {
if(e->event.type == EVENT_START_STREAM)
sound_enqueue_real(e,e->event.e);
else if(e->event.type == EVENT_STOP_STREAM)
sound_stop_id_real(e,e->event.i);
- sem_post(&e->ev_free);
+ ux_sem_post(&e->ev_free);
}
/*Start out with an empty buffer*/
sound->cleanup(sound);
free(sound);
e->streams[i] = NULL;
- sem_post(&sound_done);
+ ux_sem_post(&sound_done);
}
}
}
static void
sound_stop_id(int id)
{
- sem_wait(&frotz_audio.ev_free);
+ ux_sem_wait(&frotz_audio.ev_free);
frotz_audio.event.type = EVENT_STOP_STREAM;
frotz_audio.event.i = id;
- sem_post(&frotz_audio.ev_pending);
+ ux_sem_post(&frotz_audio.ev_pending);
}
static void
static void
sound_enqueue(sound_stream_t *s)
{
- sem_wait(&frotz_audio.ev_free);
+ ux_sem_wait(&frotz_audio.ev_free);
frotz_audio.event.type = EVENT_START_STREAM;
frotz_audio.event.e = s;
- sem_post(&frotz_audio.ev_pending);
+ ux_sem_post(&frotz_audio.ev_pending);
}
static void
frotz_audio.voices[i].active = 0;
/*No events registered on startup*/
- sem_init(&frotz_audio.ev_free, 0, 1);
- sem_init(&frotz_audio.ev_pending, 0, 0);
- sem_init(&sound_done, 0, 0);
+ ux_sem_init(&frotz_audio.ev_free, 0, 1);
+ ux_sem_init(&frotz_audio.ev_pending, 0, 0);
+ ux_sem_init(&sound_done, 0, 0);
frotz_audio.event.type = 0;
/*Start audio thread*/
--- /dev/null
+/*
+ * ux_sema.h - semaphore abstraction for frotz
+ *
+ * This file is part of Frotz.
+ *
+ * Frotz is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Frotz is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ * Or visit http://www.fsf.org/
+ *
+ * This file and only this file is dual licensed under the MIT license.
+ *
+ */
+
+/*
+ * For anything other than MAC OS X, this is a simple wrapper for unnamed
+ * POSIX Semaphores. For MAC OS X use the Grand Central Dispatch as suggested
+ * at https://stackoverflow.com/questions/27736618/why-are-sem-init-sem-getvalue-sem-destroy-deprecated-on-mac-os-x-and-w
+ */
+
+#ifdef MACOS
+#include <dispatch/dispatch.h>
+struct ux_sema {
+ dispatch_semaphore_t dsem;
+};
+typedef struct ux_sema ux_sem_t;
+
+/*
+ * Note that the current implementation does not check return codes
+ * so use void to make things simpler on the MAC side
+ */
+static inline void ux_sem_init(ux_sem_t *sem, int pshared, unsigned int value)
+{
+ dispatch_semaphore_t *sema = &sem->dsem;
+ (void) pshared;
+
+ *sema = dispatch_semaphore_create(value);
+}
+
+static inline void ux_sem_post(ux_sem_t *sem)
+{
+ dispatch_semaphore_signal(sem->dsem);
+}
+
+static inline void ux_sem_wait(ux_sem_t *sem)
+{
+ dispatch_semaphore_wait(sem->dsem, DISPATCH_TIME_FOREVER);
+}
+
+static inline int ux_sem_trywait(ux_sem_t *sem)
+{
+ return (int) dispatch_semaphore_wait(sem->dsem, DISPATCH_TIME_NOW);
+}
+#else
+#include <semaphore.h>
+typedef sem_t ux_sem_t;
+
+/*
+ * Note that the current implementation does not check return codes
+ * so use void to make things simpler on the MAC side
+ */
+static inline void ux_sem_init(ux_sem_t *sem, int pshared, unsigned int value)
+{
+ (void) sem_init(sem, pshared, value);
+}
+
+static inline void ux_sem_post(ux_sem_t *sem)
+{
+ (void) sem_post(sem);
+}
+
+static inline void ux_sem_wait(ux_sem_t *sem)
+{
+ (void) sem_wait(sem);
+}
+
+static inline int ux_sem_trywait(ux_sem_t *sem)
+{
+ return sem_trywait(sem);
+}
+#endif