diff options
Diffstat (limited to 'source/gameengine/GameLogic')
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", ¶Arg)) { + 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", ¶Arg)) { + 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", ¶Arg)) { + 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", ¶Arg1, ¶Arg2)) { + 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", ¶Arg)) { + 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", ¶Arg)) { + 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", ¶Arg1, ¶Arg2)) { + 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", ¶Arg1, ¶Arg2)) { + 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", ¶Arg)) { + 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 |