doxygen: prevent GPL license block from being parsed as doxygen comment.
[blender.git] / source / gameengine / GameLogic / SCA_MouseSensor.cpp
1 /*
2  * Sensor for mouse input
3  *
4  *
5  * $Id$
6  *
7  * ***** BEGIN GPL LICENSE BLOCK *****
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): José I. Romero (cleanup and fixes)
29  *
30  * ***** END GPL LICENSE BLOCK *****
31  */
32
33 #include <stddef.h>
34
35 #include "SCA_MouseSensor.h"
36 #include "SCA_EventManager.h"
37 #include "SCA_MouseManager.h"
38 #include "SCA_LogicManager.h"
39 #include "SCA_IInputDevice.h"
40 #include "ConstExpr.h"
41 #include <iostream>
42
43 /* ------------------------------------------------------------------------- */
44 /* Native functions                                                          */
45 /* ------------------------------------------------------------------------- */
46
47 SCA_MouseSensor::SCA_MouseSensor(SCA_MouseManager* eventmgr, 
48                                                                  int startx,int starty,
49                                                                  short int mousemode,
50                                                                  SCA_IObject* gameobj)
51     : SCA_ISensor(gameobj,eventmgr),
52         m_x(startx),
53         m_y(starty)
54 {
55         m_mousemode   = mousemode;
56         m_triggermode = true;
57
58         UpdateHotkey(this);
59         Init();
60 }
61
62 void SCA_MouseSensor::Init()
63 {
64         m_val = (m_invert)?1:0; /* stores the latest attribute */
65         m_reset = true;
66 }
67
68 SCA_MouseSensor::~SCA_MouseSensor() 
69 {
70     /* Nothing to be done here. */
71 }
72
73 void SCA_MouseSensor::UpdateHotkey(void *self)
74 {
75         // gosh, this function is so damn stupid
76         // its here because of a design mistake in the mouse sensor, it should only
77         // have 3 trigger modes (button, wheel, move), and let the user set the 
78         // hotkey separately, like the other sensors. but instead it has a mode for 
79         // each friggin key and i have to update the hotkey based on it... genius!
80         SCA_MouseSensor* sensor = reinterpret_cast<SCA_MouseSensor*>(self);
81
82         switch (sensor->m_mousemode) {
83         case KX_MOUSESENSORMODE_LEFTBUTTON:
84                 sensor->m_hotkey = SCA_IInputDevice::KX_LEFTMOUSE;
85                 break;
86         case KX_MOUSESENSORMODE_MIDDLEBUTTON:
87                 sensor->m_hotkey = SCA_IInputDevice::KX_MIDDLEMOUSE;
88                 break;
89         case KX_MOUSESENSORMODE_RIGHTBUTTON:
90                 sensor->m_hotkey = SCA_IInputDevice::KX_RIGHTMOUSE;
91                 break;
92         case KX_MOUSESENSORMODE_WHEELUP:
93                 sensor->m_hotkey = SCA_IInputDevice::KX_WHEELUPMOUSE;
94                 break;
95         case KX_MOUSESENSORMODE_WHEELDOWN:
96                 sensor->m_hotkey = SCA_IInputDevice::KX_WHEELDOWNMOUSE;
97                 break;
98         default:
99                 ; /* ignore, no hotkey */
100         }
101 }
102
103 CValue* SCA_MouseSensor::GetReplica()
104 {
105         SCA_MouseSensor* replica = new SCA_MouseSensor(*this);
106         // this will copy properties and so on...
107         replica->ProcessReplica();
108         replica->Init();
109
110         return replica;
111 }
112
113
114
115 bool SCA_MouseSensor::IsPositiveTrigger()
116 {
117         bool result = (m_val != 0);
118         if (m_invert)
119                 result = !result;
120                 
121         return result;
122 }
123
124
125
126 short int SCA_MouseSensor::GetModeKey()
127
128         return m_mousemode;
129 }
130
131
132
133 SCA_IInputDevice::KX_EnumInputs SCA_MouseSensor::GetHotKey()
134
135         return m_hotkey;
136 }
137
138
139
140 bool SCA_MouseSensor::Evaluate()
141 {
142         bool result = false;
143         bool reset = m_reset && m_level;
144         SCA_IInputDevice* mousedev = ((SCA_MouseManager *)m_eventmgr)->GetInputDevice();
145
146         m_reset = false;
147         switch (m_mousemode) {
148         case KX_MOUSESENSORMODE_LEFTBUTTON:
149         case KX_MOUSESENSORMODE_MIDDLEBUTTON:
150         case KX_MOUSESENSORMODE_RIGHTBUTTON:
151         case KX_MOUSESENSORMODE_WHEELUP:
152         case KX_MOUSESENSORMODE_WHEELDOWN:
153                 {
154                         const SCA_InputEvent& mevent = mousedev->GetEventValue(m_hotkey);
155                         switch (mevent.m_status){       
156                         case SCA_InputEvent::KX_JUSTACTIVATED:
157                                 m_val = 1;
158                                 result = true;
159                                 break;
160                         case SCA_InputEvent::KX_JUSTRELEASED:
161                                 m_val = 0;
162                                 result = true;
163                                 break;
164                         case SCA_InputEvent::KX_ACTIVE:
165                                 if (m_val == 0)
166                                 {
167                                         m_val = 1;
168                                         if (m_level)
169                                                 result = true;
170                                 }
171                                 break;
172                         default:
173                                 if (m_val == 1)
174                                 {
175                                         m_val = 0;
176                                         result = true;
177                                 }
178                                 break;
179                         }
180                         break;
181                 }
182         case KX_MOUSESENSORMODE_MOVEMENT:
183                 {
184                         const SCA_InputEvent& eventX = mousedev->GetEventValue(SCA_IInputDevice::KX_MOUSEX);
185                         const SCA_InputEvent& eventY = mousedev->GetEventValue(SCA_IInputDevice::KX_MOUSEY);
186
187                         if (eventX.m_status == SCA_InputEvent::KX_JUSTACTIVATED ||
188                                 eventY.m_status == SCA_InputEvent::KX_JUSTACTIVATED ||
189                                 eventX.m_status == SCA_InputEvent::KX_ACTIVE ||
190                                 eventY.m_status == SCA_InputEvent::KX_ACTIVE)   
191                         {
192                                 m_val = 1;
193                                 result = true;
194                         } 
195                         else if (eventX.m_status == SCA_InputEvent::KX_JUSTRELEASED ||
196                                         eventY.m_status == SCA_InputEvent::KX_JUSTRELEASED )
197                         {
198                                 m_val = 0;
199                                 result = true;
200                         } 
201                         else //KX_NO_IMPUTSTATUS
202                         { 
203                                 if (m_val == 1)
204                                 {
205                                         m_val = 0;
206                                         result = true;
207                                 }
208                         }
209                         
210                         break;
211                 }
212         default:
213                 ; /* error */
214         }
215
216         if (reset)
217                 // force an event
218                 result = true;
219         return result;
220 }
221
222 void SCA_MouseSensor::setX(short x)
223 {
224         m_x = x;
225 }
226
227 void SCA_MouseSensor::setY(short y)
228 {
229         m_y = y;
230 }
231
232 bool SCA_MouseSensor::isValid(SCA_MouseSensor::KX_MOUSESENSORMODE m)
233 {
234         return ((m > KX_MOUSESENSORMODE_NODEF) && (m < KX_MOUSESENSORMODE_MAX));
235 }
236
237 #ifdef WITH_PYTHON
238
239 /* ------------------------------------------------------------------------- */
240 /* Python functions                                                          */
241 /* ------------------------------------------------------------------------- */
242
243 KX_PYMETHODDEF_DOC_O(SCA_MouseSensor, getButtonStatus,
244 "getButtonStatus(button)\n"
245 "\tGet the given button's status (KX_INPUT_NONE, KX_INPUT_NONE, KX_INPUT_JUST_ACTIVATED, KX_INPUT_ACTIVE, KX_INPUT_JUST_RELEASED).\n")
246 {
247         if (PyLong_Check(value))
248         {
249                 int button = PyLong_AsSsize_t(value);
250                 
251                 if ((button < SCA_IInputDevice::KX_LEFTMOUSE)
252                         || (button > SCA_IInputDevice::KX_RIGHTMOUSE)){
253                         PyErr_SetString(PyExc_ValueError, "sensor.getButtonStatus(int): Mouse Sensor, invalid button specified!");
254                         return NULL;
255                 }
256                 
257                 SCA_IInputDevice* mousedev = ((SCA_MouseManager *)m_eventmgr)->GetInputDevice();
258                 const SCA_InputEvent& event = mousedev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) button);
259                 return PyLong_FromSsize_t(event.m_status);
260         }
261         
262         Py_RETURN_NONE;
263 }
264
265 /* ------------------------------------------------------------------------- */
266 /* Python Integration Hooks                                                  */
267 /* ------------------------------------------------------------------------- */
268
269 PyTypeObject SCA_MouseSensor::Type = {
270         PyVarObject_HEAD_INIT(NULL, 0)
271         "SCA_MouseSensor",
272         sizeof(PyObjectPlus_Proxy),
273         0,
274         py_base_dealloc,
275         0,
276         0,
277         0,
278         0,
279         py_base_repr,
280         0,0,0,0,0,0,0,0,0,
281         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
282         0,0,0,0,0,0,0,
283         Methods,
284         0,
285         0,
286         &SCA_ISensor::Type,
287         0,0,0,0,0,0,
288         py_base_new
289 };
290
291 PyMethodDef SCA_MouseSensor::Methods[] = {
292         KX_PYMETHODTABLE_O(SCA_MouseSensor, getButtonStatus),
293         {NULL,NULL} //Sentinel
294 };
295
296 int SCA_MouseSensor::UpdateHotkeyPy(void *self, const PyAttributeDef*)
297 {
298         UpdateHotkey(self);
299         // return value is used in py_setattro(),
300         // 0=attribute checked ok (see Attributes array definition)
301         return 0;
302 }
303
304 PyAttributeDef SCA_MouseSensor::Attributes[] = {
305         KX_PYATTRIBUTE_SHORT_RW_CHECK("mode",KX_MOUSESENSORMODE_NODEF,KX_MOUSESENSORMODE_MAX-1,true,SCA_MouseSensor,m_mousemode,UpdateHotkeyPy),
306         KX_PYATTRIBUTE_SHORT_LIST_RO("position",SCA_MouseSensor,m_x,2),
307         { NULL }        //Sentinel
308 };
309
310 #endif // WITH_PYTHON
311
312 /* eof */