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:
Diffstat (limited to 'source/gameengine/GameLogic')
-rw-r--r--source/gameengine/GameLogic/Makefile47
-rw-r--r--source/gameengine/GameLogic/SCA_ANDController.cpp143
-rw-r--r--source/gameengine/GameLogic/SCA_ANDController.h58
-rw-r--r--source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp67
-rw-r--r--source/gameengine/GameLogic/SCA_AlwaysEventManager.h48
-rw-r--r--source/gameengine/GameLogic/SCA_AlwaysSensor.cpp138
-rw-r--r--source/gameengine/GameLogic/SCA_AlwaysSensor.h62
-rw-r--r--source/gameengine/GameLogic/SCA_EventManager.cpp71
-rw-r--r--source/gameengine/GameLogic/SCA_EventManager.h69
-rw-r--r--source/gameengine/GameLogic/SCA_ExpressionController.cpp161
-rw-r--r--source/gameengine/GameLogic/SCA_ExpressionController.h64
-rw-r--r--source/gameengine/GameLogic/SCA_IActuator.cpp104
-rw-r--r--source/gameengine/GameLogic/SCA_IActuator.h81
-rw-r--r--source/gameengine/GameLogic/SCA_IController.cpp120
-rw-r--r--source/gameengine/GameLogic/SCA_IController.h56
-rw-r--r--source/gameengine/GameLogic/SCA_IInputDevice.cpp138
-rw-r--r--source/gameengine/GameLogic/SCA_IInputDevice.h307
-rw-r--r--source/gameengine/GameLogic/SCA_ILogicBrick.cpp325
-rw-r--r--source/gameengine/GameLogic/SCA_ILogicBrick.h111
-rw-r--r--source/gameengine/GameLogic/SCA_IObject.cpp363
-rw-r--r--source/gameengine/GameLogic/SCA_IObject.h126
-rw-r--r--source/gameengine/GameLogic/SCA_IScene.cpp67
-rw-r--r--source/gameengine/GameLogic/SCA_IScene.h62
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.cpp328
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.h130
-rw-r--r--source/gameengine/GameLogic/SCA_KeyboardManager.cpp91
-rw-r--r--source/gameengine/GameLogic/SCA_KeyboardManager.h66
-rw-r--r--source/gameengine/GameLogic/SCA_KeyboardSensor.cpp675
-rw-r--r--source/gameengine/GameLogic/SCA_KeyboardSensor.h158
-rw-r--r--source/gameengine/GameLogic/SCA_LogicManager.cpp461
-rw-r--r--source/gameengine/GameLogic/SCA_LogicManager.h154
-rw-r--r--source/gameengine/GameLogic/SCA_MouseManager.cpp116
-rw-r--r--source/gameengine/GameLogic/SCA_MouseManager.h72
-rw-r--r--source/gameengine/GameLogic/SCA_MouseSensor.cpp273
-rw-r--r--source/gameengine/GameLogic/SCA_MouseSensor.h120
-rw-r--r--source/gameengine/GameLogic/SCA_ORController.cpp135
-rw-r--r--source/gameengine/GameLogic/SCA_ORController.h58
-rw-r--r--source/gameengine/GameLogic/SCA_PropertyActuator.cpp285
-rw-r--r--source/gameengine/GameLogic/SCA_PropertyActuator.h116
-rw-r--r--source/gameengine/GameLogic/SCA_PropertyEventManager.cpp67
-rw-r--r--source/gameengine/GameLogic/SCA_PropertyEventManager.h52
-rw-r--r--source/gameengine/GameLogic/SCA_PropertySensor.cpp420
-rw-r--r--source/gameengine/GameLogic/SCA_PropertySensor.h109
-rw-r--r--source/gameengine/GameLogic/SCA_PythonController.cpp400
-rw-r--r--source/gameengine/GameLogic/SCA_PythonController.h88
-rw-r--r--source/gameengine/GameLogic/SCA_RandomActuator.cpp630
-rw-r--r--source/gameengine/GameLogic/SCA_RandomActuator.h144
-rw-r--r--source/gameengine/GameLogic/SCA_RandomEventManager.cpp64
-rw-r--r--source/gameengine/GameLogic/SCA_RandomEventManager.h53
-rw-r--r--source/gameengine/GameLogic/SCA_RandomNumberGenerator.cpp125
-rw-r--r--source/gameengine/GameLogic/SCA_RandomNumberGenerator.h65
-rw-r--r--source/gameengine/GameLogic/SCA_RandomSensor.cpp191
-rw-r--r--source/gameengine/GameLogic/SCA_RandomSensor.h75
-rw-r--r--source/gameengine/GameLogic/SCA_TimeEventManager.cpp110
-rw-r--r--source/gameengine/GameLogic/SCA_TimeEventManager.h54
55 files changed, 8673 insertions, 0 deletions
diff --git a/source/gameengine/GameLogic/Makefile b/source/gameengine/GameLogic/Makefile
new file mode 100644
index 00000000000..6de9ba0b145
--- /dev/null
+++ b/source/gameengine/GameLogic/Makefile
@@ -0,0 +1,47 @@
+#
+# $Id$
+#
+# ***** BEGIN GPL/BL DUAL 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. The Blender
+# Foundation also sells licenses for use in proprietary software under
+# the Blender License. See http://www.blender.org/BL/ for information
+# about this.
+#
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): none yet.
+#
+# ***** END GPL/BL DUAL LICENSE BLOCK *****
+#
+#
+
+LIBNAME = logic
+DIR = $(OCGDIR)/gameengine/$(LIBNAME)
+
+include nan_compile.mk
+
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+CPPFLAGS += -I../Expressions
+CPPFLAGS += -I$(NAN_STRING)/include
+CPPFLAGS += -I$(NAN_MOTO)/include
+CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
+CPPFLAGS += -I../../kernel/gen_system
+CPPFLAGS += -I../Ketsji
+
diff --git a/source/gameengine/GameLogic/SCA_ANDController.cpp b/source/gameengine/GameLogic/SCA_ANDController.cpp
new file mode 100644
index 00000000000..3dc20490819
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_ANDController.cpp
@@ -0,0 +1,143 @@
+/**
+ * 'And' together all inputs
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "SCA_ANDController.h"
+#include "SCA_ISensor.h"
+#include "SCA_LogicManager.h"
+#include "BoolValue.h"
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_ANDController::SCA_ANDController(SCA_IObject* gameobj,
+ PyTypeObject* T)
+ :
+ SCA_IController(gameobj,T)
+{
+}
+
+
+
+SCA_ANDController::~SCA_ANDController()
+{
+}
+
+
+
+void SCA_ANDController::Trigger(SCA_LogicManager* logicmgr)
+{
+
+ bool sensorresult = true;
+
+ for (vector<SCA_ISensor*>::const_iterator is=m_linkedsensors.begin();
+ !(is==m_linkedsensors.end());is++)
+ {
+ SCA_ISensor* sensor = *is;
+ if (!sensor->IsPositiveTrigger())
+ {
+ sensorresult = false;
+ break;
+ }
+ }
+
+ CValue* newevent = new CBoolValue(sensorresult);
+
+ for (vector<SCA_IActuator*>::const_iterator i=m_linkedactuators.begin();
+ !(i==m_linkedactuators.end());i++)
+ {
+ SCA_IActuator* actua = *i;//m_linkedactuators.at(i);
+ logicmgr->AddActiveActuator(actua,newevent);
+ }
+
+ // every actuator that needs the event, has a it's own reference to it now so
+ // release it (so to be clear: if there is no actuator, it's deleted right now)
+ newevent->Release();
+
+}
+
+
+
+CValue* SCA_ANDController::GetReplica()
+{
+ CValue* replica = new SCA_ANDController(*this);
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_ANDController::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_ANDController",
+ sizeof(SCA_ANDController),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_ANDController::Parents[] = {
+ &SCA_ANDController::Type,
+ &SCA_IController::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef SCA_ANDController::Methods[] = {
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* SCA_ANDController::_getattr(char* attr) {
+ _getattr_up(SCA_IController);
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_ANDController.h b/source/gameengine/GameLogic/SCA_ANDController.h
new file mode 100644
index 00000000000..a7d54004f90
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_ANDController.h
@@ -0,0 +1,58 @@
+/**
+ * SCA_ANDController.h
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_ANDCONTROLLER
+#define __KX_ANDCONTROLLER
+
+#include "SCA_IController.h"
+
+class SCA_ANDController : public SCA_IController
+{
+ Py_Header;
+ //virtual void Trigger(class SCA_LogicManager* logicmgr);
+public:
+ SCA_ANDController(SCA_IObject* gameobj,PyTypeObject* T=&Type);
+ virtual ~SCA_ANDController();
+ virtual CValue* GetReplica();
+ virtual void Trigger(SCA_LogicManager* logicmgr);
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(char *attr);
+
+};
+
+#endif //__KX_ANDCONTROLLER
diff --git a/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp b/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp
new file mode 100644
index 00000000000..0e2db162ec3
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp
@@ -0,0 +1,67 @@
+/**
+ * Manager for 'always' events. Since always sensors can operate in pulse
+ * mode, they need to be activated.
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "SCA_AlwaysEventManager.h"
+#include "SCA_LogicManager.h"
+#include <vector>
+#include "SCA_ISensor.h"
+
+using namespace std;
+
+
+
+SCA_AlwaysEventManager::SCA_AlwaysEventManager(class SCA_LogicManager* logicmgr)
+ : m_logicmgr(logicmgr),
+ SCA_EventManager(ALWAYS_EVENTMGR)
+{
+}
+
+
+
+void SCA_AlwaysEventManager::NextFrame(double curtime,double deltatime)
+{
+ for (vector<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++)
+ {
+ SCA_ISensor* sensor = *i;
+ sensor->Activate(m_logicmgr, NULL);
+ }
+}
+
+
+
+void SCA_AlwaysEventManager::RegisterSensor(SCA_ISensor* sensor)
+{
+ m_sensors.push_back(sensor);
+}
diff --git a/source/gameengine/GameLogic/SCA_AlwaysEventManager.h b/source/gameengine/GameLogic/SCA_AlwaysEventManager.h
new file mode 100644
index 00000000000..0fbf02c5212
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_AlwaysEventManager.h
@@ -0,0 +1,48 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef __KX_ALWAYSEVENTMGR
+#define __KX_ALWAYSEVENTMGR
+#include "SCA_EventManager.h"
+#include <vector>
+using namespace std;
+class SCA_AlwaysEventManager : public SCA_EventManager
+{
+
+ class SCA_LogicManager* m_logicmgr;
+public:
+ SCA_AlwaysEventManager(class SCA_LogicManager* logicmgr);
+ virtual void NextFrame(double curtime,double deltatime);
+ virtual void RegisterSensor(SCA_ISensor* sensor);
+
+
+};
+#endif //__KX_ALWAYSEVENTMGR
diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp
new file mode 100644
index 00000000000..cf78d109e16
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp
@@ -0,0 +1,138 @@
+/**
+ * Always trigger
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifdef WIN32
+// This warning tells us about truncation of __long__ stl-generated names.
+// It can occasionally cause DevStudio to have internal compiler warnings.
+#pragma warning( disable : 4786 )
+#endif
+
+#include "SCA_AlwaysSensor.h"
+#include "SCA_LogicManager.h"
+#include "SCA_EventManager.h"
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_AlwaysSensor::SCA_AlwaysSensor(class SCA_EventManager* eventmgr,
+ SCA_IObject* gameobj,
+ PyTypeObject* T)
+ : SCA_ISensor(gameobj,eventmgr, T)
+{
+ //SetDrawColor(255,0,0);
+ m_alwaysresult = true;
+}
+
+
+
+SCA_AlwaysSensor::~SCA_AlwaysSensor()
+{
+ /* intentionally empty */
+}
+
+
+
+CValue* SCA_AlwaysSensor::GetReplica()
+{
+ CValue* replica = new SCA_AlwaysSensor(*this);//m_float,GetName());
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+bool SCA_AlwaysSensor::IsPositiveTrigger()
+{
+ return (m_invert ? false : true);
+}
+
+
+
+bool SCA_AlwaysSensor::Evaluate(CValue* event)
+{
+ /* Nice! :) */
+ //return true;
+ /* even nicer ;) */
+ //return false;
+
+ /* nicest ! */
+ bool result = m_alwaysresult;
+ m_alwaysresult = false;
+ return result;
+}
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_AlwaysSensor::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_AlwaysSensor",
+ sizeof(SCA_AlwaysSensor),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_AlwaysSensor::Parents[] = {
+ &SCA_AlwaysSensor::Type,
+ &SCA_ISensor::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef SCA_AlwaysSensor::Methods[] = {
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* SCA_AlwaysSensor::_getattr(char* attr) {
+ _getattr_up(SCA_ISensor);
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.h b/source/gameengine/GameLogic/SCA_AlwaysSensor.h
new file mode 100644
index 00000000000..c6ff571be8a
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.h
@@ -0,0 +1,62 @@
+/**
+ * SCA_AlwaysSensor.h
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_ALWAYSSENSOR
+#define __KX_ALWAYSSENSOR
+#include "SCA_ISensor.h"
+
+
+class SCA_AlwaysSensor : public SCA_ISensor
+{
+ Py_Header;
+ bool m_alwaysresult;
+public:
+ SCA_AlwaysSensor(class SCA_EventManager* eventmgr,
+ SCA_IObject* gameobj,
+ PyTypeObject* T =&Type);
+ virtual ~SCA_AlwaysSensor();
+ virtual CValue* GetReplica();
+ virtual bool Evaluate(CValue* event);
+ virtual bool IsPositiveTrigger();
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(char *attr);
+
+
+};
+
+#endif //__KX_ALWAYSSENSOR
diff --git a/source/gameengine/GameLogic/SCA_EventManager.cpp b/source/gameengine/GameLogic/SCA_EventManager.cpp
new file mode 100644
index 00000000000..a6ce3a1af25
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_EventManager.cpp
@@ -0,0 +1,71 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+
+#include "SCA_EventManager.h"
+
+
+
+SCA_EventManager::SCA_EventManager(EVENT_MANAGER_TYPE mgrtype)
+ :m_mgrtype(mgrtype)
+{
+}
+
+
+
+SCA_EventManager::~SCA_EventManager()
+{
+}
+
+
+
+void SCA_EventManager::RemoveSensor(class SCA_ISensor* sensor)
+{
+ std::vector<SCA_ISensor*>::iterator i =
+ std::find(m_sensors.begin(), m_sensors.end(), sensor);
+ if (!(i == m_sensors.end()))
+ {
+ std::swap(*i, m_sensors.back());
+ m_sensors.pop_back();
+ }
+}
+
+
+void SCA_EventManager::EndFrame()
+{
+}
+
+
+
+int SCA_EventManager::GetType()
+{
+ return (int) m_mgrtype;
+}
diff --git a/source/gameengine/GameLogic/SCA_EventManager.h b/source/gameengine/GameLogic/SCA_EventManager.h
new file mode 100644
index 00000000000..30928af5354
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_EventManager.h
@@ -0,0 +1,69 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef __KX_EVENTMANAGER
+#define __KX_EVENTMANAGER
+
+#include <vector>
+#include <algorithm>
+
+class SCA_EventManager
+{
+protected:
+ std::vector <class SCA_ISensor*> m_sensors;
+
+public:
+ enum EVENT_MANAGER_TYPE {
+ KEYBOARD_EVENTMGR = 0,
+ MOUSE_EVENTMGR,
+ ALWAYS_EVENTMGR,
+ TOUCH_EVENTMGR,
+ PROPERTY_EVENTMGR,
+ TIME_EVENTMGR,
+ RANDOM_EVENTMGR,
+ RAY_EVENTMGR,
+ RADAR_EVENTMGR,
+ NETWORK_EVENTMGR
+ };
+
+ SCA_EventManager(EVENT_MANAGER_TYPE mgrtype);
+ virtual ~SCA_EventManager();
+
+ virtual void RemoveSensor(class SCA_ISensor* sensor);
+ virtual void NextFrame(double curtime,double deltatime)=0;
+ virtual void EndFrame();
+ virtual void RegisterSensor(class SCA_ISensor* sensor)=0;
+ int GetType();
+
+protected:
+ EVENT_MANAGER_TYPE m_mgrtype;
+};
+#endif
diff --git a/source/gameengine/GameLogic/SCA_ExpressionController.cpp b/source/gameengine/GameLogic/SCA_ExpressionController.cpp
new file mode 100644
index 00000000000..56934a695f2
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_ExpressionController.cpp
@@ -0,0 +1,161 @@
+/**
+ * 'Expression Controller enables to calculate an expression that wires inputs to output
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+
+#include "SCA_ExpressionController.h"
+#include "SCA_ISensor.h"
+#include "SCA_LogicManager.h"
+#include "BoolValue.h"
+#include "InputParser.h"
+
+#include "MT_Transform.h" // for fuzzyZero
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_ExpressionController::SCA_ExpressionController(SCA_IObject* gameobj,
+ const STR_String& exprtext,
+ PyTypeObject* T)
+ :SCA_IController(gameobj,T),
+ m_exprText(exprtext)
+{
+}
+
+
+
+SCA_ExpressionController::~SCA_ExpressionController()
+{
+}
+
+
+
+CValue* SCA_ExpressionController::GetReplica()
+{
+ SCA_ExpressionController* replica = new SCA_ExpressionController(*this);
+ replica->m_exprText = m_exprText;
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+void SCA_ExpressionController::Trigger(SCA_LogicManager* logicmgr)
+{
+
+ bool expressionresult = false;
+
+ CParser parser;
+ parser.SetContext(this->AddRef());
+ CExpression* expr = parser.ProcessText(m_exprText);
+ if (expr)
+ {
+ CValue* value = expr->Calculate();
+ if (value)
+ {
+ if (value->IsError())
+ {
+ printf(value->GetText());
+ } else
+ {
+ float num = value->GetNumber();
+ expressionresult = !MT_fuzzyZero(num);
+ }
+ value->Release();
+
+ }
+ expr->Release();
+ }
+
+ /*
+
+ for (vector<SCA_ISensor*>::const_iterator is=m_linkedsensors.begin();
+ !(is==m_linkedsensors.end());is++)
+ {
+ SCA_ISensor* sensor = *is;
+ if (!sensor->IsPositiveTrigger())
+ {
+ sensorresult = false;
+ break;
+ }
+ }
+
+ */
+
+ CValue* newevent = new CBoolValue(expressionresult);
+
+ for (vector<SCA_IActuator*>::const_iterator i=m_linkedactuators.begin();
+ !(i==m_linkedactuators.end());i++)
+ {
+ SCA_IActuator* actua = *i;
+ logicmgr->AddActiveActuator(actua,newevent);
+ }
+ //printf("expr %d.",expressionresult);
+ // every actuator that needs the event, has a it's own reference to it now so
+ // release it (so to be clear: if there is no actuator, it's deleted right now)
+ newevent->Release();
+}
+
+
+
+CValue* SCA_ExpressionController::FindIdentifier(const STR_String& identifiername)
+{
+
+ CValue* identifierval = NULL;
+
+ for (vector<SCA_ISensor*>::const_iterator is=m_linkedsensors.begin();
+ !(is==m_linkedsensors.end());is++)
+ {
+ SCA_ISensor* sensor = *is;
+ if (sensor->GetName() == identifiername)
+ {
+ identifierval = new CBoolValue(sensor->IsPositiveTrigger());
+ //identifierval = sensor->AddRef();
+ }
+
+ //if (!sensor->IsPositiveTrigger())
+ //{
+ // sensorresult = false;
+ // break;
+ //}
+ }
+
+ if (identifierval)
+ return identifierval;
+
+ return GetParent()->FindIdentifier(identifiername);
+
+}
diff --git a/source/gameengine/GameLogic/SCA_ExpressionController.h b/source/gameengine/GameLogic/SCA_ExpressionController.h
new file mode 100644
index 00000000000..59f8b7a3e04
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_ExpressionController.h
@@ -0,0 +1,64 @@
+/**
+ * KX_EXPRESSIONController.h
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_EXPRESSIONCONTROLLER
+#define __KX_EXPRESSIONCONTROLLER
+
+#include "SCA_IController.h"
+
+
+class SCA_ExpressionController : public SCA_IController
+{
+// Py_Header;
+ STR_String m_exprText;
+
+public:
+ SCA_ExpressionController(SCA_IObject* gameobj,
+ const STR_String& exprtext,
+ PyTypeObject* T=&Type );
+
+ virtual ~SCA_ExpressionController();
+ virtual CValue* GetReplica();
+ virtual void Trigger(SCA_LogicManager* logicmgr);
+ virtual CValue* FindIdentifier(const STR_String& identifiername);
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+// virtual PyObject* _getattr(char *attr);
+
+};
+
+#endif //__KX_EXPRESSIONCONTROLLER
diff --git a/source/gameengine/GameLogic/SCA_IActuator.cpp b/source/gameengine/GameLogic/SCA_IActuator.cpp
new file mode 100644
index 00000000000..81efeb6e647
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_IActuator.cpp
@@ -0,0 +1,104 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "SCA_IActuator.h"
+
+
+using namespace std;
+
+SCA_IActuator::SCA_IActuator(SCA_IObject* gameobj,
+ PyTypeObject* T) :
+ SCA_ILogicBrick(gameobj,T)
+{
+ // nothing to do
+}
+
+
+
+void SCA_IActuator::AddEvent(CValue* event)
+{
+ m_events.push_back(event);
+}
+
+
+
+void SCA_IActuator::RemoveAllEvents()
+{ // remove event queue!
+ for (vector<CValue*>::iterator i=m_events.begin(); !(i==m_events.end());i++)
+ {
+ (*i)->Release();
+ }
+ m_events.clear();
+}
+
+
+
+bool SCA_IActuator::Update(double curtime,double deltatime)
+{
+ return true;
+}
+
+
+
+bool SCA_IActuator::IsNegativeEvent() const
+{
+ bool bPositiveEvent(false);
+ bool bNegativeEvent(false);
+
+ for (vector<CValue*>::const_iterator i=m_events.begin(); i!=m_events.end();++i)
+ {
+ if ((*i)->GetNumber() == 0.0f)
+ {
+ bNegativeEvent = true;
+ } else {
+ bPositiveEvent = true;
+ }
+ }
+
+ // if at least 1 positive event, return false
+
+ return !bPositiveEvent && bNegativeEvent;
+}
+
+
+
+void SCA_IActuator::ProcessReplica()
+{
+ m_events.clear();
+}
+
+
+
+SCA_IActuator::~SCA_IActuator()
+{
+ RemoveAllEvents();
+}
+
diff --git a/source/gameengine/GameLogic/SCA_IActuator.h b/source/gameengine/GameLogic/SCA_IActuator.h
new file mode 100644
index 00000000000..67dd374b216
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_IActuator.h
@@ -0,0 +1,81 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef __KX_IACTUATOR
+#define __KX_IACTUATOR
+
+#include "SCA_ILogicBrick.h"
+#include <vector>
+
+class SCA_IActuator : public SCA_ILogicBrick
+{
+protected:
+ std::vector<CValue*> m_events;
+ void RemoveAllEvents();
+
+public:
+ /**
+ * This class also inherits the default copy constructors
+ */
+
+ SCA_IActuator(SCA_IObject* gameobj,
+ PyTypeObject* T =&Type);
+
+ /**
+ * Update(...)
+ * Update the actuator based upon the events received since
+ * the last call to Update, the current time and deltatime the
+ * time elapsed in this frame ?
+ * It is the responsibility of concrete Actuators to clear
+ * their event's. This is usually done in the Update() method via
+ * a call to RemoveAllEvents()
+ */
+
+
+ virtual bool Update(double curtime,
+ double deltatime);
+
+ /**
+ * Add an event to an actuator.
+ */
+ void AddEvent(CValue* event);
+ virtual void ProcessReplica();
+
+ /**
+ * Return true iff all the current events
+ * are negative. The definition of negative event is
+ * not immediately clear. But usually refers to key-up events
+ * or events where no action is required.
+ */
+ bool IsNegativeEvent() const;
+ virtual ~SCA_IActuator();
+};
+#endif //__KX_IACTUATOR
diff --git a/source/gameengine/GameLogic/SCA_IController.cpp b/source/gameengine/GameLogic/SCA_IController.cpp
new file mode 100644
index 00000000000..78f1980afde
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_IController.cpp
@@ -0,0 +1,120 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "SCA_IController.h"
+
+#include "SCA_LogicManager.h"
+#include "SCA_IActuator.h"
+
+SCA_IController::SCA_IController(SCA_IObject* gameobj,
+ PyTypeObject* T)
+ :
+ SCA_ILogicBrick(gameobj,T)
+{
+}
+
+
+
+SCA_IController::~SCA_IController()
+{
+}
+
+
+
+const std::vector<class SCA_ISensor*>& SCA_IController::GetLinkedSensors()
+{
+ return m_linkedsensors;
+}
+
+
+
+const std::vector<class SCA_IActuator*>& SCA_IController::GetLinkedActuators()
+{
+ return m_linkedactuators;
+}
+
+
+
+void SCA_IController::UnlinkAllSensors()
+{
+ m_linkedsensors.clear();
+}
+
+
+
+void SCA_IController::UnlinkAllActuators()
+{
+ m_linkedactuators.clear();
+}
+
+
+
+/*
+void SCA_IController::Trigger(SCA_LogicManager* logicmgr)
+{
+ //for (int i=0;i<m_linkedactuators.size();i++)
+ for (vector<SCA_IActuator*>::const_iterator i=m_linkedactuators.begin();
+ !(i==m_linkedactuators.end());i++)
+ {
+ SCA_IActuator* actua = *i;//m_linkedactuators.at(i);
+
+ logicmgr->AddActiveActuator(actua);
+ }
+
+}
+*/
+
+void SCA_IController::LinkToActuator(SCA_IActuator* actua)
+{
+ m_linkedactuators.push_back(actua);
+}
+
+void SCA_IController::UnlinkActuator(class SCA_IActuator* actua)
+{
+ std::vector<class SCA_IActuator*>::iterator actit;
+ std::vector<class SCA_IActuator*>::iterator actfound = m_linkedactuators.end();
+ for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit)
+ {
+ if ((*actit) == actua)
+ actfound = actit;
+
+ }
+ if (!(actfound==m_linkedactuators.end()))
+ {
+ m_linkedactuators.erase(actfound);
+ }
+
+}
+
+void SCA_IController::LinkToSensor(SCA_ISensor* sensor)
+{
+ m_linkedsensors.push_back(sensor);
+}
diff --git a/source/gameengine/GameLogic/SCA_IController.h b/source/gameengine/GameLogic/SCA_IController.h
new file mode 100644
index 00000000000..4f30e5ad71d
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_IController.h
@@ -0,0 +1,56 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef __KX_ICONTROLLER
+#define __KX_ICONTROLLER
+
+#include "SCA_ILogicBrick.h"
+
+class SCA_IController : public SCA_ILogicBrick
+{
+protected:
+ std::vector<class SCA_ISensor*> m_linkedsensors;
+ std::vector<class SCA_IActuator*> m_linkedactuators;
+public:
+ SCA_IController(SCA_IObject* gameobj,PyTypeObject* T);
+ virtual ~SCA_IController();
+ virtual void Trigger(class SCA_LogicManager* logicmgr)=0;
+ void LinkToSensor(SCA_ISensor* sensor);
+ void LinkToActuator(SCA_IActuator*);
+ const std::vector<class SCA_ISensor*>& GetLinkedSensors();
+ const std::vector<class SCA_IActuator*>& GetLinkedActuators();
+ void UnlinkAllSensors();
+ void UnlinkAllActuators();
+ void UnlinkActuator(class SCA_IActuator* actua);
+
+
+};
+#endif
diff --git a/source/gameengine/GameLogic/SCA_IInputDevice.cpp b/source/gameengine/GameLogic/SCA_IInputDevice.cpp
new file mode 100644
index 00000000000..75a78fe5871
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_IInputDevice.cpp
@@ -0,0 +1,138 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <iostream.h>
+
+#include "SCA_IInputDevice.h"
+
+
+
+SCA_IInputDevice::SCA_IInputDevice()
+ :
+ m_currentTable(0)
+{
+ ClearStatusTable(0);
+ ClearStatusTable(1);
+}
+
+
+
+SCA_IInputDevice::~SCA_IInputDevice()
+{
+}
+
+
+
+void SCA_IInputDevice::ClearStatusTable(int tableid)
+{
+ for (int i=0;i<SCA_IInputDevice::KX_MAX_KEYS;i++)
+ m_eventStatusTables[tableid][i]=SCA_InputEvent(SCA_InputEvent::KX_NO_INPUTSTATUS,0);
+}
+
+
+
+const SCA_InputEvent& SCA_IInputDevice::GetEventValue(SCA_IInputDevice::KX_EnumInputs inputcode)
+{
+ // cerr << "SCA_IInputDevice::GetEventValue" << endl;
+ return m_eventStatusTables[m_currentTable][inputcode];
+}
+
+
+
+int SCA_IInputDevice::GetNumActiveEvents()
+{
+ int num = 0;
+
+ // cerr << "SCA_IInputDevice::GetNumActiveEvents" << endl;
+
+ for (int i=0;i<SCA_IInputDevice::KX_MAX_KEYS;i++)
+ {
+ const SCA_InputEvent& event = m_eventStatusTables[m_currentTable][i];
+ if ((event.m_status == SCA_InputEvent::KX_JUSTACTIVATED)
+ || (event.m_status == SCA_InputEvent::KX_ACTIVE))
+ num++;
+ }
+
+ return num;
+}
+
+
+
+int SCA_IInputDevice::GetNumJustEvents()
+{
+ int num = 0;
+
+ // cerr << "SCA_IInputDevice::GetNumJustEvents" << endl;
+
+ for (int i=0;i<SCA_IInputDevice::KX_MAX_KEYS;i++)
+ {
+ const SCA_InputEvent& event = m_eventStatusTables[m_currentTable][i];
+ if ((event.m_status == SCA_InputEvent::KX_JUSTACTIVATED)
+ || (event.m_status == SCA_InputEvent::KX_JUSTRELEASED))
+ num++;
+ }
+
+ return num;
+}
+
+
+
+void SCA_IInputDevice::NextFrame()
+{
+ m_currentTable = 1 - m_currentTable;
+
+ // cerr << "SCA_IInputDevice::NextFrame " << GetNumActiveEvents() << endl;
+
+ for (int i=0;i<SCA_IInputDevice::KX_MAX_KEYS;i++)
+ {
+ switch (m_eventStatusTables[1 - m_currentTable][i].m_status)
+ {
+ case SCA_InputEvent::KX_NO_INPUTSTATUS:
+ m_eventStatusTables[m_currentTable][i]
+ = SCA_InputEvent(SCA_InputEvent::KX_NO_INPUTSTATUS, 1);
+ break;
+ case SCA_InputEvent::KX_JUSTACTIVATED:
+ m_eventStatusTables[m_currentTable][i]
+ = SCA_InputEvent(SCA_InputEvent::KX_ACTIVE, 1);
+ break;
+ case SCA_InputEvent::KX_ACTIVE:
+ m_eventStatusTables[m_currentTable][i]
+ = SCA_InputEvent(SCA_InputEvent::KX_ACTIVE, 1);
+ break;
+ case SCA_InputEvent::KX_JUSTRELEASED:
+ m_eventStatusTables[m_currentTable][i]
+ = SCA_InputEvent(SCA_InputEvent::KX_NO_INPUTSTATUS, 1);
+ break;
+ default:
+ ; /* error */
+ }
+ }
+}
diff --git a/source/gameengine/GameLogic/SCA_IInputDevice.h b/source/gameengine/GameLogic/SCA_IInputDevice.h
new file mode 100644
index 00000000000..861b4bffb5e
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_IInputDevice.h
@@ -0,0 +1,307 @@
+/**
+ * Interface for input devices. The defines for keyboard/system/mouse events
+ * here are for internal use in the KX module.
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef KX_INPUTDEVICE_H
+#define KX_INPUTDEVICE_H
+
+
+class SCA_InputEvent
+{
+
+public:
+ enum SCA_EnumInputs {
+
+ KX_NO_INPUTSTATUS = 0,
+ KX_JUSTACTIVATED,
+ KX_ACTIVE,
+ KX_JUSTRELEASED,
+ KX_MAX_INPUTSTATUS
+ };
+
+ SCA_InputEvent(SCA_EnumInputs status=KX_NO_INPUTSTATUS,int eventval=0)
+ : m_status(status),
+ m_eventval(eventval)
+ {
+
+ }
+
+ SCA_EnumInputs m_status;
+ int m_eventval;
+};
+
+class SCA_IInputDevice
+{
+
+
+public:
+
+ SCA_IInputDevice();
+ virtual ~SCA_IInputDevice();
+
+ enum KX_EnumInputs {
+
+ KX_NOKEY = 0,
+
+ // TIMERS
+
+ KX_TIMER0,
+ KX_TIMER1,
+ KX_TIMER2,
+ KX_TIMER3,
+
+ // SYSTEM
+
+ /* Moved to avoid clashes with KX_RETKEY */
+ KX_KEYBD,
+ KX_RAWKEYBD,
+ KX_REDRAW,
+ KX_INPUTCHANGE,
+ KX_QFULL,
+ KX_WINFREEZE,
+ KX_WINTHAW,
+ /* thaw is 11 */
+
+ /* move past retkey*/
+ KX_WINCLOSE = 14,
+ KX_WINQUIT,
+ KX_Q_FIRSTTIME,
+ /* sequence ends on 16 */
+
+ // standard keyboard
+
+ /* Because of the above preamble, KX_BEGINKEY is 15 ! This
+ * means that KX_RETKEY on 13d (0Dh)) will double up with
+ * KX_WINQUIT! Why is it 13? Because ascii 13d is Ctrl-M aka
+ * CR! Its little brother, LF has 10d (0Ah). This is
+ * dangerous, since the keyboards start scanning at
+ * KX_BEGINKEY. I think the keyboard system should push its
+ * key events instead of demanding the user to poll the
+ * table... But that's for another time... The fix for now is
+ * to move the above system events into a 'safe' (ie. unused)
+ * range. I am loathe to move it away from this 'magical'
+ * coincidence.. it's probably exploited somewhere. I hope the
+ * close and quit events don't mess up 'normal' kb code
+ * scanning.
+ * */
+ KX_BEGINKEY = 12,
+
+ KX_RETKEY = 13,
+ KX_SPACEKEY = 32,
+ KX_PADASTERKEY = 42,
+ KX_COMMAKEY = 44,
+ KX_MINUSKEY = 45,
+ KX_PERIODKEY = 46,
+ KX_ZEROKEY = 48,
+
+ KX_ONEKEY, // =49
+ KX_TWOKEY,
+ KX_THREEKEY,
+ KX_FOURKEY,
+ KX_FIVEKEY,
+ KX_SIXKEY,
+ KX_SEVENKEY,
+ KX_EIGHTKEY,
+ KX_NINEKEY, // = 57
+
+ KX_AKEY = 97,
+ KX_BKEY,
+ KX_CKEY,
+ KX_DKEY,
+ KX_EKEY,
+ KX_FKEY,
+ KX_GKEY,
+ KX_HKEY,
+ KX_IKEY,
+ KX_JKEY,
+ KX_KKEY,
+ KX_LKEY,
+ KX_MKEY,
+ KX_NKEY, // =110
+ KX_OKEY,
+ KX_PKEY,
+ KX_QKEY,
+ KX_RKEY,
+ KX_SKEY,
+ KX_TKEY,
+ KX_UKEY,
+ KX_VKEY,
+ KX_WKEY,
+ KX_XKEY, // =120
+ KX_YKEY,
+ KX_ZKEY, // =122
+
+
+
+ KX_CAPSLOCKKEY, // 123
+
+ KX_LEFTCTRLKEY, // 124
+ KX_LEFTALTKEY,
+ KX_RIGHTALTKEY,
+ KX_RIGHTCTRLKEY,
+ KX_RIGHTSHIFTKEY,
+ KX_LEFTSHIFTKEY,// 129
+
+ KX_ESCKEY, // 130
+ KX_TABKEY, //131
+
+
+ KX_LINEFEEDKEY, // 132
+ KX_BACKSPACEKEY,
+ KX_DELKEY,
+ KX_SEMICOLONKEY, // 135
+
+
+ KX_QUOTEKEY, //136
+ KX_ACCENTGRAVEKEY, //137
+
+ KX_SLASHKEY, //138
+ KX_BACKSLASHKEY,
+ KX_EQUALKEY,
+ KX_LEFTBRACKETKEY,
+ KX_RIGHTBRACKETKEY, // 142
+
+ KX_LEFTARROWKEY, // 145
+ KX_DOWNARROWKEY,
+ KX_RIGHTARROWKEY,
+ KX_UPARROWKEY, // 148
+
+ KX_PAD2 ,
+ KX_PAD4 ,
+ KX_PAD6 ,
+ KX_PAD8 ,
+
+ KX_PAD1 ,
+ KX_PAD3 ,
+ KX_PAD5 ,
+ KX_PAD7 ,
+ KX_PAD9 ,
+
+ KX_PADPERIOD,
+ KX_PADSLASHKEY,
+
+
+
+ KX_PAD0 ,
+ KX_PADMINUS,
+ KX_PADENTER,
+ KX_PADPLUSKEY,
+
+
+ KX_F1KEY ,
+ KX_F2KEY ,
+ KX_F3KEY ,
+ KX_F4KEY ,
+ KX_F5KEY ,
+ KX_F6KEY ,
+ KX_F7KEY ,
+ KX_F8KEY ,
+ KX_F9KEY ,
+ KX_F10KEY,
+ KX_F11KEY,
+ KX_F12KEY,
+
+ KX_PAUSEKEY,
+ KX_INSERTKEY,
+ KX_HOMEKEY ,
+ KX_PAGEUPKEY,
+ KX_PAGEDOWNKEY,
+ KX_ENDKEY,
+
+ // MOUSE
+ KX_BEGINMOUSE,
+
+ KX_BEGINMOUSEBUTTONS,
+
+ KX_LEFTMOUSE,
+ KX_MIDDLEMOUSE,
+ KX_RIGHTMOUSE,
+
+ KX_ENDMOUSEBUTTONS,
+
+ KX_MOUSEX,
+ KX_MOUSEY,
+
+ KX_ENDMOUSE,
+
+
+
+ KX_MAX_KEYS
+
+ } ; // enum
+
+
+protected:
+ /**
+ m_eventStatusTables are two tables that contain current and previous
+ status of all events
+ */
+
+ SCA_InputEvent m_eventStatusTables[2][SCA_IInputDevice::KX_MAX_KEYS];
+ /**
+ m_currentTable is index for m_keyStatusTable that toggle between 0 or 1
+ */
+ int m_currentTable;
+ void ClearStatusTable(int tableid);
+
+public:
+ virtual bool IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)=0;
+ virtual const SCA_InputEvent& GetEventValue(SCA_IInputDevice::KX_EnumInputs inputcode);
+
+ /**
+ * Count active events(active and just_activated)
+ */
+ virtual int GetNumActiveEvents();
+
+ /**
+ * Get the number of ramping events (just_activated, just_released)
+ */
+ virtual int GetNumJustEvents();
+
+ /* Next frame: we calculate the new key states. This goes as follows:
+ *
+ * KX_NO_INPUTSTATUS -> KX_NO_INPUTSTATUS
+ * KX_JUSTACTIVATED -> KX_ACTIVE
+ * KX_ACTIVE -> KX_ACTIVE
+ * KX_JUSTRELEASED -> KX_NO_INPUTSTATUS
+ *
+ * Getting new events provides the
+ * KX_NO_INPUTSTATUS->KX_JUSTACTIVATED and
+ * KX_ACTIVE->KX_JUSTRELEASED transitions.
+ */
+ virtual void NextFrame();
+
+};
+
+#endif //KX_INPUTDEVICE_H
diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp
new file mode 100644
index 00000000000..ce90a17fe0d
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp
@@ -0,0 +1,325 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "SCA_ILogicBrick.h"
+
+
+
+SCA_LogicManager* SCA_ILogicBrick::m_sCurrentLogicManager = NULL;
+
+SCA_ILogicBrick::SCA_ILogicBrick(SCA_IObject* gameobj,
+ PyTypeObject* T)
+ :
+ CValue(T),
+ m_gameobj(gameobj),
+ m_Execute_Priority(0),
+ m_Execute_Ueber_Priority(0),
+ m_bActive(false),
+ m_eventval(0)
+{
+ m_text = "KX_LogicBrick";
+}
+
+
+
+SCA_ILogicBrick::~SCA_ILogicBrick()
+{
+ RemoveEvent();
+}
+
+
+
+void SCA_ILogicBrick::SetExecutePriority(int execute_Priority)
+{
+ m_Execute_Priority = execute_Priority;
+}
+
+
+
+void SCA_ILogicBrick::SetUeberExecutePriority(int execute_Priority)
+{
+ m_Execute_Ueber_Priority = execute_Priority;
+}
+
+
+
+SCA_IObject* SCA_ILogicBrick::GetParent()
+{
+ return m_gameobj;
+}
+
+
+
+void SCA_ILogicBrick::ReParent(SCA_IObject* parent)
+{
+ m_gameobj = parent;
+}
+
+
+
+CValue* SCA_ILogicBrick::Calc(VALUE_OPERATOR op, CValue *val)
+{
+ CValue* temp = new CBoolValue(false,"");
+ CValue* result = temp->Calc(op,val);
+ temp->Release();
+
+ return result;
+}
+
+
+
+CValue* SCA_ILogicBrick::CalcFinal(VALUE_DATA_TYPE dtype,
+ VALUE_OPERATOR op,
+ CValue *val)
+{
+ // same as bool implementation, so...
+ CValue* temp = new CBoolValue(false,"");
+ CValue* result = temp->CalcFinal(dtype,op,val);
+ temp->Release();
+
+ return result;
+}
+
+
+
+const STR_String& SCA_ILogicBrick::GetText()
+{
+ if (m_name.Length())
+ return m_name;
+
+ return m_text;
+}
+
+
+
+float SCA_ILogicBrick::GetNumber()
+{
+ return -1;
+}
+
+
+
+STR_String SCA_ILogicBrick::GetName()
+{
+ return m_name;
+}
+
+
+
+void SCA_ILogicBrick::SetName(STR_String name)
+{
+ m_name = name;
+}
+
+
+
+void SCA_ILogicBrick::ReplicaSetName(STR_String name)
+{
+ m_name = name;
+}
+
+
+
+bool SCA_ILogicBrick::IsActive()
+{
+ return m_bActive;
+}
+
+
+
+bool SCA_ILogicBrick::LessComparedTo(SCA_ILogicBrick* other)
+{
+ return (this->m_Execute_Ueber_Priority < other->m_Execute_Ueber_Priority)
+ || ((this->m_Execute_Ueber_Priority == other->m_Execute_Ueber_Priority) &&
+ (this->m_Execute_Priority < other->m_Execute_Priority));
+}
+
+
+
+void SCA_ILogicBrick::SetActive(bool active)
+{
+ m_bActive=active;
+ if (active)
+ {
+ //m_gameobj->SetDebugColor(GetDrawColor());
+ } else
+ {
+ //m_gameobj->ResetDebugColor();
+ }
+}
+
+
+
+void SCA_ILogicBrick::RegisterEvent(CValue* eventval)
+{
+ if (m_eventval)
+ m_eventval->Release();
+
+ m_eventval = eventval->AddRef();
+}
+
+
+void SCA_ILogicBrick::RemoveEvent()
+{
+ if (m_eventval)
+ {
+ m_eventval->Release();
+ m_eventval = NULL;
+ }
+}
+
+
+
+CValue* SCA_ILogicBrick::GetEvent()
+{
+ if (m_eventval)
+ {
+ return m_eventval->AddRef();
+ }
+
+ return NULL;
+}
+
+
+
+
+/* python stuff */
+
+PyTypeObject SCA_ILogicBrick::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_ILogicBrick",
+ sizeof(SCA_ILogicBrick),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+
+
+PyParentObject SCA_ILogicBrick::Parents[] = {
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+
+
+PyMethodDef SCA_ILogicBrick::Methods[] = {
+ {"getOwner", (PyCFunction) SCA_ILogicBrick::sPyGetOwner, METH_VARARGS},
+ {"getExecutePriority", (PyCFunction) SCA_ILogicBrick::sPySetExecutePriority, METH_VARARGS},
+ {"setExecutePriority", (PyCFunction) SCA_ILogicBrick::sPySetExecutePriority, METH_VARARGS},
+ {NULL,NULL} //Sentinel
+};
+
+
+
+PyObject*
+SCA_ILogicBrick::_getattr(char* attr)
+{
+ _getattr_up(CValue);
+}
+
+
+
+PyObject* SCA_ILogicBrick::PyGetOwner(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ CValue* parent = GetParent();
+ if (parent)
+ {
+ parent->AddRef();
+ return parent;
+ }
+
+ printf("ERROR: Python scriptblock without owner\n");
+ Py_INCREF(Py_None);
+ return Py_None;//Int_FromLong(IsPositiveTrigger());
+}
+
+
+
+PyObject* SCA_ILogicBrick::PySetExecutePriority(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+
+ int priority=0;
+
+ if (!PyArg_ParseTuple(args, "i", &priority)) {
+ return NULL;
+ }
+
+ m_Execute_Ueber_Priority = priority;
+
+ Py_Return;
+}
+
+
+
+PyObject* SCA_ILogicBrick::PyGetExecutePriority(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ return PyInt_FromLong(m_Execute_Ueber_Priority);
+}
+
+
+
+/* Conversions for making life better. */
+bool SCA_ILogicBrick::PyArgToBool(int boolArg)
+{
+ if (boolArg == KX_TRUE) {
+ return true;
+ } else if (boolArg == KX_FALSE){
+ return false;
+ } else {
+ ; /* error: bad conversion: how to catch this? */
+ return false;
+ }
+}
+
+
+
+PyObject* SCA_ILogicBrick::BoolToPyArg(bool boolarg)
+{
+ return PyInt_FromLong(boolarg? KX_TRUE: KX_FALSE);
+}
diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.h b/source/gameengine/GameLogic/SCA_ILogicBrick.h
new file mode 100644
index 00000000000..9e293136e21
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_ILogicBrick.h
@@ -0,0 +1,111 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef __KX_ILOGICBRICK
+#define __KX_ILOGICBRICK
+
+#include "Value.h"
+#include "SCA_IObject.h"
+#include "BoolValue.h"
+class SCA_ILogicBrick : public CValue
+{
+ Py_Header;
+ SCA_IObject* m_gameobj;
+ int m_Execute_Priority;
+ int m_Execute_Ueber_Priority;
+
+ bool m_bActive;
+ CValue* m_eventval;
+ STR_String m_text;
+ STR_String m_name;
+ //unsigned long m_drawcolor;
+protected:
+ void RegisterEvent(CValue* eventval);
+ void RemoveEvent();
+ CValue* GetEvent();
+
+public:
+ SCA_ILogicBrick(SCA_IObject* gameobj,PyTypeObject* T );
+ virtual ~SCA_ILogicBrick();
+
+ void SetExecutePriority(int execute_Priority);
+ void SetUeberExecutePriority(int execute_Priority);
+
+ SCA_IObject* GetParent();
+ virtual void ReParent(SCA_IObject* parent);
+
+ // act as a BoolValue (with value IsPositiveTrigger)
+ virtual CValue* Calc(VALUE_OPERATOR op, CValue *val);
+ virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val);
+
+ virtual const STR_String & GetText();
+ virtual float GetNumber();
+ virtual STR_String GetName();
+ virtual void SetName(STR_String name);
+ virtual void ReplicaSetName(STR_String name);
+
+ bool IsActive();
+ void SetActive(bool active) ;
+
+ virtual bool LessComparedTo(SCA_ILogicBrick* other);
+
+ virtual PyObject* _getattr(char *attr);
+
+ static class SCA_LogicManager* m_sCurrentLogicManager;
+
+
+ // python methods
+
+ KX_PYMETHOD(SCA_ILogicBrick,GetOwner);
+ KX_PYMETHOD(SCA_ILogicBrick,SetExecutePriority);
+ KX_PYMETHOD(SCA_ILogicBrick,GetExecutePriority);
+
+ enum KX_BOOL_TYPE {
+ KX_BOOL_NODEF = 0,
+ KX_TRUE,
+ KX_FALSE,
+ KX_BOOL_MAX
+ };
+
+
+protected:
+ /* Some conversions to go with the bool type. */
+ /** Convert a KX_TRUE, KX_FALSE in Python to a c++ value. */
+ bool PyArgToBool(int boolArg);
+
+ /** Convert a a c++ value to KX_TRUE, KX_FALSE in Python. */
+ PyObject* BoolToPyArg(bool);
+
+
+};
+
+
+#endif
diff --git a/source/gameengine/GameLogic/SCA_IObject.cpp b/source/gameengine/GameLogic/SCA_IObject.cpp
new file mode 100644
index 00000000000..012479ba2d3
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_IObject.cpp
@@ -0,0 +1,363 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+
+#include "SCA_IObject.h"
+#include "SCA_ISensor.h"
+#include "SCA_IController.h"
+#include "SCA_IActuator.h"
+#include "MT_Point3.h"
+
+#include "ListValue.h"
+
+MT_Point3 SCA_IObject::m_sDummy=MT_Point3(0,0,0);
+
+SCA_IObject::SCA_IObject(PyTypeObject* T): CValue(T)
+{
+ m_suspended = false;
+}
+
+
+
+SCA_IObject::~SCA_IObject()
+{
+ SCA_SensorList::iterator its;
+ for (its = m_sensors.begin(); !(its == m_sensors.end()); ++its)
+ {
+ ((CValue*)(*its))->Release();
+ }
+ SCA_ControllerList::iterator itc;
+ for (itc = m_controllers.begin(); !(itc == m_controllers.end()); ++itc)
+ {
+ ((CValue*)(*itc))->Release();
+ }
+ SCA_ActuatorList::iterator ita;
+ for (ita = m_actuators.begin(); !(ita==m_actuators.end()); ++ita)
+ {
+ ((CValue*)(*ita))->Release();
+ }
+
+ //T_InterpolatorList::iterator i;
+ //for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) {
+ // delete *i;
+ //}
+}
+
+
+
+SCA_ControllerList& SCA_IObject::GetControllers()
+{
+ return m_controllers;
+}
+
+
+
+SCA_SensorList& SCA_IObject::GetSensors()
+{
+ return m_sensors;
+}
+
+
+
+SCA_ActuatorList& SCA_IObject::GetActuators()
+{
+ return m_actuators;
+}
+
+
+
+void SCA_IObject::AddSensor(SCA_ISensor* act)
+{
+ m_sensors.push_back(act);
+}
+
+
+
+void SCA_IObject::AddController(SCA_IController* act)
+{
+ m_controllers.push_back(act);
+}
+
+
+
+void SCA_IObject::AddActuator(SCA_IActuator* act)
+{
+ m_actuators.push_back(act);
+}
+
+
+
+void SCA_IObject::SetIgnoreActivityCulling(bool b)
+{
+ m_ignore_activity_culling = b;
+}
+
+
+
+bool SCA_IObject::GetIgnoreActivityCulling()
+{
+ return m_ignore_activity_culling;
+}
+
+
+
+void SCA_IObject::ReParentLogic()
+{
+ SCA_SensorList& oldsensors = GetSensors();
+
+ int sen = 0;
+ SCA_SensorList::iterator its;
+ for (its = oldsensors.begin(); !(its==oldsensors.end()); ++its)
+ {
+ SCA_ISensor* newsensor = (SCA_ISensor*)(*its)->GetReplica();
+ newsensor->ReParent(this);
+ oldsensors[sen++] = newsensor;
+ }
+
+ SCA_ControllerList& oldcontrollers = GetControllers();
+ int con = 0;
+ SCA_ControllerList::iterator itc;
+ for (itc = oldcontrollers.begin(); !(itc==oldcontrollers.end()); ++itc)
+ {
+ SCA_IController* newcontroller = (SCA_IController*)(*itc)->GetReplica();
+ newcontroller->ReParent(this);
+ oldcontrollers[con++]=newcontroller;
+
+ }
+ SCA_ActuatorList& oldactuators = GetActuators();
+
+ int act = 0;
+ SCA_ActuatorList::iterator ita;
+ for (ita = oldactuators.begin(); !(ita==oldactuators.end()); ++ita)
+ {
+ SCA_IActuator* newactuator = (SCA_IActuator*) (*ita)->GetReplica();
+ newactuator->ReParent(this);
+ newactuator->SetActive(false);
+ oldactuators[act++] = newactuator;
+ }
+
+}
+
+
+
+SCA_ISensor* SCA_IObject::FindSensor(const STR_String& sensorname)
+{
+ SCA_ISensor* foundsensor = NULL;
+
+ for (SCA_SensorList::iterator its = m_sensors.begin();!(its==m_sensors.end());its++)
+ {
+ if ((*its)->GetName() == sensorname)
+ {
+ foundsensor = (*its);
+ break;
+ }
+ }
+ return foundsensor;
+}
+
+
+
+SCA_IController* SCA_IObject::FindController(const STR_String& controllername)
+{
+ SCA_IController* foundcontroller = NULL;
+
+ for (SCA_ControllerList::iterator itc = m_controllers.begin();!(itc==m_controllers.end());itc++)
+ {
+ if ((*itc)->GetName() == controllername)
+ {
+ foundcontroller = (*itc);
+ break;
+ }
+ }
+ return foundcontroller;
+}
+
+
+
+SCA_IActuator* SCA_IObject::FindActuator(const STR_String& actuatorname)
+{
+ SCA_IActuator* foundactuator = NULL;
+
+ for (SCA_ActuatorList::iterator ita = m_actuators.begin();!(ita==m_actuators.end());ita++)
+ {
+ if ((*ita)->GetName() == actuatorname)
+ {
+ foundactuator = (*ita);
+ break;
+ }
+ }
+
+ return foundactuator;
+}
+
+
+
+void SCA_IObject::SetCurrentTime(float currentTime) {
+ //T_InterpolatorList::iterator i;
+ //for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) {
+ // (*i)->Execute(currentTime);
+ //}
+}
+
+
+
+const MT_Point3& SCA_IObject::ConvertPythonPylist(PyObject* pylist)
+{
+ bool error = false;
+ m_sDummy = MT_Vector3(0,0,0);
+ if (pylist->ob_type == &CListValue::Type)
+ {
+ CListValue* listval = (CListValue*) pylist;
+ int numelem = listval->GetCount();
+ if ( numelem <= 3)
+ {
+ int index;
+ for (index = 0;index<numelem;index++)
+ {
+ m_sDummy[index] = listval->GetValue(index)->GetNumber();
+ }
+ } else
+ {
+ error = true;
+ }
+
+ } else
+ {
+
+ // assert the list is long enough...
+ int numitems = PyList_Size(pylist);
+ if (numitems <= 3)
+ {
+ int index;
+ for (index=0;index<numitems;index++)
+ {
+ m_sDummy[index] = PyFloat_AsDouble(PyList_GetItem(pylist,index));
+ }
+ }
+ else
+ {
+ error = true;
+ }
+
+ }
+ return m_sDummy;
+}
+
+
+
+const MT_Point3& SCA_IObject::ConvertPythonVectorArg(PyObject* args)
+{
+
+ PyObject* pylist;
+ PyArg_ParseTuple(args,"O",&pylist);
+ m_sDummy = ConvertPythonPylist(pylist);
+ return m_sDummy;
+}
+
+
+
+void SCA_IObject::Suspend(void)
+{
+ if ((!m_ignore_activity_culling)
+ && (!m_suspended)) {
+ m_suspended = true;
+ /* flag suspend for all sensors */
+ SCA_SensorList::iterator i = m_sensors.begin();
+ while (i != m_sensors.end()) {
+ (*i)->Suspend();
+ i++;
+ }
+ }
+}
+
+
+
+void SCA_IObject::Resume(void)
+{
+ if (m_suspended) {
+ m_suspended = false;
+ /* unflag suspend for all sensors */
+ SCA_SensorList::iterator i = m_sensors.begin();
+ while (i != m_sensors.end()) {
+ (*i)->Resume();
+ i++;
+ }
+ }
+}
+
+
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_IObject::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_IObject",
+ sizeof(SCA_IObject),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+
+
+PyParentObject SCA_IObject::Parents[] = {
+ &SCA_IObject::Type,
+ &CValue::Type,
+ NULL
+};
+
+
+
+PyMethodDef SCA_IObject::Methods[] = {
+ //{"setOrientation", (PyCFunction) SCA_IObject::sPySetOrientation, METH_VARARGS},
+ //{"getOrientation", (PyCFunction) SCA_IObject::sPyGetOrientation, METH_VARARGS},
+ {NULL,NULL} //Sentinel
+};
+
+
+
+PyObject* SCA_IObject::_getattr(char* attr) {
+ _getattr_up(CValue);
+}
+
diff --git a/source/gameengine/GameLogic/SCA_IObject.h b/source/gameengine/GameLogic/SCA_IObject.h
new file mode 100644
index 00000000000..e3c06a92b9f
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_IObject.h
@@ -0,0 +1,126 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * An abstract object that has some logic, python scripting and
+ * reference counting Note: transformation stuff has been moved to
+ * SceneGraph
+ */
+
+#ifndef SCA_IOBJECT_H
+#define SCA_IOBJECT_H
+
+#include "Value.h"
+#include <vector>
+
+class SCA_ISensor;
+class SCA_IController;
+class SCA_IActuator;
+
+
+typedef std::vector<SCA_ISensor *> SCA_SensorList;
+typedef std::vector<SCA_IController *> SCA_ControllerList;
+typedef std::vector<SCA_IActuator *> SCA_ActuatorList;
+
+
+class SCA_IObject : public CValue
+{
+
+ Py_Header;
+
+protected:
+ SCA_SensorList m_sensors;
+ SCA_ControllerList m_controllers;
+ SCA_ActuatorList m_actuators;
+ static class MT_Point3 m_sDummy;
+
+ /**
+ * Ignore activity culling requests?
+ */
+ bool m_ignore_activity_culling;
+
+ /**
+ * Ignore updates?
+ */
+ bool m_suspended;
+
+public:
+
+ SCA_IObject(PyTypeObject* T=&Type);
+ virtual ~SCA_IObject();
+
+ SCA_ControllerList& GetControllers();
+ SCA_SensorList& GetSensors();
+ SCA_ActuatorList& GetActuators();
+
+ void AddSensor(SCA_ISensor* act);
+ void AddController(SCA_IController* act);
+ void AddActuator(SCA_IActuator* act);
+
+ SCA_ISensor* FindSensor(const STR_String& sensorname);
+ SCA_IActuator* FindActuator(const STR_String& actuatorname);
+ SCA_IController* FindController(const STR_String& controllername);
+
+ void SetCurrentTime(float currentTime);
+
+ void ReParentLogic();
+
+ /**
+ * Set whether or not to ignore activity culling requests
+ */
+ void SetIgnoreActivityCulling(bool b);
+
+ /**
+ * Set whether or not this object wants to ignore activity culling
+ * requests
+ */
+ bool GetIgnoreActivityCulling();
+
+ /**
+ * Suspend all progress.
+ */
+ void Suspend(void);
+
+ /**
+ * Resume progress
+ */
+ void Resume(void);
+
+ const class MT_Point3& ConvertPythonPylist(PyObject* pylist);
+ const class MT_Point3& ConvertPythonVectorArg(PyObject* args);
+
+ // here come the python forwarded methods
+ PyObject* _getattr(char* attr);
+
+};
+#endif //SCA_IOBJECT_H
+
+
+
+
diff --git a/source/gameengine/GameLogic/SCA_IScene.cpp b/source/gameengine/GameLogic/SCA_IScene.cpp
new file mode 100644
index 00000000000..e9ed8232824
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_IScene.cpp
@@ -0,0 +1,67 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "SCA_IScene.h"
+
+
+
+SCA_IScene::SCA_IScene()
+{
+}
+
+
+
+SCA_IScene::~SCA_IScene()
+{
+ // release debugprop list
+ for (std::vector<SCA_DebugProp*>::iterator it = m_debugList.begin();
+ !(it==m_debugList.end());it++)
+ {
+ delete (*it);
+ }
+}
+
+
+std::vector<SCA_DebugProp*>& SCA_IScene::GetDebugProperties()
+{
+ return m_debugList;
+}
+
+
+
+void SCA_IScene::AddDebugProperty(class CValue* debugprop,
+ const STR_String &name)
+{
+ SCA_DebugProp* dprop = new SCA_DebugProp();
+ dprop->m_obj = debugprop;
+ dprop->m_name = name;
+ m_debugList.push_back(dprop);
+}
diff --git a/source/gameengine/GameLogic/SCA_IScene.h b/source/gameengine/GameLogic/SCA_IScene.h
new file mode 100644
index 00000000000..a8893fe9c59
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_IScene.h
@@ -0,0 +1,62 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef __KX_ISCENE_H
+#define __KX_ISCENE_H
+
+#include <vector>
+
+#include "STR_String.h"
+
+struct SCA_DebugProp
+{
+ class CValue* m_obj;
+ STR_String m_name;
+};
+
+class SCA_IScene
+{
+ std::vector<SCA_DebugProp*> m_debugList;
+public:
+ SCA_IScene();
+ virtual ~SCA_IScene();
+ virtual class SCA_IObject* AddReplicaObject(class CValue* gameobj,
+ class CValue* locationobj,
+ int lifespan=0)=0;
+ virtual void RemoveObject(class CValue* gameobj)=0;
+ virtual void DelayedRemoveObject(class CValue* gameobj)=0;
+ virtual void ReplaceMesh(class CValue* gameobj,
+ void* meshobj)=0;
+ std::vector<SCA_DebugProp*>& GetDebugProperties();
+ void AddDebugProperty(class CValue* debugprop,
+ const STR_String &name);
+};
+#endif //__KX_ISCENE_H
diff --git a/source/gameengine/GameLogic/SCA_ISensor.cpp b/source/gameengine/GameLogic/SCA_ISensor.cpp
new file mode 100644
index 00000000000..be26f1d503e
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_ISensor.cpp
@@ -0,0 +1,328 @@
+/**
+ * Abstract class for sensor logic bricks
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "SCA_ISensor.h"
+#include "SCA_EventManager.h"
+#include "SCA_LogicManager.h"
+
+/* Native functions */
+
+
+void SCA_ISensor::ReParent(SCA_IObject* parent)
+{
+ SCA_ILogicBrick::ReParent(parent);
+ m_eventmgr->RegisterSensor(this);
+ this->SetActive(false);
+}
+
+
+SCA_ISensor::SCA_ISensor(SCA_IObject* gameobj,
+ class SCA_EventManager* eventmgr,
+ PyTypeObject* T ) :
+ SCA_ILogicBrick(gameobj,T),
+ m_triggered(false)
+{
+ m_suspended = false;
+ m_invert = false;
+ m_pos_ticks = 0;
+ m_neg_ticks = 0;
+ m_pos_pulsemode = false;
+ m_neg_pulsemode = false;
+ m_pulse_frequency = 0;
+
+ m_eventmgr = eventmgr;
+}
+
+
+SCA_ISensor::~SCA_ISensor()
+{
+ // intentionally empty
+}
+
+bool SCA_ISensor::IsPositiveTrigger() {
+ bool result = false;
+
+ if (m_eventval) {
+ result = (m_eventval->GetNumber() != 0.0);
+ }
+ if (m_invert) {
+ result = !result;
+ }
+
+ return result;
+}
+
+void SCA_ISensor::SetPulseMode(bool posmode,
+ bool negmode,
+ int freq) {
+ m_pos_pulsemode = posmode;
+ m_neg_pulsemode = negmode;
+ m_pulse_frequency = freq;
+}
+
+void SCA_ISensor::SetInvert(bool inv) {
+ m_invert = inv;
+}
+
+
+float SCA_ISensor::GetNumber() {
+ return IsPositiveTrigger();
+}
+
+void SCA_ISensor::Suspend() {
+ m_suspended = true;
+}
+
+bool SCA_ISensor::IsSuspended() {
+ return m_suspended;
+}
+
+void SCA_ISensor::Resume() {
+ m_suspended = false;
+}
+
+/* python integration */
+
+PyTypeObject SCA_ISensor::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_ISensor",
+ sizeof(SCA_ISensor),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_ISensor::Parents[] = {
+ &SCA_ISensor::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+PyMethodDef SCA_ISensor::Methods[] = {
+ {"isPositive", (PyCFunction) SCA_ISensor::sPyIsPositive,
+ METH_VARARGS, IsPositive_doc},
+ {"getUsePosPulseMode", (PyCFunction) SCA_ISensor::sPyGetUsePosPulseMode,
+ METH_VARARGS, GetUsePosPulseMode_doc},
+ {"setUsePosPulseMode", (PyCFunction) SCA_ISensor::sPySetUsePosPulseMode,
+ METH_VARARGS, SetUsePosPulseMode_doc},
+ {"getFrequency", (PyCFunction) SCA_ISensor::sPyGetFrequency,
+ METH_VARARGS, GetFrequency_doc},
+ {"setFrequency", (PyCFunction) SCA_ISensor::sPySetFrequency,
+ METH_VARARGS, SetFrequency_doc},
+ {"getUseNegPulseMode", (PyCFunction) SCA_ISensor::sPyGetUseNegPulseMode,
+ METH_VARARGS, GetUseNegPulseMode_doc},
+ {"setUseNegPulseMode", (PyCFunction) SCA_ISensor::sPySetUseNegPulseMode,
+ METH_VARARGS, SetUseNegPulseMode_doc},
+ {NULL,NULL} //Sentinel
+};
+
+
+PyObject*
+SCA_ISensor::_getattr(char* attr)
+{
+ _getattr_up(SCA_ILogicBrick);
+}
+
+
+void SCA_ISensor::RegisterToManager()
+{
+ m_eventmgr->RegisterSensor(this);
+}
+
+void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr, CValue* event)
+{
+
+ // calculate if a __triggering__ is wanted
+ if (!m_suspended) {
+ bool result = this->Evaluate(event);
+ if (result) {
+ logicmgr->AddActivatedSensor(this);
+ } else
+ {
+ /* First, the pulsing behaviour, if pulse mode is
+ * active. It seems something goes wrong if pulse mode is
+ * not set :( */
+ if (m_pos_pulsemode) {
+ m_pos_ticks++;
+ if (m_pos_ticks > m_pulse_frequency) {
+ if ( this->IsPositiveTrigger() )
+ {
+ logicmgr->AddActivatedSensor(this);
+ }
+ m_pos_ticks = 0;
+ }
+ }
+
+ if (m_neg_pulsemode)
+ {
+ m_neg_ticks++;
+ if (m_neg_ticks > m_pulse_frequency) {
+ if (!this->IsPositiveTrigger() )
+ {
+ logicmgr->AddActivatedSensor(this);
+ }
+ m_neg_ticks = 0;
+ }
+ }
+ }
+ }
+}
+
+/* Python functions: */
+char SCA_ISensor::IsPositive_doc[] =
+"isPositive()\n"
+"\tReturns whether the sensor is registered a positive event.\n";
+PyObject* SCA_ISensor::PyIsPositive(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int retval = IsPositiveTrigger();
+ return PyInt_FromLong(retval);
+}
+
+/**
+ * getUsePulseMode: getter for the pulse mode (KX_TRUE = on)
+ */
+char SCA_ISensor::GetUsePosPulseMode_doc[] =
+"getUsePosPulseMode()\n"
+"\tReturns whether positive pulse mode is active.\n";
+PyObject* SCA_ISensor::PyGetUsePosPulseMode(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return BoolToPyArg(m_pos_pulsemode);
+}
+
+/**
+ * setUsePulseMode: setter for the pulse mode (KX_TRUE = on)
+ */
+char SCA_ISensor::SetUsePosPulseMode_doc[] =
+"setUsePosPulseMode(pulse?)\n"
+"\t - pulse? : Pulse when a positive event occurs?\n"
+"\t (KX_TRUE, KX_FALSE)\n"
+"\tSet whether to do pulsing when positive pulses occur.\n";
+PyObject* SCA_ISensor::PySetUsePosPulseMode(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int pyarg = 0;
+ if(!PyArg_ParseTuple(args, "i", &pyarg)) { return NULL; }
+ m_pos_pulsemode = PyArgToBool(pyarg);
+ Py_Return;
+}
+
+/**
+ * getFrequency: getter for the pulse mode interval
+ */
+char SCA_ISensor::GetFrequency_doc[] =
+"getFrequency()\n"
+"\tReturns the frequency of the updates in pulse mode.\n" ;
+PyObject* SCA_ISensor::PyGetFrequency(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return PyInt_FromLong(m_pulse_frequency);
+}
+
+/**
+ * setFrequency: setter for the pulse mode (KX_TRUE = on)
+ */
+char SCA_ISensor::SetFrequency_doc[] =
+"setFrequency(pulse_frequency)\n"
+"\t- pulse_frequency: The frequency of the updates in pulse mode (integer)"
+"\tSet the frequency of the updates in pulse mode.\n"
+"\tIf the frequency is negative, it is set to 0.\n" ;
+PyObject* SCA_ISensor::PySetFrequency(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int pulse_frequencyArg = 0;
+
+ if(!PyArg_ParseTuple(args, "i", &pulse_frequencyArg)) {
+ return NULL;
+ }
+
+ /* We can do three things here: clip, ignore and raise an exception. */
+ /* Exceptions don't work yet, ignoring is not desirable now... */
+ if (pulse_frequencyArg < 0) {
+ pulse_frequencyArg = 0;
+ };
+ m_pulse_frequency = pulse_frequencyArg;
+
+ Py_Return;
+}
+
+
+char SCA_ISensor::GetInvert_doc[] =
+"getInvert()\n"
+"\tReturns whether or not pulses from this sensor are inverted.\n" ;
+PyObject* SCA_ISensor::PyGetInvert(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return BoolToPyArg(m_invert);
+}
+
+char SCA_ISensor::SetInvert_doc[] =
+"setInvert(invert?)\n"
+"\t- invert?: Invert the event-values? (KX_TRUE, KX_FALSE)\n"
+"\tSet whether to invert pulses.\n";
+PyObject* SCA_ISensor::PySetInvert(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int pyarg = 0;
+ if(!PyArg_ParseTuple(args, "i", &pyarg)) { return NULL; }
+ m_invert = PyArgToBool(pyarg);
+ Py_Return;
+}
+
+char SCA_ISensor::GetUseNegPulseMode_doc[] =
+"getUseNegPulseMode()\n"
+"\tReturns whether negative pulse mode is active.\n";
+PyObject* SCA_ISensor::PyGetUseNegPulseMode(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return BoolToPyArg(m_neg_pulsemode);
+}
+
+char SCA_ISensor::SetUseNegPulseMode_doc[] =
+"setUseNegPulseMode(pulse?)\n"
+"\t - pulse? : Pulse when a negative event occurs?\n"
+"\t (KX_TRUE, KX_FALSE)\n"
+"\tSet whether to do pulsing when negative pulses occur.\n";
+PyObject* SCA_ISensor::PySetUseNegPulseMode(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int pyarg = 0;
+ if(!PyArg_ParseTuple(args, "i", &pyarg)) { return NULL; }
+ m_neg_pulsemode = PyArgToBool(pyarg);
+ Py_Return;
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h
new file mode 100644
index 00000000000..ef3f037be96
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_ISensor.h
@@ -0,0 +1,130 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * Interface Class for all logic Sensors. Implements
+ * pulsemode and pulsefrequency, and event suppression.
+ */
+
+#ifndef __SCA_ISENSOR
+#define __SCA_ISENSOR
+
+#include "SCA_ILogicBrick.h"
+
+
+
+/**
+ * Interface Class for all logic Sensors. Implements
+ * pulsemode,pulsefrequency */
+class SCA_ISensor : public SCA_ILogicBrick
+{
+ Py_Header;
+ class SCA_EventManager* m_eventmgr;
+ bool m_triggered;
+
+ /* Pulse positive pulses? */
+ bool m_pos_pulsemode;
+
+ /** Pulse negative pulses? */
+ bool m_neg_pulsemode;
+
+ /** Repeat frequency in pulse mode. */
+ int m_pulse_frequency;
+
+ /** Number of ticks since the last positive pulse. */
+ int m_pos_ticks;
+
+ /** Number of ticks since the last negative pulse. */
+ int m_neg_ticks;
+
+ /* invert the output signal*/
+ bool m_invert;
+
+ /** Sensor must ignore updates? */
+ bool m_suspended;
+
+ /** Pass the activation on to the logic manager.*/
+ void SignalActivation(class SCA_LogicManager* logicmgr);
+
+public:
+ SCA_ISensor(SCA_IObject* gameobj,
+ class SCA_EventManager* eventmgr,
+ PyTypeObject* T );;
+ ~SCA_ISensor();
+ virtual void ReParent(SCA_IObject* parent);
+
+ /* Because we want sensors to share some behaviour, the Activate has */
+ /* an implementation on this level. It requires an evaluate on the lower */
+ /* level of individual sensors. Mapping the old activate()s is easy. */
+ /* The IsPosTrig() also has to change, to keep things consistent. */
+ void Activate(class SCA_LogicManager* logicmgr,CValue* event);
+ virtual bool Evaluate(CValue* event) = 0;
+ virtual bool IsPositiveTrigger();
+
+ virtual PyObject* _getattr(char *attr);
+ virtual CValue* GetReplica()=0;
+
+ /** Set parameters for the pulsing behaviour.
+ * @param posmode Trigger positive pulses?
+ * @param negmode Trigger negative pulses?
+ * @param freq Frequency to use when doing pulsing.
+ */
+ void SetPulseMode(bool posmode,
+ bool negmode,
+ int freq);
+
+ /** Set inversion of pulses on or off. */
+ void SetInvert(bool inv);
+
+ void RegisterToManager();
+ virtual float GetNumber();
+
+ /** Stop sensing for a while. */
+ void Suspend();
+
+ /** Is this sensor switched off? */
+ bool IsSuspended();
+
+ /** Resume sensing. */
+ void Resume();
+
+ /* Python functions: */
+ KX_PYMETHOD_DOC(SCA_ISensor,IsPositive);
+ KX_PYMETHOD_DOC(SCA_ISensor,GetUsePosPulseMode);
+ KX_PYMETHOD_DOC(SCA_ISensor,SetUsePosPulseMode);
+ KX_PYMETHOD_DOC(SCA_ISensor,GetFrequency);
+ KX_PYMETHOD_DOC(SCA_ISensor,SetFrequency);
+ KX_PYMETHOD_DOC(SCA_ISensor,GetUseNegPulseMode);
+ KX_PYMETHOD_DOC(SCA_ISensor,SetUseNegPulseMode);
+ KX_PYMETHOD_DOC(SCA_ISensor,GetInvert);
+ KX_PYMETHOD_DOC(SCA_ISensor,SetInvert);
+
+};
+
+#endif //__SCA_ISENSOR
diff --git a/source/gameengine/GameLogic/SCA_KeyboardManager.cpp b/source/gameengine/GameLogic/SCA_KeyboardManager.cpp
new file mode 100644
index 00000000000..46223aa11af
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_KeyboardManager.cpp
@@ -0,0 +1,91 @@
+/**
+ * Manager for keyboard events
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <iostream.h>
+#include "BoolValue.h"
+#include "SCA_KeyboardManager.h"
+#include "SCA_KeyboardSensor.h"
+#include "IntValue.h"
+#include <vector>
+
+SCA_KeyboardManager::SCA_KeyboardManager(SCA_LogicManager* logicmgr,
+ SCA_IInputDevice* inputdev)
+ : SCA_EventManager(KEYBOARD_EVENTMGR),
+ m_logicmanager(logicmgr),
+ m_inputDevice(inputdev)
+{
+}
+
+
+
+SCA_KeyboardManager::~SCA_KeyboardManager()
+{
+}
+
+
+
+SCA_IInputDevice* SCA_KeyboardManager::GetInputDevice()
+{
+ return m_inputDevice;
+}
+
+
+
+void SCA_KeyboardManager::NextFrame(double curtime,double deltatime)
+{
+ //const SCA_InputEvent& event = GetEventValue(SCA_IInputDevice::KX_EnumInputs inputcode)=0;
+ // cerr << "SCA_KeyboardManager::NextFrame"<< endl;
+ for (int i=0;i<m_sensors.size();i++)
+ {
+ SCA_KeyboardSensor* keysensor = (SCA_KeyboardSensor*)m_sensors[i];
+ keysensor->Activate(m_logicmanager,NULL);
+ }
+
+}
+
+
+
+void SCA_KeyboardManager::RegisterSensor(SCA_ISensor* keysensor)
+{
+ m_sensors.push_back(keysensor);
+}
+
+
+
+bool SCA_KeyboardManager::IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)
+{
+ return false;
+ //return m_kxsystem->IsPressed(inputcode);
+}
+
diff --git a/source/gameengine/GameLogic/SCA_KeyboardManager.h b/source/gameengine/GameLogic/SCA_KeyboardManager.h
new file mode 100644
index 00000000000..1c665ef2b88
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_KeyboardManager.h
@@ -0,0 +1,66 @@
+/**
+ * Manager for keyboard events
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_KEYBOARDMANAGER
+#define __KX_KEYBOARDMANAGER
+
+
+#include "SCA_EventManager.h"
+
+#include <vector>
+
+using namespace std;
+
+#include "SCA_IInputDevice.h"
+
+
+class SCA_KeyboardManager : public SCA_EventManager
+{
+ class SCA_IInputDevice* m_inputDevice;
+ class SCA_LogicManager* m_logicmanager;
+
+
+public:
+ SCA_KeyboardManager(class SCA_LogicManager* logicmgr,class SCA_IInputDevice* inputdev);
+ virtual ~SCA_KeyboardManager();
+
+ bool IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode);
+
+
+ virtual void NextFrame(double curtime,double deltatime);
+ virtual void RegisterSensor(class SCA_ISensor* sensor);
+ SCA_IInputDevice* GetInputDevice();
+};
+
+#endif //__KX_KEYBOARDMANAGER
diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
new file mode 100644
index 00000000000..834c9254cc0
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
@@ -0,0 +1,675 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * Sensor for keyboard input
+ */
+#include "SCA_KeyboardSensor.h"
+#include "SCA_KeyboardManager.h"
+#include "SCA_LogicManager.h"
+#include "StringValue.h"
+#include "SCA_IInputDevice.h"
+
+
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_KeyboardSensor::SCA_KeyboardSensor(SCA_KeyboardManager* keybdmgr,
+ short int hotkey,
+ short int qual,
+ short int qual2,
+ bool bAllKeys,
+ const STR_String& targetProp,
+ const STR_String& toggleProp,
+ SCA_IObject* gameobj,
+ PyTypeObject* T )
+ :SCA_ISensor(gameobj,keybdmgr,T),
+ m_pKeyboardMgr(keybdmgr),
+ m_hotkey(hotkey),
+ m_qual(qual),
+ m_qual2(qual2),
+ m_bAllKeys(bAllKeys),
+ m_targetprop(targetProp),
+ m_toggleprop(toggleProp)
+{
+
+// SetDrawColor(0xff0000ff);
+ m_val=0;
+}
+
+
+
+SCA_KeyboardSensor::~SCA_KeyboardSensor()
+{
+}
+
+
+
+CValue* SCA_KeyboardSensor::GetReplica()
+{
+ CValue* replica = new SCA_KeyboardSensor(*this);
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+short int SCA_KeyboardSensor::GetHotkey()
+{
+ return m_hotkey;
+}
+
+
+
+bool SCA_KeyboardSensor::IsPositiveTrigger()
+{
+ bool result = (m_val != 0);
+
+ if (m_invert)
+ result = !result;
+
+ return result;
+}
+
+
+
+bool SCA_KeyboardSensor::TriggerOnAllKeys()
+{
+ return m_bAllKeys;
+}
+
+
+
+bool SCA_KeyboardSensor::Evaluate(CValue* eventval)
+{
+ bool result = false;
+ SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice();
+
+ // cerr << "SCA_KeyboardSensor::Eval event, sensing for "<< m_hotkey << " at device " << inputdev << "\n";
+
+ /* See if we need to do logging: togPropState exists and is
+ * different from 0 */
+ CValue* myparent = GetParent();
+ CValue* togPropState = myparent->GetProperty(m_toggleprop);
+ if (togPropState &&
+ (((int)togPropState->GetNumber()) != 0) )
+ {
+ LogKeystrokes();
+ }
+
+
+
+ /* Now see whether events must be bounced. */
+ if (m_bAllKeys)
+ {
+ bool justactivated = false;
+ bool justreleased = false;
+
+ for (int i=SCA_IInputDevice::KX_BEGINKEY ; i< SCA_IInputDevice::KX_ENDKEY;i++)
+ {
+ const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i);
+ if (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED)
+ {
+ justactivated = true;
+ }
+ if (inevent.m_status == SCA_InputEvent::KX_JUSTRELEASED)
+ {
+ justreleased = true;
+ }
+ }
+
+ if (justactivated)
+ {
+ m_val=1;
+ result = true;
+ } else
+ {
+ if (justreleased)
+ {
+ m_val=0;
+ result = true;
+ }
+ }
+
+
+ } else
+ {
+
+ // cerr << "======= SCA_KeyboardSensor::Evaluate:: peeking at key status" << endl;
+ const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) m_hotkey);
+
+ // cerr << "======= SCA_KeyboardSensor::Evaluate:: status: " << inevent.m_status << endl;
+
+ if (inevent.m_status == SCA_InputEvent::KX_NO_INPUTSTATUS)
+ {
+ int i=4;
+ } else
+ {
+ if (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED)
+ {
+ m_val=1;
+ result = true;
+ } else
+ {
+ if (inevent.m_status == SCA_InputEvent::KX_JUSTRELEASED)
+ {
+ m_val = 0;
+ result = true;
+ }
+ }
+ }
+ }
+
+ return result;
+
+}
+
+void SCA_KeyboardSensor::AddToTargetProp(int keyIndex)
+{
+ if (IsPrintable(keyIndex)) {
+ CValue* tprop = GetParent()->GetProperty(m_targetprop);
+
+ if (tprop) {
+ /* overwrite the old property */
+ if (IsDelete(keyIndex)) {
+ /* strip one char, if possible */
+ STR_String newprop = tprop->GetText();
+ int oldlength = newprop.Length();
+ if (oldlength >= 1 ) {
+ newprop.SetLength(oldlength - 1);
+ CStringValue * newstringprop = new CStringValue(newprop, m_targetprop);
+ GetParent()->SetProperty(m_targetprop, newstringprop);
+ }
+ } else {
+ /* append */
+ char pchar = ToCharacter(keyIndex, IsShifted());
+ STR_String newprop = tprop->GetText() + pchar;
+ CStringValue * newstringprop = new CStringValue(newprop, m_targetprop);
+ GetParent()->SetProperty(m_targetprop, newstringprop);
+ }
+ } else {
+ if (!IsDelete(keyIndex)) {
+ /* Make a new property. Deletes can be ignored. */
+ char pchar = ToCharacter(keyIndex, IsShifted());
+ STR_String newprop = pchar;
+ CStringValue * newstringprop = new CStringValue(newprop, m_targetprop);
+ GetParent()->SetProperty(m_targetprop, newstringprop);
+ }
+ }
+ }
+
+}
+
+/**
+ * Determine whether this character can be printed. We cannot use
+ * the library functions here, because we need to test our own
+ * keycodes. */
+bool SCA_KeyboardSensor::IsPrintable(int keyIndex)
+{
+ /* only print
+ * - numerals: KX_ZEROKEY to KX_NINEKEY
+ * - alphas: KX_AKEY to KX_ZKEY.
+ * - specials: KX_RETKEY, KX_PADASTERKEY, KX_PADCOMMAKEY to KX_PERIODKEY,
+ * KX_TABKEY , KX_SEMICOLONKEY to KX_RIGHTBRACKETKEY,
+ * KX_PAD2 to KX_PADPLUSKEY
+ * - delete and backspace: also printable in the sense that they modify
+ * the string
+ * - retkey: should this be printable?
+ * - virgule: prints a space... don't know which key that's supposed
+ * to be...
+ */
+ if ( ((keyIndex >= SCA_IInputDevice::KX_ZEROKEY)
+ && (keyIndex <= SCA_IInputDevice::KX_NINEKEY))
+ || ((keyIndex >= SCA_IInputDevice::KX_AKEY)
+ && (keyIndex <= SCA_IInputDevice::KX_ZKEY))
+ || (keyIndex == SCA_IInputDevice::KX_SPACEKEY)
+/* || (keyIndex == KX_RETKEY) */
+ || (keyIndex == SCA_IInputDevice::KX_PADASTERKEY)
+ || (keyIndex == SCA_IInputDevice::KX_TABKEY)
+ || ((keyIndex >= SCA_IInputDevice::KX_COMMAKEY)
+ && (keyIndex <= SCA_IInputDevice::KX_PERIODKEY))
+ || ((keyIndex >= SCA_IInputDevice::KX_SEMICOLONKEY)
+ && (keyIndex <= SCA_IInputDevice::KX_RIGHTBRACKETKEY))
+ || ((keyIndex >= SCA_IInputDevice::KX_PAD2)
+ && (keyIndex <= SCA_IInputDevice::KX_PADPLUSKEY))
+ || (keyIndex == SCA_IInputDevice::KX_DELKEY)
+ || (keyIndex == SCA_IInputDevice::KX_BACKSPACEKEY)
+ )
+ {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+// this code looks ugly, please use an ordinary hashtable
+
+char SCA_KeyboardSensor::ToCharacter(int keyIndex, bool shifted)
+{
+ /* numerals */
+ if ( (keyIndex >= SCA_IInputDevice::KX_ZEROKEY)
+ && (keyIndex <= SCA_IInputDevice::KX_NINEKEY) ) {
+ if (shifted) {
+ char numshift[] = ")!@#$%^&*(";
+ return numshift[keyIndex - '0'];
+ } else {
+ return keyIndex - SCA_IInputDevice::KX_ZEROKEY + '0';
+ }
+ }
+
+ /* letters... always lowercase... is that desirable? */
+ if ( (keyIndex >= SCA_IInputDevice::KX_AKEY)
+ && (keyIndex <= SCA_IInputDevice::KX_ZKEY) ) {
+ if (shifted) {
+ return keyIndex - SCA_IInputDevice::KX_AKEY + 'A';
+ } else {
+ return keyIndex - SCA_IInputDevice::KX_AKEY + 'a';
+ }
+ }
+
+ if (keyIndex == SCA_IInputDevice::KX_SPACEKEY) {
+ return ' ';
+ }
+
+/* || (keyIndex == SCA_IInputDevice::KX_RETKEY) */
+
+ if (keyIndex == SCA_IInputDevice::KX_PADASTERKEY) {
+ return '*';
+ }
+
+ if (keyIndex == SCA_IInputDevice::KX_TABKEY) {
+ return '\t';
+ }
+
+ /* comma to period */
+ char commatoperiod[] = ",-.";
+ char commatoperiodshifted[] = "<_>";
+ if (keyIndex == SCA_IInputDevice::KX_COMMAKEY) {
+ if (shifted) {
+ return commatoperiodshifted[0];
+ } else {
+ return commatoperiod[0];
+ }
+ }
+ if (keyIndex == SCA_IInputDevice::KX_MINUSKEY) {
+ if (shifted) {
+ return commatoperiodshifted[1];
+ } else {
+ return commatoperiod[1];
+ }
+ }
+ if (keyIndex == SCA_IInputDevice::KX_PERIODKEY) {
+ if (shifted) {
+ return commatoperiodshifted[2];
+ } else {
+ return commatoperiod[2];
+ }
+ }
+
+ /* semicolon to rightbracket */
+ char semicolontorightbracket[] = ";\'` /\\=[]";
+ char semicolontorightbracketshifted[] = ":\"~ \?|+{}";
+ if ((keyIndex >= SCA_IInputDevice::KX_SEMICOLONKEY)
+ && (keyIndex <= SCA_IInputDevice::KX_RIGHTBRACKETKEY)) {
+ if (shifted) {
+ return semicolontorightbracketshifted[keyIndex - SCA_IInputDevice::KX_SEMICOLONKEY];
+ } else {
+ return semicolontorightbracket[keyIndex - SCA_IInputDevice::KX_SEMICOLONKEY];
+ }
+ }
+
+ /* keypad2 to padplus */
+ char pad2topadplus[] = "246813579. 0- +";
+ if ((keyIndex >= SCA_IInputDevice::KX_PAD2)
+ && (keyIndex <= SCA_IInputDevice::KX_PADPLUSKEY)) {
+ return pad2topadplus[keyIndex - SCA_IInputDevice::KX_PAD2];
+ }
+
+ return '!';
+}
+
+/**
+ * Tests whether this is a delete key.
+ */
+bool SCA_KeyboardSensor::IsDelete(int keyIndex)
+{
+ if ( (keyIndex == SCA_IInputDevice::KX_DELKEY)
+ || (keyIndex == SCA_IInputDevice::KX_BACKSPACEKEY) ) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+/**
+ * Tests whether shift is pressed
+ */
+bool SCA_KeyboardSensor::IsShifted(void)
+{
+ SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice();
+
+ if ( (inputdev->GetEventValue(SCA_IInputDevice::KX_RIGHTSHIFTKEY).m_status
+ == SCA_InputEvent::KX_ACTIVE)
+ || (inputdev->GetEventValue(SCA_IInputDevice::KX_RIGHTSHIFTKEY).m_status
+ == SCA_InputEvent::KX_JUSTACTIVATED)
+ || (inputdev->GetEventValue(SCA_IInputDevice::KX_LEFTSHIFTKEY).m_status
+ == SCA_InputEvent::KX_ACTIVE)
+ || (inputdev->GetEventValue(SCA_IInputDevice::KX_LEFTSHIFTKEY).m_status
+ == SCA_InputEvent::KX_JUSTACTIVATED)
+ ) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void SCA_KeyboardSensor::LogKeystrokes(void)
+{
+ SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice();
+ int num = inputdev->GetNumActiveEvents();
+
+ /* weird loop, this one... */
+ if (num > 0)
+ {
+
+ int index = 0;
+ /* Check on all keys whether they were pushed. This does not
+ * untangle the ordering, so don't type too fast :) */
+ for (int i=SCA_IInputDevice::KX_BEGINKEY ; i< SCA_IInputDevice::KX_ENDKEY;i++)
+ {
+ const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i);
+ if (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED) //NO_INPUTSTATUS)
+ {
+ if (index < num)
+ {
+ AddToTargetProp(i);
+ index++;
+ }
+ }
+ }
+ }
+}
+
+
+/* ------------------------------------------------------------------------- */
+/* Python functions : specific */
+/* ------------------------------------------------------------------------- */
+
+
+PyObject* SCA_KeyboardSensor::PySetAllMode(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ bool allkeys;
+
+ if (!PyArg_ParseTuple(args, "i", &allkeys))
+ {
+ return NULL;
+ }
+
+ m_bAllKeys = allkeys;
+ Py_Return
+}
+
+
+
+PyObject* SCA_KeyboardSensor::sPySetAllMode(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+// printf("sPyIsPositive\n");
+ return ((SCA_KeyboardSensor*) self)->PyIsPositive(self, args, kwds);
+}
+
+
+/** 1. GetKey : check which key this sensor looks at */
+char SCA_KeyboardSensor::GetKey_doc[] =
+"getKey()\n"
+"\tReturn the code of the key this sensor is listening to.\n" ;
+PyObject* SCA_KeyboardSensor::PyGetKey(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return PyInt_FromLong(m_hotkey);
+}
+
+/** 2. SetKey: change the key to look at */
+char SCA_KeyboardSensor::SetKey_doc[] =
+"setKey(keycode)\n"
+"\t- keycode: any code from GameKeys\n"
+"\tSet the key this sensor should listen to.\n" ;
+PyObject* SCA_KeyboardSensor::PySetKey(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int keyCode;
+
+ if(!PyArg_ParseTuple(args, "i", &keyCode)) {
+ return NULL;
+ }
+
+ /* Since we have symbolic constants for this in Python, we don't guard */
+ /* anything. It's up to the user to provide a sensible number. */
+ m_hotkey = keyCode;
+
+ Py_Return;
+}
+
+/** 3. GetHold1 : set the first bucky bit */
+char SCA_KeyboardSensor::GetHold1_doc[] =
+"getHold1()\n"
+"\tReturn the code of the first key modifier to the key this \n"
+"\tsensor is listening to.\n" ;
+PyObject* SCA_KeyboardSensor::PyGetHold1(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return PyInt_FromLong(m_qual);
+}
+
+/** 4. SetHold1: change the first bucky bit */
+char SCA_KeyboardSensor::SetHold1_doc[] =
+"setHold1(keycode)\n"
+"\t- keycode: any code from GameKeys\n"
+"\tSet the first modifier to the key this sensor should listen to.\n" ;
+PyObject* SCA_KeyboardSensor::PySetHold1(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int keyCode;
+
+ if(!PyArg_ParseTuple(args, "i", &keyCode)) {
+ return NULL;
+ }
+
+ /* Since we have symbolic constants for this in Python, we don't guard */
+ /* anything. It's up to the user to provide a sensible number. */
+ m_qual = keyCode;
+
+ Py_Return;
+}
+
+/** 5. GetHold2 : get the second bucky bit */
+char SCA_KeyboardSensor::GetHold2_doc[] =
+"getHold2()\n"
+"\tReturn the code of the second key modifier to the key this \n"
+"\tsensor is listening to.\n" ;
+PyObject* SCA_KeyboardSensor::PyGetHold2(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return PyInt_FromLong(m_qual2);
+}
+
+/** 6. SetHold2: change the second bucky bit */
+char SCA_KeyboardSensor::SetHold2_doc[] =
+"setHold2(keycode)\n"
+"\t- keycode: any code from GameKeys\n"
+"\tSet the first modifier to the key this sensor should listen to.\n" ;
+PyObject* SCA_KeyboardSensor::PySetHold2(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int keyCode;
+
+ if(!PyArg_ParseTuple(args, "i", &keyCode)) {
+ return NULL;
+ }
+
+ /* Since we have symbolic constants for this in Python, we don't guard */
+ /* anything. It's up to the user to provide a sensible number. */
+ m_qual2 = keyCode;
+
+ Py_Return;
+}
+
+
+char SCA_KeyboardSensor::GetPressedKeys_doc[] =
+"getPressedKeys()\n"
+"\tGet a list of pressed keys that have either been pressed, or just released this frame.\n" ;
+
+PyObject* SCA_KeyboardSensor::PyGetPressedKeys(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice();
+
+ int num = inputdev->GetNumJustEvents();
+ PyObject* resultlist = PyList_New(num);
+
+ if (num > 0)
+ {
+
+ int index = 0;
+
+ for (int i=SCA_IInputDevice::KX_BEGINKEY ; i< SCA_IInputDevice::KX_ENDKEY;i++)
+ {
+ const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i);
+ if ((inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED)
+ || (inevent.m_status == SCA_InputEvent::KX_JUSTRELEASED))
+ {
+ if (index < num)
+ {
+ PyObject* keypair = PyList_New(2);
+ PyList_SetItem(keypair,0,PyInt_FromLong(i));
+ PyList_SetItem(keypair,1,PyInt_FromLong(inevent.m_status));
+ PyList_SetItem(resultlist,index,keypair);
+ index++;
+ }
+ }
+ }
+ if (index>0) return resultlist;
+ }
+
+ Py_Return;
+}
+
+
+
+char SCA_KeyboardSensor::GetCurrentlyPressedKeys_doc[] =
+"getCurrentlyPressedKeys()\n"
+"\tGet a list of keys that are currently pressed.\n" ;
+
+PyObject* SCA_KeyboardSensor::PyGetCurrentlyPressedKeys(PyObject* self, PyObject* args, PyObject* kwds)
+{
+SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice();
+
+ int num = inputdev->GetNumActiveEvents();
+ PyObject* resultlist = PyList_New(num);
+
+ if (num > 0)
+ {
+ int index = 0;
+
+ for (int i=SCA_IInputDevice::KX_BEGINKEY ; i< SCA_IInputDevice::KX_ENDKEY;i++)
+ {
+ const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i);
+ if ( (inevent.m_status == SCA_InputEvent::KX_ACTIVE)
+ || (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED))
+ {
+ if (index < num)
+ {
+ PyObject* keypair = PyList_New(2);
+ PyList_SetItem(keypair,0,PyInt_FromLong(i));
+ PyList_SetItem(keypair,1,PyInt_FromLong(inevent.m_status));
+ PyList_SetItem(resultlist,index,keypair);
+ index++;
+ }
+ }
+ }
+
+ /* why?*/
+ if (index > 0) return resultlist;
+ }
+
+ Py_Return;
+}
+
+/* ------------------------------------------------------------------------- */
+/* Python functions : integration hooks */
+/* ------------------------------------------------------------------------- */
+
+PyTypeObject SCA_KeyboardSensor::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_KeyboardSensor",
+ sizeof(SCA_KeyboardSensor),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_KeyboardSensor::Parents[] = {
+ &SCA_KeyboardSensor::Type,
+ &SCA_ISensor::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef SCA_KeyboardSensor::Methods[] = {
+ {"getKey", (PyCFunction) SCA_KeyboardSensor::sPyGetKey, METH_VARARGS, GetKey_doc},
+ {"setKey", (PyCFunction) SCA_KeyboardSensor::sPySetKey, METH_VARARGS, SetKey_doc},
+ {"getHold1", (PyCFunction) SCA_KeyboardSensor::sPyGetHold1, METH_VARARGS, GetHold1_doc},
+ {"setHold1", (PyCFunction) SCA_KeyboardSensor::sPySetHold1, METH_VARARGS, SetHold1_doc},
+ {"getHold2", (PyCFunction) SCA_KeyboardSensor::sPyGetHold2, METH_VARARGS, GetHold2_doc},
+ {"setHold2", (PyCFunction) SCA_KeyboardSensor::sPySetHold2, METH_VARARGS, SetHold2_doc},
+// {"getUseAllKeys", (PyCFunction) SCA_KeyboardSensor::sPyGetUseAllKeys, METH_VARARGS, GetUseAllKeys_doc},
+// {"setUseAllKeys", (PyCFunction) SCA_KeyboardSensor::sPySetUseAllKeys, METH_VARARGS, SetUseAllKeys_doc},
+ {"getPressedKeys", (PyCFunction) SCA_KeyboardSensor::sPyGetPressedKeys, METH_VARARGS, GetPressedKeys_doc},
+ {"getCurrentlyPressedKeys", (PyCFunction) SCA_KeyboardSensor::sPyGetCurrentlyPressedKeys, METH_VARARGS, GetCurrentlyPressedKeys_doc},
+// {"getKeyEvents", (PyCFunction) SCA_KeyboardSensor::sPyGetKeyEvents, METH_VARARGS, GetKeyEvents_doc},
+ {NULL,NULL} //Sentinel
+};
+
+PyObject*
+SCA_KeyboardSensor::_getattr(char* attr)
+{
+ _getattr_up(SCA_ISensor);
+}
+
diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.h b/source/gameengine/GameLogic/SCA_KeyboardSensor.h
new file mode 100644
index 00000000000..f9de2a0e715
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.h
@@ -0,0 +1,158 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * Sensor for keyboard input
+ */
+
+#ifndef __KX_KEYBOARDSENSOR
+#define __KX_KEYBOARDSENSOR
+
+#include "SCA_ISensor.h"
+#include "BoolValue.h"
+#include <list>
+
+/**
+ * The keyboard sensor listens to the keyboard, and passes on events
+ * on selected keystrokes. It has an alternate mode in which it logs
+ * keypresses to a property. Note that these modes are not mutually
+ * exclusive. */
+class SCA_KeyboardSensor : public SCA_ISensor
+{
+ Py_Header;
+ class SCA_KeyboardManager* m_pKeyboardMgr;
+
+
+ /**
+ * the key this sensor is sensing for
+ */
+ int m_hotkey;
+ short int m_qual,m_qual2;
+ short int m_val;
+ /**
+ * If this toggle is true, all incoming key events generate a
+ * response.
+ */
+ bool m_bAllKeys;
+
+ /**
+ * The name of the property to which logged text is appended. If
+ * this property is not defined, no logging takes place.
+ */
+ STR_String m_targetprop;
+ /**
+ * The property that indicates whether or not to log text when in
+ * loggin mode. If the property equals 0, no loggin is done. For
+ * all other values, logging is active. Logging can only become
+ * active if there is a property to log to. Logging is independant
+ * from hotkey settings. */
+ STR_String m_toggleprop;
+
+ /**
+ * Log the keystrokes from the current input buffer.
+ */
+ void LogKeystrokes(void);
+
+ /**
+ * Adds this key-code to the target prop.
+ */
+ void AddToTargetProp(int keyIndex);
+
+ /**
+ * Determine whether this character can be printed. We cannot use
+ * the library functions here, because we need to test our own
+ * keycodes. */
+ bool IsPrintable(int keyIndex);
+
+ /**
+ * Transform keycodes to something printable.
+ */
+ char ToCharacter(int keyIndex, bool shifted);
+
+ /**
+ * Tests whether this is a delete key.
+ */
+ bool IsDelete(int keyIndex);
+
+ /**
+ * Tests whether shift is pressed.
+ */
+ bool IsShifted(void);
+
+public:
+ SCA_KeyboardSensor(class SCA_KeyboardManager* keybdmgr,
+ short int hotkey,
+ short int qual,
+ short int qual2,
+ bool bAllKeys,
+ const STR_String& targetProp,
+ const STR_String& toggleProp,
+ SCA_IObject* gameobj,
+ PyTypeObject* T=&Type );
+ virtual ~SCA_KeyboardSensor();
+ virtual CValue* GetReplica();
+
+ short int GetHotkey();
+ virtual bool Evaluate(CValue* event);
+ virtual bool IsPositiveTrigger();
+ bool TriggerOnAllKeys();
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(char *attr);
+
+
+ PyObject* PySetAllMode(PyObject* self,
+ PyObject* args,
+ PyObject* kwds);
+ static PyObject* sPySetAllMode(PyObject* self,
+ PyObject* args,
+ PyObject* kwds);
+
+ /** 1. GetKey : check which key this sensor looks at */
+ KX_PYMETHOD_DOC(SCA_KeyboardSensor,GetKey);
+ /** 2. SetKey: change the key to look at */
+ KX_PYMETHOD_DOC(SCA_KeyboardSensor,SetKey);
+ /** 3. GetHold1 : set the first bucky bit */
+ KX_PYMETHOD_DOC(SCA_KeyboardSensor,GetHold1);
+ /** 4. SetHold1: change the first bucky bit */
+ KX_PYMETHOD_DOC(SCA_KeyboardSensor,SetHold1);
+ /** 5. GetHold2 : set the second bucky bit */
+ KX_PYMETHOD_DOC(SCA_KeyboardSensor,GetHold2);
+ /** 6. SetHold2: change the second bucky bit */
+ KX_PYMETHOD_DOC(SCA_KeyboardSensor,SetHold2);
+ /** 9. GetPressedKeys: */
+ KX_PYMETHOD_DOC(SCA_KeyboardSensor,GetPressedKeys);
+ /** 9. GetCurrrentlyPressedKeys: */
+ KX_PYMETHOD_DOC(SCA_KeyboardSensor,GetCurrentlyPressedKeys);
+};
+
+#endif //__KX_KEYBOARDSENSOR
diff --git a/source/gameengine/GameLogic/SCA_LogicManager.cpp b/source/gameengine/GameLogic/SCA_LogicManager.cpp
new file mode 100644
index 00000000000..a29d6d19729
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_LogicManager.cpp
@@ -0,0 +1,461 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * Regulates the top-level logic behaviour for one scene.
+ */
+#include "Value.h"
+#include "SCA_LogicManager.h"
+
+#include "SCA_ISensor.h"
+#include "SCA_IController.h"
+#include "SCA_IActuator.h"
+#include "SCA_EventManager.h"
+
+#include <set>
+
+SCA_LogicManager::SCA_LogicManager()
+{
+}
+
+
+
+SCA_LogicManager::~SCA_LogicManager()
+{
+ for (vector<SCA_EventManager*>::iterator it = m_eventmanagers.begin();!(it==m_eventmanagers.end());it++)
+ {
+ delete (*it);
+ }
+ m_eventmanagers.clear();
+ m_sensorcontrollermapje.clear();
+
+ int numgameobj = m_mapStringToGameObjects.size();
+ for (int i = 0; i < numgameobj; i++)
+ {
+ CValue** gameobjptr = m_mapStringToGameObjects.at(i);
+ assert(gameobjptr);
+ if (gameobjptr)
+ (*gameobjptr)->Release();
+
+ }
+
+ /*for (int i=0;i<m_sensorcontrollermap.size();i++)
+ {
+ vector<SCA_IController*>* controllerarray = *(m_sensorcontrollermap[i]);
+ delete controllerarray;
+ }
+ */
+}
+
+
+/*
+// this kind of fixes bug 398 but breakes games, so better leave it out for now.
+// a removed object's gameobject (and logicbricks and stuff) didn't get released
+// because it was still in the m_mapStringToGameObjects map.
+void SCA_LogicManager::RemoveGameObject(const STR_String& gameobjname)
+{
+ int numgameobj = m_mapStringToGameObjects.size();
+ for (int i = 0; i < numgameobj; i++)
+ {
+ CValue** gameobjptr = m_mapStringToGameObjects.at(i);
+ assert(gameobjptr);
+
+ if (gameobjptr)
+ {
+ if ((*gameobjptr)->GetName() == gameobjname)
+ (*gameobjptr)->Release();
+ }
+ }
+
+ m_mapStringToGameObjects.remove(gameobjname);
+}
+*/
+
+
+void SCA_LogicManager::RegisterEventManager(SCA_EventManager* eventmgr)
+{
+ m_eventmanagers.push_back(eventmgr);
+}
+
+
+
+void SCA_LogicManager::RegisterGameObjectName(const STR_String& gameobjname,
+ CValue* gameobj)
+{
+ STR_HashedString mn = gameobjname;
+ m_mapStringToGameObjects.insert(mn,gameobj);
+}
+
+
+
+CValue* SCA_LogicManager::GetGameObjectByName(const STR_String& gameobjname)
+{
+ STR_HashedString mn = "OB"+gameobjname;
+ CValue** gameptr = m_mapStringToGameObjects[mn];
+
+ if (gameptr)
+ return *gameptr;
+
+ return NULL;
+}
+
+
+
+void SCA_LogicManager::RemoveSensor(SCA_ISensor* sensor)
+{
+ m_sensorcontrollermapje.erase(sensor);
+
+ for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin();
+ !(ie==m_eventmanagers.end());ie++)
+ {
+ (*ie)->RemoveSensor(sensor);
+ }
+}
+
+
+
+void SCA_LogicManager::RemoveDestroyedActuator(SCA_IActuator* actuator)
+{
+
+ m_removedActuators.push_back(SmartActuatorPtr(actuator,0));
+ // take care that no controller can use this actuator again !
+
+ std::map<SCA_ISensor*,controllerlist>::const_iterator sit;
+ for (sit = m_sensorcontrollermapje.begin();!(sit==m_sensorcontrollermapje.end());++sit)
+ {
+ controllerlist contlist = (*sit).second;
+ for (list<SCA_IController*>::const_iterator c= contlist.begin();!(c==contlist.end());c++)
+ {
+ (*c)->UnlinkActuator(actuator);
+ }
+ }
+}
+
+
+
+void SCA_LogicManager::RegisterToSensor(SCA_IController* controller,SCA_ISensor* sensor)
+{
+ m_sensorcontrollermapje[sensor].push_back(controller);
+ controller->LinkToSensor(sensor);
+}
+
+
+
+void SCA_LogicManager::RegisterToActuator(SCA_IController* controller,SCA_IActuator* actua)
+{
+ controller->LinkToActuator(actua);
+}
+
+
+
+void SCA_LogicManager::BeginFrame(double curtime,double deltatime)
+{
+ for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin();
+ !(ie==m_eventmanagers.end());ie++)
+ {
+ (*ie)->NextFrame(curtime,deltatime);
+ }
+
+ // for this frame, look up for activated sensors, and build the collection of triggered controllers
+ int numsensors = this->m_activatedsensors.size();
+
+ set<SmartControllerPtr> triggeredControllerSet;
+
+ for (vector<SCA_ISensor*>::const_iterator is=m_activatedsensors.begin();
+ !(is==m_activatedsensors.end());is++)
+ {
+ SCA_ISensor* sensor = *is;
+ controllerlist contlist = m_sensorcontrollermapje[sensor];
+ for (list<SCA_IController*>::const_iterator c= contlist.begin();
+ !(c==contlist.end());c++)
+ {
+ SCA_IController* contr = *c;//controllerarray->at(c);
+ triggeredControllerSet.insert(SmartControllerPtr(contr,0));
+ }
+ //sensor->SetActive(false);
+ }
+
+
+ int numtriggered = triggeredControllerSet.size();
+ for (set<SmartControllerPtr>::iterator tit=triggeredControllerSet.begin();
+ !(tit==triggeredControllerSet.end());tit++)
+ {
+ (*tit)->Trigger(this);
+ }
+ triggeredControllerSet.clear();
+}
+
+
+
+void SCA_LogicManager::UpdateFrame(double curtime,double deltatime)
+{
+ vector<SmartActuatorPtr>::iterator ra;
+ for (ra = m_removedActuators.begin();
+ !(ra == m_removedActuators.end());ra++)
+ {
+ m_activeActuators.erase(*ra);
+ (*ra)->SetActive(false);
+ }
+ m_removedActuators.clear();
+
+ for (set<SmartActuatorPtr>::iterator ia = m_activeActuators.begin();!(ia==m_activeActuators.end());ia++)
+ {
+ //SCA_IActuator* actua = *ia;
+ if (!(*ia)->Update(curtime,deltatime))
+ {
+ //*ia = m_activeactuators.back();
+ m_removedActuators.push_back(*ia);
+
+ (*ia)->SetActive(false);
+ //m_activeactuators.pop_back();
+ }
+ }
+
+ for ( ra = m_removedActuators.begin();
+ !(ra == m_removedActuators.end());ra++)
+ {
+ m_activeActuators.erase(*ra);
+ (*ra)->SetActive(false);
+ }
+ m_removedActuators.clear();
+}
+
+
+
+void* SCA_LogicManager::GetActionByName (const STR_String& actname)
+{
+ STR_HashedString an = "AC"+actname;
+ void** actptr = m_mapStringToActions[an];
+
+ if (actptr)
+ return *actptr;
+
+ return NULL;
+}
+
+
+
+void* SCA_LogicManager::GetMeshByName(const STR_String& meshname)
+{
+ STR_HashedString mn = "ME"+meshname;
+ void** meshptr = m_mapStringToMeshes[mn];
+
+ if (meshptr)
+ return *meshptr;
+
+ return NULL;
+}
+
+
+
+void SCA_LogicManager::RegisterMeshName(const STR_String& meshname,void* mesh)
+{
+ STR_HashedString mn = meshname;
+ m_mapStringToMeshes.insert(mn,mesh);
+}
+
+
+
+void SCA_LogicManager::RegisterActionName(const STR_String& actname,void* action)
+{
+ STR_HashedString an = actname;
+ m_mapStringToActions.insert(an, action);
+}
+
+
+
+void SCA_LogicManager::EndFrame()
+{
+ for (vector<SCA_ISensor*>::const_iterator is=m_activatedsensors.begin();
+ !(is==m_activatedsensors.end());is++)
+ {
+ SCA_ISensor* sensor = *is;
+ sensor->SetActive(false);
+ }
+ m_activatedsensors.clear();
+
+ for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin();
+ !(ie==m_eventmanagers.end());ie++)
+ {
+ (*ie)->EndFrame();
+ }
+
+
+}
+
+
+
+void SCA_LogicManager::AddActivatedSensor(SCA_ISensor* sensor)
+{
+ // each frame, only add sensor once, and to avoid a seek, or bloated container
+ // hold a flag in each sensor, with the 'framenr'
+ if (!sensor->IsActive())
+ {
+ sensor->SetActive(true);
+ m_activatedsensors.push_back(sensor);
+ }
+}
+
+
+
+void SCA_LogicManager::AddActiveActuator(SCA_IActuator* actua,CValue* event)
+{
+ if (!actua->IsActive())
+ {
+ actua->SetActive(true);
+ m_activeActuators.insert(SmartActuatorPtr(actua,0));
+ }
+ actua->AddEvent(event->AddRef());
+}
+
+
+
+SCA_EventManager* SCA_LogicManager::FindEventManager(int eventmgrtype)
+{
+ // find an eventmanager of a certain type
+ SCA_EventManager* eventmgr = NULL;
+
+ for (vector<SCA_EventManager*>::const_iterator i=
+ m_eventmanagers.begin();!(i==m_eventmanagers.end());i++)
+ {
+ SCA_EventManager* emgr = *i;
+ if (emgr->GetType() == eventmgrtype)
+ {
+ eventmgr = emgr;
+ break;
+ }
+ }
+ return eventmgr;
+}
+
+
+
+SmartActuatorPtr::SmartActuatorPtr(const SmartActuatorPtr& other)
+{
+ this->m_actuator = other.m_actuator;
+ this->m_actuator->AddRef();
+}
+
+
+
+SmartActuatorPtr::SmartActuatorPtr(SCA_IActuator* actua,int dummy)
+: m_actuator(actua)
+{
+ actua->AddRef();
+}
+
+
+
+SmartActuatorPtr::~SmartActuatorPtr()
+{
+ m_actuator->Release();
+}
+
+
+
+bool SmartActuatorPtr::operator <(const SmartActuatorPtr& other) const
+{
+
+ return m_actuator->LessComparedTo(*other);
+}
+
+
+
+bool SmartActuatorPtr::operator ==(const SmartActuatorPtr& other) const
+{
+ bool result2 = other->LessComparedTo(m_actuator);
+ return (m_actuator->LessComparedTo(*other) && result2);
+}
+
+
+
+SCA_IActuator* SmartActuatorPtr::operator->() const
+{
+ return m_actuator;
+}
+
+
+
+SCA_IActuator* SmartActuatorPtr::operator*() const
+{
+ return m_actuator;
+}
+
+
+
+SmartControllerPtr::SmartControllerPtr(const SmartControllerPtr& copy)
+{
+ this->m_controller = copy.m_controller;
+ this->m_controller->AddRef();
+}
+
+
+
+SmartControllerPtr::SmartControllerPtr(SCA_IController* contr,int dummy)
+: m_controller(contr)
+{
+ m_controller->AddRef();
+}
+
+
+
+SmartControllerPtr::~SmartControllerPtr()
+{
+ m_controller->Release();
+}
+
+
+
+bool SmartControllerPtr::operator <(const SmartControllerPtr& other) const
+{
+ return m_controller->LessComparedTo(*other);
+}
+
+
+
+bool SmartControllerPtr::operator ==(const SmartControllerPtr& other) const
+{
+ return (m_controller->LessComparedTo(*other) && other->LessComparedTo(m_controller));
+}
+
+
+
+SCA_IController* SmartControllerPtr::operator->() const
+{
+ return m_controller;
+}
+
+
+
+SCA_IController* SmartControllerPtr::operator*() const
+{
+ return m_controller;
+}
+
+
diff --git a/source/gameengine/GameLogic/SCA_LogicManager.h b/source/gameengine/GameLogic/SCA_LogicManager.h
new file mode 100644
index 00000000000..f79b19a0dbf
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_LogicManager.h
@@ -0,0 +1,154 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * Regulates the top-level logic behaviour for one scene.
+ */
+#ifndef __KX_LOGICMANAGER
+#define __KX_LOGICMANAGER
+
+#ifdef WIN32
+#pragma warning (disable:4786)
+#endif
+
+#include <vector>
+//#include "GEN_Map.h"
+#include <set>
+#include <map>
+#include <list>
+
+#include "GEN_Map.h"
+#include "STR_HashedString.h"
+#include "Value.h"
+
+using namespace std;
+typedef list<class SCA_IController*> controllerlist;
+
+/**
+ * This manager handles sensor, controllers and actuators.
+ * logic executes each frame the following way:
+ * find triggering sensors
+ * build list of controllers that are triggered by these triggering sensors
+ * process all triggered controllers
+ * during this phase actuators can be added to the active actuator list
+ * process all active actuators
+ * clear triggering sensors
+ * clear triggered controllers
+ * (actuators may be active during a longer timeframe)
+*/
+
+#include "SCA_ILogicBrick.h"
+
+// todo: make this into a template, but first I want to think about what exactly to put in
+class SmartActuatorPtr
+{
+ SCA_IActuator* m_actuator;
+public:
+ SmartActuatorPtr(SCA_IActuator* actua,int dummy);
+ SmartActuatorPtr(const SmartActuatorPtr& other);
+ virtual ~SmartActuatorPtr();
+ bool operator <(const SmartActuatorPtr& other) const;
+ bool operator ==(const SmartActuatorPtr& other) const;
+ SCA_IActuator* operator->() const;
+ SCA_IActuator* operator*() const;
+
+};
+
+class SmartControllerPtr
+{
+ SCA_IController* m_controller;
+public:
+ SmartControllerPtr(const SmartControllerPtr& copy);
+ SmartControllerPtr(SCA_IController* contr,int dummy);
+ virtual ~SmartControllerPtr();
+ bool operator <(const SmartControllerPtr& other) const;
+ bool operator ==(const SmartControllerPtr& other) const;
+ SCA_IController* operator->() const;
+ SCA_IController* operator*() const;
+
+};
+
+
+
+class SCA_LogicManager
+{
+ vector<class SCA_EventManager*> m_eventmanagers;
+
+ vector<class SCA_ISensor*> m_activatedsensors;
+ set<class SmartActuatorPtr> m_activeActuators;
+
+ map<SCA_ISensor*,controllerlist > m_sensorcontrollermapje;
+
+ // need to find better way for this
+ // also known as FactoryManager...
+ GEN_Map<STR_HashedString,CValue*> m_mapStringToGameObjects;
+ GEN_Map<STR_HashedString,void*> m_mapStringToMeshes;
+ GEN_Map<STR_HashedString,void*> m_mapStringToActions;
+
+ vector<SmartActuatorPtr> m_removedActuators;
+
+public:
+ SCA_LogicManager();
+ virtual ~SCA_LogicManager();
+ //void SetKeyboardManager(SCA_KeyboardManager* keyboardmgr) { m_keyboardmgr=keyboardmgr;}
+ void RegisterEventManager(SCA_EventManager* eventmgr);
+ void RegisterToSensor(SCA_IController* controller,
+ class SCA_ISensor* sensor);
+ void RegisterToActuator(SCA_IController* controller,
+ class SCA_IActuator* actuator);
+
+ void BeginFrame(double curtime,double deltatime);
+ void UpdateFrame(double curtime,double deltatime);
+ void EndFrame();
+ void AddActivatedSensor(SCA_ISensor* sensor);
+ void AddActiveActuator(SCA_IActuator* sensor,class CValue* event);
+ SCA_EventManager* FindEventManager(int eventmgrtype);
+
+ void RemoveGameObject(const STR_String& gameobjname);
+
+ /**
+ * remove Logic Bricks from the running logicmanager
+ */
+ void RemoveSensor(SCA_ISensor* sensor);
+ void RemoveController(SCA_IController* controller);
+ void RemoveDestroyedActuator(SCA_IActuator* actuator);
+
+
+ // for the scripting... needs a FactoryManager later (if we would have time... ;)
+ void RegisterMeshName(const STR_String& meshname,void* mesh);
+ void RegisterActionName(const STR_String& actname,void* action);
+
+ void* GetActionByName (const STR_String& actname);
+ void* GetMeshByName(const STR_String& meshname);
+
+ void RegisterGameObjectName(const STR_String& gameobjname,CValue* gameobj);
+ class CValue* GetGameObjectByName(const STR_String& gameobjname);
+};
+
+#endif //__KX_LOGICMANAGER
diff --git a/source/gameengine/GameLogic/SCA_MouseManager.cpp b/source/gameengine/GameLogic/SCA_MouseManager.cpp
new file mode 100644
index 00000000000..580c77ee61f
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_MouseManager.cpp
@@ -0,0 +1,116 @@
+/**
+ * Manager for mouse events
+ *
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifdef WIN32
+// This warning tells us about truncation of __long__ stl-generated names.
+// It can occasionally cause DevStudio to have internal compiler warnings.
+#pragma warning( disable : 4786 )
+#endif
+
+#include "BoolValue.h"
+#include "SCA_MouseManager.h"
+#include "SCA_MouseSensor.h"
+#include "IntValue.h"
+
+
+SCA_MouseManager::SCA_MouseManager(SCA_LogicManager* logicmgr,
+ SCA_IInputDevice* mousedev)
+ : SCA_EventManager(MOUSE_EVENTMGR),
+ m_logicmanager(logicmgr),
+ m_mousedevice (mousedev)
+{
+ m_xpos = 0;
+ m_ypos = 0;
+}
+
+
+
+SCA_MouseManager::~SCA_MouseManager()
+{
+}
+
+
+
+SCA_IInputDevice* SCA_MouseManager::GetInputDevice()
+{
+ return m_mousedevice;
+}
+
+
+
+void SCA_MouseManager::NextFrame(double curtime,double deltatime)
+{
+ if (m_mousedevice)
+ {
+ for (int i = 0; i < m_sensors.size(); i++)
+ {
+ SCA_MouseSensor* mousesensor = (SCA_MouseSensor*) m_sensors[i];
+ // (0,0) is the Upper Left corner in our local window
+ // coordinates
+ if (!mousesensor->IsSuspended())
+ {
+ const SCA_InputEvent& event =
+ m_mousedevice->GetEventValue(SCA_IInputDevice::KX_MOUSEX);
+ int mx = event.m_eventval;
+ const SCA_InputEvent& event2 =
+ m_mousedevice->GetEventValue(SCA_IInputDevice::KX_MOUSEY);
+ int my = event2.m_eventval;
+
+ mousesensor->setX(mx);
+ mousesensor->setY(my);
+
+ mousesensor->Activate(m_logicmanager,NULL);
+ }
+ }
+ }
+}
+
+
+
+void SCA_MouseManager::RegisterSensor(SCA_ISensor* keysensor)
+{
+ m_sensors.push_back(keysensor);
+}
+
+
+
+bool SCA_MouseManager::IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)
+{
+ /* We should guard for non-mouse events maybe? A rather silly side */
+ /* effect here is that position-change events are considered presses as */
+ /* well. */
+
+ return m_mousedevice->IsPressed(inputcode);
+}
diff --git a/source/gameengine/GameLogic/SCA_MouseManager.h b/source/gameengine/GameLogic/SCA_MouseManager.h
new file mode 100644
index 00000000000..9f26a706c17
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_MouseManager.h
@@ -0,0 +1,72 @@
+/**
+ * Manager for mouse events
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+
+#ifndef __KX_MOUSEMANAGER
+#define __KX_MOUSEMANAGER
+
+
+#include "SCA_EventManager.h"
+
+#include <vector>
+
+using namespace std;
+
+#include "SCA_IInputDevice.h"
+
+
+class SCA_MouseManager : public SCA_EventManager
+{
+
+ class SCA_IInputDevice* m_mousedevice;
+ class SCA_LogicManager* m_logicmanager;
+
+ unsigned short m_xpos; // Cached location of the mouse pointer
+ unsigned short m_ypos;
+
+public:
+ SCA_MouseManager(class SCA_LogicManager* logicmgr,class SCA_IInputDevice* mousedev);
+ virtual ~SCA_MouseManager();
+
+ /**
+ * Checks whether a mouse button is depressed. Ignores requests on non-
+ * mouse related evenst. Can also flag mouse movement.
+ */
+ bool IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode);
+ virtual void NextFrame(double curtime,double deltatime);
+ virtual void RegisterSensor(class SCA_ISensor* sensor);
+ SCA_IInputDevice* GetInputDevice();
+};
+
+#endif //__KX_MOUSEMANAGER
diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.cpp b/source/gameengine/GameLogic/SCA_MouseSensor.cpp
new file mode 100644
index 00000000000..f21e4c1b07e
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_MouseSensor.cpp
@@ -0,0 +1,273 @@
+/**
+ * Sensor for mouse input
+ *
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "SCA_MouseSensor.h"
+#include "SCA_EventManager.h"
+#include "SCA_MouseManager.h"
+#include "SCA_LogicManager.h"
+#include "SCA_IInputDevice.h"
+#include "ConstExpr.h"
+#include <iostream>
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_MouseSensor::SCA_MouseSensor(SCA_MouseManager* eventmgr,
+ int startx,int starty,
+ short int mousemode,
+ SCA_IObject* gameobj,
+ PyTypeObject* T)
+ : SCA_ISensor(gameobj,eventmgr, T),
+ m_pMouseMgr(eventmgr),
+ m_x(startx),
+ m_y(starty)
+{
+ m_mousemode = mousemode;
+ m_triggermode = true;
+ m_val = 0; /* stores the latest attribute */
+
+ switch (m_mousemode) {
+ case KX_MOUSESENSORMODE_LEFTBUTTON:
+ m_hotkey = SCA_IInputDevice::KX_LEFTMOUSE;
+ break;
+ case KX_MOUSESENSORMODE_MIDDLEBUTTON:
+ m_hotkey = SCA_IInputDevice::KX_MIDDLEMOUSE;
+ break;
+ case KX_MOUSESENSORMODE_RIGHTBUTTON:
+ m_hotkey = SCA_IInputDevice::KX_RIGHTMOUSE;
+ break;
+ default:
+ ; /* ignore, no hotkey */
+ }
+
+}
+
+SCA_MouseSensor::~SCA_MouseSensor()
+{
+ /* Nothing to be done here. */
+}
+
+
+
+CValue* SCA_MouseSensor::GetReplica()
+{
+ CValue* replica = new SCA_MouseSensor(*this);
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+bool SCA_MouseSensor::IsPositiveTrigger()
+{
+ bool result = (m_val != 0);
+ if (m_invert)
+ result = !result;
+
+ return result;
+}
+
+
+
+short int SCA_MouseSensor::GetModeKey()
+{
+ return m_mousemode;
+}
+
+
+
+SCA_IInputDevice::KX_EnumInputs SCA_MouseSensor::GetHotKey()
+{
+ return m_hotkey;
+}
+
+
+
+bool SCA_MouseSensor::Evaluate(CValue* event)
+{
+ bool result = false;
+ SCA_IInputDevice* mousedev = m_pMouseMgr->GetInputDevice();
+
+
+
+// SCA_ILogicBrick::RegisterEvent(event);
+// if (m_mousemode == KX_MOUSESENSORMODE_MOVEMENT) cout << "\nChecking for movement...";
+//CValue* val = event->GetProperty("val");
+
+ /* both MOUSEX and MOUSEY. Treat all of these as key-presses. */
+ /* So, treat KX_MOUSESENSORMODE_POSITION as */
+ /* KX_MOUSESENSORMODE_POSITIONX || KX_MOUSESENSORMODE_POSITIONY */
+
+ switch (m_mousemode) {
+ case KX_MOUSESENSORMODE_LEFTBUTTON:
+ case KX_MOUSESENSORMODE_MIDDLEBUTTON:
+ case KX_MOUSESENSORMODE_RIGHTBUTTON:
+ {
+ const SCA_InputEvent& event = mousedev->GetEventValue(m_hotkey);
+ if (event.m_status == SCA_InputEvent::KX_JUSTACTIVATED)
+ {
+ m_val = 1;
+ result = true;
+ } else
+ {
+ if (event.m_status == SCA_InputEvent::KX_JUSTRELEASED)
+ {
+ m_val = 0;
+ result = true;
+ }
+ }
+ break;
+ }
+ case KX_MOUSESENSORMODE_MOVEMENT:
+
+ {
+ const SCA_InputEvent& eventX = mousedev->GetEventValue(SCA_IInputDevice::KX_MOUSEX);
+ const SCA_InputEvent& eventY = mousedev->GetEventValue(SCA_IInputDevice::KX_MOUSEY);
+
+ if (eventX.m_status == SCA_InputEvent::KX_JUSTACTIVATED ||
+ eventY.m_status == SCA_InputEvent::KX_JUSTACTIVATED ||
+ eventX.m_status == SCA_InputEvent::KX_ACTIVE ||
+ eventY.m_status == SCA_InputEvent::KX_ACTIVE)
+
+ {
+ m_val = 1;
+ result = true;
+ } else
+ {
+ if (eventX.m_status == SCA_InputEvent::KX_JUSTRELEASED ||
+ eventY.m_status == SCA_InputEvent::KX_JUSTRELEASED )
+ {
+ m_val = 0;
+ result = true;
+ }
+ }
+ break;
+ }
+ default:
+ ; /* error */
+ }
+
+ return result;
+}
+
+void SCA_MouseSensor::setX(short x)
+{
+ m_x = x;
+}
+
+void SCA_MouseSensor::setY(short y)
+{
+ m_y = y;
+}
+
+bool SCA_MouseSensor::isValid(SCA_MouseSensor::KX_MOUSESENSORMODE m)
+{
+ bool res = false;
+
+ res = ((m > KX_MOUSESENSORMODE_NODEF) && (m < KX_MOUSESENSORMODE_MAX));
+
+ return res;
+}
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_MouseSensor::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_MouseSensor",
+ sizeof(SCA_MouseSensor),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_MouseSensor::Parents[] = {
+ &SCA_MouseSensor::Type,
+ &SCA_ISensor::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef SCA_MouseSensor::Methods[] = {
+ {"getXPosition", (PyCFunction) SCA_MouseSensor::sPyGetXPosition, METH_VARARGS, GetXPosition_doc},
+ {"getYPosition", (PyCFunction) SCA_MouseSensor::sPyGetYPosition, METH_VARARGS, GetYPosition_doc},
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* SCA_MouseSensor::_getattr(char* attr) {
+ _getattr_up(SCA_ISensor);
+}
+
+/* get x position ---------------------------------------------------------- */
+char SCA_MouseSensor::GetXPosition_doc[] =
+"getXPosition\n"
+"\tReturns the x-coordinate of the mouse sensor, in frame coordinates.\n"
+"\tThe lower-left corner is the origin. The coordinate is given in\n"
+"\tpixels\n";
+PyObject* SCA_MouseSensor::PyGetXPosition(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ return PyInt_FromLong(m_x);
+}
+
+/* get y position ---------------------------------------------------------- */
+char SCA_MouseSensor::GetYPosition_doc[] =
+"getYPosition\n"
+"\tReturns the y-coordinate of the mouse sensor, in frame coordinates.\n"
+"\tThe lower-left corner is the origin. The coordinate is given in\n"
+"\tpixels\n";
+PyObject* SCA_MouseSensor::PyGetYPosition(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ return PyInt_FromLong(m_y);
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.h b/source/gameengine/GameLogic/SCA_MouseSensor.h
new file mode 100644
index 00000000000..dd6230f421c
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_MouseSensor.h
@@ -0,0 +1,120 @@
+/**
+ * Senses mouse events
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_MOUSESENSOR
+#define __KX_MOUSESENSOR
+
+#include "SCA_ISensor.h"
+#include "BoolValue.h"
+#include "SCA_IInputDevice.h"
+
+class SCA_MouseSensor : public SCA_ISensor
+{
+ Py_Header;
+ class SCA_MouseManager* m_pMouseMgr;
+
+ /**
+ * Use SCA_IInputDevice values to encode the mouse mode for now.
+ */
+ short int m_mousemode;
+ /**
+ * Triggermode true means all mouse events trigger. Useful mainly
+ * for button presses.
+ */
+ bool m_triggermode;
+ /**
+ * Remember the last state update
+ */
+ int m_val;
+
+ SCA_IInputDevice::KX_EnumInputs m_hotkey;
+
+ /**
+ * valid x coordinate
+ */
+ short m_x;
+
+ /**
+ * valid y coordinate
+ */
+ short m_y;
+
+ public:
+ /**
+ * Allowable modes for the trigger status of the mouse sensor.
+ */
+ enum KX_MOUSESENSORMODE {
+ KX_MOUSESENSORMODE_NODEF = 0,
+ KX_MOUSESENSORMODE_LEFTBUTTON,
+ KX_MOUSESENSORMODE_MIDDLEBUTTON,
+ KX_MOUSESENSORMODE_RIGHTBUTTON,
+ KX_MOUSESENSORMODE_POSITION,
+ KX_MOUSESENSORMODE_POSITIONX,
+ KX_MOUSESENSORMODE_POSITIONY,
+ KX_MOUSESENSORMODE_MOVEMENT,
+ KX_MOUSESENSORMODE_MAX
+ };
+
+ bool isValid(KX_MOUSESENSORMODE);
+
+ SCA_MouseSensor(class SCA_MouseManager* keybdmgr,
+ int startx,int starty,
+ short int mousemode,
+ SCA_IObject* gameobj,
+ PyTypeObject* T=&Type );
+
+ virtual ~SCA_MouseSensor();
+ virtual CValue* GetReplica();
+ virtual bool Evaluate(CValue* event);
+
+ virtual bool IsPositiveTrigger();
+ short int GetModeKey();
+ SCA_IInputDevice::KX_EnumInputs GetHotKey();
+ void setX(short x);
+ void setY(short y);
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(char *attr);
+
+ /* read x-coordinate */
+ KX_PYMETHOD_DOC(SCA_MouseSensor,GetXPosition);
+ /* read y-coordinate */
+ KX_PYMETHOD_DOC(SCA_MouseSensor,GetYPosition);
+
+};
+
+#endif //__KX_MOUSESENSOR
diff --git a/source/gameengine/GameLogic/SCA_ORController.cpp b/source/gameengine/GameLogic/SCA_ORController.cpp
new file mode 100644
index 00000000000..966884da809
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_ORController.cpp
@@ -0,0 +1,135 @@
+/**
+ * 'Or' together all inputs
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "SCA_ORController.h"
+#include "SCA_ISensor.h"
+#include "SCA_LogicManager.h"
+#include "BoolValue.h"
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_ORController::SCA_ORController(SCA_IObject* gameobj,
+ PyTypeObject* T)
+ :SCA_IController(gameobj, T)
+{
+}
+
+
+
+SCA_ORController::~SCA_ORController()
+{
+}
+
+
+
+CValue* SCA_ORController::GetReplica()
+{
+ CValue* replica = new SCA_ORController(*this);
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+void SCA_ORController::Trigger(SCA_LogicManager* logicmgr)
+{
+
+ bool sensorresult = false;
+ SCA_ISensor* sensor;
+
+ vector<SCA_ISensor*>::const_iterator is=m_linkedsensors.begin();
+ while ( (!sensorresult) && (!(is==m_linkedsensors.end())) )
+ {
+ sensor = *is;
+ if (sensor->IsPositiveTrigger()) sensorresult = true;
+ is++;
+ }
+
+ CValue* newevent = new CBoolValue(sensorresult);
+
+ for (vector<SCA_IActuator*>::const_iterator i=m_linkedactuators.begin();
+ !(i==m_linkedactuators.end());i++)
+ {
+ SCA_IActuator* actua = *i;//m_linkedactuators.at(i);
+ logicmgr->AddActiveActuator(actua,newevent);
+ }
+
+
+ newevent->Release();
+}
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_ORController::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_ORController",
+ sizeof(SCA_ORController),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_ORController::Parents[] = {
+ &SCA_ORController::Type,
+ &SCA_IController::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef SCA_ORController::Methods[] = {
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* SCA_ORController::_getattr(char* attr) {
+ _getattr_up(SCA_IController);
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_ORController.h b/source/gameengine/GameLogic/SCA_ORController.h
new file mode 100644
index 00000000000..89dab8731ca
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_ORController.h
@@ -0,0 +1,58 @@
+/**
+ * SCA_ORController.h
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_ORCONTROLLER
+#define __KX_ORCONTROLLER
+
+#include "SCA_IController.h"
+
+class SCA_ORController : public SCA_IController
+{
+ Py_Header;
+ //virtual void Trigger(class SCA_LogicManager* logicmgr);
+public:
+ SCA_ORController(SCA_IObject* gameobj, PyTypeObject* T=&Type);
+
+ virtual ~SCA_ORController();
+ virtual CValue* GetReplica();
+ virtual void Trigger(SCA_LogicManager* logicmgr);
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(char *attr);
+};
+
+#endif //__KX_ORCONTROLLER
diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp
new file mode 100644
index 00000000000..893db892ef0
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp
@@ -0,0 +1,285 @@
+/**
+ * Assign, change, copy properties
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "SCA_PropertyActuator.h"
+#include "InputParser.h"
+
+#include "Operator2Expr.h"
+#include "ConstExpr.h"
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_PropertyActuator::SCA_PropertyActuator(SCA_IObject* gameobj,CValue* sourceObj,const STR_String& propname,const STR_String& expr,int acttype,PyTypeObject* T )
+: SCA_IActuator(gameobj,T),
+m_propname(propname),
+m_exprtxt(expr),
+m_type(acttype),
+m_sourceObj(sourceObj)
+{
+}
+
+SCA_PropertyActuator::~SCA_PropertyActuator()
+{
+}
+
+bool SCA_PropertyActuator::Update(double curtime,double deltatime)
+{
+ bool result = false;
+
+ bool bNegativeEvent = IsNegativeEvent();
+ RemoveAllEvents();
+
+
+ if (bNegativeEvent)
+ return false; // do nothing on negative events
+
+
+ CValue* propowner = GetParent();
+ CParser parser;
+ parser.SetContext( propowner->AddRef());
+
+ CExpression* userexpr = parser.ProcessText(m_exprtxt);
+ if (userexpr)
+ {
+
+
+ switch (m_type)
+ {
+
+ case KX_ACT_PROP_ASSIGN:
+ {
+
+ CValue* newval = userexpr->Calculate();
+ CValue* oldprop = propowner->GetProperty(m_propname);
+ if (oldprop)
+ {
+ oldprop->SetValue(newval);
+ newval->Release();
+ } else
+ {
+ propowner->SetProperty(m_propname,newval);
+ }
+
+ break;
+ }
+ case KX_ACT_PROP_ADD:
+ {
+ CValue* oldprop = propowner->GetProperty(m_propname);
+ if (oldprop)
+ {
+ int waarde = (int)oldprop->GetNumber();
+ CExpression* expr = new COperator2Expr(VALUE_ADD_OPERATOR,new CConstExpr(oldprop->AddRef()),
+ userexpr->AddRef());
+
+ CValue* newprop = expr->Calculate();
+ oldprop->SetValue(newprop);
+ newprop->Release();
+ expr->Release();
+
+ }
+
+ break;
+ }
+ case KX_ACT_PROP_COPY:
+ {
+ if (m_sourceObj)
+ {
+ CValue* copyprop = m_sourceObj->GetProperty(m_exprtxt);
+ if (copyprop)
+ {
+ GetParent()->SetProperty(
+ m_propname,
+ copyprop->GetReplica());
+
+ }
+ }
+ break;
+ }
+ default:
+ {
+
+ }
+ }
+
+ userexpr->Release();
+ }
+
+ return result;
+}
+
+ bool
+
+SCA_PropertyActuator::
+
+isValid(
+
+ SCA_PropertyActuator::KX_ACT_PROP_MODE mode
+
+){
+ bool res = false;
+ res = ((mode > KX_ACT_PROP_NODEF) && (mode < KX_ACT_PROP_MAX));
+ return res;
+}
+
+
+ CValue*
+
+SCA_PropertyActuator::
+
+GetReplica() {
+
+ SCA_PropertyActuator* replica = new SCA_PropertyActuator(*this);
+
+ replica->ProcessReplica();
+
+ // this will copy properties and so on...
+
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+
+};
+
+
+
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_PropertyActuator::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_PropertyActuator",
+ sizeof(SCA_PropertyActuator),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_PropertyActuator::Parents[] = {
+ &SCA_PropertyActuator::Type,
+ &SCA_IActuator::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef SCA_PropertyActuator::Methods[] = {
+ {"setProperty", (PyCFunction) SCA_PropertyActuator::sPySetProperty, METH_VARARGS, SetProperty_doc},
+ {"getProperty", (PyCFunction) SCA_PropertyActuator::sPyGetProperty, METH_VARARGS, GetProperty_doc},
+ {"setValue", (PyCFunction) SCA_PropertyActuator::sPySetValue, METH_VARARGS, SetValue_doc},
+ {"getValue", (PyCFunction) SCA_PropertyActuator::sPyGetValue, METH_VARARGS, GetValue_doc},
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* SCA_PropertyActuator::_getattr(char* attr) {
+ _getattr_up(SCA_IActuator);
+}
+
+/* 1. setProperty */
+char SCA_PropertyActuator::SetProperty_doc[] =
+"setProperty(name)\n"
+"\t- name: string\n"
+"\tSet the property on which to operate. If there is no property\n"
+"\tof this name, the call is ignored.\n";
+PyObject* SCA_PropertyActuator::PySetProperty(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ /* Check whether the name exists first ! */
+ char *nameArg;
+ if (!PyArg_ParseTuple(args, "s", &nameArg)) {
+ return NULL;
+ }
+
+ CValue* prop = GetParent()->FindIdentifier(nameArg);
+
+ if (prop) {
+ m_propname = nameArg;
+ } else {
+ ; /* not found ... */
+ }
+
+ Py_Return;
+}
+
+/* 2. getProperty */
+char SCA_PropertyActuator::GetProperty_doc[] =
+"getProperty(name)\n"
+"\tReturn the property on which the actuator operates.\n";
+PyObject* SCA_PropertyActuator::PyGetProperty(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return PyString_FromString(m_propname);
+}
+
+/* 3. setValue */
+char SCA_PropertyActuator::SetValue_doc[] =
+"setValue(value)\n"
+"\t- value: string\n"
+"\tSet the value with which the actuator operates. If the value\n"
+"\tis not compatible with the type of the property, the subsequent\n"
+"\t action is ignored.\n";
+PyObject* SCA_PropertyActuator::PySetValue(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ char *valArg;
+ if(!PyArg_ParseTuple(args, "s", &valArg)) {
+ return NULL;
+ }
+
+ if (valArg) m_exprtxt = valArg;
+
+ Py_Return;
+}
+
+/* 4. getValue */
+char SCA_PropertyActuator::GetValue_doc[] =
+"getValue()\n"
+"\tReturns the value with which the actuator operates.\n";
+PyObject* SCA_PropertyActuator::PyGetValue(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return PyString_FromString(m_exprtxt);
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.h b/source/gameengine/GameLogic/SCA_PropertyActuator.h
new file mode 100644
index 00000000000..7d09a8683cf
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_PropertyActuator.h
@@ -0,0 +1,116 @@
+/**
+ * SCA_PropertyActuator.h
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_PROPERTYACTUATOR
+#define __KX_PROPERTYACTUATOR
+
+#include "SCA_IActuator.h"
+
+class SCA_PropertyActuator : public SCA_IActuator
+{
+ Py_Header;
+
+ enum KX_ACT_PROP_MODE {
+ KX_ACT_PROP_NODEF = 0,
+ KX_ACT_PROP_ASSIGN,
+ KX_ACT_PROP_ADD,
+ KX_ACT_PROP_COPY,
+ KX_ACT_PROP_MAX
+ };
+
+ /**check whether this value is valid */
+ bool isValid(KX_ACT_PROP_MODE mode);
+
+ int m_type;
+ STR_String m_propname;
+ STR_String m_exprtxt;
+ CValue* m_sourceObj; // for copy property actuator
+
+public:
+
+
+
+ SCA_PropertyActuator(
+
+ SCA_IObject* gameobj,
+
+ CValue* sourceObj,
+
+ const STR_String& propname,
+
+ const STR_String& expr,
+
+ int acttype,
+
+ PyTypeObject* T=&Type
+
+ );
+
+
+ ~SCA_PropertyActuator();
+
+
+ CValue*
+
+ GetReplica(
+
+ );
+
+
+ bool
+
+ Update(
+
+ double curtime,
+
+ double deltatime
+
+ );
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ PyObject* _getattr(char *attr);
+
+ // python wrapped methods
+ KX_PYMETHOD_DOC(SCA_PropertyActuator,SetProperty);
+ KX_PYMETHOD_DOC(SCA_PropertyActuator,GetProperty);
+ KX_PYMETHOD_DOC(SCA_PropertyActuator,SetValue);
+ KX_PYMETHOD_DOC(SCA_PropertyActuator,GetValue);
+
+ /* 5. - ... setObject, getObject, setProp2, getProp2, setMode, getMode*/
+
+};
+#endif //__KX_PROPERTYACTUATOR_DOC
diff --git a/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp b/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp
new file mode 100644
index 00000000000..2b3ad1d2c1c
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp
@@ -0,0 +1,67 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "SCA_ISensor.h"
+
+#include "SCA_PropertyEventManager.h"
+
+
+
+SCA_PropertyEventManager::SCA_PropertyEventManager(class SCA_LogicManager* logicmgr)
+ : SCA_EventManager(PROPERTY_EVENTMGR),
+ m_logicmgr(logicmgr)
+{
+}
+
+
+
+SCA_PropertyEventManager::~SCA_PropertyEventManager()
+{
+
+}
+
+
+
+void SCA_PropertyEventManager::RegisterSensor(SCA_ISensor* sensor)
+{
+ m_sensors.push_back(sensor);
+}
+
+
+
+void SCA_PropertyEventManager::NextFrame(double curtime,double deltatime)
+{
+ // check for changed properties
+ for (vector<SCA_ISensor*>::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++)
+ {
+ (*it)->Activate(m_logicmgr,NULL);
+ }
+}
diff --git a/source/gameengine/GameLogic/SCA_PropertyEventManager.h b/source/gameengine/GameLogic/SCA_PropertyEventManager.h
new file mode 100644
index 00000000000..db203b7d92b
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_PropertyEventManager.h
@@ -0,0 +1,52 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef __KX_PROPERTYEVENTMANAGER
+#define __KX_PROPERTYEVENTMANAGER
+
+#include "SCA_EventManager.h"
+
+#include <vector>
+using namespace std;
+
+
+class SCA_PropertyEventManager : public SCA_EventManager
+{
+ class SCA_LogicManager* m_logicmgr;
+
+public:
+ SCA_PropertyEventManager(class SCA_LogicManager* logicmgr);
+ virtual ~SCA_PropertyEventManager();
+ virtual void NextFrame(double curtime,double deltatime);
+ virtual void RegisterSensor(SCA_ISensor* sensor);
+ //SCA_LogicManager* GetLogicManager() { return m_logicmgr;}
+};
+#endif //__KX_PROPERTYEVENTMANAGER
diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.cpp b/source/gameengine/GameLogic/SCA_PropertySensor.cpp
new file mode 100644
index 00000000000..52642c6757f
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_PropertySensor.cpp
@@ -0,0 +1,420 @@
+/**
+ * Property sensor
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <iostream>
+#include "SCA_PropertySensor.h"
+#include "Operator2Expr.h"
+#include "ConstExpr.h"
+#include "InputParser.h"
+#include "StringValue.h"
+#include "SCA_EventManager.h"
+#include "SCA_LogicManager.h"
+
+SCA_PropertySensor::SCA_PropertySensor(SCA_EventManager* eventmgr,
+ SCA_IObject* gameobj,
+ const STR_String& propname,
+ const STR_String& propval,
+ const STR_String& propmaxval,
+ KX_PROPSENSOR_TYPE checktype,
+ PyTypeObject* T )
+ : SCA_ISensor(gameobj,eventmgr,T),
+ m_checkpropname(propname),
+ m_checkpropval(propval),
+ m_checkpropmaxval(propmaxval),
+ m_checktype(checktype),
+ m_range_expr(NULL),
+ m_lastresult(false)
+{
+ m_recentresult=false;
+ //CParser pars;
+ //pars.SetContext(this->AddRef());
+ //CValue* resultval = m_rightexpr->Calculate();
+
+ CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname);
+ if (orgprop)
+ {
+ m_previoustext = orgprop->GetText();
+ orgprop->Release();
+ }
+
+ if (m_checktype==KX_PROPSENSOR_INTERVAL)
+ {
+ PrecalculateRangeExpression();
+ }
+
+}
+
+void SCA_PropertySensor::PrecalculateRangeExpression()
+{
+ CParser pars;
+ pars.SetContext(this->AddRef());
+ STR_String checkstr = "(" + m_checkpropval + " <= "
+ + m_checkpropname + ") && ( "
+ + m_checkpropname + " <= "
+ + m_checkpropmaxval;
+
+ m_range_expr = pars.ProcessText(checkstr);
+}
+
+
+
+CValue* SCA_PropertySensor::GetReplica()
+{
+ SCA_PropertySensor* replica = new SCA_PropertySensor(*this);
+ // m_range_expr must be recalculated on replica!
+ CValue::AddDataToReplica(replica);
+
+ replica->m_range_expr = NULL;
+ if (replica->m_checktype==KX_PROPSENSOR_INTERVAL)
+ {
+ replica->PrecalculateRangeExpression();
+ }
+
+
+ return replica;
+}
+
+
+
+bool SCA_PropertySensor::IsPositiveTrigger()
+{
+ bool result = m_recentresult;//CheckPropertyCondition();
+ if (m_invert)
+ result = !result;
+
+ return result;
+}
+
+
+
+SCA_PropertySensor::~SCA_PropertySensor()
+{
+ //if (m_rightexpr)
+ // m_rightexpr->Release();
+
+ if (m_range_expr)
+ {
+ m_range_expr->Release();
+ m_range_expr=NULL;
+ }
+
+}
+
+
+
+bool SCA_PropertySensor::Evaluate(CValue* event)
+{
+ bool result = CheckPropertyCondition();
+
+ if (m_lastresult!=result)
+ {
+ m_lastresult = result;
+ return true;
+ }
+
+ return false;
+}
+
+
+bool SCA_PropertySensor::CheckPropertyCondition()
+{
+
+ m_recentresult=false;
+ bool result=false;
+ bool reverse = false;
+ switch (m_checktype)
+ {
+ case KX_PROPSENSOR_NOTEQUAL:
+ reverse = true;
+ case KX_PROPSENSOR_EQUAL:
+ {
+ CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname);
+ if (orgprop)
+ {
+ STR_String testprop = orgprop->GetText();
+ // Force strings to upper case, to avoid confusion in
+ // bool tests. It's stupid the prop's identity is lost
+ // on the way here...
+ if ((testprop == "TRUE") || (testprop == "FALSE")) {
+ STR_String checkprop = m_checkpropval;
+ checkprop.Upper();
+ result = (testprop == checkprop);
+ } else {
+ result = (orgprop->GetText() == m_checkpropval);
+ }
+ orgprop->Release();
+
+ }
+
+ if (reverse)
+ result = !result;
+ break;
+
+ }
+
+ case KX_PROPSENSOR_EXPRESSION:
+ {
+ /*
+ if (m_rightexpr)
+ {
+ CValue* resultval = m_rightexpr->Calculate();
+ if (resultval->IsError())
+ {
+ int i=0;
+ STR_String errortest = resultval->GetText();
+ printf(errortest);
+
+ } else
+ {
+ result = resultval->GetNumber() != 0;
+ }
+ }
+ */
+ break;
+ }
+ case KX_PROPSENSOR_INTERVAL:
+ {
+ //CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname);
+ //if (orgprop)
+ //{
+ if (m_range_expr)
+ {
+ CValue* vallie = m_range_expr->Calculate();
+ if (vallie)
+ {
+ STR_String errtext = vallie->GetText();
+ if (errtext == "TRUE")
+ {
+ result = true;
+ } else
+ {
+ if (vallie->IsError())
+ {
+ //printf (errtext.ReadPtr());
+ }
+ }
+
+ vallie->Release();
+ }
+ }
+
+
+ //}
+
+ //cout << " \nSens:Prop:interval!"; /* need implementation here!!! */
+
+ break;
+ }
+ case KX_PROPSENSOR_CHANGED:
+ {
+ CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname);
+
+ if (orgprop)
+ {
+ if (m_previoustext != orgprop->GetText())
+ {
+ m_previoustext = orgprop->GetText();
+ result = true;
+ }
+ orgprop->Release();
+ }
+
+ //cout << " \nSens:Prop:changed!"; /* need implementation here!!! */
+ break;
+ }
+ default:
+ ; /* error */
+ }
+ m_recentresult=result;
+ return result;
+}
+
+CValue* SCA_PropertySensor::FindIdentifier(const STR_String& identifiername)
+{
+ return GetParent()->FindIdentifier(identifiername);
+}
+
+bool SCA_PropertySensor::validValueForProperty(char *val, STR_String &prop)
+{
+ bool result = true;
+ /* There is no type checking at this moment, unfortunately... */
+ return result;
+}
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_PropertySensor::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_PropertySensor",
+ sizeof(SCA_PropertySensor),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_PropertySensor::Parents[] = {
+ &SCA_PropertySensor::Type,
+ &SCA_ISensor::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef SCA_PropertySensor::Methods[] = {
+ {"getType", (PyCFunction) SCA_PropertySensor::sPyGetType, METH_VARARGS, GetType_doc},
+ {"setType", (PyCFunction) SCA_PropertySensor::sPySetType, METH_VARARGS, SetType_doc},
+ {"getProperty", (PyCFunction) SCA_PropertySensor::sPyGetProperty, METH_VARARGS, GetProperty_doc},
+ {"setProperty", (PyCFunction) SCA_PropertySensor::sPySetProperty, METH_VARARGS, SetProperty_doc},
+ {"getValue", (PyCFunction) SCA_PropertySensor::sPyGetValue, METH_VARARGS, GetValue_doc},
+ {"setValue", (PyCFunction) SCA_PropertySensor::sPySetValue, METH_VARARGS, SetValue_doc},
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* SCA_PropertySensor::_getattr(char* attr) {
+ _getattr_up(SCA_ISensor); /* implicit return! */
+}
+
+/* 1. getType */
+char SCA_PropertySensor::GetType_doc[] =
+"getType()\n"
+"\tReturns the type of check this sensor performs.\n";
+PyObject* SCA_PropertySensor::PyGetType(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return PyInt_FromLong(m_checktype);
+}
+
+/* 2. setType */
+char SCA_PropertySensor::SetType_doc[] =
+"setType(type)\n"
+"\t- type: KX_PROPSENSOR_EQUAL, KX_PROPSENSOR_NOTEQUAL,\n"
+"\t KX_PROPSENSOR_INTERVAL, KX_PROPSENSOR_CHANGED,\n"
+"\t or KX_PROPSENSOR_EXPRESSION.\n"
+"\tSet the type of check to perform.\n";
+PyObject* SCA_PropertySensor::PySetType(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int typeArg;
+
+ if (!PyArg_ParseTuple(args, "i", &typeArg)) {
+ return NULL;
+ }
+
+ if ( (typeArg > KX_PROPSENSOR_NODEF)
+ && (typeArg < KX_PROPSENSOR_MAX) ) {
+ m_checktype = typeArg;
+ }
+
+ Py_Return;
+}
+
+/* 3. getProperty */
+char SCA_PropertySensor::GetProperty_doc[] =
+"getProperty()\n"
+"\tReturn the property with which the sensor operates.\n";
+PyObject* SCA_PropertySensor::PyGetProperty(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return PyString_FromString(m_checkpropname);
+}
+
+/* 4. setProperty */
+char SCA_PropertySensor::SetProperty_doc[] =
+"setProperty(name)\n"
+"\t- name: string\n"
+"\tSets the property with which to operate. If there is no property\n"
+"\tof this name, the call is ignored.\n";
+PyObject* SCA_PropertySensor::PySetProperty(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ /* We should query whether the name exists. Or should we create a prop */
+ /* on the fly? */
+ char *propNameArg = NULL;
+
+ if (!PyArg_ParseTuple(args, "s", &propNameArg)) {
+ return NULL;
+ }
+
+ if (FindIdentifier(STR_String(propNameArg))) {
+ m_checkpropname = propNameArg;
+ } else {
+ ; /* error: bad property name */
+ }
+
+ Py_Return;
+}
+
+/* 5. getValue */
+char SCA_PropertySensor::GetValue_doc[] =
+"getValue()\n"
+"\tReturns the value with which the sensor operates.\n";
+PyObject* SCA_PropertySensor::PyGetValue(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return PyString_FromString(m_checkpropval);
+}
+
+/* 6. setValue */
+char SCA_PropertySensor::SetValue_doc[] =
+"setValue(value)\n"
+"\t- value: string\n"
+"\tSet the value with which the sensor operates. If the value\n"
+"\tis not compatible with the type of the property, the subsequent\n"
+"\t action is ignored.\n";
+PyObject* SCA_PropertySensor::PySetValue(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ /* Here, we need to check whether the value is 'valid' for this property.*/
+ /* We know that the property exists, or is NULL. */
+ char *propValArg = NULL;
+
+ if(!PyArg_ParseTuple(args, "s", &propValArg)) {
+ return NULL;
+ }
+
+ if (validValueForProperty(propValArg, m_checkpropname)) {
+ m_checkpropval = propValArg;
+ }
+
+ Py_Return;
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.h b/source/gameengine/GameLogic/SCA_PropertySensor.h
new file mode 100644
index 00000000000..89debebda3d
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_PropertySensor.h
@@ -0,0 +1,109 @@
+/**
+ * Property sensor
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_PROPERTYSENSOR
+#define __KX_PROPERTYSENSOR
+
+#include "SCA_ISensor.h"
+
+class SCA_PropertySensor : public SCA_ISensor
+{
+ Py_Header;
+ //class CExpression* m_rightexpr;
+ int m_checktype;
+ STR_String m_checkpropval;
+ STR_String m_checkpropmaxval;
+ STR_String m_checkpropname;
+ STR_String m_previoustext;
+ bool m_lastresult;
+ bool m_recentresult;
+ CExpression* m_range_expr;
+
+ /**
+ * Test whether this is a sensible value (type check)
+ */
+ bool validValueForProperty(char *val, STR_String &prop);
+ protected:
+
+public:
+ enum KX_PROPSENSOR_TYPE {
+ KX_PROPSENSOR_NODEF = 0,
+ KX_PROPSENSOR_EQUAL,
+ KX_PROPSENSOR_NOTEQUAL,
+ KX_PROPSENSOR_INTERVAL,
+ KX_PROPSENSOR_CHANGED,
+ KX_PROPSENSOR_EXPRESSION,
+ KX_PROPSENSOR_MAX
+ };
+
+ const STR_String S_KX_PROPSENSOR_EQ_STRING;
+
+ SCA_PropertySensor(class SCA_EventManager* eventmgr,
+ SCA_IObject* gameobj,
+ const STR_String& propname,
+ const STR_String& propval,
+ const STR_String& propmaxval,
+ KX_PROPSENSOR_TYPE checktype,
+ PyTypeObject* T=&Type );
+
+ virtual ~SCA_PropertySensor();
+ virtual CValue* GetReplica();
+ void PrecalculateRangeExpression();
+ bool CheckPropertyCondition();
+
+ virtual bool Evaluate(CValue* event);
+ virtual bool IsPositiveTrigger();
+ virtual CValue* FindIdentifier(const STR_String& identifiername);
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(char *attr);
+
+ /* 1. getType */
+ KX_PYMETHOD_DOC(SCA_PropertySensor,GetType);
+ /* 2. setType */
+ KX_PYMETHOD_DOC(SCA_PropertySensor,SetType);
+ /* 3. setProperty */
+ KX_PYMETHOD_DOC(SCA_PropertySensor,SetProperty);
+ /* 4. getProperty */
+ KX_PYMETHOD_DOC(SCA_PropertySensor,GetProperty);
+ /* 5. getValue */
+ KX_PYMETHOD_DOC(SCA_PropertySensor,GetValue);
+ /* 6. setValue */
+ KX_PYMETHOD_DOC(SCA_PropertySensor,SetValue);
+
+};
+#endif
diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp
new file mode 100644
index 00000000000..2d57a5f116d
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_PythonController.cpp
@@ -0,0 +1,400 @@
+/**
+ * Execute Python scripts
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "SCA_PythonController.h"
+#include "SCA_LogicManager.h"
+#include "SCA_ISensor.h"
+#include "SCA_IActuator.h"
+#include "compile.h"
+#include "eval.h"
+
+
+// initialize static member variables
+SCA_PythonController* SCA_PythonController::m_sCurrentController = NULL;
+
+
+SCA_PythonController::SCA_PythonController(SCA_IObject* gameobj,
+ PyTypeObject* T)
+ : SCA_IController(gameobj, T),
+ m_pythondictionary(NULL),
+ m_bytecode(NULL),
+ m_bModified(true)
+{
+}
+
+
+
+SCA_PythonController::~SCA_PythonController()
+{
+ if (m_bytecode)
+ {
+ //
+ //printf("released python byte script\n");
+ Py_DECREF(m_bytecode);
+ }
+}
+
+
+
+CValue* SCA_PythonController::GetReplica()
+{
+ SCA_PythonController* replica = new SCA_PythonController(*this);
+ replica->m_bytecode = NULL;
+ replica->m_bModified = true;
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+void SCA_PythonController::SetScriptText(const STR_String& text)
+{
+ m_scriptText = text;
+ m_bModified = true;
+}
+
+
+
+void SCA_PythonController::SetScriptName(const STR_String& name)
+{
+ m_scriptName = name;
+}
+
+
+
+void SCA_PythonController::SetDictionary(PyObject* pythondictionary)
+{
+ m_pythondictionary = pythondictionary;
+}
+
+
+static char* sPyGetCurrentController__doc__;
+
+
+PyObject* SCA_PythonController::sPyGetCurrentController(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ m_sCurrentController->AddRef();
+ return m_sCurrentController;
+}
+
+
+static char* sPyAddActiveActuator__doc__;
+
+
+PyObject* SCA_PythonController::sPyAddActiveActuator(
+
+ PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+
+ PyObject* ob1;
+ int activate;
+ if (!PyArg_ParseTuple(args, "Oi", &ob1,&activate))
+ {
+ return NULL;
+
+ }
+ // for safety, todo: only allow for registered actuators (pointertable)
+ // we don't want to crash gameengine/blender by python scripts
+
+ CValue* ac = (CValue*)ob1;
+ CValue* boolval = new CBoolValue(activate!=0);
+ m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)ac,boolval);
+ boolval->Release();
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+char* SCA_PythonController::sPyGetCurrentController__doc__ = "getCurrentController()";
+char* SCA_PythonController::sPyAddActiveActuator__doc__= "addActiveActuator(actuator,bool)";
+char SCA_PythonController::GetActuators_doc[] = "getActuator";
+
+PyTypeObject SCA_PythonController::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_PythonController",
+ sizeof(SCA_PythonController),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_PythonController::Parents[] = {
+ &SCA_PythonController::Type,
+ &SCA_IController::Type,
+ &CValue::Type,
+ NULL
+};
+PyMethodDef SCA_PythonController::Methods[] = {
+ {"getActuators", (PyCFunction) SCA_PythonController::sPyGetActuators,
+ METH_VARARGS, SCA_PythonController::GetActuators_doc},
+ {"getActuator", (PyCFunction) SCA_PythonController::sPyGetActuator,
+ METH_VARARGS, SCA_PythonController::GetActuator_doc},
+ {"getSensors", (PyCFunction) SCA_PythonController::sPyGetSensors,
+ METH_VARARGS, SCA_PythonController::GetSensors_doc},
+ {"getSensor", (PyCFunction) SCA_PythonController::sPyGetSensor,
+ METH_VARARGS, SCA_PythonController::GetSensor_doc}
+ ,
+ {NULL,NULL} //Sentinel
+};
+
+
+
+ /* XXX, function should be removed and PyDict_Copy used
+ * once we switch to all builds using Python 2.0 - zr */
+static PyObject *myPyDict_Copy(PyObject *odict)
+{
+ PyObject *ndict= PyDict_New();
+ PyObject *key, *val;
+ int ppos= 0;
+
+ while (PyDict_Next(odict, &ppos, &key, &val))
+ PyDict_SetItem(ndict, key, val);
+
+ return ndict;
+}
+
+void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr)
+{
+ m_sCurrentController = this;
+ m_sCurrentLogicManager = logicmgr;
+
+ if (m_bModified)
+ {
+ // if a script already exists, decref it before replace the pointer to a new script
+ if (m_bytecode)
+ {
+ Py_DECREF(m_bytecode);
+ m_bytecode=NULL;
+ }
+ // recompile the scripttext into bytecode
+ m_bytecode = Py_CompileString(m_scriptText.Ptr(), m_scriptName.Ptr(), Py_file_input);
+ if (m_bytecode)
+ {
+ // store the
+ int i=0;
+ i+=2; // so compiler doesn't complain about unused variable
+ PyRun_SimpleString("import GameLogic\n");
+ } else
+ {
+ // didn't compile, so instead of compile, complain
+ int i=0;
+ i++; // so compiler doesn't complain about unused variable
+ }
+ m_bModified=false;
+ }
+
+ /*
+ * This part here with excdict is a temporary patch
+ * to avoid python/gameengine crashes when python
+ * inadvertently holds references to game objects
+ * in global variables.
+ *
+ * The idea is always make a fresh dictionary, and
+ * destroy it right after it is used to make sure
+ * python won't hold any gameobject references.
+ *
+ * Note that the PyDict_Clear _is_ necessary before
+ * the Py_DECREF() because it is possible for the
+ * variables inside the dictionary to hold references
+ * to the dictionary (ie. generate a cycle), so we
+ * break it by hand, then DECREF (which in this case
+ * should always ensure excdict is cleared).
+ */
+ PyObject *excdict= myPyDict_Copy(m_pythondictionary);
+ struct _object* resultobj = PyEval_EvalCode((PyCodeObject*)m_bytecode,
+ excdict,
+ excdict
+ );
+ PyDict_Clear(excdict);
+ Py_DECREF(excdict);
+
+ if (resultobj)
+ {
+ Py_DECREF(resultobj);
+ } else
+ {
+ // something is wrong, tell the user what went wrong
+ printf("PYTHON SCRIPT ERROR:\n");
+ PyRun_SimpleString(m_scriptText.Ptr());
+ }
+
+ m_sCurrentController = NULL;
+}
+
+
+
+PyObject* SCA_PythonController::_getattr(char* attr)
+{
+ _getattr_up(SCA_IController);
+}
+
+
+
+PyObject* SCA_PythonController::PyGetActuators(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ int index;
+
+ PyObject* resultlist = PyList_New(m_linkedactuators.size());
+ for (index=0;index<m_linkedactuators.size();index++)
+ {
+ PyList_SetItem(resultlist,index,m_linkedactuators[index]->AddRef());
+ }
+
+ return resultlist;
+}
+
+char SCA_PythonController::GetSensor_doc[] =
+"GetSensor (char sensorname) return linked sensor that is named [sensorname]\n";
+PyObject*
+SCA_PythonController::PyGetSensor(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+
+ char *scriptArg;
+
+ if (!PyArg_ParseTuple(args, "s", &scriptArg)) {
+ return NULL;
+ }
+
+ int index;
+ for (index=0;index<m_linkedsensors.size();index++)
+ {
+ SCA_ISensor* sensor = m_linkedsensors[index];
+ STR_String realname = sensor->GetName();
+ if (realname == scriptArg)
+ {
+ return sensor->AddRef();
+ }
+ }
+
+ PyErr_SetString(PyExc_AttributeError, "Unable to find requested sensor");
+ return NULL;
+}
+
+
+
+char SCA_PythonController::GetActuator_doc[] =
+"GetActuator (char sensorname) return linked actuator that is named [actuatorname]\n";
+PyObject*
+SCA_PythonController::PyGetActuator(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+
+ char *scriptArg;
+
+ if (!PyArg_ParseTuple(args, "s", &scriptArg)) {
+ return NULL;
+ }
+
+ int index;
+ for (index=0;index<m_linkedactuators.size();index++)
+ {
+ SCA_IActuator* actua = m_linkedactuators[index];
+ STR_String realname = actua->GetName();
+ if (realname == scriptArg)
+ {
+ return actua->AddRef();
+ }
+ }
+
+ PyErr_SetString(PyExc_AttributeError, "Unable to find requested actuator");
+ return NULL;
+}
+
+
+char SCA_PythonController::GetSensors_doc[] = "getSensors returns a list of all attached sensors";
+PyObject*
+SCA_PythonController::PyGetSensors(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ int index;
+
+ PyObject* resultlist = PyList_New(m_linkedsensors.size());
+ for (index=0;index<m_linkedsensors.size();index++)
+ {
+ PyList_SetItem(resultlist,index,m_linkedsensors[index]->AddRef());
+ }
+
+ return resultlist;
+}
+
+/* 1. getScript */
+PyObject* SCA_PythonController::PyGetScript(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ return PyString_FromString(m_scriptText);
+}
+
+/* 2. setScript */
+PyObject* SCA_PythonController::PySetScript(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ char *scriptArg;
+ if (!PyArg_ParseTuple(args, "s", &scriptArg)) {
+ return NULL;
+ }
+
+ /* set scripttext sets m_bModified to true,
+ so next time the script is needed, a reparse into byte code is done */
+
+ this->SetScriptText(scriptArg);
+
+ Py_Return;
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_PythonController.h b/source/gameengine/GameLogic/SCA_PythonController.h
new file mode 100644
index 00000000000..f19fcac72f3
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_PythonController.h
@@ -0,0 +1,88 @@
+/**
+ * Execute Python scripts
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef KX_PYTHONCONTROLLER_H
+#define KX_PYTHONCONTROLLER_H
+
+#include "SCA_IController.h"
+#include "SCA_LogicManager.h"
+#include "BoolValue.h"
+
+class SCA_IObject;
+class SCA_PythonController : public SCA_IController
+{
+ Py_Header;
+ struct _object * m_bytecode;
+ bool m_bModified;
+
+ protected:
+ STR_String m_scriptText;
+ STR_String m_scriptName;
+ PyObject* m_pythondictionary;
+
+ public:
+ static SCA_PythonController* m_sCurrentController; // protected !!!
+
+ SCA_PythonController(SCA_IObject* gameobj,PyTypeObject* T = &Type);
+ virtual ~SCA_PythonController();
+
+ virtual CValue* GetReplica();
+ virtual void Trigger(class SCA_LogicManager* logicmgr);
+
+ void SetScriptText(const STR_String& text);
+ void SetScriptName(const STR_String& name);
+ void SetDictionary(PyObject* pythondictionary);
+
+ static char* sPyGetCurrentController__doc__;
+ static PyObject* sPyGetCurrentController(PyObject* self,
+ PyObject* args,
+ PyObject* kwds);
+ static char* sPyAddActiveActuator__doc__;
+ static PyObject* sPyAddActiveActuator(PyObject* self,
+ PyObject* args,
+ PyObject* kwds);
+ virtual PyObject* _getattr(char *attr);
+
+ KX_PYMETHOD_DOC(SCA_PythonController,GetSensors);
+ KX_PYMETHOD_DOC(SCA_PythonController,GetSensor);
+ KX_PYMETHOD_DOC(SCA_PythonController,GetActuator);
+ KX_PYMETHOD_DOC(SCA_PythonController,GetActuators);
+ KX_PYMETHOD(SCA_PythonController,SetScript);
+ KX_PYMETHOD(SCA_PythonController,GetScript);
+
+
+};
+
+#endif //KX_PYTHONCONTROLLER_H
+
diff --git a/source/gameengine/GameLogic/SCA_RandomActuator.cpp b/source/gameengine/GameLogic/SCA_RandomActuator.cpp
new file mode 100644
index 00000000000..50acf24251f
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_RandomActuator.cpp
@@ -0,0 +1,630 @@
+/**
+ * Set random/camera stuff
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "BoolValue.h"
+#include "IntValue.h"
+#include "FloatValue.h"
+#include "SCA_IActuator.h"
+#include "SCA_RandomActuator.h"
+#include "math.h"
+
+#include "MT_Transform.h"
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_RandomActuator::SCA_RandomActuator(SCA_IObject *gameobj,
+ long seed,
+ SCA_RandomActuator::KX_RANDOMACT_MODE mode,
+ float para1,
+ float para2,
+ const STR_String &propName,
+ PyTypeObject* T)
+ : SCA_IActuator(gameobj, T),
+ m_distribution(mode),
+ m_propname(propName),
+ m_parameter1(para1),
+ m_parameter2(para2)
+{
+ m_base = new SCA_RandomNumberGenerator(seed);
+ m_counter = 0;
+ enforceConstraints();
+}
+
+
+
+SCA_RandomActuator::~SCA_RandomActuator()
+{
+ /* intentionally empty */
+}
+
+
+
+CValue* SCA_RandomActuator::GetReplica()
+{
+ SCA_RandomActuator* replica = new SCA_RandomActuator(*this);
+ replica->ProcessReplica();
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+bool SCA_RandomActuator::Update(double curtime,double deltatime)
+{
+ bool result = false;
+ bool bNegativeEvent = IsNegativeEvent();
+
+ RemoveAllEvents();
+
+
+ CValue *tmpval;
+
+ if (bNegativeEvent)
+ return false; // do nothing on negative events
+
+ switch (m_distribution) {
+ case KX_RANDOMACT_BOOL_CONST: {
+ /* un petit peu filthy */
+ bool res = !(m_parameter1 < 0.5);
+ tmpval = new CBoolValue(res);
+ }
+ break;
+ case KX_RANDOMACT_BOOL_UNIFORM: {
+ /* flip a coin */
+ bool res;
+ if (m_counter > 31) {
+ m_previous = m_base->Draw();
+ res = ((m_previous & 0x1) == 0);
+ m_counter = 1;
+ } else {
+ res = (((m_previous >> m_counter) & 0x1) == 0);
+ m_counter++;
+ }
+ tmpval = new CBoolValue(res);
+ }
+ break;
+ case KX_RANDOMACT_BOOL_BERNOUILLI: {
+ /* 'percentage' */
+ bool res;
+ res = (m_base->DrawFloat() < m_parameter1);
+ tmpval = new CBoolValue(res);
+ }
+ break;
+ case KX_RANDOMACT_INT_CONST: {
+ /* constant */
+ tmpval = new CIntValue((int) floor(m_parameter1));
+ }
+ break;
+ case KX_RANDOMACT_INT_UNIFORM: {
+ /* uniform (toss a die) */
+ int res;
+ /* The [0, 1] interval is projected onto the [min, max+1] domain, */
+ /* and then rounded. */
+ res = (int) floor( ((m_parameter2 - m_parameter1 + 1) * m_base->DrawFloat())
+ + m_parameter1);
+ tmpval = new CIntValue(res);
+ }
+ break;
+ case KX_RANDOMACT_INT_POISSON: {
+ /* poisson (queues) */
+ /* If x_1, x_2, ... is a sequence of random numbers with uniform */
+ /* distribution between zero and one, k is the first integer for */
+ /* which the product x_1*x_2*...*x_k < exp(-\lamba). */
+ float a = 0.0, b = 0.0;
+ int res = 0;
+ /* The - sign is important here! The number to test for, a, must be */
+ /* between 0 and 1. */
+ a = exp(-m_parameter1);
+ /* a quickly reaches 0.... so we guard explicitly for that. */
+ if (a < FLT_MIN) a = FLT_MIN;
+ b = m_base->DrawFloat();
+ while (b >= a) {
+ b = b * m_base->DrawFloat();
+ res++;
+ };
+ tmpval = new CIntValue(res);
+ }
+ break;
+ case KX_RANDOMACT_FLOAT_CONST: {
+ /* constant */
+ tmpval = new CFloatValue(m_parameter1);
+ }
+ break;
+ case KX_RANDOMACT_FLOAT_UNIFORM: {
+ float res = ((m_parameter2 - m_parameter1) * m_base->DrawFloat())
+ + m_parameter1;
+ tmpval = new CFloatValue(res);
+ }
+ break;
+ case KX_RANDOMACT_FLOAT_NORMAL: {
+ /* normal (big numbers): para1 = mean, para2 = std dev */
+
+ /*
+
+ 070301 - nzc - Changed the termination condition. I think I
+ made a small mistake here, but it only affects distro's where
+ the seed equals 0. In that case, the algorithm locks. Let's
+ just guard that case separately.
+
+ */
+
+ float x = 0.0, y = 0.0, s = 0.0, t = 0.0;
+ if (m_base->GetSeed() == 0) {
+ /*
+
+ 070301 - nzc
+ Just taking the mean here seems reasonable.
+
+ */
+ tmpval = new CFloatValue(m_parameter1);
+ } else {
+ /*
+
+ 070301 - nzc
+ Now, with seed != 0, we will most assuredly get some
+ sensible values. The termination condition states two
+ things:
+ 1. s >= 0 is not allowed: to prevent the distro from
+ getting a bias towards high values. This is a small
+ correction, really, and might also be left out.
+ 2. s == 0 is not allowed: to prevent a division by zero
+ when renormalising the drawn value to the desired
+ distribution shape. As a side effect, the distro will
+ never yield the exact mean.
+ I am not sure whether this is consistent, since the error
+ cause by #2 is of the same magnitude as the one
+ prevented by #1. The error introduced into the SD will be
+ improved, though. By how much? Hard to say... If you like
+ the maths, feel free to analyse. Be aware that this is
+ one of the really old standard algorithms. I think the
+ original came in Fortran, was translated to Pascal, and
+ then someone came up with the C code. My guess it that
+ this will be quite sufficient here.
+
+ */
+ do
+ {
+ x = 2.0 * m_base->DrawFloat() - 1.0;
+ y = 2.0 * m_base->DrawFloat() - 1.0;
+ s = x*x + y*y;
+ } while ( (s >= 1.0) || (s == 0.0) );
+ t = x * sqrt( (-2.0 * log(s)) / s);
+ tmpval = new CFloatValue(m_parameter1 + m_parameter2 * t);
+ }
+ }
+ break;
+ case KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL: {
+ /* 1st order fall-off. I am very partial to using the half-life as */
+ /* controlling parameter. Using the 'normal' exponent is not very */
+ /* intuitive... */
+ /* tmpval = new CFloatValue( (1.0 / m_parameter1) */
+ tmpval = new CFloatValue( (m_parameter1)
+ * (-log(1.0 - m_base->DrawFloat())) );
+
+ }
+ break;
+ default:
+ ; /* unknown distribution... */
+ }
+
+ /* Round up: assign it */
+ CValue *prop = GetParent()->GetProperty(m_propname);
+ if (prop) {
+ prop->SetValue(tmpval);
+ }
+ tmpval->Release();
+
+ return false;
+}
+
+void SCA_RandomActuator::enforceConstraints() {
+ /* The constraints that are checked here are the ones fundamental to */
+ /* the various distributions. Limitations of the algorithms are checked */
+ /* elsewhere (or they should be... ). */
+ switch (m_distribution) {
+ case KX_RANDOMACT_BOOL_CONST:
+ case KX_RANDOMACT_BOOL_UNIFORM:
+ case KX_RANDOMACT_INT_CONST:
+ case KX_RANDOMACT_INT_UNIFORM:
+ case KX_RANDOMACT_FLOAT_UNIFORM:
+ case KX_RANDOMACT_FLOAT_CONST:
+ ; /* Nothing to be done here. We allow uniform distro's to have */
+ /* 'funny' domains, i.e. max < min. This does not give problems. */
+ break;
+ case KX_RANDOMACT_BOOL_BERNOUILLI:
+ /* clamp to [0, 1] */
+ if (m_parameter1 < 0.0) {
+ m_parameter1 = 0.0;
+ } else if (m_parameter1 > 1.0) {
+ m_parameter1 = 1.0;
+ }
+ break;
+ case KX_RANDOMACT_INT_POISSON:
+ /* non-negative */
+ if (m_parameter1 < 0.0) {
+ m_parameter1 = 0.0;
+ }
+ break;
+ case KX_RANDOMACT_FLOAT_NORMAL:
+ /* standard dev. is non-negative */
+ if (m_parameter2 < 0.0) {
+ m_parameter2 = 0.0;
+ }
+ break;
+ case KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL:
+ /* halflife must be non-negative */
+ if (m_parameter1 < 0.0) {
+ m_parameter1 = 0.0;
+ }
+ break;
+ default:
+ ; /* unknown distribution... */
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_RandomActuator::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_RandomActuator",
+ sizeof(SCA_RandomActuator),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_RandomActuator::Parents[] = {
+ &SCA_RandomActuator::Type,
+ &SCA_IActuator::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef SCA_RandomActuator::Methods[] = {
+ {"setSeed", (PyCFunction) SCA_RandomActuator::sPySetSeed, METH_VARARGS, SetSeed_doc},
+ {"getSeed", (PyCFunction) SCA_RandomActuator::sPyGetSeed, METH_VARARGS, GetSeed_doc},
+ {"getPara1", (PyCFunction) SCA_RandomActuator::sPyGetPara1, METH_VARARGS, GetPara1_doc},
+ {"getPara2", (PyCFunction) SCA_RandomActuator::sPyGetPara2, METH_VARARGS, GetPara2_doc},
+ {"getDistribution", (PyCFunction) SCA_RandomActuator::sPyGetDistribution, METH_VARARGS, GetDistribution_doc},
+ {"setProperty", (PyCFunction) SCA_RandomActuator::sPySetProperty, METH_VARARGS, SetProperty_doc},
+ {"getProperty", (PyCFunction) SCA_RandomActuator::sPyGetProperty, METH_VARARGS, GetProperty_doc},
+ {"setBoolConst", (PyCFunction) SCA_RandomActuator::sPySetBoolConst, METH_VARARGS, SetBoolConst_doc},
+ {"setBoolUniform", (PyCFunction) SCA_RandomActuator::sPySetBoolUniform, METH_VARARGS, SetBoolUniform_doc},
+ {"setBoolBernouilli",(PyCFunction) SCA_RandomActuator::sPySetBoolBernouilli, METH_VARARGS, SetBoolBernouilli_doc},
+ {"setIntConst", (PyCFunction) SCA_RandomActuator::sPySetIntConst, METH_VARARGS, SetIntConst_doc},
+ {"setIntUniform", (PyCFunction) SCA_RandomActuator::sPySetIntUniform, METH_VARARGS, SetIntUniform_doc},
+ {"setIntPoisson", (PyCFunction) SCA_RandomActuator::sPySetIntPoisson, METH_VARARGS, SetIntPoisson_doc},
+ {"setFloatConst", (PyCFunction) SCA_RandomActuator::sPySetFloatConst, METH_VARARGS, SetFloatConst_doc},
+ {"setFloatUniform", (PyCFunction) SCA_RandomActuator::sPySetFloatUniform, METH_VARARGS, SetFloatUniform_doc},
+ {"setFloatNormal", (PyCFunction) SCA_RandomActuator::sPySetFloatNormal, METH_VARARGS, SetFloatNormal_doc},
+ {"setFloatNegativeExponential", (PyCFunction) SCA_RandomActuator::sPySetFloatNegativeExponential, METH_VARARGS, SetFloatNegativeExponential_doc},
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* SCA_RandomActuator::_getattr(char* attr) {
+ _getattr_up(SCA_IActuator);
+}
+
+/* 1. setSeed */
+char SCA_RandomActuator::SetSeed_doc[] =
+"setSeed(seed)\n"
+"\t- seed: integer\n"
+"\tSet the initial seed of the generator. Equal seeds produce\n"
+"\tequal series. If the seed is 0, the generator will produce\n"
+"\tthe same value on every call.\n";
+PyObject* SCA_RandomActuator::PySetSeed(PyObject* self, PyObject* args, PyObject* kwds) {
+ long seedArg;
+ if(!PyArg_ParseTuple(args, "i", &seedArg)) {
+ return NULL;
+ }
+
+ m_base->SetSeed(seedArg);
+
+ Py_Return;
+}
+/* 2. getSeed */
+char SCA_RandomActuator::GetSeed_doc[] =
+"getSeed()\n"
+"\tReturns the initial seed of the generator. Equal seeds produce\n"
+"\tequal series.\n";
+PyObject* SCA_RandomActuator::PyGetSeed(PyObject* self, PyObject* args, PyObject* kwds) {
+ return PyInt_FromLong(m_base->GetSeed());
+}
+
+/* 4. getPara1 */
+char SCA_RandomActuator::GetPara1_doc[] =
+"getPara1()\n"
+"\tReturns the first parameter of the active distribution. Refer\n"
+"\tto the documentation of the generator types for the meaning\n"
+"\tof this value.";
+PyObject* SCA_RandomActuator::PyGetPara1(PyObject* self, PyObject* args, PyObject* kwds) {
+ return PyFloat_FromDouble(m_parameter1);
+}
+
+/* 6. getPara2 */
+char SCA_RandomActuator::GetPara2_doc[] =
+"getPara2()\n"
+"\tReturns the first parameter of the active distribution. Refer\n"
+"\tto the documentation of the generator types for the meaning\n"
+"\tof this value.";
+PyObject* SCA_RandomActuator::PyGetPara2(PyObject* self, PyObject* args, PyObject* kwds) {
+ return PyFloat_FromDouble(m_parameter2);
+}
+
+/* 8. getDistribution */
+char SCA_RandomActuator::GetDistribution_doc[] =
+"getDistribution()\n"
+"\tReturns the type of the active distribution.\n";
+PyObject* SCA_RandomActuator::PyGetDistribution(PyObject* self, PyObject* args, PyObject* kwds) {
+ return PyInt_FromLong(m_distribution);
+}
+
+/* 9. setProperty */
+char SCA_RandomActuator::SetProperty_doc[] =
+"setProperty(name)\n"
+"\t- name: string\n"
+"\tSet the property to which the random value is assigned. If the \n"
+"\tgenerator and property types do not match, the assignment is ignored.\n";
+PyObject* SCA_RandomActuator::PySetProperty(PyObject* self, PyObject* args, PyObject* kwds) {
+ char *nameArg;
+ if (!PyArg_ParseTuple(args, "s", &nameArg)) {
+ return NULL;
+ }
+
+ CValue* prop = GetParent()->FindIdentifier(nameArg);
+
+ if (prop) {
+ m_propname = nameArg;
+ prop->Release();
+ } else {
+ ; /* not found ... */
+ }
+
+ Py_Return;
+}
+/* 10. getProperty */
+char SCA_RandomActuator::GetProperty_doc[] =
+"getProperty(name)\n"
+"\tReturn the property to which the random value is assigned. If the \n"
+"\tgenerator and property types do not match, the assignment is ignored.\n";
+PyObject* SCA_RandomActuator::PyGetProperty(PyObject* self, PyObject* args, PyObject* kwds) {
+ return PyString_FromString(m_propname);
+}
+
+/* 11. setBoolConst */
+char SCA_RandomActuator::SetBoolConst_doc[] =
+"setBoolConst(value)\n"
+"\t- value: 0 or 1\n"
+"\tSet this generator to produce a constant boolean value.\n";
+PyObject* SCA_RandomActuator::PySetBoolConst(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ int paraArg;
+ if(!PyArg_ParseTuple(args, "i", &paraArg)) {
+ return NULL;
+ }
+
+ m_distribution = KX_RANDOMACT_BOOL_CONST;
+ if (paraArg == KX_TRUE) {
+ m_parameter1 = 1;
+ }
+
+ Py_Return;
+}
+/* 12. setBoolUniform, */
+char SCA_RandomActuator::SetBoolUniform_doc[] =
+"setBoolUniform()\n"
+"\tSet this generator to produce true and false, each with 50%% chance of occuring\n";
+PyObject* SCA_RandomActuator::PySetBoolUniform(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ /* no args */
+ m_distribution = KX_RANDOMACT_BOOL_UNIFORM;
+ enforceConstraints();
+ Py_Return;
+}
+/* 13. setBoolBernouilli, */
+char SCA_RandomActuator::SetBoolBernouilli_doc[] =
+"setBoolBernouilli(value)\n"
+"\t- value: a float between 0 and 1\n"
+"\tReturn false value * 100%% of the time.\n";
+PyObject* SCA_RandomActuator::PySetBoolBernouilli(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ float paraArg;
+ if(!PyArg_ParseTuple(args, "f", &paraArg)) {
+ return NULL;
+ }
+
+ m_distribution = KX_RANDOMACT_BOOL_CONST;
+ m_parameter1 = paraArg;
+ enforceConstraints();
+ Py_Return;
+}
+/* 14. setIntConst,*/
+char SCA_RandomActuator::SetIntConst_doc[] =
+"setIntConst(value)\n"
+"\t- value: integer\n"
+"\tAlways return value\n";
+PyObject* SCA_RandomActuator::PySetIntConst(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ int paraArg;
+ if(!PyArg_ParseTuple(args, "i", &paraArg)) {
+ return NULL;
+ }
+
+ m_distribution = KX_RANDOMACT_INT_CONST;
+ m_parameter1 = paraArg;
+ enforceConstraints();
+ Py_Return;
+}
+/* 15. setIntUniform,*/
+char SCA_RandomActuator::SetIntUniform_doc[] =
+"setIntUniform(lower_bound, upper_bound)\n"
+"\t- lower_bound: integer\n"
+"\t- upper_bound: integer\n"
+"\tReturn a random integer between lower_bound and\n"
+"\tupper_bound. The boundaries are included.\n";
+PyObject* SCA_RandomActuator::PySetIntUniform(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ int paraArg1, paraArg2;
+ if(!PyArg_ParseTuple(args, "ii", &paraArg1, &paraArg2)) {
+ return NULL;
+ }
+
+ m_distribution = KX_RANDOMACT_INT_UNIFORM;
+ m_parameter1 = paraArg1;
+ m_parameter2 = paraArg2;
+ enforceConstraints();
+ Py_Return;
+}
+/* 16. setIntPoisson, */
+char SCA_RandomActuator::SetIntPoisson_doc[] =
+"setIntPoisson(value)\n"
+"\t- value: float\n"
+"\tReturn a Poisson-distributed number. This performs a series\n"
+"\tof Bernouilli tests with parameter value. It returns the\n"
+"\tnumber of tries needed to achieve succes.\n";
+PyObject* SCA_RandomActuator::PySetIntPoisson(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ float paraArg;
+ if(!PyArg_ParseTuple(args, "f", &paraArg)) {
+ return NULL;
+ }
+
+ m_distribution = KX_RANDOMACT_INT_POISSON;
+ m_parameter1 = paraArg;
+ enforceConstraints();
+ Py_Return;
+}
+/* 17. setFloatConst,*/
+char SCA_RandomActuator::SetFloatConst_doc[] =
+"setFloatConst(value)\n"
+"\t- value: float\n"
+"\tAlways return value\n";
+PyObject* SCA_RandomActuator::PySetFloatConst(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ float paraArg;
+ if(!PyArg_ParseTuple(args, "f", &paraArg)) {
+ return NULL;
+ }
+
+ m_distribution = KX_RANDOMACT_FLOAT_CONST;
+ m_parameter1 = paraArg;
+ enforceConstraints();
+ Py_Return;
+}
+/* 18. setFloatUniform, */
+char SCA_RandomActuator::SetFloatUniform_doc[] =
+"setFloatUniform(lower_bound, upper_bound)\n"
+"\t- lower_bound: float\n"
+"\t- upper_bound: float\n"
+"\tReturn a random integer between lower_bound and\n"
+"\tupper_bound.\n";
+PyObject* SCA_RandomActuator::PySetFloatUniform(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ float paraArg1, paraArg2;
+ if(!PyArg_ParseTuple(args, "ff", &paraArg1, &paraArg2)) {
+ return NULL;
+ }
+
+ m_distribution = KX_RANDOMACT_FLOAT_UNIFORM;
+ m_parameter1 = paraArg1;
+ m_parameter2 = paraArg2;
+ enforceConstraints();
+ Py_Return;
+}
+/* 19. setFloatNormal, */
+char SCA_RandomActuator::SetFloatNormal_doc[] =
+"setFloatNormal(mean, standard_deviation)\n"
+"\t- mean: float\n"
+"\t- standard_deviation: float\n"
+"\tReturn normal-distributed numbers. The average is mean, and the\n"
+"\tdeviation from the mean is characterized by standard_deviation.\n";
+PyObject* SCA_RandomActuator::PySetFloatNormal(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ float paraArg1, paraArg2;
+ if(!PyArg_ParseTuple(args, "ff", &paraArg1, &paraArg2)) {
+ return NULL;
+ }
+
+ m_distribution = KX_RANDOMACT_FLOAT_NORMAL;
+ m_parameter1 = paraArg1;
+ m_parameter2 = paraArg2;
+ enforceConstraints();
+ Py_Return;
+}
+/* 20. setFloatNegativeExponential, */
+char SCA_RandomActuator::SetFloatNegativeExponential_doc[] =
+"setFloatNegativeExponential(half_life)\n"
+"\t- half_life: float\n"
+"\tReturn negative-exponentially distributed numbers. The half-life 'time'\n"
+"\tis characterized by half_life.\n";
+PyObject* SCA_RandomActuator::PySetFloatNegativeExponential(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ float paraArg;
+ if(!PyArg_ParseTuple(args, "f", &paraArg)) {
+ return NULL;
+ }
+
+ m_distribution = KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL;
+ m_parameter1 = paraArg;
+ enforceConstraints();
+ Py_Return;
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_RandomActuator.h b/source/gameengine/GameLogic/SCA_RandomActuator.h
new file mode 100644
index 00000000000..236d41c5154
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_RandomActuator.h
@@ -0,0 +1,144 @@
+/**
+ * Draw a random number, and put it in a property
+ *
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_RANDOMACTUATOR
+#define __KX_RANDOMACTUATOR
+
+#include "SCA_IActuator.h"
+#include "SCA_RandomNumberGenerator.h"
+
+class SCA_RandomActuator : public SCA_IActuator
+{
+ Py_Header;
+ /** Property to assign to */
+ STR_String m_propname;
+
+ /** First parameter. The meaning of the parameters depends on the
+ * distribution */
+ float m_parameter1;
+ /** Second parameter. The meaning of the parameters depends on the
+ * distribution */
+ float m_parameter2;
+
+ /** The base generator */
+ SCA_RandomNumberGenerator *m_base;
+
+ /** just a generic, persistent counter */
+ int m_counter;
+
+ /** cache for the previous draw */
+ long m_previous;
+
+ /** apply constraints for the chosen distribution to the parameters */
+ void enforceConstraints(void);
+
+ public:
+
+ enum KX_RANDOMACT_MODE {
+ KX_RANDOMACT_NODEF,
+ KX_RANDOMACT_BOOL_CONST,
+ KX_RANDOMACT_BOOL_UNIFORM,
+ KX_RANDOMACT_BOOL_BERNOUILLI,
+ KX_RANDOMACT_INT_CONST,
+ KX_RANDOMACT_INT_UNIFORM,
+ KX_RANDOMACT_INT_POISSON,
+ KX_RANDOMACT_FLOAT_CONST,
+ KX_RANDOMACT_FLOAT_UNIFORM,
+ KX_RANDOMACT_FLOAT_NORMAL,
+ KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL,
+ KX_RANDOMACT_MAX
+ };
+ /** distribution type */
+ KX_RANDOMACT_MODE m_distribution;
+
+ SCA_RandomActuator(class SCA_IObject* gameobj,
+ long seed,
+ KX_RANDOMACT_MODE mode,
+ float para1,
+ float para2,
+ const STR_String &propName,
+ PyTypeObject* T=&Type);
+ virtual ~SCA_RandomActuator();
+ virtual bool Update(double curtime,double deltatime);
+
+ virtual CValue* GetReplica();
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(char *attr);
+
+ /* 1. setSeed */
+ KX_PYMETHOD_DOC(SCA_RandomActuator,SetSeed);
+ /* 2. getSeed */
+ KX_PYMETHOD_DOC(SCA_RandomActuator,GetSeed);
+ /* 3. setPara1 -removed- */
+ /* 4. getPara1 */
+ KX_PYMETHOD_DOC(SCA_RandomActuator,GetPara1);
+ /* 5. setPara2 -removed- */
+ /* 6. getPara2 */
+ KX_PYMETHOD_DOC(SCA_RandomActuator,GetPara2);
+ /* 7. setDistribution -removed- */
+ /* 8. getDistribution */
+ KX_PYMETHOD_DOC(SCA_RandomActuator,GetDistribution);
+ /* 9. setProperty */
+ KX_PYMETHOD_DOC(SCA_RandomActuator,SetProperty);
+ /* 10. getProperty */
+ KX_PYMETHOD_DOC(SCA_RandomActuator,GetProperty);
+ /* 11. setBoolConst */
+ KX_PYMETHOD_DOC(SCA_RandomActuator,SetBoolConst);
+ /* 12. setBoolUniform, */
+ KX_PYMETHOD_DOC(SCA_RandomActuator,SetBoolUniform);
+ /* 13. setBoolBernouilli, */
+ KX_PYMETHOD_DOC(SCA_RandomActuator,SetBoolBernouilli);
+ /* 14. setIntConst,*/
+ KX_PYMETHOD_DOC(SCA_RandomActuator,SetIntConst);
+ /* 15. setIntUniform,*/
+ KX_PYMETHOD_DOC(SCA_RandomActuator,SetIntUniform);
+ /* 16. setIntPoisson, */
+ KX_PYMETHOD_DOC(SCA_RandomActuator,SetIntPoisson);
+ /* 17. setFloatConst,*/
+ KX_PYMETHOD_DOC(SCA_RandomActuator,SetFloatConst);
+ /* 18. setFloatUniform, */
+ KX_PYMETHOD_DOC(SCA_RandomActuator,SetFloatUniform);
+ /* 19. setFloatNormal, */
+ KX_PYMETHOD_DOC(SCA_RandomActuator,SetFloatNormal);
+ /* 20. setFloatNegativeExponential, */
+ KX_PYMETHOD_DOC(SCA_RandomActuator,SetFloatNegativeExponential);
+
+}; /* end of class KX_EditObjectActuator : public SCA_PropertyActuator */
+
+#endif
diff --git a/source/gameengine/GameLogic/SCA_RandomEventManager.cpp b/source/gameengine/GameLogic/SCA_RandomEventManager.cpp
new file mode 100644
index 00000000000..12cf78d234a
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_RandomEventManager.cpp
@@ -0,0 +1,64 @@
+/**
+ * Manager for random events
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#include "SCA_RandomEventManager.h"
+#include "SCA_LogicManager.h"
+#include "SCA_ISensor.h"
+#include <vector>
+using namespace std;
+
+#include <iostream>
+#include <stdio.h>
+
+SCA_RandomEventManager::SCA_RandomEventManager(class SCA_LogicManager* logicmgr)
+ : m_logicmgr(logicmgr),
+ SCA_EventManager(RANDOM_EVENTMGR)
+{
+}
+
+
+void SCA_RandomEventManager::NextFrame(double curtime,double deltatime)
+{
+ for (vector<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++)
+ {
+ SCA_ISensor *sensor = *i;
+ sensor->Activate(m_logicmgr, NULL);
+ }
+}
+
+
+
+void SCA_RandomEventManager::RegisterSensor(SCA_ISensor* sensor)
+{
+ m_sensors.push_back(sensor);
+};
diff --git a/source/gameengine/GameLogic/SCA_RandomEventManager.h b/source/gameengine/GameLogic/SCA_RandomEventManager.h
new file mode 100644
index 00000000000..1014bddcd82
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_RandomEventManager.h
@@ -0,0 +1,53 @@
+/**
+ * Manager for random events
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_RANDOMEVENTMGR
+#define __KX_RANDOMEVENTMGR
+
+#include "SCA_EventManager.h"
+#include <vector>
+
+using namespace std;
+
+class SCA_RandomEventManager : public SCA_EventManager
+{
+ class SCA_LogicManager* m_logicmgr;
+
+public:
+ SCA_RandomEventManager(class SCA_LogicManager* logicmgr);
+
+ virtual void NextFrame(double curtime,double deltatime);
+ virtual void RegisterSensor(SCA_ISensor* sensor);
+};
+#endif //__KX_RANDOMEVENTMGR
diff --git a/source/gameengine/GameLogic/SCA_RandomNumberGenerator.cpp b/source/gameengine/GameLogic/SCA_RandomNumberGenerator.cpp
new file mode 100644
index 00000000000..7faa76fd01d
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_RandomNumberGenerator.cpp
@@ -0,0 +1,125 @@
+/**
+ * Generate random numbers that can be used by other components. We
+ * convert to different types/distributions elsewhere. This just
+ * delivers a clean, random bitvector.
+ *
+ * $Id$
+ */
+
+/* A C-program for MT19937: Real number version */
+/* genrand() generates one pseudorandom real number (double) */
+/* which is uniformly distributed on [0,1]-interval, for each */
+/* call. sgenrand(seed) set initial values to the working area */
+/* of 624 words. Before genrand(), sgenrand(seed) must be */
+/* called once. (seed is any 32-bit integer except for 0). */
+/* Integer generator is obtained by modifying two lines. */
+/* Coded by Takuji Nishimura, considering the suggestions by */
+/* Topher Cooper and Marc Rieffel in July-Aug. 1997. */
+
+/* This library is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU Library General Public */
+/* License as published by the Free Software Foundation; either */
+/* version 2 of the License, or (at your option) any later */
+/* version. */
+/* This library 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 Library General Public License for more details. */
+/* You should have received a copy of the GNU Library General */
+/* Public License along with this library; if not, write to the */
+/* Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA */
+/* 02111-1307 USA */
+
+/* Copyright (C) 1997 Makoto Matsumoto and Takuji Nishimura. */
+/* When you use this, send an email to: matumoto@math.keio.ac.jp */
+/* with an appropriate reference to your work. */
+
+#include <limits.h>
+#include "SCA_RandomNumberGenerator.h"
+
+/* Period parameters */
+#define N 624
+#define M 397
+#define MATRIX_A 0x9908b0df /* constant vector a */
+#define UPPER_MASK 0x80000000 /* most significant w-r bits */
+#define LOWER_MASK 0x7fffffff /* least significant r bits */
+
+/* Tempering parameters */
+#define TEMPERING_MASK_B 0x9d2c5680
+#define TEMPERING_MASK_C 0xefc60000
+#define TEMPERING_SHIFT_U(y) (y >> 11)
+#define TEMPERING_SHIFT_S(y) (y << 7)
+#define TEMPERING_SHIFT_T(y) (y << 15)
+#define TEMPERING_SHIFT_L(y) (y >> 18)
+
+SCA_RandomNumberGenerator::SCA_RandomNumberGenerator(long seed) {
+ int mti = N + 1;
+ m_seed = seed;
+ SetStartVector();
+}
+
+SCA_RandomNumberGenerator::~SCA_RandomNumberGenerator() {
+ /* intentionally empty */
+}
+
+void SCA_RandomNumberGenerator::SetStartVector(void) {
+ /* setting initial seeds to mt[N] using */
+ /* the generator Line 25 of Table 1 in */
+ /* [KNUTH 1981, The Art of Computer Programming */
+ /* Vol. 2 (2nd Ed.), pp102] */
+ mt[0] = m_seed & 0xffffffff;
+ for (mti = 1; mti < N; mti++)
+ mt[mti] = (69069 * mt[mti-1]) & 0xffffffff;
+}
+
+long SCA_RandomNumberGenerator::GetSeed() { return m_seed; }
+void SCA_RandomNumberGenerator::SetSeed(long newseed)
+{
+ m_seed = newseed;
+ SetStartVector();
+}
+
+/**
+ * This is the important part: copied verbatim :)
+ */
+unsigned long SCA_RandomNumberGenerator::Draw() {
+ static unsigned long mag01[2] = { 0x0, MATRIX_A };
+ /* mag01[x] = x * MATRIX_A for x=0,1 */
+
+ unsigned long y;
+
+ if (mti >= N) { /* generate N words at one time */
+ int kk;
+
+ /* I set this in the constructor, so it is always satisfied ! */
+// if (mti == N+1) /* if sgenrand() has not been called, */
+// GEN_srand(4357); /* a default initial seed is used */
+
+ for (kk = 0; kk < N - M; kk++) {
+ y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
+ mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1];
+ }
+ for (; kk < N-1; kk++) {
+ y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
+ mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1];
+ }
+ y = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
+ mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1];
+
+ mti = 0;
+ }
+
+ y = mt[mti++];
+ y ^= TEMPERING_SHIFT_U(y);
+ y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B;
+ y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C;
+ y ^= TEMPERING_SHIFT_L(y);
+
+ return y;
+}
+
+float SCA_RandomNumberGenerator::DrawFloat() {
+ return ( (float) Draw()/ (unsigned long) 0xffffffff );
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_RandomNumberGenerator.h b/source/gameengine/GameLogic/SCA_RandomNumberGenerator.h
new file mode 100644
index 00000000000..c6cd52dd3db
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_RandomNumberGenerator.h
@@ -0,0 +1,65 @@
+/**
+ * Generate random numbers that can be used by other components. Each
+ * generator needs its own generator, so that the seed can be set
+ * on a per-generator basis.
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_RANDOMNUMBERGENERATOR
+#define __KX_RANDOMNUMBERGENERATOR
+
+
+class SCA_RandomNumberGenerator {
+
+ /** base seed */
+ long m_seed;
+
+ /* A bit silly.. The N parameter is a define in the .cpp file */
+ /** the array for the state vector */
+ /* unsigned long mt[N]; */
+ unsigned long mt[624];
+
+ /** mti==N+1 means mt[KX_MT_VectorLenght] is not initialized */
+ int mti; /* initialised in the cpp file */
+
+ /** Calculate a start vector */
+ void SetStartVector(void);
+ public:
+ SCA_RandomNumberGenerator(long seed);
+ ~SCA_RandomNumberGenerator();
+ unsigned long Draw();
+ float DrawFloat();
+ long GetSeed();
+ void SetSeed(long newseed);
+};
+
+#endif /* __KX_RANDOMNUMBERGENERATOR */
diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.cpp b/source/gameengine/GameLogic/SCA_RandomSensor.cpp
new file mode 100644
index 00000000000..7f3f2f93315
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_RandomSensor.cpp
@@ -0,0 +1,191 @@
+/**
+ * Generate random pulses
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "SCA_RandomSensor.h"
+#include "SCA_EventManager.h"
+#include "SCA_RandomEventManager.h"
+#include "SCA_LogicManager.h"
+#include "ConstExpr.h"
+#include <iostream>
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_RandomSensor::SCA_RandomSensor(SCA_EventManager* eventmgr,
+ SCA_IObject* gameobj,
+ int startseed,
+ PyTypeObject* T)
+ : SCA_ISensor(gameobj,eventmgr, T)
+{
+ m_iteration = 0;
+ m_lastdraw = false;
+
+ m_basegenerator = new SCA_RandomNumberGenerator(startseed);
+ m_currentDraw = m_basegenerator->Draw();
+ RegisterToManager();
+}
+
+
+
+SCA_RandomSensor::~SCA_RandomSensor()
+{
+ /* Nothing to be done here. */
+}
+
+
+
+CValue* SCA_RandomSensor::GetReplica()
+{
+ CValue* replica = new SCA_RandomSensor(*this);
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+bool SCA_RandomSensor::IsPositiveTrigger()
+{
+ return (m_invert !=m_lastdraw);
+}
+
+
+bool SCA_RandomSensor::Evaluate(CValue* event)
+{
+ /* Random generator is the generator from Line 25 of Table 1 in */
+ /* [KNUTH 1981, The Art of Computer Programming Vol. 2 */
+ /* (2nd Ed.), pp102] */
+ /* It's a very simple max. length sequence generator. We can */
+ /* draw 32 bool values before having to generate the next */
+ /* sequence value. There are some theorems that will tell you */
+ /* this is a reasonable way of generating bools. Check Knuth. */
+ /* Furthermore, we only draw each <delay>-eth frame. */
+
+ bool drawResult = false;
+
+ if (m_iteration > 31) {
+ m_currentDraw = m_basegenerator->Draw();
+ drawResult = (m_currentDraw & 0x1) == 0;
+ m_iteration = 1;
+ } else {
+ drawResult = ((m_currentDraw >> m_iteration) & 0x1) == 0;
+ m_iteration++;
+ }
+
+ /* now pass this result to some controller */
+ m_lastdraw = drawResult;
+ return drawResult;
+}
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_RandomSensor::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_RandomSensor",
+ sizeof(SCA_RandomSensor),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_RandomSensor::Parents[] = {
+ &SCA_RandomSensor::Type,
+ &SCA_ISensor::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef SCA_RandomSensor::Methods[] = {
+ {"setSeed", (PyCFunction) SCA_RandomSensor::sPySetSeed, METH_VARARGS, SetSeed_doc},
+ {"getSeed", (PyCFunction) SCA_RandomSensor::sPyGetSeed, METH_VARARGS, GetSeed_doc},
+ {"getLastDraw", (PyCFunction) SCA_RandomSensor::sPyGetLastDraw, METH_VARARGS, GetLastDraw_doc},
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* SCA_RandomSensor::_getattr(char* attr) {
+ _getattr_up(SCA_ISensor);
+}
+
+/* 1. setSeed */
+char SCA_RandomSensor::SetSeed_doc[] =
+"setSeed(seed)\n"
+"\t- seed: integer\n"
+"\tSet the initial seed of the generator. Equal seeds produce\n"
+"\tequal series. If the seed is 0, the generator will produce\n"
+"\tthe same value on every call.\n";
+PyObject* SCA_RandomSensor::PySetSeed(PyObject* self, PyObject* args, PyObject* kwds) {
+ long seedArg;
+ if(!PyArg_ParseTuple(args, "i", &seedArg)) {
+ return NULL;
+ }
+
+ m_basegenerator->SetSeed(seedArg);
+
+ Py_Return;
+}
+
+/* 2. getSeed */
+char SCA_RandomSensor::GetSeed_doc[] =
+"getSeed()\n"
+"\tReturns the initial seed of the generator. Equal seeds produce\n"
+"\tequal series.\n";
+PyObject* SCA_RandomSensor::PyGetSeed(PyObject* self, PyObject* args, PyObject* kwds) {
+ return PyInt_FromLong(m_basegenerator->GetSeed());
+}
+
+/* 3. getLastDraw */
+char SCA_RandomSensor::GetLastDraw_doc[] =
+"getLastDraw()\n"
+"\tReturn the last value that was drawn.\n";
+PyObject* SCA_RandomSensor::PyGetLastDraw(PyObject* self, PyObject* args, PyObject* kwds) {
+ return PyInt_FromLong(m_lastdraw);
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.h b/source/gameengine/GameLogic/SCA_RandomSensor.h
new file mode 100644
index 00000000000..6a77f289be5
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_RandomSensor.h
@@ -0,0 +1,75 @@
+/**
+ * Generate random pulses
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_RANDOMSENSOR
+#define __KX_RANDOMSENSOR
+
+#include "SCA_ISensor.h"
+#include "BoolValue.h"
+#include "SCA_RandomNumberGenerator.h"
+
+class SCA_RandomSensor : public SCA_ISensor
+{
+ Py_Header;
+
+ unsigned int m_currentDraw;
+ int m_iteration;
+ SCA_RandomNumberGenerator *m_basegenerator;
+ bool m_lastdraw;
+public:
+ SCA_RandomSensor(class SCA_EventManager* rndmgr,
+ SCA_IObject* gameobj,
+ int startseed,
+ PyTypeObject* T=&Type);
+ virtual ~SCA_RandomSensor();
+ virtual CValue* GetReplica();
+ virtual bool Evaluate(CValue* event);
+ virtual bool IsPositiveTrigger();
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(char *attr);
+
+ /* 1. setSeed */
+ KX_PYMETHOD_DOC(SCA_RandomSensor,SetSeed);
+ /* 2. getSeed */
+ KX_PYMETHOD_DOC(SCA_RandomSensor,GetSeed);
+ /* 3. getSeed */
+ KX_PYMETHOD_DOC(SCA_RandomSensor,GetLastDraw);
+
+};
+
+#endif //__KX_RANDOMSENSOR
diff --git a/source/gameengine/GameLogic/SCA_TimeEventManager.cpp b/source/gameengine/GameLogic/SCA_TimeEventManager.cpp
new file mode 100644
index 00000000000..784afcce298
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_TimeEventManager.cpp
@@ -0,0 +1,110 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifdef WIN32
+
+// This warning tells us about truncation of __long__ stl-generated names.
+// It can occasionally cause DevStudio to have internal compiler warnings.
+#pragma warning( disable : 4786 )
+#endif
+
+#include "SCA_TimeEventManager.h"
+
+#include "SCA_LogicManager.h"
+#include "FloatValue.h"
+
+SCA_TimeEventManager::SCA_TimeEventManager(SCA_LogicManager* logicmgr)
+: SCA_EventManager(TIME_EVENTMGR)
+{
+}
+
+
+
+SCA_TimeEventManager::~SCA_TimeEventManager()
+{
+ for (vector<CValue*>::iterator it = m_timevalues.begin();
+ !(it == m_timevalues.end()); it++)
+ {
+ (*it)->Release();
+ }
+}
+
+
+
+void SCA_TimeEventManager::RegisterSensor(SCA_ISensor* sensor)
+{
+ // not yet
+}
+
+
+
+void SCA_TimeEventManager::NextFrame(double curtime,double deltatime)
+{
+ if (m_timevalues.size() > 0)
+ {
+ CFloatValue* floatval = new CFloatValue(curtime);
+
+ // update sensors, but ... need deltatime !
+ for (vector<CValue*>::iterator it = m_timevalues.begin();
+ !(it == m_timevalues.end()); it++)
+ {
+ float newtime = (*it)->GetNumber() + deltatime;
+ floatval->SetFloat(newtime);
+ (*it)->SetValue(floatval);
+ }
+
+ floatval->Release();
+ }
+}
+
+
+
+void SCA_TimeEventManager::AddTimeProperty(CValue* timeval)
+{
+ timeval->AddRef();
+ m_timevalues.push_back(timeval);
+}
+
+
+
+void SCA_TimeEventManager::RemoveTimeProperty(CValue* timeval)
+{
+ for (vector<CValue*>::iterator it = m_timevalues.begin();
+ !(it == m_timevalues.end()); it++)
+ {
+ if ((*it) == timeval)
+ {
+ this->m_timevalues.erase(it);
+ timeval->Release();
+ break;
+ }
+ }
+}
diff --git a/source/gameengine/GameLogic/SCA_TimeEventManager.h b/source/gameengine/GameLogic/SCA_TimeEventManager.h
new file mode 100644
index 00000000000..880659e1a87
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_TimeEventManager.h
@@ -0,0 +1,54 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef __KX_TIMEEVENTMANAGER
+#define __KX_TIMEEVENTMANAGER
+
+#include "SCA_EventManager.h"
+#include "Value.h"
+#include <vector>
+
+using namespace std;
+
+class SCA_TimeEventManager : public SCA_EventManager
+{
+ vector<CValue*> m_timevalues; // values that need their time updated regularly
+
+public:
+ SCA_TimeEventManager(class SCA_LogicManager* logicmgr);
+ virtual ~SCA_TimeEventManager();
+
+ virtual void NextFrame(double curtime,double deltatime);
+ virtual void RegisterSensor(class SCA_ISensor* sensor);
+ void AddTimeProperty(CValue* timeval);
+ void RemoveTimeProperty(CValue* timeval);
+};
+#endif //__KX_TIMEEVENTMANAGER