foxygit / doom Log in
commit 57ad83802bd66f6f3346cdeddd6e7e474b793511
Author:     Simon Howard <fraggle@gmail.com>
AuthorDate: Sat Jun 9 17:51:16 2007 +0000
Commit:     Simon Howard <fraggle@gmail.com>
CommitDate: Sat Jun 9 17:51:16 2007 +0000

    Initial joystick calibration code.

    Subversion-branch: /trunk/chocolate-doom
    Subversion-revision: 898
---
 setup/joystick.c | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 162 insertions(+)

diff --git a/setup/joystick.c b/setup/joystick.c
index ce6a81ec..8a7ff012 100644
--- a/setup/joystick.c
+++ b/setup/joystick.c
@@ -26,6 +26,13 @@

 #include "joystick.h"

+typedef enum
+{
+    CALIBRATE_CENTER,
+    CALIBRATE_LEFT,
+    CALIBRATE_UP,
+} calibration_stage_t;
+
 // Joystick enable/disable

 int usejoystick = 0;
@@ -55,6 +62,159 @@ int joystick_y_invert = 0;

 static txt_button_t *joystick_button;

+//
+// Calibration
+//
+
+static txt_window_t *calibration_window;
+static txt_label_t *calibration_label;
+static calibration_stage_t calibrate_stage;
+static SDL_Joystick **all_joysticks = NULL;
+
+// Try to open all joysticks visible to SDL.
+
+static int OpenAllJoysticks(void)
+{
+    int i;
+    int num_joysticks;
+    int result;
+
+    // SDL_JoystickOpen() all joysticks.
+
+    num_joysticks = SDL_NumJoysticks();
+
+    all_joysticks = malloc(sizeof(SDL_Joystick *) * num_joysticks);
+
+    result = 0;
+
+    for (i=0; i<num_joysticks; ++i)
+    {
+        all_joysticks[i] = SDL_JoystickOpen(i);
+
+        // If any joystick is successfully opened, return true.
+
+        if (all_joysticks[i] != NULL)
+        {
+            result = 1;
+        }
+    }
+
+    if (!result)
+    {
+        free(all_joysticks);
+        all_joysticks = NULL;
+    }
+
+    return result;
+}
+
+// Close all the joysticks opened with OpenAllJoysticks()
+
+static void CloseAllJoysticks(void)
+{
+    int i;
+    int num_joysticks;
+
+    num_joysticks = SDL_NumJoysticks();
+
+    for (i=0; i<num_joysticks; ++i)
+    {
+        if (all_joysticks[i] != NULL)
+        {
+            SDL_JoystickClose(all_joysticks[i]);
+        }
+    }
+
+    free(all_joysticks);
+    all_joysticks = NULL;
+}
+
+static void SetCalibrationLabel(void)
+{
+    char *message = "???";
+
+    switch (calibrate_stage)
+    {
+        case CALIBRATE_CENTER:
+            message = "Move the joystick to the\n"
+                      "center, and press fire.";
+            break;
+        case CALIBRATE_UP:
+            message = "Move the joystick up,\n"
+                      "and press fire.";
+            break;
+        case CALIBRATE_LEFT:
+            message = "Move the joystick to the\n"
+                      "left, and press fire.";
+            break;
+    }
+
+    TXT_SetLabel(calibration_label, message);
+}
+
+static int CalibrationEventCallback(SDL_Event *event, void *user_data)
+{
+    return 0;
+}
+
+static void NoJoystick(void)
+{
+    txt_window_t *window;
+
+    window = TXT_NewWindow(NULL);
+
+    TXT_AddWidget(window,
+                  TXT_NewLabel("No joysticks could be opened.\n\n"
+                               "Try configuring your joystick from within\n"
+                               "your OS first."));
+
+    TXT_SetWindowAction(window, TXT_HORIZ_LEFT, NULL);
+    TXT_SetWindowAction(window, TXT_HORIZ_CENTER,
+                        TXT_NewWindowEscapeAction(window));
+    TXT_SetWindowAction(window, TXT_HORIZ_RIGHT, NULL);
+}
+
+static void CalibrateWindowClosed(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(unused))
+{
+    CloseAllJoysticks();
+    TXT_SDL_SetEventCallback(NULL, NULL);
+}
+
+static void CalibrateJoystick(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(unused))
+{
+    calibrate_stage = CALIBRATE_CENTER;
+
+    // Try to open all available joysticks.  If none are opened successfully,
+    // bomb out with an error.
+
+    if (!OpenAllJoysticks())
+    {
+        NoJoystick();
+        return;
+    }
+
+    calibration_window = TXT_NewWindow("Joystick calibration");
+
+    TXT_AddWidgets(calibration_window,
+                   TXT_NewLabel("Please follow the following instructions\n"
+                                "in order to calibrate your joystick."),
+                   TXT_NewStrut(0, 1),
+                   calibration_label = TXT_NewLabel("zzz"),
+                   TXT_NewStrut(0, 1),
+                   NULL);
+
+    TXT_SetWidgetAlign(calibration_label, TXT_HORIZ_CENTER);
+    SetCalibrationLabel();
+    TXT_SDL_SetEventCallback(CalibrationEventCallback, NULL);
+
+    TXT_SignalConnect(calibration_window, "closed", CalibrateWindowClosed, NULL);
+}
+
+
+//
+// GUI
+//
+
 static void SetJoystickButtonLabel(void)
 {
     char *name;
@@ -116,6 +276,8 @@ void ConfigJoystick(void)
                        NULL);
     }

+    TXT_SignalConnect(joystick_button, "pressed", CalibrateJoystick, NULL);
+
     SetJoystickButtonLabel();
 }