Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitchell Stokes <mogurijin@gmail.com>2012-12-21 06:28:59 +0400
committerMitchell Stokes <mogurijin@gmail.com>2012-12-21 06:28:59 +0400
commitf2f2b6153a2a818ca940a4df5b7dafc743ef2d2f (patch)
treea6562a6c389b7f3e99461dda1245b1037b78a020 /source/gameengine/GameLogic
parent26752e8b3a367a7c5161ad7418e910bb2ce6ee5d (diff)
BGE: Adding a Python interface for handling joysticks without needing logic bricks. These new SCA_PythonJoystick objects can be accessed using bge.logic.joysticks, which is a list of joysticks. The length of the list is the number of maximum supported joysticks, and indexes that do not have a joystick available are set to None. This means joysticks can be checked for using something like:
if bge.logic.joysticks[0]: activate_player_one() if bge.logic.joysticks[1]: activate_player_two() etc.. The interface exposed by SCA_PythonJoystick is very similar to the joystick logic brick except for one key difference: axis values are normalized to a -1.0 to 1.0 range instead of -32767 to 32767, which is what the logic brick exposed.
Diffstat (limited to 'source/gameengine/GameLogic')
-rw-r--r--source/gameengine/GameLogic/CMakeLists.txt2
-rw-r--r--source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp9
-rw-r--r--source/gameengine/GameLogic/Joystick/SCA_Joystick.h5
-rw-r--r--source/gameengine/GameLogic/SCA_JoystickManager.cpp8
-rw-r--r--source/gameengine/GameLogic/SCA_PythonJoystick.cpp184
-rw-r--r--source/gameengine/GameLogic/SCA_PythonJoystick.h56
6 files changed, 261 insertions, 3 deletions
diff --git a/source/gameengine/GameLogic/CMakeLists.txt b/source/gameengine/GameLogic/CMakeLists.txt
index e511704c7f4..ad357bd015b 100644
--- a/source/gameengine/GameLogic/CMakeLists.txt
+++ b/source/gameengine/GameLogic/CMakeLists.txt
@@ -71,6 +71,7 @@ set(SRC
SCA_PropertyEventManager.cpp
SCA_PropertySensor.cpp
SCA_PythonController.cpp
+ SCA_PythonJoystick.cpp
SCA_PythonKeyboard.cpp
SCA_PythonMouse.cpp
SCA_RandomActuator.cpp
@@ -114,6 +115,7 @@ set(SRC
SCA_PropertyEventManager.h
SCA_PropertySensor.h
SCA_PythonController.h
+ SCA_PythonJoystick.h
SCA_PythonKeyboard.h
SCA_PythonMouse.h
SCA_RandomActuator.h
diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
index 8b343be8226..b7fbe958c86 100644
--- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
+++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
@@ -321,3 +321,12 @@ int SCA_Joystick::pAxisTest(int axisnum)
return 0;
#endif /* WITH_SDL */
}
+
+const char *SCA_Joystick::GetName()
+{
+#ifdef WITH_SDL
+ return SDL_JoystickName(m_joyindex);
+#else /* WITH_SDL */
+ return "";
+#endif /* WITH_SDL */
+}
diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.h b/source/gameengine/GameLogic/Joystick/SCA_Joystick.h
index 912484a2fe5..dd9fbefa545 100644
--- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.h
+++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.h
@@ -192,6 +192,11 @@ public:
* Test if the joystick is connected
*/
int Connected(void);
+
+ /**
+ * Name of the joytsick
+ */
+ const char *GetName();
};
#endif
diff --git a/source/gameengine/GameLogic/SCA_JoystickManager.cpp b/source/gameengine/GameLogic/SCA_JoystickManager.cpp
index c21db794e42..780e4e9ce88 100644
--- a/source/gameengine/GameLogic/SCA_JoystickManager.cpp
+++ b/source/gameengine/GameLogic/SCA_JoystickManager.cpp
@@ -60,14 +60,16 @@ SCA_JoystickManager::~SCA_JoystickManager()
void SCA_JoystickManager::NextFrame(double curtime,double deltatime)
{
+ // We should always handle events in case we want to grab them with Python
+#ifdef WITH_SDL
+ SCA_Joystick::HandleEvents(); /* Handle all SDL Joystick events */
+#endif
+
if (m_sensors.Empty()) {
return;
}
else {
;
-#ifdef WITH_SDL
- SCA_Joystick::HandleEvents(); /* Handle all SDL Joystick events */
-#endif
SG_DList::iterator<SCA_JoystickSensor> it(m_sensors);
for (it.begin();!it.end();++it)
{
diff --git a/source/gameengine/GameLogic/SCA_PythonJoystick.cpp b/source/gameengine/GameLogic/SCA_PythonJoystick.cpp
new file mode 100644
index 00000000000..ee792111705
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_PythonJoystick.cpp
@@ -0,0 +1,184 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Mitchell Stokes.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file gameengine/GameLogic/SCA_PythonJoystick.cpp
+ * \ingroup gamelogic
+ */
+
+
+#include "SCA_PythonJoystick.h"
+#include "./Joystick/SCA_Joystick.h"
+#include "SCA_IInputDevice.h"
+
+//#include "GHOST_C-api.h"
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_PythonJoystick::SCA_PythonJoystick(SCA_Joystick* joystick)
+: PyObjectPlus(),
+m_joystick(joystick)
+{
+#ifdef WITH_PYTHON
+ m_event_dict = PyDict_New();
+#endif
+}
+
+SCA_PythonJoystick::~SCA_PythonJoystick()
+{
+#ifdef WITH_PYTHON
+ PyDict_Clear(m_event_dict);
+ Py_DECREF(m_event_dict);
+#endif
+}
+
+#ifdef WITH_PYTHON
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+PyObject* SCA_PythonJoystick::py_repr(void)
+{
+ return PyUnicode_FromString(m_joystick->GetName());
+}
+
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_PythonJoystick::Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "SCA_PythonJoystick",
+ sizeof(PyObjectPlus_Proxy),
+ 0,
+ py_base_dealloc,
+ 0,
+ 0,
+ 0,
+ 0,
+ py_base_repr,
+ 0,0,0,0,0,0,0,0,0,
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ 0,0,0,0,0,0,0,
+ Methods,
+ 0,
+ 0,
+ &PyObjectPlus::Type,
+ 0,0,0,0,0,0,
+ py_base_new
+};
+
+PyMethodDef SCA_PythonJoystick::Methods[] = {
+ {NULL,NULL} //Sentinel
+};
+
+PyAttributeDef SCA_PythonJoystick::Attributes[] = {
+ KX_PYATTRIBUTE_RO_FUNCTION("numButtons", SCA_PythonJoystick, pyattr_get_num_x),
+ KX_PYATTRIBUTE_RO_FUNCTION("numHats", SCA_PythonJoystick, pyattr_get_num_x),
+ KX_PYATTRIBUTE_RO_FUNCTION("numAxis", SCA_PythonJoystick, pyattr_get_num_x),
+ KX_PYATTRIBUTE_RO_FUNCTION("activeButtons", SCA_PythonJoystick, pyattr_get_active_buttons),
+ KX_PYATTRIBUTE_RO_FUNCTION("hatValues", SCA_PythonJoystick, pyattr_get_hat_values),
+ KX_PYATTRIBUTE_RO_FUNCTION("axisValues", SCA_PythonJoystick, pyattr_get_axis_values),
+ KX_PYATTRIBUTE_RO_FUNCTION("name", SCA_PythonJoystick, pyattr_get_name),
+ { NULL } //Sentinel
+};
+
+// Use one function for numAxis, numButtons, and numHats
+PyObject* SCA_PythonJoystick::pyattr_get_num_x(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ SCA_PythonJoystick* self = static_cast<SCA_PythonJoystick*>(self_v);
+
+ if (strcmp(attrdef->m_name, "numButtons") == 0)
+ return PyLong_FromLong(self->m_joystick->GetNumberOfButtons());
+ else if (strcmp(attrdef->m_name, "numAxis") == 0)
+ return PyLong_FromLong(self->m_joystick->GetNumberOfAxes());
+ else if (strcmp(attrdef->m_name, "numHats") == 0)
+ return PyLong_FromLong(self->m_joystick->GetNumberOfHats());
+
+ // If we got here, we have a problem...
+ PyErr_SetString(PyExc_AttributeError, "invalid attribute");
+ return NULL;
+}
+
+PyObject* SCA_PythonJoystick::pyattr_get_active_buttons(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ SCA_PythonJoystick* self = static_cast<SCA_PythonJoystick*>(self_v);
+
+ int button_index = self->m_joystick->GetNumberOfButtons();
+
+ PyObject *list = PyList_New(0);
+ PyObject *value;
+
+ for (int i=0; i < self->m_joystick->GetNumberOfButtons(); i++) {
+ if (self->m_joystick->aButtonPressIsPositive(i)) {
+ value = PyLong_FromSsize_t(i);
+ PyList_Append(list, value);
+ Py_DECREF(value);
+ }
+ }
+
+ return list;
+}
+
+PyObject* SCA_PythonJoystick::pyattr_get_hat_values(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ SCA_PythonJoystick* self = static_cast<SCA_PythonJoystick*>(self_v);
+
+ int hat_index = self->m_joystick->GetNumberOfHats();
+ PyObject *list = PyList_New(hat_index);
+
+ while (hat_index--) {
+ PyList_SET_ITEM(list, hat_index, PyLong_FromLong(self->m_joystick->GetHat(hat_index)));
+ }
+
+ return list;
+}
+
+PyObject* SCA_PythonJoystick::pyattr_get_axis_values(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ SCA_PythonJoystick* self = static_cast<SCA_PythonJoystick*>(self_v);
+
+ int axis_index = self->m_joystick->GetNumberOfAxes();
+ PyObject *list = PyList_New(axis_index);
+ int position;
+
+ while (axis_index--) {
+ position = self->m_joystick->GetAxisPosition(axis_index);
+
+ // We get back a range from -32768 to 32767, so we use an if here to
+ // get a perfect -1.0 to 1.0 mapping. Some oddball system might have an
+ // actual min of -32767 for shorts, so we use SHRT_MIN/MAX to be safe.
+ if (position < 0)
+ PyList_SET_ITEM(list, axis_index, PyFloat_FromDouble(position/((double)-SHRT_MIN)));
+ else
+ PyList_SET_ITEM(list, axis_index, PyFloat_FromDouble(position/(double)SHRT_MAX));
+ }
+
+ return list;
+}
+
+PyObject* SCA_PythonJoystick::pyattr_get_name(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ SCA_PythonJoystick* self = static_cast<SCA_PythonJoystick*>(self_v);
+
+ return PyUnicode_FromString(self->m_joystick->GetName());
+}
+#endif
diff --git a/source/gameengine/GameLogic/SCA_PythonJoystick.h b/source/gameengine/GameLogic/SCA_PythonJoystick.h
new file mode 100644
index 00000000000..15c6285aed5
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_PythonJoystick.h
@@ -0,0 +1,56 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Mitchell Stokes.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file SCA_PythonJoystick.h
+ * \ingroup gamelogic
+ */
+
+#ifndef __SCA_PYTHONJOYSTICK_H__
+#define __SCA_PYTHONJOYSTICK_H__
+
+#include "PyObjectPlus.h"
+
+class SCA_PythonJoystick : public PyObjectPlus
+{
+ Py_Header
+private:
+ class SCA_Joystick *m_joystick;
+#ifdef WITH_PYTHON
+ PyObject* m_event_dict;
+#endif
+public:
+ SCA_PythonJoystick(class SCA_Joystick* joystick);
+ virtual ~SCA_PythonJoystick();
+
+#ifdef WITH_PYTHON
+ virtual PyObject* py_repr(void);
+
+ static PyObject* pyattr_get_num_x(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_active_buttons(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_hat_values(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_axis_values(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_name(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+#endif
+};
+
+#endif //__SCA_PYTHONJOYSTICK_H__
+