| 1 |
/* |
| 2 |
* Custom keyboard shortcuts configuration |
| 3 |
* Copyright (C) 2007 Joshua Langley <joshlangley@optusnet.com.au> |
| 4 |
* |
| 5 |
* This file is part of The Mana World. |
| 6 |
* |
| 7 |
* This program is free software; you can redistribute it and/or modify |
| 8 |
* it under the terms of the GNU General Public License as published by |
| 9 |
* the Free Software Foundation; either version 2 of the License, or |
| 10 |
* any later version. |
| 11 |
* |
| 12 |
* This program is distributed in the hope that it will be useful, |
| 13 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 15 |
* GNU General Public License for more details. |
| 16 |
* |
| 17 |
* You should have received a copy of the GNU General Public License |
| 18 |
* along with this program; if not, write to the Free Software |
| 19 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 20 |
*/ |
| 21 |
|
| 22 |
#include "configuration.h" |
| 23 |
#include "keyboardconfig.h" |
| 24 |
#include "log.h" |
| 25 |
|
| 26 |
#include "gui/sdlinput.h" |
| 27 |
#include "gui/setup_keyboard.h" |
| 28 |
|
| 29 |
#include "utils/gettext.h" |
| 30 |
#include "utils/stringutils.h" |
| 31 |
|
| 32 |
struct KeyData |
| 33 |
{ |
| 34 |
const char *configField; |
| 35 |
int defaultValue; |
| 36 |
std::string caption; |
| 37 |
}; |
| 38 |
|
| 39 |
// keyData must be in same order as enum keyAction. |
| 40 |
static KeyData const keyData[KeyboardConfig::KEY_TOTAL] = { |
| 41 |
{"keyMoveUp", SDLK_UP, _("Move Up")}, |
| 42 |
{"keyMoveDown", SDLK_DOWN, _("Move Down")}, |
| 43 |
{"keyMoveLeft", SDLK_LEFT, _("Move Left")}, |
| 44 |
{"keyMoveRight", SDLK_RIGHT, _("Move Right")}, |
| 45 |
{"keyAttack", SDLK_LCTRL, _("Attack")}, |
| 46 |
{"keyTargetAttack", SDLK_x, _("Target & Attack")}, |
| 47 |
{"keySmilie", SDLK_LALT, _("Smilie")}, |
| 48 |
{"keyTalk", SDLK_t, _("Talk")}, |
| 49 |
{"keyTarget", SDLK_LSHIFT, _("Stop Attack")}, |
| 50 |
{"keyTargetClosest", SDLK_a, _("Target Closest")}, |
| 51 |
{"keyTargetNPC", SDLK_n, _("Target NPC")}, |
| 52 |
{"keyTargetPlayer", SDLK_q, _("Target Player")}, |
| 53 |
{"keyPickup", SDLK_z, _("Pickup")}, |
| 54 |
{"keyHideWindows", SDLK_h, _("Hide Windows")}, |
| 55 |
{"keyBeingSit", SDLK_s, _("Sit")}, |
| 56 |
{"keyScreenshot", SDLK_p, _("Screenshot")}, |
| 57 |
{"keyTrade", SDLK_r, _("Enable/Disable Trading")}, |
| 58 |
{"keyPathfind", SDLK_f, _("Find Path to Mouse")}, |
| 59 |
{"keyShortcut1", SDLK_1, strprintf(_("Item Shortcut %d"), 1)}, |
| 60 |
{"keyShortcut2", SDLK_2, strprintf(_("Item Shortcut %d"), 2)}, |
| 61 |
{"keyShortcut3", SDLK_3, strprintf(_("Item Shortcut %d"), 3)}, |
| 62 |
{"keyShortcut4", SDLK_4, strprintf(_("Item Shortcut %d"), 4)}, |
| 63 |
{"keyShortcut5", SDLK_5, strprintf(_("Item Shortcut %d"), 5)}, |
| 64 |
{"keyShortcut6", SDLK_6, strprintf(_("Item Shortcut %d"), 6)}, |
| 65 |
{"keyShortcut7", SDLK_7, strprintf(_("Item Shortcut %d"), 7)}, |
| 66 |
{"keyShortcut8", SDLK_8, strprintf(_("Item Shortcut %d"), 8)}, |
| 67 |
{"keyShortcut9", SDLK_9, strprintf(_("Item Shortcut %d"), 9)}, |
| 68 |
{"keyShortcut10", SDLK_0, strprintf(_("Item Shortcut %d"), 10)}, |
| 69 |
{"keyShortcut11", SDLK_MINUS, strprintf(_("Item Shortcut %d"), 11)}, |
| 70 |
{"keyShortcut12", SDLK_EQUALS, strprintf(_("Item Shortcut %d"), 12)}, |
| 71 |
{"keyWindowHelp", SDLK_F1, _("Help Window")}, |
| 72 |
{"keyWindowStatus", SDLK_F2, _("Status Window")}, |
| 73 |
{"keyWindowInventory", SDLK_F3, _("Inventory Window")}, |
| 74 |
{"keyWindowEquipment", SDLK_F4, _("Equipment Window")}, |
| 75 |
{"keyWindowSkill", SDLK_F5, _("Skill Window")}, |
| 76 |
{"keyWindowMinimap", SDLK_F6, _("Minimap Window")}, |
| 77 |
{"keyWindowChat", SDLK_F7, _("Chat Window")}, |
| 78 |
{"keyWindowShortcut", SDLK_F8, _("Item Shortcut Window")}, |
| 79 |
{"keyWindowSetup", SDLK_F9, _("Setup Window")}, |
| 80 |
{"keyWindowDebug", SDLK_F10, _("Debug Window")}, |
| 81 |
{"keyWindowParty", SDLK_F11, _("Party Window")}, |
| 82 |
{"keyWindowEmoteBar", SDLK_F12, _("Emote Shortcut Window")}, |
| 83 |
{"keyWindowOutfit", SDLK_o, _("Outfits Window")}, |
| 84 |
{"keyEmoteShortcut1", SDLK_1, strprintf(_("Emote Shortcut %d"), 1)}, |
| 85 |
{"keyEmoteShortcut2", SDLK_2, strprintf(_("Emote Shortcut %d"), 2)}, |
| 86 |
{"keyEmoteShortcut3", SDLK_3, strprintf(_("Emote Shortcut %d"), 3)}, |
| 87 |
{"keyEmoteShortcut4", SDLK_4, strprintf(_("Emote Shortcut %d"), 4)}, |
| 88 |
{"keyEmoteShortcut5", SDLK_5, strprintf(_("Emote Shortcut %d"), 5)}, |
| 89 |
{"keyEmoteShortcut6", SDLK_6, strprintf(_("Emote Shortcut %d"), 6)}, |
| 90 |
{"keyEmoteShortcut7", SDLK_7, strprintf(_("Emote Shortcut %d"), 7)}, |
| 91 |
{"keyEmoteShortcut8", SDLK_8, strprintf(_("Emote Shortcut %d"), 8)}, |
| 92 |
{"keyEmoteShortcut9", SDLK_9, strprintf(_("Emote Shortcut %d"), 9)}, |
| 93 |
{"keyEmoteShortcut10", SDLK_0, strprintf(_("Emote Shortcut %d"), 10)}, |
| 94 |
{"keyEmoteShortcut11", SDLK_MINUS, strprintf(_("Emote Shortcut %d"), 11)}, |
| 95 |
{"keyEmoteShortcut12", SDLK_EQUALS, strprintf(_("Emote Shortcut %d"), 12)}, |
| 96 |
{"keyChat", SDLK_RETURN, _("Toggle Chat")}, |
| 97 |
{"keyChatScrollUp", SDLK_PAGEUP, _("Scroll Chat Up")}, |
| 98 |
{"keyChatScrollDown", SDLK_PAGEDOWN, _("Scroll Chat Down")}, |
| 99 |
{"keyChatPrevTab", SDLK_LEFTBRACKET, _("Previous Chat Tab")}, |
| 100 |
{"keyChatNextTab", SDLK_RIGHTBRACKET, _("Next Chat Tab")}, |
| 101 |
{"keyOK", SDLK_SPACE, _("Select OK")}, |
| 102 |
{"keyQuit", SDLK_ESCAPE, _("Quit")}, |
| 103 |
{"keyIgnoreInput1", SDLK_LSUPER, _("Ignore input 1")}, |
| 104 |
{"keyIgnoreInput2", SDLK_RSUPER, _("Ignore input 2")} |
| 105 |
}; |
| 106 |
|
| 107 |
void KeyboardConfig::init() |
| 108 |
{ |
| 109 |
for (int i = 0; i < KEY_TOTAL; i++) |
| 110 |
{ |
| 111 |
mKey[i].configField = keyData[i].configField; |
| 112 |
mKey[i].defaultValue = keyData[i].defaultValue; |
| 113 |
mKey[i].caption = keyData[i].caption; |
| 114 |
mKey[i].value = KEY_NO_VALUE; |
| 115 |
} |
| 116 |
mNewKeyIndex = KEY_NO_VALUE; |
| 117 |
mEnabled = true; |
| 118 |
|
| 119 |
retrieve(); |
| 120 |
} |
| 121 |
|
| 122 |
void KeyboardConfig::retrieve() |
| 123 |
{ |
| 124 |
for (int i = 0; i < KEY_TOTAL; i++) |
| 125 |
{ |
| 126 |
mKey[i].value = (int) config.getValue( |
| 127 |
mKey[i].configField, mKey[i].defaultValue); |
| 128 |
} |
| 129 |
} |
| 130 |
|
| 131 |
void KeyboardConfig::store() |
| 132 |
{ |
| 133 |
for (int i = 0; i < KEY_TOTAL; i++) |
| 134 |
{ |
| 135 |
config.setValue(mKey[i].configField, mKey[i].value); |
| 136 |
} |
| 137 |
} |
| 138 |
|
| 139 |
void KeyboardConfig::makeDefault() |
| 140 |
{ |
| 141 |
for (int i = 0; i < KEY_TOTAL; i++) |
| 142 |
{ |
| 143 |
mKey[i].value = mKey[i].defaultValue; |
| 144 |
} |
| 145 |
} |
| 146 |
|
| 147 |
bool KeyboardConfig::hasConflicts() |
| 148 |
{ |
| 149 |
int i, j; |
| 150 |
/** |
| 151 |
* No need to parse the square matrix: only check one triangle |
| 152 |
* that's enough to detect conflicts |
| 153 |
*/ |
| 154 |
for (i = 0; i < KEY_TOTAL; i++) |
| 155 |
{ |
| 156 |
for (j = i, j++; j < KEY_TOTAL; j++) |
| 157 |
{ |
| 158 |
// Allow for item shortcut and emote keys to overlap |
| 159 |
// as well as emote and ignore keys, but no other keys |
| 160 |
if (!((((i >= KEY_SHORTCUT_1) && (i <= KEY_SHORTCUT_12)) && |
| 161 |
((j >= KEY_EMOTE_1) && (j <= KEY_EMOTE_12))) || |
| 162 |
((i == KEY_TOGGLE_CHAT) && (j == KEY_OK)) || |
| 163 |
((i == KEY_EMOTE) && |
| 164 |
(j == KEY_IGNORE_INPUT_1 || j == KEY_IGNORE_INPUT_2))) && |
| 165 |
(mKey[i].value == mKey[j].value) |
| 166 |
) |
| 167 |
{ |
| 168 |
return true; |
| 169 |
} |
| 170 |
} |
| 171 |
} |
| 172 |
return false; |
| 173 |
} |
| 174 |
|
| 175 |
void KeyboardConfig::callbackNewKey() |
| 176 |
{ |
| 177 |
mSetupKey->newKeyCallback(mNewKeyIndex); |
| 178 |
} |
| 179 |
|
| 180 |
int KeyboardConfig::getKeyIndex(int keyValue) const |
| 181 |
{ |
| 182 |
for (int i = 0; i < KEY_TOTAL; i++) |
| 183 |
{ |
| 184 |
if (keyValue == mKey[i].value) |
| 185 |
{ |
| 186 |
return i; |
| 187 |
} |
| 188 |
} |
| 189 |
return KEY_NO_VALUE; |
| 190 |
} |
| 191 |
|
| 192 |
|
| 193 |
int KeyboardConfig::getKeyEmoteOffset(int keyValue) const |
| 194 |
{ |
| 195 |
for (int i = KEY_EMOTE_1; i <= KEY_EMOTE_12; i++) |
| 196 |
{ |
| 197 |
if (keyValue == mKey[i].value) |
| 198 |
{ |
| 199 |
return 1 + i - KEY_EMOTE_1; |
| 200 |
} |
| 201 |
} |
| 202 |
return 0; |
| 203 |
} |
| 204 |
|
| 205 |
bool KeyboardConfig::isKeyActive(int index) const |
| 206 |
{ |
| 207 |
if (!mActiveKeys) |
| 208 |
return false; |
| 209 |
return mActiveKeys[mKey[index].value]; |
| 210 |
} |
| 211 |
|
| 212 |
void KeyboardConfig::refreshActiveKeys() |
| 213 |
{ |
| 214 |
mActiveKeys = SDL_GetKeyState(NULL); |
| 215 |
} |