diff --git a/Makefile b/Makefile index 430d017ae0..b1e6156f74 100644 --- a/Makefile +++ b/Makefile @@ -9,13 +9,16 @@ ifeq ($(BUILD_RSOUND), 1) SOURCE += rsound.c LIBS += -lrsound endif +ifeq ($(BUILD_OSS), 1) + SOURCE += oss.c +endif ifeq ($(BUILD_OPENGL), 1) SOURCE += gl.c LIBS += -lglfw endif -CFLAGS = -Wall -O3 -march=native +CFLAGS = -Wall -O2 -march=native -s OBJ = ssnes.o diff --git a/config.h b/config.h index a0bc0db53a..3e1d3d09ac 100644 --- a/config.h +++ b/config.h @@ -18,9 +18,10 @@ //////////// Drivers #define VIDEO_GL 0 #define AUDIO_RSOUND 1 +#define AUDIO_OSS 2 #define VIDEO_DRIVER VIDEO_GL -#define AUDIO_DRIVER AUDIO_RSOUND +#define AUDIO_DRIVER AUDIO_OSS static const bool force_aspect = true; // On resize and fullscreen, rendering area will stay 8:7 diff --git a/oss.c b/oss.c new file mode 100644 index 0000000000..bfc36e144c --- /dev/null +++ b/oss.c @@ -0,0 +1,109 @@ +#include "driver.h" +#include +#include +#include +#include +#include + +static void* __oss_init(const char* device, int rate, int latency) +{ + int *fd = calloc(1, sizeof(int)); + if ( fd == NULL ) + return NULL; + + const char *oss_device = "/dev/dsp"; + + if ( device != NULL ) + oss_device = device; + + if ( (*fd = open(oss_device, O_WRONLY)) < 0 ) + { + free(fd); + return NULL; + } + + int frags = (latency * rate * 4)/(1000 * (1 << 9)); + int frag = (frags << 16) | 9; + + if ( ioctl(*fd, SNDCTL_DSP_SETFRAGMENT, &frag) < 0 ) + { + close(*fd); + free(fd); + return NULL; + } + + int channels = 2; + int format = AFMT_S16_LE; + + if ( ioctl(*fd, SNDCTL_DSP_CHANNELS, &channels) < 0 ) + { + close(*fd); + free(fd); + return NULL; + } + + if ( ioctl(*fd, SNDCTL_DSP_SETFMT, &format) < 0 ) + { + close(*fd); + free(fd); + return NULL; + } + + if ( ioctl(*fd, SNDCTL_DSP_SPEED, &rate) < 0 ) + { + close(*fd); + free(fd); + return NULL; + } + + return fd; +} + +static ssize_t __oss_write(void* data, const void* buf, size_t size) +{ + int *fd = data; + + if ( size == 0 ) + return 0; + + ssize_t ret; + if ( (ret = write(*fd, buf, size)) <= 0 ) + return -1; + + return ret; +} + +static bool __oss_stop(void *data) +{ + int *fd = data; + ioctl(*fd, SNDCTL_DSP_RESET, 0); + return true; +} + +static bool __oss_start(void *data) +{ + return true; +} + +static void __oss_free(void *data) +{ + int *fd = data; + + ioctl(*fd, SNDCTL_DSP_RESET, 0); + close(*fd); + free(fd); +} + +const audio_driver_t audio_oss = { + .init = __oss_init, + .write = __oss_write, + .stop = __oss_stop, + .start = __oss_start, + .free = __oss_free +}; + + + + + + diff --git a/ssnes.c b/ssnes.c index d6d01544b7..29f9a6f7c9 100644 --- a/ssnes.c +++ b/ssnes.c @@ -16,6 +16,7 @@ static SRC_STATE* source = NULL; //////////////////////////////////////////////// Backends extern const audio_driver_t audio_rsound; +extern const audio_driver_t audio_oss; extern const video_driver_t video_gl; //////////////////////////////////////////////// @@ -24,7 +25,9 @@ static driver_t driver = { .video = &video_gl, #endif #if AUDIO_DRIVER == AUDIO_RSOUND - .audio = &audio_rsound + .audio = &audio_rsound, +#elif AUDIO_DRIVER == AUDIO_OSS + .audio = &audio_oss, #endif }; @@ -204,13 +207,13 @@ int main(int argc, char *argv[]) void *rom_buf = malloc(length); if ( rom_buf == NULL ) { - fprintf(stderr, "Couldn't allocate memory!\n"); + fprintf(stderr, "SSNES [ERROR] :: Couldn't allocate memory!\n"); exit(1); } if ( fread(rom_buf, 1, length, file) < length ) { - fprintf(stderr, "Didn't read whole file.\n"); + fprintf(stderr, "SSNES [ERROR] :: Didn't read whole file.\n"); exit(1); } @@ -268,7 +271,7 @@ static void write_state(const char* path, uint8_t* data, size_t size) FILE *file = fopen(path, "wb"); if ( file != NULL ) { - fprintf(stderr, "SSNES: Saving state. Size: %d bytes.\n", (int)size); + //fprintf(stderr, "SSNES: Saving state. Size: %d bytes.\n", (int)size); snes_serialize(data, size); if ( fwrite(data, 1, size, file) != size ) fprintf(stderr, "SSNES [WARN]: Did not save state properly."); @@ -281,7 +284,7 @@ static void load_state(const char* path, uint8_t* data, size_t size) FILE *file = fopen(path, "rb"); if ( file != NULL ) { - fprintf(stderr, "SSNES: Loading state. Size: %d bytes.\n", (int)size); + //fprintf(stderr, "SSNES: Loading state. Size: %d bytes.\n", (int)size); if ( fread(data, 1, size, file) != size ) fprintf(stderr, "SSNES [WARN]: Did not load state properly."); fclose(file);