Merge 16964:17122
[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 : specific                                               */
549 /* ------------------------------------------------------------------------- */
550
551
552 PyObject* SCA_KeyboardSensor::PySetAllMode(PyObject* self, 
553                                PyObject* args, 
554                                PyObject* kwds)
555 {
556         bool allkeys;
557
558         if (!PyArg_ParseTuple(args, "i", &allkeys))
559         {
560           return NULL;
561         }
562         
563         m_bAllKeys = allkeys;
564         Py_Return
565 }
566
567
568
569 PyObject* SCA_KeyboardSensor::sPySetAllMode(PyObject* self, 
570                                        PyObject* args, 
571                                        PyObject* kwds)
572 {
573 //      printf("sPyIsPositive\n");
574     return ((SCA_KeyboardSensor*) self)->PyIsPositive(self);
575 }
576
577
578 /** 1. GetKey : check which key this sensor looks at */
579 const char SCA_KeyboardSensor::GetKey_doc[] = 
580 "getKey()\n"
581 "\tReturn the code of the key this sensor is listening to.\n" ;
582 PyObject* SCA_KeyboardSensor::PyGetKey(PyObject* self, PyObject* args, PyObject* kwds)
583 {
584         return PyInt_FromLong(m_hotkey);
585 }
586
587 /** 2. SetKey: change the key to look at */
588 const char SCA_KeyboardSensor::SetKey_doc[] = 
589 "setKey(keycode)\n"
590 "\t- keycode: any code from GameKeys\n"
591 "\tSet the key this sensor should listen to.\n" ;
592 PyObject* SCA_KeyboardSensor::PySetKey(PyObject* self, PyObject* args, PyObject* kwds)
593 {
594         int keyCode;
595         
596         if(!PyArg_ParseTuple(args, "i", &keyCode)) {
597                 return NULL;
598         }
599
600         /* Since we have symbolic constants for this in Python, we don't guard   */
601         /* anything. It's up to the user to provide a sensible number.           */
602         m_hotkey = keyCode;
603
604         Py_Return;
605 }
606
607 /** 3. GetHold1 : set the first bucky bit */
608 const char SCA_KeyboardSensor::GetHold1_doc[] = 
609 "getHold1()\n"
610 "\tReturn the code of the first key modifier to the key this \n"
611 "\tsensor is listening to.\n" ;
612 PyObject* SCA_KeyboardSensor::PyGetHold1(PyObject* self, PyObject* args, PyObject* kwds)
613 {
614         return PyInt_FromLong(m_qual);
615 }
616
617 /** 4. SetHold1: change the first bucky bit */
618 const char SCA_KeyboardSensor::SetHold1_doc[] = 
619 "setHold1(keycode)\n"
620 "\t- keycode: any code from GameKeys\n"
621 "\tSet the first modifier to the key this sensor should listen to.\n" ;
622 PyObject* SCA_KeyboardSensor::PySetHold1(PyObject* self, PyObject* args, PyObject* kwds)
623 {
624         int keyCode;
625
626         if(!PyArg_ParseTuple(args, "i", &keyCode)) {
627                 return NULL;
628         }
629         
630         /* Since we have symbolic constants for this in Python, we don't guard   */
631         /* anything. It's up to the user to provide a sensible number.           */
632         m_qual = keyCode;
633
634         Py_Return;
635 }
636         
637 /** 5. GetHold2 : get the second bucky bit */
638 const char SCA_KeyboardSensor::GetHold2_doc[] = 
639 "getHold2()\n"
640 "\tReturn the code of the second key modifier to the key this \n"
641 "\tsensor is listening to.\n" ;
642 PyObject* SCA_KeyboardSensor::PyGetHold2(PyObject* self, PyObject* args, PyObject* kwds)
643 {
644         return PyInt_FromLong(m_qual2);
645 }
646
647 /** 6. SetHold2: change the second bucky bit */
648 const char SCA_KeyboardSensor::SetHold2_doc[] = 
649 "setHold2(keycode)\n"
650 "\t- keycode: any code from GameKeys\n"
651 "\tSet the first modifier to the key this sensor should listen to.\n" ;
652 PyObject* SCA_KeyboardSensor::PySetHold2(PyObject* self, PyObject* args, PyObject* kwds)
653 {
654         int keyCode;
655
656         if(!PyArg_ParseTuple(args, "i", &keyCode)) {
657                 return NULL;
658         }
659         
660         /* Since we have symbolic constants for this in Python, we don't guard   */
661         /* anything. It's up to the user to provide a sensible number.           */
662         m_qual2 = keyCode;
663
664         Py_Return;
665 }
666
667         
668 const char SCA_KeyboardSensor::GetPressedKeys_doc[] = 
669 "getPressedKeys()\n"
670 "\tGet a list of pressed keys that have either been pressed, or just released this frame.\n" ;
671
672 PyObject* SCA_KeyboardSensor::PyGetPressedKeys(PyObject* self, PyObject* args, PyObject* kwds)
673 {
674         SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice();
675
676         int num = inputdev->GetNumJustEvents();
677         PyObject* resultlist = PyList_New(num);
678
679         if (num > 0)
680         {
681                 
682                 int index = 0;
683                 
684                 for (int i=SCA_IInputDevice::KX_BEGINKEY ; i< SCA_IInputDevice::KX_ENDKEY;i++)
685                 {
686                         const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i);
687                         if ((inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED)
688                                 || (inevent.m_status == SCA_InputEvent::KX_JUSTRELEASED))
689                         {
690                                 if (index < num)
691                                 {
692                                         PyObject* keypair = PyList_New(2);
693                                         PyList_SetItem(keypair,0,PyInt_FromLong(i));
694                                         PyList_SetItem(keypair,1,PyInt_FromLong(inevent.m_status));
695                                         PyList_SetItem(resultlist,index,keypair);
696                                         index++;
697                                 }
698                         }
699                 }       
700                 if (index>0) return resultlist;
701         }
702         
703         Py_Return;
704 }
705
706
707
708 const char SCA_KeyboardSensor::GetCurrentlyPressedKeys_doc[] = 
709 "getCurrentlyPressedKeys()\n"
710 "\tGet a list of keys that are currently pressed.\n" ;
711
712 PyObject* SCA_KeyboardSensor::PyGetCurrentlyPressedKeys(PyObject* self, PyObject* args, PyObject* kwds)
713 {
714 SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice();
715
716         int num = inputdev->GetNumActiveEvents();
717         PyObject* resultlist = PyList_New(num);
718
719         if (num > 0)
720         {
721                 int index = 0;
722                 
723                 for (int i=SCA_IInputDevice::KX_BEGINKEY ; i< SCA_IInputDevice::KX_ENDKEY;i++)
724                 {
725                         const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i);
726                         if ( (inevent.m_status == SCA_InputEvent::KX_ACTIVE)
727                                  || (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED))
728                         {
729                                 if (index < num)
730                                 {
731                                         PyObject* keypair = PyList_New(2);
732                                         PyList_SetItem(keypair,0,PyInt_FromLong(i));
733                                         PyList_SetItem(keypair,1,PyInt_FromLong(inevent.m_status));
734                                         PyList_SetItem(resultlist,index,keypair);
735                                         index++;
736                                 }
737                         }
738                 }
739
740                 /* why?*/
741                 if (index > 0) return resultlist;
742         }
743
744         Py_Return;
745 }
746
747 /* ------------------------------------------------------------------------- */
748 /* Python functions : integration hooks                                      */
749 /* ------------------------------------------------------------------------- */
750
751 PyTypeObject SCA_KeyboardSensor::Type = {
752         PyObject_HEAD_INIT(&PyType_Type)
753         0,
754         "SCA_KeyboardSensor",
755         sizeof(SCA_KeyboardSensor),
756         0,
757         PyDestructor,
758         0,
759         __getattr,
760         __setattr,
761         0, //&MyPyCompare,
762         __repr,
763         0, //&cvalue_as_number,
764         0,
765         0,
766         0,
767         0
768 };
769
770 PyParentObject SCA_KeyboardSensor::Parents[] = {
771         &SCA_KeyboardSensor::Type,
772         &SCA_ISensor::Type,
773         &SCA_ILogicBrick::Type,
774         &CValue::Type,
775         NULL
776 };
777
778 PyMethodDef SCA_KeyboardSensor::Methods[] = {
779   {"getKey", (PyCFunction) SCA_KeyboardSensor::sPyGetKey, METH_VARARGS, (PY_METHODCHAR)GetKey_doc},
780   {"setKey", (PyCFunction) SCA_KeyboardSensor::sPySetKey, METH_VARARGS, (PY_METHODCHAR)SetKey_doc},
781   {"getHold1", (PyCFunction) SCA_KeyboardSensor::sPyGetHold1, METH_VARARGS, (PY_METHODCHAR)GetHold1_doc},
782   {"setHold1", (PyCFunction) SCA_KeyboardSensor::sPySetHold1, METH_VARARGS, (PY_METHODCHAR)SetHold1_doc},
783   {"getHold2", (PyCFunction) SCA_KeyboardSensor::sPyGetHold2, METH_VARARGS, (PY_METHODCHAR)GetHold2_doc},
784   {"setHold2", (PyCFunction) SCA_KeyboardSensor::sPySetHold2, METH_VARARGS, (PY_METHODCHAR)SetHold2_doc},
785 //  {"getUseAllKeys", (PyCFunction) SCA_KeyboardSensor::sPyGetUseAllKeys, METH_VARARGS, (PY_METHODCHAR)GetUseAllKeys_doc},
786 //  {"setUseAllKeys", (PyCFunction) SCA_KeyboardSensor::sPySetUseAllKeys, METH_VARARGS, (PY_METHODCHAR)SetUseAllKeys_doc},
787   {"getPressedKeys", (PyCFunction) SCA_KeyboardSensor::sPyGetPressedKeys, METH_VARARGS, (PY_METHODCHAR)GetPressedKeys_doc},
788   {"getCurrentlyPressedKeys", (PyCFunction) SCA_KeyboardSensor::sPyGetCurrentlyPressedKeys, METH_VARARGS, (PY_METHODCHAR)GetCurrentlyPressedKeys_doc},
789 //  {"getKeyEvents", (PyCFunction) SCA_KeyboardSensor::sPyGetKeyEvents, METH_VARARGS, (PY_METHODCHAR)GetKeyEvents_doc},
790   {NULL,NULL} //Sentinel
791 };
792
793 PyObject*
794 SCA_KeyboardSensor::_getattr(const STR_String& attr)
795 {
796   _getattr_up(SCA_ISensor);
797 }
798