shithub: choc

Download patch

ref: 7127f6c844ee24e3629f292a8301395111266a7e
parent: f37794b0e04ba617e2908f445858803abbf576e9
author: Simon Howard <fraggle@gmail.com>
date: Thu May 31 19:16:23 EDT 2007

Initial joystick support.

Subversion-branch: /trunk/chocolate-doom
Subversion-revision: 887

--- a/setup/Makefile.am
+++ b/setup/Makefile.am
@@ -10,6 +10,7 @@
     compatibility.c   compatibility.h           \
     configfile.c      configfile.h              \
     display.c         display.h                 \
+    joystick.c        joystick.h                \
     keyboard.c        keyboard.h                \
     m_argv.c          m_argv.h                  \
     mainmenu.c                                  \
@@ -17,6 +18,7 @@
     multiplayer.c     multiplayer.h             \
     sound.c           sound.h                   \
     execute.c         execute.h                 \
+    txt_joybinput.c   txt_joybinput.h           \
     txt_keyinput.c    txt_keyinput.h            \
     txt_mouseinput.c  txt_mouseinput.h
 
--- a/setup/configfile.c
+++ b/setup/configfile.c
@@ -50,6 +50,7 @@
 
 #include "compatibility.h"
 #include "display.h"
+#include "joystick.h"
 #include "keyboard.h"
 #include "mouse.h"
 #include "multiplayer.h"
@@ -136,11 +137,6 @@
 static int detailLevel = 0;
 static int usegamma = 0;
 
-static int usejoystick = 0;
-static int joybfire = 0;
-static int joybstrafe = 1;
-static int joybuse = 2;
-
 // dos specific options: these are unused but should be maintained
 // so that the config file can be shared between chocolate
 // doom and doom.exe
@@ -270,6 +266,11 @@
     {"player_name",                 &net_player_name,          DEFAULT_STRING, 0, 0},
 #endif
     {"video_driver",                &video_driver,             DEFAULT_STRING, 0, 0},
+    {"joystick_index",              &joystick_index, DEFAULT_INT, 0, 0},
+    {"joystick_x_axis",             &joystick_x_axis, DEFAULT_INT, 0, 0},
+    {"joystick_x_invert",           &joystick_x_invert, DEFAULT_INT, 0, 0},
+    {"joystick_y_axis",             &joystick_y_axis, DEFAULT_INT, 0, 0},
+    {"joystick_y_invert",           &joystick_y_invert, DEFAULT_INT, 0, 0},
 };
 
 static default_collection_t extra_defaults =
--- /dev/null
+++ b/setup/joystick.c
@@ -1,0 +1,111 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 2007 Simon Howard
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+
+#include <stdlib.h>
+
+#include "textscreen.h"
+#include "txt_joybinput.h"
+
+#include "joystick.h"
+
+// Joystick enable/disable
+
+int usejoystick = 0;
+
+// Button mappings
+
+int joybfire = 0;
+int joybstrafe = 1;
+int joybuse = 2;
+int joybspeed = 3;
+
+// Joystick to use, as an SDL joystick index:
+
+int joystick_index = -1;
+
+// Which joystick axis to use for horizontal movement, and whether to
+// invert the direction:
+
+int joystick_x_axis = 0;
+int joystick_x_invert = 0;
+
+// Which joystick axis to use for vertical movement, and whether to
+// invert the direction:
+
+int joystick_y_axis = 1;
+int joystick_y_invert = 0;
+
+static txt_button_t *joystick_button;
+
+static void SetJoystickButtonLabel(void)
+{
+    char *name;
+
+    name = "None set";
+
+    if (joystick_index >= 0 && joystick_index < SDL_NumJoysticks())
+    {
+        name = (char *) SDL_JoystickName(joystick_index);
+    }
+
+    TXT_SetButtonLabel(joystick_button, name);
+}
+
+void ConfigJoystick(void)
+{
+    txt_window_t *window;
+    txt_table_t *button_table;
+    txt_table_t *joystick_table;
+
+    SDL_Init(SDL_INIT_JOYSTICK);
+
+    window = TXT_NewWindow("Joystick configuration");
+
+    TXT_AddWidgets(window,
+                   TXT_NewCheckBox("Enable joystick", &usejoystick),
+                   joystick_table = TXT_NewTable(2),
+                   TXT_NewSeparator("Joystick buttons"),
+                   button_table = TXT_NewTable(2),
+                   NULL);
+
+    TXT_SetColumnWidths(joystick_table, 20, 15);
+
+    TXT_AddWidgets(joystick_table,
+                   TXT_NewLabel("Current joystick"),
+                   joystick_button = TXT_NewButton("zzzz"),
+                   NULL);
+
+    TXT_SetColumnWidths(button_table, 20, 15);
+
+    TXT_AddWidgets(button_table,
+                   TXT_NewLabel("Fire"),
+                   TXT_NewJoystickInput(&joybfire),
+                   TXT_NewLabel("Speed"),
+                   TXT_NewJoystickInput(&joybspeed),
+                   TXT_NewLabel("Use"),
+                   TXT_NewJoystickInput(&joybuse),
+                   TXT_NewLabel("Strafe"),
+                   TXT_NewJoystickInput(&joybstrafe),
+                   NULL);
+
+    SetJoystickButtonLabel();
+}
+
--- /dev/null
+++ b/setup/joystick.h
@@ -1,0 +1,40 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 2006 Simon Howard
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+
+#ifndef SETUP_JOYSTICK_H
+#define SETUP_JOYSTICK_H
+
+extern int usejoystick;
+extern int joybfire;
+extern int joybstrafe;
+extern int joybuse;
+extern int joybspeed;
+
+extern int joystick_index;
+extern int joystick_x_axis;
+extern int joystick_x_invert;
+extern int joystick_y_axis;
+extern int joystick_y_invert;
+
+void ConfigJoystick(void);
+
+#endif /* #ifndef SETUP_JOYSTICK_H */
+
--- a/setup/keyboard.c
+++ b/setup/keyboard.c
@@ -23,6 +23,7 @@
 #include "execute.h"
 #include "txt_keyinput.h"
 
+#include "joystick.h"
 #include "keyboard.h"
 
 int key_left = KEY_LEFTARROW;
@@ -35,7 +36,6 @@
 int key_use = ' ';
 int key_strafe = KEY_RALT;
 int key_speed = KEY_RSHIFT;
-int joybspeed = 3;
 
 int vanilla_keyboard_mapping = 1;
 
--- a/setup/mainmenu.c
+++ b/setup/mainmenu.c
@@ -32,6 +32,7 @@
 
 #include "compatibility.h"
 #include "display.h"
+#include "joystick.h"
 #include "keyboard.h"
 #include "mouse.h"
 #include "multiplayer.h"
@@ -106,6 +107,8 @@
     TXT_AddWidgets(window,
           TXT_NewButton2("Configure Display", 
                          (TxtWidgetSignalFunc) ConfigDisplay, NULL),
+          TXT_NewButton2("Configure Joystick", 
+                         (TxtWidgetSignalFunc) ConfigJoystick, NULL),
           TXT_NewButton2("Configure Keyboard", 
                          (TxtWidgetSignalFunc) ConfigKeyboard, NULL),
           TXT_NewButton2("Configure Mouse", 
--- /dev/null
+++ b/setup/txt_joybinput.c
@@ -1,0 +1,156 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 2006 Simon Howard
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "doomkeys.h"
+#include "joystick.h"
+
+#include "txt_joybinput.h"
+#include "txt_gui.h"
+#include "txt_io.h"
+#include "txt_label.h"
+#include "txt_window.h"
+
+#define JOYSTICK_INPUT_WIDTH 10
+
+static void OpenPromptWindow(txt_joystick_input_t *joystick_input)
+{
+    txt_window_t *window;
+    txt_label_t *label;
+
+    window = TXT_NewWindow(NULL);
+    TXT_SetWindowAction(window, TXT_HORIZ_LEFT, NULL);
+    TXT_SetWindowAction(window, TXT_HORIZ_CENTER, 
+                        TXT_NewWindowAbortAction(window));
+    TXT_SetWindowAction(window, TXT_HORIZ_RIGHT, NULL);
+    
+    label = TXT_NewLabel("Press the new joystick button...");
+
+    TXT_AddWidget(window, label);
+    TXT_SetWidgetAlign(label, TXT_HORIZ_CENTER);
+}
+
+static void TXT_JoystickInputSizeCalc(TXT_UNCAST_ARG(joystick_input))
+{
+    TXT_CAST_ARG(txt_joystick_input_t, joystick_input);
+
+    // All joystickinputs are the same size.
+
+    joystick_input->widget.w = JOYSTICK_INPUT_WIDTH;
+    joystick_input->widget.h = 1;
+}
+
+static void GetJoystickButtonDescription(int button, char *buf)
+{
+    sprintf(buf, "BUTTON #%i", button + 1);
+}
+
+static void TXT_JoystickInputDrawer(TXT_UNCAST_ARG(joystick_input), int selected)
+{
+    TXT_CAST_ARG(txt_joystick_input_t, joystick_input);
+    char buf[20];
+    int i;
+
+    if (*joystick_input->variable == -1)
+    {
+        strcpy(buf, "");
+    }
+    else
+    {
+        GetJoystickButtonDescription(*joystick_input->variable, buf);
+    }
+
+    if (selected)
+    {
+        TXT_BGColor(TXT_COLOR_GREY, 0);
+    }
+    else
+    {
+        TXT_BGColor(TXT_COLOR_BLUE, 0);
+    }
+
+    TXT_FGColor(TXT_COLOR_BRIGHT_WHITE);
+    
+    TXT_DrawString(buf);
+    
+    for (i=strlen(buf); i<JOYSTICK_INPUT_WIDTH; ++i)
+    {
+        TXT_DrawString(" ");
+    }
+}
+
+static void TXT_JoystickInputDestructor(TXT_UNCAST_ARG(joystick_input))
+{
+}
+
+static int TXT_JoystickInputKeyPress(TXT_UNCAST_ARG(joystick_input), int joystick)
+{
+    TXT_CAST_ARG(txt_joystick_input_t, joystick_input);
+
+    if (joystick == KEY_ENTER)
+    {
+        // Open a window to prompt for the new joystick press
+
+        OpenPromptWindow(joystick_input);
+
+        return 1;
+    }
+
+    return 0;
+}
+
+static void TXT_JoystickInputMousePress(TXT_UNCAST_ARG(widget), int x, int y, int b)
+{
+    TXT_CAST_ARG(txt_joystick_input_t, widget);
+            
+    // Clicking is like pressing enter
+
+    if (b == TXT_MOUSE_LEFT)
+    {
+        TXT_JoystickInputKeyPress(widget, KEY_ENTER);
+    }
+}
+
+txt_widget_class_t txt_joystick_input_class =
+{
+    TXT_JoystickInputSizeCalc,
+    TXT_JoystickInputDrawer,
+    TXT_JoystickInputKeyPress,
+    TXT_JoystickInputDestructor,
+    TXT_JoystickInputMousePress,
+    NULL,
+};
+
+txt_joystick_input_t *TXT_NewJoystickInput(int *variable)
+{
+    txt_joystick_input_t *joystick_input;
+
+    joystick_input = malloc(sizeof(txt_joystick_input_t));
+
+    TXT_InitWidget(joystick_input, &txt_joystick_input_class);
+    joystick_input->variable = variable;
+
+    return joystick_input;
+}
+
--- /dev/null
+++ b/setup/txt_joybinput.h
@@ -1,0 +1,44 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 2007 Simon Howard
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+
+#ifndef TXT_JOYB_INPUT_H
+#define TXT_JOYB_INPUT_H
+
+typedef struct txt_joystick_input_s txt_joystick_input_t;
+
+#include "txt_widget.h"
+
+//
+// A joystick input is like an input box.  When selected, a box pops up
+// allowing a joystick button to be pressed to select it.
+//
+
+struct txt_joystick_input_s
+{
+    txt_widget_t widget;
+    int *variable;
+};
+
+txt_joystick_input_t *TXT_NewJoystickInput(int *variable);
+
+#endif /* #ifndef TXT_JOYB_INPUT_H */
+
+
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -48,6 +48,7 @@
 hu_stuff.c           hu_stuff.h            \
 i_main.c                                   \
 info.c               info.h                \
+i_joystick.c         i_joystick.h          \
 i_scale.c            i_scale.h             \
                      i_swap.h              \
 i_system.c           i_system.h            \
--- /dev/null
+++ b/src/i_joystick.c
@@ -1,0 +1,166 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 2007 Simon Howard
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+// DESCRIPTION:
+//       SDL Joystick code.
+//
+//-----------------------------------------------------------------------------
+
+
+#include "SDL.h"
+#include "SDL_joystick.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "doomdef.h"
+#include "doomtype.h"
+#include "d_event.h"
+#include "d_main.h"
+#include "i_joystick.h"
+
+static SDL_Joystick *joystick = NULL;
+
+// Configuration variables:
+
+// Standard default.cfg Joystick enable/disable
+
+extern int usejoystick;
+
+// Joystick to use, as an SDL joystick index:
+
+int joystick_index = -1;
+
+// Which joystick axis to use for horizontal movement, and whether to
+// invert the direction:
+
+int joystick_x_axis = 0;
+int joystick_x_invert = 0;
+
+// Which joystick axis to use for vertical movement, and whether to
+// invert the direction:
+
+int joystick_y_axis = 1;
+int joystick_y_invert = 0;
+
+void I_InitJoystick(void)
+{
+    int num_axes;
+
+    if (!usejoystick)
+    {
+        return;
+    }
+
+    if (SDL_Init(SDL_INIT_JOYSTICK) < 0)
+    {
+        return;
+    }
+
+    // Open the joystick
+
+    joystick = SDL_JoystickOpen(joystick_index);
+
+    if (joystick == NULL)
+    {
+        printf("I_InitJoystick: Failed to open joystick #%i\n",
+               joystick_index);
+        SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
+        return;
+    }
+
+    num_axes = SDL_JoystickNumAxes(joystick);
+
+    if (joystick_x_axis < 0 || joystick_x_axis >= num_axes
+     || joystick_y_axis < 0 || joystick_y_axis >= num_axes)
+    {
+        printf("I_InitJoystick: Invalid joystick axis for joystick #%i "
+               "(run joystick setup again)\n",
+               joystick_index);
+
+        SDL_JoystickClose(joystick);
+        joystick = NULL;
+        SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
+    }
+
+    // Initialised okay!
+
+    printf("I_InitJoystick: %s\n", SDL_JoystickName(joystick_index));
+}
+
+void I_ShutdownJoystick(void)
+{
+    if (joystick != NULL) 
+    {
+        SDL_JoystickClose(joystick);
+        joystick = NULL;
+        SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
+    }
+}
+
+// Get a bitmask of all currently-pressed buttons
+
+static int GetButtonState(void)
+{
+    int i;
+    int result;
+
+    result = 0;
+
+    for (i=0; i<SDL_JoystickNumButtons(joystick); ++i) 
+    {
+        if (SDL_JoystickGetButton(joystick, i))
+        {
+            result |= 1 << i;
+        }
+    }
+
+    return result;
+}
+
+// Read the state of an axis, inverting if necessary.
+
+static int GetAxisState(int axis, int invert)
+{
+    int result;
+
+    result = SDL_JoystickGetAxis(joystick, axis);
+
+    if (invert)
+    {
+        result = -result;
+    }
+
+    return result;
+}
+
+void I_UpdateJoystick(void)
+{
+    event_t ev;
+
+    ev.type = ev_joystick;
+    ev.data1 = GetButtonState();
+    ev.data2 = GetAxisState(joystick_x_axis, joystick_x_invert);
+    ev.data3 = GetAxisState(joystick_y_axis, joystick_y_invert);
+
+    D_PostEvent(&ev);
+}
+
--- /dev/null
+++ b/src/i_joystick.h
@@ -1,0 +1,41 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 2007 Simon Howard
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+// DESCRIPTION:
+//      System-specific joystick interface.
+//
+//-----------------------------------------------------------------------------
+
+
+#ifndef __I_JOYSTICK__
+#define __I_JOYSTICK__
+
+extern int joystick_index;
+extern int joystick_x_axis;
+extern int joystick_x_invert;
+extern int joystick_y_axis;
+extern int joystick_y_invert;
+
+void I_InitJoystick(void);
+void I_ShutdownJoystick(void);
+void I_UpdateJoystick(void);
+
+#endif /* #ifndef __I_JOYSTICK__ */
+
--- a/src/i_main.c
+++ b/src/i_main.c
@@ -36,7 +36,6 @@
 
 int main(int argc, char **argv) 
 { 
-
     // save arguments
 
     myargc = argc; 
@@ -48,3 +47,4 @@
 
     return 0;
 } 
+
--- a/src/i_system.c
+++ b/src/i_system.c
@@ -36,6 +36,7 @@
 #include "doomstat.h"
 #include "m_argv.h"
 #include "m_misc.h"
+#include "i_joystick.h"
 #include "i_timer.h"
 #include "i_video.h"
 #include "s_sound.h"
@@ -114,6 +115,7 @@
 {
     I_CheckIsScreensaver();
     I_InitTimer();
+    I_InitJoystick();
 }
 
 // 
--- a/src/m_misc.c
+++ b/src/m_misc.c
@@ -54,6 +54,7 @@
 
 #include "w_wad.h"
 
+#include "i_joystick.h"
 #include "i_swap.h"
 #include "i_system.h"
 #include "i_video.h"
@@ -413,6 +414,12 @@
 #ifdef FEATURE_MULTIPLAYER
     {"player_name",                 &net_player_name,          DEFAULT_STRING, 0, 0},
 #endif
+
+    {"joystick_index",              &joystick_index, DEFAULT_INT, 0, 0},
+    {"joystick_x_axis",             &joystick_x_axis, DEFAULT_INT, 0, 0},
+    {"joystick_x_invert",           &joystick_x_invert, DEFAULT_INT, 0, 0},
+    {"joystick_y_axis",             &joystick_y_axis, DEFAULT_INT, 0, 0},
+    {"joystick_y_invert",           &joystick_y_invert, DEFAULT_INT, 0, 0},
 };
 
 static default_collection_t extra_defaults =