OVR: Change the way to walk and rotate with the controller
[mercenary-reloaded.git] / src / libsdl / sdl.c
index d7e96ce..804695c 100644 (file)
@@ -21,8 +21,8 @@
 #include <stdint.h>
 #include <errno.h>
 #include "print.h"
+#include "../../include/keycodes.h"
 #include "sdl.h"
-#include "opengl.h"
 
 #include <SDL2/SDL.h>
 #define GL3_PROTOTYPES 1
@@ -30,6 +30,8 @@
 
 static int sdl_initialized = 0;
 static int audio_initialized = 0;
+static const char *device_string = NULL;
+static SDL_AudioDeviceID audio_devid = 0;
 static SDL_Window *gl_window = NULL;
 static SDL_GLContext gl_context = NULL;
 static void (*keyboard_sdl)(int down, enum keycode keycode) = NULL;
@@ -42,10 +44,10 @@ static void audio_cb(void __attribute__((unused)) *userdata, Uint8 *stream, int
 
        SDL_memset(stream, 0, len);
        audio_sdl(audio_data, len / sizeof(float) / 2);
-       SDL_MixAudio(stream, (Uint8 *)audio_data, len, SDL_MIX_MAXVOLUME);
+       SDL_MixAudioFormat(stream, (Uint8 *)audio_data, AUDIO_F32, len, SDL_MIX_MAXVOLUME / 2.0);
 }
 
-int init_sdl(const char *progname, int width, int height, int sound_samplerate, int sound_chunk, void (*keyboard)(int down, enum keycode keycode), void (*audio)(float *data, int len), void (*resize_window)(int width, int height), int multisampling, int vbl_sync)
+int init_sdl(const char *progname, int width, int height, int sound_samplerate, int sound_chunk, void (*keyboard)(int down, enum keycode keycode), void (*audio)(float *data, int len), void (*resize_window)(int width, int height), int multisampling, int vbl_sync, int rift)
 {
        int rc;
 
@@ -61,7 +63,8 @@ int init_sdl(const char *progname, int width, int height, int sound_samplerate,
        }
        sdl_initialized = 1;
 
-       if (multisampling) {
+retry_without_multisampling:
+       if (multisampling > 1) {
                SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
                SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
                SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
@@ -74,7 +77,16 @@ int init_sdl(const char *progname, int width, int height, int sound_samplerate,
        /* open window */
        gl_window = SDL_CreateWindow(progname, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
        if (!gl_window) {
-               print_error("Failed to open SDL window: %s (try without multisampling)\n", SDL_GetError());
+               if (multisampling) {
+                       print_info("Failed to open SDL window: %s (retrying without multisampling)\n", SDL_GetError());
+                       SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
+                       SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
+                       multisampling = 0;
+                       goto retry_without_multisampling;
+               }
+               print_error("Failed to open SDL window: %s\n", SDL_GetError());
+               SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
+               SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, multisampling);
                rc = EIO;
                goto error;
        }
@@ -130,9 +142,22 @@ int init_sdl(const char *progname, int width, int height, int sound_samplerate,
        /* just in case */
        glDisable(GL_DEPTH_TEST);
        glDisable(GL_CULL_FACE);
-       if (multisampling)
+       if (multisampling > 1)
                glEnable(GL_MULTISAMPLE);
 
+       if (rift) {
+               int i, count;
+               count = SDL_GetNumAudioDevices(0);
+               const char *string;
+               for(i = 0; i < count; i++) {
+                       string = SDL_GetAudioDeviceName(i, 0);
+                       if (strstr(string, "Rift"))
+                               device_string = string;
+               }
+               if (!device_string)
+                       print_error("Oculus Rift headset not found, falling back to default audio device.\n");
+       }
+
        /* open audio */
        SDL_AudioSpec want, have;
        SDL_memset(&want, 0, sizeof(want)); /* or SDL_zero(want) */
@@ -141,27 +166,25 @@ int init_sdl(const char *progname, int width, int height, int sound_samplerate,
        want.channels = 2;
        want.samples = sound_chunk; /* must be a power of two */
        want.callback = audio_cb;
-       rc = SDL_OpenAudio(&want, &have);
-       if (rc < 0) {
+       audio_devid = SDL_OpenAudioDevice(device_string, 0, &want, &have, SDL_AUDIO_ALLOW_ANY_CHANGE);
+       if (audio_devid <= 0) {
                print_error("Failed to open audio! (No speaker connected?)\n");
+               rc = -EIO;
                goto error;
        } else if (have.format != want.format) {
-               print_error("Failed to open audio with desired audio format\n");
-               SDL_CloseAudio();
+               print_error("Failed to open audio with desired audio format (want %d, got %d)\n", want.format, have.format);
                rc = -EIO;
                goto error;
        } else if (have.freq != want.freq) {
-               print_error("Failed to open audio with desired sample rate\n");
-               SDL_CloseAudio();
+               print_error("Failed to open audio with desired sample rate (want %d, got %d)\n", want.freq, have.freq);
                rc = -EIO;
                goto error;
        } else if (have.channels != want.channels) {
-               print_error("Failed to open audio with desired channels (got %d)\n", have.channels);
-               SDL_CloseAudio();
+               print_error("Failed to open audio with desired number of channels (want %d, got %d)\n", want.channels, have.channels);
                rc = -EIO;
                goto error;
        } else {
-               SDL_PauseAudio(0);
+               SDL_PauseAudioDevice(audio_devid, 0);
                audio_initialized = 1;
        }
 
@@ -179,6 +202,8 @@ static enum keycode sdl2keycode(SDL_Keycode sym)
        case SDLK_RCTRL: return KEYCODE_RCTRL;
        case SDLK_LSHIFT: return KEYCODE_LSHIFT;
        case SDLK_RSHIFT: return KEYCODE_RSHIFT;
+       case SDLK_LALT: return KEYCODE_LALT;
+       case SDLK_RALT: return KEYCODE_RALT;
        case SDLK_PAUSE: return KEYCODE_PAUSE;
        case SDLK_LEFT: return KEYCODE_LEFT;
        case SDLK_RIGHT: return KEYCODE_RIGHT;
@@ -236,6 +261,7 @@ static enum keycode sdl2keycode(SDL_Keycode sym)
        case SDLK_KP_MINUS: return KEYCODE_KP_MINUS;
        case SDLK_KP_PLUS: return KEYCODE_KP_PLUS;
        case SDLK_KP_PERIOD: return KEYCODE_KP_PERIOD;
+       case SDLK_KP_ENTER: return KEYCODE_KP_ENTER;
        case SDLK_F1: return KEYCODE_F1;
        case SDLK_F2: return KEYCODE_F2;
        case SDLK_F3: return KEYCODE_F3;
@@ -249,11 +275,12 @@ static enum keycode sdl2keycode(SDL_Keycode sym)
        case SDLK_SPACE: return KEYCODE_SPACE;
        case SDLK_BACKSPACE: return KEYCODE_BACKSPACE;
        case SDLK_TAB: return KEYCODE_TAB;
-       case SDLK_KP_ENTER: return KEYCODE_KP_ENTER;
        case SDLK_RETURN: return KEYCODE_RETURN;
        case SDLK_ESCAPE: return KEYCODE_ESCAPE;
        case SDLK_DELETE: return KEYCODE_DELETE;
        case SDLK_INSERT: return KEYCODE_INSERT;
+       case SDLK_COMMA: return KEYCODE_COMMA;
+       case SDLK_PERIOD: return KEYCODE_PERIOD;
        default: return KEYCODE_UNDEFINED;
        }
 }
@@ -333,10 +360,13 @@ void exit_sdl(void)
 
        /* exit SDL library */
        if (audio_initialized) {
-               SDL_PauseAudio(1);
-               SDL_CloseAudio();
+               SDL_PauseAudioDevice(audio_devid, 1);
                audio_initialized = 0;
        }
+       if (audio_devid > 0) {
+               SDL_CloseAudioDevice(audio_devid);
+               audio_devid = 0;
+       }
        if (sdl_initialized) {
                SDL_Quit();
                sdl_initialized = 0;