diff options
author | Simon Howard | 2006-08-31 18:13:40 +0000 |
---|---|---|
committer | Simon Howard | 2006-08-31 18:13:40 +0000 |
commit | 0a29eddd798e0722b74d0653fcd293b977cb5704 (patch) | |
tree | 983ab4b583421e4039112cf2c796236540aba20b | |
parent | b4082e71fc70f9295952b8c8c5cd77b85d602671 (diff) | |
download | chocolate-doom-0a29eddd798e0722b74d0653fcd293b977cb5704.tar.gz chocolate-doom-0a29eddd798e0722b74d0653fcd293b977cb5704.tar.bz2 chocolate-doom-0a29eddd798e0722b74d0653fcd293b977cb5704.zip |
Add key and mouse input widgets for selecting keys and mouse buttons.
Subversion-branch: /trunk/chocolate-doom
Subversion-revision: 583
-rw-r--r-- | setup/keyboard.c | 85 | ||||
-rw-r--r-- | setup/mouse.c | 60 | ||||
-rw-r--r-- | setup/txt_keyinput.c | 151 | ||||
-rw-r--r-- | setup/txt_keyinput.h | 47 | ||||
-rw-r--r-- | setup/txt_mouseinput.c | 180 | ||||
-rw-r--r-- | setup/txt_mouseinput.h | 47 |
6 files changed, 540 insertions, 30 deletions
diff --git a/setup/keyboard.c b/setup/keyboard.c index 61b12a97..c635e93c 100644 --- a/setup/keyboard.c +++ b/setup/keyboard.c @@ -1,6 +1,51 @@ #include "textscreen.h" -int dummy; +#include "txt_keyinput.h" + +int key_left = KEY_LEFTARROW; +int key_right = KEY_RIGHTARROW; +int key_up = KEY_UPARROW; +int key_down = KEY_DOWNARROW; +int key_strafeleft = ','; +int key_straferight = '.'; +int key_fire = KEY_RCTRL; +int key_use = ' '; +int key_strafe = KEY_RALT; +int key_speed = KEY_RSHIFT; + +static int *allkeys[] = {&key_left, &key_right, &key_up, &key_down, + &key_strafeleft, &key_straferight, &key_fire, + &key_use, &key_strafe, &key_speed}; + +// Callback invoked when a key control is set + +static void KeySetCallback(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(variable)) +{ + TXT_CAST_ARG(int, variable); + int i; + + for (i=0; i<sizeof(allkeys) / sizeof(*allkeys); ++i) + { + if (*variable == *allkeys[i] && allkeys[i] != variable) + { + // A different key has the same value. Clear the existing + // value. This ensures that no two keys can have the same + // value. + + *allkeys[i] = 0; + } + } +} + +static void AddKeyControl(txt_table_t *table, char *name, int *var) +{ + txt_key_input_t *key_input; + + TXT_AddWidget(table, TXT_NewLabel(name)); + key_input = TXT_NewKeyInput(var); + TXT_AddWidget(table, key_input); + TXT_SignalConnect(key_input, "set", KeySetCallback, var); +} void ConfigKeyboard(void) { @@ -12,38 +57,26 @@ void ConfigKeyboard(void) TXT_AddWidget(window, TXT_NewSeparator("Movement")); table = TXT_NewTable(2); - TXT_AddWidget(table, TXT_NewStrut(20, 0)); - TXT_AddWidget(table, TXT_NewStrut(8, 0)); - - TXT_AddWidget(table, TXT_NewLabel("Move Forward")); - TXT_AddWidget(table, TXT_NewIntInputBox(&dummy, 7)); - TXT_AddWidget(table, TXT_NewLabel("Move Backward")); - TXT_AddWidget(table, TXT_NewIntInputBox(&dummy, 7)); - TXT_AddWidget(table, TXT_NewLabel("Turn Left")); - TXT_AddWidget(table, TXT_NewIntInputBox(&dummy, 7)); - TXT_AddWidget(table, TXT_NewLabel("Turn Right")); - TXT_AddWidget(table, TXT_NewIntInputBox(&dummy, 7)); - TXT_AddWidget(table, TXT_NewLabel("Strafe Left")); - TXT_AddWidget(table, TXT_NewIntInputBox(&dummy, 7)); - TXT_AddWidget(table, TXT_NewLabel("Strafe Right")); - TXT_AddWidget(table, TXT_NewIntInputBox(&dummy, 7)); - TXT_AddWidget(table, TXT_NewLabel("Speed On")); - TXT_AddWidget(table, TXT_NewIntInputBox(&dummy, 7)); - TXT_AddWidget(table, TXT_NewLabel("Strafe On")); - TXT_AddWidget(table, TXT_NewIntInputBox(&dummy, 7)); + TXT_SetColumnWidths(table, 20, 8); + + AddKeyControl(table, "Move Forward", &key_up); + AddKeyControl(table, "Move Backward", &key_down); + AddKeyControl(table, "Turn Left", &key_left); + AddKeyControl(table, "Turn Right", &key_right); + AddKeyControl(table, "Strafe Left", &key_strafeleft); + AddKeyControl(table, "Strafe Right", &key_straferight); + AddKeyControl(table, "Speed On", &key_speed); + AddKeyControl(table, "Strafe On", &key_strafe); TXT_AddWidget(window, table); TXT_AddWidget(window, TXT_NewSeparator("Action")); table = TXT_NewTable(2); - TXT_AddWidget(table, TXT_NewStrut(20, 0)); - TXT_AddWidget(table, TXT_NewStrut(8, 0)); + TXT_SetColumnWidths(table, 20, 8); - TXT_AddWidget(table, TXT_NewLabel("Use")); - TXT_AddWidget(table, TXT_NewIntInputBox(&dummy, 7)); - TXT_AddWidget(table, TXT_NewLabel("Fire")); - TXT_AddWidget(table, TXT_NewIntInputBox(&dummy, 7)); + AddKeyControl(table, "Use", &key_use); + AddKeyControl(table, "Fire", &key_fire); TXT_AddWidget(window, table); } diff --git a/setup/mouse.c b/setup/mouse.c index f87eb390..e60868fc 100644 --- a/setup/mouse.c +++ b/setup/mouse.c @@ -2,11 +2,50 @@ #include <stdlib.h> #include "textscreen.h" +#include "txt_mouseinput.h" + int novert; int speed; int accel; int threshold; +int mouseb_fire; +int mouseb_strafe; +int mouseb_forward; + +static int *all_mouse_buttons[] = {&mouseb_fire, &mouseb_strafe, + &mouseb_forward}; + +static void MouseSetCallback(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(variable)) +{ + TXT_CAST_ARG(int, variable); + int i; + + // Check if the same mouse button is used for a different action + // If so, set the other action(s) to -1 (unset) + + for (i=0; i<sizeof(all_mouse_buttons) / sizeof(*all_mouse_buttons); ++i) + { + if (*all_mouse_buttons[i] == *variable + && all_mouse_buttons[i] != variable) + { + *all_mouse_buttons[i] = -1; + } + } +} + +static void AddMouseControl(txt_table_t *table, char *label, int *var) +{ + txt_mouse_input_t *mouse_input; + + TXT_AddWidget(table, TXT_NewLabel(label)); + + mouse_input = TXT_NewMouseInput(var); + TXT_AddWidget(table, mouse_input); + + TXT_SignalConnect(mouse_input, "set", MouseSetCallback, var); +} + void ConfigMouse(void) { txt_window_t *window; @@ -18,19 +57,32 @@ void ConfigMouse(void) table = TXT_NewTable(2); - TXT_AddWidget(table, TXT_NewLabel("Speed: ")); + TXT_SetColumnWidths(table, 25, 10); + TXT_AddWidget(table, TXT_NewLabel("Speed")); TXT_AddWidget(table, TXT_NewIntInputBox(&speed, 8)); - TXT_AddWidget(table, TXT_NewLabel("Acceleration: ")); + TXT_AddWidget(table, TXT_NewLabel("Acceleration")); TXT_AddWidget(table, TXT_NewIntInputBox(&accel, 8)); - TXT_AddWidget(table, TXT_NewLabel("Acceleration threshold: ")); + TXT_AddWidget(table, TXT_NewLabel("Acceleration threshold")); TXT_AddWidget(table, TXT_NewIntInputBox(&threshold, 8)); + + TXT_AddWidget(window, table); + + TXT_AddWidget(window, TXT_NewSeparator("Mouse buttons")); + + table = TXT_NewTable(2); + + TXT_SetColumnWidths(table, 25, 10); + AddMouseControl(table, "Fire weapon", &mouseb_fire); + AddMouseControl(table, "Move forward", &mouseb_forward); + AddMouseControl(table, "Strafe on", &mouseb_strafe); TXT_AddWidget(window, table); TXT_AddWidget(window, TXT_NewSeparator(NULL)); TXT_AddWidget(window, - TXT_NewInvertedCheckBox("Allow vertical mouse movement", &novert)); + TXT_NewInvertedCheckBox("Allow vertical mouse movement", + &novert)); } diff --git a/setup/txt_keyinput.c b/setup/txt_keyinput.c new file mode 100644 index 00000000..1d79dbc1 --- /dev/null +++ b/setup/txt_keyinput.c @@ -0,0 +1,151 @@ + +#include <stdlib.h> +#include <string.h> + +#include "doomkeys.h" + +#include "txt_keyinput.h" +#include "txt_io.h" +#include "txt_label.h" +#include "txt_window.h" + +#define KEY_INPUT_WIDTH 10 + +static int KeyPressCallback(txt_window_t *window, int key, + TXT_UNCAST_ARG(key_input)) +{ + TXT_CAST_ARG(txt_key_input_t, key_input); + + if (key != KEY_ESCAPE) + { + // Got the key press. Save to the variable and close the window. + + *key_input->variable = key; + TXT_EmitSignal(key_input, "set"); + TXT_CloseWindow(window); + return 1; + } + else + { + return 0; + } +} + +static void OpenPromptWindow(txt_key_input_t *key_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 key..."); + + TXT_AddWidget(window, label); + TXT_SetWidgetAlign(label, TXT_HORIZ_CENTER); + + TXT_SetKeyListener(window, KeyPressCallback, key_input); +} + +static void TXT_KeyInputSizeCalc(TXT_UNCAST_ARG(key_input)) +{ + TXT_CAST_ARG(txt_key_input_t, key_input); + + // All keyinputs are the same size. + + key_input->widget.w = KEY_INPUT_WIDTH; + key_input->widget.h = 1; +} + + +static void TXT_KeyInputDrawer(TXT_UNCAST_ARG(key_input), int selected) +{ + TXT_CAST_ARG(txt_key_input_t, key_input); + char buf[20]; + int i; + + if (*key_input->variable == 0) + { + strcpy(buf, ""); + } + else + { + TXT_GetKeyDescription(*key_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<KEY_INPUT_WIDTH; ++i) + { + TXT_DrawString(" "); + } +} + +static void TXT_KeyInputDestructor(TXT_UNCAST_ARG(key_input)) +{ + TXT_CAST_ARG(txt_key_input_t, key_input); +} + +static int TXT_KeyInputKeyPress(TXT_UNCAST_ARG(key_input), int key) +{ + TXT_CAST_ARG(txt_key_input_t, key_input); + + if (key == KEY_ENTER) + { + // Open a window to prompt for the new key press + + OpenPromptWindow(key_input); + + return 1; + } + + return 0; +} + +static void TXT_KeyInputMousePress(TXT_UNCAST_ARG(widget), int x, int y, int b) +{ + TXT_CAST_ARG(txt_key_input_t, widget); + + // Clicking is like pressing enter + + if (b == TXT_MOUSE_LEFT) + { + TXT_KeyInputKeyPress(widget, KEY_ENTER); + } +} + +txt_widget_class_t txt_key_input_class = +{ + TXT_KeyInputSizeCalc, + TXT_KeyInputDrawer, + TXT_KeyInputKeyPress, + TXT_KeyInputDestructor, + TXT_KeyInputMousePress, +}; + +txt_key_input_t *TXT_NewKeyInput(int *variable) +{ + txt_key_input_t *key_input; + + key_input = malloc(sizeof(txt_key_input_t)); + + TXT_InitWidget(key_input, &txt_key_input_class); + key_input->variable = variable; + + return key_input; +} + diff --git a/setup/txt_keyinput.h b/setup/txt_keyinput.h new file mode 100644 index 00000000..e52d3041 --- /dev/null +++ b/setup/txt_keyinput.h @@ -0,0 +1,47 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// $Id$ +// +// Copyright(C) 1993-1996 Id Software, Inc. +// 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 TXT_KEY_INPUT_H +#define TXT_KEY_INPUT_H + +typedef struct txt_key_input_s txt_key_input_t; + +#include "txt_widget.h" + +// +// A key input is like an input box. When selected, a box pops up +// allowing a key to be selected. +// + +struct txt_key_input_s +{ + txt_widget_t widget; + int *variable; +}; + +txt_key_input_t *TXT_NewKeyInput(int *variable); + +#endif /* #ifndef TXT_KEY_INPUT_H */ + + diff --git a/setup/txt_mouseinput.c b/setup/txt_mouseinput.c new file mode 100644 index 00000000..1c81e8dd --- /dev/null +++ b/setup/txt_mouseinput.c @@ -0,0 +1,180 @@ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "doomkeys.h" + +#include "txt_mouseinput.h" +#include "txt_io.h" +#include "txt_label.h" +#include "txt_window.h" + +#define MOUSE_INPUT_WIDTH 10 + +static int MouseButtonToSetting(int b) +{ + switch (b) + { + case TXT_MOUSE_LEFT: + return 0; + case TXT_MOUSE_RIGHT: + return 1; + case TXT_MOUSE_MIDDLE: + return 2; + default: + return -1; + } +} + +static int MousePressCallback(txt_window_t *window, + int x, int y, int b, + TXT_UNCAST_ARG(mouse_input)) +{ + TXT_CAST_ARG(txt_mouse_input_t, mouse_input); + + // Got the mouse press. Save to the variable and close the window. + + *mouse_input->variable = MouseButtonToSetting(b); + TXT_EmitSignal(mouse_input, "set"); + TXT_CloseWindow(window); + + return 1; +} + +static void OpenPromptWindow(txt_mouse_input_t *mouse_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 mouse button..."); + + TXT_AddWidget(window, label); + TXT_SetWidgetAlign(label, TXT_HORIZ_CENTER); + + TXT_SetMouseListener(window, MousePressCallback, mouse_input); +} + +static void TXT_MouseInputSizeCalc(TXT_UNCAST_ARG(mouse_input)) +{ + TXT_CAST_ARG(txt_mouse_input_t, mouse_input); + + // All mouseinputs are the same size. + + mouse_input->widget.w = MOUSE_INPUT_WIDTH; + mouse_input->widget.h = 1; +} + +static void GetMouseButtonDescription(int button, char *buf) +{ + switch (button) + { + case 0: + strcpy(buf, "LEFT"); + break; + case 1: + strcpy(buf, "RIGHT"); + break; + case 2: + strcpy(buf, "MID"); + break; + default: + sprintf(buf, "BUTTON #%i", button); + break; + } +} + +static void TXT_MouseInputDrawer(TXT_UNCAST_ARG(mouse_input), int selected) +{ + TXT_CAST_ARG(txt_mouse_input_t, mouse_input); + char buf[20]; + int i; + + if (*mouse_input->variable == -1) + { + strcpy(buf, ""); + } + else + { + GetMouseButtonDescription(*mouse_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<MOUSE_INPUT_WIDTH; ++i) + { + TXT_DrawString(" "); + } +} + +static void TXT_MouseInputDestructor(TXT_UNCAST_ARG(mouse_input)) +{ + TXT_CAST_ARG(txt_mouse_input_t, mouse_input); +} + +static int TXT_MouseInputKeyPress(TXT_UNCAST_ARG(mouse_input), int mouse) +{ + TXT_CAST_ARG(txt_mouse_input_t, mouse_input); + + if (mouse == KEY_ENTER) + { + // Open a window to prompt for the new mouse press + + OpenPromptWindow(mouse_input); + + return 1; + } + + return 0; +} + +static void TXT_MouseInputMousePress(TXT_UNCAST_ARG(widget), int x, int y, int b) +{ + TXT_CAST_ARG(txt_mouse_input_t, widget); + + // Clicking is like pressing enter + + if (b == TXT_MOUSE_LEFT) + { + TXT_MouseInputKeyPress(widget, KEY_ENTER); + } +} + +txt_widget_class_t txt_mouse_input_class = +{ + TXT_MouseInputSizeCalc, + TXT_MouseInputDrawer, + TXT_MouseInputKeyPress, + TXT_MouseInputDestructor, + TXT_MouseInputMousePress, +}; + +txt_mouse_input_t *TXT_NewMouseInput(int *variable) +{ + txt_mouse_input_t *mouse_input; + + mouse_input = malloc(sizeof(txt_mouse_input_t)); + + TXT_InitWidget(mouse_input, &txt_mouse_input_class); + mouse_input->variable = variable; + + return mouse_input; +} + diff --git a/setup/txt_mouseinput.h b/setup/txt_mouseinput.h new file mode 100644 index 00000000..bfefb846 --- /dev/null +++ b/setup/txt_mouseinput.h @@ -0,0 +1,47 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// $Id$ +// +// Copyright(C) 1993-1996 Id Software, Inc. +// 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 TXT_MOUSE_INPUT_H +#define TXT_MOUSE_INPUT_H + +typedef struct txt_mouse_input_s txt_mouse_input_t; + +#include "txt_widget.h" + +// +// A mouse input is like an input box. When selected, a box pops up +// allowing a mouse to be selected. +// + +struct txt_mouse_input_s +{ + txt_widget_t widget; + int *variable; +}; + +txt_mouse_input_t *TXT_NewMouseInput(int *variable); + +#endif /* #ifndef TXT_MOUSE_INPUT_H */ + + |