From: <pa...@us...> - 2009-03-15 00:47:44
|
Revision: 1160 http://opde.svn.sourceforge.net/opde/?rev=1160&view=rev Author: patryn Date: 2009-03-15 00:47:35 +0000 (Sun, 15 Mar 2009) Log Message: ----------- A major rewrite of the InputService to add the capability of parsing DarkEngine's BND files. Still very much work in progress, please have patience! Modified Paths: -------------- trunk/src/bindings/InputServiceBinder.cpp trunk/src/services/input/InputEventMapper.cpp trunk/src/services/input/InputEventMapper.h trunk/src/services/input/InputService.cpp trunk/src/services/input/InputService.h Modified: trunk/src/bindings/InputServiceBinder.cpp =================================================================== --- trunk/src/bindings/InputServiceBinder.cpp 2009-03-13 15:27:20 UTC (rev 1159) +++ trunk/src/bindings/InputServiceBinder.cpp 2009-03-15 00:47:35 UTC (rev 1160) @@ -172,7 +172,7 @@ char* command; if (PyArg_ParseTuple(args, "s", &command)) { - o->mInstance->command(command); + //o->mInstance->command(command); This has to be fixed for the new input service result = Py_None; Py_INCREF(result); Modified: trunk/src/services/input/InputEventMapper.cpp =================================================================== --- trunk/src/services/input/InputEventMapper.cpp 2009-03-13 15:27:20 UTC (rev 1159) +++ trunk/src/services/input/InputEventMapper.cpp 2009-03-15 00:47:35 UTC (rev 1160) @@ -1,7 +1,7 @@ /****************************************************************************** * * This file is part of openDarkEngine project - * Copyright (C) 2005-2006 openDarkEngine team + * Copyright (C) 2005-2009 openDarkEngine team * * 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 @@ -61,70 +61,4 @@ std::vector<std::string> a; return a; } - - //------------------------------------------------------ - bool InputEventMapper::command(const std::string& cmd) { - WhitespaceStringTokenizer stok(cmd, false); - - if (stok.end()) - return false; - - // if the bind keyword is not present, return false - if (stok.next() != "bind") - return false; - - // validate the keyboard command - - if (stok.end()) - return false; - - string ev = stok.next(); - - if (stok.end()) - return false; - - // The whole command, with parameters and binding type - string wcommand = stok.next(); - - Command spc; - - if (wcommand == "") - return false; - - spc.type = CET_NORMAL; - - if (wcommand.substr(1,1) == "+") { - spc.command = wcommand.substr(1); - spc.type = CET_PEDGE; - } else if (cmd.substr(1,1) == "-") { - spc.command = wcommand.substr(1); - spc.type = CET_NEDGE; - } else { - spc.command = wcommand; - } - - // The bnd files are not case sensitive. Thus, I convert the ev to lower case before validating/inserting - // (Argh. The lower case conversion is way complicated in c++, the reason being locales and stuff like that. I simply ignore this here, OK?) - transform(ev.begin(), ev.end(), ev.begin(), ::tolower); - - if (!mInputService->validateEventString(ev)) { - LOG_ERROR("Encountered invalid event code: %s" ,ev.c_str()); - return false; - } - - // event to command lookup - pair<EventToCommandMap::const_iterator, bool> res = mEventToCommand.insert(make_pair(ev, spc)); - - LOG_DEBUG("InputEventMapper::command: Mapping '%s' to cmd '%s'", ev.c_str(), wcommand.c_str()); - - if (res.second) { // did insert - return true; - } - - // Reverse lookup helper (command to keys) - // TODO: Code. Not needed for now. I guess that this one should search on command part, not the whole command - - return false; - } - } Modified: trunk/src/services/input/InputEventMapper.h =================================================================== --- trunk/src/services/input/InputEventMapper.h 2009-03-13 15:27:20 UTC (rev 1159) +++ trunk/src/services/input/InputEventMapper.h 2009-03-15 00:47:35 UTC (rev 1160) @@ -1,7 +1,7 @@ /****************************************************************************** * * This file is part of openDarkEngine project - * Copyright (C) 2005-2006 openDarkEngine team + * Copyright (C) 2005-2009 openDarkEngine team * * 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 @@ -68,9 +68,6 @@ /** Gets the list of events leading to a command */ std::vector<std::string> getCommandEvents(const std::string& command); - /// Executes a command. The only supported command is "bind event command" - bool command(const std::string& cmd); - protected: typedef std::map<std::string, Command> EventToCommandMap; Modified: trunk/src/services/input/InputService.cpp =================================================================== --- trunk/src/services/input/InputService.cpp 2009-03-13 15:27:20 UTC (rev 1159) +++ trunk/src/services/input/InputService.cpp 2009-03-15 00:47:35 UTC (rev 1160) @@ -46,7 +46,8 @@ mDirectListener(NULL), mMouse(NULL), mKeyboard(NULL), - mJoystick(NULL) { + mJoystick(NULL) + { // Loop client definition mLoopClientDef.id = LOOPCLIENT_ID_INPUT; @@ -54,189 +55,31 @@ mLoopClientDef.priority = LOOPCLIENT_PRIORITY_INPUT; mLoopClientDef.name = mName; - // Initialize the valid keys - registerValidKey(KC_ESCAPE, "esc"); - - registerValidKey(KC_1, "1"); - registerValidKey(KC_2, "2"); - registerValidKey(KC_3, "3"); - registerValidKey(KC_4, "4"); - registerValidKey(KC_5, "5"); - registerValidKey(KC_6, "6"); - registerValidKey(KC_7, "7"); - registerValidKey(KC_8, "8"); - registerValidKey(KC_9, "9"); - registerValidKey(KC_0, "0"); - - registerValidKey(KC_MINUS, "-"); - registerValidKey(KC_EQUALS, "="); - registerValidKey(KC_BACK, "backspace"); - registerValidKey(KC_TAB, "tab"); - - registerValidKey(KC_Q, "q"); - registerValidKey(KC_W, "w"); - registerValidKey(KC_E, "e"); - registerValidKey(KC_R, "r"); - registerValidKey(KC_T, "t"); - registerValidKey(KC_Y, "y"); - registerValidKey(KC_U, "u"); - registerValidKey(KC_I, "i"); - registerValidKey(KC_O, "o"); - registerValidKey(KC_P, "p"); - - registerValidKey(KC_LBRACKET, "["); - registerValidKey(KC_RBRACKET, "]"); - registerValidKey(KC_RETURN, "enter"); - registerValidKey(KC_LCONTROL, "ctrl"); // Not identified - left right? - - registerValidKey(KC_A, "a"); - registerValidKey(KC_S, "s"); - registerValidKey(KC_D, "d"); - registerValidKey(KC_F, "f"); - registerValidKey(KC_G, "g"); - registerValidKey(KC_H, "h"); - registerValidKey(KC_J, "j"); - registerValidKey(KC_K, "k"); - registerValidKey(KC_L, "l"); - registerValidKey(KC_SEMICOLON, ";"); - registerValidKey(KC_APOSTROPHE, "'"); - registerValidKey(KC_GRAVE, "~"); // This is also '`' it seems. Hmm. Why do they set the key twice? Are those separate on some keyboards? - registerValidKey(KC_LSHIFT, "shift"); - registerValidKey(KC_BACKSLASH, "\\"); - registerValidKey(KC_Z, "z"); - registerValidKey(KC_X, "x"); - registerValidKey(KC_C, "c"); - registerValidKey(KC_V, "v"); - registerValidKey(KC_B, "b"); - registerValidKey(KC_N, "n"); - registerValidKey(KC_M, "m"); - registerValidKey(KC_COMMA, ","); - registerValidKey(KC_PERIOD, "."); - registerValidKey(KC_SLASH, "/"); - registerValidKey(KC_RSHIFT, "shift"); - registerValidKey(KC_MULTIPLY, "keypad_star"); // Keypad star? - registerValidKey(KC_LMENU, "alt"); - registerValidKey(KC_SPACE, "space"); - // registerValidKey(KC_CAPITAL, ""); // CAPS_LOCK? - registerValidKey(KC_F1, "f1"); - registerValidKey(KC_F2, "f2"); - registerValidKey(KC_F3, "f3"); - registerValidKey(KC_F4, "f4"); - registerValidKey(KC_F5, "f5"); - registerValidKey(KC_F6, "f6"); - registerValidKey(KC_F7, "f7"); - registerValidKey(KC_F8, "f8"); - registerValidKey(KC_F9, "f9"); - registerValidKey(KC_F10, "f10"); - registerValidKey(KC_NUMLOCK, "numlock"); - registerValidKey(KC_SCROLL, "scroll"); - registerValidKey(KC_NUMPAD7, "keypad_home"); - registerValidKey(KC_NUMPAD8, "keypad_up"); - registerValidKey(KC_NUMPAD9, "keypad_pgup"); - registerValidKey(KC_SUBTRACT, "keypad_minus"); - registerValidKey(KC_NUMPAD4, "keypad_left"); - registerValidKey(KC_NUMPAD5, "keypad_center"); - registerValidKey(KC_NUMPAD6, "keypad_right"); - registerValidKey(KC_ADD, "keypad_plus"); - registerValidKey(KC_NUMPAD1, "keypad_end"); - registerValidKey(KC_NUMPAD2, "keypad_down"); - registerValidKey(KC_NUMPAD3, "keypad_pgdn"); - registerValidKey(KC_NUMPAD0, "keypad_ins"); - registerValidKey(KC_DECIMAL, "keypad_del"); - // registerValidKey(KC_OEM_102, ""); // ? - registerValidKey(KC_F11, "f11"); - registerValidKey(KC_F12, "f12"); - registerValidKey(KC_F13, "f13"); - registerValidKey(KC_F14, "f14"); - registerValidKey(KC_F15, "f15"); - - // It would be nice to include these at least in some non-compatibility mode - // registerValidKey(KC_KANA, ""); // ? - // registerValidKey(KC_ABNT_C1, ""); - // registerValidKey(KC_CONVERT, ""); - // registerValidKey(KC_NOCONVERT, ""); - // registerValidKey(KC_YEN, ""); - // registerValidKey(KC_ABNT_C2, ""); - // registerValidKey(KC_NUMPADEQUALS, ""); - // registerValidKey(KC_PREVTRACK, ""); - // registerValidKey(KC_AT, ""); - // registerValidKey(KC_COLON, ""); - // registerValidKey(KC_UNDERLINE, ""); - // registerValidKey(KC_KANJI, ""); - // registerValidKey(KC_STOP, ""); - // registerValidKey(KC_AX, ""); - // registerValidKey(KC_UNLABELED, ""); - // registerValidKey(KC_NEXTTRACK, ""); - registerValidKey(KC_NUMPADENTER, "keypad_enter"); - // registerValidKey(KC_RCONTROL, ""); - // registerValidKey(KC_MUTE, ""); - // registerValidKey(KC_CALCULATOR, ""); - // registerValidKey(KC_PLAYPAUSE, ""); - // registerValidKey(KC_MEDIASTOP, ""); - //registerValidKey(KC_VOLUMEDOWN, ""); - // registerValidKey(KC_VOLUMEUP, ""); - // registerValidKey(KC_WEBHOME, ""); - // registerValidKey(KC_NUMPADCOMMA, ""); - // registerValidKey(KC_DIVIDE, ""); - // registerValidKey(KC_SYSRQ, ""); - registerValidKey(KC_RMENU, "alt"); - // registerValidKey(KC_PAUSE, ""); - registerValidKey(KC_HOME, "home"); - registerValidKey(KC_UP, "up"); - registerValidKey(KC_PGUP, "pgup"); - registerValidKey(KC_LEFT, "left"); - registerValidKey(KC_RIGHT, "right"); - registerValidKey(KC_END, "end"); - registerValidKey(KC_DOWN, "down"); - registerValidKey(KC_PGDOWN, "pgdn"); - registerValidKey(KC_INSERT, "ins"); - registerValidKey(KC_DELETE, "del"); - - // registerValidKey(KC_LWIN, ""); - // registerValidKey(KC_RWIN, ""); - // registerValidKey(KC_APPS, ""); - // registerValidKey(KC_POWER, ""); - // registerValidKey(KC_SLEEP, ""); - // registerValidKey(KC_WAKE, ""); - // registerValidKey(KC_WEBSEARCH, ""); - // registerValidKey(KC_WEBFAVORITES, ""); - // registerValidKey(KC_WEBREFRESH, ""); - // registerValidKey(KC_WEBSTOP, ""); - // registerValidKey(KC_WEBFORWARD, ""); - // registerValidKey(KC_WEBBACK, ""); - // registerValidKey(KC_MYCOMPUTER, ""); - // registerValidKey(KC_MAIL, ""); - // registerValidKey(KC_MEDIASELECT, ""); - - // For simplicity, I insert the mouse / joystick events as well - registerValidKey(KC_UNASSIGNED, "mouse_axisx"); - registerValidKey(KC_UNASSIGNED, "mouse_axisy"); - - registerValidKey(KC_UNASSIGNED, "mouse1"); - registerValidKey(KC_UNASSIGNED, "mouse2"); - registerValidKey(KC_UNASSIGNED, "mouse3"); - - registerValidKey(KC_UNASSIGNED, "joy_axisx"); - registerValidKey(KC_UNASSIGNED, "joy_axisy"); + mCurrentMapper = new InputEventMapper(this); } //------------------------------------------------------ - InputService::~InputService() { + InputService::~InputService() + { mMappers.clear(); mCurrentMapper = NULL; - if (mInputSystem) { - if( mMouse ) { + if (mInputSystem) + { + if( mMouse ) + { mInputSystem->destroyInputObject( mMouse ); mMouse = NULL; } - if( mKeyboard ) { + if( mKeyboard ) + { mInputSystem->destroyInputObject( mKeyboard ); mKeyboard = NULL; } - if( mJoystick ) { + if( mJoystick ) + { mInputSystem->destroyInputObject( mJoystick ); mJoystick = NULL; } @@ -253,55 +96,274 @@ } //------------------------------------------------------ - void InputService::createBindContext(const std::string& ctx) { - ContextToMapper::const_iterator it = mMappers.find(ctx); + void InputService::RegisterValidKey(int kc, const std::string& txt) + { + mKeyMap.insert(make_pair(kc, txt)); + mReverseKeyMap.insert(make_pair(txt, kc)); + } - if (it == mMappers.end()) { - InputEventMapperPtr mapper = new InputEventMapper(this); - mMappers.insert(make_pair(ctx, mapper)); - } else { - LOG_ERROR("InputService::createBindContext: Context already exists: %s", ctx.c_str()); - } + //------------------------------------------------------ + void InputService::InitKeyMap() + { + RegisterValidKey(KC_ESCAPE, "esc"); + + RegisterValidKey(KC_1, "1"); + RegisterValidKey(KC_1 | SHIFT_MOD, "!"); + RegisterValidKey(KC_2, "2"); + RegisterValidKey(KC_2 | SHIFT_MOD, "@"); + RegisterValidKey(KC_3, "3"); + RegisterValidKey(KC_3 | SHIFT_MOD, "#"); + RegisterValidKey(KC_4, "4"); + RegisterValidKey(KC_4 | SHIFT_MOD, "$"); + RegisterValidKey(KC_5, "5"); + RegisterValidKey(KC_5 | SHIFT_MOD, "%"); + RegisterValidKey(KC_6, "6"); + RegisterValidKey(KC_6 | SHIFT_MOD, "^"); + RegisterValidKey(KC_7, "7"); + RegisterValidKey(KC_7 | SHIFT_MOD, "&"); + RegisterValidKey(KC_8, "8"); + RegisterValidKey(KC_8 | SHIFT_MOD, "*"); + RegisterValidKey(KC_9, "9"); + RegisterValidKey(KC_9 | SHIFT_MOD, "("); + RegisterValidKey(KC_0, "0"); + RegisterValidKey(KC_0 | SHIFT_MOD, ")"); + + RegisterValidKey(KC_MINUS, "-"); + RegisterValidKey(KC_MINUS | SHIFT_MOD, "_"); + RegisterValidKey(KC_EQUALS, "="); + RegisterValidKey(KC_EQUALS | SHIFT_MOD, "+"); + RegisterValidKey(KC_BACK, "backspace"); + RegisterValidKey(KC_TAB, "tab"); + + RegisterValidKey(KC_Q, "q"); + RegisterValidKey(KC_W, "w"); + RegisterValidKey(KC_E, "e"); + RegisterValidKey(KC_R, "r"); + RegisterValidKey(KC_T, "t"); + RegisterValidKey(KC_Y, "y"); + RegisterValidKey(KC_U, "u"); + RegisterValidKey(KC_I, "i"); + RegisterValidKey(KC_O, "o"); + RegisterValidKey(KC_P, "p"); + + RegisterValidKey(KC_LBRACKET, "["); + RegisterValidKey(KC_LBRACKET | SHIFT_MOD, "{"); + RegisterValidKey(KC_RBRACKET, "]"); + RegisterValidKey(KC_RBRACKET | SHIFT_MOD, "}"); + RegisterValidKey(KC_RETURN, "enter"); + RegisterValidKey(KC_LCONTROL, "ctrl"); + + RegisterValidKey(KC_A, "a"); + RegisterValidKey(KC_S, "s"); + RegisterValidKey(KC_D, "d"); + RegisterValidKey(KC_F, "f"); + RegisterValidKey(KC_G, "g"); + RegisterValidKey(KC_H, "h"); + RegisterValidKey(KC_J, "j"); + RegisterValidKey(KC_K, "k"); + RegisterValidKey(KC_L, "l"); + RegisterValidKey(KC_SEMICOLON, ";"); + RegisterValidKey(KC_SEMICOLON | SHIFT_MOD, ":"); + RegisterValidKey(KC_APOSTROPHE, "'"); + RegisterValidKey(KC_APOSTROPHE | SHIFT_MOD, "\""); + RegisterValidKey(KC_LSHIFT, "shift"); + RegisterValidKey(KC_BACKSLASH, "\\"); + RegisterValidKey(KC_BACKSLASH | SHIFT_MOD, "|"); + RegisterValidKey(KC_Z, "z"); + RegisterValidKey(KC_X, "x"); + RegisterValidKey(KC_C, "c"); + RegisterValidKey(KC_V, "v"); + RegisterValidKey(KC_B, "b"); + RegisterValidKey(KC_N, "n"); + RegisterValidKey(KC_M, "m"); + RegisterValidKey(KC_COMMA, ","); + RegisterValidKey(KC_COMMA | SHIFT_MOD, "<"); + RegisterValidKey(KC_PERIOD, "."); + RegisterValidKey(KC_PERIOD | SHIFT_MOD, ">"); + RegisterValidKey(KC_SLASH, "/"); + RegisterValidKey(KC_SLASH, "keypad_slash"); + RegisterValidKey(KC_SLASH | SHIFT_MOD, "?"); + RegisterValidKey(KC_RSHIFT, "shift"); + RegisterValidKey(KC_MULTIPLY, "keypad_star"); + RegisterValidKey(KC_LMENU, "alt"); + RegisterValidKey(KC_SPACE, "space"); + RegisterValidKey(KC_F1, "f1"); + RegisterValidKey(KC_F2, "f2"); + RegisterValidKey(KC_F3, "f3"); + RegisterValidKey(KC_F4, "f4"); + RegisterValidKey(KC_F5, "f5"); + RegisterValidKey(KC_F6, "f6"); + RegisterValidKey(KC_F7, "f7"); + RegisterValidKey(KC_F8, "f8"); + RegisterValidKey(KC_F9, "f9"); + RegisterValidKey(KC_F10, "f10"); + RegisterValidKey(KC_NUMLOCK, "numlock"); + RegisterValidKey(KC_SCROLL, "scroll"); + RegisterValidKey(KC_NUMPAD7, "keypad_home"); + RegisterValidKey(KC_NUMPAD8, "keypad_up"); + RegisterValidKey(KC_NUMPAD9, "keypad_pgup"); + RegisterValidKey(KC_SUBTRACT, "keypad_minus"); + RegisterValidKey(KC_NUMPAD4, "keypad_left"); + RegisterValidKey(KC_NUMPAD5, "keypad_center"); + RegisterValidKey(KC_NUMPAD6, "keypad_right"); + RegisterValidKey(KC_ADD, "keypad_plus"); + RegisterValidKey(KC_NUMPAD1, "keypad_end"); + RegisterValidKey(KC_NUMPAD2, "keypad_down"); + RegisterValidKey(KC_NUMPAD3, "keypad_pgdn"); + RegisterValidKey(KC_NUMPAD0, "keypad_ins"); + RegisterValidKey(KC_DECIMAL, "keypad_del"); + RegisterValidKey(KC_F11, "f11"); + RegisterValidKey(KC_F12, "f12"); + RegisterValidKey(KC_F13, "f13"); + RegisterValidKey(KC_F14, "f14"); + RegisterValidKey(KC_F15, "f15"); + + RegisterValidKey(KC_NUMPADENTER, "keypad_enter"); + RegisterValidKey(KC_RMENU, "alt"); + RegisterValidKey(KC_HOME, "home"); + RegisterValidKey(KC_UP, "up"); + RegisterValidKey(KC_PGUP, "pgup"); + RegisterValidKey(KC_LEFT, "left"); + RegisterValidKey(KC_RIGHT, "right"); + RegisterValidKey(KC_END, "end"); + RegisterValidKey(KC_DOWN, "down"); + RegisterValidKey(KC_PGDOWN, "pgdn"); + RegisterValidKey(KC_INSERT, "ins"); + RegisterValidKey(KC_DELETE, "del"); + RegisterValidKey(KC_GRAVE, "`"); + RegisterValidKey(KC_GRAVE | SHIFT_MOD, "~"); + RegisterValidKey(KC_SYSRQ, "print_screen"); + RegisterValidKey(joy_axisr, "joy_axisr"); + RegisterValidKey(joy_axisx, "joy_axisx"); + RegisterValidKey(joy_axisy, "joy_axisy"); + RegisterValidKey(joy_hat_up, "joy_hat_up"); + RegisterValidKey(joy_hat_down, "joy_hat_down"); + RegisterValidKey(joy_hat_right, "joy_hat_right"); + RegisterValidKey(joy_hat_left, "joy_hat_left"); + RegisterValidKey(joy_1, "joy_1"); + RegisterValidKey(joy_2, "joy_2"); + RegisterValidKey(joy_3, "joy_3"); + RegisterValidKey(joy_4, "joy_4"); + RegisterValidKey(joy_5, "joy_5"); + RegisterValidKey(joy_6, "joy_6"); + RegisterValidKey(joy_7, "joy_7"); + RegisterValidKey(joy_8, "joy_8"); + RegisterValidKey(joy_9, "joy_9"); + RegisterValidKey(Mouse1, "mouse1"); + RegisterValidKey(Mouse2, "mouse2"); + RegisterValidKey(Mouse3, "mouse3"); + RegisterValidKey(Mouse4, "mouse4"); + RegisterValidKey(Mouse5, "mouse5"); + RegisterValidKey(Mouse6, "mouse6"); + RegisterValidKey(Mouse7, "mouse7"); + RegisterValidKey(Mouse8, "mouse8"); + RegisterValidKey(Mouse_axisx, "mouse_axisx"); + RegisterValidKey(Mouse_axisy, "mouse_axisy"); + RegisterValidKey(Mouse_wheel, "mouse_wheel"); } //------------------------------------------------------ - void InputService::registerValidKey(OIS::KeyCode kc, const std::string& txt) { - mKeyMap.insert(make_pair(kc, txt)); - mReverseKeyMap.insert(make_pair(txt, kc)); + void InputService::Tokenize(std::string InString, std::vector<std::string> &OutVector, char Token) + { + unsigned int OldOffset = 0, NewOffset; + + do + { + NewOffset = InString.find(Token, OldOffset); + if((NewOffset == string::npos) || (InString.at(OldOffset) == 0x22)) + NewOffset = InString.length(); + OutVector.push_back (InString.substr(OldOffset, NewOffset - OldOffset)); + OldOffset = NewOffset + 1; + } + while(OldOffset < InString.length()); } //------------------------------------------------------ - bool InputService::isKeyTextValid(std::string& txt) { - ReverseKeyMap::const_iterator it = mReverseKeyMap.find(txt); + int InputService::MapToOISCode(std::string Key) + { + int Code; + ReverseKeyMap::const_iterator it = mReverseKeyMap.find(Key); if (it != mReverseKeyMap.end()) - return true; + Code = it->second; else - return false; + Code = KC_UNASSIGNED; //If we get here, then there is a key name that DarkEngine creates that we didn't cover + + return Code; } //------------------------------------------------------ - OIS::KeyCode InputService::getKeyTextCode(std::string& txt) { - ReverseKeyMap::const_iterator it = mReverseKeyMap.find(txt); + bool InputService::LoadBNDFile(const std::string& FileName) + { + ContentsVector Contents; + BindFileCommands BindCommands; - if (it != mReverseKeyMap.end()) - return it->second; - else - return KC_UNASSIGNED; + if(Ogre::ResourceGroupManager::getSingleton().resourceExists(ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, FileName) == false) + return false; + + Ogre::DataStreamPtr Stream = Ogre::ResourceGroupManager::getSingleton().openResource(FileName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true); + + while (!Stream->eof()) + { + std::string Line = Stream->getLine(); + if((Line.length() == 0) || (Line.at(0) == ';')) + continue; + std::transform(Line.begin(), Line.end(), Line.begin(), tolower); //Lowercase + Tokenize(Line, Contents, ' '); + if(Contents.at(0) == "bind") + BindCommands.push_back (Contents); + Contents.clear(); + } + + + for(BindFileCommands::const_iterator Command = BindCommands.begin(); Command != BindCommands.end(); Command++) + { + int Modifier = 0; + std::string Key, Keys = Command->at(1); + + if((Keys.length() > 1) && (Keys.find('+') != string::npos)) + { + Contents.clear(); + Tokenize(Keys, Contents, '+'); + for(ContentsVector::const_iterator Content = Contents.begin(); Content != Contents.end(); Content++) + { + std::string ContentStr = *Content; + if (ContentStr == "shift") + Modifier |= SHIFT_MOD; + else if (ContentStr == "ctrl") + Modifier |= CTRL_MOD; + else if (ContentStr == "alt") + Modifier |= ALT_MOD; + else + Key = ContentStr; + } + } + else + Key = Keys; + + int Code = MapToOISCode(Key); + CommandMap.insert(make_pair(Code | Modifier, Command->at(2))); + } + + return true; } //------------------------------------------------------ - std::string InputService::getKeyText(OIS::KeyCode kc) { - KeyMap::const_iterator it = mKeyMap.find(kc); + void InputService::createBindContext(const std::string& ctx) + { + ContextToMapper::const_iterator it = mMappers.find(ctx); - if (it != mKeyMap.end()) - return it->second; - else - return ""; + if (it == mMappers.end()) { + InputEventMapperPtr mapper = new InputEventMapper(this); + mMappers.insert(make_pair(ctx, mapper)); + } else { + LOG_ERROR("InputService::createBindContext: Context already exists: %s", ctx.c_str()); + } } //------------------------------------------------------ - bool InputService::init() { + bool InputService::init() + { OIS::ParamList paramList; size_t windowHnd = 0; std::ostringstream windowHndStr; @@ -316,7 +378,7 @@ // Fill parameter list windowHndStr << (unsigned int) windowHnd; - paramList.insert( std::make_pair( std::string( "WINDOW" ), windowHndStr.str() ) ); + paramList.insert( std::make_pair( std::string( "WINDOW" ), windowHndStr.str())); // Non-exclusive input - for debugging purposes bool nonex = false; @@ -324,7 +386,8 @@ if (mConfigService->hasParam("nonexclusive")) nonex = mConfigService->getParam("nonexclusive").toBool(); - if (nonex) { + if (nonex) + { #if defined OIS_WIN32_PLATFORM paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND" ))); paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE"))); @@ -349,9 +412,10 @@ #if OIS_VERSION >= 66048 if( mInputSystem->getNumberOfDevices(OIS::OISKeyboard) > 0 ) { #else - if( mInputSystem->numKeyboards() > 0 ) { + if( mInputSystem->numKeyboards() > 0 ) + { #endif - mKeyboard = static_cast<OIS::Keyboard*>( mInputSystem->createInputObject( OIS::OISKeyboard, true ) ); + mKeyboard = static_cast<OIS::Keyboard*>( mInputSystem->createInputObject( OIS::OISKeyboard, true)); mKeyboard->setEventCallback( this ); LOG_INFO("Found keyboard %s", mKeyboard->vendor().c_str()); } @@ -360,16 +424,17 @@ #if OIS_VERSION >= 66048 if( mInputSystem->getNumberOfDevices(OIS::OISMouse) > 0 ) { #else - if( mInputSystem->numMice() > 0 ) { + if( mInputSystem->numMice() > 0 ) + { #endif - mMouse = static_cast<OIS::Mouse*>( mInputSystem->createInputObject( OIS::OISMouse, true ) ); + mMouse = static_cast<OIS::Mouse*>( mInputSystem->createInputObject( OIS::OISMouse, true)); mMouse->setEventCallback( this ); LOG_INFO("Found mouse %s", mMouse->vendor().c_str()); // Get window size unsigned int width, height, depth; int left, top; - mRenderWindow->getMetrics( width, height, depth, left, top ); + mRenderWindow->getMetrics( width, height, depth, left, top); // Set mouse region const OIS::MouseState &mouseState = mMouse->getMouseState(); @@ -380,9 +445,10 @@ #if OIS_VERSION >= 66048 if( mInputSystem->getNumberOfDevices(OIS::OISJoyStick) > 0 ) { #else - if( mInputSystem->numJoySticks() > 0 ) { + if( mInputSystem->numJoySticks() > 0 ) + { #endif - mJoystick = static_cast<OIS::JoyStick*>( mInputSystem->createInputObject( OIS::OISJoyStick, true ) ); + mJoystick = static_cast<OIS::JoyStick*>( mInputSystem->createInputObject( OIS::OISJoyStick, true)); mJoystick->setEventCallback( this ); LOG_INFO("Found Joystick %s", mJoystick->vendor().c_str()); } @@ -391,41 +457,51 @@ mLoopService = static_pointer_cast<LoopService>(ServiceManager::getSingleton().getService("LoopService")); mLoopService->addLoopClient(this); + InitKeyMap(); + if(LoadBNDFile("user.bnd") == false) + LoadBNDFile("dark.bnd"); + return true; } //------------------------------------------------------ - void InputService::bootstrapFinished() { + void InputService::bootstrapFinished() + { // So the services will be able to catch up ServiceManager::getSingleton().createByMask(SERVICE_INPUT_LISTENER); } //------------------------------------------------------ - void InputService::shutdown() { + void InputService::shutdown() + { LOG_DEBUG("InputService::shutdown"); mConfigService.setNull(); } //------------------------------------------------------ - void InputService::loopStep(float deltaTime) { + void InputService::loopStep(float deltaTime) + { // TODO: For now. The code will move here for 0.3 captureInputs(); } //------------------------------------------------------ - void InputService::setBindContext(const std::string& context) { + void InputService::setBindContext(const std::string& context) + { InputEventMapperPtr iemp = findMapperForContext(context); - if (!iemp.isNull()) { + if (!iemp.isNull()) mCurrentMapper = iemp; - } else { + else + { mCurrentMapper = NULL; LOG_ERROR("InputService::setBindContext: invalid context specified: %s", context.c_str()); } } //------------------------------------------------------ - std::string InputService::fillVariables(const std::string& src) const { + std::string InputService::fillVariables(const std::string& src) const + { // This is quite bad implementation actually. // Should use a StringTokenizer with custom rule ($ and some non-alpha like space etc split). @@ -438,7 +514,8 @@ bool first = true; - while (!st.end()) { + while (!st.end()) + { if (!first) result += " "; @@ -449,157 +526,47 @@ if (var == "") continue; - if (var.substr(0,1) == "$") { - ValueMap::const_iterator it = mVariables.find(var.substr(1,var.length()-1)); + if (var.substr(0,1) == "$") + { + ValueMap::const_iterator it = mVariables.find(var.substr(1, var.length() - 1)); if (it != mVariables.end()) result += it->second.toString(); else result += var; - } else { + } + else result += var; - } } return result; } //------------------------------------------------------ - DVariant InputService::command(const std::string& command) { - LOG_DEBUG("InputService::command: '%s'", command.c_str()); - - string cmd = fillVariables(stripComment(command)); - - // Peek at first or second position. If we find bind command - WhitespaceStringTokenizer st(cmd, false); - - if (st.end()) { - LOG_DEBUG("InputService::command: Empty Line?"); - return false; - } - - string f = st.next(); - - if (f == "bind") { - LOG_DEBUG("InputService::command: Bind cmd for current ctx..."); - - if (!mCurrentMapper.isNull()) - return mCurrentMapper->command(cmd); - else { - LOG_ERROR("InputService::command: Current context is NULL! Can't bind..."); - return false; - } - - } else if (f == "echo") { - LOG_DEBUG("InputService::command: Echo cmd"); - - // return the string past the command - return st.rest(); - } else if (f == "set") { - LOG_DEBUG("InputService::command: set cmd"); - // "set var val" - var without dollar sign - - if (st.end()) - LOG_ERROR("Incomplete set line encountered (missing variable name): %s", command.c_str()); - - string var = st.next(); - - if (var == "") - LOG_ERROR("Incomplete set line encountered (missing variable name): %s", command.c_str()); - - if (st.end()) - LOG_ERROR("Incomplete set line encountered (missing variable value): %s", command.c_str()); - - string val = st.next(); - - mVariables[var] = DVariant(val); - - } else if (hasCommandTrap(f)) { - string f1 = ""; - - if (!st.end()) - f1 = st.rest(); - - InputEventMsg msg; - msg.command = f; - msg.event = IET_COMMAND_CALL; - msg.params = f1; - - callCommandTrap(msg); - - return true; - } - - if (st.end()) { - LOG_DEBUG("InputService::command: incomplete command?"); - return false; - } - - string f1 = st.next(); - - if (f1 == "bind") { - LOG_DEBUG("InputService::command: bind for context %s", f.c_str()); - InputEventMapperPtr imp = findMapperForContext(f); - - if (!imp.isNull()) - return imp->command(f1); - else - LOG_ERROR("Unknown context for binding operation : %s", f.c_str()); - } - - // Default process: set variable value - setVariable(f, f1); - - return false; - } - - //------------------------------------------------------ - bool InputService::validateEventString(const std::string& ev) { - - IsChar Splitter('+'); - - if(ev.length() == 1) - Splitter = ' '; - - StringTokenizer stc(ev, Splitter, false); - - while (!stc.end()) { - string key = stc.next(); - - LOG_DEBUG("InputService::validateEventString: Validating key part: %s", key.c_str()); - - // search for the definition of the given key. if not found, return false - if (!isKeyTextValid(key)) { - LOG_ERROR("InputService::validateEventString: Encountered an invalid key code: %s", key.c_str()); - return false; - } - } - - return true; - } - - //------------------------------------------------------ - InputEventMapperPtr InputService::findMapperForContext(const std::string& ctx) { + InputEventMapperPtr InputService::findMapperForContext(const std::string& ctx) + { ContextToMapper::const_iterator it = mMappers.find(ctx); if (it != mMappers.end()) return it->second; else return NULL; - } //------------------------------------------------------ /// char classifier (is comment) - struct IsComment : public std::unary_function<char, bool> { - bool operator()(char c) { + struct IsComment : public std::unary_function<char, bool> + { + bool operator()(char c) + { return c==';'; } }; //------------------------------------------------------ - std::string InputService::stripComment(const std::string& cmd) { + std::string InputService::stripComment(const std::string& cmd) + { IsComment isC; string::const_iterator it = find_if(cmd.begin(), cmd.end(), isC); @@ -608,79 +575,46 @@ } //------------------------------------------------------ - void InputService::loadBNDFile(const std::string& filename) { - // open as ogre::data_stream, read line by line, execute as command - Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().openResource(filename, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true); - - //TODO: To be completely glad, I'd have to write a line reading functionality in File class. not there now, I'm afraid - - while (!stream->eof()) { - std::string line = stream->getLine(); - - // send to the command processing - command(line); - } - } - - - //------------------------------------------------------ - DVariant InputService::getVariable(const std::string& var) { + DVariant InputService::getVariable(const std::string& var) + { ValueMap::const_iterator it = mVariables.find(var); - if (it != mVariables.end()) { + if (it != mVariables.end()) return it->second; - } else + else return DVariant(); } //------------------------------------------------------ - void InputService::setVariable(const std::string& var, const DVariant& val) { + void InputService::setVariable(const std::string& var, const DVariant& val) + { LOG_DEBUG("InputService::setVariable: '%s' -> %s", var.c_str(), val.toString().c_str()); ValueMap::iterator it = mVariables.find(var); - if (it != mVariables.end()) { + if (it != mVariables.end()) it->second = val; - } else { + else mVariables.insert(make_pair(var, val)); - } } - //------------------------------------------------------ - void InputService::attachModifiers(std::string& tgt) { - // Order is cruical here. The bindings also use this order (and it is ALT, CTRL, SHIFT) - if (mKeyboard->isModifierDown(Keyboard::Alt)) { - tgt += "+" + getKeyText(KC_LMENU); - } - - if (mKeyboard->isModifierDown(Keyboard::Ctrl)) { - tgt += "+" + getKeyText(KC_LCONTROL); - } - - if (mKeyboard->isModifierDown(Keyboard::Shift)) { - tgt += "+" + getKeyText(KC_LSHIFT); - } - } - - //------------------------------------------------------ - void InputService::captureInputs() { - if( mMouse ) { + void InputService::captureInputs() + { + if( mMouse ) mMouse->capture(); - } - if( mKeyboard ) { + if( mKeyboard ) mKeyboard->capture(); - } - if( mJoystick ) { + if( mJoystick ) mJoystick->capture(); - } // now iterate through the events, for the repeated events, dispatch command } //------------------------------------------------------ - void InputService::processKeyEvent(const OIS::KeyEvent &e, InputEventType t) { + void InputService::ProcessKeyEvent(const OIS::KeyEvent &e, InputEventType t) + { // Some safety checks if (mInputMode == IM_DIRECT) return; @@ -691,98 +625,152 @@ } // dispatch the key event using the mapper - string key = getKeyText(e.key); + int Key = (int)e.key; - InputEventMapper::Command result; + if (mKeyboard->isModifierDown(Keyboard::Alt)) + Key |= ALT_MOD; + if (mKeyboard->isModifierDown(Keyboard::Ctrl)) + Key |= CTRL_MOD; + if (mKeyboard->isModifierDown(Keyboard::Shift)) + Key |= SHIFT_MOD; - // first cycle without mods, second with them - for (int it = 0; it < 2; it++) { // Just to run this two times + std::string Command; + CommandMapVector::const_iterator it = CommandMap.find(Key); + if (it != CommandMap.end()) + Command = it->second; + else + return; - // Try to find the key without the modifiers - if (mCurrentMapper->unmapEvent(key, result)) { - // TODO: Send the event - // Split the command to cmd and params parts - std::pair<string, string> split = splitCommand(result.command); + InputEventMsg Msg; + std::pair<string, string> Split = splitCommand(Command); - InputEventMsg msg; + Msg.command = Split.first; + Msg.params = Split.second; + Msg.event = t; - msg.command = split.first; - msg.params = split.second; - msg.event = t; + if (Command[0] == '+') + { + if (t == IET_KEYBOARD_PRESS) + Msg.params = 1.0f; + else + Msg.params = 0.0f; + Command = Command.substr(1); + } + else if (Command[0] == '-') + { + if (t == IET_KEYBOARD_PRESS) + Msg.params = 0.0f; + else + Msg.params = 1.0f; + Command = Command.substr(1); + } - // If it is denoted by plus sign, we replace the param with on/off 1.0/0.0 (- does the opposite, really) - if (result.type == InputEventMapper::CET_PEDGE) { - if (t == IET_KEYBOARD_PRESS) - msg.params = 1.0f; - else - msg.params = 0.0f; - } else if (result.type == InputEventMapper::CET_NEDGE) { - if (t == IET_KEYBOARD_PRESS) - msg.params = 0.0f; - else - msg.params = 1.0f; - } + callCommandTrap(Msg); + } - // No key repeat for now... - // If it would be CET_NORMAL. We could mark the event as running, then process every frame/key repeat - // Don't worry. It will definatelly be implemented. + //------------------------------------------------------ + void InputService::ProcessJoyMouseEvent(int Id, InputEventType Event) + { + // Some safety checks + if (mInputMode == IM_DIRECT) + return; - // If the binding is not +/-, only progress on button press. This will be handled differently with the key repeats - if (t != IET_KEYBOARD_RELEASE && result.type == InputEventMapper::CET_NORMAL) - if (callCommandTrap(msg)) - return; - } + if (mCurrentMapper.isNull()) { + LOG_ERROR("InputService::processKeyEvent: Mapped input, but no mapper set for the current state!"); + return; + } - // no event for the key itself, try the modifiers - attachModifiers(key); + // dispatch the key event using the mapper + int Button = Id; + if((Event == IET_MOUSE_PRESS) || (Event == IET_MOUSE_RELEASE)) + Button += DARK_MOUSE_EVENT; + else + Button += DARK_JOY_EVENT; + + std::string Command; + CommandMapVector::const_iterator it = CommandMap.find(Button); + if (it != CommandMap.end()) + Command = it->second; + else + return; + + InputEventMsg Msg; + std::pair<string, string> Split = splitCommand(Command); + + Msg.command = Split.first; + Msg.params = Split.second; + Msg.event = Event; + + if (Command[0] == '+') + { + if (Event == IET_MOUSE_PRESS) + Msg.params = 1.0f; + else + Msg.params = 0.0f; + Command = Command.substr(1); + } + else if (Command[0] == '-') + { + if (Event == IET_MOUSE_PRESS) + Msg.params = 0.0f; + else + Msg.params = 1.0f; + Command = Command.substr(1); } + callCommandTrap(Msg); } //------------------------------------------------------ - void InputService::registerCommandTrap(const std::string& command, const ListenerPtr& listener) { - if (mCommandTraps.find(command) != mCommandTraps.end()) { + void InputService::registerCommandTrap(const std::string& command, const ListenerPtr& listener) + { + if (mCommandTraps.find(command) != mCommandTraps.end()) + { // Already registered command. LOG an error LOG_ERROR("The command %s already has a registered trap. Not registering", command.c_str()); return; - } else { + } + else mCommandTraps.insert(make_pair(command, listener)); - } } //------------------------------------------------------ - void InputService::unregisterCommandTrap(const ListenerPtr& listener) { + void InputService::unregisterCommandTrap(const ListenerPtr& listener) + { // Iterate through the trappers, find the ones with this listener ptr, remove ListenerMap::iterator it = mCommandTraps.begin(); - while (it != mCommandTraps.end()) { + while (it != mCommandTraps.end()) + { ListenerMap::iterator pos = it++; - if (pos->second == listener) { + if (pos->second == listener) mCommandTraps.erase(pos); - } } } //------------------------------------------------------ - void InputService::unregisterCommandTrap(const std::string& command) { + void InputService::unregisterCommandTrap(const std::string& command) + { // Iterate through the trappers, find the ones with the given command name, remove ListenerMap::iterator it = mCommandTraps.begin(); - while (it != mCommandTraps.end()) { + while (it != mCommandTraps.end()) + { ListenerMap::iterator pos = it++; - if (pos->first == command) { + if (pos->first == command) mCommandTraps.erase(pos); - } } } //------------------------------------------------------ - bool InputService::callCommandTrap(const InputEventMsg& msg) { + bool InputService::callCommandTrap(const InputEventMsg& msg) + { ListenerMap::const_iterator it = mCommandTraps.find(msg.command); - if (it != mCommandTraps.end()) { + if (it != mCommandTraps.end()) + { (*it->second)(msg); return true; } @@ -791,16 +779,17 @@ } //------------------------------------------------------ - bool InputService::hasCommandTrap(const std::string& cmd) { - if (mCommandTraps.find(cmd) != mCommandTraps.end()) { + bool InputService::hasCommandTrap(const std::string& cmd) + { + if (mCommandTraps.find(cmd) != mCommandTraps.end()) return true; - } return false; } //------------------------------------------------------ - std::pair<std::string, std::string> InputService::splitCommand(const std::string& cmd) const { + std::pair<std::string, std::string> InputService::splitCommand(const std::string& cmd) const + { WhitespaceStringTokenizer stok(cmd); std::pair<std::string, std::string> res = make_pair("", ""); @@ -815,39 +804,40 @@ } //------------------------------------------------------ - bool InputService::keyPressed( const OIS::KeyEvent &e ) { + bool InputService::keyPressed(const OIS::KeyEvent &e) + { - if (mInputMode == IM_DIRECT) { // direct event, dispatch to the current listener - if (mDirectListener) + if (mInputMode == IM_DIRECT) + if (mDirectListener) // direct event, dispatch to the current listener return mDirectListener->keyPressed(e); - } else { - processKeyEvent(e, IET_KEYBOARD_PRESS); - } + else + ProcessKeyEvent(e, IET_KEYBOARD_PRESS); return false; } //------------------------------------------------------ - bool InputService::keyReleased( const OIS::KeyEvent &e ) { + bool InputService::keyReleased(const OIS::KeyEvent &e) + { - if (mInputMode == IM_DIRECT) { // direct event, dispatch to the current listener - if (mDirectListener) + if (mInputMode == IM_DIRECT) + if (mDirectListener) // direct event, dispatch to the current listener return mDirectListener->keyReleased(e); - } else { - // dispatch the key event using the mapper - processKeyEvent(e, IET_KEYBOARD_RELEASE); - } + else + ProcessKeyEvent(e, IET_KEYBOARD_RELEASE); return false; } //------------------------------------------------------ - bool InputService::mouseMoved( const OIS::MouseEvent &e ) { + bool InputService::mouseMoved(const OIS::MouseEvent &e) + { - if (mInputMode == IM_DIRECT) { // direct event, dispatch to the current listener - if (mDirectListener) + if (mInputMode == IM_DIRECT) + if (mDirectListener) // direct event, dispatch to the current listener return mDirectListener->mouseMoved(e); - } else { + else + { // dispatch the key event using the mapper } @@ -855,27 +845,28 @@ } //------------------------------------------------------ - bool InputService::mousePressed( const OIS::MouseEvent &e, OIS::MouseButtonID id ) { + bool InputService::mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id) + { + ProcessJoyMouseEvent((int) id, IET_MOUSE_PRESS); - if (mInputMode == IM_DIRECT) { // direct event, dispatch to the current listener - if (mDirectListener) + if (mInputMode == IM_DIRECT) + if (mDirectListener) // direct event, dispatch to the current listener return mDirectListener->mousePressed(e, id); - } else { - // dispatch the key event using the mapper - } + else + ProcessJoyMouseEvent((int) id, IET_MOUSE_PRESS); return false; } //------------------------------------------------------ - bool InputService::mouseReleased( const OIS::MouseEvent &e, OIS::MouseButtonID id ) { + bool InputService::mouseReleased( const OIS::MouseEvent &e, OIS::MouseButtonID id) + { - if (mInputMode == IM_DIRECT) { // direct event, dispatch to the current listener - if (mDirectListener) + if (mInputMode == IM_DIRECT) + if (mDirectListener) // direct event, dispatch to the current listener return mDirectListener->mouseReleased(e, id); - } else { - // dispatch the key event using the mapper - } + else + ProcessJoyMouseEvent((int) id, IET_MOUSE_RELEASE); return false; } @@ -886,10 +877,11 @@ if((arg.state.mAxes[axis].abs > JoyStick::MIN_AXIS / 10) && (arg.state.mAxes[axis].abs < JoyStick::MAX_AXIS / 10)) return true; //Eat the small axis movements. - if (mInputMode == IM_DIRECT) { // direct event, dispatch to the current listener - if (mDirectListener) + if (mInputMode == IM_DIRECT) + if (mDirectListener) // direct event, dispatch to the current listener return mDirectListener->axisMoved(arg, axis); - } else { + else + { // dispatch the key event using the mapper } @@ -897,12 +889,13 @@ } //------------------------------------------------------ - bool InputService::povMoved( const OIS::JoyStickEvent &e, int pov ) + bool InputService::povMoved(const OIS::JoyStickEvent &e, int pov) { - if (mInputMode == IM_DIRECT) { // direct event, dispatch to the current listener - if (mDirectListener) + if (mInputMode == IM_DIRECT) + if (mDirectListener) // direct event, dispatch to the current listener return mDirectListener->povMoved(e, pov); - } else { + else + { // dispatch the key event using the mapper } @@ -912,12 +905,13 @@ //------------------------------------------------------ bool InputService::buttonPressed(const JoyStickEvent &arg, int button) { - if (mInputMode == IM_DIRECT) { // direct event, dispatch to the current listener - if (mDirectListener) + ProcessJoyMouseEvent((int) button, IET_JOYSTICK_PRESS); + + if (mInputMode == IM_DIRECT) + if (mDirectListener) // direct event, dispatch to the current listener return mDirectListener->buttonPressed(arg, button); - } else { - // dispatch the key event using the mapper - } + else + ProcessJoyMouseEvent((int) button, IET_JOYSTICK_PRESS); return false; } @@ -925,12 +919,11 @@ //------------------------------------------------------ bool InputService::buttonReleased(const JoyStickEvent &arg, int button) { - if (mInputMode == IM_DIRECT) { // direct event, dispatch to the current listener - if (mDirectListener) + if (mInputMode == IM_DIRECT) + if (mDirectListener) // direct event, dispatch to the current listener return mDirectListener->buttonReleased(arg, button); - } else { - // dispatch the key event using the mapper - } + else + ProcessJoyMouseEvent((int) button, IET_JOYSTICK_RELEASE); return false; } @@ -938,20 +931,23 @@ //-------------------------- Factory implementation std::string InputServiceFactory::mName = "InputService"; - InputServiceFactory::InputServiceFactory() : ServiceFactory() { + InputServiceFactory::InputServiceFactory() : ServiceFactory() + { ServiceManager::getSingleton().addServiceFactory(this); - }; + } - const std::string& InputServiceFactory::getName() { + const std::string& InputServiceFactory::getName() + { return mName; } - const uint InputServiceFactory::getMask() { + const uint InputServiceFactory::getMask() + { return SERVICE_ENGINE; } - Service* InputServiceFactory::createInstance(ServiceManager* manager) { - return new InputService(manager, mName); + Service* InputServiceFactory::createInstance(ServiceManager* manager) + { + return new InputService(manager, mName); } - } Modified: trunk/src/services/input/InputService.h =================================================================== --- trunk/src/services/input/InputService.h 2009-03-13 15:27:20 UTC (rev 1159) +++ trunk/src/services/input/InputService.h 2009-03-15 00:47:35 UTC (rev 1160) @@ -65,8 +65,50 @@ IET_COMMAND_CALL } InputEventType; +#define SHIFT_MOD (1 << 31) +#define CTRL_MOD (1 << 30) +#define ALT_MOD (1 << 29) +#define DARK_JOY_EVENT (1 << 28) +#define DARK_MOUSE_EVENT (1 << 27) + + enum DarkJoyStickEvents + { + joy_axisr = DARK_JOY_EVENT, + joy_axisx, + joy_axisy, + joy_hat_up, + joy_hat_down, + joy_hat_right, + joy_hat_left, + joy_1, + joy_2, + joy_3, + joy_4, + joy_5, + joy_6, + joy_7, + joy_8, + joy_9 + }; + + enum DarkMouseEvents + { + Mouse1 = DARK_MOUSE_EVENT + OIS::MB_Left, + Mouse2 = DARK_MOUSE_EVENT + OIS::MB_Right, + Mouse3 = DARK_MOUSE_EVENT + OIS::MB_Middle, + Mouse4 = DARK_MOUSE_EVENT + OIS::MB_Button3, + Mouse5 = DARK_MOUSE_EVENT + OIS::MB_Button4, + Mouse6 = DARK_MOUSE_EVENT + OIS::MB_Button5, + Mouse7 = DARK_MOUSE_EVENT + OIS::MB_Button6, + Mouse8 = DARK_MOUSE_EVENT + OIS::MB_Button7, + Mouse_axisx, + Mouse_axisy, + Mouse_wheel + }; + /// Input event - typedef struct { + typedef struct + { InputEventType event; // unmapped command, or empty std::string command; @@ -75,7 +117,8 @@ } InputEventMsg; /// The state of input modifiers - typedef enum { + typedef enum + { /// Shift key modifier IST_SHIFT = 1, /// Alt key modifier @@ -85,7 +128,8 @@ } InputModifierState; /// The input mode - direct or translated to the commands - typedef enum { + typedef enum + { /// Direct mode IM_DIRECT = 1, /// Translated mode @@ -98,16 +142,17 @@ typedef OIS::MouseButtonID MouseButtonID;*/ /// Listener for the direct - unfiltered events. Typically one per application (GUIService for example) - class DirectInputListener { + class DirectInputListener + { public: virtual ~DirectInputListener() {}; - virtual bool keyPressed( const OIS::KeyEvent &e ) = 0; - virtual bool keyReleased( const OIS::KeyEvent &e ) = 0; + virtual bool keyPressed(const OIS::KeyEvent &e) = 0; + virtual bool keyReleased(const OIS::KeyEvent &e) = 0; - virtual bool mouseMoved( const OIS::MouseEvent &e ) = 0; - virtual bool mousePressed( const OIS::MouseEvent &e, OIS::MouseButtonID id ) = 0; - virtual bool mouseReleased( const OIS::MouseEvent &e, OIS::MouseButtonID id ) = 0; + virtual bool mouseMoved(const OIS::MouseEvent &e) = 0; + virtual bool mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id) = 0; + virtual bool mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id) = 0; virtual bool povMoved(const OIS::JoyStickEvent &e, int pov) = 0; virtual bool axisMoved(const OIS::JoyStickEvent &arg, int axis) = 0; @@ -124,7 +169,8 @@ * @todo +/without + binding modes - how they differ, how to implement the one with key repeat... * @todo BND file writing ability (needs cooperation with nonexistent platform service) */ - class OPDELIB_EXPORT InputService : public Service, public OIS::KeyListener, public OIS::MouseListener, public OIS::JoyStickListener, public LoopClient { + class OPDELIB_EXPORT InputService : public Service, public OIS::KeyListener, public OIS::MouseListener, public OIS::JoyStickListener, public LoopClient + { public: InputService(ServiceManager *manager, const std::string& name); virtual ~InputService(); @@ -132,18 +178,6 @@ /// Creates bind context (e.g. a switchable context, that maps events to commands if IM_MAPPED is active, using the mapper of this context) void createBindContext(const std::string& ctx); - /// returns true if the key text is a valid key name - bool isKeyTextValid(std::string& txt); - - /// returns ois::KeyCode code for the key text, or KC_UNASSIGNED if not found - OIS::KeyCode getKeyTextCode(std::string& txt); - - /// returns the mapped key text for the OIS key code - std::string getKeyText(OIS::KeyCode kc); - - /// Input Service command. If you call this one a line-by-line on .BND file, it should catch up and be ready to operate with the settings - DVariant command(const std::string& command); - /// Set a current bind context void setBindContext(const std::string& context); @@ -151,13 +185,13 @@ std::string fillVariables(const std::string& src) const; /// Sets the input mode to either direct or mapped (IM_DIRECT/IM_MAPPED) - void setInputMode(InputMode mode) { mInputMode = mode; }; + void setInputMode(InputMode mode) {mInputMode = mode;}; /** Loads a bindings file, possibly rebinding the current bindings * @param filename The filename of the bnd file to load * @todo dcontext The default context for bind commands not preceeded with the context information. Defaults to the current context if not specified */ - void loadBNDFile(const std::string& filename); + bool LoadBNDFile(const std::string& filename); /// TODO: void saveBNDFile(const std::string& filename); @@ -167,11 +201,6 @@ /// Variable setter (for mouse senitivity, etc) void setVariable(const std::string& var, const DVariant& val); - /** Validates the event string (checks for format "event[+modifier]") - * @return true if the string is valid, true otherwise - */ - bool validateEventString(const std::string& ev); - /// Definition of the command listener typedef Callback< InputEventMsg > Listener; @@ -188,10 +217,10 @@ void unregisterCommandTrap(const std::string& command); /// Sets a direct listener (only notified when IM_DIRECT is active) - void setDirectListener(DirectInputListener* listener) { mDirectListener = listener; }; + void setDirectListener(DirectInputListener* listener) {mDirectListener = listener;}; /// Clears the direct listener mapping - void unsetDirectListener() { mDirectListener = NULL; }; + void unsetDirectListener() {mDirectListener = NULL;}; /** Capture the inputs. Should be called every frame (Temporary code, will be removed after loop service is done) */ void captureInputs(); @@ -203,11 +232,12 @@ void loopStep(float deltaTime); - /// registers OIS::KeyCode to textual representation and inverse mappings - void registerValidKey(OIS::KeyCode kc, const std::string& txt); + void InitKeyMap(); + void Tokenize(std::string , std::vector<std::string> &OutVector, char Token); + int InputService::MapToOISCode(std::string Key); - /// Attaches the ctrl, alt and shift texts if they are pressed - void attachModifiers(std::string& tgt); + /// registers (int)OIS::KeyCode to textual representation and inverse mappings + void RegisterValidKey(int kc, const std::string& txt); /// Calls a trap for a command /// @returns true if the command was found, false otherwise @@ -220,21 +250,23 @@ std::pair<std::string, std::string> splitCommand(const std::string& cmd) const; /// Processes the received key event with current mapper, and if it finds a match, sends an event - void processKeyEvent(const OIS::KeyEvent &e, InputEventType t); + void ProcessKeyEvent(const OIS::KeyEvent &e, InputEventType t); + void ProcessJoyMouseEvent(int Id, InputEventType Event); + // ---- OIS input events ---- - bool keyPressed( const OIS::KeyEvent &e ); - bool keyReleased( const OIS::KeyEvent &e ); + bool keyPressed(const OIS::KeyEvent &e); + bool keyReleased(const OIS::KeyEvent &e); - bool mouseMoved( const OIS::MouseEvent &e ); - bool mousePressed( const OIS::MouseEvent &e, OIS::MouseButtonID id ); - bool mouseReleased( const OIS::MouseEvent &e, OIS::MouseButtonID id ); + bool mouseMoved(const OIS::MouseEvent &e); + bool mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id); + bool mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id); bool axisMoved(const OIS::JoyStickEvent &,int); bool buttonPressed(const OIS::JoyStickEvent &,int); bool buttonReleased(const OIS::JoyStickEvent &,int); - bool povMoved( const OIS::JoyStickEvent &, int ); + bool povMoved(const OIS::JoyStickEvent &, int); /// Finds a mapper (Or NULL) for the specified context InputEventMapperPtr findMapperForContext(const std::string& ctx); @@ -242,17 +274,23 @@ /// Strips a comment (any text after ';' including that character) std::string stripComment(const std::string& cmd); + typedef std::vector<std::string> ContentsVector; + + typedef std::vector<ContentsVector> BindFileCommands; + + typedef std::map<int, std::string> CommandMapVector; + /// Named context to an event mapper map typedef std::map< std::string, InputEventMapperPtr > ContextToMapper; /// string variable name to variant map typedef std::map< std::string, DVariant > ValueMap; - /// map of OIS::KeyCode to the code text - typedef std::map< OIS::KeyCode, std::string > KeyMap; // (lower case please) + /// map of (int)OIS::KeyCode to the code text + typedef std::map<int, std::string> KeyMap; // (lower case please) - /// map of the command text to the ois key code - typedef std::map< std::string, OIS::KeyCode > ReverseKeyMap; // (lower case please) + /// map of the command text to the (int) ois key code + typedef std::map<std::string, int> ReverseKeyMap; // (lower case please) /// map of command text to the handling listener typedef std::map< std::string, ListenerPtr > ListenerMap; @@ -268,10 +306,12 @@ /// Key map KeyMap mKeyMap; - + /// Reverse key map ReverseKeyMap mReverseKeyMap; + CommandMapVector CommandMap; + /// Current mapper InputEventMapperPtr mCurrentMapper; @@ -281,7 +321,7 @@ /// Map of the command trappers ListenerMap mCommandTraps; - /// Set of commands that receive events every refresh if the button is holded + /// Set of commands that receive events every refresh if the button is held CommandSet mOnPressCommands; /// Current direct listener @@ -315,7 +355,8 @@ typedef shared_ptr<InputService> InputServicePtr; /// Factory for the InputService objects - class OPDELIB_EXPORT InputServiceFactory : public ServiceFactory { + class OPDELIB_EXPORT InputServiceFactory : public ServiceFactory + { public: InputServiceFactory(); ~InputServiceFactory() {}; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |