static SDL_AudioDeviceID audio_devid = 0;
static SDL_Window *gl_window = NULL;
static SDL_GLContext gl_context = NULL;
+static SDL_Joystick *sdl_joystick = NULL;
static void (*keyboard_sdl)(int down, enum keycode keycode) = NULL;
+static void (*joystick_sdl)(double x, double y, int fire) = NULL;
static void (*audio_sdl)(float *data, int len) = NULL;
static void (*resize_window_sdl)(int width, int height) = NULL;
+static int joystick_y_axis_sdl = 1, joystick_x_axis_sdl = 0, joystick_fire_button_sdl = -1;
static void audio_cb(void __attribute__((unused)) *userdata, Uint8 *stream, int len)
{
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 rift)
+void sdl_list_joysticks(void)
{
- int rc;
+ int num, i, rc;
+
+ rc = SDL_Init(SDL_INIT_JOYSTICK);
+ if (rc < 0) {
+ print_error("Failed to init SDL\n");
+ return;
+ }
+
+ num = SDL_NumJoysticks();
+ for (i = 0; i < num; i++)
+ printf("#%d: %s\n", i, SDL_JoystickNameForIndex(i));
+
+ SDL_Quit();
+}
+
+int init_sdl(const char *progname, int width, int height, int sound_samplerate, int sound_chunk, void (*keyboard)(int down, enum keycode keycode), int joysticknum, int joystick_x_axis, int joystick_y_axis, int joystick_fire_button, void (*joystick)(double x, double y, int fire), void (*audio)(float *data, int len), void (*resize_window)(int width, int height), int multisampling, int vbl_sync, int rift)
+{
+ int rc = -EINVAL;
keyboard_sdl = keyboard;
+ joystick_sdl = joystick;
audio_sdl = audio;
resize_window_sdl = resize_window;
+ if (joystick_x_axis >= 0)
+ joystick_x_axis_sdl = joystick_x_axis;
+ if (joystick_y_axis >= 0)
+ joystick_y_axis_sdl = joystick_y_axis;
+ if (joystick_fire_button >= 0)
+ joystick_fire_button_sdl = joystick_fire_button;
/* init SDL library */
- rc = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
+ rc = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK);
if (rc < 0) {
print_error("Failed to init SDL\n");
goto error;
}
sdl_initialized = 1;
+ SDL_JoystickEventState(SDL_ENABLE);
+ sdl_joystick = SDL_JoystickOpen((joysticknum < 0) ? 0 : joysticknum);
+ if (!sdl_joystick && joysticknum >= 0) {
+ rc = -EIO;
+ print_error("Failed to open joystick #%d, see help!\n", joysticknum);
+ goto error;
+ }
+
retry_without_multisampling:
if (multisampling > 1) {
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
}
}
+static double joystick_x = 0, joystick_y = 0;
+static int joystick_fire = 0;
+
+static void joystick_event(int axis, int value)
+{
+ double v = (double)value / 32767.0;
+
+ switch (axis) {
+ case 0: joystick_y = v; break;
+ case 1: joystick_x = v; break;
+ case 2: joystick_fire = value; break;
+ }
+
+ joystick_sdl(joystick_x, joystick_y, joystick_fire);
+}
+
static int key_ctrl = 0, key_f = 0, fullscreen = 0;
int event_sdl(void)
SDL_Event event;
while (SDL_PollEvent(&event)) {
- if (event.type == SDL_QUIT)
+ switch (event.type) {
+ case SDL_QUIT:
quit = 1;
- if (event.type == SDL_WINDOWEVENT) {
+ break;
+ case SDL_WINDOWEVENT:
if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
resize_window_sdl(event.window.data1, event.window.data2);
- }
- if (event.type == SDL_KEYDOWN) {
+ break;
+ case SDL_KEYDOWN:
switch (event.key.keysym.sym) {
case SDLK_f:
if (key_ctrl && !key_f) {
break;
}
keyboard_sdl(1, sdl2keycode(event.key.keysym.sym));
- }
- if (event.type == SDL_KEYUP) {
+ break;
+ case SDL_KEYUP:
switch (event.key.keysym.sym) {
case SDLK_LCTRL:
case SDLK_RCTRL:
break;
}
keyboard_sdl(0, sdl2keycode(event.key.keysym.sym));
+ break;
+ case SDL_JOYAXISMOTION:
+ if (event.jaxis.axis == joystick_y_axis_sdl)
+ joystick_event(0, event.jaxis.value);
+ if (event.jaxis.axis == joystick_x_axis_sdl)
+ joystick_event(1, event.jaxis.value);
+ break;
+ case SDL_JOYBUTTONDOWN:
+ if (joystick_fire_button_sdl < 0 || event.jbutton.button == joystick_fire_button_sdl)
+ joystick_event(2, 1);
+ break;
+ case SDL_JOYBUTTONUP:
+ if (joystick_fire_button_sdl < 0 || event.jbutton.button == joystick_fire_button_sdl)
+ joystick_event(2, 0);
+ break;
}
}
void exit_sdl(void)
{
+ /* close joystick */
+ if (sdl_joystick) {
+ SDL_JoystickClose(sdl_joystick);
+ sdl_joystick = NULL;
+ }
/* close window */
if (gl_window) {
SDL_DestroyWindow(gl_window);