BGE Python API
[blender.git] / source / gameengine / GameLogic / SCA_KeyboardSensor.cpp
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  * Sensor for keyboard input
29  */
30 #include "SCA_KeyboardSensor.h"
31 #include "SCA_KeyboardManager.h"
32 #include "SCA_LogicManager.h"
33 #include "StringValue.h"
34 #include "SCA_IInputDevice.h"
35
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
39
40 /* ------------------------------------------------------------------------- */
41 /* Native functions                                                          */
42 /* ------------------------------------------------------------------------- */
43
44 SCA_KeyboardSensor::SCA_KeyboardSensor(SCA_KeyboardManager* keybdmgr,
45                                                                            short int hotkey,
46                                                                            short int qual,
47                                                                            short int qual2,
48                                                                            bool bAllKeys,
49                                                                            const STR_String& targetProp,
50                                                                            const STR_String& toggleProp,
51                                                                            SCA_IObject* gameobj,
52                                                                            PyTypeObject* T )
53         :SCA_ISensor(gameobj,keybdmgr,T),
54          m_pKeyboardMgr(keybdmgr),
55          m_hotkey(hotkey),
56          m_qual(qual),
57          m_qual2(qual2),
58          m_bAllKeys(bAllKeys),
59          m_targetprop(targetProp),
60          m_toggleprop(toggleProp)
61 {
62         if (hotkey == SCA_IInputDevice::KX_ESCKEY)
63                 keybdmgr->GetInputDevice()->HookEscape();
64 //      SetDrawColor(0xff0000ff);
65         Init();
66 }
67
68
69
70 SCA_KeyboardSensor::~SCA_KeyboardSensor()
71 {
72 }
73
74 void SCA_KeyboardSensor::Init()
75 {
76         // this function is used when the sensor is disconnected from all controllers
77         // by the state engine. It reinitializes the sensor as if it was just created.
78         // However, if the target key is pressed when the sensor is reactivated, it
79         // will not generated an event (see remark in Evaluate()).
80         m_val = (m_invert)?1:0;
81         m_reset = true;
82 }
83
84 CValue* SCA_KeyboardSensor::GetReplica()
85 {
86         SCA_KeyboardSensor* replica = new SCA_KeyboardSensor(*this);
87         // this will copy properties and so on...
88         CValue::AddDataToReplica(replica);
89         replica->Init();
90         return replica;
91 }
92
93
94
95 short int SCA_KeyboardSensor::GetHotkey()
96 {
97         return m_hotkey;
98 }
99
100
101
102 bool SCA_KeyboardSensor::IsPositiveTrigger()
103
104         bool result = (m_val != 0);
105
106         if (m_invert)
107                 result = !result;
108                 
109         return result;
110 }
111
112
113
114 bool SCA_KeyboardSensor::TriggerOnAllKeys()
115
116         return m_bAllKeys;
117 }
118
119
120
121 bool SCA_KeyboardSensor::Evaluate(CValue* eventval)
122 {
123         bool result    = false;
124         bool reset     = m_reset && m_level;
125         bool qual          = true;
126         bool qual_change = false;
127         short int m_val_orig = m_val;
128         
129         SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice();
130         //      cerr << "SCA_KeyboardSensor::Eval event, sensing for "<< m_hotkey << " at device " << inputdev << "\n";
131
132         /* See if we need to do logging: togPropState exists and is
133      * different from 0 */
134         CValue* myparent = GetParent();
135         CValue* togPropState = myparent->GetProperty(m_toggleprop);
136         if (togPropState &&
137                 (((int)togPropState->GetNumber()) != 0) )
138         {
139                 LogKeystrokes();
140         }
141
142         m_reset = false;
143
144         /* Now see whether events must be bounced. */
145         if (m_bAllKeys)
146         {
147                 bool justactivated = false;
148                 bool justreleased = false;
149                 bool active = false;
150
151                 for (int i=SCA_IInputDevice::KX_BEGINKEY ; i< SCA_IInputDevice::KX_ENDKEY;i++)
152                 {
153                         const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i);
154                         switch (inevent.m_status) 
155                         { 
156                         case SCA_InputEvent::KX_JUSTACTIVATED:
157                                 justactivated = true;
158                                 break;
159                         case SCA_InputEvent::KX_JUSTRELEASED:
160                                 justreleased = true;
161                                 break;
162                         case SCA_InputEvent::KX_ACTIVE:
163                                 active = true;
164                                 break;
165                         }
166                 }
167
168                 if (justactivated)
169                 {
170                         m_val=1;
171                         result = true;
172                 } else
173                 {
174                         if (justreleased)
175                         {
176                                 m_val=(active)?1:0;
177                                 result = true;
178                         } else
179                         {
180                                 if (active)
181                                 {
182                                         if (m_val == 0)
183                                         {
184                                                 m_val = 1;
185                                                 if (m_level) {
186                                                         result = true;
187                                                 }
188                                         }
189                                 } else
190                                 {
191                                         if (m_val == 1)
192                                         {
193                                                 m_val = 0;
194                                                 result = true;
195                                         }
196                                 }
197                         }
198                 }
199
200
201         } else
202         {
203
204         //              cerr << "======= SCA_KeyboardSensor::Evaluate:: peeking at key status" << endl;
205                 const SCA_InputEvent & inevent = inputdev->GetEventValue(
206                         (SCA_IInputDevice::KX_EnumInputs) m_hotkey);
207         
208         //              cerr << "======= SCA_KeyboardSensor::Evaluate:: status: " << inevent.m_status << endl;
209                 
210                 
211                 /* Check qualifier keys
212                  * - see if the qualifiers we request are pressed - 'qual' true/false
213                  * - see if the qualifiers we request changed their state - 'qual_change' true/false
214                  */
215                 if (m_qual > 0) {
216                         const SCA_InputEvent & qualevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) m_qual);
217                         switch(qualevent.m_status) {
218                         case SCA_InputEvent::KX_NO_INPUTSTATUS:
219                                 qual = false;
220                                 break;
221                         case SCA_InputEvent::KX_JUSTRELEASED:
222                                 qual_change = true;
223                                 qual = false;
224                                 break;
225                         case SCA_InputEvent::KX_JUSTACTIVATED:
226                                 qual_change = true;
227                         }
228                 }
229                 if (m_qual2 > 0 && qual==true) {
230                         const SCA_InputEvent & qualevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) m_qual2);
231                         /* copy of above */
232                         switch(qualevent.m_status) {
233                         case SCA_InputEvent::KX_NO_INPUTSTATUS:
234                                 qual = false;
235                                 break;
236                         case SCA_InputEvent::KX_JUSTRELEASED:
237                                 qual_change = true;
238                                 qual = false;
239                                 break;
240                         case SCA_InputEvent::KX_JUSTACTIVATED:
241                                 qual_change = true;
242                         }
243                 }
244                 /* done reading qualifiers */
245                 
246                 if (inevent.m_status == SCA_InputEvent::KX_NO_INPUTSTATUS)
247                 {
248                         if (m_val == 1)
249                         {
250                                 // this situation may occur after a scene suspend: the keyboard release 
251                                 // event was not captured, produce now the event off
252                                 m_val = 0;
253                                 result = true;
254                         }
255                 } else
256                 {
257                         if (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED)
258                         {
259                                 m_val=1;
260                                 result = true;
261                         } else
262                         {
263                                 if (inevent.m_status == SCA_InputEvent::KX_JUSTRELEASED)
264                                 {
265                                         m_val = 0;
266                                         result = true;
267                                 } else 
268                                 {
269                                         if (inevent.m_status == SCA_InputEvent::KX_ACTIVE)
270                                         {
271                                                 if (m_val == 0)
272                                                 {
273                                                         m_val = 1;
274                                                         if (m_level) 
275                                                         {
276                                                                 result = true;
277                                                         }
278                                                 }
279                                         }
280                                 }
281                         }
282                 }
283                 
284                 /* Modify the key state based on qual(s)
285                  * Tested carefuly. dont touch unless your really sure.
286                  * note, this will only change the results if key modifiers are set.
287                  *
288                  * When all modifiers and keys are positive
289                  *  - pulse true
290                  * 
291                  * When ANY of the modifiers or main key become inactive,
292                  *  - pulse false
293                  */
294                 if (qual==false) { /* one of the qualifiers are not pressed */
295                         if (m_val_orig && qual_change) { /* we were originally enabled, but a qualifier changed */
296                                 result = true;
297                         } else {
298                                 result = false;
299                         }
300                         m_val = 0; /* since one of the qualifiers is not on, set the state to false */
301                 } else {                                                /* we done have any qualifiers or they are all pressed */
302                         if (m_val && qual_change) {     /* the main key state is true and our qualifier just changed */
303                                 result = true;
304                         }
305                 }
306                 /* done with key quals */
307                 
308         }
309         
310         if (reset)
311                 // force an event
312                 result = true;
313         return result;
314
315 }
316
317 void SCA_KeyboardSensor::AddToTargetProp(int keyIndex)
318 {
319         if (IsPrintable(keyIndex)) {
320                 CValue* tprop = GetParent()->GetProperty(m_targetprop);
321                 
322                 if (tprop) {
323                         /* overwrite the old property */
324                         if (IsDelete(keyIndex)) {
325                                 /* strip one char, if possible */
326                                 STR_String newprop = tprop->GetText();
327                                 int oldlength = newprop.Length();
328                                 if (oldlength >= 1 ) {
329                                         newprop.SetLength(oldlength - 1);
330                                         CStringValue * newstringprop = new CStringValue(newprop, m_targetprop);
331                                         GetParent()->SetProperty(m_targetprop, newstringprop);
332                                         newstringprop->Release();
333                                 }                               
334                         } else {
335                                 /* append */
336                                 char pchar = ToCharacter(keyIndex, IsShifted());
337                                 STR_String newprop = tprop->GetText() + pchar;
338                                 CStringValue * newstringprop = new CStringValue(newprop, m_targetprop);                 
339                                 GetParent()->SetProperty(m_targetprop, newstringprop);
340                                 newstringprop->Release();
341                         }
342                 } else {
343                         if (!IsDelete(keyIndex)) {
344                                 /* Make a new property. Deletes can be ignored. */
345                                 char pchar = ToCharacter(keyIndex, IsShifted());
346                                 STR_String newprop = pchar;
347                                 CStringValue * newstringprop = new CStringValue(newprop, m_targetprop);                 
348                                 GetParent()->SetProperty(m_targetprop, newstringprop);
349                                 newstringprop->Release();
350                         }
351                 }
352         }
353         
354 }
355
356 /**
357  * Determine whether this character can be printed. We cannot use
358  * the library functions here, because we need to test our own
359  * keycodes. */
360 bool SCA_KeyboardSensor::IsPrintable(int keyIndex)
361 {
362         /* only print 
363          * - numerals: KX_ZEROKEY to KX_NINEKEY
364          * - alphas:   KX_AKEY to KX_ZKEY. 
365          * - specials: KX_RETKEY, KX_PADASTERKEY, KX_PADCOMMAKEY to KX_PERIODKEY,
366          *             KX_TABKEY , KX_SEMICOLONKEY to KX_RIGHTBRACKETKEY, 
367          *             KX_PAD2 to KX_PADPLUSKEY
368          * - delete and backspace: also printable in the sense that they modify 
369          *                         the string
370          * - retkey: should this be printable?
371          * - virgule: prints a space... don't know which key that's supposed
372          *   to be...
373          */
374         if ( ((keyIndex >= SCA_IInputDevice::KX_ZEROKEY) 
375                   && (keyIndex <= SCA_IInputDevice::KX_NINEKEY))
376                  || ((keyIndex >= SCA_IInputDevice::KX_AKEY) 
377                          && (keyIndex <= SCA_IInputDevice::KX_ZKEY)) 
378                  || (keyIndex == SCA_IInputDevice::KX_SPACEKEY) 
379 /*                       || (keyIndex == KX_RETKEY)  */
380                  || (keyIndex == SCA_IInputDevice::KX_PADASTERKEY) 
381                  || (keyIndex == SCA_IInputDevice::KX_TABKEY) 
382                  || ((keyIndex >= SCA_IInputDevice::KX_COMMAKEY) 
383                          && (keyIndex <= SCA_IInputDevice::KX_PERIODKEY)) 
384                  || ((keyIndex >= SCA_IInputDevice::KX_SEMICOLONKEY) 
385                          && (keyIndex <= SCA_IInputDevice::KX_RIGHTBRACKETKEY)) 
386                  || ((keyIndex >= SCA_IInputDevice::KX_PAD2) 
387                          && (keyIndex <= SCA_IInputDevice::KX_PADPLUSKEY)) 
388                  || (keyIndex == SCA_IInputDevice::KX_DELKEY)
389                  || (keyIndex == SCA_IInputDevice::KX_BACKSPACEKEY)                              
390                 )
391         {
392                 return true;
393         } else {
394                 return false;
395         }
396 }
397
398 // this code looks ugly, please use an ordinary hashtable
399
400 char SCA_KeyboardSensor::ToCharacter(int keyIndex, bool shifted)
401 {
402         /* numerals */
403         if ( (keyIndex >= SCA_IInputDevice::KX_ZEROKEY) 
404                  && (keyIndex <= SCA_IInputDevice::KX_NINEKEY) ) {
405                 if (shifted) {
406                         char numshift[] = ")!@#$%^&*(";
407                         return numshift[keyIndex - '0']; 
408                 } else {
409                         return keyIndex - SCA_IInputDevice::KX_ZEROKEY + '0'; 
410                 }
411         }
412         
413         /* letters... always lowercase... is that desirable? */
414         if ( (keyIndex >= SCA_IInputDevice::KX_AKEY) 
415                  && (keyIndex <= SCA_IInputDevice::KX_ZKEY) ) {
416                 if (shifted) {
417                         return keyIndex - SCA_IInputDevice::KX_AKEY + 'A'; 
418                 } else {
419                         return keyIndex - SCA_IInputDevice::KX_AKEY + 'a'; 
420                 }
421         }
422         
423         if (keyIndex == SCA_IInputDevice::KX_SPACEKEY) {
424                 return ' ';
425         }
426         
427 /*                       || (keyIndex == SCA_IInputDevice::KX_RETKEY)  */
428         
429         if (keyIndex == SCA_IInputDevice::KX_PADASTERKEY) {
430                 return '*';
431         }
432         
433         if (keyIndex == SCA_IInputDevice::KX_TABKEY) {
434                 return '\t';
435         }
436         
437         /* comma to period */
438         char commatoperiod[] = ",-.";
439         char commatoperiodshifted[] = "<_>";
440         if (keyIndex == SCA_IInputDevice::KX_COMMAKEY) {
441                 if (shifted) {
442                         return commatoperiodshifted[0];
443                 } else {
444                         return commatoperiod[0];
445                 }
446         }
447         if (keyIndex == SCA_IInputDevice::KX_MINUSKEY) {
448                 if (shifted) {
449                         return commatoperiodshifted[1];
450                 } else {
451                         return commatoperiod[1];
452                 }
453         }
454         if (keyIndex == SCA_IInputDevice::KX_PERIODKEY) {
455                 if (shifted) {
456                         return commatoperiodshifted[2];
457                 } else {
458                         return commatoperiod[2];
459                 }
460         }
461         
462         /* semicolon to rightbracket */
463         char semicolontorightbracket[] = ";\'` /\\=[]";
464         char semicolontorightbracketshifted[] = ":\"~ \?|+{}";
465         if ((keyIndex >= SCA_IInputDevice::KX_SEMICOLONKEY) 
466                 && (keyIndex <= SCA_IInputDevice::KX_RIGHTBRACKETKEY)) {
467                 if (shifted) {
468                         return semicolontorightbracketshifted[keyIndex - SCA_IInputDevice::KX_SEMICOLONKEY];
469                 } else {
470                         return semicolontorightbracket[keyIndex - SCA_IInputDevice::KX_SEMICOLONKEY];
471                 }
472         }
473         
474         /* keypad2 to padplus */
475         char pad2topadplus[] = "246813579. 0- +";
476         if ((keyIndex >= SCA_IInputDevice::KX_PAD2) 
477                 && (keyIndex <= SCA_IInputDevice::KX_PADPLUSKEY)) { 
478                 return pad2topadplus[keyIndex - SCA_IInputDevice::KX_PAD2];
479         }
480
481         return '!';
482 }
483         
484 /**
485  * Tests whether this is a delete key.
486  */     
487 bool SCA_KeyboardSensor::IsDelete(int keyIndex)
488 {
489         if ( (keyIndex == SCA_IInputDevice::KX_DELKEY)
490                  || (keyIndex == SCA_IInputDevice::KX_BACKSPACEKEY) ) {
491                 return true;
492         } else {
493                 return false;
494         }
495 }
496
497 /**
498  * Tests whether shift is pressed
499  */     
500 bool SCA_KeyboardSensor::IsShifted(void)
501 {
502         SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice();
503         
504         if ( (inputdev->GetEventValue(SCA_IInputDevice::KX_RIGHTSHIFTKEY).m_status 
505                   == SCA_InputEvent::KX_ACTIVE)
506                  || (inputdev->GetEventValue(SCA_IInputDevice::KX_RIGHTSHIFTKEY).m_status 
507                          == SCA_InputEvent::KX_JUSTACTIVATED)
508                  || (inputdev->GetEventValue(SCA_IInputDevice::KX_LEFTSHIFTKEY).m_status 
509                          == SCA_InputEvent::KX_ACTIVE)
510                  || (inputdev->GetEventValue(SCA_IInputDevice::KX_LEFTSHIFTKEY).m_status 
511                          == SCA_InputEvent::KX_JUSTACTIVATED)
512                 ) {
513                 return true;
514         } else {
515                 return false;
516         }       
517 }
518
519 void SCA_KeyboardSensor::LogKeystrokes(void) 
520 {
521         SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice();
522         int num = inputdev->GetNumActiveEvents();
523
524         /* weird loop, this one... */
525         if (num > 0)
526         {
527                 
528                 int index = 0;
529                 /* Check on all keys whether they were pushed. This does not
530          * untangle the ordering, so don't type too fast :) */
531                 for (int i=SCA_IInputDevice::KX_BEGINKEY ; i< SCA_IInputDevice::KX_ENDKEY;i++)
532                 {
533                         const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i);
534                         if (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED) //NO_INPUTSTATUS)
535                         {
536                                 if (index < num)
537                                 {
538                                         AddToTargetProp(i);
539                                         index++;
540                                 }
541                         }
542                 }
543         }
544 }
545
546
547 /* ------------------------------------------------------------------------- */
548 /* Python Functions                                                    */
549 /* ------------------------------------------------------------------------- */
550
551 //Deprecated ----->
552 /** 1. GetKey : check which key this sensor looks at */
553 const char SCA_KeyboardSensor::GetKey_doc[] = 
554 "getKey()\n"
555 "\tReturn the code of the key this sensor is listening to.\n" ;
556 PyObject* SCA_KeyboardSensor::PyGetKey(PyObject* self, PyObject* args, PyObject* kwds)
557 {
558         ShowDeprecationWarning("getKey()", "the key property");
559         return PyInt_FromLong(m_hotkey);
560 }
561
562 /** 2. SetKey: change the key to look at */
563 const char SCA_KeyboardSensor::SetKey_doc[] = 
564 "setKey(keycode)\n"
565 "\t- keycode: any code from GameKeys\n"
566 "\tSet the key this sensor should listen to.\n" ;
567 PyObject* SCA_KeyboardSensor::PySetKey(PyObject* self, PyObject* args, PyObject* kwds)
568 {
569         ShowDeprecationWarning("setKey()", "the key property");
570         int keyCode;
571         
572         if(!PyArg_ParseTuple(args, "i", &keyCode)) {
573                 return NULL;
574         }
575
576         /* Since we have symbolic constants for this in Python, we don't guard   */
577         /* anything. It's up to the user to provide a sensible number.           */
578         m_hotkey = keyCode;
579
580         Py_RETURN_NONE;
581 }
582
583 /** 3. GetHold1 : set the first bucky bit */
584 const char SCA_KeyboardSensor::GetHold1_doc[] = 
585 "getHold1()\n"
586 "\tReturn the code of the first key modifier to the key this \n"
587 "\tsensor is listening to.\n" ;
588 PyObject* SCA_KeyboardSensor::PyGetHold1(PyObject* self, PyObject* args, PyObject* kwds)
589 {
590         ShowDeprecationWarning("getHold1()", "the hold1 property");
591         return PyInt_FromLong(m_qual);
592 }
593
594 /** 4. SetHold1: change the first bucky bit */
595 const char SCA_KeyboardSensor::SetHold1_doc[] = 
596 "setHold1(keycode)\n"
597 "\t- keycode: any code from GameKeys\n"
598 "\tSet the first modifier to the key this sensor should listen to.\n" ;
599 PyObject* SCA_KeyboardSensor::PySetHold1(PyObject* self, PyObject* args, PyObject* kwds)
600 {
601         ShowDeprecationWarning("setHold1()", "the hold1 property");
602         int keyCode;
603
604         if(!PyArg_ParseTuple(args, "i", &keyCode)) {
605                 return NULL;
606         }
607         
608         /* Since we have symbolic constants for this in Python, we don't guard   */
609         /* anything. It's up to the user to provide a sensible number.           */
610         m_qual = keyCode;
611
612         Py_RETURN_NONE;
613 }
614         
615 /** 5. GetHold2 : get the second bucky bit */
616 const char SCA_KeyboardSensor::GetHold2_doc[] = 
617 "getHold2()\n"
618 "\tReturn the code of the second key modifier to the key this \n"
619 "\tsensor is listening to.\n" ;
620 PyObject* SCA_KeyboardSensor::PyGetHold2(PyObject* self, PyObject* args, PyObject* kwds)
621 {
622         ShowDeprecationWarning("getHold2()", "the hold2 property");
623         return PyInt_FromLong(m_qual2);
624 }
625
626 /** 6. SetHold2: change the second bucky bit */
627 const char SCA_KeyboardSensor::SetHold2_doc[] = 
628 "setHold2(keycode)\n"
629 "\t- keycode: any code from GameKeys\n"
630 "\tSet the first modifier to the key this sensor should listen to.\n" ;
631 PyObject* SCA_KeyboardSensor::PySetHold2(PyObject* self, PyObject* args, PyObject* kwds)
632 {
633         ShowDeprecationWarning("setHold2()", "the hold2 property");
634         int keyCode;
635
636         if(!PyArg_ParseTuple(args, "i", &keyCode)) {
637                 return NULL;
638         }
639         
640         /* Since we have symbolic constants for this in Python, we don't guard   */
641         /* anything. It's up to the user to provide a sensible number.           */
642         m_qual2 = keyCode;
643
644         Py_RETURN_NONE;
645 }
646
647         
648 const char SCA_KeyboardSensor::GetPressedKeys_doc[] = 
649 "getPressedKeys()\n"
650 "\tGet a list of pressed keys that have either been pressed, or just released this frame.\n" ;
651
652 PyObject* SCA_KeyboardSensor::PyGetPressedKeys(PyObject* self, PyObject* args, PyObject* kwds)
653 {
654         ShowDeprecationWarning("getPressedKeys()", "getEventList()");
655
656         SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice();
657
658         int num = inputdev->GetNumJustEvents();
659         PyObject* resultlist = PyList_New(num);
660
661         if (num > 0)
662         {
663                 
664                 int index = 0;
665                 
666                 for (int i=SCA_IInputDevice::KX_BEGINKEY ; i< SCA_IInputDevice::KX_ENDKEY;i++)
667                 {
668                         const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i);
669                         if ((inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED)
670                                 || (inevent.m_status == SCA_InputEvent::KX_JUSTRELEASED))
671                         {
672                                 if (index < num)
673                                 {
674                                         PyObject* keypair = PyList_New(2);
675                                         PyList_SetItem(keypair,0,PyInt_FromLong(i));
676                                         PyList_SetItem(keypair,1,PyInt_FromLong(inevent.m_status));
677                                         PyList_SetItem(resultlist,index,keypair);
678                                         index++;
679                                 }
680                         }
681                 }       
682                 if (index>0) return resultlist;
683         }
684         
685         Py_RETURN_NONE;
686 }
687
688
689
690 const char SCA_KeyboardSensor::GetCurrentlyPressedKeys_doc[] = 
691 "getCurrentlyPressedKeys()\n"
692 "\tGet a list of keys that are currently pressed.\n" ;
693
694 PyObject* SCA_KeyboardSensor::PyGetCurrentlyPressedKeys(PyObject* self, PyObject* args, PyObject* kwds)
695 {
696 ShowDeprecationWarning("getCurrentlyPressedKeys()", "getEventList()");
697
698 SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice();
699
700         int num = inputdev->GetNumActiveEvents();
701         PyObject* resultlist = PyList_New(num);
702
703         if (num > 0)
704         {
705                 int index = 0;
706                 
707                 for (int i=SCA_IInputDevice::KX_BEGINKEY ; i< SCA_IInputDevice::KX_ENDKEY;i++)
708                 {
709                         const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i);
710                         if ( (inevent.m_status == SCA_InputEvent::KX_ACTIVE)
711                                  || (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED))
712                         {
713                                 if (index < num)
714                                 {
715                                         PyObject* keypair = PyList_New(2);
716                                         PyList_SetItem(keypair,0,PyInt_FromLong(i));
717                                         PyList_SetItem(keypair,1,PyInt_FromLong(inevent.m_status));
718                                         PyList_SetItem(resultlist,index,keypair);
719                                         index++;
720                                 }
721                         }
722                 }
723
724                 /* why?*/
725                 if (index > 0) return resultlist;
726         }
727
728         Py_RETURN_NONE;
729 }
730 //<---- Deprecated
731
732 KX_PYMETHODDEF_DOC_NOARGS(SCA_KeyboardSensor, getEventList,
733 "getEventList()\n"
734 "\tGet the list of the keyboard events in this frame.\n")
735 {
736         SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice();
737
738         PyObject* resultlist = PyList_New(0);
739         
740         for (int i=SCA_IInputDevice::KX_BEGINKEY ; i< SCA_IInputDevice::KX_ENDKEY;i++)
741         {
742                 const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i);
743                 if (inevent.m_status != SCA_InputEvent::KX_NO_INPUTSTATUS)
744                 {
745                         PyObject* keypair = PyList_New(2);
746                         PyList_SetItem(keypair,0,PyInt_FromLong(i));
747                         PyList_SetItem(keypair,1,PyInt_FromLong(inevent.m_status));
748                         PyList_Append(resultlist,keypair);
749                 }
750         }       
751         return resultlist;
752 }
753
754 KX_PYMETHODDEF_DOC_O(SCA_KeyboardSensor, getKeyStatus,
755 "getKeyStatus(keycode)\n"
756 "\tGet the given key's status (KX_NO_INPUTSTATUS, KX_JUSTACTIVATED, KX_ACTIVE or KX_JUSTRELEASED).\n")
757 {
758         if (PyInt_Check(value))
759         {
760                 int keycode = PyInt_AsLong(value);
761                 
762                 if ((keycode < SCA_IInputDevice::KX_BEGINKEY)
763                         || (keycode > SCA_IInputDevice::KX_ENDKEY)){
764                         PyErr_SetString(PyExc_AttributeError, "invalid keycode specified!");
765                         return NULL;
766                 }
767                 
768                 SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice();
769                 const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) keycode);
770                 return PyInt_FromLong(inevent.m_status);
771         }
772         
773         Py_RETURN_NONE;
774 }
775
776 /* ------------------------------------------------------------------------- */
777 /* Python Integration Hooks                                            */
778 /* ------------------------------------------------------------------------- */
779
780 PyTypeObject SCA_KeyboardSensor::Type = {
781         PyObject_HEAD_INIT(NULL)
782         0,
783         "SCA_KeyboardSensor",
784         sizeof(SCA_KeyboardSensor),
785         0,
786         PyDestructor,
787         0,
788         0,
789         0,
790         0,
791         py_base_repr,
792         0,0,0,0,0,0,
793         py_base_getattro,
794         py_base_setattro,
795         0,0,0,0,0,0,0,0,0,
796         Methods
797 };
798
799 PyParentObject SCA_KeyboardSensor::Parents[] = {
800         &SCA_KeyboardSensor::Type,
801         &SCA_ISensor::Type,
802         &SCA_ILogicBrick::Type,
803         &CValue::Type,
804         NULL
805 };
806
807 PyMethodDef SCA_KeyboardSensor::Methods[] = {
808         //Deprecated functions ------>
809         {"getKey", (PyCFunction) SCA_KeyboardSensor::sPyGetKey, METH_VARARGS, (PY_METHODCHAR)GetKey_doc},
810         {"setKey", (PyCFunction) SCA_KeyboardSensor::sPySetKey, METH_VARARGS, (PY_METHODCHAR)SetKey_doc},
811         {"getHold1", (PyCFunction) SCA_KeyboardSensor::sPyGetHold1, METH_VARARGS, (PY_METHODCHAR)GetHold1_doc},
812         {"setHold1", (PyCFunction) SCA_KeyboardSensor::sPySetHold1, METH_VARARGS, (PY_METHODCHAR)SetHold1_doc},
813         {"getHold2", (PyCFunction) SCA_KeyboardSensor::sPyGetHold2, METH_VARARGS, (PY_METHODCHAR)GetHold2_doc},
814         {"setHold2", (PyCFunction) SCA_KeyboardSensor::sPySetHold2, METH_VARARGS, (PY_METHODCHAR)SetHold2_doc},
815         {"getPressedKeys", (PyCFunction) SCA_KeyboardSensor::sPyGetPressedKeys, METH_VARARGS, (PY_METHODCHAR)GetPressedKeys_doc},
816         {"getCurrentlyPressedKeys", (PyCFunction) SCA_KeyboardSensor::sPyGetCurrentlyPressedKeys, METH_VARARGS, (PY_METHODCHAR)GetCurrentlyPressedKeys_doc},
817         //<----- Deprecated
818         KX_PYMETHODTABLE_NOARGS(SCA_KeyboardSensor, getEventList),
819         KX_PYMETHODTABLE_O(SCA_KeyboardSensor, getKeyStatus),
820         {NULL,NULL} //Sentinel
821 };
822
823 PyAttributeDef SCA_KeyboardSensor::Attributes[] = {
824         KX_PYATTRIBUTE_BOOL_RW("useAllKeys",SCA_KeyboardSensor,m_bAllKeys),
825         KX_PYATTRIBUTE_INT_RW("key",0,SCA_IInputDevice::KX_ENDKEY,true,SCA_KeyboardSensor,m_hotkey),
826         KX_PYATTRIBUTE_SHORT_RW("hold1",0,SCA_IInputDevice::KX_ENDKEY,true,SCA_KeyboardSensor,m_qual),
827         KX_PYATTRIBUTE_SHORT_RW("hold2",0,SCA_IInputDevice::KX_ENDKEY,true,SCA_KeyboardSensor,m_qual2),
828         KX_PYATTRIBUTE_STRING_RW("toggleProperty",0,100,false,SCA_KeyboardSensor,m_toggleprop),
829         KX_PYATTRIBUTE_STRING_RW("targetProperty",0,100,false,SCA_KeyboardSensor,m_targetprop),
830         { NULL }        //Sentinel
831 };
832
833 PyObject*
834 SCA_KeyboardSensor::py_getattro(PyObject *attr)
835 {
836   py_getattro_up(SCA_ISensor);
837 }
838
839 int SCA_KeyboardSensor::py_setattro(PyObject *attr, PyObject *value)
840 {
841         py_setattro_up(SCA_ISensor);
842 }