Drive gameplay with audio instead of timer
This commit is contained in:
		
							parent
							
								
									3d2c6cbddf
								
							
						
					
					
						commit
						a479d3c0b3
					
				
							
								
								
									
										41
									
								
								audio.c
								
								
								
								
							
							
						
						
									
										41
									
								
								audio.c
								
								
								
								
							| 
						 | 
					@ -1,14 +1,30 @@
 | 
				
			||||||
#include <audio.h>
 | 
					#include <audio.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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) {
 | 
					int audioInit(AudioContext *aud) {
 | 
				
			||||||
    SDL_AudioSpec spec;
 | 
					    SDL_AudioSpec spec;
 | 
				
			||||||
    spec.freq = 41700;
 | 
					    spec.freq = 41700;
 | 
				
			||||||
    spec.format = AUDIO_S16;
 | 
					    spec.format = AUDIO_S16;
 | 
				
			||||||
    spec.channels = 2;
 | 
					    spec.channels = 2;
 | 
				
			||||||
    spec.samples = 1024;
 | 
					    spec.samples = 834;
 | 
				
			||||||
    spec.callback = NULL;
 | 
					    spec.callback = &audioCallback;
 | 
				
			||||||
    spec.userdata = NULL;
 | 
					    spec.userdata = aud;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    aud->id = SDL_OpenAudioDevice(NULL, 0, &spec, NULL, 0);
 | 
					    aud->id = SDL_OpenAudioDevice(NULL, 0, &spec, NULL, 0);
 | 
				
			||||||
    aud->paused = true;
 | 
					    aud->paused = true;
 | 
				
			||||||
| 
						 | 
					@ -16,21 +32,34 @@ int audioInit(AudioContext *aud) {
 | 
				
			||||||
        fprintf(stderr, "could not open audio device: %s\n", SDL_GetError());
 | 
					        fprintf(stderr, "could not open audio device: %s\n", SDL_GetError());
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    aud->current = 0;
 | 
				
			||||||
 | 
					    aud->filled = 0;
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int audioUpdate(AudioContext *aud, void *data, uint32_t bytes) {
 | 
					int audioUpdate(AudioContext *aud, void *data, uint32_t bytes) {
 | 
				
			||||||
 | 
					    int filled;
 | 
				
			||||||
    if (!aud->id) return -1;
 | 
					    if (!aud->id) return -1;
 | 
				
			||||||
 | 
					    SDL_assert(bytes == 834 * 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (SDL_QueueAudio(aud->id, data, bytes)) {
 | 
					    SDL_LockAudioDevice(aud->id);
 | 
				
			||||||
        fprintf(stderr, "could not write audio: %s\n", SDL_GetError());
 | 
					    if (aud->filled < 2) {
 | 
				
			||||||
        return -1;
 | 
					        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) {
 | 
					    if (aud->paused) {
 | 
				
			||||||
        SDL_PauseAudioDevice(aud->id, false);
 | 
					        SDL_PauseAudioDevice(aud->id, false);
 | 
				
			||||||
        aud->paused = false;
 | 
					        aud->paused = false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (filled > 1) {
 | 
				
			||||||
 | 
					        SDL_Delay(0);
 | 
				
			||||||
 | 
					        filled = aud->filled;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										3
									
								
								audio.h
								
								
								
								
							
							
						
						
									
										3
									
								
								audio.h
								
								
								
								
							| 
						 | 
					@ -7,6 +7,9 @@
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
    SDL_AudioDeviceID id;
 | 
					    SDL_AudioDeviceID id;
 | 
				
			||||||
    bool paused;
 | 
					    bool paused;
 | 
				
			||||||
 | 
					    uint32_t buffers[2][834];
 | 
				
			||||||
 | 
					    int current;
 | 
				
			||||||
 | 
					    int filled;
 | 
				
			||||||
} AudioContext;
 | 
					} AudioContext;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int audioInit(AudioContext *aud);
 | 
					int audioInit(AudioContext *aud);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										17
									
								
								game.c
								
								
								
								
							
							
						
						
									
										17
									
								
								game.c
								
								
								
								
							| 
						 | 
					@ -6,19 +6,6 @@
 | 
				
			||||||
#include <stdbool.h>
 | 
					#include <stdbool.h>
 | 
				
			||||||
#include <time.h>
 | 
					#include <time.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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 {
 | 
					typedef struct {
 | 
				
			||||||
    GraphicsContext *gfx;
 | 
					    GraphicsContext *gfx;
 | 
				
			||||||
    AudioContext aud;
 | 
					    AudioContext aud;
 | 
				
			||||||
| 
						 | 
					@ -52,7 +39,6 @@ int runGame(VB *sim, GraphicsContext *gfx) {
 | 
				
			||||||
    SDL_Event event;
 | 
					    SDL_Event event;
 | 
				
			||||||
    GameState state;
 | 
					    GameState state;
 | 
				
			||||||
    ControllerState ctrl;
 | 
					    ControllerState ctrl;
 | 
				
			||||||
    uint64_t ticks, prevTicks;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    state.gfx = gfx;
 | 
					    state.gfx = gfx;
 | 
				
			||||||
    audioInit(&state.aud);
 | 
					    audioInit(&state.aud);
 | 
				
			||||||
| 
						 | 
					@ -67,10 +53,7 @@ int runGame(VB *sim, GraphicsContext *gfx) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while (1) {
 | 
					    while (1) {
 | 
				
			||||||
        clocks = MAX_STEP_CLOCKS;
 | 
					        clocks = MAX_STEP_CLOCKS;
 | 
				
			||||||
        prevTicks = tickNs();
 | 
					 | 
				
			||||||
        vbEmulate(sim, &clocks);
 | 
					        vbEmulate(sim, &clocks);
 | 
				
			||||||
        ticks = tickNs();
 | 
					 | 
				
			||||||
        sleepNanos(((MAX_STEP_CLOCKS - clocks) * 50) - (ticks - prevTicks));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        while (SDL_PollEvent(&event)) {
 | 
					        while (SDL_PollEvent(&event)) {
 | 
				
			||||||
            if (event.type == SDL_QUIT) {
 | 
					            if (event.type == SDL_QUIT) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										6
									
								
								makefile
								
								
								
								
							
							
						
						
									
										6
									
								
								makefile
								
								
								
								
							| 
						 | 
					@ -28,17 +28,15 @@ output/%.o: %.c
 | 
				
			||||||
	@mkdir -p output
 | 
						@mkdir -p output
 | 
				
			||||||
	@$(CC) -c -o $@ $< -I . \
 | 
						@$(CC) -c -o $@ $< -I . \
 | 
				
			||||||
		-I shrooms-vb-core/core $(SDL2FLAGS) \
 | 
							-I shrooms-vb-core/core $(SDL2FLAGS) \
 | 
				
			||||||
		-D _POSIX_C_SOURCE=199309L \
 | 
					 | 
				
			||||||
		-O3 -flto -fno-strict-aliasing \
 | 
							-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
 | 
					output/vb.o: shrooms-vb-core/core/vb.c
 | 
				
			||||||
	@mkdir -p output
 | 
						@mkdir -p output
 | 
				
			||||||
	@$(CC) -c -o $@ $< -I . \
 | 
						@$(CC) -c -o $@ $< -I . \
 | 
				
			||||||
		-I shrooms-vb-core/core $(SDL2FLAGS) \
 | 
							-I shrooms-vb-core/core $(SDL2FLAGS) \
 | 
				
			||||||
		-D _POSIX_C_SOURCE=199309L \
 | 
					 | 
				
			||||||
		-O3 -flto -fno-strict-aliasing \
 | 
							-O3 -flto -fno-strict-aliasing \
 | 
				
			||||||
		-Werror -std=c11 -Wall -Wextra -Wpedantic
 | 
							-Werror -std=c90 -Wall -Wextra -Wpedantic
 | 
				
			||||||
 | 
					
 | 
				
			||||||
output/%.o: assets/%.bin
 | 
					output/%.o: assets/%.bin
 | 
				
			||||||
	@mkdir -p output
 | 
						@mkdir -p output
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue