#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
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;
static void (*audio_sdl)(float *data, int len) = NULL;
+static void (*resize_window_sdl)(int width, int height) = NULL;
static void audio_cb(void __attribute__((unused)) *userdata, Uint8 *stream, int len)
{
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), int multisampling)
+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;
keyboard_sdl = keyboard;
audio_sdl = audio;
+ resize_window_sdl = resize_window;
/* init SDL library */
rc = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
}
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);
/* 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;
}
goto error;
}
- rc = SDL_GL_SetSwapInterval(1);
+ rc = SDL_GL_SetSwapInterval((vbl_sync) ? 1 : 0);
if (rc < 0) {
print_error("Failed to set SDL's OpenGL swap interval to VBLANK\n");
// continue anyway
}
+// seems like a hack to me. do we need this?
#ifndef __APPLE__
+#if !defined(_WIN32)
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) {
print_error("Failed to init GLEW\n");
goto error;
}
#endif
+#endif
/* 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) */
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;
}
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;
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;
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;
}
}
quit = 1;
if (event.type == SDL_WINDOWEVENT) {
if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
- resize_opengl(event.window.data1, event.window.data2);
+ resize_window_sdl(event.window.data1, event.window.data2);
}
if (event.type == SDL_KEYDOWN) {
switch (event.key.keysym.sym) {
/* 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;