diff options
Diffstat (limited to 'source/gameengine/GameLogic/SCA_KeyboardSensor.cpp')
-rw-r--r-- | source/gameengine/GameLogic/SCA_KeyboardSensor.cpp | 668 |
1 files changed, 0 insertions, 668 deletions
diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp deleted file mode 100644 index 414a685d358..00000000000 --- a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp +++ /dev/null @@ -1,668 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - * Sensor for keyboard input - */ - -/** \file gameengine/GameLogic/SCA_KeyboardSensor.cpp - * \ingroup gamelogic - */ - - -#include <stddef.h> - -#include "SCA_KeyboardSensor.h" -#include "SCA_KeyboardManager.h" -#include "SCA_LogicManager.h" -#include "EXP_StringValue.h" -#include "SCA_IInputDevice.h" - -extern "C" { - #include "BLI_string_utf8.h" - #include "BLI_string_cursor_utf8.h" -} - -/* ------------------------------------------------------------------------- */ -/* Native functions */ -/* ------------------------------------------------------------------------- */ - -SCA_KeyboardSensor::SCA_KeyboardSensor(SCA_KeyboardManager* keybdmgr, - short int hotkey, - short int qual, - short int qual2, - bool bAllKeys, - const STR_String& targetProp, - const STR_String& toggleProp, - SCA_IObject* gameobj, - short int exitKey) - :SCA_ISensor(gameobj,keybdmgr), - m_hotkey(hotkey), - m_qual(qual), - m_qual2(qual2), - m_bAllKeys(bAllKeys), - m_targetprop(targetProp), - m_toggleprop(toggleProp) -{ - if (hotkey == exitKey) - keybdmgr->GetInputDevice()->HookEscape(); -// SetDrawColor(0xff0000ff); - Init(); -} - - - -SCA_KeyboardSensor::~SCA_KeyboardSensor() -{ -} - -void SCA_KeyboardSensor::Init() -{ - // this function is used when the sensor is disconnected from all controllers - // by the state engine. It reinitializes the sensor as if it was just created. - // However, if the target key is pressed when the sensor is reactivated, it - // will not generated an event (see remark in Evaluate()). - m_val = (m_invert)?1:0; - m_reset = true; -} - -CValue* SCA_KeyboardSensor::GetReplica() -{ - SCA_KeyboardSensor* replica = new SCA_KeyboardSensor(*this); - // this will copy properties and so on... - replica->ProcessReplica(); - replica->Init(); - return replica; -} - - - -short int SCA_KeyboardSensor::GetHotkey() -{ - return m_hotkey; -} - - - -bool SCA_KeyboardSensor::IsPositiveTrigger() -{ - bool result = (m_val != 0); - - if (m_invert) - result = !result; - - return result; -} - - - -bool SCA_KeyboardSensor::TriggerOnAllKeys() -{ - return m_bAllKeys; -} - - - -bool SCA_KeyboardSensor::Evaluate() -{ - bool result = false; - bool reset = m_reset && m_level; - bool qual = true; - bool qual_change = false; - short int m_val_orig = m_val; - - SCA_IInputDevice* inputdev = ((SCA_KeyboardManager *)m_eventmgr)->GetInputDevice(); - // cerr << "SCA_KeyboardSensor::Eval event, sensing for "<< m_hotkey << " at device " << inputdev << "\n"; - - /* See if we need to do logging: togPropState exists and is - * different from 0 */ - CValue* myparent = GetParent(); - CValue* togPropState = myparent->GetProperty(m_toggleprop); - if (togPropState && - (((int)togPropState->GetNumber()) != 0) ) - { - LogKeystrokes(); - } - - m_reset = false; - - /* Now see whether events must be bounced. */ - if (m_bAllKeys) - { - bool justactivated = false; - bool justreleased = false; - bool active = false; - - for (int i=SCA_IInputDevice::KX_BEGINKEY ; i<= SCA_IInputDevice::KX_ENDKEY;i++) - { - const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i); - switch (inevent.m_status) - { - case SCA_InputEvent::KX_JUSTACTIVATED: - justactivated = true; - break; - case SCA_InputEvent::KX_JUSTRELEASED: - justreleased = true; - break; - case SCA_InputEvent::KX_ACTIVE: - active = true; - break; - case SCA_InputEvent::KX_NO_INPUTSTATUS: - /* do nothing */ - break; - } - } - - if (justactivated) - { - m_val=1; - result = true; - } else - { - if (justreleased) - { - m_val=(active)?1:0; - result = true; - } else - { - if (active) - { - if (m_val == 0) - { - m_val = 1; - if (m_level) { - result = true; - } - } - } else - { - if (m_val == 1) - { - m_val = 0; - result = true; - } - } - } - if (m_tap) - // special case for tap mode: only generate event for new activation - result = false; - } - - - } else - { - - // cerr << "======= SCA_KeyboardSensor::Evaluate:: peeking at key status" << endl; - const SCA_InputEvent & inevent = inputdev->GetEventValue( - (SCA_IInputDevice::KX_EnumInputs) m_hotkey); - - // cerr << "======= SCA_KeyboardSensor::Evaluate:: status: " << inevent.m_status << endl; - - - /* Check qualifier keys - * - see if the qualifiers we request are pressed - 'qual' true/false - * - see if the qualifiers we request changed their state - 'qual_change' true/false - */ - if (m_qual > 0) { - const SCA_InputEvent & qualevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) m_qual); - switch (qualevent.m_status) { - case SCA_InputEvent::KX_NO_INPUTSTATUS: - qual = false; - break; - case SCA_InputEvent::KX_JUSTRELEASED: - qual_change = true; - qual = false; - break; - case SCA_InputEvent::KX_JUSTACTIVATED: - qual_change = true; - case SCA_InputEvent::KX_ACTIVE: - /* do nothing */ - break; - } - } - if (m_qual2 > 0 && qual==true) { - const SCA_InputEvent & qualevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) m_qual2); - /* copy of above */ - switch (qualevent.m_status) { - case SCA_InputEvent::KX_NO_INPUTSTATUS: - qual = false; - break; - case SCA_InputEvent::KX_JUSTRELEASED: - qual_change = true; - qual = false; - break; - case SCA_InputEvent::KX_JUSTACTIVATED: - qual_change = true; - case SCA_InputEvent::KX_ACTIVE: - /* do nothing */ - break; - } - } - /* done reading qualifiers */ - - if (inevent.m_status == SCA_InputEvent::KX_NO_INPUTSTATUS) - { - if (m_val == 1) - { - // this situation may occur after a scene suspend: the keyboard release - // event was not captured, produce now the event off - m_val = 0; - result = true; - } - } else - { - if (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED) - { - m_val=1; - result = true; - } else - { - if (inevent.m_status == SCA_InputEvent::KX_JUSTRELEASED) - { - m_val = 0; - result = true; - } else - { - if (inevent.m_status == SCA_InputEvent::KX_ACTIVE) - { - if (m_val == 0) - { - m_val = 1; - if (m_level) - { - result = true; - } - } - } - } - } - } - - /* Modify the key state based on qual(s) - * Tested carefully. don't touch unless your really sure. - * note, this will only change the results if key modifiers are set. - * - * When all modifiers and keys are positive - * - pulse true - * - * When ANY of the modifiers or main key become inactive, - * - pulse false - */ - if (qual==false) { /* one of the qualifiers are not pressed */ - if (m_val_orig && qual_change) { /* we were originally enabled, but a qualifier changed */ - result = true; - } else { - result = false; - } - m_val = 0; /* since one of the qualifiers is not on, set the state to false */ - } else { /* we done have any qualifiers or they are all pressed */ - if (m_val && qual_change) { /* the main key state is true and our qualifier just changed */ - result = true; - } - } - /* done with key quals */ - - } - - if (reset) - // force an event - result = true; - return result; - -} - -void SCA_KeyboardSensor::AddToTargetProp(int keyIndex, int unicode) -{ - if (IsPrintable(keyIndex)) { - CValue* tprop = GetParent()->GetProperty(m_targetprop); - - if (IsDelete(keyIndex)) { - /* Make a new property. Deletes can be ignored. */ - if (tprop) { - /* overwrite the old property */ - /* strip one char, if possible */ - STR_String newprop = tprop->GetText(); - int oldlength = newprop.Length(); - if (oldlength >= 1 ) { - int newlength=oldlength; - - BLI_str_cursor_step_prev_utf8(newprop, newprop.Length(), &newlength); - newprop.SetLength(newlength); - - CStringValue * newstringprop = new CStringValue(newprop, m_targetprop); - GetParent()->SetProperty(m_targetprop, newstringprop); - newstringprop->Release(); - } - } - } - else { - char utf8_buf[7]; - size_t utf8_len; - - utf8_len = BLI_str_utf8_from_unicode(unicode, utf8_buf); - utf8_buf[utf8_len] = '\0'; - - STR_String newprop = tprop ? (tprop->GetText() + utf8_buf) : utf8_buf; - - CStringValue * newstringprop = new CStringValue(newprop, m_targetprop); - GetParent()->SetProperty(m_targetprop, newstringprop); - newstringprop->Release(); - } - } -} - -/** - * Tests whether shift is pressed - */ -bool SCA_KeyboardSensor::IsShifted(void) -{ - SCA_IInputDevice* inputdev = ((SCA_KeyboardManager *)m_eventmgr)->GetInputDevice(); - - if ( (inputdev->GetEventValue(SCA_IInputDevice::KX_RIGHTSHIFTKEY).m_status - == SCA_InputEvent::KX_ACTIVE) - || (inputdev->GetEventValue(SCA_IInputDevice::KX_RIGHTSHIFTKEY).m_status - == SCA_InputEvent::KX_JUSTACTIVATED) - || (inputdev->GetEventValue(SCA_IInputDevice::KX_LEFTSHIFTKEY).m_status - == SCA_InputEvent::KX_ACTIVE) - || (inputdev->GetEventValue(SCA_IInputDevice::KX_LEFTSHIFTKEY).m_status - == SCA_InputEvent::KX_JUSTACTIVATED) - ) { - return true; - } - else { - return false; - } -} - -void SCA_KeyboardSensor::LogKeystrokes(void) -{ - SCA_IInputDevice* inputdev = ((SCA_KeyboardManager *)m_eventmgr)->GetInputDevice(); - int num = inputdev->GetNumActiveEvents(); - - /* weird loop, this one... */ - if (num > 0) - { - - int index = 0; - /* Check on all keys whether they were pushed. This does not - * untangle the ordering, so don't type too fast :) */ - for (int i=SCA_IInputDevice::KX_BEGINKEY ; i<= SCA_IInputDevice::KX_ENDKEY;i++) - { - const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i); - if (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED) //NO_INPUTSTATUS) - { - if (index < num) - { - AddToTargetProp(i, inevent.m_unicode); - index++; - } - } - } - } -} - -#ifdef WITH_PYTHON - -/* ------------------------------------------------------------------------- */ -/* Python Functions */ -/* ------------------------------------------------------------------------- */ - -KX_PYMETHODDEF_DOC_O(SCA_KeyboardSensor, getKeyStatus, -"getKeyStatus(keycode)\n" -"\tGet the given key's status (KX_NO_INPUTSTATUS, KX_JUSTACTIVATED, KX_ACTIVE or KX_JUSTRELEASED).\n") -{ - if (!PyLong_Check(value)) { - PyErr_SetString(PyExc_ValueError, "sensor.getKeyStatus(int): Keyboard Sensor, expected an int"); - return NULL; - } - - SCA_IInputDevice::KX_EnumInputs keycode = (SCA_IInputDevice::KX_EnumInputs)PyLong_AsLong(value); - - if ((keycode < SCA_IInputDevice::KX_BEGINKEY) || - (keycode > SCA_IInputDevice::KX_ENDKEY)) - { - PyErr_SetString(PyExc_AttributeError, "sensor.getKeyStatus(int): Keyboard Sensor, invalid keycode specified!"); - return NULL; - } - - SCA_IInputDevice* inputdev = ((SCA_KeyboardManager *)m_eventmgr)->GetInputDevice(); - const SCA_InputEvent & inevent = inputdev->GetEventValue(keycode); - return PyLong_FromLong(inevent.m_status); -} - -/* ------------------------------------------------------------------------- */ -/* Python Integration Hooks */ -/* ------------------------------------------------------------------------- */ - -PyTypeObject SCA_KeyboardSensor::Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "SCA_KeyboardSensor", - sizeof(PyObjectPlus_Proxy), - 0, - py_base_dealloc, - 0, - 0, - 0, - 0, - py_base_repr, - 0,0,0,0,0,0,0,0,0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - 0,0,0,0,0,0,0, - Methods, - 0, - 0, - &SCA_ISensor::Type, - 0,0,0,0,0,0, - py_base_new -}; - -PyMethodDef SCA_KeyboardSensor::Methods[] = { - KX_PYMETHODTABLE_O(SCA_KeyboardSensor, getKeyStatus), - {NULL,NULL} //Sentinel -}; - -PyAttributeDef SCA_KeyboardSensor::Attributes[] = { - KX_PYATTRIBUTE_RO_FUNCTION("events", SCA_KeyboardSensor, pyattr_get_events), - KX_PYATTRIBUTE_BOOL_RW("useAllKeys",SCA_KeyboardSensor,m_bAllKeys), - KX_PYATTRIBUTE_INT_RW("key",0,SCA_IInputDevice::KX_ENDKEY,true,SCA_KeyboardSensor,m_hotkey), - KX_PYATTRIBUTE_SHORT_RW("hold1",0,SCA_IInputDevice::KX_ENDKEY,true,SCA_KeyboardSensor,m_qual), - KX_PYATTRIBUTE_SHORT_RW("hold2",0,SCA_IInputDevice::KX_ENDKEY,true,SCA_KeyboardSensor,m_qual2), - KX_PYATTRIBUTE_STRING_RW("toggleProperty",0,MAX_PROP_NAME,false,SCA_KeyboardSensor,m_toggleprop), - KX_PYATTRIBUTE_STRING_RW("targetProperty",0,MAX_PROP_NAME,false,SCA_KeyboardSensor,m_targetprop), - { NULL } //Sentinel -}; - - -PyObject *SCA_KeyboardSensor::pyattr_get_events(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) -{ - SCA_KeyboardSensor* self = static_cast<SCA_KeyboardSensor*>(self_v); - - SCA_IInputDevice* inputdev = ((SCA_KeyboardManager *)self->m_eventmgr)->GetInputDevice(); - - PyObject *resultlist = PyList_New(0); - - for (int i=SCA_IInputDevice::KX_BEGINKEY ; i<= SCA_IInputDevice::KX_ENDKEY;i++) - { - const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i); - if (inevent.m_status != SCA_InputEvent::KX_NO_INPUTSTATUS) - { - PyObject *keypair = PyList_New(2); - PyList_SET_ITEM(keypair,0,PyLong_FromLong(i)); - PyList_SET_ITEM(keypair,1,PyLong_FromLong(inevent.m_status)); - PyList_Append(resultlist,keypair); - Py_DECREF(keypair); - } - } - return resultlist; -} - -#endif // WITH_PYTHON - -/* Accessed from python */ - -// this code looks ugly, please use an ordinary hashtable - -char ToCharacter(int keyIndex, bool shifted) -{ - /* numerals */ - if ( (keyIndex >= SCA_IInputDevice::KX_ZEROKEY) - && (keyIndex <= SCA_IInputDevice::KX_NINEKEY) ) { - if (shifted) { - char numshift[] = ")!@#$%^&*("; - return numshift[keyIndex - '0']; - } else { - return keyIndex - SCA_IInputDevice::KX_ZEROKEY + '0'; - } - } - - /* letters... always lowercase... is that desirable? */ - if ( (keyIndex >= SCA_IInputDevice::KX_AKEY) - && (keyIndex <= SCA_IInputDevice::KX_ZKEY) ) { - if (shifted) { - return keyIndex - SCA_IInputDevice::KX_AKEY + 'A'; - } else { - return keyIndex - SCA_IInputDevice::KX_AKEY + 'a'; - } - } - - if (keyIndex == SCA_IInputDevice::KX_SPACEKEY) { - return ' '; - } - if (keyIndex == SCA_IInputDevice::KX_RETKEY || keyIndex == SCA_IInputDevice::KX_PADENTER) { - return '\n'; - } - - - if (keyIndex == SCA_IInputDevice::KX_PADASTERKEY) { - return '*'; - } - - if (keyIndex == SCA_IInputDevice::KX_TABKEY) { - return '\t'; - } - - /* comma to period */ - char commatoperiod[] = ",-."; - char commatoperiodshifted[] = "<_>"; - if (keyIndex == SCA_IInputDevice::KX_COMMAKEY) { - if (shifted) { - return commatoperiodshifted[0]; - } else { - return commatoperiod[0]; - } - } - if (keyIndex == SCA_IInputDevice::KX_MINUSKEY) { - if (shifted) { - return commatoperiodshifted[1]; - } else { - return commatoperiod[1]; - } - } - if (keyIndex == SCA_IInputDevice::KX_PERIODKEY) { - if (shifted) { - return commatoperiodshifted[2]; - } else { - return commatoperiod[2]; - } - } - - /* semicolon to rightbracket */ - char semicolontorightbracket[] = ";\'`/\\=[]"; - char semicolontorightbracketshifted[] = ":\"~\?|+{}"; - if ((keyIndex >= SCA_IInputDevice::KX_SEMICOLONKEY) - && (keyIndex <= SCA_IInputDevice::KX_RIGHTBRACKETKEY)) { - if (shifted) { - return semicolontorightbracketshifted[keyIndex - SCA_IInputDevice::KX_SEMICOLONKEY]; - } else { - return semicolontorightbracket[keyIndex - SCA_IInputDevice::KX_SEMICOLONKEY]; - } - } - - /* keypad2 to padplus */ - char pad2topadplus[] = "246813579. 0- +"; - if ((keyIndex >= SCA_IInputDevice::KX_PAD2) - && (keyIndex <= SCA_IInputDevice::KX_PADPLUSKEY)) { - return pad2topadplus[keyIndex - SCA_IInputDevice::KX_PAD2]; - } - - return '!'; -} - - - -/** - * Determine whether this character can be printed. We cannot use - * the library functions here, because we need to test our own - * keycodes. */ -bool IsPrintable(int keyIndex) -{ - /* only print - * - numerals: KX_ZEROKEY to KX_NINEKEY - * - alphas: KX_AKEY to KX_ZKEY. - * - specials: KX_RETKEY, KX_PADASTERKEY, KX_PADCOMMAKEY to KX_PERIODKEY, - * KX_TABKEY, KX_SEMICOLONKEY to KX_RIGHTBRACKETKEY, - * KX_PAD2 to KX_PADPLUSKEY - * - delete and backspace: also printable in the sense that they modify - * the string - * - retkey: should this be printable? - * - virgule: prints a space... don't know which key that's supposed - * to be... - */ - if ( ((keyIndex >= SCA_IInputDevice::KX_ZEROKEY) - && (keyIndex <= SCA_IInputDevice::KX_NINEKEY)) - || ((keyIndex >= SCA_IInputDevice::KX_AKEY) - && (keyIndex <= SCA_IInputDevice::KX_ZKEY)) - || (keyIndex == SCA_IInputDevice::KX_SPACEKEY) - || (keyIndex == SCA_IInputDevice::KX_RETKEY) - || (keyIndex == SCA_IInputDevice::KX_PADENTER) - || (keyIndex == SCA_IInputDevice::KX_PADASTERKEY) - || (keyIndex == SCA_IInputDevice::KX_TABKEY) - || ((keyIndex >= SCA_IInputDevice::KX_COMMAKEY) - && (keyIndex <= SCA_IInputDevice::KX_PERIODKEY)) - || ((keyIndex >= SCA_IInputDevice::KX_SEMICOLONKEY) - && (keyIndex <= SCA_IInputDevice::KX_RIGHTBRACKETKEY)) - || ((keyIndex >= SCA_IInputDevice::KX_PAD2) - && (keyIndex <= SCA_IInputDevice::KX_PADPLUSKEY)) - || (keyIndex == SCA_IInputDevice::KX_DELKEY) - || (keyIndex == SCA_IInputDevice::KX_BACKSPACEKEY) - ) - { - return true; - } else { - return false; - } -} - -/** - * Tests whether this is a delete key. - */ -bool IsDelete(int keyIndex) -{ - if ( (keyIndex == SCA_IInputDevice::KX_DELKEY) - || (keyIndex == SCA_IInputDevice::KX_BACKSPACEKEY) ) { - return true; - } else { - return false; - } -} |