Copying scripts from 2.4x without 2.5x changes
[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_x(startx),
55         m_y(starty)
56 {
57         m_mousemode   = mousemode;
58         m_triggermode = true;
59
60         UpdateHotkey(this, NULL);
61         Init();
62 }
63
64 void SCA_MouseSensor::Init()
65 {
66         m_val = (m_invert)?1:0; /* stores the latest attribute */
67         m_reset = true;
68 }
69
70 SCA_MouseSensor::~SCA_MouseSensor() 
71 {
72     /* Nothing to be done here. */
73 }
74
75 int SCA_MouseSensor::UpdateHotkey(void *self, const PyAttributeDef*)
76 {
77         // gosh, this function is so damn stupid
78         // its here because of a design mistake in the mouse sensor, it should only
79         // have 3 trigger modes (button, wheel, move), and let the user set the 
80         // hotkey separately, like the other sensors. but instead it has a mode for 
81         // each friggin key and i have to update the hotkey based on it... genius!
82         SCA_MouseSensor* sensor = reinterpret_cast<SCA_MouseSensor*>(self);
83
84         switch (sensor->m_mousemode) {
85         case KX_MOUSESENSORMODE_LEFTBUTTON:
86                 sensor->m_hotkey = SCA_IInputDevice::KX_LEFTMOUSE;
87                 break;
88         case KX_MOUSESENSORMODE_MIDDLEBUTTON:
89                 sensor->m_hotkey = SCA_IInputDevice::KX_MIDDLEMOUSE;
90                 break;
91         case KX_MOUSESENSORMODE_RIGHTBUTTON:
92                 sensor->m_hotkey = SCA_IInputDevice::KX_RIGHTMOUSE;
93                 break;
94         case KX_MOUSESENSORMODE_WHEELUP:
95                 sensor->m_hotkey = SCA_IInputDevice::KX_WHEELUPMOUSE;
96                 break;
97         case KX_MOUSESENSORMODE_WHEELDOWN:
98                 sensor->m_hotkey = SCA_IInputDevice::KX_WHEELDOWNMOUSE;
99                 break;
100         default:
101                 ; /* ignore, no hotkey */
102         }
103         // return value is used in py_setattro(), 
104         // 0=attribute checked ok (see Attributes array definition)
105         return 0;
106 }
107
108 CValue* SCA_MouseSensor::GetReplica()
109 {
110         SCA_MouseSensor* replica = new SCA_MouseSensor(*this);
111         // this will copy properties and so on...
112         replica->ProcessReplica();
113         replica->Init();
114
115         return replica;
116 }
117
118
119
120 bool SCA_MouseSensor::IsPositiveTrigger()
121 {
122         bool result = (m_val != 0);
123         if (m_invert)
124                 result = !result;
125                 
126         return result;
127 }
128
129
130
131 short int SCA_MouseSensor::GetModeKey()
132
133         return m_mousemode;
134 }
135
136
137
138 SCA_IInputDevice::KX_EnumInputs SCA_MouseSensor::GetHotKey()
139
140         return m_hotkey;
141 }
142
143
144
145 bool SCA_MouseSensor::Evaluate()
146 {
147         bool result = false;
148         bool reset = m_reset && m_level;
149         SCA_IInputDevice* mousedev = ((SCA_MouseManager *)m_eventmgr)->GetInputDevice();
150
151         m_reset = false;
152         switch (m_mousemode) {
153         case KX_MOUSESENSORMODE_LEFTBUTTON:
154         case KX_MOUSESENSORMODE_MIDDLEBUTTON:
155         case KX_MOUSESENSORMODE_RIGHTBUTTON:
156         case KX_MOUSESENSORMODE_WHEELUP:
157         case KX_MOUSESENSORMODE_WHEELDOWN:
158                 {
159                         const SCA_InputEvent& mevent = mousedev->GetEventValue(m_hotkey);
160                         switch (mevent.m_status){       
161                         case SCA_InputEvent::KX_JUSTACTIVATED:
162                                 m_val = 1;
163                                 result = true;
164                                 break;
165                         case SCA_InputEvent::KX_JUSTRELEASED:
166                                 m_val = 0;
167                                 result = true;
168                                 break;
169                         case SCA_InputEvent::KX_ACTIVE:
170                                 if (m_val == 0)
171                                 {
172                                         m_val = 1;
173                                         if (m_level)
174                                                 result = true;
175                                 }
176                                 break;
177                         default:
178                                 if (m_val == 1)
179                                 {
180                                         m_val = 0;
181                                         result = true;
182                                 }
183                                 break;
184                         }
185                         break;
186                 }
187         case KX_MOUSESENSORMODE_MOVEMENT:
188                 {
189                         const SCA_InputEvent& eventX = mousedev->GetEventValue(SCA_IInputDevice::KX_MOUSEX);
190                         const SCA_InputEvent& eventY = mousedev->GetEventValue(SCA_IInputDevice::KX_MOUSEY);
191
192                         if (eventX.m_status == SCA_InputEvent::KX_JUSTACTIVATED ||
193                                 eventY.m_status == SCA_InputEvent::KX_JUSTACTIVATED ||
194                                 eventX.m_status == SCA_InputEvent::KX_ACTIVE ||
195                                 eventY.m_status == SCA_InputEvent::KX_ACTIVE)   
196                         {
197                                 m_val = 1;
198                                 result = true;
199                         } 
200                         else if (eventX.m_status == SCA_InputEvent::KX_JUSTRELEASED ||
201                                         eventY.m_status == SCA_InputEvent::KX_JUSTRELEASED )
202                         {
203                                 m_val = 0;
204                                 result = true;
205                         } 
206                         else //KX_NO_IMPUTSTATUS
207                         { 
208                                 if (m_val == 1)
209                                 {
210                                         m_val = 0;
211                                         result = true;
212                                 }
213                         }
214                         
215                         break;
216                 }
217         default:
218                 ; /* error */
219         }
220
221         if (reset)
222                 // force an event
223                 result = true;
224         return result;
225 }
226
227 void SCA_MouseSensor::setX(short x)
228 {
229         m_x = x;
230 }
231
232 void SCA_MouseSensor::setY(short y)
233 {
234         m_y = y;
235 }
236
237 bool SCA_MouseSensor::isValid(SCA_MouseSensor::KX_MOUSESENSORMODE m)
238 {
239         return ((m > KX_MOUSESENSORMODE_NODEF) && (m < KX_MOUSESENSORMODE_MAX));
240 }
241
242 /* ------------------------------------------------------------------------- */
243 /* Python functions                                                          */
244 /* ------------------------------------------------------------------------- */
245
246 KX_PYMETHODDEF_DOC_O(SCA_MouseSensor, getButtonStatus,
247 "getButtonStatus(button)\n"
248 "\tGet the given button's status (KX_INPUT_NONE, KX_INPUT_NONE, KX_INPUT_JUST_ACTIVATED, KX_INPUT_ACTIVE, KX_INPUT_JUST_RELEASED).\n")
249 {
250         if (PyLong_Check(value))
251         {
252                 int button = PyLong_AsSsize_t(value);
253                 
254                 if ((button < SCA_IInputDevice::KX_LEFTMOUSE)
255                         || (button > SCA_IInputDevice::KX_RIGHTMOUSE)){
256                         PyErr_SetString(PyExc_ValueError, "sensor.getButtonStatus(int): Mouse Sensor, invalid button specified!");
257                         return NULL;
258                 }
259                 
260                 SCA_IInputDevice* mousedev = ((SCA_MouseManager *)m_eventmgr)->GetInputDevice();
261                 const SCA_InputEvent& event = mousedev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) button);
262                 return PyLong_FromSsize_t(event.m_status);
263         }
264         
265         Py_RETURN_NONE;
266 }
267
268 /* ------------------------------------------------------------------------- */
269 /* Python Integration Hooks                                                  */
270 /* ------------------------------------------------------------------------- */
271
272 PyTypeObject SCA_MouseSensor::Type = {
273         PyVarObject_HEAD_INIT(NULL, 0)
274         "SCA_MouseSensor",
275         sizeof(PyObjectPlus_Proxy),
276         0,
277         py_base_dealloc,
278         0,
279         0,
280         0,
281         0,
282         py_base_repr,
283         0,0,0,0,0,0,0,0,0,
284         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
285         0,0,0,0,0,0,0,
286         Methods,
287         0,
288         0,
289         &SCA_ISensor::Type,
290         0,0,0,0,0,0,
291         py_base_new
292 };
293
294 PyMethodDef SCA_MouseSensor::Methods[] = {
295         KX_PYMETHODTABLE_O(SCA_MouseSensor, getButtonStatus),
296         {NULL,NULL} //Sentinel
297 };
298
299 PyAttributeDef SCA_MouseSensor::Attributes[] = {
300         KX_PYATTRIBUTE_SHORT_RW_CHECK("mode",KX_MOUSESENSORMODE_NODEF,KX_MOUSESENSORMODE_MAX-1,true,SCA_MouseSensor,m_mousemode,UpdateHotkey),
301         KX_PYATTRIBUTE_SHORT_LIST_RO("position",SCA_MouseSensor,m_x,2),
302         { NULL }        //Sentinel
303 };
304
305 /* eof */