foxygit / doom Log in
commit eb86fcdf3099404ed8cc0feaf96dd94654d2b8dd
Author:     Simon Howard <fraggle@gmail.com>
AuthorDate: Mon Apr 11 19:49:45 2011 +0000
Commit:     Simon Howard <fraggle@gmail.com>
CommitDate: Mon Apr 11 19:49:45 2011 +0000

    Allow the shift key to be held down when changing key/mouse/joystick
    bindings to prevent bindings to the same key from being cleared (thanks
    myk).

    Subversion-branch: /trunk/chocolate-doom
    Subversion-revision: 2325
---
 NEWS                   |  3 +++
 setup/txt_joybinput.c  | 11 ++++++++-
 setup/txt_joybinput.h  |  1 +
 setup/txt_keyinput.c   | 11 ++++++++-
 setup/txt_keyinput.h   |  1 +
 setup/txt_mouseinput.c | 10 ++++++++-
 setup/txt_mouseinput.h |  1 +
 textscreen/txt_main.h  | 14 ++++++++++++
 textscreen/txt_sdl.c   | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++
 9 files changed, 109 insertions(+), 3 deletions(-)

diff --git a/NEWS b/NEWS
index 45c51e71..1cfca6a7 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,9 @@
        reorganised to a better arrangement.
      * It is now possible to load .lmp files (and play back demos)
        with long filenames (thanks blzut3).
+     * In the setup tool, it is now possible to hold down shift when
+       changing key/mouse/joystick bindings to prevent other bindings
+       to the same key from being cleared (thanks myk).

     Compatibility:
      * Added support for the alternate version of the Final Doom
diff --git a/setup/txt_joybinput.c b/setup/txt_joybinput.c
index 861414f7..9ad26a45 100644
--- a/setup/txt_joybinput.c
+++ b/setup/txt_joybinput.c
@@ -48,7 +48,12 @@ static int EventCallback(SDL_Event *event, TXT_UNCAST_ARG(joystick_input))
     if (event->type == SDL_JOYBUTTONDOWN)
     {
         *joystick_input->variable = event->jbutton.button;
-        TXT_EmitSignal(joystick_input, "set");
+
+        if (joystick_input->check_conflicts)
+        {
+            TXT_EmitSignal(joystick_input, "set");
+        }
+
         TXT_CloseWindow(joystick_input->prompt_window);
         return 1;
     }
@@ -89,6 +94,10 @@ static void OpenPromptWindow(txt_joystick_input_t *joystick_input)
     txt_label_t *label;
     SDL_Joystick *joystick;

+    // Silently update when the shift button is held down.
+
+    joystick_input->check_conflicts = !TXT_GetModifierState(TXT_MOD_SHIFT);
+
     if (SDL_Init(SDL_INIT_JOYSTICK) < 0)
     {
         return;
diff --git a/setup/txt_joybinput.h b/setup/txt_joybinput.h
index b2920b88..69ec4a1f 100644
--- a/setup/txt_joybinput.h
+++ b/setup/txt_joybinput.h
@@ -37,6 +37,7 @@ struct txt_joystick_input_s
     txt_widget_t widget;
     int *variable;
     txt_window_t *prompt_window;
+    int check_conflicts;
 };

 txt_joystick_input_t *TXT_NewJoystickInput(int *variable);
diff --git a/setup/txt_keyinput.c b/setup/txt_keyinput.c
index dfa6ede2..6f1ee4dd 100644
--- a/setup/txt_keyinput.c
+++ b/setup/txt_keyinput.c
@@ -42,7 +42,12 @@ static int KeyPressCallback(txt_window_t *window, int key,
         // Got the key press.  Save to the variable and close the window.

         *key_input->variable = key;
-        TXT_EmitSignal(key_input, "set");
+
+        if (key_input->check_conflicts)
+        {
+            TXT_EmitSignal(key_input, "set");
+        }
+
         TXT_CloseWindow(window);

         // Re-enable key mappings now that we have the key
@@ -67,6 +72,10 @@ static void OpenPromptWindow(txt_key_input_t *key_input)
     txt_window_t *window;
     txt_label_t *label;

+    // Silently update when the shift button is held down.
+
+    key_input->check_conflicts = !TXT_GetModifierState(TXT_MOD_SHIFT);
+
     window = TXT_NewWindow(NULL);
     TXT_SetWindowAction(window, TXT_HORIZ_LEFT, NULL);
     TXT_SetWindowAction(window, TXT_HORIZ_CENTER,
diff --git a/setup/txt_keyinput.h b/setup/txt_keyinput.h
index 4952a970..5df0b2e3 100644
--- a/setup/txt_keyinput.h
+++ b/setup/txt_keyinput.h
@@ -35,6 +35,7 @@ struct txt_key_input_s
 {
     txt_widget_t widget;
     int *variable;
+    int check_conflicts;
 };

 txt_key_input_t *TXT_NewKeyInput(int *variable);
diff --git a/setup/txt_mouseinput.c b/setup/txt_mouseinput.c
index 2c14a010..c3e17299 100644
--- a/setup/txt_mouseinput.c
+++ b/setup/txt_mouseinput.c
@@ -42,7 +42,12 @@ static int MousePressCallback(txt_window_t *window,
     // Got the mouse press.  Save to the variable and close the window.

     *mouse_input->variable = b - TXT_MOUSE_BASE;
-    TXT_EmitSignal(mouse_input, "set");
+
+    if (mouse_input->check_conflicts)
+    {
+        TXT_EmitSignal(mouse_input, "set");
+    }
+
     TXT_CloseWindow(window);

     return 1;
@@ -53,6 +58,9 @@ static void OpenPromptWindow(txt_mouse_input_t *mouse_input)
     txt_window_t *window;
     txt_label_t *label;

+    // Silently update when the shift key is held down.
+    mouse_input->check_conflicts = !TXT_GetModifierState(TXT_MOD_SHIFT);
+
     window = TXT_NewWindow(NULL);
     TXT_SetWindowAction(window, TXT_HORIZ_LEFT, NULL);
     TXT_SetWindowAction(window, TXT_HORIZ_CENTER,
diff --git a/setup/txt_mouseinput.h b/setup/txt_mouseinput.h
index 57c258eb..ef3ec2aa 100644
--- a/setup/txt_mouseinput.h
+++ b/setup/txt_mouseinput.h
@@ -35,6 +35,7 @@ struct txt_mouse_input_s
 {
     txt_widget_t widget;
     int *variable;
+    int check_conflicts;
 };

 txt_mouse_input_t *TXT_NewMouseInput(int *variable);
diff --git a/textscreen/txt_main.h b/textscreen/txt_main.h
index 601548e5..a415ee1b 100644
--- a/textscreen/txt_main.h
+++ b/textscreen/txt_main.h
@@ -69,6 +69,16 @@ typedef enum
     TXT_COLOR_BRIGHT_WHITE,
 } txt_color_t;

+// Modifier keys.
+
+typedef enum
+{
+    TXT_MOD_SHIFT,
+    TXT_MOD_CTRL,
+    TXT_MOD_ALT,
+    TXT_NUM_MODIFIERS
+} txt_modifier_t;
+
 // Initialize the screen
 // Returns 1 if successful, 0 if failed.

@@ -94,6 +104,10 @@ void TXT_UpdateScreen(void);

 int TXT_GetChar(void);

+// Read the current state of modifier keys that are held down.
+
+int TXT_GetModifierState(txt_modifier_t mod);
+
 // Provides a short description of a key code, placing into the
 // provided buffer.

diff --git a/textscreen/txt_sdl.c b/textscreen/txt_sdl.c
index 5ae151e9..767c9b3e 100644
--- a/textscreen/txt_sdl.c
+++ b/textscreen/txt_sdl.c
@@ -63,6 +63,8 @@ static int key_mapping = 1;
 static TxtSDLEventCallbackFunc event_callback;
 static void *event_callback_data;

+static int modifier_state[TXT_NUM_MODIFIERS];
+
 // Font we are using:

 static txt_font_t *font;
@@ -493,6 +495,48 @@ static int MouseHasMoved(void)
     }
 }

+// Examine a key press/release and update the modifier key state
+// if necessary.
+
+static void UpdateModifierState(SDL_keysym *sym, int pressed)
+{
+    txt_modifier_t mod;
+
+    switch (sym->sym)
+    {
+        case SDLK_LSHIFT:
+        case SDLK_RSHIFT:
+            mod = TXT_MOD_SHIFT;
+            break;
+
+        case SDLK_LCTRL:
+        case SDLK_RCTRL:
+            mod = TXT_MOD_CTRL;
+            break;
+
+        case SDLK_LALT:
+        case SDLK_RALT:
+#if !SDL_VERSION_ATLEAST(1, 3, 0)
+        case SDLK_LMETA:
+        case SDLK_RMETA:
+#endif
+            mod = TXT_MOD_ALT;
+            break;
+
+        default:
+            return;
+    }
+
+    if (pressed)
+    {
+        ++modifier_state[mod];
+    }
+    else
+    {
+        --modifier_state[mod];
+    }
+}
+
 signed int TXT_GetChar(void)
 {
     SDL_Event ev;
@@ -522,8 +566,14 @@ signed int TXT_GetChar(void)
                 break;

             case SDL_KEYDOWN:
+                UpdateModifierState(&ev.key.keysym, 1);
+
                 return TranslateKey(&ev.key.keysym);

+            case SDL_KEYUP:
+                UpdateModifierState(&ev.key.keysym, 0);
+                break;
+
             case SDL_QUIT:
                 // Quit = escape
                 return 27;
@@ -542,6 +592,16 @@ signed int TXT_GetChar(void)
     return -1;
 }

+int TXT_GetModifierState(txt_modifier_t mod)
+{
+    if (mod < TXT_NUM_MODIFIERS)
+    {
+        return modifier_state[mod] > 0;
+    }
+
+    return 0;
+}
+
 static const char *SpecialKeyName(int key)
 {
     switch (key)