49fa19dce38832bfa6c9cb9d5016632b4007248c
[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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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 "SCA_MouseSensor.h"
34 #include "SCA_EventManager.h"
35 #include "SCA_MouseManager.h"
36 #include "SCA_LogicManager.h"
37 #include "SCA_IInputDevice.h"
38 #include "ConstExpr.h"
39 #include <iostream>
40
41 #ifdef HAVE_CONFIG_H
42 #include <config.h>
43 #endif
44
45 /* ------------------------------------------------------------------------- */
46 /* Native functions                                                          */
47 /* ------------------------------------------------------------------------- */
48
49 SCA_MouseSensor::SCA_MouseSensor(SCA_MouseManager* eventmgr, 
50                                                                  int startx,int starty,
51                                                                  short int mousemode,
52                                                                  SCA_IObject* gameobj)
53     : SCA_ISensor(gameobj,eventmgr),
54         m_pMouseMgr(eventmgr),
55         m_x(startx),
56         m_y(starty)
57 {
58         m_mousemode   = mousemode;
59         m_triggermode = true;
60
61         UpdateHotkey(this, NULL);
62         Init();
63 }
64
65 void SCA_MouseSensor::Init()
66 {
67         m_val = (m_invert)?1:0; /* stores the latest attribute */
68         m_reset = true;
69 }
70
71 SCA_MouseSensor::~SCA_MouseSensor() 
72 {
73     /* Nothing to be done here. */
74 }
75
76 int SCA_MouseSensor::UpdateHotkey(void *self, const PyAttributeDef*)
77 {
78         // gosh, this function is so damn stupid
79         // its here because of a design mistake in the mouse sensor, it should only
80         // have 3 trigger modes (button, wheel, move), and let the user set the 
81         // hotkey separately, like the other sensors. but instead it has a mode for 
82         // each friggin key and i have to update the hotkey based on it... genius!
83         SCA_MouseSensor* sensor = reinterpret_cast<SCA_MouseSensor*>(self);
84
85         switch (sensor->m_mousemode) {
86         case KX_MOUSESENSORMODE_LEFTBUTTON:
87                 sensor->m_hotkey = SCA_IInputDevice::KX_LEFTMOUSE;
88                 break;
89         case KX_MOUSESENSORMODE_MIDDLEBUTTON:
90                 sensor->m_hotkey = SCA_IInputDevice::KX_MIDDLEMOUSE;
91                 break;
92         case KX_MOUSESENSORMODE_RIGHTBUTTON:
93                 sensor->m_hotkey = SCA_IInputDevice::KX_RIGHTMOUSE;
94                 break;
95         case KX_MOUSESENSORMODE_WHEELUP:
96                 sensor->m_hotkey = SCA_IInputDevice::KX_WHEELUPMOUSE;
97                 break;
98         case KX_MOUSESENSORMODE_WHEELDOWN:
99                 sensor->m_hotkey = SCA_IInputDevice::KX_WHEELDOWNMOUSE;
100                 break;
101         default:
102                 ; /* ignore, no hotkey */
103         }
104         // return value is used in py_setattro(), 
105         // 0=attribute checked ok (see Attributes array definition)
106         return 0;
107 }
108
109 CValue* SCA_MouseSensor::GetReplica()
110 {
111         SCA_MouseSensor* replica = new SCA_MouseSensor(*this);
112         // this will copy properties and so on...
113         replica->ProcessReplica();
114         replica->Init();
115
116         return replica;
117 }
118
119
120
121 bool SCA_MouseSensor::IsPositiveTrigger()
122 {
123         bool result = (m_val != 0);
124         if (m_invert)
125                 result = !result;
126                 
127         return result;
128 }
129
130
131
132 short int SCA_MouseSensor::GetModeKey()
133
134         return m_mousemode;
135 }
136
137
138
139 SCA_IInputDevice::KX_EnumInputs SCA_MouseSensor::GetHotKey()
140
141         return m_hotkey;
142 }
143
144
145
146 bool SCA_MouseSensor::Evaluate()
147 {
148         bool result = false;
149         bool reset = m_reset && m_level;
150         SCA_IInputDevice* mousedev = m_pMouseMgr->GetInputDevice();
151
152         m_reset = false;
153         switch (m_mousemode) {
154         case KX_MOUSESENSORMODE_LEFTBUTTON:
155         case KX_MOUSESENSORMODE_MIDDLEBUTTON:
156         case KX_MOUSESENSORMODE_RIGHTBUTTON:
157         case KX_MOUSESENSORMODE_WHEELUP:
158         case KX_MOUSESENSORMODE_WHEELDOWN:
159                 {
160                         const SCA_InputEvent& mevent = mousedev->GetEventValue(m_hotkey);
161                         switch (mevent.m_status){       
162                         case SCA_InputEvent::KX_JUSTACTIVATED:
163                                 m_val = 1;
164                                 result = true;
165                                 break;
166                         case SCA_InputEvent::KX_JUSTRELEASED:
167                                 m_val = 0;
168                                 result = true;
169                                 break;
170                         case SCA_InputEvent::KX_ACTIVE:
171                                 if (m_val == 0)
172                                 {
173                                         m_val = 1;
174                                         if (m_level)
175                                                 result = true;
176                                 }
177                                 break;
178                         default:
179                                 if (m_val == 1)
180                                 {
181                                         m_val = 0;
182                                         result = true;
183                                 }
184                                 break;
185                         }
186                         break;
187                 }
188         case KX_MOUSESENSORMODE_MOVEMENT:
189                 {
190                         const SCA_InputEvent& eventX = mousedev->GetEventValue(SCA_IInputDevice::KX_MOUSEX);
191                         const SCA_InputEvent& eventY = mousedev->GetEventValue(SCA_IInputDevice::KX_MOUSEY);
192
193                         if (eventX.m_status == SCA_InputEvent::KX_JUSTACTIVATED ||
194                                 eventY.m_status == SCA_InputEvent::KX_JUSTACTIVATED ||
195                                 eventX.m_status == SCA_InputEvent::KX_ACTIVE ||
196                                 eventY.m_status == SCA_InputEvent::KX_ACTIVE)   
197                         {
198                                 m_val = 1;
199                                 result = true;
200                         } 
201                         else if (eventX.m_status == SCA_InputEvent::KX_JUSTRELEASED ||
202                                         eventY.m_status == SCA_InputEvent::KX_JUSTRELEASED )
203                         {
204                                 m_val = 0;
205                                 result = true;
206                         } 
207                         else //KX_NO_IMPUTSTATUS
208                         { 
209                                 if (m_val == 1)
210                                 {
211                                         m_val = 0;
212                                         result = true;
213                                 }
214                         }
215                         
216                         break;
217                 }
218         default:
219                 ; /* error */
220         }
221
222         if (reset)
223                 // force an event
224                 result = true;
225         return result;
226 }
227
228 void SCA_MouseSensor::setX(short x)
229 {
230         m_x = x;
231 }
232
233 void SCA_MouseSensor::setY(short y)
234 {
235         m_y = y;
236 }
237
238 bool SCA_MouseSensor::isValid(SCA_MouseSensor::KX_MOUSESENSORMODE m)
239 {
240         return ((m > KX_MOUSESENSORMODE_NODEF) && (m < KX_MOUSESENSORMODE_MAX));
241 }
242
243 /* ------------------------------------------------------------------------- */
244 /* Python functions                                                          */
245 /* ------------------------------------------------------------------------- */
246
247 //Deprecated functions ------>
248 /* get x position ---------------------------------------------------------- */
249 const char SCA_MouseSensor::GetXPosition_doc[] = 
250 "getXPosition\n"
251 "\tReturns the x-coordinate of the mouse sensor, in frame coordinates.\n"
252 "\tThe lower-left corner is the origin. The coordinate is given in\n"
253 "\tpixels\n";
254 PyObject* SCA_MouseSensor::PyGetXPosition() {
255         ShowDeprecationWarning("getXPosition()", "the position property");
256         return PyLong_FromSsize_t(m_x);
257 }
258
259 /* get y position ---------------------------------------------------------- */
260 const char SCA_MouseSensor::GetYPosition_doc[] = 
261 "getYPosition\n"
262 "\tReturns the y-coordinate of the mouse sensor, in frame coordinates.\n"
263 "\tThe lower-left corner is the origin. The coordinate is given in\n"
264 "\tpixels\n";
265 PyObject* SCA_MouseSensor::PyGetYPosition() {
266         ShowDeprecationWarning("getYPosition()", "the position property");
267         return PyLong_FromSsize_t(m_y);
268 }
269 //<----- Deprecated
270
271 KX_PYMETHODDEF_DOC_O(SCA_MouseSensor, getButtonStatus,
272 "getButtonStatus(button)\n"
273 "\tGet the given button's status (KX_INPUT_NONE, KX_INPUT_NONE, KX_INPUT_JUST_ACTIVATED, KX_INPUT_ACTIVE, KX_INPUT_JUST_RELEASED).\n")
274 {
275         if (PyLong_Check(value))
276         {
277                 int button = PyLong_AsSsize_t(value);
278                 
279                 if ((button < SCA_IInputDevice::KX_LEFTMOUSE)
280                         || (button > SCA_IInputDevice::KX_RIGHTMOUSE)){
281                         PyErr_SetString(PyExc_ValueError, "sensor.getButtonStatus(int): Mouse Sensor, invalid button specified!");
282                         return NULL;
283                 }
284                 
285                 SCA_IInputDevice* mousedev = m_pMouseMgr->GetInputDevice();
286                 const SCA_InputEvent& event = mousedev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) button);
287                 return PyLong_FromSsize_t(event.m_status);
288         }
289         
290         Py_RETURN_NONE;
291 }
292
293 /* ------------------------------------------------------------------------- */
294 /* Python Integration Hooks                                                  */
295 /* ------------------------------------------------------------------------- */
296
297 PyTypeObject SCA_MouseSensor::Type = {
298 #if (PY_VERSION_HEX >= 0x02060000)
299         PyVarObject_HEAD_INIT(NULL, 0)
300 #else
301         /* python 2.5 and below */
302         PyObject_HEAD_INIT( NULL )  /* required py macro */
303         0,                          /* ob_size */
304 #endif
305         "SCA_MouseSensor",
306         sizeof(PyObjectPlus_Proxy),
307         0,
308         py_base_dealloc,
309         0,
310         0,
311         0,
312         0,
313         py_base_repr,
314         0,0,0,0,0,0,0,0,0,
315         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
316         0,0,0,0,0,0,0,
317         Methods,
318         0,
319         0,
320         &SCA_ISensor::Type,
321         0,0,0,0,0,0,
322         py_base_new
323 };
324
325 PyMethodDef SCA_MouseSensor::Methods[] = {
326         //Deprecated functions ------>
327         {"getXPosition", (PyCFunction) SCA_MouseSensor::sPyGetXPosition, METH_VARARGS, (PY_METHODCHAR)GetXPosition_doc},
328         {"getYPosition", (PyCFunction) SCA_MouseSensor::sPyGetYPosition, METH_VARARGS, (PY_METHODCHAR)GetYPosition_doc},
329         //<----- Deprecated
330         KX_PYMETHODTABLE_O(SCA_MouseSensor, getButtonStatus),
331         {NULL,NULL} //Sentinel
332 };
333
334 PyAttributeDef SCA_MouseSensor::Attributes[] = {
335         KX_PYATTRIBUTE_SHORT_RW_CHECK("mode",KX_MOUSESENSORMODE_NODEF,KX_MOUSESENSORMODE_MAX-1,true,SCA_MouseSensor,m_mousemode,UpdateHotkey),
336         KX_PYATTRIBUTE_SHORT_LIST_RO("position",SCA_MouseSensor,m_x,2),
337         { NULL }        //Sentinel
338 };
339
340 /* eof */