shithub: choc

Download patch

ref: eb86fcdf3099404ed8cc0feaf96dd94654d2b8dd
parent: d4ef7c37721ee261ac23305fd52239a91e58250a
author: Simon Howard <[email protected]>
date: Mon Apr 11 15:49:45 EDT 2011

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

--- 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
--- a/setup/txt_joybinput.c
+++ b/setup/txt_joybinput.c
@@ -48,7 +48,12 @@
     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;
     }
@@ -88,6 +93,10 @@
     txt_window_t *window;
     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)
     {
--- a/setup/txt_joybinput.h
+++ b/setup/txt_joybinput.h
@@ -37,6 +37,7 @@
     txt_widget_t widget;
     int *variable;
     txt_window_t *prompt_window;
+    int check_conflicts;
 };
 
 txt_joystick_input_t *TXT_NewJoystickInput(int *variable);
--- a/setup/txt_keyinput.c
+++ b/setup/txt_keyinput.c
@@ -42,7 +42,12 @@
         // 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
@@ -66,6 +71,10 @@
 {
     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);
--- a/setup/txt_keyinput.h
+++ b/setup/txt_keyinput.h
@@ -35,6 +35,7 @@
 {
     txt_widget_t widget;
     int *variable;
+    int check_conflicts;
 };
 
 txt_key_input_t *TXT_NewKeyInput(int *variable);
--- a/setup/txt_mouseinput.c
+++ b/setup/txt_mouseinput.c
@@ -42,7 +42,12 @@
     // 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;
@@ -52,6 +57,9 @@
 {
     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);
--- a/setup/txt_mouseinput.h
+++ b/setup/txt_mouseinput.h
@@ -35,6 +35,7 @@
 {
     txt_widget_t widget;
     int *variable;
+    int check_conflicts;
 };
 
 txt_mouse_input_t *TXT_NewMouseInput(int *variable);
--- a/textscreen/txt_main.h
+++ b/textscreen/txt_main.h
@@ -69,6 +69,16 @@
     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.
 
@@ -93,6 +103,10 @@
 // Read a character from the keyboard
 
 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.
--- a/textscreen/txt_sdl.c
+++ b/textscreen/txt_sdl.c
@@ -63,6 +63,8 @@
 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 @@
     }
 }
 
+// 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 @@
                 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;
@@ -540,6 +590,16 @@
     }
 
     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)