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 =