diff --git a/audio.c b/audio.c index a9faba1..169886e 100644 --- a/audio.c +++ b/audio.c @@ -1,14 +1,30 @@ #include #include +void audioCallback(void *userdata, uint8_t *stream, int len) { + AudioContext *aud; + SDL_assert(len == 834 * 4); + + aud = userdata; + if (!aud->filled) { + /* too little data, play silence */ + SDL_memset4(stream, 0, 834); + return; + } + SDL_memcpy4(stream, aud->buffers[aud->current], 834); + ++aud->current; + aud->current %= 2; + aud->filled -= 1; +} + int audioInit(AudioContext *aud) { SDL_AudioSpec spec; spec.freq = 41700; spec.format = AUDIO_S16; spec.channels = 2; - spec.samples = 1024; - spec.callback = NULL; - spec.userdata = NULL; + spec.samples = 834; + spec.callback = &audioCallback; + spec.userdata = aud; aud->id = SDL_OpenAudioDevice(NULL, 0, &spec, NULL, 0); aud->paused = true; @@ -16,21 +32,34 @@ int audioInit(AudioContext *aud) { fprintf(stderr, "could not open audio device: %s\n", SDL_GetError()); return -1; } + aud->current = 0; + aud->filled = 0; return 0; } int audioUpdate(AudioContext *aud, void *data, uint32_t bytes) { + int filled; if (!aud->id) return -1; + SDL_assert(bytes == 834 * 4); - if (SDL_QueueAudio(aud->id, data, bytes)) { - fprintf(stderr, "could not write audio: %s\n", SDL_GetError()); - return -1; + SDL_LockAudioDevice(aud->id); + if (aud->filled < 2) { + int next = (aud->current + aud->filled) % 2; + SDL_memcpy4(aud->buffers[next], data, bytes / 4); + aud->filled += 1; } + filled = aud->filled; + SDL_UnlockAudioDevice(aud->id); if (aud->paused) { SDL_PauseAudioDevice(aud->id, false); aud->paused = false; } + while (filled > 1) { + SDL_Delay(0); + filled = aud->filled; + } + return 0; } \ No newline at end of file diff --git a/audio.h b/audio.h index 075239a..644724f 100644 --- a/audio.h +++ b/audio.h @@ -7,6 +7,9 @@ typedef struct { SDL_AudioDeviceID id; bool paused; + uint32_t buffers[2][834]; + int current; + int filled; } AudioContext; int audioInit(AudioContext *aud); diff --git a/game.c b/game.c index b818d75..2a93bf5 100644 --- a/game.c +++ b/game.c @@ -6,19 +6,6 @@ #include #include -int sleepNanos(long int ns) { - struct timespec time; - if (ns < 0) return 0; - time.tv_sec = ns / 1000000000; - time.tv_nsec = ns % 1000000000; - return nanosleep(&time, NULL); -} -long int tickNs() { - struct timespec time; - clock_gettime(CLOCK_MONOTONIC, &time); - return (time.tv_sec * 1000000000) + time.tv_nsec; -} - typedef struct { GraphicsContext *gfx; AudioContext aud; @@ -52,7 +39,6 @@ int runGame(VB *sim, GraphicsContext *gfx) { SDL_Event event; GameState state; ControllerState ctrl; - uint64_t ticks, prevTicks; state.gfx = gfx; audioInit(&state.aud); @@ -67,10 +53,7 @@ int runGame(VB *sim, GraphicsContext *gfx) { while (1) { clocks = MAX_STEP_CLOCKS; - prevTicks = tickNs(); vbEmulate(sim, &clocks); - ticks = tickNs(); - sleepNanos(((MAX_STEP_CLOCKS - clocks) * 50) - (ticks - prevTicks)); while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) { diff --git a/makefile b/makefile index b1f6bd9..71115dc 100644 --- a/makefile +++ b/makefile @@ -28,17 +28,15 @@ output/%.o: %.c @mkdir -p output @$(CC) -c -o $@ $< -I . \ -I shrooms-vb-core/core $(SDL2FLAGS) \ - -D _POSIX_C_SOURCE=199309L \ -O3 -flto -fno-strict-aliasing \ - -Werror -std=c11 -Wall -Wextra -Wpedantic + -Werror -std=c90 -Wall -Wextra -Wpedantic output/vb.o: shrooms-vb-core/core/vb.c @mkdir -p output @$(CC) -c -o $@ $< -I . \ -I shrooms-vb-core/core $(SDL2FLAGS) \ - -D _POSIX_C_SOURCE=199309L \ -O3 -flto -fno-strict-aliasing \ - -Werror -std=c11 -Wall -Wextra -Wpedantic + -Werror -std=c90 -Wall -Wextra -Wpedantic output/%.o: assets/%.bin @mkdir -p output