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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/gameengine')
-rw-r--r--source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp374
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp164
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderCanvas.h165
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderGL.cpp259
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderGL.h66
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderInputDevice.cpp32
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h220
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp161
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.h48
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.cpp177
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.h48
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.cpp106
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.h98
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp411
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h100
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderSystem.cpp56
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderSystem.h51
-rw-r--r--source/gameengine/BlenderRoutines/Makefile75
-rw-r--r--source/gameengine/Converter/BL_ActionActuator.cpp805
-rw-r--r--source/gameengine/Converter/BL_ActionActuator.h126
-rw-r--r--source/gameengine/Converter/BL_ArmatureObject.cpp149
-rw-r--r--source/gameengine/Converter/BL_ArmatureObject.h79
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp1227
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.h54
-rw-r--r--source/gameengine/Converter/BL_DeformableGameObject.cpp62
-rw-r--r--source/gameengine/Converter/BL_DeformableGameObject.h66
-rw-r--r--source/gameengine/Converter/BL_MeshDeformer.cpp165
-rw-r--r--source/gameengine/Converter/BL_MeshDeformer.h72
-rw-r--r--source/gameengine/Converter/BL_SkinDeformer.cpp187
-rw-r--r--source/gameengine/Converter/BL_SkinDeformer.h98
-rw-r--r--source/gameengine/Converter/BL_SkinMeshObject.cpp152
-rw-r--r--source/gameengine/Converter/BL_SkinMeshObject.h184
-rw-r--r--source/gameengine/Converter/BlenderWorldInfo.cpp215
-rw-r--r--source/gameengine/Converter/BlenderWorldInfo.h95
-rw-r--r--source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp81
-rw-r--r--source/gameengine/Converter/KX_BlenderScalarInterpolator.h70
-rw-r--r--source/gameengine/Converter/KX_BlenderSceneConverter.cpp416
-rw-r--r--source/gameengine/Converter/KX_BlenderSceneConverter.h120
-rw-r--r--source/gameengine/Converter/KX_ConvertActuators.cpp909
-rw-r--r--source/gameengine/Converter/KX_ConvertActuators.h48
-rw-r--r--source/gameengine/Converter/KX_ConvertControllers.cpp179
-rw-r--r--source/gameengine/Converter/KX_ConvertControllers.h51
-rw-r--r--source/gameengine/Converter/KX_ConvertProperties.cpp134
-rw-r--r--source/gameengine/Converter/KX_ConvertProperties.h41
-rw-r--r--source/gameengine/Converter/KX_ConvertSensors.cpp658
-rw-r--r--source/gameengine/Converter/KX_ConvertSensors.h47
-rw-r--r--source/gameengine/Converter/KX_IpoConvert.cpp559
-rw-r--r--source/gameengine/Converter/KX_IpoConvert.h54
-rw-r--r--source/gameengine/Converter/Makefile60
-rw-r--r--source/gameengine/Expressions/BoolValue.cpp213
-rw-r--r--source/gameengine/Expressions/BoolValue.h51
-rw-r--r--source/gameengine/Expressions/ConstExpr.cpp132
-rw-r--r--source/gameengine/Expressions/ConstExpr.h46
-rw-r--r--source/gameengine/Expressions/EXP_C-Api.cpp124
-rw-r--r--source/gameengine/Expressions/EXP_C-Api.h68
-rw-r--r--source/gameengine/Expressions/EmptyValue.cpp127
-rw-r--r--source/gameengine/Expressions/EmptyValue.h39
-rw-r--r--source/gameengine/Expressions/ErrorValue.cpp125
-rw-r--r--source/gameengine/Expressions/ErrorValue.h38
-rw-r--r--source/gameengine/Expressions/Expression.cpp75
-rw-r--r--source/gameengine/Expressions/Expression.h133
-rw-r--r--source/gameengine/Expressions/FloatValue.cpp316
-rw-r--r--source/gameengine/Expressions/FloatValue.h48
-rw-r--r--source/gameengine/Expressions/IdentifierExpr.cpp103
-rw-r--r--source/gameengine/Expressions/IdentifierExpr.h55
-rw-r--r--source/gameengine/Expressions/IfExpr.cpp141
-rw-r--r--source/gameengine/Expressions/IfExpr.h49
-rw-r--r--source/gameengine/Expressions/InputParser.cpp648
-rw-r--r--source/gameengine/Expressions/InputParser.h105
-rw-r--r--source/gameengine/Expressions/IntValue.cpp325
-rw-r--r--source/gameengine/Expressions/IntValue.h60
-rw-r--r--source/gameengine/Expressions/KX_HashedPtr.cpp58
-rw-r--r--source/gameengine/Expressions/KX_HashedPtr.h53
-rw-r--r--source/gameengine/Expressions/ListValue.cpp536
-rw-r--r--source/gameengine/Expressions/ListValue.h77
-rw-r--r--source/gameengine/Expressions/Makefile45
-rw-r--r--source/gameengine/Expressions/Operator1Expr.cpp148
-rw-r--r--source/gameengine/Expressions/Operator1Expr.h53
-rw-r--r--source/gameengine/Expressions/Operator2Expr.cpp275
-rw-r--r--source/gameengine/Expressions/Operator2Expr.h59
-rw-r--r--source/gameengine/Expressions/PyObjectPlus.cpp157
-rw-r--r--source/gameengine/Expressions/PyObjectPlus.h135
-rw-r--r--source/gameengine/Expressions/StringValue.cpp139
-rw-r--r--source/gameengine/Expressions/StringValue.h51
-rw-r--r--source/gameengine/Expressions/Value.cpp767
-rw-r--r--source/gameengine/Expressions/Value.h467
-rw-r--r--source/gameengine/Expressions/VectorValue.cpp213
-rw-r--r--source/gameengine/Expressions/VectorValue.h86
-rw-r--r--source/gameengine/Expressions/VoidValue.h68
-rw-r--r--source/gameengine/GameLogic/Makefile47
-rw-r--r--source/gameengine/GameLogic/SCA_ANDController.cpp143
-rw-r--r--source/gameengine/GameLogic/SCA_ANDController.h58
-rw-r--r--source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp67
-rw-r--r--source/gameengine/GameLogic/SCA_AlwaysEventManager.h48
-rw-r--r--source/gameengine/GameLogic/SCA_AlwaysSensor.cpp138
-rw-r--r--source/gameengine/GameLogic/SCA_AlwaysSensor.h62
-rw-r--r--source/gameengine/GameLogic/SCA_EventManager.cpp71
-rw-r--r--source/gameengine/GameLogic/SCA_EventManager.h69
-rw-r--r--source/gameengine/GameLogic/SCA_ExpressionController.cpp161
-rw-r--r--source/gameengine/GameLogic/SCA_ExpressionController.h64
-rw-r--r--source/gameengine/GameLogic/SCA_IActuator.cpp104
-rw-r--r--source/gameengine/GameLogic/SCA_IActuator.h81
-rw-r--r--source/gameengine/GameLogic/SCA_IController.cpp120
-rw-r--r--source/gameengine/GameLogic/SCA_IController.h56
-rw-r--r--source/gameengine/GameLogic/SCA_IInputDevice.cpp138
-rw-r--r--source/gameengine/GameLogic/SCA_IInputDevice.h307
-rw-r--r--source/gameengine/GameLogic/SCA_ILogicBrick.cpp325
-rw-r--r--source/gameengine/GameLogic/SCA_ILogicBrick.h111
-rw-r--r--source/gameengine/GameLogic/SCA_IObject.cpp363
-rw-r--r--source/gameengine/GameLogic/SCA_IObject.h126
-rw-r--r--source/gameengine/GameLogic/SCA_IScene.cpp67
-rw-r--r--source/gameengine/GameLogic/SCA_IScene.h62
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.cpp328
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.h130
-rw-r--r--source/gameengine/GameLogic/SCA_KeyboardManager.cpp91
-rw-r--r--source/gameengine/GameLogic/SCA_KeyboardManager.h66
-rw-r--r--source/gameengine/GameLogic/SCA_KeyboardSensor.cpp675
-rw-r--r--source/gameengine/GameLogic/SCA_KeyboardSensor.h158
-rw-r--r--source/gameengine/GameLogic/SCA_LogicManager.cpp461
-rw-r--r--source/gameengine/GameLogic/SCA_LogicManager.h154
-rw-r--r--source/gameengine/GameLogic/SCA_MouseManager.cpp116
-rw-r--r--source/gameengine/GameLogic/SCA_MouseManager.h72
-rw-r--r--source/gameengine/GameLogic/SCA_MouseSensor.cpp273
-rw-r--r--source/gameengine/GameLogic/SCA_MouseSensor.h120
-rw-r--r--source/gameengine/GameLogic/SCA_ORController.cpp135
-rw-r--r--source/gameengine/GameLogic/SCA_ORController.h58
-rw-r--r--source/gameengine/GameLogic/SCA_PropertyActuator.cpp285
-rw-r--r--source/gameengine/GameLogic/SCA_PropertyActuator.h116
-rw-r--r--source/gameengine/GameLogic/SCA_PropertyEventManager.cpp67
-rw-r--r--source/gameengine/GameLogic/SCA_PropertyEventManager.h52
-rw-r--r--source/gameengine/GameLogic/SCA_PropertySensor.cpp420
-rw-r--r--source/gameengine/GameLogic/SCA_PropertySensor.h109
-rw-r--r--source/gameengine/GameLogic/SCA_PythonController.cpp400
-rw-r--r--source/gameengine/GameLogic/SCA_PythonController.h88
-rw-r--r--source/gameengine/GameLogic/SCA_RandomActuator.cpp630
-rw-r--r--source/gameengine/GameLogic/SCA_RandomActuator.h144
-rw-r--r--source/gameengine/GameLogic/SCA_RandomEventManager.cpp64
-rw-r--r--source/gameengine/GameLogic/SCA_RandomEventManager.h53
-rw-r--r--source/gameengine/GameLogic/SCA_RandomNumberGenerator.cpp125
-rw-r--r--source/gameengine/GameLogic/SCA_RandomNumberGenerator.h65
-rw-r--r--source/gameengine/GameLogic/SCA_RandomSensor.cpp191
-rw-r--r--source/gameengine/GameLogic/SCA_RandomSensor.h75
-rw-r--r--source/gameengine/GameLogic/SCA_TimeEventManager.cpp110
-rw-r--r--source/gameengine/GameLogic/SCA_TimeEventManager.h54
-rw-r--r--source/gameengine/GamePlayer/Makefile56
-rw-r--r--source/gameengine/GamePlayer/common/GPC_Canvas.cpp371
-rw-r--r--source/gameengine/GamePlayer/common/GPC_Canvas.h275
-rw-r--r--source/gameengine/GamePlayer/common/GPC_Engine.cpp337
-rw-r--r--source/gameengine/GamePlayer/common/GPC_Engine.h130
-rw-r--r--source/gameengine/GamePlayer/common/GPC_KeyboardDevice.cpp124
-rw-r--r--source/gameengine/GamePlayer/common/GPC_KeyboardDevice.h87
-rw-r--r--source/gameengine/GamePlayer/common/GPC_MouseDevice.cpp207
-rw-r--r--source/gameengine/GamePlayer/common/GPC_MouseDevice.h105
-rw-r--r--source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp410
-rw-r--r--source/gameengine/GamePlayer/common/GPC_PolygonMaterial.h87
-rw-r--r--source/gameengine/GamePlayer/common/GPC_RawImage.cpp135
-rw-r--r--source/gameengine/GamePlayer/common/GPC_RawImage.h122
-rw-r--r--source/gameengine/GamePlayer/common/GPC_RawLoadDotBlendArray.cpp9312
-rw-r--r--source/gameengine/GamePlayer/common/GPC_RawLoadDotBlendArray.h40
-rw-r--r--source/gameengine/GamePlayer/common/GPC_RawLogoArrays.cpp1462
-rw-r--r--source/gameengine/GamePlayer/common/GPC_RawLogoArrays.h44
-rw-r--r--source/gameengine/GamePlayer/common/GPC_RenderTools.cpp498
-rw-r--r--source/gameengine/GamePlayer/common/GPC_RenderTools.h176
-rw-r--r--source/gameengine/GamePlayer/common/GPC_System.cpp90
-rw-r--r--source/gameengine/GamePlayer/common/GPC_System.h64
-rw-r--r--source/gameengine/GamePlayer/common/Makefile83
-rw-r--r--source/gameengine/GamePlayer/common/bmfont.cpp301
-rw-r--r--source/gameengine/GamePlayer/common/load.blendbin0 -> 135908 bytes
-rw-r--r--source/gameengine/GamePlayer/common/logo_blender.rawbin0 -> 14720 bytes
-rw-r--r--source/gameengine/GamePlayer/common/logo_blender3d.rawbin0 -> 5984 bytes
-rw-r--r--source/gameengine/GamePlayer/common/logo_nan.rawbin0 -> 3968 bytes
-rw-r--r--source/gameengine/GamePlayer/common/unix/GPU_Canvas.cpp72
-rw-r--r--source/gameengine/GamePlayer/common/unix/GPU_Canvas.h60
-rw-r--r--source/gameengine/GamePlayer/common/unix/GPU_Engine.cpp307
-rw-r--r--source/gameengine/GamePlayer/common/unix/GPU_Engine.h65
-rw-r--r--source/gameengine/GamePlayer/common/unix/GPU_KeyboardDevice.cpp137
-rw-r--r--source/gameengine/GamePlayer/common/unix/GPU_KeyboardDevice.h64
-rw-r--r--source/gameengine/GamePlayer/common/unix/GPU_PolygonMaterial.h57
-rw-r--r--source/gameengine/GamePlayer/common/unix/GPU_System.cpp56
-rw-r--r--source/gameengine/GamePlayer/common/unix/GPU_System.h51
-rw-r--r--source/gameengine/GamePlayer/common/unix/Makefile81
-rw-r--r--source/gameengine/GamePlayer/common/windows/GPW_Canvas.cpp174
-rw-r--r--source/gameengine/GamePlayer/common/windows/GPW_Canvas.h119
-rw-r--r--source/gameengine/GamePlayer/common/windows/GPW_Engine.cpp120
-rw-r--r--source/gameengine/GamePlayer/common/windows/GPW_Engine.h50
-rw-r--r--source/gameengine/GamePlayer/common/windows/GPW_KeyboardDevice.cpp280
-rw-r--r--source/gameengine/GamePlayer/common/windows/GPW_KeyboardDevice.h69
-rw-r--r--source/gameengine/GamePlayer/common/windows/GPW_System.cpp93
-rw-r--r--source/gameengine/GamePlayer/common/windows/GPW_System.h62
-rw-r--r--source/gameengine/GamePlayer/common/windows/Makefile66
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_Application.cpp607
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_Application.h138
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_Canvas.cpp110
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_Canvas.h64
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_KeyboardDevice.cpp156
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_KeyboardDevice.h57
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_System.cpp56
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_System.h56
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_ghost.cpp597
-rw-r--r--source/gameengine/GamePlayer/ghost/Makefile82
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp92
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h59
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp208
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h77
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp258
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h85
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkObjectActuator.cpp31
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkObjectActuator.h31
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkObjectSensor.cpp31
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkObjectSensor.h31
-rw-r--r--source/gameengine/Ketsji/KXNetwork/Makefile48
-rw-r--r--source/gameengine/Ketsji/KX_CDActuator.cpp252
-rw-r--r--source/gameengine/Ketsji/KX_CDActuator.h97
-rw-r--r--source/gameengine/Ketsji/KX_Camera.cpp181
-rw-r--r--source/gameengine/Ketsji/KX_Camera.h114
-rw-r--r--source/gameengine/Ketsji/KX_CameraActuator.cpp368
-rw-r--r--source/gameengine/Ketsji/KX_CameraActuator.h128
-rw-r--r--source/gameengine/Ketsji/KX_CameraIpoSGController.cpp125
-rw-r--r--source/gameengine/Ketsji/KX_CameraIpoSGController.h91
-rw-r--r--source/gameengine/Ketsji/KX_ClientObjectInfo.h46
-rw-r--r--source/gameengine/Ketsji/KX_ConstraintActuator.cpp369
-rw-r--r--source/gameengine/Ketsji/KX_ConstraintActuator.h109
-rw-r--r--source/gameengine/Ketsji/KX_ConstraintWrapper.cpp131
-rw-r--r--source/gameengine/Ketsji/KX_ConstraintWrapper.h57
-rw-r--r--source/gameengine/Ketsji/KX_ConvertPhysicsObject.h110
-rw-r--r--source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp427
-rw-r--r--source/gameengine/Ketsji/KX_EmptyObject.cpp32
-rw-r--r--source/gameengine/Ketsji/KX_EmptyObject.h45
-rw-r--r--source/gameengine/Ketsji/KX_GameActuator.cpp186
-rw-r--r--source/gameengine/Ketsji/KX_GameActuator.h86
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp1096
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h614
-rw-r--r--source/gameengine/Ketsji/KX_IInterpolator.h46
-rw-r--r--source/gameengine/Ketsji/KX_IPOTransform.h92
-rw-r--r--source/gameengine/Ketsji/KX_IPO_SGController.cpp193
-rw-r--r--source/gameengine/Ketsji/KX_IPO_SGController.h111
-rw-r--r--source/gameengine/Ketsji/KX_IPhysicsController.cpp45
-rw-r--r--source/gameengine/Ketsji/KX_IPhysicsController.h99
-rw-r--r--source/gameengine/Ketsji/KX_IScalarInterpolator.h42
-rw-r--r--source/gameengine/Ketsji/KX_ISceneConverter.h64
-rw-r--r--source/gameengine/Ketsji/KX_ISystem.h55
-rw-r--r--source/gameengine/Ketsji/KX_IpoActuator.cpp643
-rw-r--r--source/gameengine/Ketsji/KX_IpoActuator.h141
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp1250
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.h316
-rw-r--r--source/gameengine/Ketsji/KX_Light.cpp75
-rw-r--r--source/gameengine/Ketsji/KX_Light.h50
-rw-r--r--source/gameengine/Ketsji/KX_LightIpoSGController.cpp118
-rw-r--r--source/gameengine/Ketsji/KX_LightIpoSGController.h99
-rw-r--r--source/gameengine/Ketsji/KX_MeshProxy.cpp193
-rw-r--r--source/gameengine/Ketsji/KX_MeshProxy.h66
-rw-r--r--source/gameengine/Ketsji/KX_MotionState.cpp91
-rw-r--r--source/gameengine/Ketsji/KX_MotionState.h54
-rw-r--r--source/gameengine/Ketsji/KX_MouseFocusSensor.cpp353
-rw-r--r--source/gameengine/Ketsji/KX_MouseFocusSensor.h152
-rw-r--r--source/gameengine/Ketsji/KX_NearSensor.cpp262
-rw-r--r--source/gameengine/Ketsji/KX_NearSensor.h61
-rw-r--r--source/gameengine/Ketsji/KX_ObColorIpoSGController.cpp107
-rw-r--r--source/gameengine/Ketsji/KX_ObColorIpoSGController.h77
-rw-r--r--source/gameengine/Ketsji/KX_ObjectActuator.cpp400
-rw-r--r--source/gameengine/Ketsji/KX_ObjectActuator.h140
-rw-r--r--source/gameengine/Ketsji/KX_OrientationInterpolator.cpp56
-rw-r--r--source/gameengine/Ketsji/KX_OrientationInterpolator.h58
-rw-r--r--source/gameengine/Ketsji/KX_PhysicsEngineEnums.h44
-rw-r--r--source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp161
-rw-r--r--source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h58
-rw-r--r--source/gameengine/Ketsji/KX_PhysicsPropertiesobsolete.h60
-rw-r--r--source/gameengine/Ketsji/KX_PositionInterpolator.cpp42
-rw-r--r--source/gameengine/Ketsji/KX_PositionInterpolator.h58
-rw-r--r--source/gameengine/Ketsji/KX_PyConstraintBinding.cpp193
-rw-r--r--source/gameengine/Ketsji/KX_PyConstraintBinding.h43
-rw-r--r--source/gameengine/Ketsji/KX_Python.h38
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.cpp832
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.h55
-rw-r--r--source/gameengine/Ketsji/KX_Python_dynamic.h38
-rw-r--r--source/gameengine/Ketsji/KX_Python_static.h38
-rw-r--r--source/gameengine/Ketsji/KX_RadarSensor.cpp220
-rw-r--r--source/gameengine/Ketsji/KX_RadarSensor.h93
-rw-r--r--source/gameengine/Ketsji/KX_RayEventManager.cpp55
-rw-r--r--source/gameengine/Ketsji/KX_RayEventManager.h52
-rw-r--r--source/gameengine/Ketsji/KX_RaySensor.cpp381
-rw-r--r--source/gameengine/Ketsji/KX_RaySensor.h79
-rw-r--r--source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp335
-rw-r--r--source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h133
-rw-r--r--source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp137
-rw-r--r--source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h80
-rw-r--r--source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp182
-rw-r--r--source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h88
-rw-r--r--source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp328
-rw-r--r--source/gameengine/Ketsji/KX_SG_NodeRelationships.h214
-rw-r--r--source/gameengine/Ketsji/KX_ScalarInterpolator.cpp38
-rw-r--r--source/gameengine/Ketsji/KX_ScalarInterpolator.h63
-rw-r--r--source/gameengine/Ketsji/KX_ScalingInterpolator.cpp42
-rw-r--r--source/gameengine/Ketsji/KX_ScalingInterpolator.h61
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp977
-rw-r--r--source/gameengine/Ketsji/KX_Scene.h480
-rw-r--r--source/gameengine/Ketsji/KX_SceneActuator.cpp354
-rw-r--r--source/gameengine/Ketsji/KX_SceneActuator.h115
-rw-r--r--source/gameengine/Ketsji/KX_SoundActuator.cpp466
-rw-r--r--source/gameengine/Ketsji/KX_SoundActuator.h106
-rw-r--r--source/gameengine/Ketsji/KX_SumoPhysicsController.cpp204
-rw-r--r--source/gameengine/Ketsji/KX_SumoPhysicsController.h81
-rw-r--r--source/gameengine/Ketsji/KX_TimeCategoryLogger.cpp142
-rw-r--r--source/gameengine/Ketsji/KX_TimeCategoryLogger.h133
-rw-r--r--source/gameengine/Ketsji/KX_TimeLogger.cpp117
-rw-r--r--source/gameengine/Ketsji/KX_TimeLogger.h107
-rw-r--r--source/gameengine/Ketsji/KX_TouchEventManager.cpp117
-rw-r--r--source/gameengine/Ketsji/KX_TouchEventManager.h67
-rw-r--r--source/gameengine/Ketsji/KX_TouchSensor.cpp393
-rw-r--r--source/gameengine/Ketsji/KX_TouchSensor.h146
-rw-r--r--source/gameengine/Ketsji/KX_TrackToActuator.cpp487
-rw-r--r--source/gameengine/Ketsji/KX_TrackToActuator.h85
-rw-r--r--source/gameengine/Ketsji/KX_VertexProxy.cpp217
-rw-r--r--source/gameengine/Ketsji/KX_VertexProxy.h70
-rw-r--r--source/gameengine/Ketsji/KX_VisibilityActuator.cpp161
-rw-r--r--source/gameengine/Ketsji/KX_VisibilityActuator.h80
-rw-r--r--source/gameengine/Ketsji/KX_WorldInfo.cpp38
-rw-r--r--source/gameengine/Ketsji/KX_WorldInfo.h65
-rw-r--r--source/gameengine/Ketsji/KX_WorldIpoController.cpp111
-rw-r--r--source/gameengine/Ketsji/KX_WorldIpoController.h99
-rw-r--r--source/gameengine/Ketsji/Makefile60
-rw-r--r--source/gameengine/Makefile43
-rw-r--r--source/gameengine/Network/LoopBackNetwork/Makefile44
-rw-r--r--source/gameengine/Network/LoopBackNetwork/NG_LoopBackNetworkDeviceInterface.cpp110
-rw-r--r--source/gameengine/Network/LoopBackNetwork/NG_LoopBackNetworkDeviceInterface.h68
-rw-r--r--source/gameengine/Network/Makefile50
-rw-r--r--source/gameengine/Network/NG_NetworkDeviceInterface.h85
-rw-r--r--source/gameengine/Network/NG_NetworkMessage.cpp55
-rw-r--r--source/gameengine/Network/NG_NetworkMessage.h130
-rw-r--r--source/gameengine/Network/NG_NetworkObject.cpp46
-rw-r--r--source/gameengine/Network/NG_NetworkObject.h47
-rw-r--r--source/gameengine/Network/NG_NetworkScene.cpp271
-rw-r--r--source/gameengine/Network/NG_NetworkScene.h102
-rw-r--r--source/gameengine/Network/TerraplayNetwork/Makefile45
-rw-r--r--source/gameengine/Network/TerraplayNetwork/NG_TerraplayNetworkDeviceInterface.cpp192
-rw-r--r--source/gameengine/Network/TerraplayNetwork/NG_TerraplayNetworkDeviceInterface.h70
-rw-r--r--source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp91
-rw-r--r--source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h70
-rw-r--r--source/gameengine/Physics/Dummy/Makefile47
-rw-r--r--source/gameengine/Physics/Makefile40
-rw-r--r--source/gameengine/Physics/Sumo/Fuzzics/Makefile9
-rw-r--r--source/gameengine/Physics/Sumo/Fuzzics/include/SM_Callback.h10
-rw-r--r--source/gameengine/Physics/Sumo/Fuzzics/include/SM_ClientObjectInfo.h15
-rw-r--r--source/gameengine/Physics/Sumo/Fuzzics/include/SM_FhObject.h36
-rw-r--r--source/gameengine/Physics/Sumo/Fuzzics/include/SM_MotionState.h36
-rw-r--r--source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h280
-rw-r--r--source/gameengine/Physics/Sumo/Fuzzics/include/SM_Props.h60
-rw-r--r--source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h129
-rw-r--r--source/gameengine/Physics/Sumo/Fuzzics/sample/Makefile25
-rw-r--r--source/gameengine/Physics/Sumo/Fuzzics/sample/particle.cpp705
-rw-r--r--source/gameengine/Physics/Sumo/Fuzzics/sample/particle0.cpp691
-rw-r--r--source/gameengine/Physics/Sumo/Fuzzics/src/Makefile13
-rw-r--r--source/gameengine/Physics/Sumo/Fuzzics/src/SM_FhObject.cpp115
-rw-r--r--source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp953
-rw-r--r--source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp179
-rw-r--r--source/gameengine/Physics/Sumo/Makefile47
-rw-r--r--source/gameengine/Physics/Sumo/SumoPhysicsController.cpp462
-rw-r--r--source/gameengine/Physics/Sumo/SumoPhysicsController.h171
-rw-r--r--source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp103
-rw-r--r--source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h88
-rw-r--r--source/gameengine/Physics/Sumo/convert.txt35
-rw-r--r--source/gameengine/Physics/Sumo/include/interpolator.h27
-rw-r--r--source/gameengine/Physics/Sumo/include/solid.h195
-rw-r--r--source/gameengine/Physics/Sumo/include/solid_broadphase.h38
-rw-r--r--source/gameengine/Physics/Sumo/include/solid_types.h14
-rw-r--r--source/gameengine/Physics/common/Makefile59
-rw-r--r--source/gameengine/Physics/common/PHY_DynamicTypes.h68
-rw-r--r--source/gameengine/Physics/common/PHY_IMotionState.cpp37
-rw-r--r--source/gameengine/Physics/common/PHY_IMotionState.h57
-rw-r--r--source/gameengine/Physics/common/PHY_IPhysicsController.cpp39
-rw-r--r--source/gameengine/Physics/common/PHY_IPhysicsController.h89
-rw-r--r--source/gameengine/Physics/common/PHY_IPhysicsEnvironment.cpp45
-rw-r--r--source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h60
-rw-r--r--source/gameengine/Physics/common/PHY_Pro.h60
-rw-r--r--source/gameengine/Rasterizer/Makefile51
-rw-r--r--source/gameengine/Rasterizer/RAS_BucketManager.cpp156
-rw-r--r--source/gameengine/Rasterizer/RAS_BucketManager.h63
-rw-r--r--source/gameengine/Rasterizer/RAS_CameraData.h42
-rw-r--r--source/gameengine/Rasterizer/RAS_Deformer.h56
-rw-r--r--source/gameengine/Rasterizer/RAS_FramingManager.cpp234
-rw-r--r--source/gameengine/Rasterizer/RAS_FramingManager.h255
-rw-r--r--source/gameengine/Rasterizer/RAS_ICanvas.h172
-rw-r--r--source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp125
-rw-r--r--source/gameengine/Rasterizer/RAS_IPolygonMaterial.h123
-rw-r--r--source/gameengine/Rasterizer/RAS_IRasterizer.h191
-rw-r--r--source/gameengine/Rasterizer/RAS_IRenderTools.cpp76
-rw-r--r--source/gameengine/Rasterizer/RAS_IRenderTools.h196
-rw-r--r--source/gameengine/Rasterizer/RAS_LightObject.h63
-rw-r--r--source/gameengine/Rasterizer/RAS_MaterialBucket.cpp248
-rw-r--r--source/gameengine/Rasterizer/RAS_MaterialBucket.h126
-rw-r--r--source/gameengine/Rasterizer/RAS_MeshObject.cpp635
-rw-r--r--source/gameengine/Rasterizer/RAS_MeshObject.h230
-rw-r--r--source/gameengine/Rasterizer/RAS_ObjectColor.h41
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/Makefile47
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_CheckVertexArrays.cpp61
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_CheckVertexArrays.h37
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp1226
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h226
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp215
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h62
-rw-r--r--source/gameengine/Rasterizer/RAS_Polygon.cpp142
-rw-r--r--source/gameengine/Rasterizer/RAS_Polygon.h92
-rw-r--r--source/gameengine/Rasterizer/RAS_Rect.h99
-rw-r--r--source/gameengine/Rasterizer/RAS_TexMatrix.h45
-rw-r--r--source/gameengine/Rasterizer/RAS_TexVert.cpp152
-rw-r--r--source/gameengine/Rasterizer/RAS_TexVert.h98
-rw-r--r--source/gameengine/Rasterizer/RAS_texmatrix.cpp133
-rw-r--r--source/gameengine/SceneGraph/Makefile41
-rw-r--r--source/gameengine/SceneGraph/SG_Controller.cpp49
-rw-r--r--source/gameengine/SceneGraph/SG_Controller.h116
-rw-r--r--source/gameengine/SceneGraph/SG_IObject.cpp153
-rw-r--r--source/gameengine/SceneGraph/SG_IObject.h220
-rw-r--r--source/gameengine/SceneGraph/SG_Node.cpp231
-rw-r--r--source/gameengine/SceneGraph/SG_Node.h208
-rw-r--r--source/gameengine/SceneGraph/SG_ParentRelation.h116
-rw-r--r--source/gameengine/SceneGraph/SG_Spatial.cpp283
-rw-r--r--source/gameengine/SceneGraph/SG_Spatial.h205
417 files changed, 78016 insertions, 0 deletions
diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
new file mode 100644
index 00000000000..ba0c7fa3917
--- /dev/null
+++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
@@ -0,0 +1,374 @@
+/**
+ * $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 *****
+ * Blender's Ketsji startpoint
+ */
+
+#ifdef WIN32
+// don't show stl-warnings
+#pragma warning (disable:4786)
+#endif
+
+#include "KX_BlenderGL.h"
+#include "KX_BlenderCanvas.h"
+#include "KX_BlenderKeyboardDevice.h"
+#include "KX_BlenderMouseDevice.h"
+#include "KX_BlenderRenderTools.h"
+#include "KX_BlenderSystem.h"
+
+#include "KX_KetsjiEngine.h"
+#include "KX_BlenderSceneConverter.h"
+#include "KX_PythonInit.h"
+#include "KX_PyConstraintBinding.h"
+
+#include "RAS_OpenGLRasterizer.h"
+#include "RAS_CheckVertexArrays.h"
+
+
+#ifdef WIN32
+#include "RAS_VAOpenGLRasterizer.h"
+#endif
+
+#include "NG_LoopBackNetworkDeviceInterface.h"
+#include "SND_DeviceManager.h"
+
+#include "SYS_System.h"
+
+ /***/
+
+#include "DNA_view3d_types.h"
+#include "DNA_screen_types.h"
+#include "BKE_global.h"
+#include "BIF_screen.h"
+#include "BIF_scrarea.h"
+
+#include "BKE_main.h"
+#include "BLI_blenlib.h"
+#include "BLO_readfile.h"
+#include "DNA_scene_types.h"
+ /***/
+
+static BlendFileData *load_game_data(char *filename) {
+ BlendReadError error;
+ BlendFileData *bfd= BLO_read_from_file(filename, &error);
+
+ if (!bfd) {
+ printf("Loading %s failed: %s\n", filename, BLO_bre_as_string(error));
+ }
+
+ return bfd;
+}
+
+extern "C" void StartKetsjiShell(struct ScrArea *area,
+ char* scenename,
+ struct Main* maggie,
+ int always_use_expand_framing)
+{
+ int exitrequested = KX_EXIT_REQUEST_NO_REQUEST;
+ Main* blenderdata = maggie;
+ char* startscenename = scenename;
+ char pathname[160];
+ strcpy (pathname, maggie->name);
+ STR_String exitstring = "";
+ BlendFileData *bfd= NULL;
+
+ do
+ {
+ View3D *v3d= (View3D*) area->spacedata.first;
+
+ // get some preferences
+ SYS_SystemHandle syshandle = SYS_GetSystem();
+ bool properties = (SYS_GetCommandLineInt(syshandle, "show_properties", 0) != 0);
+ bool usefixed = (SYS_GetCommandLineInt(syshandle, "fixedtime", 0) != 0);
+ bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0);
+ bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0);
+
+ // create the canvas, rasterizer and rendertools
+ RAS_ICanvas* canvas = new KX_BlenderCanvas(area);
+ canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE);
+ RAS_IRenderTools* rendertools = new KX_BlenderRenderTools();
+ RAS_IRasterizer* rasterizer = NULL;
+
+ // let's see if we want to use vertexarrays or not
+#ifdef WIN32
+ int usevta = SYS_GetCommandLineInt(syshandle,"vertexarrays",1);
+ bool useVertexArrays = (usevta > 0);
+
+ if (useVertexArrays && RAS_SystemSupportsVertexArrays())
+ rasterizer = new RAS_VAOpenGLRasterizer(canvas);
+ else
+ rasterizer = new RAS_OpenGLRasterizer(canvas);
+#else
+ rasterizer = new RAS_OpenGLRasterizer(canvas);
+#endif
+
+ // create the inputdevices
+ KX_BlenderKeyboardDevice* keyboarddevice = new KX_BlenderKeyboardDevice();
+ KX_BlenderMouseDevice* mousedevice = new KX_BlenderMouseDevice();
+
+ // create a networkdevice
+ NG_NetworkDeviceInterface* networkdevice = new
+ NG_LoopBackNetworkDeviceInterface();
+
+ // get an audiodevice
+ SND_DeviceManager::Subscribe();
+ SND_IAudioDevice* audiodevice = SND_DeviceManager::Instance();
+ audiodevice->UseCD();
+
+ // create a ketsji/blendersystem (only needed for timing and stuff)
+ KX_BlenderSystem* kxsystem = new KX_BlenderSystem();
+
+ // create the ketsjiengine
+ KX_KetsjiEngine* ketsjiengine = new KX_KetsjiEngine(kxsystem);
+
+ // set the devices
+ ketsjiengine->SetKeyboardDevice(keyboarddevice);
+ ketsjiengine->SetMouseDevice(mousedevice);
+ ketsjiengine->SetNetworkDevice(networkdevice);
+ ketsjiengine->SetCanvas(canvas);
+ ketsjiengine->SetRenderTools(rendertools);
+ ketsjiengine->SetRasterizer(rasterizer);
+ ketsjiengine->SetNetworkDevice(networkdevice);
+ ketsjiengine->SetAudioDevice(audiodevice);
+ ketsjiengine->SetUseFixedTime(usefixed);
+ ketsjiengine->SetTimingDisplay(frameRate, profile, properties);
+
+ // some blender stuff
+ MT_CmMatrix4x4 projmat;
+ MT_CmMatrix4x4 viewmat;
+ int i;
+
+ for (i = 0; i < 16; i++)
+ {
+ float *viewmat_linear= (float*) v3d->viewmat;
+ viewmat.setElem(i, viewmat_linear[i]);
+ }
+ for (i = 0; i < 16; i++)
+ {
+ float *projmat_linear = (float*) area->winmat;
+ projmat.setElem(i, projmat_linear[i]);
+ }
+
+ float camzoom = (1.41421 + (v3d->camzoom / 50.0));
+ camzoom *= camzoom;
+ camzoom = 4.0 / camzoom;
+
+ ketsjiengine->SetDrawType(v3d->drawtype);
+ ketsjiengine->SetCameraZoom(camzoom);
+
+ // if we got an exitcode 3 (KX_EXIT_REQUEST_START_OTHER_GAME) load a different file
+ if (exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME || exitrequested == KX_EXIT_REQUEST_RESTART_GAME)
+ {
+ exitrequested = KX_EXIT_REQUEST_NO_REQUEST;
+ if (bfd) BLO_blendfiledata_free(bfd);
+
+ char basedpath[160];
+ // base the actuator filename with respect
+ // to the original file working directory
+ if (exitstring != "")
+ strcpy(basedpath, exitstring.Ptr());
+
+ BLI_convertstringcode(basedpath, pathname, 0);
+ bfd = load_game_data(basedpath);
+
+ // if it wasn't loaded, try it forced relative
+ if (!bfd)
+ {
+ // just add "//" in front of it
+ char temppath[162];
+ strcpy(temppath, "//");
+ strcat(temppath, basedpath);
+
+ BLI_convertstringcode(temppath, pathname, 0);
+ bfd = load_game_data(temppath);
+ }
+
+ // if we got a loaded blendfile, proceed
+ if (bfd)
+ {
+ blenderdata = bfd->main;
+ startscenename = bfd->curscene->id.name + 2;
+ }
+ // else forget it, we can't find it
+ else
+ {
+ exitrequested = KX_EXIT_REQUEST_QUIT_GAME;
+ }
+ }
+
+ if (exitrequested != KX_EXIT_REQUEST_QUIT_GAME)
+ {
+ if (v3d->persp != 2)
+ {
+ ketsjiengine->EnableCameraOverride(startscenename);
+ ketsjiengine->SetCameraOverrideUseOrtho((v3d->persp == 0));
+ ketsjiengine->SetCameraOverrideProjectionMatrix(projmat);
+ ketsjiengine->SetCameraOverrideViewMatrix(viewmat);
+ }
+
+ // create a scene converter, create and convert the startingscene
+ KX_ISceneConverter* sceneconverter = new KX_BlenderSceneConverter(blenderdata, ketsjiengine);
+ ketsjiengine->SetSceneConverter(sceneconverter);
+
+ if (always_use_expand_framing)
+ sceneconverter->SetAlwaysUseExpandFraming(true);
+
+
+ KX_Scene* startscene = new KX_Scene(keyboarddevice,
+ mousedevice,
+ networkdevice,
+ audiodevice,
+ startscenename);
+
+ // some python things
+ PyObject* dictionaryobject = initGamePythonScripting("Ketsji", psl_Lowest);
+ ketsjiengine->SetPythonDictionary(dictionaryobject);
+ initRasterizer(rasterizer, canvas);
+ initGameLogic(startscene);
+ initGameKeys();
+ initPythonConstraintBinding();
+
+
+ if (sceneconverter)
+ {
+ // convert and add scene
+ sceneconverter->ConvertScene(
+ startscenename,
+ startscene,
+ dictionaryobject,
+ keyboarddevice,
+ rendertools,
+ canvas);
+ ketsjiengine->AddScene(startscene);
+
+ // init the rasterizer
+ rasterizer->Init();
+
+ // start the engine
+ ketsjiengine->StartEngine();
+
+ // the mainloop
+ while (!exitrequested)
+ {
+ // first check if we want to exit
+ exitrequested = ketsjiengine->GetExitCode();
+
+ // kick the engine
+ ketsjiengine->NextFrame();
+
+ // render the frame
+ ketsjiengine->Render();
+
+ // test for the ESC key
+ while (qtest())
+ {
+ short val;
+ unsigned short event = extern_qread(&val);
+
+ if (keyboarddevice->ConvertBlenderEvent(event,val))
+ exitrequested = KX_EXIT_REQUEST_BLENDER_ESC;
+
+ /* Coordinate conversion... where
+ * should this really be?
+ */
+ if (event==MOUSEX) {
+ val = val - scrarea_get_win_x(area);
+ } else if (event==MOUSEY) {
+ val = scrarea_get_win_height(area) - (val - scrarea_get_win_y(area)) - 1;
+ }
+
+ mousedevice->ConvertBlenderEvent(event,val);
+ }
+ }
+ exitstring = ketsjiengine->GetExitString();
+
+ // when exiting the mainloop
+ exitGamePythonScripting();
+ ketsjiengine->StopEngine();
+ networkdevice->Disconnect();
+ }
+
+ if (sceneconverter)
+ {
+ delete sceneconverter;
+ sceneconverter = NULL;
+ }
+ }
+ // set the cursor back to normal
+ canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL);
+
+ // clean up some stuff
+ audiodevice->StopCD();
+ SND_DeviceManager::Unsubscribe();
+
+ if (ketsjiengine)
+ {
+ delete ketsjiengine;
+ ketsjiengine = NULL;
+ }
+ if (kxsystem)
+ {
+ delete kxsystem;
+ kxsystem = NULL;
+ }
+ if (networkdevice)
+ {
+ delete networkdevice;
+ networkdevice = NULL;
+ }
+ if (keyboarddevice)
+ {
+ delete keyboarddevice;
+ keyboarddevice = NULL;
+ }
+ if (mousedevice)
+ {
+ delete mousedevice;
+ mousedevice = NULL;
+ }
+ if (rasterizer)
+ {
+ delete rasterizer;
+ rasterizer = NULL;
+ }
+ if (rendertools)
+ {
+ delete rendertools;
+ rendertools = NULL;
+ }
+ if (canvas)
+ {
+ delete canvas;
+ canvas = NULL;
+ }
+ } while (exitrequested == KX_EXIT_REQUEST_RESTART_GAME || exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME);
+
+ if (bfd) BLO_blendfiledata_free(bfd);
+}
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp
new file mode 100644
index 00000000000..3dfae217453
--- /dev/null
+++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp
@@ -0,0 +1,164 @@
+/**
+ * $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 "BIF_scrarea.h"
+
+
+#include "KX_BlenderCanvas.h"
+
+
+KX_BlenderCanvas::KX_BlenderCanvas(struct ScrArea *area) :
+m_area(area)
+{
+}
+
+KX_BlenderCanvas::~KX_BlenderCanvas()
+{
+}
+
+void KX_BlenderCanvas::Init()
+{
+ glDepthFunc(GL_LEQUAL);
+}
+
+
+void KX_BlenderCanvas::SwapBuffers()
+{
+ BL_SwapBuffers();
+}
+
+void KX_BlenderCanvas::BeginFrame()
+{
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LEQUAL);
+
+}
+
+
+void KX_BlenderCanvas::EndFrame()
+{
+ // this is needed, else blender distorts a lot
+ glPopAttrib();
+ glPushAttrib(GL_ALL_ATTRIB_BITS);
+
+ glDisable(GL_FOG);
+}
+
+
+
+void KX_BlenderCanvas::ClearColor(float r,float g,float b,float a)
+{
+ glClearColor(r,g,b,a);
+}
+
+
+
+void KX_BlenderCanvas::ClearBuffer(int type)
+{
+ int ogltype = 0;
+
+ if (type & RAS_ICanvas::COLOR_BUFFER )
+ ogltype |= GL_COLOR_BUFFER_BIT;
+
+ if (type & RAS_ICanvas::DEPTH_BUFFER )
+ ogltype |= GL_DEPTH_BUFFER_BIT;
+ glClear(ogltype);
+}
+
+int KX_BlenderCanvas::GetWidth(
+) const {
+ return scrarea_get_win_width(m_area);
+}
+
+int KX_BlenderCanvas::GetHeight(
+) const {
+ return scrarea_get_win_height(m_area);
+}
+
+ void
+KX_BlenderCanvas::
+SetViewPort(
+ int x1, int y1,
+ int x2, int y2
+){
+ int vp_width = (x2 - x1) + 1;
+ int vp_height = (y2 - y1) + 1;
+ int minx = scrarea_get_win_x(m_area);
+ int miny = scrarea_get_win_y(m_area);
+
+ glViewport(minx + x1, miny + y1, vp_width, vp_height);
+ glScissor(minx + x1, miny + y1, vp_width, vp_height);
+}
+
+
+void KX_BlenderCanvas::SetMouseState(RAS_MouseState mousestate)
+{
+ switch (mousestate)
+ {
+ case MOUSE_INVISIBLE:
+ {
+ BL_HideMouse();
+ break;
+ }
+ case MOUSE_WAIT:
+ {
+ BL_WaitMouse();
+ break;
+ }
+ case MOUSE_NORMAL:
+ {
+ BL_NormalMouse();
+ break;
+ }
+ default:
+ {
+ }
+ }
+}
+
+
+
+// (0,0) is top left, (width,height) is bottom right
+void KX_BlenderCanvas::SetMousePosition(int x,int y)
+{
+ int winX = scrarea_get_win_x(m_area);
+ int winY = scrarea_get_win_y(m_area);
+ int winH = scrarea_get_win_height(m_area);
+
+ BL_warp_pointer(winX + x, winY + (winH-y-1));
+}
+
+
+
+void KX_BlenderCanvas::MakeScreenShot(const char* filename)
+{
+ BL_MakeScreenShot(m_area, filename);
+}
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h
new file mode 100644
index 00000000000..85b41e37f1d
--- /dev/null
+++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h
@@ -0,0 +1,165 @@
+/**
+ * $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_BLENDERCANVAS
+#define __KX_BLENDERCANVAS
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+#include <GL/gl.h>
+
+#include "RAS_ICanvas.h"
+#include "RAS_Rect.h"
+
+#include "KX_BlenderGL.h"
+
+struct ScrArea;
+
+/**
+ * 2D Blender device context abstraction.
+ * The connection from 3d rendercontext to 2d Blender surface embedding.
+ */
+
+class KX_BlenderCanvas : public RAS_ICanvas
+{
+private:
+ /** Rect that defines the area used for rendering,
+ relative to the context */
+ RAS_Rect m_displayarea;
+
+public:
+ /* Construct a new canvas.
+ *
+ * @param area The Blender ScrArea to run the game within.
+ */
+ KX_BlenderCanvas(struct ScrArea* area);
+ ~KX_BlenderCanvas();
+
+ void
+ Init(
+ );
+
+ void
+ SwapBuffers(
+ );
+ void
+ Resize(
+ int width,
+ int height
+ );
+
+ void
+ BeginFrame(
+ );
+
+ void
+ EndFrame(
+ );
+
+ void
+ ClearColor(
+ float r,
+ float g,
+ float b,
+ float a
+ );
+
+ void
+ ClearBuffer(
+ int type
+ );
+
+ int
+ GetWidth(
+ ) const ;
+
+ int
+ GetHeight(
+ ) const ;
+
+ const
+ RAS_Rect &
+ GetDisplayArea(
+ ) const {
+ return m_displayarea;
+ };
+
+ RAS_Rect &
+ GetDisplayArea(
+ ) {
+ return m_displayarea;
+ };
+
+ void
+ SetViewPort(
+ int x1, int y1,
+ int x2, int y2
+ );
+
+ void
+ SetMouseState(
+ RAS_MouseState mousestate
+ );
+
+ void
+ SetMousePosition(
+ int x,
+ int y
+ );
+
+ void
+ MakeScreenShot(
+ const char* filename
+ );
+
+ /**
+ * Nothing needs be done for BlenderCanvas
+ * Begin/End Draw, as the game engine GL context
+ * is always current/active.
+ */
+
+ bool
+ BeginDraw(
+ ) {
+ return true;
+ };
+
+ void
+ EndDraw(
+ ) {
+ };
+
+private:
+ /** Blender area the game engine is running within */
+ struct ScrArea* m_area;
+};
+#endif // __KX_BLENDERCANVAS
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
new file mode 100644
index 00000000000..c2b4da62ece
--- /dev/null
+++ b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
@@ -0,0 +1,259 @@
+/**
+ * $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 "KX_BlenderGL.h"
+
+
+/*
+ * This little block needed for linking to Blender...
+ */
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "BMF_Api.h"
+
+
+
+/* Data types encoding the game world: */
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_camera_types.h"
+#include "DNA_world_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_image_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_material_types.h"
+
+#include "BKE_global.h"
+#include "BKE_bmfont.h"
+
+#include "BIF_gl.h"
+extern "C" {
+#include "BDR_drawmesh.h"
+#include "BIF_mywindow.h"
+#include "BIF_toolbox.h"
+#include "BIF_graphics.h" /* For CURSOR_NONE CURSOR_WAIT CURSOR_STD */
+
+}
+
+/* end of blender block */
+
+
+#include <GL/gl.h>
+
+
+void BL_warp_pointer(int x,int y)
+{
+ warp_pointer(x,y);
+}
+
+void BL_SwapBuffers()
+{
+ myswapbuffers();
+}
+
+void BL_RenderText(int mode,const char* textstr,int textlen,struct TFace* tface,
+ float v1[3],float v2[3],float v3[3],float v4[3])
+{
+ Image* ima;
+
+ if(mode & TF_BMFONT) {
+ //char string[MAX_PROPSTRING];
+ int characters, index, character;
+ float centerx, centery, sizex, sizey, transx, transy, movex, movey, advance;
+
+// bProperty *prop;
+
+ // string = "Frank van Beek";
+
+ characters = textlen;
+
+ ima = (struct Image*) tface->tpage;
+ if (ima == NULL) {
+ characters = 0;
+ }
+
+ glPushMatrix();
+ for (index = 0; index < characters; index++) {
+ // lets calculate offset stuff
+ character = textstr[index];
+
+ // space starts at offset 1
+ // character = character - ' ' + 1;
+
+ matrixGlyph(ima->ibuf, character, & centerx, &centery, &sizex, &sizey, &transx, &transy, &movex, &movey, &advance);
+
+ glBegin(GL_POLYGON);
+ // printf(" %c %f %f %f %f\n", character, tface->uv[0][0], tface->uv[0][1], );
+ // glTexCoord2f((tface->uv[0][0] - centerx) * sizex + transx, (tface->uv[0][1] - centery) * sizey + transy);
+ glTexCoord2f((tface->uv[0][0] - centerx) * sizex + transx, (tface->uv[0][1] - centery) * sizey + transy);
+
+ spack(tface->col[0]);
+ // glVertex3fv(v1);
+ glVertex3f(sizex * v1[0] + movex, sizey * v1[1] + movey, v1[2]);
+
+ glTexCoord2f((tface->uv[1][0] - centerx) * sizex + transx, (tface->uv[1][1] - centery) * sizey + transy);
+ spack(tface->col[1]);
+ // glVertex3fv(v2);
+ glVertex3f(sizex * v2[0] + movex, sizey * v2[1] + movey, v2[2]);
+
+ glTexCoord2f((tface->uv[2][0] - centerx) * sizex + transx, (tface->uv[2][1] - centery) * sizey + transy);
+ spack(tface->col[2]);
+ // glVertex3fv(v3);
+ glVertex3f(sizex * v3[0] + movex, sizey * v3[1] + movey, v3[2]);
+
+ if(v4) {
+ // glTexCoord2f((tface->uv[3][0] - centerx) * sizex + transx, 1.0 - (1.0 - tface->uv[3][1]) * sizey - transy);
+ glTexCoord2f((tface->uv[3][0] - centerx) * sizex + transx, (tface->uv[3][1] - centery) * sizey + transy);
+ spack(tface->col[3]);
+ // glVertex3fv(v4);
+ glVertex3f(sizex * v4[0] + movex, sizey * v4[1] + movey, v4[2]);
+ }
+ glEnd();
+
+ glTranslatef(advance, 0.0, 0.0);
+ }
+ glPopMatrix();
+
+ }
+}
+
+
+void BL_print_gamedebug_line(char* text, int xco, int yco, int width, int height)
+{
+ /* gl prepping */
+ glDisable(GL_TEXTURE_2D);
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+
+ glOrtho(0, width,
+ 0, height, 0, 1);
+
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+ glMatrixMode(GL_TEXTURE);
+ glPushMatrix();
+ glLoadIdentity();
+
+ /* the actual drawing */
+ glColor3ub(255, 255, 255);
+ glRasterPos2s(xco, height-yco);
+ BMF_DrawString(G.fonts, text);
+
+ glMatrixMode(GL_TEXTURE);
+ glPopMatrix();
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+ glEnable(GL_DEPTH_TEST);
+}
+
+void BL_print_gamedebug_line_padded(char* text, int xco, int yco, int width, int height)
+{
+ /* This is a rather important line :( The gl-mode hasn't been left
+ * behind quite as neatly as we'd have wanted to. I don't know
+ * what cause it, though :/ .*/
+ glDisable(GL_TEXTURE_2D);
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+
+ glOrtho(0, width,
+ 0, height, 0, 1);
+
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+ glMatrixMode(GL_TEXTURE);
+ glPushMatrix();
+ glLoadIdentity();
+
+ /* draw in black first*/
+ glColor3ub(0, 0, 0);
+ glRasterPos2s(xco+1, height-yco-1);
+ BMF_DrawString(G.fonts, text);
+ glColor3ub(255, 255, 255);
+ glRasterPos2s(xco, height-yco);
+ BMF_DrawString(G.fonts, text);
+
+ glMatrixMode(GL_TEXTURE);
+ glPopMatrix();
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+ glEnable(GL_DEPTH_TEST);
+}
+
+void BL_HideMouse()
+{
+ set_cursor(CURSOR_NONE);
+}
+
+
+void BL_WaitMouse()
+{
+ set_cursor(CURSOR_WAIT);
+}
+
+
+void BL_NormalMouse()
+{
+ set_cursor(CURSOR_STD);
+}
+#define MAX_FILE_LENGTH 512
+
+
+void BL_MakeScreenShot(struct ScrArea *area, const char* filename)
+{
+ char copyfilename[MAX_FILE_LENGTH];
+ strcpy(copyfilename,filename);
+
+ // filename read - only
+
+ /* XXX will need to change at some point */
+ BIF_screendump();
+/* BIF_screendump(area); */
+
+ // write+read filename
+ write_screendump((char*) copyfilename);
+}
+
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderGL.h b/source/gameengine/BlenderRoutines/KX_BlenderGL.h
new file mode 100644
index 00000000000..c3648a21810
--- /dev/null
+++ b/source/gameengine/BlenderRoutines/KX_BlenderGL.h
@@ -0,0 +1,66 @@
+/**
+ * $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 __BLENDERGL
+#define __BLENDERGL
+
+#ifdef __cplusplus
+extern "C" {
+#endif //__cplusplus
+
+struct ScrArea;
+
+// special swapbuffers, that takes care of which area (viewport) needs to be swapped
+void BL_SwapBuffers();
+
+void BL_warp_pointer(int x,int y);
+
+void BL_MakeScreenShot(struct ScrArea *area, const char* filename);
+
+void BL_HideMouse();
+void BL_NormalMouse();
+void BL_WaitMouse();
+
+void BL_RenderText(int mode,const char* textstr,int textlen,struct TFace* tface,
+ float v1[3],float v2[3],float v3[3],float v4[3]);
+
+void BL_print_gamedebug_line(char* text, int xco, int yco, int width, int height);
+void BL_print_gamedebug_line_padded(char* text, int xco, int yco, int width, int height);
+
+
+
+#ifdef __cplusplus
+}
+#endif //__cplusplus
+
+
+#endif //__BLENDERGL
+
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.cpp b/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.cpp
new file mode 100644
index 00000000000..b364d4d40dd
--- /dev/null
+++ b/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.cpp
@@ -0,0 +1,32 @@
+/**
+ * $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 "KX_BlenderInputDevice.h"
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h b/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h
new file mode 100644
index 00000000000..7a2951838fc
--- /dev/null
+++ b/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h
@@ -0,0 +1,220 @@
+/**
+ * $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_BLENDERINPUTDEVICE
+#define __KX_BLENDERINPUTDEVICE
+
+#ifdef WIN32
+#pragma warning(disable : 4786) // shut off 255 char limit debug template warning
+#endif
+
+/* need to be here for conversion purposes */
+#include "mydevice.h"
+#include "SCA_IInputDevice.h"
+
+#include <map>
+/**
+ Base Class for Blender specific inputdevices. Blender specific inputdevices are used when the gameengine is running in embedded mode instead of standalone mode.
+*/
+class BL_BlenderInputDevice : public SCA_IInputDevice
+{
+ // this map is Blender specific: a conversion between blender and ketsji enums
+ std::map<int,KX_EnumInputs> m_reverseKeyTranslateTable;
+public:
+ BL_BlenderInputDevice()
+ {
+
+ /* The reverse table. In order to not confuse ourselves, we */
+ /* immediately convert all events that come in to KX codes. */
+ m_reverseKeyTranslateTable[LEFTMOUSE ] = KX_LEFTMOUSE ;
+ m_reverseKeyTranslateTable[MIDDLEMOUSE ] = KX_MIDDLEMOUSE ;
+ m_reverseKeyTranslateTable[RIGHTMOUSE ] = KX_RIGHTMOUSE ;
+ m_reverseKeyTranslateTable[MOUSEX ] = KX_MOUSEX ;
+ m_reverseKeyTranslateTable[MOUSEY ] = KX_MOUSEY ;
+
+ // TIMERS
+
+ m_reverseKeyTranslateTable[TIMER0 ] = KX_TIMER0 ;
+ m_reverseKeyTranslateTable[TIMER1 ] = KX_TIMER1 ;
+ m_reverseKeyTranslateTable[TIMER2 ] = KX_TIMER2 ;
+ m_reverseKeyTranslateTable[TIMER3 ] = KX_TIMER3 ;
+
+ // SYSTEM
+
+ m_reverseKeyTranslateTable[KEYBD ] = KX_KEYBD ;
+ m_reverseKeyTranslateTable[RAWKEYBD ] = KX_RAWKEYBD ;
+ m_reverseKeyTranslateTable[REDRAW ] = KX_REDRAW ;
+ m_reverseKeyTranslateTable[INPUTCHANGE ] = KX_INPUTCHANGE ;
+ m_reverseKeyTranslateTable[QFULL ] = KX_QFULL ;
+ m_reverseKeyTranslateTable[WINFREEZE ] = KX_WINFREEZE ;
+ m_reverseKeyTranslateTable[WINTHAW ] = KX_WINTHAW ;
+ m_reverseKeyTranslateTable[WINCLOSE ] = KX_WINCLOSE ;
+ m_reverseKeyTranslateTable[WINQUIT ] = KX_WINQUIT ;
+ m_reverseKeyTranslateTable[Q_FIRSTTIME ] = KX_Q_FIRSTTIME ;
+
+ // standard keyboard
+
+ m_reverseKeyTranslateTable[AKEY ] = KX_AKEY ;
+ m_reverseKeyTranslateTable[BKEY ] = KX_BKEY ;
+ m_reverseKeyTranslateTable[CKEY ] = KX_CKEY ;
+ m_reverseKeyTranslateTable[DKEY ] = KX_DKEY ;
+ m_reverseKeyTranslateTable[EKEY ] = KX_EKEY ;
+ m_reverseKeyTranslateTable[FKEY ] = KX_FKEY ;
+ m_reverseKeyTranslateTable[GKEY ] = KX_GKEY ;
+ m_reverseKeyTranslateTable[HKEY ] = KX_HKEY ;
+ m_reverseKeyTranslateTable[IKEY ] = KX_IKEY ;
+ m_reverseKeyTranslateTable[JKEY ] = KX_JKEY ;
+ m_reverseKeyTranslateTable[KKEY ] = KX_KKEY ;
+ m_reverseKeyTranslateTable[LKEY ] = KX_LKEY ;
+ m_reverseKeyTranslateTable[MKEY ] = KX_MKEY ;
+ m_reverseKeyTranslateTable[NKEY ] = KX_NKEY ;
+ m_reverseKeyTranslateTable[OKEY ] = KX_OKEY ;
+ m_reverseKeyTranslateTable[PKEY ] = KX_PKEY ;
+ m_reverseKeyTranslateTable[QKEY ] = KX_QKEY ;
+ m_reverseKeyTranslateTable[RKEY ] = KX_RKEY ;
+ m_reverseKeyTranslateTable[SKEY ] = KX_SKEY ;
+ m_reverseKeyTranslateTable[TKEY ] = KX_TKEY ;
+ m_reverseKeyTranslateTable[UKEY ] = KX_UKEY ;
+ m_reverseKeyTranslateTable[VKEY ] = KX_VKEY ;
+ m_reverseKeyTranslateTable[WKEY ] = KX_WKEY ;
+ m_reverseKeyTranslateTable[XKEY ] = KX_XKEY ;
+ m_reverseKeyTranslateTable[YKEY ] = KX_YKEY ;
+ m_reverseKeyTranslateTable[ZKEY ] = KX_ZKEY ;
+
+ m_reverseKeyTranslateTable[ZEROKEY ] = KX_ZEROKEY ;
+ m_reverseKeyTranslateTable[ONEKEY ] = KX_ONEKEY ;
+ m_reverseKeyTranslateTable[TWOKEY ] = KX_TWOKEY ;
+ m_reverseKeyTranslateTable[THREEKEY ] = KX_THREEKEY ;
+ m_reverseKeyTranslateTable[FOURKEY ] = KX_FOURKEY ;
+ m_reverseKeyTranslateTable[FIVEKEY ] = KX_FIVEKEY ;
+ m_reverseKeyTranslateTable[SIXKEY ] = KX_SIXKEY ;
+ m_reverseKeyTranslateTable[SEVENKEY ] = KX_SEVENKEY ;
+ m_reverseKeyTranslateTable[EIGHTKEY ] = KX_EIGHTKEY ;
+ m_reverseKeyTranslateTable[NINEKEY ] = KX_NINEKEY ;
+
+ m_reverseKeyTranslateTable[CAPSLOCKKEY ] = KX_CAPSLOCKKEY ;
+
+ m_reverseKeyTranslateTable[LEFTCTRLKEY ] = KX_LEFTCTRLKEY ;
+ m_reverseKeyTranslateTable[LEFTALTKEY ] = KX_LEFTALTKEY ;
+ m_reverseKeyTranslateTable[RIGHTALTKEY ] = KX_RIGHTALTKEY ;
+ m_reverseKeyTranslateTable[RIGHTCTRLKEY ] = KX_RIGHTCTRLKEY ;
+ m_reverseKeyTranslateTable[RIGHTSHIFTKEY ] = KX_RIGHTSHIFTKEY ;
+ m_reverseKeyTranslateTable[LEFTSHIFTKEY ] = KX_LEFTSHIFTKEY ;
+
+ m_reverseKeyTranslateTable[ESCKEY ] = KX_ESCKEY ;
+ m_reverseKeyTranslateTable[TABKEY ] = KX_TABKEY ;
+ m_reverseKeyTranslateTable[RETKEY ] = KX_RETKEY ;
+ m_reverseKeyTranslateTable[SPACEKEY ] = KX_SPACEKEY ;
+ m_reverseKeyTranslateTable[LINEFEEDKEY ] = KX_LINEFEEDKEY ;
+ m_reverseKeyTranslateTable[BACKSPACEKEY ] = KX_BACKSPACEKEY ;
+ m_reverseKeyTranslateTable[DELKEY ] = KX_DELKEY ;
+ m_reverseKeyTranslateTable[SEMICOLONKEY ] = KX_SEMICOLONKEY ;
+ m_reverseKeyTranslateTable[PERIODKEY ] = KX_PERIODKEY ;
+ m_reverseKeyTranslateTable[COMMAKEY ] = KX_COMMAKEY ;
+ m_reverseKeyTranslateTable[QUOTEKEY ] = KX_QUOTEKEY ;
+ m_reverseKeyTranslateTable[ACCENTGRAVEKEY ] = KX_ACCENTGRAVEKEY ;
+ m_reverseKeyTranslateTable[MINUSKEY ] = KX_MINUSKEY ;
+ m_reverseKeyTranslateTable[SLASHKEY ] = KX_SLASHKEY ;
+ m_reverseKeyTranslateTable[BACKSLASHKEY ] = KX_BACKSLASHKEY ;
+ m_reverseKeyTranslateTable[EQUALKEY ] = KX_EQUALKEY ;
+ m_reverseKeyTranslateTable[LEFTBRACKETKEY ] = KX_LEFTBRACKETKEY ;
+ m_reverseKeyTranslateTable[RIGHTBRACKETKEY ] = KX_RIGHTBRACKETKEY ;
+
+ m_reverseKeyTranslateTable[LEFTARROWKEY ] = KX_LEFTARROWKEY ;
+ m_reverseKeyTranslateTable[DOWNARROWKEY ] = KX_DOWNARROWKEY ;
+ m_reverseKeyTranslateTable[RIGHTARROWKEY ] = KX_RIGHTARROWKEY ;
+ m_reverseKeyTranslateTable[UPARROWKEY ] = KX_UPARROWKEY ;
+
+ m_reverseKeyTranslateTable[PAD2 ] = KX_PAD2 ;
+ m_reverseKeyTranslateTable[PAD4 ] = KX_PAD4 ;
+ m_reverseKeyTranslateTable[PAD6 ] = KX_PAD6 ;
+ m_reverseKeyTranslateTable[PAD8 ] = KX_PAD8 ;
+
+ m_reverseKeyTranslateTable[PAD1 ] = KX_PAD1 ;
+ m_reverseKeyTranslateTable[PAD3 ] = KX_PAD3 ;
+ m_reverseKeyTranslateTable[PAD5 ] = KX_PAD5 ;
+ m_reverseKeyTranslateTable[PAD7 ] = KX_PAD7 ;
+ m_reverseKeyTranslateTable[PAD9 ] = KX_PAD9 ;
+
+ m_reverseKeyTranslateTable[PADPERIOD ] = KX_PADPERIOD ;
+ m_reverseKeyTranslateTable[PADSLASHKEY ] = KX_PADSLASHKEY ;
+ m_reverseKeyTranslateTable[PADASTERKEY ] = KX_PADASTERKEY ;
+
+
+ m_reverseKeyTranslateTable[PAD0 ] = KX_PAD0 ;
+ m_reverseKeyTranslateTable[PADMINUS ] = KX_PADMINUS ;
+ m_reverseKeyTranslateTable[PADENTER ] = KX_PADENTER ;
+ m_reverseKeyTranslateTable[PADPLUSKEY ] = KX_PADPLUSKEY ;
+
+
+ m_reverseKeyTranslateTable[F1KEY ] = KX_F1KEY ;
+ m_reverseKeyTranslateTable[F2KEY ] = KX_F2KEY ;
+ m_reverseKeyTranslateTable[F3KEY ] = KX_F3KEY ;
+ m_reverseKeyTranslateTable[F4KEY ] = KX_F4KEY ;
+ m_reverseKeyTranslateTable[F5KEY ] = KX_F5KEY ;
+ m_reverseKeyTranslateTable[F6KEY ] = KX_F6KEY ;
+ m_reverseKeyTranslateTable[F7KEY ] = KX_F7KEY ;
+ m_reverseKeyTranslateTable[F8KEY ] = KX_F8KEY ;
+ m_reverseKeyTranslateTable[F9KEY ] = KX_F9KEY ;
+ m_reverseKeyTranslateTable[F10KEY ] = KX_F10KEY ;
+ m_reverseKeyTranslateTable[F11KEY ] = KX_F11KEY ;
+ m_reverseKeyTranslateTable[F12KEY ] = KX_F12KEY ;
+
+ m_reverseKeyTranslateTable[PAUSEKEY ] = KX_PAUSEKEY ;
+ m_reverseKeyTranslateTable[INSERTKEY ] = KX_INSERTKEY ;
+ m_reverseKeyTranslateTable[HOMEKEY ] = KX_HOMEKEY ;
+ m_reverseKeyTranslateTable[PAGEUPKEY ] = KX_PAGEUPKEY ;
+ m_reverseKeyTranslateTable[PAGEDOWNKEY ] = KX_PAGEDOWNKEY ;
+ m_reverseKeyTranslateTable[ENDKEY ] = KX_ENDKEY ;
+
+
+ }
+
+ virtual ~BL_BlenderInputDevice()
+ {
+
+ }
+
+ KX_EnumInputs ToNative(unsigned short incode) {
+ return m_reverseKeyTranslateTable[incode];
+ }
+
+ virtual bool IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)=0;
+// virtual const SCA_InputEvent& GetEventValue(SCA_IInputDevice::KX_EnumInputs inputcode)=0;
+ virtual bool ConvertBlenderEvent(unsigned short incode,short val)=0;
+
+};
+
+
+
+
+
+#endif //__KX_BLENDERINPUTDEVICE
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp b/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp
new file mode 100644
index 00000000000..81f233d6433
--- /dev/null
+++ b/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp
@@ -0,0 +1,161 @@
+/**
+ * $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
+// annoying warnings about truncated STL debug info
+#pragma warning (disable :4786)
+#endif
+
+#include "KX_BlenderKeyboardDevice.h"
+
+KX_BlenderKeyboardDevice::KX_BlenderKeyboardDevice()
+{
+
+}
+KX_BlenderKeyboardDevice::~KX_BlenderKeyboardDevice()
+{
+
+}
+
+/**
+ IsPressed gives boolean information about keyboard status, true if pressed, false if not
+*/
+
+bool KX_BlenderKeyboardDevice::IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)
+{
+ const SCA_InputEvent & inevent = m_eventStatusTables[m_currentTable][inputcode];
+ bool pressed = (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED ||
+ inevent.m_status == SCA_InputEvent::KX_ACTIVE);
+ return pressed;
+}
+/*const SCA_InputEvent& KX_BlenderKeyboardDevice::GetEventValue(SCA_IInputDevice::KX_EnumInputs inputcode)
+{
+ return m_eventStatusTables[m_currentTable][inputcode];
+}
+*/
+/**
+ NextFrame toggles currentTable with previousTable,
+ and copy relevant event information from previous to current
+ (pressed keys need to be remembered)
+*/
+void KX_BlenderKeyboardDevice::NextFrame()
+{
+ SCA_IInputDevice::NextFrame();
+
+ // now convert justpressed keyevents into regular (active) keyevents
+ int previousTable = 1-m_currentTable;
+ for (int keyevent= KX_BEGINKEY; keyevent< KX_ENDKEY;keyevent++)
+ {
+ SCA_InputEvent& oldevent = m_eventStatusTables[previousTable][keyevent];
+ if (oldevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED ||
+ oldevent.m_status == SCA_InputEvent::KX_ACTIVE )
+ {
+ m_eventStatusTables[m_currentTable][keyevent] = oldevent;
+ m_eventStatusTables[m_currentTable][keyevent].m_status = SCA_InputEvent::KX_ACTIVE;
+ }
+ }
+}
+
+/**
+ ConvertBlenderEvent translates blender keyboard events into ketsji kbd events
+ extra event information is stored, like ramp-mode (just released/pressed)
+*/
+
+
+bool KX_BlenderKeyboardDevice::ConvertBlenderEvent(unsigned short incode,short val)
+{
+ bool result = false;
+
+ // convert event
+ KX_EnumInputs kxevent = this->ToNative(incode);
+
+ // only process it, if it's a key
+ if (kxevent >= KX_BEGINKEY && kxevent < KX_ENDKEY)
+ {
+ int previousTable = 1-m_currentTable;
+
+ if (val > 0)
+ {
+ if (kxevent == SCA_IInputDevice::KX_ESCKEY && val != 0)
+ result = true;
+
+ // todo: convert val ??
+ m_eventStatusTables[m_currentTable][kxevent].m_eventval = val ; //???
+
+ switch (m_eventStatusTables[previousTable][kxevent].m_status)
+ {
+ case SCA_InputEvent::KX_JUSTACTIVATED:
+ {
+ m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_ACTIVE;
+ break;
+ }
+ case SCA_InputEvent::KX_ACTIVE:
+
+ {
+ m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_ACTIVE;
+ break;
+ }
+ case SCA_InputEvent::KX_NO_INPUTSTATUS:
+ {
+ m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_JUSTACTIVATED;
+ break;
+ }
+ default:
+ {
+ m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_JUSTACTIVATED;
+ }
+ }
+
+ } else
+ {
+ // blender eventval == 0
+ switch (m_eventStatusTables[previousTable][kxevent].m_status)
+ {
+ case SCA_InputEvent::KX_JUSTACTIVATED:
+ {
+ m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_JUSTRELEASED;
+ break;
+ }
+ case SCA_InputEvent::KX_ACTIVE:
+ {
+ m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_JUSTRELEASED;
+ break;
+ }
+ default:
+ {
+ m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_NO_INPUTSTATUS;
+ }
+ }
+ }
+ }
+ return result;
+}
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.h b/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.h
new file mode 100644
index 00000000000..98791dba95b
--- /dev/null
+++ b/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.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_BLENDERKEYBOARDDEVICE
+#define __KX_BLENDERKEYBOARDDEVICE
+
+#include "KX_BlenderInputDevice.h"
+
+class KX_BlenderKeyboardDevice : public BL_BlenderInputDevice
+{
+public:
+ KX_BlenderKeyboardDevice();
+ virtual ~KX_BlenderKeyboardDevice();
+
+ virtual bool IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode);
+// virtual const SCA_InputEvent& GetEventValue(SCA_IInputDevice::KX_EnumInputs inputcode);
+ virtual bool ConvertBlenderEvent(unsigned short incode,short val);
+ virtual void NextFrame();
+};
+#endif //__KX_BLENDERKEYBOARDDEVICE
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.cpp b/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.cpp
new file mode 100644
index 00000000000..e3d4f36cc26
--- /dev/null
+++ b/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.cpp
@@ -0,0 +1,177 @@
+/**
+ * $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
+// annoying warnings about truncated STL debug info
+#pragma warning (disable :4786)
+#endif
+
+#include "KX_BlenderMouseDevice.h"
+
+KX_BlenderMouseDevice::KX_BlenderMouseDevice()
+{
+
+}
+KX_BlenderMouseDevice::~KX_BlenderMouseDevice()
+{
+
+}
+
+/**
+ IsPressed gives boolean information about mouse status, true if pressed, false if not
+*/
+
+bool KX_BlenderMouseDevice::IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)
+{
+ const SCA_InputEvent & inevent = m_eventStatusTables[m_currentTable][inputcode];
+ bool pressed = (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED ||
+ inevent.m_status == SCA_InputEvent::KX_ACTIVE);
+ return pressed;
+}
+/*const SCA_InputEvent& KX_BlenderMouseDevice::GetEventValue(SCA_IInputDevice::KX_EnumInputs inputcode)
+{
+ return m_eventStatusTables[m_currentTable][inputcode];
+}
+*/
+
+/**
+ NextFrame toggles currentTable with previousTable,
+ and copy relevant event information from previous to current
+ (pressed keys need to be remembered)
+*/
+void KX_BlenderMouseDevice::NextFrame()
+{
+ SCA_IInputDevice::NextFrame();
+
+ // now convert justpressed keyevents into regular (active) keyevents
+ int previousTable = 1-m_currentTable;
+ for (int mouseevent= KX_BEGINMOUSE; mouseevent< KX_ENDMOUSEBUTTONS;mouseevent++)
+ {
+ SCA_InputEvent& oldevent = m_eventStatusTables[previousTable][mouseevent];
+ if (oldevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED ||
+ oldevent.m_status == SCA_InputEvent::KX_ACTIVE )
+ {
+ m_eventStatusTables[m_currentTable][mouseevent] = oldevent;
+ m_eventStatusTables[m_currentTable][mouseevent].m_status = SCA_InputEvent::KX_ACTIVE;
+ }
+ }
+ for (int mousemove= KX_ENDMOUSEBUTTONS; mousemove< KX_ENDMOUSE;mousemove++)
+ {
+ SCA_InputEvent& oldevent = m_eventStatusTables[previousTable][mousemove];
+ m_eventStatusTables[m_currentTable][mousemove] = oldevent;
+ if (oldevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED ||
+ oldevent.m_status == SCA_InputEvent::KX_ACTIVE )
+ {
+
+ m_eventStatusTables[m_currentTable][mousemove].m_status = SCA_InputEvent::KX_JUSTRELEASED;
+ } else
+ {
+ if (oldevent.m_status == SCA_InputEvent::KX_JUSTRELEASED)
+ {
+
+ m_eventStatusTables[m_currentTable][mousemove].m_status = SCA_InputEvent::KX_NO_INPUTSTATUS ;
+ }
+ }
+ }
+}
+
+
+/**
+ ConvertBlenderEvent translates blender mouse events into ketsji kbd events
+ extra event information is stored, like ramp-mode (just released/pressed)
+*/
+
+
+bool KX_BlenderMouseDevice::ConvertBlenderEvent(unsigned short incode,short val)
+{
+ bool result = false;
+
+ // convert event
+ KX_EnumInputs kxevent = this->ToNative(incode);
+
+ // only process it, if it's a key
+ if (kxevent > KX_BEGINMOUSE && kxevent < KX_ENDMOUSE)
+ {
+ int previousTable = 1-m_currentTable;
+
+
+ if (val > 0)
+ {
+ m_eventStatusTables[m_currentTable][kxevent].m_eventval = val ; //???
+
+ switch (m_eventStatusTables[previousTable][kxevent].m_status)
+ {
+
+ case SCA_InputEvent::KX_ACTIVE:
+ case SCA_InputEvent::KX_JUSTACTIVATED:
+ {
+ m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_ACTIVE;
+ break;
+ }
+ case SCA_InputEvent::KX_JUSTRELEASED:
+ {
+ if ( kxevent > KX_BEGINMOUSEBUTTONS && kxevent < KX_ENDMOUSEBUTTONS)
+ {
+ m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_JUSTACTIVATED;
+ } else
+ {
+ m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_ACTIVE;
+
+ }
+ break;
+ }
+ default:
+ {
+ m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_JUSTACTIVATED;
+ }
+ }
+
+ } else
+ {
+ // blender eventval == 0
+ switch (m_eventStatusTables[previousTable][kxevent].m_status)
+ {
+ case SCA_InputEvent::KX_JUSTACTIVATED:
+ case SCA_InputEvent::KX_ACTIVE:
+ {
+ m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_JUSTRELEASED;
+ break;
+ }
+ default:
+ {
+ m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_NO_INPUTSTATUS;
+ }
+ }
+ }
+ }
+ return result;
+}
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.h b/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.h
new file mode 100644
index 00000000000..6eb02622f9b
--- /dev/null
+++ b/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.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_BLENDERMOUSEDEVICE
+#define __KX_BLENDERMOUSEDEVICE
+
+#include "KX_BlenderInputDevice.h"
+
+class KX_BlenderMouseDevice : public BL_BlenderInputDevice
+{
+public:
+ KX_BlenderMouseDevice();
+ virtual ~KX_BlenderMouseDevice();
+
+ virtual bool IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode);
+// virtual const SCA_InputEvent& GetEventValue(SCA_IInputDevice::KX_EnumInputs inputcode);
+ virtual bool ConvertBlenderEvent(unsigned short incode,short val);
+ virtual void NextFrame();
+};
+#endif //__KX_BLENDERMOUSEDEVICE
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.cpp b/source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.cpp
new file mode 100644
index 00000000000..fc7eb3a6c7f
--- /dev/null
+++ b/source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.cpp
@@ -0,0 +1,106 @@
+/**
+ * $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 "KX_BlenderPolyMaterial.h"
+#include "BKE_mesh.h"
+
+KX_BlenderPolyMaterial::KX_BlenderPolyMaterial(const STR_String &texname,
+ bool ba,
+ const STR_String& matname,
+ int tile,
+ int tilexrep,
+ int tileyrep,
+ int mode,
+ int transparant,
+ int lightlayer,
+ bool bIsTriangle,
+ void* clientobject,
+ struct TFace* tface)
+ : RAS_IPolyMaterial(texname,
+ false,
+ matname,
+ tile,
+ tilexrep,
+ tileyrep,
+ mode,
+ transparant,
+ lightlayer,
+ bIsTriangle,
+ clientobject),
+ m_tface(tface)
+{
+}
+
+
+void KX_BlenderPolyMaterial::Activate(RAS_IRasterizer* rasty, TCachingInfo& cachingInfo) const
+{
+
+
+ if (GetCachingInfo() != cachingInfo)
+ {
+ if (!cachingInfo)
+ {
+ set_tpage(NULL);
+ }
+ cachingInfo = GetCachingInfo();
+
+ if ((m_drawingmode & 4)&& (rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED))
+ {
+ update_realtime_texture((struct TFace*) m_tface, rasty->GetTime());
+ set_tpage(m_tface);
+ rasty->EnableTextures(true);
+ }
+ else
+ {
+ set_tpage(NULL);
+ rasty->EnableTextures(false);
+ }
+
+ //TF_TWOSIDE == 512, todo, make this a ketsji enum
+ if(m_drawingmode & 512)
+ {
+ rasty->SetCullFace(false);
+ }
+ else
+ {
+ rasty->SetCullFace(true);
+ }
+ }
+
+ rasty->SetSpecularity(m_specular[0],m_specular[1],m_specular[2],m_specularity);
+ rasty->SetShinyness(m_shininess);
+ rasty->SetDiffuse(m_diffuse[0], m_diffuse[1],m_diffuse[2], 1.0);
+}
+
+
+
+
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.h b/source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.h
new file mode 100644
index 00000000000..3513765410f
--- /dev/null
+++ b/source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.h
@@ -0,0 +1,98 @@
+/**
+ * $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_BLENDERPOLYMATERIAL
+#define __KX_BLENDERPOLYMATERIAL
+
+#include "RAS_MaterialBucket.h"
+#include "RAS_IRasterizer.h"
+
+struct TFace;
+extern "C" int set_tpage(TFace* tface); /* Worst hack ever */
+
+
+class KX_BlenderPolyMaterial : public RAS_IPolyMaterial
+{
+ /** Blender texture face structure. */
+ TFace* m_tface;
+
+public:
+
+ KX_BlenderPolyMaterial(const STR_String &texname,
+ bool ba,
+ const STR_String& matname,
+ int tile,
+ int tilexrep,
+ int tileyrep,
+ int mode,
+ int transparant,
+ int lightlayer,
+ bool bIsTriangle,
+ void* clientobject,
+ struct TFace* tface);
+
+ /**
+ * Returns the caching information for this material,
+ * This can be used to speed up the rasterizing process.
+ * @return The caching information.
+ */
+ virtual TCachingInfo GetCachingInfo(void) const;
+
+ /**
+ * Activates the material in the (OpenGL) rasterizer.
+ * On entry, the cachingInfo contains info about the last activated material.
+ * On exit, the cachingInfo should contain updated info about this material.
+ * @param rasty The rasterizer in which the material should be active.
+ * @param cachingInfo The information about the material used to speed up rasterizing.
+ */
+ virtual void Activate(RAS_IRasterizer* rasty, TCachingInfo& cachingInfo) const;
+
+ /**
+ * Returns the Blender texture face structure that is used for this material.
+ * @return The material's texture face.
+ */
+ TFace* GetTFace(void) const;
+protected:
+private:
+};
+
+
+inline TFace* KX_BlenderPolyMaterial::GetTFace(void) const
+{
+ return m_tface;
+}
+
+inline RAS_IPolyMaterial::TCachingInfo KX_BlenderPolyMaterial::GetCachingInfo(void) const
+{
+ return GetTFace();
+}
+
+#endif // __KX_BLENDERPOLYMATERIAL
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
new file mode 100644
index 00000000000..4fdb9aafc33
--- /dev/null
+++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
@@ -0,0 +1,411 @@
+/**
+ * $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 "KX_BlenderRenderTools.h"
+
+#ifdef WIN32
+// OpenGL gl.h needs 'windows.h' on windows platforms
+#include <windows.h>
+#endif //WIN32
+#include "GL/gl.h"
+
+#include "RAS_IRenderTools.h"
+#include "RAS_IRasterizer.h"
+#include "RAS_LightObject.h"
+#include "RAS_ICanvas.h"
+
+
+// next two includes/dependencies come from the shadow feature
+// it needs the gameobject and the sumo physics scene for a raycast
+#include "KX_GameObject.h"
+
+#include "KX_BlenderPolyMaterial.h"
+#include "Value.h"
+
+#include "KX_BlenderGL.h" // for text printing
+#include "STR_String.h"
+#include "RAS_BucketManager.h" // for polymaterial (needed for textprinting)
+
+KX_BlenderRenderTools::KX_BlenderRenderTools()
+{
+}
+
+/**
+ProcessLighting performs lighting on objects. the layer is a bitfield that contains layer information.
+There are 20 'official' layers in blender.
+A light is applied on an object only when they are in the same layer.
+OpenGL has a maximum of 8 lights (simultaneous), so 20 * 8 lights are possible in a scene.
+*/
+
+int KX_BlenderRenderTools::ProcessLighting(int layer)
+{
+
+ int result = false;
+
+ if (layer < 0)
+ {
+ DisableOpenGLLights();
+ result = false;
+ } else
+ {
+ if (m_clientobject)
+ {
+
+
+ if (applyLights(layer))
+ {
+ EnableOpenGLLights();
+ result = true;
+ } else
+ {
+ DisableOpenGLLights();
+ result = false;
+ }
+
+
+ }
+ }
+ return result;
+
+
+}
+
+
+void KX_BlenderRenderTools::BeginFrame(RAS_IRasterizer* rasty)
+{
+ m_clientobject = NULL;
+ m_lastblenderobject = NULL;
+ m_lastblenderlights = false;
+ m_lastlayer = -1;
+ m_lastlighting = false;
+ m_modified = true;
+ DisableOpenGLLights();
+
+
+}
+
+
+void KX_BlenderRenderTools::applyTransform(RAS_IRasterizer* rasty,double* oglmatrix,int objectdrawmode )
+{
+ if (objectdrawmode & RAS_IPolyMaterial::BILLBOARD_SCREENALIGNED ||
+ objectdrawmode & RAS_IPolyMaterial::BILLBOARD_AXISALIGNED)
+ {
+ // rotate the billboard/halo
+ //page 360/361 3D Game Engine Design, David Eberly for a discussion
+ // on screen aligned and axis aligned billboards
+ // assumed is that the preprocessor transformed all billboard polygons
+ // so that their normal points into the positive x direction (1.0 , 0.0 , 0.0)
+ // when new parenting for objects is done, this rotation
+ // will be moved into the object
+
+ MT_Point3 objpos (oglmatrix[12],oglmatrix[13],oglmatrix[14]);
+ MT_Point3 campos = rasty->GetCameraPosition();
+ MT_Vector3 dir = (campos - objpos).safe_normalized();
+ MT_Vector3 up(0,0,1.0);
+
+ KX_GameObject* gameobj = (KX_GameObject*) this->m_clientobject;
+ // get scaling of halo object
+ MT_Vector3 size = gameobj->GetSGNode()->GetLocalScale();
+
+ bool screenaligned = (objectdrawmode & RAS_IPolyMaterial::BILLBOARD_SCREENALIGNED)!=0;//false; //either screen or axisaligned
+ if (screenaligned)
+ {
+ up = (up - up.dot(dir) * dir).safe_normalized();
+ } else
+ {
+ dir = (dir - up.dot(dir)*up).safe_normalized();
+ }
+
+ MT_Vector3 left = dir.normalized();
+ dir = (left.cross(up)).normalized();
+
+ // we have calculated the row vectors, now we keep
+ // local scaling into account:
+
+ left *= size[0];
+ dir *= size[1];
+ up *= size[2];
+ double maat[16]={
+ left[0], left[1],left[2], 0,
+ dir[0], dir[1],dir[2],0,
+ up[0],up[1],up[2],0,
+ 0,0,0,1};
+ glTranslated(objpos[0],objpos[1],objpos[2]);
+ glMultMatrixd(maat);
+
+ } else
+ {
+ if (objectdrawmode & RAS_IPolyMaterial::SHADOW)
+ {
+ // shadow must be cast to the ground, physics system needed here!
+ KX_GameObject* gameobj = (KX_GameObject*) this->m_clientobject;
+ MT_Point3 frompoint(oglmatrix[12],oglmatrix[13],oglmatrix[14]);
+ MT_Vector3 direction = MT_Vector3(0,0,-1);
+
+
+ direction.normalize();
+ direction *= 100000;
+
+ MT_Point3 topoint = frompoint + direction;
+ MT_Point3 resultpoint;
+ MT_Vector3 resultnormal;
+
+ //todo:
+ //use physics abstraction
+
+
+ //SM_Scene* scene = (SM_Scene*) m_auxilaryClientInfo;
+
+ //SM_Object* hitObj = scene->rayTest(gameobj->GetSumoObject(),frompoint,topoint,
+ // resultpoint, resultnormal);
+
+
+ if (0) //hitObj)
+ {
+ MT_Vector3 left(oglmatrix[0],oglmatrix[1],oglmatrix[2]);
+ MT_Vector3 dir = -(left.cross(resultnormal)).normalized();
+ left = (dir.cross(resultnormal)).normalized();
+ // for the up vector, we take the 'resultnormal' returned by the physics
+
+ double maat[16]={
+ left[0], left[1],left[2], 0,
+ dir[0], dir[1],dir[2],0,
+ resultnormal[0],resultnormal[1],resultnormal[2],0,
+ 0,0,0,1};
+ glTranslated(resultpoint[0],resultpoint[1],resultpoint[2]);
+ glMultMatrixd(maat);
+ // glMultMatrixd(oglmatrix);
+ } else
+ {
+ glMultMatrixd(oglmatrix);
+ }
+
+
+ } else
+ {
+
+ // 'normal' object
+ glMultMatrixd(oglmatrix);
+ }
+ }
+}
+
+
+/**
+Render Text renders text into a (series of) polygon, using a texture font,
+Each character consists of one polygon (one quad or two triangles)
+*/
+void KX_BlenderRenderTools::RenderText(int mode,RAS_IPolyMaterial* polymat,float v1[3],float v2[3],float v3[3],float v4[3])
+{
+
+ STR_String mytext = ((CValue*)m_clientobject)->GetPropertyText("Text");
+
+ KX_BlenderPolyMaterial* blenderpoly = (KX_BlenderPolyMaterial*)polymat;
+ struct TFace* tface = blenderpoly->GetTFace();
+
+ BL_RenderText( mode,mytext,mytext.Length(),tface,v1,v2,v3,v4);
+
+}
+
+
+
+KX_BlenderRenderTools::~KX_BlenderRenderTools()
+{
+};
+
+
+void KX_BlenderRenderTools::EndFrame(RAS_IRasterizer* rasty)
+{
+}
+
+
+
+void KX_BlenderRenderTools::DisableOpenGLLights()
+{
+ glDisable(GL_LIGHTING);
+ glDisable(GL_COLOR_MATERIAL);
+#ifndef SLOWPAINT
+ glDisableClientState(GL_NORMAL_ARRAY);
+#endif //SLOWPAINT
+}
+
+
+void KX_BlenderRenderTools::EnableOpenGLLights()
+{
+ glEnable(GL_LIGHTING);
+
+ glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);
+ glEnable(GL_COLOR_MATERIAL);
+#ifndef SLOWPAINT
+ glEnableClientState(GL_NORMAL_ARRAY);
+#endif //SLOWPAINT
+ glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, false);
+}
+
+
+/**
+ * Rendering text using 2D bitmap functionality.
+ */
+void KX_BlenderRenderTools::RenderText2D(RAS_TEXT_RENDER_MODE mode,
+ const char* text,
+ int xco,
+ int yco,
+ int width,
+ int height)
+{
+ switch (mode) {
+ case RAS_IRenderTools::RAS_TEXT_PADDED: {
+ STR_String tmpstr(text);
+ BL_print_gamedebug_line_padded(tmpstr.Ptr(),xco,yco,width,height);
+ break;
+ }
+ default: {
+ STR_String tmpstr(text);
+ BL_print_gamedebug_line(tmpstr.Ptr(),xco,yco,width,height);
+ }
+ }
+}
+
+
+
+void KX_BlenderRenderTools::PushMatrix()
+{
+ glPushMatrix();
+}
+
+void KX_BlenderRenderTools::PopMatrix()
+{
+ glPopMatrix();
+}
+
+
+
+int KX_BlenderRenderTools::applyLights(int objectlayer)
+{
+// taken from blender source, incompatibility between Blender Object / GameObject
+
+ int count;
+ float vec[4];
+
+ vec[3]= 1.0;
+
+ for(count=0; count<8; count++)
+ glDisable((GLenum)(GL_LIGHT0+count));
+
+ count= 0;
+
+ //std::vector<struct RAS_LightObject*> m_lights;
+ std::vector<struct RAS_LightObject*>::iterator lit = m_lights.begin();
+
+
+ for (lit = m_lights.begin(); !(lit==m_lights.end()); ++lit)
+ {
+ RAS_LightObject* lightdata = (*lit);
+ if (lightdata->m_layer & objectlayer)
+ {
+
+ glPushMatrix();
+ glLoadMatrixf(m_viewmat);
+
+
+ vec[0] = (*(lightdata->m_worldmatrix))(0,3);
+ vec[1] = (*(lightdata->m_worldmatrix))(1,3);
+ vec[2] = (*(lightdata->m_worldmatrix))(2,3);
+ vec[3] = 1;
+
+
+ if(lightdata->m_type==RAS_LightObject::LIGHT_SUN) {
+
+ vec[0] = (*(lightdata->m_worldmatrix))(0,2);
+ vec[1] = (*(lightdata->m_worldmatrix))(1,2);
+ vec[2] = (*(lightdata->m_worldmatrix))(2,2);
+ //vec[0]= base->object->obmat[2][0];
+ //vec[1]= base->object->obmat[2][1];
+ //vec[2]= base->object->obmat[2][2];
+ vec[3]= 0.0;
+ glLightfv((GLenum)(GL_LIGHT0+count), GL_POSITION, vec);
+ }
+ else {
+ //vec[3]= 1.0;
+ glLightfv((GLenum)(GL_LIGHT0+count), GL_POSITION, vec);
+ glLightf((GLenum)(GL_LIGHT0+count), GL_CONSTANT_ATTENUATION, 1.0);
+ glLightf((GLenum)(GL_LIGHT0+count), GL_LINEAR_ATTENUATION, lightdata->m_att1/lightdata->m_distance);
+ // without this next line it looks backward compatible.
+ //attennuation still is acceptable
+ // glLightf((GLenum)(GL_LIGHT0+count), GL_QUADRATIC_ATTENUATION, la->att2/(la->dist*la->dist));
+
+ if(lightdata->m_type==RAS_LightObject::LIGHT_SPOT) {
+ vec[0] = -(*(lightdata->m_worldmatrix))(0,2);
+ vec[1] = -(*(lightdata->m_worldmatrix))(1,2);
+ vec[2] = -(*(lightdata->m_worldmatrix))(2,2);
+ //vec[0]= -base->object->obmat[2][0];
+ //vec[1]= -base->object->obmat[2][1];
+ //vec[2]= -base->object->obmat[2][2];
+ glLightfv((GLenum)(GL_LIGHT0+count), GL_SPOT_DIRECTION, vec);
+ glLightf((GLenum)(GL_LIGHT0+count), GL_SPOT_CUTOFF, lightdata->m_spotsize/2.0);
+ glLightf((GLenum)(GL_LIGHT0+count), GL_SPOT_EXPONENT, 128.0*lightdata->m_spotblend);
+ }
+ else glLightf((GLenum)(GL_LIGHT0+count), GL_SPOT_CUTOFF, 180.0);
+ }
+
+ vec[0]= lightdata->m_energy*lightdata->m_red;
+ vec[1]= lightdata->m_energy*lightdata->m_green;
+ vec[2]= lightdata->m_energy*lightdata->m_blue;
+ vec[3]= 1.0;
+ glLightfv((GLenum)(GL_LIGHT0+count), GL_DIFFUSE, vec);
+ glLightfv((GLenum)(GL_LIGHT0+count), GL_SPECULAR, vec);
+ glEnable((GLenum)(GL_LIGHT0+count));
+
+ glPopMatrix();
+
+ count++;
+ if(count>7)
+ break;
+ }
+ }
+
+ return count;
+
+}
+
+
+
+RAS_IPolyMaterial* KX_BlenderRenderTools::CreateBlenderPolyMaterial(
+ const STR_String &texname,
+ bool ba,const STR_String& matname,int tile,int tilexrep,int tileyrep,int mode,int transparant,int lightlayer
+ ,bool bIsTriangle,void* clientobject,void* tface)
+{
+ return new KX_BlenderPolyMaterial(
+
+ texname,
+ ba,matname,tile,tilexrep,tileyrep,mode,transparant,lightlayer
+ ,bIsTriangle,clientobject,(struct TFace*)tface);
+}
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h
new file mode 100644
index 00000000000..fb4c5a6f2ba
--- /dev/null
+++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h
@@ -0,0 +1,100 @@
+/**
+ * $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_BLENDERRENDERTOOLS
+#define __KX_BLENDERRENDERTOOLS
+
+#ifdef WIN32
+// don't show stl-warnings
+#pragma warning (disable:4786)
+#endif
+
+#include "RAS_IRenderTools.h"
+
+/**
+BlenderRenderTools are a set of tools to apply 2D/3D graphics effects, which are not
+part of the (polygon) Rasterizer.
+Effects like 2D text, 3D (polygon) text, lighting.
+*/
+
+class KX_BlenderRenderTools : public RAS_IRenderTools
+{
+ bool m_lastblenderlights;
+ void* m_lastblenderobject;
+ int m_lastlayer;
+ bool m_lastlighting;
+
+public:
+
+ KX_BlenderRenderTools();
+ virtual ~KX_BlenderRenderTools();
+
+ virtual void EndFrame(class RAS_IRasterizer* rasty);
+ virtual void BeginFrame(class RAS_IRasterizer* rasty);
+ void DisableOpenGLLights();
+ void EnableOpenGLLights();
+ int ProcessLighting(int layer);
+
+ virtual void RenderText2D(RAS_TEXT_RENDER_MODE mode,
+ const char* text,
+ int xco,
+ int yco,
+ int width,
+ int height);
+ virtual void RenderText(int mode,
+ class RAS_IPolyMaterial* polymat,
+ float v1[3],
+ float v2[3],
+ float v3[3],
+ float v4[3]);
+ void applyTransform(class RAS_IRasterizer* rasty,
+ double* oglmatrix,
+ int objectdrawmode );
+ int applyLights(int objectlayer);
+ virtual void PushMatrix();
+ virtual void PopMatrix();
+
+ virtual class RAS_IPolyMaterial* CreateBlenderPolyMaterial(const STR_String &texname,
+ bool ba,
+ const STR_String& matname,
+ int tile,
+ int tilexrep,
+ int tileyrep,
+ int mode,
+ int transparant,
+ int lightlayer,
+ bool bIsTriangle,
+ void* clientobject,
+ void* tface);
+};
+
+
+#endif //__KX_BLENDERRENDERTOOLS
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderSystem.cpp b/source/gameengine/BlenderRoutines/KX_BlenderSystem.cpp
new file mode 100644
index 00000000000..f690f7c74e2
--- /dev/null
+++ b/source/gameengine/BlenderRoutines/KX_BlenderSystem.cpp
@@ -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 *****
+ */
+
+#include "KX_ISystem.h"
+
+
+#ifdef WIN32
+#pragma warning (disable :4786)
+#include <windows.h>
+#endif //WIN32
+
+#include <iostream>
+#include <stdio.h>
+#include "KX_BlenderInputDevice.h"
+#include "KX_BlenderSystem.h"
+
+#include "PIL_time.h"
+
+KX_BlenderSystem::KX_BlenderSystem()
+: KX_ISystem()
+{
+ m_starttime = PIL_check_seconds_timer();
+}
+
+double KX_BlenderSystem::GetTimeInSeconds()
+{
+ return PIL_check_seconds_timer() - m_starttime;
+}
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderSystem.h b/source/gameengine/BlenderRoutines/KX_BlenderSystem.h
new file mode 100644
index 00000000000..68db3194b0a
--- /dev/null
+++ b/source/gameengine/BlenderRoutines/KX_BlenderSystem.h
@@ -0,0 +1,51 @@
+/**
+ * $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_BLENDERSYSTEM
+#define __KX_BLENDERSYSTEM
+
+#include "blendertimer.h"
+
+/**
+ * Blender System embedding. Needed when gameengine runs embedded within Blender.
+ */
+#include "KX_ISystem.h"
+
+class KX_BlenderSystem : public KX_ISystem
+{
+ double m_starttime;
+
+public:
+ KX_BlenderSystem();
+ virtual ~KX_BlenderSystem() {};
+ virtual double GetTimeInSeconds();
+};
+#endif //__KX_BLENDERSYSTEM
diff --git a/source/gameengine/BlenderRoutines/Makefile b/source/gameengine/BlenderRoutines/Makefile
new file mode 100644
index 00000000000..9a4ba217ac7
--- /dev/null
+++ b/source/gameengine/BlenderRoutines/Makefile
@@ -0,0 +1,75 @@
+#
+# $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 = bloutines
+DIR = $(OCGDIR)/gameengine/$(LIBNAME)
+
+include nan_compile.mk
+
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+CPPFLAGS += -I$(OPENGL_HEADERS)
+CPPFLAGS += -I$(NAN_SUMO)/include
+CPPFLAGS += -I$(NAN_STRING)/include
+CPPFLAGS += -I$(NAN_MOTO)/include
+CPPFLAGS += -I$(NAN_BMFONT)/include
+CPPFLAGS += -I$(NAN_FUZZICS)/include
+# because of kernel dependency on makesdna
+CPPFLAGS += -I../../blender/makesdna
+CPPFLAGS += -I../../blender/include
+# timer stuff
+CPPFLAGS += -I../../blender/misc
+# because of kernel dependency on imbuf
+CPPFLAGS += -I../../blender/imbuf
+CPPFLAGS += -I../../blender/blenlib
+CPPFLAGS += -I../../blender/blenkernel
+CPPFLAGS += -I../../blender/render/extern/include
+CPPFLAGS += -I../../blender/blenloader
+CPPFLAGS += -I../../blender/blenkernel
+CPPFLAGS += -I../Converter
+CPPFLAGS += -I../Expressions
+CPPFLAGS += -I../GameLogic
+CPPFLAGS += -I../Ketsji
+CPPFLAGS += -I../Rasterizer
+CPPFLAGS += -I../Rasterizer/RAS_OpenGLRasterizer
+CPPFLAGS += -I../SceneGraph
+CPPFLAGS += -I../SoundSystem
+CPPFLAGS += -I../../kernel/gen_system
+CPPFLAGS += -I../Network
+CPPFLAGS += -I../Network/LoopBackNetwork
+ifeq ($(OS),windows)
+ CPPFLAGS += -I../../blender
+endif
+
+CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
+
diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp
new file mode 100644
index 00000000000..cbe0dd2263c
--- /dev/null
+++ b/source/gameengine/Converter/BL_ActionActuator.cpp
@@ -0,0 +1,805 @@
+/**
+* $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_LogicManager.h"
+#include "BL_ActionActuator.h"
+#include "BL_ArmatureObject.h"
+#include "BL_SkinDeformer.h"
+#include "KX_GameObject.h"
+#include "STR_HashedString.h"
+#include "DNA_action_types.h"
+#include "DNA_actuator_types.h"
+#include "BKE_action.h"
+#include "DNA_armature_types.h"
+#include "MEM_guardedalloc.h"
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+#include "MT_Matrix4x4.h"
+#include "BKE_utildefines.h"
+
+BL_ActionActuator::~BL_ActionActuator()
+{
+ if (m_pose) {
+ clear_pose(m_pose);
+ MEM_freeN(m_pose);
+ m_pose = NULL;
+ };
+
+ if (m_userpose){
+ clear_pose(m_userpose);
+ MEM_freeN(m_userpose);
+ m_userpose=NULL;
+ }
+ if (m_blendpose) {
+ clear_pose(m_blendpose);
+ MEM_freeN(m_blendpose);
+ m_blendpose = NULL;
+ };
+
+}
+
+void BL_ActionActuator::ProcessReplica(){
+ bPose *oldpose = m_pose;
+ bPose *oldbpose = m_blendpose;
+
+ m_pose = NULL;
+ m_blendpose = NULL;
+ m_localtime=m_starttime;
+ m_lastUpdate=-1;
+
+}
+
+void BL_ActionActuator::SetBlendTime (float newtime){
+ m_blendframe = newtime;
+}
+
+CValue* BL_ActionActuator::GetReplica() {
+ BL_ActionActuator* replica = new BL_ActionActuator(*this);//m_float,GetName());
+ replica->ProcessReplica();
+
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+ return replica;
+};
+
+bool BL_ActionActuator::Update(double curtime,double deltatime)
+{
+ bool bNegativeEvent = false;
+ bool bPositiveEvent = false;
+ int numevents = m_events.size();
+ bool keepgoing = true;
+ bool wrap = false;
+ bool apply=true;
+ int priority;
+ float newweight;
+
+ // result = true if animation has to be continued, false if animation stops
+ // maybe there are events for us in the queue !
+
+ for (vector<CValue*>::iterator i=m_events.end(); !(i==m_events.begin());)
+ {
+ i--;
+ if ((*i)->GetNumber() == 0.0f)
+ {
+ int ka=0;
+ bNegativeEvent = true;
+ }
+ else
+ bPositiveEvent= true;
+ (*i)->Release();
+ m_events.pop_back();
+ }
+
+ /* We know that action actuators have been discarded from all non armature objects:
+ if we're being called, we're attached to a BL_ArmatureObject */
+ BL_ArmatureObject *obj = (BL_ArmatureObject*)GetParent();
+ int length = m_endtime - m_starttime;
+
+ priority = m_priority;
+
+ /* Determine pre-incrementation behaviour and set appropriate flags */
+ switch (m_playtype){
+ case ACT_ACTION_MOTION:
+ if (bNegativeEvent){
+ keepgoing=false;
+ apply=false;
+ };
+ break;
+ case ACT_ACTION_FROM_PROP:
+ if (bNegativeEvent){
+ apply=false;
+ keepgoing=false;
+ }
+ break;
+ case ACT_ACTION_LOOP_END:
+ if (bPositiveEvent){
+ if (!(m_flag & ACT_FLAG_LOCKINPUT)){
+ m_flag &= ~ACT_FLAG_KEYUP;
+ m_flag &= ~ACT_FLAG_REVERSE;
+ m_flag |= ACT_FLAG_LOCKINPUT;
+ m_localtime = m_starttime;
+ }
+ }
+ if (bNegativeEvent){
+ m_flag |= ACT_FLAG_KEYUP;
+ }
+ break;
+ case ACT_ACTION_LOOP_STOP:
+ if (bPositiveEvent){
+ if (!(m_flag & ACT_FLAG_LOCKINPUT)){
+ m_flag &= ~ACT_FLAG_REVERSE;
+ }
+ }
+ if (bNegativeEvent){
+ keepgoing=false;
+ apply=false;
+ }
+ break;
+ case ACT_ACTION_FLIPPER:
+ if (bPositiveEvent){
+ if (!(m_flag & ACT_FLAG_LOCKINPUT)){
+ m_flag &= ~ACT_FLAG_REVERSE;
+ }
+ }
+ else if (bNegativeEvent){
+ m_flag |= ACT_FLAG_REVERSE;
+ }
+ break;
+ case ACT_ACTION_PLAY:
+ if (bPositiveEvent){
+ if (!(m_flag & ACT_FLAG_LOCKINPUT)){
+ m_flag &= ~ACT_FLAG_REVERSE;
+ m_localtime = m_starttime;
+ m_flag |= ACT_FLAG_LOCKINPUT;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ /* Perform increment */
+ if (keepgoing){
+ if (m_playtype == ACT_ACTION_MOTION){
+ MT_Point3 newpos;
+ MT_Point3 deltapos;
+
+ newpos = obj->NodeGetWorldPosition();
+
+ /* Find displacement */
+ deltapos = newpos-m_lastpos;
+ m_localtime += (length/m_stridelength) * deltapos.length();
+ m_lastpos = newpos;
+ }
+ else{
+ if (m_flag & ACT_FLAG_REVERSE)
+ m_localtime -= deltatime* KX_FIXED_FRAME_PER_SEC;
+ else
+ m_localtime += deltatime* KX_FIXED_FRAME_PER_SEC;
+ }
+ }
+
+ /* Check if a wrapping response is needed */
+ if (length){
+ if (m_flag & ACT_FLAG_REVERSE){
+ if (m_localtime < m_starttime){
+ m_localtime = m_endtime+(
+ (int)((m_localtime - m_starttime)/length)
+ *(int)length);
+ wrap = true;
+ }
+ }
+ else{
+ if (m_localtime > m_endtime){
+ m_localtime = m_starttime+(
+ (int)((m_localtime - m_endtime)/length)
+ *(int)length);
+ wrap = true;
+ }
+ }
+
+ }
+ else
+ m_localtime = m_starttime;
+
+ /* Perform post-increment tasks */
+ switch (m_playtype){
+ case ACT_ACTION_FROM_PROP:
+ {
+ CValue* propval = GetParent()->GetProperty(m_propname);
+ if (propval) {
+ m_localtime = propval->GetNumber();
+ };
+
+ if (bNegativeEvent){
+ keepgoing=false;
+ }
+ }
+ break;
+ case ACT_ACTION_MOTION:
+ break;
+ case ACT_ACTION_LOOP_STOP:
+ break;
+ case ACT_ACTION_FLIPPER:
+ if (wrap){
+ if (!(m_flag & ACT_FLAG_REVERSE)){
+ m_localtime=m_endtime;
+ keepgoing = false;
+ }
+ else {
+ m_localtime=m_starttime;
+ keepgoing = false;
+ }
+ }
+ break;
+ case ACT_ACTION_LOOP_END:
+ if (wrap){
+ if (m_flag & ACT_FLAG_KEYUP){
+ keepgoing = false;
+ m_localtime = m_endtime;
+ m_flag &= ~ACT_FLAG_LOCKINPUT;
+ }
+ }
+ break;
+ case ACT_ACTION_PLAY:
+ if (wrap){
+ m_localtime = m_endtime;
+ keepgoing = false;
+ m_flag &= ~ACT_FLAG_LOCKINPUT;
+ }
+ break;
+ default:
+ keepgoing = false;
+ break;
+ }
+
+
+ if (bNegativeEvent){
+ m_blendframe=0.0;
+
+ }
+
+
+ /* Apply the pose if necessary*/
+ if (apply){
+
+ /* Priority test */
+ if (obj->SetActiveAction(this, priority, curtime)){
+
+ /* Get the underlying pose from the armature */
+ obj->GetPose(&m_pose);
+
+ /* Override the necessary channels with ones from the action */
+ get_pose_from_action(&m_pose, m_action, m_localtime);
+
+ /* Perform the user override (if any) */
+ if (m_userpose){
+ get_pose_from_pose(&m_pose, m_userpose);
+ clear_pose(m_userpose);
+ MEM_freeN(m_userpose);
+ m_userpose = NULL;
+ }
+#if 1
+ /* Handle blending */
+ if (m_blendin && (m_blendframe<m_blendin)){
+ /* If this is the start of a blending sequence... */
+ if ((m_blendframe==0.0) || (!m_blendpose)){
+ obj->GetMRDPose(&m_blendpose);
+ }
+
+ /* Find percentages */
+ newweight = (m_blendframe/(float)m_blendin);
+ blend_poses(m_pose, m_blendpose, 1.0 - newweight, POSE_BLEND);
+
+ /* Increment current blending percentage */
+ m_blendframe+=(deltatime*KX_FIXED_FRAME_PER_SEC);
+ if (m_blendframe>m_blendin)
+ m_blendframe = m_blendin;
+
+ }
+#endif
+ m_lastUpdate = m_localtime;
+ obj->SetPose (m_pose);
+ }
+ else{
+ m_blendframe = 0.0;
+ }
+ }
+
+ if (!keepgoing){
+ m_blendframe = 0.0;
+ }
+ return keepgoing;
+};
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+
+PyTypeObject BL_ActionActuator::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "BL_ActionActuator",
+ sizeof(BL_ActionActuator),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject BL_ActionActuator::Parents[] = {
+ &BL_ActionActuator::Type,
+ &SCA_IActuator::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef BL_ActionActuator::Methods[] = {
+ {"setAction", (PyCFunction) BL_ActionActuator::sPySetAction, METH_VARARGS, SetAction_doc},
+ {"setStart", (PyCFunction) BL_ActionActuator::sPySetStart, METH_VARARGS, SetStart_doc},
+ {"setEnd", (PyCFunction) BL_ActionActuator::sPySetEnd, METH_VARARGS, SetEnd_doc},
+ {"setBlendin", (PyCFunction) BL_ActionActuator::sPySetBlendin, METH_VARARGS, SetBlendin_doc},
+ {"setPriority", (PyCFunction) BL_ActionActuator::sPySetPriority, METH_VARARGS, SetPriority_doc},
+ {"setFrame", (PyCFunction) BL_ActionActuator::sPySetFrame, METH_VARARGS, SetFrame_doc},
+ {"setProperty", (PyCFunction) BL_ActionActuator::sPySetProperty, METH_VARARGS, SetProperty_doc},
+ {"setBlendtime", (PyCFunction) BL_ActionActuator::sPySetBlendtime, METH_VARARGS, SetBlendtime_doc},
+
+ {"getAction", (PyCFunction) BL_ActionActuator::sPyGetAction, METH_VARARGS, GetAction_doc},
+ {"getStart", (PyCFunction) BL_ActionActuator::sPyGetStart, METH_VARARGS, GetStart_doc},
+ {"getEnd", (PyCFunction) BL_ActionActuator::sPyGetEnd, METH_VARARGS, GetEnd_doc},
+ {"getBlendin", (PyCFunction) BL_ActionActuator::sPyGetBlendin, METH_VARARGS, GetBlendin_doc},
+ {"getPriority", (PyCFunction) BL_ActionActuator::sPyGetPriority, METH_VARARGS, GetPriority_doc},
+ {"getFrame", (PyCFunction) BL_ActionActuator::sPyGetFrame, METH_VARARGS, GetFrame_doc},
+ {"getProperty", (PyCFunction) BL_ActionActuator::sPyGetProperty, METH_VARARGS, GetProperty_doc},
+ {"setChannel", (PyCFunction) BL_ActionActuator::sPySetChannel, METH_VARARGS, SetChannel_doc},
+// {"getChannel", (PyCFunction) BL_ActionActuator::sPyGetChannel, METH_VARARGS},
+
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* BL_ActionActuator::_getattr(char* attr) {
+ _getattr_up(SCA_IActuator);
+}
+
+/* setStart */
+char BL_ActionActuator::GetAction_doc[] =
+"getAction()\n"
+"\tReturns a string containing the name of the current action.\n";
+
+PyObject* BL_ActionActuator::PyGetAction(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ PyObject *result;
+
+ if (m_action){
+ result = Py_BuildValue("s", m_action->id.name+2);
+ }
+ else{
+ Py_INCREF(Py_None);
+ result = Py_None;
+ }
+
+ return result;
+}
+
+/* getProperty */
+char BL_ActionActuator::GetProperty_doc[] =
+"getProperty()\n"
+"\tReturns the name of the property to be used in FromProp mode.\n";
+
+PyObject* BL_ActionActuator::PyGetProperty(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ PyObject *result;
+
+ result = Py_BuildValue("s", m_propname);
+
+ return result;
+}
+
+/* getFrame */
+char BL_ActionActuator::GetFrame_doc[] =
+"getFrame()\n"
+"\tReturns the current frame number.\n";
+
+PyObject* BL_ActionActuator::PyGetFrame(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ PyObject *result;
+
+ result = Py_BuildValue("f", m_localtime);
+
+ return result;
+}
+
+/* getEnd */
+char BL_ActionActuator::GetEnd_doc[] =
+"getEnd()\n"
+"\tReturns the last frame of the action.\n";
+
+PyObject* BL_ActionActuator::PyGetEnd(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ PyObject *result;
+
+ result = Py_BuildValue("f", m_endtime);
+
+ return result;
+}
+
+/* getStart */
+char BL_ActionActuator::GetStart_doc[] =
+"getStart()\n"
+"\tReturns the starting frame of the action.\n";
+
+PyObject* BL_ActionActuator::PyGetStart(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ PyObject *result;
+
+ result = Py_BuildValue("f", m_starttime);
+
+ return result;
+}
+
+/* getBlendin */
+char BL_ActionActuator::GetBlendin_doc[] =
+"getBlendin()\n"
+"\tReturns the number of interpolation animation frames to be\n"
+"\tgenerated when this actuator is triggered.\n";
+
+PyObject* BL_ActionActuator::PyGetBlendin(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ PyObject *result;
+
+ result = Py_BuildValue("f", m_blendin);
+
+ return result;
+}
+
+/* getPriority */
+char BL_ActionActuator::GetPriority_doc[] =
+"getPriority()\n"
+"\tReturns the priority for this actuator. Actuators with lower\n"
+"\tPriority numbers will override actuators with higher numbers.\n";
+
+PyObject* BL_ActionActuator::PyGetPriority(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ PyObject *result;
+
+ result = Py_BuildValue("i", m_priority);
+
+ return result;
+}
+
+/* setAction */
+char BL_ActionActuator::SetAction_doc[] =
+"setAction(action, (reset))\n"
+"\t - action : The name of the action to set as the current action.\n"
+"\t - reset : Optional parameter indicating whether to reset the\n"
+"\t blend timer or not. A value of 1 indicates that the\n"
+"\t timer should be reset. A value of 0 will leave it\n"
+"\t unchanged. If reset is not specified, the timer will"
+"\t be reset.\n";
+
+PyObject* BL_ActionActuator::PySetAction(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ char *string;
+ int reset = 1;
+
+ if (PyArg_ParseTuple(args,"s|i",&string, &reset))
+ {
+ bAction *action;
+
+ action = (bAction*)SCA_ILogicBrick::m_sCurrentLogicManager->GetActionByName(STR_String(string));
+
+ if (!action){
+ /* NOTE! Throw an exception or something */
+ // printf ("setAction failed: Action not found\n", string);
+ }
+ else{
+ m_action=action;
+ if (reset)
+ m_blendframe = 0;
+ }
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* setStart */
+char BL_ActionActuator::SetStart_doc[] =
+"setStart(start)\n"
+"\t - start : Specifies the starting frame of the animation.\n";
+
+PyObject* BL_ActionActuator::PySetStart(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ float start;
+
+ if (PyArg_ParseTuple(args,"f",&start))
+ {
+ m_starttime = start;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* setEnd */
+char BL_ActionActuator::SetEnd_doc[] =
+"setEnd(end)\n"
+"\t - end : Specifies the ending frame of the animation.\n";
+
+PyObject* BL_ActionActuator::PySetEnd(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ float end;
+
+ if (PyArg_ParseTuple(args,"f",&end))
+ {
+ m_endtime = end;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* setBlendin */
+char BL_ActionActuator::SetBlendin_doc[] =
+"setBlendin(blendin)\n"
+"\t - blendin : Specifies the number of frames of animation to generate\n"
+"\t when making transitions between actions.\n";
+
+PyObject* BL_ActionActuator::PySetBlendin(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ float blendin;
+
+ if (PyArg_ParseTuple(args,"f",&blendin))
+ {
+ m_blendin = blendin;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* setBlendtime */
+char BL_ActionActuator::SetBlendtime_doc[] =
+"setBlendtime(blendtime)\n"
+"\t - blendtime : Allows the script to directly modify the internal timer\n"
+"\t used when generating transitions between actions. This\n"
+"\t parameter must be in the range from 0.0 to 1.0.\n";
+
+PyObject* BL_ActionActuator::PySetBlendtime(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ float blendframe;
+
+ if (PyArg_ParseTuple(args,"f",&blendframe))
+ {
+ m_blendframe = blendframe * m_blendin;
+ if (m_blendframe<0)
+ m_blendframe = 0;
+ if (m_blendframe>m_blendin)
+ m_blendframe = m_blendin;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* setPriority */
+char BL_ActionActuator::SetPriority_doc[] =
+"setPriority(priority)\n"
+"\t - priority : Specifies the new priority. Actuators will lower\n"
+"\t priority numbers will override actuators with higher\n"
+"\t numbers.\n";
+
+PyObject* BL_ActionActuator::PySetPriority(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ int priority;
+
+ if (PyArg_ParseTuple(args,"i",&priority))
+ {
+ m_priority = priority;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* setFrame */
+char BL_ActionActuator::SetFrame_doc[] =
+"setFrame(frame)\n"
+"\t - frame : Specifies the new current frame for the animation\n";
+
+PyObject* BL_ActionActuator::PySetFrame(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ float frame;
+
+ if (PyArg_ParseTuple(args,"f",&frame))
+ {
+ m_localtime = frame;
+ if (m_localtime<m_starttime)
+ m_localtime=m_starttime;
+ else if (m_localtime>m_endtime)
+ m_localtime=m_endtime;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* setProperty */
+char BL_ActionActuator::SetProperty_doc[] =
+"setProperty(prop)\n"
+"\t - prop : A string specifying the property name to be used in\n"
+"\t FromProp playback mode.\n";
+
+PyObject* BL_ActionActuator::PySetProperty(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ char *string;
+
+ if (PyArg_ParseTuple(args,"s",&string))
+ {
+ m_propname = string;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/*
+PyObject* BL_ActionActuator::PyGetChannel(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ char *string;
+
+ if (PyArg_ParseTuple(args,"s",&string))
+ {
+ m_propname = string;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+*/
+
+/* setChannel */
+char BL_ActionActuator::SetChannel_doc[] =
+"setChannel(channel, matrix)\n"
+"\t - channel : A string specifying the name of the bone channel.\n"
+"\t - matrix : A 4x4 matrix specifying the overriding transformation\n"
+"\t as an offset from the bone's rest position.\n";
+
+PyObject* BL_ActionActuator::PySetChannel(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ float matrix[4][4];
+ char *string;
+ PyObject* pylist;
+ bool error = false;
+ int row,col;
+ int mode = 0; /* 0 for bone space, 1 for armature/world space */
+
+ PyArg_ParseTuple(args,"sO|i", &string, &pylist, &mode);
+
+ if (pylist->ob_type == &CListValue::Type)
+ {
+ CListValue* listval = (CListValue*) pylist;
+ if (listval->GetCount() == 4)
+ {
+ for (row=0;row<4;row++) // each row has a 4-vector [x,y,z, w]
+ {
+ CListValue* vecval = (CListValue*)listval->GetValue(row);
+ for (col=0;col<4;col++)
+ {
+ matrix[row][col] = vecval->GetValue(col)->GetNumber();
+
+ }
+ }
+ }
+ else
+ {
+ error = true;
+ }
+ }
+ else
+ {
+ // assert the list is long enough...
+ int numitems = PyList_Size(pylist);
+ if (numitems == 4)
+ {
+ for (row=0;row<4;row++) // each row has a 4-vector [x,y,z, w]
+ {
+
+ PyObject* veclist = PyList_GetItem(pylist,row); // here we have a vector4 list
+ for (col=0;col<4;col++)
+ {
+ matrix[row][col] = PyFloat_AsDouble(PyList_GetItem(veclist,col));
+
+ }
+ }
+ }
+ else
+ {
+ error = true;
+ }
+ }
+
+ if (!error)
+ {
+
+/* DO IT HERE */
+ bPoseChannel *pchan;
+
+ pchan = (bPoseChannel*) MEM_callocN(sizeof(bPoseChannel), "userChannel");
+ strcpy(pchan->name, string);
+ Mat4ToQuat(matrix, pchan->quat);
+ Mat4ToSize(matrix, pchan->size);
+ VECCOPY (pchan->loc, matrix[3]);
+
+ pchan->flag |= POSE_ROT|POSE_LOC|POSE_SIZE;
+
+ if (!m_userpose){
+ m_userpose = (bPose*)MEM_callocN(sizeof(bPose), "userPose");
+ }
+
+ verify_pose_channel(m_userpose, string);
+ set_pose_channel(m_userpose, pchan);
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
diff --git a/source/gameengine/Converter/BL_ActionActuator.h b/source/gameengine/Converter/BL_ActionActuator.h
new file mode 100644
index 00000000000..49485cb324d
--- /dev/null
+++ b/source/gameengine/Converter/BL_ActionActuator.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 *****
+ */
+
+#ifndef BL_ACTIONACTUATOR
+#define BL_ACTIONACTUATOR
+
+#include "SCA_IActuator.h"
+#include "MT_Point3.h"
+
+class BL_ActionActuator : public SCA_IActuator
+{
+public:
+ Py_Header;
+ BL_ActionActuator(SCA_IObject* gameobj,
+ const STR_String& propname,
+ float starttime,
+ float endtime,
+ struct bAction *action,
+ short playtype,
+ short blendin,
+ short priority,
+ float stride,
+ PyTypeObject* T=&Type)
+ : SCA_IActuator(gameobj,T),
+ m_starttime (starttime),
+ m_endtime(endtime) ,
+ m_localtime(starttime),
+ m_lastUpdate(-1),
+ m_propname(propname),
+ m_action(action),
+ m_playtype(playtype),
+ m_flag(0),
+ m_blendin(blendin),
+ m_blendframe(0),
+ m_pose(NULL),
+ m_userpose(NULL),
+ m_blendpose(NULL),
+ m_priority(priority),
+ m_stridelength(stride),
+ m_lastpos(0, 0, 0)
+ {
+ };
+ virtual ~BL_ActionActuator();
+ virtual bool Update(double curtime,double deltatime);
+ CValue* GetReplica();
+ void ProcessReplica();
+
+ KX_PYMETHOD_DOC(BL_ActionActuator,SetAction);
+ KX_PYMETHOD_DOC(BL_ActionActuator,SetBlendin);
+ KX_PYMETHOD_DOC(BL_ActionActuator,SetPriority);
+ KX_PYMETHOD_DOC(BL_ActionActuator,SetStart);
+ KX_PYMETHOD_DOC(BL_ActionActuator,SetEnd);
+ KX_PYMETHOD_DOC(BL_ActionActuator,SetFrame);
+ KX_PYMETHOD_DOC(BL_ActionActuator,SetProperty);
+ KX_PYMETHOD_DOC(BL_ActionActuator,SetBlendtime);
+ KX_PYMETHOD_DOC(BL_ActionActuator,SetChannel);
+
+ KX_PYMETHOD_DOC(BL_ActionActuator,GetAction);
+ KX_PYMETHOD_DOC(BL_ActionActuator,GetBlendin);
+ KX_PYMETHOD_DOC(BL_ActionActuator,GetPriority);
+ KX_PYMETHOD_DOC(BL_ActionActuator,GetStart);
+ KX_PYMETHOD_DOC(BL_ActionActuator,GetEnd);
+ KX_PYMETHOD_DOC(BL_ActionActuator,GetFrame);
+ KX_PYMETHOD_DOC(BL_ActionActuator,GetProperty);
+// KX_PYMETHOD(BL_ActionActuator,GetChannel);
+
+
+ virtual PyObject* _getattr(char* attr);
+ void SetBlendTime (float newtime);
+
+protected:
+ float m_blendframe;
+ MT_Point3 m_lastpos;
+ int m_flag;
+ float m_starttime;
+ float m_endtime;
+ float m_localtime;
+ float m_lastUpdate;
+ short m_playtype;
+ float m_blendin;
+ short m_priority;
+ float m_stridelength;
+ struct bPose* m_pose;
+ struct bPose* m_blendpose;
+ struct bPose* m_userpose;
+ STR_String m_propname;
+ struct bAction *m_action;
+
+};
+
+enum {
+ ACT_FLAG_REVERSE = 0x00000001,
+ ACT_FLAG_LOCKINPUT = 0x00000002,
+ ACT_FLAG_KEYUP = 0x00000004
+};
+#endif
+
diff --git a/source/gameengine/Converter/BL_ArmatureObject.cpp b/source/gameengine/Converter/BL_ArmatureObject.cpp
new file mode 100644
index 00000000000..1668cd522a3
--- /dev/null
+++ b/source/gameengine/Converter/BL_ArmatureObject.cpp
@@ -0,0 +1,149 @@
+/**
+ * $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 "BL_ArmatureObject.h"
+#include "BL_ActionActuator.h"
+#include "BLI_blenlib.h"
+#include "BKE_action.h"
+#include "BKE_armature.h"
+#include "GEN_Map.h"
+#include "GEN_HashedPtr.h"
+#include "MEM_guardedalloc.h"
+#include "DNA_action_types.h"
+
+CValue* BL_ArmatureObject::GetReplica()
+{
+ BL_ArmatureObject* replica = new BL_ArmatureObject(*this);
+
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ ProcessReplica(replica);
+ return replica;
+}
+
+void BL_ArmatureObject::ProcessReplica(BL_ArmatureObject *replica)
+{
+ KX_GameObject::ProcessReplica(replica);
+
+}
+
+BL_ArmatureObject::~BL_ArmatureObject()
+{
+ if (m_mrdPose){
+ clear_pose(m_mrdPose);
+ MEM_freeN(m_mrdPose);
+ }
+}
+
+void BL_ArmatureObject::ApplyPose()
+{
+ if (m_pose){
+ apply_pose_armature(m_armature, m_pose, 1);
+ if (!m_mrdPose)
+ copy_pose (&m_mrdPose, m_pose, 0);
+ else
+ get_pose_from_pose(&m_mrdPose, m_pose);
+ }
+}
+
+void BL_ArmatureObject::SetPose(bPose *pose)
+{
+ m_pose = pose;
+}
+
+bool BL_ArmatureObject::SetActiveAction(BL_ActionActuator *act, short priority, double curtime)
+{
+ if (curtime != m_lastframe){
+ m_activePriority = 9999;
+ m_lastframe= curtime;
+ m_activeAct = NULL;
+ }
+
+ if (priority<=m_activePriority)
+ {
+ if (m_activeAct && (m_activeAct!=act))
+ m_activeAct->SetBlendTime(0.0); /* Reset the blend timer */
+ m_activeAct = act;
+ m_activePriority = priority;
+ m_lastframe = curtime;
+
+ return true;
+ }
+ else{
+ act->SetBlendTime(0.0);
+ return false;
+ }
+
+}
+
+BL_ActionActuator * BL_ArmatureObject::GetActiveAction()
+{
+ return m_activeAct;
+}
+
+void BL_ArmatureObject::GetPose(bPose **pose)
+{
+ /* If the caller supplies a null pose, create a new one. */
+ /* Otherwise, copy the armature's pose channels into the caller-supplied pose */
+ if (!*pose)
+ copy_pose(pose, m_pose, 0);
+ else
+ get_pose_from_pose(pose, m_pose);
+
+}
+
+void BL_ArmatureObject::GetMRDPose(bPose **pose)
+{
+ /* If the caller supplies a null pose, create a new one. */
+ /* Otherwise, copy the armature's pose channels into the caller-supplied pose */
+
+ if (!m_mrdPose){
+ copy_pose (&m_mrdPose, m_pose, 0);
+ }
+
+ if (!*pose)
+ copy_pose(pose, m_mrdPose, 0);
+ else
+ get_pose_from_pose(pose, m_mrdPose);
+
+}
+
+short BL_ArmatureObject::GetActivePriority()
+{
+ return m_activePriority;
+}
+
+double BL_ArmatureObject::GetLastFrame()
+{
+ return m_lastframe;
+}
diff --git a/source/gameengine/Converter/BL_ArmatureObject.h b/source/gameengine/Converter/BL_ArmatureObject.h
new file mode 100644
index 00000000000..a438eced5d2
--- /dev/null
+++ b/source/gameengine/Converter/BL_ArmatureObject.h
@@ -0,0 +1,79 @@
+/**
+ * $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 BL_ARMATUREOBJECT
+#define BL_ARMATUREOBJECT
+
+#include "KX_GameObject.h"
+
+#include "SG_IObject.h"
+
+class BL_ActionActuator;
+
+class BL_ArmatureObject : public KX_GameObject
+{
+public:
+ double GetLastFrame ();
+ short GetActivePriority();
+ virtual void ProcessReplica(BL_ArmatureObject *replica);
+ class BL_ActionActuator * GetActiveAction();
+ BL_ArmatureObject(void* sgReplicationInfo, SG_Callbacks callbacks,
+ struct bArmature *arm,
+ struct bPose *pose) :
+ KX_GameObject(sgReplicationInfo,callbacks),
+ m_pose(pose),
+ m_mrdPose(NULL),
+ m_armature(arm),
+ m_activeAct(NULL),
+ m_activePriority(999)
+ {}
+
+ virtual CValue* GetReplica();
+ virtual ~BL_ArmatureObject();
+ void GetMRDPose(bPose **pose);
+ void GetPose(struct bPose **pose);
+ void SetPose (struct bPose *pose);
+ void ApplyPose();
+ bool SetActiveAction(class BL_ActionActuator *act, short priority, double curtime);
+ struct bArmature * GetArmature(){return m_armature;};
+
+protected:
+ struct bArmature *m_armature;
+ struct bPose *m_pose;
+ struct bPose *m_mrdPose;
+ double m_lastframe;
+ class BL_ActionActuator *m_activeAct;
+ short m_activePriority;
+};
+
+#endif
+
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
new file mode 100644
index 00000000000..68d45044fff
--- /dev/null
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -0,0 +1,1227 @@
+/**
+ * $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 *****
+ * Convert blender data to ketsji
+ */
+
+#ifdef WIN32
+#pragma warning (disable : 4786)
+#endif
+
+#include "BL_BlenderDataConversion.h"
+#include "KX_BlenderGL.h"
+#include "KX_BlenderScalarInterpolator.h"
+
+#include "RAS_IPolygonMaterial.h"
+
+// Expressions
+#include "ListValue.h"
+#include "IntValue.h"
+// Collision & Fuzzics LTD
+
+#include "PHY_Pro.h"
+
+
+#include "KX_Scene.h"
+#include "KX_GameObject.h"
+#include "RAS_FramingManager.h"
+#include "RAS_MeshObject.h"
+
+#include "KX_ConvertActuators.h"
+#include "KX_ConvertControllers.h"
+#include "KX_ConvertSensors.h"
+
+#include "KX_GameObject.h"
+#include "SCA_LogicManager.h"
+#include "SCA_EventManager.h"
+#include "SCA_TimeEventManager.h"
+#include "KX_Light.h"
+#include "KX_Camera.h"
+#include "KX_EmptyObject.h"
+#include "MT_Point3.h"
+#include "MT_Transform.h"
+#include "SCA_IInputDevice.h"
+#include "RAS_TexMatrix.h"
+#include "RAS_ICanvas.h"
+#include "RAS_MaterialBucket.h"
+//#include "KX_BlenderPolyMaterial.h"
+#include "RAS_Polygon.h"
+#include "RAS_TexVert.h"
+#include "RAS_BucketManager.h"
+#include "RAS_IRenderTools.h"
+
+#include "DNA_action_types.h"
+#include "BKE_main.h"
+#include "BL_SkinMeshObject.h"
+#include "BL_SkinDeformer.h"
+#include "BL_MeshDeformer.h"
+//#include "BL_ArmatureController.h"
+
+#include "BlenderWorldInfo.h"
+
+#include "KX_KetsjiEngine.h"
+#include "KX_BlenderSceneConverter.h"
+
+#include"SND_Scene.h"
+#include "SND_SoundListener.h"
+
+/* This little block needed for linking to Blender... */
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
+/* This list includes only data type definitions */
+#include "DNA_object_types.h"
+#include "DNA_material_types.h"
+#include "DNA_image_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_group_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_camera_types.h"
+#include "DNA_property_types.h"
+#include "DNA_text_types.h"
+#include "DNA_sensor_types.h"
+#include "DNA_controller_types.h"
+#include "DNA_actuator_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_world_types.h"
+#include "DNA_sound_types.h"
+#include "DNA_key_types.h"
+
+
+#include "MEM_guardedalloc.h"
+#include "BKE_utildefines.h"
+#include "BKE_key.h"
+#include "BKE_mesh.h"
+#include "MT_Point3.h"
+
+
+#include "BKE_material.h" /* give_current_material */
+/* end of blender include block */
+
+#include "KX_BlenderInputDevice.h"
+#include "KX_ConvertProperties.h"
+#include "KX_HashedPtr.h"
+
+
+#include "KX_ScalarInterpolator.h"
+
+#include "KX_IpoConvert.h"
+#include "SYS_System.h"
+
+#include "SG_Node.h"
+
+#include "KX_ConvertPhysicsObject.h"
+
+
+// This file defines relationships between parents and children
+// in the game engine.
+
+#include "KX_SG_NodeRelationships.h"
+
+#include "BL_ArmatureObject.h"
+#include "BL_DeformableGameObject.h"
+
+static unsigned int KX_rgbaint2uint_new(unsigned int icol)
+{
+ unsigned int temp=0;
+ unsigned char *cp= (unsigned char *)&temp;
+ unsigned char *src= (unsigned char *)&icol;
+ cp[3]= src[0];//alpha
+ cp[2]= src[1];//blue
+ cp[1]= src[2];//green
+ cp[0]= src[3];//red
+ return temp;
+}
+
+/* Now the real converting starts... */
+static unsigned int KX_Mcol2uint_new(MCol col)
+{
+ /* color has to be converted without endian sensitivity. So no shifting! */
+ unsigned int temp=0;
+ unsigned char *cp= (unsigned char *)&temp;
+ cp[3]=255;
+ cp[2]= col.r;
+ cp[1]= col.g;
+ cp[0]= col.b;
+ return temp;
+}
+
+RAS_MeshObject* BL_ConvertMesh(Mesh* mesh,Object* blenderobj,RAS_IRenderTools* rendertools,KX_Scene* scene,KX_BlenderSceneConverter *converter)
+{
+ RAS_MeshObject *meshobj;
+ bool skinMesh = false;
+
+ int lightlayer = blenderobj->lay;
+
+ // Determine if we need to make a skinned mesh
+ if (mesh->dvert){
+ meshobj = new BL_SkinMeshObject(lightlayer);
+ skinMesh = true;
+ }
+ else {
+ meshobj = new RAS_MeshObject(lightlayer);
+ }
+
+ meshobj->SetName(mesh->id.name);
+
+
+ MFace* mface = static_cast<MFace*>(mesh->mface);
+ TFace* tface = static_cast<TFace*>(mesh->tface);
+
+
+ MCol* mmcol = mesh->mcol;
+
+
+ meshobj->m_xyz_index_to_vertex_index_mapping.resize(mesh->totvert);
+
+ for (int f=0;f<mesh->totface;f++,mface++,tface++)
+ {
+
+ bool collider = true;
+
+ // only add valid polygons
+ if (mface->v3)
+ {
+
+ MT_Vector3 no0(0.0,0.0,0.0),no1(0.0,0.0,0.0),no2(0.0,0.0,0.0),no3(0.0,0.0,0.0);
+ MT_Point3 pt0,pt1,pt2,pt3;
+
+ MT_Point2 uv0(0.0,0.0),uv1(0.0,0.0),uv2(0.0,0.0),uv3(0.0,0.0);
+ // rgb3 is set from the adjoint face in a square
+ unsigned int rgb0,rgb1,rgb2,rgb3 = 0;
+ pt0 = MT_Point3( mesh->mvert[mface->v1].co[0],
+ mesh->mvert[mface->v1].co[1],
+ mesh->mvert[mface->v1].co[2]);
+ no0 = MT_Vector3(
+ mesh->mvert[mface->v1].no[0]/32767.0,
+ mesh->mvert[mface->v1].no[1]/32767.0,
+ mesh->mvert[mface->v1].no[2]/32767.0
+ );
+
+ pt1 = MT_Point3( mesh->mvert[mface->v2].co[0],
+ mesh->mvert[mface->v2].co[1],
+ mesh->mvert[mface->v2].co[2]);
+
+ no1 = MT_Vector3(
+ mesh->mvert[mface->v2].no[0]/32767.0,
+ mesh->mvert[mface->v2].no[1]/32767.0,
+ mesh->mvert[mface->v2].no[2]/32767.0
+ );
+
+ pt2 = MT_Point3( mesh->mvert[mface->v3].co[0],
+ mesh->mvert[mface->v3].co[1],
+ mesh->mvert[mface->v3].co[2]);
+
+ no2 = MT_Vector3(
+ mesh->mvert[mface->v3].no[0]/32767.0,
+ mesh->mvert[mface->v3].no[1]/32767.0,
+ mesh->mvert[mface->v3].no[2]/32767.0
+ );
+
+ if (mface->v4)
+ {
+ pt3 = MT_Point3( mesh->mvert[mface->v4].co[0],
+ mesh->mvert[mface->v4].co[1],
+ mesh->mvert[mface->v4].co[2]);
+ no3 = MT_Vector3(
+ mesh->mvert[mface->v4].no[0]/32767.0,
+ mesh->mvert[mface->v4].no[1]/32767.0,
+ mesh->mvert[mface->v4].no[2]/32767.0
+ );
+ }
+
+
+
+ if((!mface->flag & ME_SMOOTH))
+ {
+ MT_Vector3 norm = ((pt1-pt0).cross(pt2-pt0)).safe_normalized();
+ norm[0] = ((int) (10*norm[0]))/10.0;
+ norm[1] = ((int) (10*norm[1]))/10.0;
+ norm[2] = ((int) (10*norm[2]))/10.0;
+ no0=no1=no2=no3= norm;
+
+ }
+
+ {
+ Image* bima = ((mesh->tface && tface) ? (Image*) tface->tpage : NULL);
+
+ STR_String imastr =
+ ((mesh->tface && tface) ?
+ (bima? (bima)->id.name : "" ) : "" );
+
+ char transp=0;
+ short mode=0, tile=0;
+ int tilexrep=4,tileyrep = 4;
+
+ if (bima)
+ {
+ tilexrep = bima->xrep;
+ tileyrep = bima->yrep;
+
+ }
+
+
+ bool polyvisible = true;
+ if (mesh->tface && tface)
+ {
+ // Use texface colors if available
+ //TF_DYNAMIC means the polygon is a collision face
+ collider = (tface->mode & TF_DYNAMIC != 0);
+ transp = tface->transp;
+ tile = tface->tile;
+ mode = tface->mode;
+
+ polyvisible = !((tface->flag & TF_HIDE)||(tface->mode & TF_INVISIBLE));
+
+ uv0 = MT_Point2(tface->uv[0]);
+ uv1 = MT_Point2(tface->uv[1]);
+ uv2 = MT_Point2(tface->uv[2]);
+ rgb0 = KX_rgbaint2uint_new(tface->col[0]);
+ rgb1 = KX_rgbaint2uint_new(tface->col[1]);
+ rgb2 = KX_rgbaint2uint_new(tface->col[2]);
+
+ if (mface->v4)
+ {
+ uv3 = MT_Point2(tface->uv[3]);
+ rgb3 = KX_rgbaint2uint_new(tface->col[3]);
+ } else {
+ }
+
+
+ } else
+ {
+ //
+ if (mmcol)
+ {
+ // Use vertex colours
+ rgb0 = KX_Mcol2uint_new(mmcol[0]);
+ rgb1 = KX_Mcol2uint_new(mmcol[1]);
+ rgb2 = KX_Mcol2uint_new(mmcol[2]);
+
+
+ if (mface->v4)
+ {
+ rgb3 = KX_Mcol2uint_new(mmcol[3]);
+
+ }
+
+ mmcol += 4;
+ }
+ else{
+ // If there are no vertex colors OR texfaces,
+ // Initialize face to white and set COLLSION true and everything else FALSE
+ rgb0 = KX_rgbaint2uint_new(0xFFFFFFFF);
+ rgb1 = KX_rgbaint2uint_new(0xFFFFFFFF);
+ rgb2 = KX_rgbaint2uint_new(0xFFFFFFFF);
+
+ if (mface->v4)
+ rgb3 = KX_rgbaint2uint_new(0xFFFFFFFF);
+
+ mode = TF_DYNAMIC;
+ transp = TF_SOLID;
+ tile = 0;
+ }
+ }
+
+
+ Material* ma = give_current_material(blenderobj, 1);
+ const char* matnameptr = (ma ? ma->id.name : "");
+
+
+ bool istriangle = (mface->v4==0);
+
+ RAS_IPolyMaterial* polymat = rendertools->CreateBlenderPolyMaterial(imastr,false,matnameptr,tile,tilexrep,tileyrep,mode,transp, lightlayer,istriangle,blenderobj,tface);
+
+ if (ma)
+ {
+ polymat->m_specular = MT_Vector3(ma->spec * ma->specr,ma->spec * ma->specg,ma->spec * ma->specb);
+ polymat->m_shininess = (float)ma->har;
+
+ } else
+ {
+ polymat->m_specular = MT_Vector3(0.0f,0.0f,0.0f);
+ polymat->m_shininess = 35.0;
+ }
+
+
+ // this is needed to free up memory afterwards
+ converter->RegisterPolyMaterial(polymat);
+
+ RAS_MaterialBucket* bucket = scene->FindBucket(polymat);
+
+ int nverts = mface->v4?4:3;
+ int vtxarray = meshobj->FindVertexArray(nverts,polymat);
+ RAS_Polygon* poly = new RAS_Polygon(bucket,polyvisible,nverts,vtxarray);
+ if (skinMesh) {
+ int d1, d2, d3, d4;
+ bool flat;
+
+ /* If the face is set to solid, all fnors are the same */
+ if (mface->flag & ME_SMOOTH)
+ flat = false;
+ else
+ flat = true;
+
+ d1=((BL_SkinMeshObject*)meshobj)->FindOrAddDeform(vtxarray, mface->v1, &mesh->dvert[mface->v1], polymat);
+ d2=((BL_SkinMeshObject*)meshobj)->FindOrAddDeform(vtxarray, mface->v2, &mesh->dvert[mface->v2], polymat);
+ d3=((BL_SkinMeshObject*)meshobj)->FindOrAddDeform(vtxarray, mface->v3, &mesh->dvert[mface->v3], polymat);
+ if (nverts==4)
+ d4=((BL_SkinMeshObject*)meshobj)->FindOrAddDeform(vtxarray, mface->v4, &mesh->dvert[mface->v4], polymat);
+ poly->SetVertex(0,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt0,uv0,rgb0,no0,d1,flat, polymat));
+ poly->SetVertex(1,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt1,uv1,rgb1,no1,d2,flat, polymat));
+ poly->SetVertex(2,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt2,uv2,rgb2,no2,d3,flat, polymat));
+ if (nverts==4)
+ poly->SetVertex(3,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt3,uv3,rgb3,no3,d4, flat,polymat));
+ }
+ else
+ {
+ poly->SetVertex(0,meshobj->FindOrAddVertex(vtxarray,pt0,uv0,rgb0,no0,polymat,mface->v1));
+ poly->SetVertex(1,meshobj->FindOrAddVertex(vtxarray,pt1,uv1,rgb1,no1,polymat,mface->v2));
+ poly->SetVertex(2,meshobj->FindOrAddVertex(vtxarray,pt2,uv2,rgb2,no2,polymat,mface->v3));
+ if (nverts==4)
+ poly->SetVertex(3,meshobj->FindOrAddVertex(vtxarray,pt3,uv3,rgb3,no3,polymat,mface->v4));
+ }
+ meshobj->AddPolygon(poly);
+ if (poly->IsCollider())
+ {
+ RAS_TriangleIndex idx;
+ idx.m_index[0] = mface->v1;
+ idx.m_index[1] = mface->v2;
+ idx.m_index[2] = mface->v3;
+ idx.m_collider = collider;
+ meshobj->m_triangle_indices.push_back(idx);
+ if (nverts==4)
+ {
+ idx.m_index[0] = mface->v1;
+ idx.m_index[1] = mface->v3;
+ idx.m_index[2] = mface->v4;
+ idx.m_collider = collider;
+ meshobj->m_triangle_indices.push_back(idx);
+ }
+ }
+
+ poly->SetVisibleWireframeEdges(mface->edcode);
+ poly->SetCollider(collider);
+ }
+ }
+ }
+ meshobj->UpdateMaterialList();
+
+ return meshobj;
+}
+
+static PHY_MaterialProps g_materialProps = {
+ 1.0, // restitution
+ 2.0, // friction
+ 0.0, // fh spring constant
+ 0.0, // fh damping
+ 0.0, // fh distance
+ false // sliding material?
+};
+
+
+
+static PHY_MaterialProps *CreateMaterialFromBlenderObject(struct Object* blenderobject,
+ KX_Scene *kxscene)
+{
+ PHY_MaterialProps *materialProps = new PHY_MaterialProps;
+
+ assert(materialProps);
+
+ Material* blendermat = give_current_material(blenderobject, 0);
+
+ if (blendermat)
+ {
+ assert(0.0f <= blendermat->reflect && blendermat->reflect <= 1.0f);
+
+ materialProps->m_restitution = blendermat->reflect;
+ materialProps->m_friction = blendermat->friction;
+ materialProps->m_fh_spring = blendermat->fh;
+ materialProps->m_fh_damping = blendermat->xyfrict;
+ materialProps->m_fh_distance = blendermat->fhdist;
+ materialProps->m_fh_normal = (blendermat->dynamode & MA_FH_NOR) != 0;
+ }
+ else {
+ *materialProps = g_materialProps;
+ }
+
+ return materialProps;
+}
+
+static PHY_ShapeProps *CreateShapePropsFromBlenderObject(struct Object* blenderobject,
+ KX_Scene *kxscene)
+{
+ PHY_ShapeProps *shapeProps = new PHY_ShapeProps;
+
+ assert(shapeProps);
+
+ shapeProps->m_mass = blenderobject->mass;
+
+// This needs to be fixed in blender. For now, we use:
+
+// in Blender, inertia stands for the size value which is equivalent to
+// the sphere radius
+ shapeProps->m_inertia = blenderobject->formfactor * blenderobject->mass * blenderobject->inertia * blenderobject->inertia;
+
+ assert(0.0f <= blenderobject->damping && blenderobject->damping <= 1.0f);
+ assert(0.0f <= blenderobject->rdamping && blenderobject->rdamping <= 1.0f);
+
+ shapeProps->m_lin_drag = 1.0 - blenderobject->damping;
+ shapeProps->m_ang_drag = 1.0 - blenderobject->rdamping;
+
+ shapeProps->m_friction_scaling[0] = blenderobject->anisotropicFriction[0];
+ shapeProps->m_friction_scaling[1] = blenderobject->anisotropicFriction[1];
+ shapeProps->m_friction_scaling[2] = blenderobject->anisotropicFriction[2];
+ shapeProps->m_do_anisotropic = ((blenderobject->gameflag & OB_ANISOTROPIC_FRICTION) != 0);
+
+ shapeProps->m_do_fh = (blenderobject->gameflag & OB_DO_FH) != 0;
+ shapeProps->m_do_rot_fh = (blenderobject->gameflag & OB_ROT_FH) != 0;
+
+ return shapeProps;
+}
+
+
+
+
+
+//////////////////////////////////////////////////////////
+
+
+
+
+void my_boundbox_mesh(Mesh *me, float *loc, float *size)
+ {
+ MVert *mvert;
+ BoundBox *bb;
+ float min[3], max[3];
+ float mloc[3], msize[3];
+ int a;
+
+ if(me->bb==0) me->bb= (struct BoundBox *)MEM_callocN(sizeof(BoundBox), "boundbox");
+ bb= me->bb;
+
+ INIT_MINMAX(min, max);
+
+ if (!loc) loc= mloc;
+ if (!size) size= msize;
+
+ mvert= me->mvert;
+ for(a=0; a<me->totvert; a++, mvert++) {
+ DO_MINMAX(mvert->co, min, max);
+ }
+
+ if(me->totvert) {
+ loc[0]= (min[0]+max[0])/2.0;
+ loc[1]= (min[1]+max[1])/2.0;
+ loc[2]= (min[2]+max[2])/2.0;
+
+ size[0]= (max[0]-min[0])/2.0;
+ size[1]= (max[1]-min[1])/2.0;
+ size[2]= (max[2]-min[2])/2.0;
+ }
+ else {
+ loc[0]= loc[1]= loc[2]= 0.0;
+ size[0]= size[1]= size[2]= 0.0;
+ }
+
+ bb->vec[0][0]=bb->vec[1][0]=bb->vec[2][0]=bb->vec[3][0]= loc[0]-size[0];
+ bb->vec[4][0]=bb->vec[5][0]=bb->vec[6][0]=bb->vec[7][0]= loc[0]+size[0];
+
+ bb->vec[0][1]=bb->vec[1][1]=bb->vec[4][1]=bb->vec[5][1]= loc[1]-size[1];
+ bb->vec[2][1]=bb->vec[3][1]=bb->vec[6][1]=bb->vec[7][1]= loc[1]+size[1];
+
+ bb->vec[0][2]=bb->vec[3][2]=bb->vec[4][2]=bb->vec[7][2]= loc[2]-size[2];
+ bb->vec[1][2]=bb->vec[2][2]=bb->vec[5][2]=bb->vec[6][2]= loc[2]+size[2];
+ }
+
+
+
+
+void my_tex_space_mesh(Mesh *me)
+ {
+ KeyBlock *kb;
+ float *fp, loc[3], size[3], min[3], max[3];
+ int a;
+
+ my_boundbox_mesh(me, loc, size);
+
+ if(me->texflag & AUTOSPACE) {
+ if(me->key) {
+ kb= me->key->refkey;
+ if (kb) {
+
+ INIT_MINMAX(min, max);
+
+ fp= (float *)kb->data;
+ for(a=0; a<kb->totelem; a++, fp+=3) {
+ DO_MINMAX(fp, min, max);
+ }
+ if(kb->totelem) {
+ loc[0]= (min[0]+max[0])/2.0; loc[1]= (min[1]+max[1])/2.0; loc[2]= (min[2]+max[2])/2.0;
+ size[0]= (max[0]-min[0])/2.0; size[1]= (max[1]-min[1])/2.0; size[2]= (max[2]-min[2])/2.0;
+ }
+ else {
+ loc[0]= loc[1]= loc[2]= 0.0;
+ size[0]= size[1]= size[2]= 0.0;
+ }
+
+ }
+ }
+
+ VECCOPY(me->loc, loc);
+ VECCOPY(me->size, size);
+ me->rot[0]= me->rot[1]= me->rot[2]= 0.0;
+
+ if(me->size[0]==0.0) me->size[0]= 1.0;
+ else if(me->size[0]>0.0 && me->size[0]<0.00001) me->size[0]= 0.00001;
+ else if(me->size[0]<0.0 && me->size[0]> -0.00001) me->size[0]= -0.00001;
+
+ if(me->size[1]==0.0) me->size[1]= 1.0;
+ else if(me->size[1]>0.0 && me->size[1]<0.00001) me->size[1]= 0.00001;
+ else if(me->size[1]<0.0 && me->size[1]> -0.00001) me->size[1]= -0.00001;
+
+ if(me->size[2]==0.0) me->size[2]= 1.0;
+ else if(me->size[2]>0.0 && me->size[2]<0.00001) me->size[2]= 0.00001;
+ else if(me->size[2]<0.0 && me->size[2]> -0.00001) me->size[2]= -0.00001;
+ }
+
+}
+
+void my_get_local_bounds(Object *ob, float *centre, float *size)
+ {
+ BoundBox *bb= NULL;
+ /* uses boundbox, function used by Ketsji */
+
+ if(ob->type==OB_MESH) {
+ bb= ( (Mesh *)ob->data )->bb;
+ if(bb==0) {
+ my_tex_space_mesh((struct Mesh *)ob->data);
+ bb= ( (Mesh *)ob->data )->bb;
+ }
+ }
+ else if ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT) {
+ centre[0]= centre[1]= centre[2]= 0.0;
+ size[0] = size[1]=size[2]=0.0;
+ }
+ else if(ob->type==OB_MBALL) {
+ bb= ob->bb;
+ }
+ if(bb==NULL) {
+ centre[0]= centre[1]= centre[2]= 0.0;
+ size[0] = size[1]=size[2]=0.0;
+ }
+ else {
+ size[0]= 0.5*fabs(bb->vec[0][0] - bb->vec[4][0]);
+ size[1]= 0.5*fabs(bb->vec[0][1] - bb->vec[2][1]);
+ size[2]= 0.5*fabs(bb->vec[0][2] - bb->vec[1][2]);
+
+ centre[0]= (bb->vec[0][0] + bb->vec[4][0])/2.0;
+ centre[1]= (bb->vec[0][1] + bb->vec[2][1])/2.0;
+ centre[2]= (bb->vec[0][2] + bb->vec[1][2])/2.0;
+ }
+}
+
+
+
+
+//////////////////////////////////////////////////////
+
+
+
+
+
+void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
+ struct Object* blenderobject,
+ RAS_MeshObject* meshobj,
+ KX_Scene* kxscene,
+ int activeLayerBitInfo,
+ e_PhysicsEngine physics_engine,
+ KX_BlenderSceneConverter *converter
+ )
+
+ {
+
+
+ SYS_SystemHandle syshandle = SYS_GetSystem();
+ //int userigidbody = SYS_GetCommandLineInt(syshandle,"norigidbody",0);
+ //bool bRigidBody = (userigidbody == 0);
+
+ PHY_ShapeProps* shapeprops =
+ CreateShapePropsFromBlenderObject(blenderobject,
+ kxscene);
+
+
+ PHY_MaterialProps* smmaterial =
+ CreateMaterialFromBlenderObject(blenderobject, kxscene);
+
+ KX_ObjectProperties objprop;
+ objprop.m_dyna = (blenderobject->gameflag & OB_DYNAMIC) != 0;
+ //mmm, for now, taks this for the size of the dynamicobject
+ // Blender uses inertia for radius of dynamic object
+ objprop.m_radius = blenderobject->inertia;
+ objprop.m_angular_rigidbody = (blenderobject->gameflag & OB_RIGID_BODY) != 0;
+ objprop.m_in_active_layer = (blenderobject->lay & activeLayerBitInfo) != 0;
+ objprop.m_ghost = (blenderobject->gameflag & OB_GHOST) != 0;
+ objprop.m_dynamic_parent=NULL;
+ objprop.m_isdeformable = ((blenderobject->gameflag2 & 2)) != 0;
+ objprop.m_implicitsphere = false;
+ objprop.m_implicitbox = false;
+
+ if (blenderobject->dtx & OB_BOUNDBOX)
+ {
+ objprop.m_implicitsphere = (blenderobject->boundtype == OB_BOUND_SPHERE);
+ objprop.m_implicitbox = (blenderobject->boundtype == OB_BOUND_BOX);
+ }
+
+ // get Root Parent of blenderobject
+ struct Object* parent= blenderobject->parent;
+ while(parent && parent->parent) {
+ parent= parent->parent;
+ }
+
+ if (parent && (parent->gameflag & OB_DYNAMIC)) {
+
+ KX_GameObject *parentgameobject = converter->FindGameObject(parent);
+ objprop.m_dynamic_parent = parentgameobject;
+
+ }
+
+ objprop.m_isactor = (blenderobject->gameflag & OB_ACTOR)!=0;
+ objprop.m_concave = (blenderobject->boundtype & 4) != 0;
+
+
+ my_get_local_bounds(blenderobject,objprop.m_boundingbox.m_center,objprop.m_boundingbox.m_extends);
+ //mmm, has to be divided by 2 to be proper extends
+ objprop.m_boundingbox.m_extends[0]*=2.f;
+ objprop.m_boundingbox.m_extends[1]*=2.f;
+ objprop.m_boundingbox.m_extends[2]*=2.f;
+
+ switch (physics_engine)
+ {
+ case UseSumo:
+ {
+
+#ifdef USE_SUMO_SOLID
+ KX_ConvertSumoObject( gameobj,meshobj,kxscene,shapeprops, smmaterial, &objprop);
+#endif
+ break;
+ }
+ case UseODE:
+ {
+
+#ifdef USE_ODE
+ KX_ConvertODEEngineObject(gameobj,meshobj,kxscene,shapeprops, smmaterial, &objprop);
+#endif //USE_ODE
+
+
+ break;
+ }
+ case UseDynamo:
+ {
+ //KX_ConvertDynamoObject(gameobj,meshobj,kxscene,shapeprops, smmaterial, &objprop);
+ break;
+ }
+ case UseNone:
+ default:
+ {
+ }
+
+}
+
+}
+
+
+
+
+
+static KX_LightObject *gamelight_from_blamp(Lamp *la, unsigned int layerflag, KX_Scene *kxscene, RAS_IRenderTools *rendertools, KX_BlenderSceneConverter *converter) {
+ RAS_LightObject lightobj;
+ KX_LightObject *gamelight;
+
+ lightobj.m_att1 = la->att1;
+ lightobj.m_red = la->r;
+ lightobj.m_green = la->g;
+ lightobj.m_blue = la->b;
+ lightobj.m_distance = la->dist;
+ lightobj.m_energy = la->energy;
+ lightobj.m_layer = layerflag;
+ lightobj.m_spotblend = la->spotblend;
+ lightobj.m_spotsize = la->spotsize;
+
+ if (la->type==LA_SUN) {
+ lightobj.m_type = RAS_LightObject::LIGHT_SUN;
+ } else if (la->type==LA_SPOT) {
+ lightobj.m_type = RAS_LightObject::LIGHT_SPOT;
+ } else {
+ lightobj.m_type = RAS_LightObject::LIGHT_NORMAL;
+ }
+
+ gamelight = new KX_LightObject(kxscene, KX_Scene::m_callbacks, rendertools, lightobj);
+ BL_ConvertLampIpos(la, gamelight, converter);
+
+ return gamelight;
+}
+
+static KX_Camera *gamecamera_from_bcamera(Camera *ca, KX_Scene *kxscene, KX_BlenderSceneConverter *converter) {
+ RAS_CameraData camdata;
+ KX_Camera *gamecamera;
+
+ camdata.m_lens= ca->lens;
+ camdata.m_clipend= ca->clipend;
+ camdata.m_clipstart= ca->clipsta;
+
+ gamecamera= new KX_Camera(kxscene, KX_Scene::m_callbacks, camdata);
+ gamecamera->SetName(ca->id.name + 2);
+
+ BL_ConvertCameraIpos(ca, gamecamera, converter);
+
+ return gamecamera;
+}
+
+static KX_GameObject *gameobject_from_blenderobject(
+ Object *ob,
+ KX_Scene *kxscene,
+ RAS_IRenderTools *rendertools,
+ KX_BlenderSceneConverter *converter,
+ Scene *blenderscene)
+{
+ KX_GameObject *gameobj = NULL;
+
+ switch(ob->type)
+ {
+ case OB_LAMP:
+ {
+ KX_LightObject* gamelight= gamelight_from_blamp(static_cast<Lamp*>(ob->data), ob->lay, kxscene, rendertools, converter);
+ gameobj = gamelight;
+
+ gamelight->AddRef();
+ kxscene->GetLightList()->Add(gamelight);
+
+ break;
+ }
+
+ case OB_CAMERA:
+ {
+ KX_Camera* gamecamera = gamecamera_from_bcamera(static_cast<Camera*>(ob->data), kxscene, converter);
+ gameobj = gamecamera;
+
+ gamecamera->AddRef();
+ kxscene->AddCamera(gamecamera);
+
+ break;
+ }
+
+ case OB_MESH:
+ {
+ Mesh* mesh = static_cast<Mesh*>(ob->data);
+ RAS_MeshObject* meshobj = converter->FindGameMesh(mesh, ob->lay);
+
+ if (!meshobj) {
+ meshobj = BL_ConvertMesh(mesh,ob,rendertools,kxscene,converter);
+ converter->RegisterGameMesh(meshobj, mesh);
+ }
+
+ // needed for python scripting
+ kxscene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj);
+
+ gameobj = new BL_DeformableGameObject(kxscene,KX_Scene::m_callbacks);
+
+ // set transformation
+ gameobj->AddMesh(meshobj);
+
+ // for all objects: check whether they want to
+ // respond to updates
+ bool ignoreActivityCulling =
+ ((ob->gameflag2 & OB_NEVER_DO_ACTIVITY_CULLING)!=0);
+ gameobj->SetIgnoreActivityCulling(ignoreActivityCulling);
+
+ // If this is a skin object, make Skin Controller
+ if (ob->parent && ob->parent->type == OB_ARMATURE && ob->partype==PARSKEL && ((Mesh*)ob->data)->dvert){
+ BL_SkinDeformer *dcont = new BL_SkinDeformer(ob, (BL_SkinMeshObject*)meshobj);
+ ((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont;
+ }
+ else if (((Mesh*)ob->data)->dvert){
+ BL_MeshDeformer *dcont = new BL_MeshDeformer(ob, (BL_SkinMeshObject*)meshobj);
+ ((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont;
+ }
+
+ break;
+ }
+
+ case OB_ARMATURE:
+ {
+ gameobj = new BL_ArmatureObject (kxscene, KX_Scene::m_callbacks,
+ (bArmature*)ob->data,
+ ob->pose);
+
+ /* Get the current pose from the armature object and apply it as the rest pose */
+ break;
+ }
+
+ case OB_EMPTY:
+ {
+ gameobj = new KX_EmptyObject(kxscene,KX_Scene::m_callbacks);
+ // set transformation
+ break;
+ }
+ }
+
+ return gameobj;
+}
+
+struct parentChildLink {
+ struct Object* m_blenderchild;
+ SG_Node* m_gamechildnode;
+};
+
+ /**
+ * Find the specified scene by name, or the first
+ * scene if nothing matches (shouldn't happen).
+ */
+static struct Scene *GetSceneForName(struct Main *maggie, const STR_String& scenename) {
+ Scene *sce;
+
+ for (sce= (Scene*) maggie->scene.first; sce; sce= (Scene*) sce->id.next)
+ if (scenename == (sce->id.name+2))
+ return sce;
+
+ return (Scene*) maggie->scene.first;
+}
+
+// convert blender objects into ketsji gameobjects
+void BL_ConvertBlenderObjects(struct Main* maggie,
+ const STR_String& scenename,
+ KX_Scene* kxscene,
+ KX_KetsjiEngine* ketsjiEngine,
+ e_PhysicsEngine physics_engine,
+ PyObject* pythondictionary,
+ SCA_IInputDevice* keydev,
+ RAS_IRenderTools* rendertools,
+ RAS_ICanvas* canvas,
+ KX_BlenderSceneConverter* converter,
+ bool alwaysUseExpandFraming
+ )
+{
+ Scene *blenderscene = GetSceneForName(maggie, scenename);
+
+ // Get the frame settings of the canvas.
+ // Get the aspect ratio of the canvas as designed by the user.
+
+ RAS_FrameSettings::RAS_FrameType frame_type;
+ int aspect_width;
+ int aspect_height;
+
+ if (alwaysUseExpandFraming) {
+ frame_type = RAS_FrameSettings::e_frame_extend;
+ aspect_width = canvas->GetWidth();
+ aspect_height = canvas->GetHeight();
+ } else {
+ if (blenderscene->framing.type == SCE_GAMEFRAMING_BARS) {
+ frame_type = RAS_FrameSettings::e_frame_bars;
+ } else if (blenderscene->framing.type == SCE_GAMEFRAMING_EXTEND) {
+ frame_type = RAS_FrameSettings::e_frame_extend;
+ } else {
+ frame_type = RAS_FrameSettings::e_frame_scale;
+ }
+
+ aspect_width = blenderscene->r.xsch;
+ aspect_height = blenderscene->r.ysch;
+ }
+
+ RAS_FrameSettings frame_settings(
+ frame_type,
+ blenderscene->framing.col[0],
+ blenderscene->framing.col[1],
+ blenderscene->framing.col[2],
+ aspect_width,
+ aspect_height
+ );
+ kxscene->SetFramingType(frame_settings);
+
+ kxscene->SetGravity(MT_Vector3(0,0,(blenderscene->world != NULL) ? -blenderscene->world->gravity : -9.8));
+
+ /* set activity culling parameters */
+ if (blenderscene->world) {
+ kxscene->SetActivityCulling( (blenderscene->world->mode & WO_ACTIVITY_CULLING) != 0);
+ kxscene->SetActivityCullingRadius(blenderscene->world->activityBoxRadius);
+ } else {
+ kxscene->SetActivityCulling(false);
+ }
+
+ int activeLayerBitInfo = blenderscene->lay;
+
+ // templist to find Root Parents (object with no parents)
+ CListValue* templist = new CListValue();
+ CListValue* sumolist = new CListValue();
+
+ vector<parentChildLink> vec_parent_child;
+
+ CListValue* objectlist = kxscene->GetObjectList();
+ CListValue* parentlist = kxscene->GetRootParentList();
+
+ SCA_LogicManager* logicmgr = kxscene->GetLogicManager();
+ SCA_TimeEventManager* timemgr = kxscene->GetTimeEventManager();
+
+ CListValue* logicbrick_conversionlist = new CListValue();
+
+ // Convert actions to actionmap
+ bAction *curAct;
+ for (curAct = (bAction*)maggie->action.first; curAct; curAct=(bAction*)curAct->id.next)
+ {
+ logicmgr->RegisterActionName(curAct->id.name, curAct);
+ }
+
+ Base *base = static_cast<Base*>(blenderscene->base.first);
+ while(base)
+ {
+ Object* blenderobject = base->object;
+ KX_GameObject* gameobj = gameobject_from_blenderobject(
+ base->object,
+ kxscene,
+ rendertools,
+ converter,
+ blenderscene);
+
+ if (gameobj)
+ {
+ MT_Point3 pos = MT_Point3(
+ blenderobject->loc[0]+blenderobject->dloc[0],
+ blenderobject->loc[1]+blenderobject->dloc[1],
+ blenderobject->loc[2]+blenderobject->dloc[2]
+ );
+ MT_Vector3 eulxyz = MT_Vector3(
+ blenderobject->rot[0],
+ blenderobject->rot[1],
+ blenderobject->rot[2]
+ );
+ MT_Vector3 scale = MT_Vector3(
+ blenderobject->size[0],
+ blenderobject->size[1],
+ blenderobject->size[2]
+ );
+
+ gameobj->NodeSetLocalPosition(pos);
+ gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz));
+ gameobj->NodeSetLocalScale(scale);
+ gameobj->NodeUpdateGS(0,true);
+
+ BL_ConvertIpos(blenderobject,gameobj,converter);
+
+ bool isInActiveLayer = (blenderobject->lay & activeLayerBitInfo) !=0;
+
+ sumolist->Add(gameobj->AddRef());
+
+ BL_ConvertProperties(blenderobject,gameobj,timemgr,kxscene,isInActiveLayer);
+
+
+ gameobj->SetName(blenderobject->id.name);
+
+ // templist to find Root Parents (object with no parents)
+ templist->Add(gameobj->AddRef());
+
+ // update children/parent hierarchy
+ if (blenderobject->parent != 0)
+ {
+ // blender has an additional 'parentinverse' offset in each object
+ SG_Node* parentinversenode = new SG_Node(NULL,NULL,SG_Callbacks());
+
+ // define a normal parent relationship for this node.
+ KX_NormalParentRelation * parent_relation = KX_NormalParentRelation::New();
+ parentinversenode->SetParentRelation(parent_relation);
+
+ parentChildLink pclink;
+ pclink.m_blenderchild = blenderobject;
+ pclink.m_gamechildnode = parentinversenode;
+ vec_parent_child.push_back(pclink);
+
+ float* fl = (float*) blenderobject->parentinv;
+ MT_Transform parinvtrans(fl);
+ parentinversenode->SetLocalPosition(parinvtrans.getOrigin());
+ parentinversenode->SetLocalOrientation(parinvtrans.getBasis());
+ parentinversenode->AddChild(gameobj->GetSGNode());
+ }
+
+ // needed for python scripting
+ logicmgr->RegisterGameObjectName(gameobj->GetName(),gameobj);
+
+ converter->RegisterGameObject(gameobj, blenderobject);
+
+ // this was put in rapidly, needs to be looked at more closely
+ // only draw/use objects in active 'blender' layers
+
+ logicbrick_conversionlist->Add(gameobj->AddRef());
+
+ if (isInActiveLayer)
+ {
+ objectlist->Add(gameobj->AddRef());
+
+ gameobj->NodeUpdateGS(0,true);
+ gameobj->Bucketize();
+
+ }
+ }
+
+ base = base->next;
+ }
+
+ if (blenderscene->camera) {
+ KX_Camera *gamecamera= (KX_Camera*) converter->FindGameObject(blenderscene->camera);
+
+ kxscene->SetActiveCamera(gamecamera);
+ }
+
+ // Set up armatures
+ for (base = static_cast<Base*>(blenderscene->base.first); base; base=base->next){
+ if (base->object->type==OB_MESH){
+ Mesh *me = (Mesh*)base->object->data;
+
+ if (me->dvert){
+ KX_GameObject *obj = converter->FindGameObject(base->object);
+
+ if (base->object->parent && base->object->parent->type==OB_ARMATURE && base->object->partype==PARSKEL){
+ KX_GameObject *par = converter->FindGameObject(base->object->parent);
+ if (par)
+ ((BL_SkinDeformer*)(((BL_DeformableGameObject*)obj)->m_pDeformer))->SetArmature((BL_ArmatureObject*) par);
+ }
+ }
+ }
+ }
+
+ // create hierarchy information
+ int i;
+ vector<parentChildLink>::iterator pcit;
+
+ for (pcit = vec_parent_child.begin();!(pcit==vec_parent_child.end());++pcit)
+ {
+
+ struct Object* blenderchild = pcit->m_blenderchild;
+ if (blenderchild->partype == PARVERT1)
+ {
+ // creat a new vertex parent relationship for this node.
+ KX_VertexParentRelation * vertex_parent_relation = KX_VertexParentRelation::New();
+ pcit->m_gamechildnode->SetParentRelation(vertex_parent_relation);
+ } else
+ if (blenderchild->partype == PARSLOW)
+ {
+ // creat a new slow parent relationship for this node.
+ KX_SlowParentRelation * slow_parent_relation = KX_SlowParentRelation::New(blenderchild->sf);
+ pcit->m_gamechildnode->SetParentRelation(slow_parent_relation);
+ }
+
+ struct Object* blenderparent = blenderchild->parent;
+ KX_GameObject* parentobj = converter->FindGameObject(blenderparent);
+ if (parentobj)
+ {
+ parentobj-> GetSGNode()->AddChild(pcit->m_gamechildnode);
+ }
+ }
+ vec_parent_child.clear();
+
+ // find 'root' parents (object that has not parents in SceneGraph)
+ for (i=0;i<templist->GetCount();++i)
+ {
+ KX_GameObject* gameobj = (KX_GameObject*) templist->GetValue(i);
+ if (gameobj->GetSGNode()->GetSGParent() == 0)
+ {
+ parentlist->Add(gameobj->AddRef());
+ gameobj->NodeUpdateGS(0,true);
+ }
+ }
+
+ // create physics information
+ for (i=0;i<sumolist->GetCount();i++)
+ {
+ KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
+ struct Object* blenderobject = converter->FindBlenderObject(gameobj);
+ int nummeshes = gameobj->GetMeshCount();
+ RAS_MeshObject* meshobj = 0;
+
+ if (nummeshes > 0)
+ {
+ meshobj = gameobj->GetMesh(0);
+ }
+
+ BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,activeLayerBitInfo,physics_engine,converter);
+
+ }
+
+ templist->Release();
+ sumolist->Release();
+
+
+ int executePriority=0; /* incremented by converter routines */
+
+ // convert global sound stuff
+
+ /* XXX, glob is the very very wrong place for this
+ * to be, re-enable once the listener has been moved into
+ * the scene. */
+#if 0
+ SND_Scene* soundscene = kxscene->GetSoundScene();
+ SND_SoundListener* listener = soundscene->GetListener();
+ if (listener && glob->listener)
+ {
+ listener->SetDopplerFactor(glob->listener->dopplerfactor);
+ listener->SetDopplerVelocity(glob->listener->dopplervelocity);
+ listener->SetGain(glob->listener->gain);
+ }
+#endif
+
+ // convert world
+ KX_WorldInfo* worldinfo = new BlenderWorldInfo(blenderscene->world);
+ converter->RegisterWorldInfo(worldinfo);
+ kxscene->SetWorldInfo(worldinfo);
+
+ // convert logic bricks, sensors, controllers and actuators
+ for (i=0;i<logicbrick_conversionlist->GetCount();i++)
+ {
+ KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i));
+ struct Object* blenderobj = converter->FindBlenderObject(gameobj);
+ bool isInActiveLayer = (blenderobj->lay & activeLayerBitInfo)!=0;
+ BL_ConvertActuators(maggie->name, blenderobj,gameobj,logicmgr,kxscene,ketsjiEngine,executePriority, activeLayerBitInfo,isInActiveLayer,rendertools,converter);
+ }
+ for ( i=0;i<logicbrick_conversionlist->GetCount();i++)
+ {
+ KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i));
+ struct Object* blenderobj = converter->FindBlenderObject(gameobj);
+ bool isInActiveLayer = (blenderobj->lay & activeLayerBitInfo)!=0;
+ BL_ConvertControllers(blenderobj,gameobj,logicmgr,pythondictionary,executePriority,activeLayerBitInfo,isInActiveLayer,converter);
+ }
+ for ( i=0;i<logicbrick_conversionlist->GetCount();i++)
+ {
+ KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i));
+ struct Object* blenderobj = converter->FindBlenderObject(gameobj);
+ bool isInActiveLayer = (blenderobj->lay & activeLayerBitInfo)!=0;
+ BL_ConvertSensors(blenderobj,gameobj,logicmgr,kxscene,keydev,executePriority,activeLayerBitInfo,isInActiveLayer,canvas,converter);
+ }
+ logicbrick_conversionlist->Release();
+}
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.h b/source/gameengine/Converter/BL_BlenderDataConversion.h
new file mode 100644
index 00000000000..1ed6a866269
--- /dev/null
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.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 __BLENDER_CONVERT
+#define __BLENDER_CONVERT
+
+#include "STR_String.h"
+#include "KX_Python.h"
+#include "KX_PhysicsEngineEnums.h"
+
+class RAS_MeshObject* BL_ConvertMesh(struct Mesh* mesh,struct Object* lightobj,class RAS_IRenderTools* rendertools,class KX_Scene* scene, class KX_BlenderSceneConverter *converter);
+
+void BL_ConvertBlenderObjects(struct Main* maggie,
+ const STR_String& scenename,
+ class KX_Scene* kxscene,
+ class KX_KetsjiEngine* ketsjiEngine,
+ e_PhysicsEngine physics_engine,
+ PyObject* pythondictionary,
+ class SCA_IInputDevice* keydev,
+ class RAS_IRenderTools* rendertools,
+ class RAS_ICanvas* canvas,
+ class KX_BlenderSceneConverter* sceneconverter,
+ bool alwaysUseExpandFraming
+ );
+
+#endif // __BLENDER_CONVERT
diff --git a/source/gameengine/Converter/BL_DeformableGameObject.cpp b/source/gameengine/Converter/BL_DeformableGameObject.cpp
new file mode 100644
index 00000000000..d6830380b00
--- /dev/null
+++ b/source/gameengine/Converter/BL_DeformableGameObject.cpp
@@ -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 *****
+ */
+
+#include "BL_DeformableGameObject.h"
+
+BL_DeformableGameObject::~BL_DeformableGameObject()
+{
+ if (m_pDeformer)
+ delete m_pDeformer; // __NLA : Temporary until we decide where to put this
+}
+
+void BL_DeformableGameObject::ProcessReplica(KX_GameObject* replica)
+{
+ KX_GameObject::ProcessReplica(replica);
+
+ if (m_pDeformer){
+ ((BL_DeformableGameObject*)replica)->m_pDeformer = m_pDeformer->GetReplica();
+ }
+
+}
+
+CValue* BL_DeformableGameObject::GetReplica()
+{
+
+ BL_DeformableGameObject* replica = new BL_DeformableGameObject(*this);//m_float,GetName());
+
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ ProcessReplica(replica);
+ return replica;
+
+}
diff --git a/source/gameengine/Converter/BL_DeformableGameObject.h b/source/gameengine/Converter/BL_DeformableGameObject.h
new file mode 100644
index 00000000000..1f05d2fcbcc
--- /dev/null
+++ b/source/gameengine/Converter/BL_DeformableGameObject.h
@@ -0,0 +1,66 @@
+/**
+ * $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 BL_DEFORMABLEGAMEOBJECT
+#define BL_DEFORMABLEGAMEOBJECT
+
+#ifdef WIN32
+#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
+#endif //WIN32
+
+#include "KX_GameObject.h"
+#include "RAS_Deformer.h"
+
+class BL_DeformableGameObject : public KX_GameObject
+{
+public:
+
+ RAS_Deformer *m_pDeformer;
+ CValue* GetReplica();
+ virtual void Relink(GEN_Map<GEN_HashedPtr, void*>*map)
+ {
+ if (m_pDeformer)
+ m_pDeformer->Relink (map);
+ };
+ void ProcessReplica(KX_GameObject* replica);
+
+ BL_DeformableGameObject(void* sgReplicationInfo, SG_Callbacks callbacks) :
+ KX_GameObject(sgReplicationInfo,callbacks),
+ m_pDeformer(NULL)
+{
+ };
+ virtual ~BL_DeformableGameObject();
+
+};
+
+#endif
+
diff --git a/source/gameengine/Converter/BL_MeshDeformer.cpp b/source/gameengine/Converter/BL_MeshDeformer.cpp
new file mode 100644
index 00000000000..3aa4287478d
--- /dev/null
+++ b/source/gameengine/Converter/BL_MeshDeformer.cpp
@@ -0,0 +1,165 @@
+/**
+ * $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 *****
+ * Simple deformation controller that restores a mesh to its rest position
+ */
+
+#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 "RAS_IPolygonMaterial.h"
+#include "BL_MeshDeformer.h"
+#include "BL_SkinMeshObject.h"
+#include "DNA_mesh_types.h"
+#include "BLI_arithb.h"
+
+#include "GEN_Map.h"
+#include "STR_HashedString.h"
+
+
+bool BL_MeshDeformer::Apply(RAS_IPolyMaterial *mat)
+{
+ int i, j, index;
+ vecVertexArray array;
+ vecIndexArrays mvarray;
+ vecIndexArrays diarray;
+ float co[3];
+
+ RAS_TexVert *tv;
+ MVert *mvert;
+
+ // For each material
+ array = m_pMeshObject->GetVertexCache(mat);
+ mvarray = m_pMeshObject->GetMVertCache(mat);
+ diarray = m_pMeshObject->GetDIndexCache(mat);
+
+ // For each array
+ for (i=0; i<array.size(); i++){
+ // For each vertex
+ for (j=0; j<array[i]->size(); j++){
+ tv = &((*array[i])[j]);
+ MT_Point3 pt = tv->xyz();
+
+ index = ((*diarray[i])[j]);
+
+ mvert = &(m_bmesh->mvert[((*mvarray[i])[index])]);
+ // Do the nasty (in this case, copy the untransformed data from the blender mesh)
+ co[0]=mvert->co[0];
+ co[1]=mvert->co[1];
+ co[2]=mvert->co[2];
+
+ pt[0] = co[0];
+ pt[1] = co[1];
+ pt[2] = co[2];
+
+ tv->SetXYZ(pt);
+ }
+ }
+ return true;
+}
+
+BL_MeshDeformer::~BL_MeshDeformer()
+{
+ if (m_transverts)
+ delete []m_transverts;
+ if (m_transnors)
+ delete []m_transnors;
+};
+
+void BL_MeshDeformer::RecalcNormals()
+{
+ int v, f;
+ float fnor[3], co1[3], co2[3], co3[3], co4[3];
+
+ /* Clear all vertex normal accumulators */
+ for (v =0; v<m_bmesh->totvert; v++){
+ m_transnors[v]=MT_Point3(0,0,0);
+ }
+
+ /* Find the face normals */
+ for (f = 0; f<m_bmesh->totface; f++){
+ // Make new face normal based on the transverts
+ MFace *mf= &((MFace*)m_bmesh->mface)[f];
+
+ if (mf->v3) {
+ for (int vl=0; vl<3; vl++){
+ co1[vl]=m_transverts[mf->v1][vl];
+ co2[vl]=m_transverts[mf->v2][vl];
+ co3[vl]=m_transverts[mf->v3][vl];
+ if (mf->v4)
+ co4[vl]=m_transverts[mf->v4][vl];
+ }
+
+ /* FIXME: Use moto */
+ if (mf->v4)
+ CalcNormFloat4(co1, co2, co3, co4, fnor);
+ else
+ CalcNormFloat(co1, co2, co3, fnor);
+
+ /* Decide which normals are affected by this face's normal */
+ m_transnors[mf->v1]+=MT_Point3(fnor);
+ m_transnors[mf->v2]+=MT_Point3(fnor);
+ m_transnors[mf->v3]+=MT_Point3(fnor);
+ if (mf->v4)
+ m_transnors[mf->v4]+=MT_Point3(fnor);
+
+ }
+
+ }
+
+ for (v =0; v<m_bmesh->totvert; v++){
+ float nor[3];
+
+ m_transnors[v]=m_transnors[v].safe_normalized();
+ nor[0]=m_transnors[v][0];
+ nor[1]=m_transnors[v][1];
+ nor[2]=m_transnors[v][2];
+
+ };
+}
+
+void BL_MeshDeformer::VerifyStorage()
+{
+ /* Ensure that we have the right number of verts assigned */
+ if (m_tvtot!=m_bmesh->totvert+m_bmesh->totface){
+ if (m_transverts)
+ delete []m_transverts;
+ if (m_transnors)
+ delete []m_transnors;
+
+ m_transnors =new MT_Point3[m_bmesh->totvert+m_bmesh->totface];
+ m_transverts=new MT_Point3[m_bmesh->totvert];
+ m_tvtot = m_bmesh->totvert;
+ }
+}
+ \ No newline at end of file
diff --git a/source/gameengine/Converter/BL_MeshDeformer.h b/source/gameengine/Converter/BL_MeshDeformer.h
new file mode 100644
index 00000000000..9880725a2d0
--- /dev/null
+++ b/source/gameengine/Converter/BL_MeshDeformer.h
@@ -0,0 +1,72 @@
+/**
+ * $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 BL_MESHDEFORMER
+#define BL_MESHDEFORMER
+
+#include "RAS_Deformer.h"
+#include "DNA_object_types.h"
+#include "MT_Point3.h"
+#include <stdlib.h>
+
+#ifdef WIN32
+#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
+#endif //WIN32
+
+class BL_MeshDeformer : public RAS_Deformer
+{
+public:
+ void VerifyStorage();
+ void RecalcNormals();
+ virtual void Relink(GEN_Map<class GEN_HashedPtr, void*>*map){};
+ BL_MeshDeformer(struct Object* obj, class BL_SkinMeshObject *meshobj):
+ m_transverts(NULL),
+ m_tvtot(0),
+ m_transnors(NULL),
+ m_pMeshObject(meshobj),
+ m_bmesh((struct Mesh*)(obj->data)){};
+ virtual ~BL_MeshDeformer();
+ virtual void SetSimulatedTime(double time){};
+ virtual bool Apply(class RAS_IPolyMaterial *mat);
+ virtual void Update(void){};
+ virtual RAS_Deformer* GetReplica(){return NULL;};
+ // virtual void InitDeform(double time){};
+protected:
+ class BL_SkinMeshObject *m_pMeshObject;
+ struct Mesh *m_bmesh;
+ MT_Point3 *m_transnors;
+ MT_Point3 *m_transverts;
+ int m_tvtot;
+
+};
+
+#endif
diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp
new file mode 100644
index 00000000000..4eb2b849c3c
--- /dev/null
+++ b/source/gameengine/Converter/BL_SkinDeformer.cpp
@@ -0,0 +1,187 @@
+/**
+ * $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
+#pragma warning (disable : 4786)
+#endif //WIN32
+
+#include "GEN_Map.h"
+#include "STR_HashedString.h"
+#include "RAS_IPolygonMaterial.h"
+#include "BL_SkinMeshObject.h"
+
+//#include "BL_ArmatureController.h"
+#include "BL_SkinDeformer.h"
+#include "DNA_armature_types.h"
+#include "DNA_action_types.h"
+#include "DNA_mesh_types.h"
+#include "BKE_armature.h"
+#include "BKE_action.h"
+#include "MT_Point3.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+
+#define __NLA_DEFNORMALS
+//#undef __NLA_DEFNORMALS
+
+BL_SkinDeformer::~BL_SkinDeformer()
+{
+};
+
+bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *mat)
+{
+ int i, j, index;
+ vecVertexArray array;
+#ifdef __NLA_OLDDEFORM
+ vecMVertArray mvarray;
+#else
+ vecIndexArrays mvarray;
+#endif
+ vecMDVertArray dvarray;
+ vecIndexArrays diarray;
+
+ RAS_TexVert *tv;
+#ifdef __NLA_OLDDEFORM
+ MVert *mvert;
+ MDeformVert *dvert;
+#endif
+ MT_Point3 pt;
+// float co[3];
+
+ if (!m_armobj)
+ return false;
+
+ Update();
+
+ array = m_pMeshObject->GetVertexCache(mat);
+#ifdef __NLA_OLDDEFORM
+ dvarray = m_pMeshObject->GetDVertCache(mat);
+#endif
+ mvarray = m_pMeshObject->GetMVertCache(mat);
+ diarray = m_pMeshObject->GetDIndexCache(mat);
+
+
+ // For each array
+ for (i=0; i<array.size(); i++){
+ // For each vertex
+ for (j=0; j<array[i]->size(); j++){
+
+ tv = &((*array[i])[j]);
+
+ index = ((*diarray[i])[j]);
+#ifdef __NLA_OLDDEFORM
+ pt = tv->xyz();
+ mvert = ((*mvarray[i])[index]);
+ dvert = ((*dvarray[i])[index]);
+#endif
+
+ // Copy the untransformed data from the original mvert
+#ifdef __NLA_OLDDEFORM
+ co[0]=mvert->co[0];
+ co[1]=mvert->co[1];
+ co[2]=mvert->co[2];
+
+ // Do the deformation
+ GB_calc_armature_deform(co, dvert);
+ tv->SetXYZ(co);
+#else
+ // Set the data
+ tv->SetXYZ(m_transverts[((*mvarray[i])[index])]);
+#ifdef __NLA_DEFNORMALS
+
+ tv->SetNormal(m_transnors[((*mvarray[i])[index])]);
+#endif
+#endif
+ }
+ }
+
+ return true;
+}
+
+RAS_Deformer *BL_SkinDeformer::GetReplica()
+{
+ BL_SkinDeformer *result;
+
+ result = new BL_SkinDeformer(*this);
+ result->ProcessReplica();
+ return result;
+}
+
+void BL_SkinDeformer::ProcessReplica()
+{
+}
+
+void BL_SkinDeformer::Update(void)
+{
+
+ /* See if the armature has been updated for this frame */
+ if (m_lastUpdate!=m_armobj->GetLastFrame()){
+
+ /* Do all of the posing necessary */
+ GB_init_armature_deform (m_defbase, m_premat, m_postmat);
+ m_armobj->ApplyPose();
+ precalc_armature_posemats (m_armobj->GetArmature());
+ for (Bone *curBone=(Bone*)m_armobj->GetArmature()->bonebase.first; curBone; curBone=(Bone*)curBone->next)
+ precalc_bone_defmat(curBone);
+
+ VerifyStorage();
+
+ /* Transform the verts & store locally */
+ for (int v =0; v<m_bmesh->totvert; v++){
+ float co[3];
+
+ co[0]=m_bmesh->mvert[v].co[0];
+ co[1]=m_bmesh->mvert[v].co[1];
+ co[2]=m_bmesh->mvert[v].co[2];
+ GB_calc_armature_deform(co, &m_bmesh->dvert[v]);
+
+ m_transverts[v]=MT_Point3(co);
+ }
+
+ RecalcNormals();
+
+
+ /* Update the current frame */
+ m_lastUpdate=m_armobj->GetLastFrame();
+ }
+}
+
+void BL_SkinDeformer::SetArmature(BL_ArmatureObject *armobj)
+{
+ m_armobj = armobj;
+
+ for (bDeformGroup *dg=(bDeformGroup*)m_defbase->first; dg; dg=(bDeformGroup*)dg->next)
+ dg->data = (void*)get_named_bone(m_armobj->GetArmature(), dg->name);
+
+ GB_validate_defgroups(m_bmesh, m_defbase);
+}
diff --git a/source/gameengine/Converter/BL_SkinDeformer.h b/source/gameengine/Converter/BL_SkinDeformer.h
new file mode 100644
index 00000000000..25c3654d269
--- /dev/null
+++ b/source/gameengine/Converter/BL_SkinDeformer.h
@@ -0,0 +1,98 @@
+/**
+ * $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 BL_SKINDEFORMER
+#define BL_SKINDEFORMER
+
+#ifdef WIN32
+#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
+#endif //WIN32
+
+#include "BL_MeshDeformer.h"
+#include "BL_ArmatureObject.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_object_types.h"
+#include "BKE_armature.h"
+
+#include "RAS_Deformer.h"
+
+
+class BL_SkinDeformer : public BL_MeshDeformer
+{
+public:
+// void SetArmatureController (BL_ArmatureController *cont);
+ virtual void Relink(GEN_Map<class GEN_HashedPtr, void*>*map)
+ {
+ void **h_obj = (*map)[m_armobj];
+ if (h_obj){
+ SetArmature( (BL_ArmatureObject*)(*h_obj) );
+ }
+ else
+ m_armobj=NULL;
+ }
+ void SetArmature (class BL_ArmatureObject *armobj);
+ BL_SkinDeformer( struct Object *bmeshobj,
+ class BL_SkinMeshObject *mesh)
+ :BL_MeshDeformer(bmeshobj, mesh),
+ m_armobj(NULL),
+ m_defbase(&bmeshobj->defbase),
+ m_lastUpdate(-1)
+ {
+ /* Build all precalculatable matrices for bones */
+
+ GB_build_mats(bmeshobj->parent->obmat, bmeshobj->obmat, m_premat, m_postmat);
+ GB_validate_defgroups((Mesh*)bmeshobj->data, m_defbase);
+ // Validate bone data in bDeformGroups
+/*
+ for (bDeformGroup *dg=(bDeformGroup*)m_defbase->first; dg; dg=(bDeformGroup*)dg->next)
+ dg->data = (void*)get_named_bone(barm, dg->name);
+*/
+ };
+
+ virtual void ProcessReplica();
+ virtual RAS_Deformer *GetReplica();
+ virtual ~BL_SkinDeformer();
+ void Update (void);
+ bool Apply (class RAS_IPolyMaterial *polymat);
+
+protected:
+ BL_ArmatureObject *m_armobj; // Our parent object
+ float m_premat[4][4];
+ float m_postmat[4][4];
+ float m_time;
+ double m_lastUpdate;
+ ListBase *m_defbase;
+};
+
+#endif
+
diff --git a/source/gameengine/Converter/BL_SkinMeshObject.cpp b/source/gameengine/Converter/BL_SkinMeshObject.cpp
new file mode 100644
index 00000000000..859b495b9d5
--- /dev/null
+++ b/source/gameengine/Converter/BL_SkinMeshObject.cpp
@@ -0,0 +1,152 @@
+/**
+ * $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 *****
+ * Deformer that supports armature skinning
+ */
+
+#ifdef WIN32
+#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
+#endif //WIN32
+#include "RAS_IPolygonMaterial.h"
+#include "BL_SkinMeshObject.h"
+#include "BL_DeformableGameObject.h"
+#include "DNA_mesh_types.h"
+#include "KX_GameObject.h"
+#include "RAS_BucketManager.h"
+
+void BL_SkinMeshObject::AddPolygon(RAS_Polygon* poly)
+{
+ /* We're overriding this so that we can eventually associate faces with verts somehow */
+
+ // For vertIndex in poly:
+ // find the appropriate normal
+
+ RAS_MeshObject::AddPolygon(poly);
+}
+
+#ifdef __NLA_OLDDEFORM
+int BL_SkinMeshObject::FindOrAddDeform(int vtxarray, struct MVert *mv, struct MDeformVert *dv, RAS_IPolyMaterial* mat)
+#else
+int BL_SkinMeshObject::FindOrAddDeform(int vtxarray, int mv, struct MDeformVert *dv, RAS_IPolyMaterial* mat)
+#endif
+{
+ BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]);
+ int numvert = ao->m_MvertArrayCache1[vtxarray]->size();
+
+ /* Check to see if this has already been pushed */
+ for (int i=0; i<ao->m_MvertArrayCache1[vtxarray]->size(); i++){
+ if (mv == (*ao->m_MvertArrayCache1[vtxarray])[i])
+ return i;
+ }
+
+ ao->m_MvertArrayCache1[vtxarray]->push_back(mv);
+ ao->m_DvertArrayCache1[vtxarray]->push_back(dv);
+
+ return numvert;
+};
+
+int BL_SkinMeshObject::FindVertexArray(int numverts,RAS_IPolyMaterial* polymat)
+{
+ int array=-1;
+
+ BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(polymat);
+
+
+ for (int i=0;i<ao->m_VertexArrayCache1.size();i++)
+ {
+ if ( (ao->m_TriangleArrayCount[i] + (numverts-2)) < BUCKET_MAX_TRIANGLES)
+ {
+ if((ao->m_VertexArrayCache1[i]->size()+numverts < BUCKET_MAX_INDICES))
+ {
+ array = i;
+ ao->m_TriangleArrayCount[array]+=numverts-2;
+ break;
+ }
+ }
+ }
+
+
+ if (array == -1)
+ {
+ array = ao->m_VertexArrayCache1.size();
+
+ vector<RAS_TexVert>* va = new vector<RAS_TexVert>;
+ ao->m_VertexArrayCache1.push_back(va);
+
+ KX_IndexArray *ia = new KX_IndexArray();
+ ao->m_IndexArrayCache1.push_back(ia);
+
+#ifdef __NLA_OLDDEFORM
+ BL_MVertArray *bva = new BL_MVertArray();
+#else
+ KX_IndexArray *bva = new KX_IndexArray();
+#endif
+ ao->m_MvertArrayCache1.push_back(bva);
+
+ BL_DeformVertArray *dva = new BL_DeformVertArray();
+ ao->m_DvertArrayCache1.push_back(dva);
+
+ KX_IndexArray *da = new KX_IndexArray();
+ ao->m_DIndexArrayCache1.push_back(da);
+
+ ao->m_TriangleArrayCount.push_back(numverts-2);
+
+ }
+
+
+ return array;
+}
+
+
+//void BL_SkinMeshObject::Bucketize(double* oglmatrix,void* clientobj,bool useObjectColor,const MT_Vector4& rgbavec,RAS_BucketManager* bucketmgr)
+void BL_SkinMeshObject::Bucketize(double* oglmatrix,void* clientobj,bool useObjectColor,const MT_Vector4& rgbavec)
+{
+
+ KX_MeshSlot ms;
+ ms.m_clientObj = clientobj;
+ ms.m_mesh = this;
+ ms.m_OpenGLMatrix = oglmatrix;
+ ms.m_bObjectColor = useObjectColor;
+ ms.m_RGBAcolor = rgbavec;
+ ms.m_pDeformer = ((BL_DeformableGameObject*)clientobj)->m_pDeformer;
+
+ for (BucketMaterialSet::iterator it = m_materials.begin();it!=m_materials.end();it++)
+ {
+
+ RAS_MaterialBucket* materialbucket = (*it);
+
+ KX_ArrayOptimizer* oa = GetArrayOptimizer(materialbucket->GetPolyMaterial());
+ materialbucket->SetMeshSlot(ms);
+ }
+
+}
+
+
+
diff --git a/source/gameengine/Converter/BL_SkinMeshObject.h b/source/gameengine/Converter/BL_SkinMeshObject.h
new file mode 100644
index 00000000000..5ac95b48a35
--- /dev/null
+++ b/source/gameengine/Converter/BL_SkinMeshObject.h
@@ -0,0 +1,184 @@
+/**
+ * $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 __BL_SKINMESHOBJECT
+#define __BL_SKINMESHOBJECT
+
+#ifdef WIN32
+#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
+#endif //WIN32
+
+#include "RAS_MeshObject.h"
+#include "RAS_Deformer.h"
+#include "RAS_IPolygonMaterial.h"
+
+#include "BL_MeshDeformer.h"
+
+#include "DNA_mesh_types.h"
+
+typedef vector<struct MVert*> BL_MVertArray;
+typedef vector<struct MDeformVert*> BL_DeformVertArray;
+typedef vector<class BL_TexVert> BL_VertexArray;
+
+
+typedef vector<vector<struct MDeformVert*>*> vecMDVertArray;
+typedef vector<vector<class BL_TexVert>*> vecBVertexArray;
+
+class BL_SkinArrayOptimizer : public KX_ArrayOptimizer
+{
+public:
+ BL_SkinArrayOptimizer(int index)
+ :KX_ArrayOptimizer (index) {};
+ virtual ~BL_SkinArrayOptimizer(){
+
+ for (vector<KX_IndexArray*>::iterator itv = m_MvertArrayCache1.begin();
+ !(itv == m_MvertArrayCache1.end());itv++)
+ {
+ delete (*itv);
+ }
+ for (vector<BL_DeformVertArray*>::iterator itd = m_DvertArrayCache1.begin();
+ !(itd == m_DvertArrayCache1.end());itd++)
+ {
+ delete (*itd);
+ }
+ for (vector<KX_IndexArray*>::iterator iti = m_DIndexArrayCache1.begin();
+ !(iti == m_DIndexArrayCache1.end());iti++)
+ {
+ delete (*iti);
+ }
+
+ m_MvertArrayCache1.clear();
+ m_DvertArrayCache1.clear();
+ m_DIndexArrayCache1.clear();
+ };
+
+ vector<KX_IndexArray*> m_MvertArrayCache1;
+ vector<BL_DeformVertArray*> m_DvertArrayCache1;
+ vector<KX_IndexArray*> m_DIndexArrayCache1;
+
+};
+
+class BL_SkinMeshObject : public RAS_MeshObject
+{
+
+ enum { BUCKET_MAX_INDICES = 2048};//2048};//8192};
+ enum { BUCKET_MAX_TRIANGLES = 1024};
+
+ KX_ArrayOptimizer* GetArrayOptimizer(RAS_IPolyMaterial* polymat)
+ {
+ KX_ArrayOptimizer** aop = (m_matVertexArrayS[*polymat]);
+ if (aop)
+ return *aop;
+ int numelements = m_matVertexArrayS.size();
+ m_sortedMaterials.push_back(polymat);
+
+ BL_SkinArrayOptimizer* ao = new BL_SkinArrayOptimizer(numelements);
+ m_matVertexArrayS.insert(*polymat,ao);
+ return ao;
+ }
+
+protected:
+public:
+ void Bucketize(double* oglmatrix,void* clientobj,bool useObjectColor,const MT_Vector4& rgbavec);
+// void Bucketize(double* oglmatrix,void* clientobj,bool useObjectColor,const MT_Vector4& rgbavec,class RAS_BucketManager* bucketmgr);
+
+ int FindVertexArray(int numverts,RAS_IPolyMaterial* polymat);
+ BL_SkinMeshObject(int lightlayer) : RAS_MeshObject (lightlayer)
+ {};
+
+ virtual ~BL_SkinMeshObject(){
+ };
+
+ const vecIndexArrays& GetDIndexCache (RAS_IPolyMaterial* mat)
+ {
+ BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]);
+ return ao->m_DIndexArrayCache1;
+ }
+ const vecMDVertArray& GetDVertCache (RAS_IPolyMaterial* mat)
+ {
+ BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]);
+ return ao->m_DvertArrayCache1;
+ }
+ const vecIndexArrays& GetMVertCache (RAS_IPolyMaterial* mat)
+ {
+ BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]);
+ return ao->m_MvertArrayCache1;
+ }
+
+ void AddPolygon(RAS_Polygon* poly);
+ int FindOrAddDeform(int vtxarray, int mv, struct MDeformVert *dv, RAS_IPolyMaterial* mat);
+ int FindOrAddVertex(int vtxarray,const MT_Point3& xyz,
+ const MT_Point2& uv,
+ const unsigned int rgbacolor,
+ const MT_Vector3& normal, int defnr, bool flat, RAS_IPolyMaterial* mat)
+ {
+ short newnormal[3];
+ newnormal[0]=(short)(normal[0] * 32767.0);
+ newnormal[1]=(short)(normal[1] * 32767.0);
+ newnormal[2]=(short)(normal[2] * 32767.0);
+
+ RAS_TexVert tempvert(xyz,uv,rgbacolor,newnormal,flat ? TV_CALCFACENORMAL : 0);
+
+ // KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]);
+ BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]);
+
+ int numverts = ao->m_VertexArrayCache1[vtxarray]->size();//m_VertexArrayCount[vtxarray];
+
+ int index=-1;
+
+ for (int i=0;i<numverts;i++)
+ {
+ const RAS_TexVert& vtx = (*ao->m_VertexArrayCache1[vtxarray])[i];
+ if (tempvert.closeTo(&vtx))
+ {
+ index = i;
+ break;
+ }
+
+ }
+ if (index >= 0)
+ return index;
+
+ // no vertex found, add one
+ ao->m_VertexArrayCache1[vtxarray]->push_back(tempvert);
+ ao->m_DIndexArrayCache1[vtxarray]->push_back(defnr);
+
+ return numverts;
+
+
+ }
+
+};
+
+
+#endif
+
diff --git a/source/gameengine/Converter/BlenderWorldInfo.cpp b/source/gameengine/Converter/BlenderWorldInfo.cpp
new file mode 100644
index 00000000000..5dd41a317aa
--- /dev/null
+++ b/source/gameengine/Converter/BlenderWorldInfo.cpp
@@ -0,0 +1,215 @@
+/**
+ * $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 <stdio.h> // printf()
+
+
+#include "BlenderWorldInfo.h"
+#include "KX_BlenderGL.h"
+
+/* This little block needed for linking to Blender... */
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
+/* This list includes only data type definitions */
+#include "DNA_object_types.h"
+#include "DNA_material_types.h"
+#include "DNA_image_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_group_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_camera_types.h"
+#include "DNA_property_types.h"
+#include "DNA_text_types.h"
+#include "DNA_sensor_types.h"
+#include "DNA_controller_types.h"
+#include "DNA_actuator_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_world_types.h"
+#include "DNA_screen_types.h"
+
+#include "BKE_global.h"
+/* end of blender include block */
+
+
+BlenderWorldInfo::BlenderWorldInfo(struct World* blenderworld)
+{
+ if (blenderworld)
+ {
+ m_hasworld = true;
+
+ // do we have mist?
+ if ((blenderworld->mode) & WO_MIST)
+ {
+ m_hasmist = true;
+ m_miststart = blenderworld->miststa;
+ m_mistdistance = blenderworld->mistdist;
+ m_mistred = blenderworld->horr;
+ m_mistgreen = blenderworld->horg;
+ m_mistblue = blenderworld->horb;
+ }
+ else
+ {
+ m_hasmist = false;
+ m_miststart = 0.0;
+ m_mistdistance = 0.0;
+ m_mistred = 0.0;
+ m_mistgreen = 0.0;
+ m_mistblue = 0.0;
+ }
+
+ m_backgroundred = blenderworld->horr;
+ m_backgroundgreen = blenderworld->horg;
+ m_backgroundblue = blenderworld->horb;
+ }
+ else
+ {
+ m_hasworld = false;
+ }
+}
+
+
+
+BlenderWorldInfo::~BlenderWorldInfo()
+{
+
+}
+
+
+bool BlenderWorldInfo::hasWorld()
+{
+ return m_hasworld;
+}
+
+
+
+bool BlenderWorldInfo::hasMist()
+{
+ return m_hasmist;
+}
+
+
+
+float BlenderWorldInfo::getBackColorRed()
+{
+ return m_backgroundred;
+}
+
+
+
+float BlenderWorldInfo::getBackColorGreen()
+{
+ return m_backgroundgreen;
+}
+
+
+
+float BlenderWorldInfo::getBackColorBlue()
+{
+ return m_backgroundblue;
+}
+
+
+
+float BlenderWorldInfo::getMistStart()
+{
+ return m_miststart;
+}
+
+
+
+float BlenderWorldInfo::getMistDistance()
+{
+ return m_mistdistance;
+}
+
+
+
+float BlenderWorldInfo::getMistColorRed()
+{
+ return m_mistred;
+}
+
+
+
+float BlenderWorldInfo::getMistColorGreen()
+{
+ return m_mistgreen;
+}
+
+
+
+float BlenderWorldInfo::getMistColorBlue()
+{
+ return m_mistblue;
+}
+
+
+ void
+BlenderWorldInfo::setMistStart(
+ float d
+) {
+ m_miststart = d;
+}
+
+
+ void
+BlenderWorldInfo::setMistDistance(
+ float d
+) {
+ m_mistdistance = d;
+}
+
+
+ void
+BlenderWorldInfo::setMistColorRed(
+ float d
+) {
+ m_mistred = d;
+}
+
+
+ void
+BlenderWorldInfo::setMistColorGreen(
+ float d
+) {
+ m_mistgreen = d;
+}
+
+
+ void
+BlenderWorldInfo::setMistColorBlue(
+ float d
+) {
+ m_mistblue = d;
+}
diff --git a/source/gameengine/Converter/BlenderWorldInfo.h b/source/gameengine/Converter/BlenderWorldInfo.h
new file mode 100644
index 00000000000..1defd41bc72
--- /dev/null
+++ b/source/gameengine/Converter/BlenderWorldInfo.h
@@ -0,0 +1,95 @@
+/**
+ * $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 __BLENDERWORLDINFO_H
+#define __BLENDERWORLDINFO_H
+#include "MT_CmMatrix4x4.h"
+#include "KX_WorldInfo.h"
+#include "KX_BlenderGL.h"
+
+
+class BlenderWorldInfo : public KX_WorldInfo
+{
+ bool m_hasworld;
+ float m_backgroundred;
+ float m_backgroundgreen;
+ float m_backgroundblue;
+
+ bool m_hasmist;
+ float m_miststart;
+ float m_mistdistance;
+ float m_mistred;
+ float m_mistgreen;
+ float m_mistblue;
+
+public:
+ BlenderWorldInfo(struct World* blenderworld);
+ ~BlenderWorldInfo();
+
+ bool hasWorld();
+ bool hasMist();
+ float getBackColorRed();
+ float getBackColorGreen();
+ float getBackColorBlue();
+
+ float getMistStart();
+ float getMistDistance();
+ float getMistColorRed();
+ float getMistColorGreen();
+ float getMistColorBlue();
+
+ void
+ setMistStart(
+ float d
+ );
+
+ void
+ setMistDistance(
+ float d
+ );
+
+ void
+ setMistColorRed(
+ float d
+ );
+
+ void
+ setMistColorGreen(
+ float d
+ );
+
+ void
+ setMistColorBlue(
+ float d
+ );
+};
+
+#endif //__BLENDERWORLDINFO_H
diff --git a/source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp b/source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp
new file mode 100644
index 00000000000..c75a6e5b4e7
--- /dev/null
+++ b/source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp
@@ -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 *****
+ */
+
+
+#include "KX_BlenderScalarInterpolator.h"
+
+extern "C" int IPO_GetChannels(struct Ipo *ipo, short *channels);
+extern "C" float IPO_GetFloatValue(struct Ipo *ipo, /*IPO_Channel*/ short channel, float ctime);
+
+
+static const int BL_MAX_CHANNELS = 32;
+
+float BL_ScalarInterpolator::GetValue(float currentTime) const {
+ return IPO_GetFloatValue(m_blender_ipo, m_channel, currentTime);
+}
+
+typedef short IPO_Channel;
+
+BL_InterpolatorList::BL_InterpolatorList(struct Ipo *ipo) {
+ IPO_Channel channels[BL_MAX_CHANNELS];
+
+ int num_channels = IPO_GetChannels(ipo, channels);
+
+ int i;
+
+ for (i = 0; i != num_channels; ++i) {
+ BL_ScalarInterpolator *new_ipo =
+ new BL_ScalarInterpolator(ipo, channels[i]);
+
+ //assert(new_ipo);
+ push_back(new_ipo);
+ }
+}
+
+BL_InterpolatorList::~BL_InterpolatorList() {
+ BL_InterpolatorList::iterator i;
+ for (i = begin(); !(i == end()); ++i) {
+ delete *i;
+ }
+}
+
+
+KX_IScalarInterpolator *BL_InterpolatorList::GetScalarInterpolator(BL_IpoChannel channel) {
+ BL_InterpolatorList::iterator i = begin();
+ while (!(i == end()) &&
+ (static_cast<BL_ScalarInterpolator *>(*i))->GetChannel() !=
+ channel) {
+ ++i;
+ }
+
+ return (i == end()) ? 0 : *i;
+}
+
diff --git a/source/gameengine/Converter/KX_BlenderScalarInterpolator.h b/source/gameengine/Converter/KX_BlenderScalarInterpolator.h
new file mode 100644
index 00000000000..6276b286ce4
--- /dev/null
+++ b/source/gameengine/Converter/KX_BlenderScalarInterpolator.h
@@ -0,0 +1,70 @@
+/**
+ * $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_SCALARINTERPOLATOR_H
+#define __KX_SCALARINTERPOLATOR_H
+
+#include <vector>
+
+#include "KX_IScalarInterpolator.h"
+
+typedef unsigned short BL_IpoChannel;
+
+class BL_ScalarInterpolator : public KX_IScalarInterpolator {
+public:
+ BL_ScalarInterpolator() {} // required for use in STL list
+ BL_ScalarInterpolator(struct Ipo *ipo, BL_IpoChannel channel) :
+ m_blender_ipo(ipo),
+ m_channel(channel)
+ {}
+
+ virtual ~BL_ScalarInterpolator() {}
+
+ virtual float GetValue(float currentTime) const;
+
+ BL_IpoChannel GetChannel() const { return m_channel; }
+
+private:
+ struct Ipo *m_blender_ipo;
+ BL_IpoChannel m_channel;
+};
+
+
+class BL_InterpolatorList : public std::vector<KX_IScalarInterpolator *> {
+public:
+ BL_InterpolatorList(struct Ipo *ipo);
+ ~BL_InterpolatorList();
+
+ KX_IScalarInterpolator *GetScalarInterpolator(BL_IpoChannel channel);
+};
+
+
+#endif //__KX_SCALARINTERPOLATOR_H
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
new file mode 100644
index 00000000000..fdba851b7a3
--- /dev/null
+++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
@@ -0,0 +1,416 @@
+/**
+ * $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
+
+ #pragma warning (disable:4786) // suppress stl-MSVC debug info warning
+#endif
+
+
+#include "KX_Scene.h"
+#include "KX_GameObject.h"
+#include "KX_IpoConvert.h"
+#include "RAS_MeshObject.h"
+#include "KX_PhysicsEngineEnums.h"
+
+#include "DummyPhysicsEnvironment.h"
+
+#ifdef USE_ODE
+#include "OdePhysicsEnvironment.h"
+#endif //USE_ODE
+
+//to decide to use sumo/ode or dummy physics
+#include "KX_ConvertPhysicsObject.h"
+#ifdef USE_SUMO_SOLID
+#include "SumoPhysicsEnvironment.h"
+#endif
+
+#include "KX_BlenderSceneConverter.h"
+#include "KX_BlenderScalarInterpolator.h"
+#include "BL_BlenderDataConversion.h"
+#include "BlenderWorldInfo.h"
+#include "KX_Scene.h"
+
+/* This little block needed for linking to Blender... */
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
+/* This list includes only data type definitions */
+#include "DNA_scene_types.h"
+#include "DNA_world_types.h"
+#include "BKE_main.h"
+
+
+KX_BlenderSceneConverter::KX_BlenderSceneConverter(
+ struct Main* maggie,
+ class KX_KetsjiEngine* engine
+ )
+ : m_maggie(maggie),
+ m_ketsjiEngine(engine),
+ m_alwaysUseExpandFraming(false)
+{
+ m_newfilename = "";
+}
+
+
+KX_BlenderSceneConverter::~KX_BlenderSceneConverter()
+{
+ // clears meshes, and hashmaps from blender to gameengine data
+ int i;
+ // delete sumoshapes
+
+
+ int numipolists = m_map_blender_to_gameipolist.size();
+ for (i=0; i<numipolists; i++) {
+ BL_InterpolatorList *ipoList= *m_map_blender_to_gameipolist.at(i);
+
+ delete (ipoList);
+ }
+
+ vector<KX_WorldInfo*>::iterator itw = m_worldinfos.begin();
+ while (itw != m_worldinfos.end()) {
+ delete (*itw);
+ itw++;
+ }
+
+ vector<RAS_IPolyMaterial*>::iterator itp = m_polymaterials.begin();
+ while (itp != m_polymaterials.end()) {
+ delete (*itp);
+ itp++;
+ }
+
+ vector<RAS_MeshObject*>::iterator itm = m_meshobjects.begin();
+ while (itm != m_meshobjects.end()) {
+ delete (*itm);
+ itm++;
+ }
+}
+
+
+
+void KX_BlenderSceneConverter::SetNewFileName(const STR_String& filename)
+{
+ m_newfilename = filename;
+}
+
+
+
+bool KX_BlenderSceneConverter::TryAndLoadNewFile()
+{
+ bool result = false;
+
+ // find the file
+/* if ()
+ {
+ result = true;
+ }
+ // if not, clear the newfilename
+ else
+ {
+ m_newfilename = "";
+ }
+*/
+ return result;
+}
+
+
+
+ /**
+ * Find the specified scene by name, or the first
+ * scene if nothing matches (shouldn't happen).
+ */
+static struct Scene *GetSceneForName2(struct Main *maggie, const STR_String& scenename) {
+ Scene *sce;
+
+ for (sce= (Scene*) maggie->scene.first; sce; sce= (Scene*) sce->id.next)
+ if (scenename == (sce->id.name+2))
+ return sce;
+
+ return (Scene*) maggie->scene.first;
+}
+
+
+void KX_BlenderSceneConverter::ConvertScene(const STR_String& scenename,
+ class KX_Scene* destinationscene,
+ PyObject* dictobj,
+ class SCA_IInputDevice* keyinputdev,
+ class RAS_IRenderTools* rendertools,
+ class RAS_ICanvas* canvas)
+{
+ //find out which physics engine
+ Scene *blenderscene = GetSceneForName2(m_maggie, scenename);
+
+ e_PhysicsEngine physics_engine = UseSumo;
+
+ if (blenderscene)
+ {
+ int i=0;
+
+ if (blenderscene->world)
+ {
+
+ switch (blenderscene->world->pad1)
+ {
+
+ case 4:
+ {
+ physics_engine = UseODE;
+ break;
+ }
+ case 5:
+ {
+ physics_engine = UseDynamo;
+ break;
+ }
+ case 7:
+ {
+ physics_engine = UseNone;
+ break;
+ };
+ default:
+ {
+ physics_engine = UseSumo;
+ }
+ }
+ }
+ }
+
+ switch (physics_engine)
+ {
+
+ case UseSumo:
+ {
+#ifdef USE_SUMO_SOLID
+
+ PHY_IPhysicsEnvironment* physEnv =
+ new SumoPhysicsEnvironment();
+#else
+ physics_engine = UseNone;
+
+ PHY_IPhysicsEnvironment* physEnv =
+ new DummyPhysicsEnvironment();
+
+#endif
+ destinationscene ->SetPhysicsEnvironment(physEnv);
+ break;
+ }
+ case UseODE:
+ {
+#ifdef USE_ODE
+
+ PHY_IPhysicsEnvironment* physEnv =
+ new ODEPhysicsEnvironment();
+#else
+ PHY_IPhysicsEnvironment* physEnv =
+ new DummyPhysicsEnvironment();
+
+#endif //USE_ODE
+
+ destinationscene ->SetPhysicsEnvironment(physEnv);
+ break;
+ }
+ case UseDynamo:
+ {
+ }
+
+ case UseNone:
+ {
+ };
+ default:
+ {
+ physics_engine = UseNone;
+
+ PHY_IPhysicsEnvironment* physEnv =
+ new DummyPhysicsEnvironment();
+ destinationscene ->SetPhysicsEnvironment(physEnv);
+
+ }
+ }
+
+ BL_ConvertBlenderObjects(m_maggie,
+ scenename,
+ destinationscene,
+ m_ketsjiEngine,
+ physics_engine,
+ dictobj,
+ keyinputdev,
+ rendertools,
+ canvas,
+ this,
+ m_alwaysUseExpandFraming
+ );
+
+ m_map_blender_to_gameactuator.clear();
+ m_map_blender_to_gamecontroller.clear();
+
+ m_map_blender_to_gameobject.clear();
+ m_map_mesh_to_gamemesh.clear();
+ m_map_gameobject_to_blender.clear();
+}
+
+
+
+void KX_BlenderSceneConverter::SetAlwaysUseExpandFraming(
+ bool to_what)
+{
+ m_alwaysUseExpandFraming= to_what;
+}
+
+
+
+void KX_BlenderSceneConverter::RegisterGameObject(
+ KX_GameObject *gameobject,
+ struct Object *for_blenderobject)
+{
+ m_map_gameobject_to_blender.insert(CHashedPtr(gameobject),for_blenderobject);
+ m_map_blender_to_gameobject.insert(CHashedPtr(for_blenderobject),gameobject);
+}
+
+
+
+KX_GameObject *KX_BlenderSceneConverter::FindGameObject(
+ struct Object *for_blenderobject)
+{
+ KX_GameObject **obp= m_map_blender_to_gameobject[CHashedPtr(for_blenderobject)];
+
+ return obp?*obp:NULL;
+}
+
+
+
+struct Object *KX_BlenderSceneConverter::FindBlenderObject(
+ KX_GameObject *for_gameobject)
+{
+ struct Object **obp= m_map_gameobject_to_blender[CHashedPtr(for_gameobject)];
+
+ return obp?*obp:NULL;
+}
+
+
+
+void KX_BlenderSceneConverter::RegisterGameMesh(
+ RAS_MeshObject *gamemesh,
+ struct Mesh *for_blendermesh)
+{
+ m_map_mesh_to_gamemesh.insert(CHashedPtr(for_blendermesh),gamemesh);
+ m_meshobjects.push_back(gamemesh);
+}
+
+
+
+RAS_MeshObject *KX_BlenderSceneConverter::FindGameMesh(
+ struct Mesh *for_blendermesh,
+ unsigned int onlayer)
+{
+ RAS_MeshObject** meshp = m_map_mesh_to_gamemesh[CHashedPtr(for_blendermesh)];
+
+ if (meshp && onlayer==(*meshp)->GetLightLayer()) {
+ return *meshp;
+ } else {
+ return NULL;
+ }
+}
+
+
+
+
+
+
+void KX_BlenderSceneConverter::RegisterPolyMaterial(RAS_IPolyMaterial *polymat)
+{
+ m_polymaterials.push_back(polymat);
+}
+
+
+
+void KX_BlenderSceneConverter::RegisterInterpolatorList(
+ BL_InterpolatorList *ipoList,
+ struct Ipo *for_ipo)
+{
+ m_map_blender_to_gameipolist.insert(CHashedPtr(for_ipo), ipoList);
+}
+
+
+
+BL_InterpolatorList *KX_BlenderSceneConverter::FindInterpolatorList(
+ struct Ipo *for_ipo)
+{
+ BL_InterpolatorList **listp = m_map_blender_to_gameipolist[CHashedPtr(for_ipo)];
+
+ return listp?*listp:NULL;
+}
+
+
+
+void KX_BlenderSceneConverter::RegisterGameActuator(
+ SCA_IActuator *act,
+ struct bActuator *for_actuator)
+{
+ m_map_blender_to_gameactuator.insert(CHashedPtr(for_actuator), act);
+}
+
+
+
+SCA_IActuator *KX_BlenderSceneConverter::FindGameActuator(
+ struct bActuator *for_actuator)
+{
+ SCA_IActuator **actp = m_map_blender_to_gameactuator[CHashedPtr(for_actuator)];
+
+ return actp?*actp:NULL;
+}
+
+
+
+void KX_BlenderSceneConverter::RegisterGameController(
+ SCA_IController *cont,
+ struct bController *for_controller)
+{
+ m_map_blender_to_gamecontroller.insert(CHashedPtr(for_controller), cont);
+}
+
+
+
+SCA_IController *KX_BlenderSceneConverter::FindGameController(
+ struct bController *for_controller)
+{
+ SCA_IController **contp = m_map_blender_to_gamecontroller[CHashedPtr(for_controller)];
+
+ return contp?*contp:NULL;
+}
+
+
+
+void KX_BlenderSceneConverter::RegisterWorldInfo(
+ KX_WorldInfo *worldinfo)
+{
+ m_worldinfos.push_back(worldinfo);
+}
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.h b/source/gameengine/Converter/KX_BlenderSceneConverter.h
new file mode 100644
index 00000000000..446c238a274
--- /dev/null
+++ b/source/gameengine/Converter/KX_BlenderSceneConverter.h
@@ -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 *****
+ */
+#ifndef __KX_BLENDERSCENECONVERTER_H
+#define __KX_BLENDERSCENECONVERTER_H
+
+#include "GEN_Map.h"
+
+#include "KX_ISceneConverter.h"
+#include "KX_HashedPtr.h"
+#include "KX_IpoConvert.h"
+
+class KX_WorldInfo;
+class SCA_IActuator;
+class SCA_IController;
+class RAS_MeshObject;
+class RAS_IPolyMaterial;
+class BL_InterpolatorList;
+
+class KX_BlenderSceneConverter : public KX_ISceneConverter
+{
+ vector<KX_WorldInfo*> m_worldinfos;
+ vector<RAS_IPolyMaterial*> m_polymaterials;
+ vector<RAS_MeshObject*> m_meshobjects;
+
+ GEN_Map<CHashedPtr,struct Object*> m_map_gameobject_to_blender;
+ GEN_Map<CHashedPtr,KX_GameObject*> m_map_blender_to_gameobject;
+
+ GEN_Map<CHashedPtr,RAS_MeshObject*> m_map_mesh_to_gamemesh;
+// GEN_Map<CHashedPtr,DT_ShapeHandle> m_map_gamemesh_to_sumoshape;
+
+ GEN_Map<CHashedPtr,SCA_IActuator*> m_map_blender_to_gameactuator;
+ GEN_Map<CHashedPtr,SCA_IController*> m_map_blender_to_gamecontroller;
+
+ GEN_Map<CHashedPtr,BL_InterpolatorList*> m_map_blender_to_gameipolist;
+
+ struct Main* m_maggie;
+ STR_String m_newfilename;
+ class KX_KetsjiEngine* m_ketsjiEngine;
+ bool m_alwaysUseExpandFraming;
+
+public:
+ KX_BlenderSceneConverter(
+ struct Main* maggie,
+ class KX_KetsjiEngine* engine
+ );
+
+ virtual ~KX_BlenderSceneConverter();
+
+ /* Scenename: name of the scene to be converted.
+ * destinationscene: pass an empty scene, everything goes into this
+ * dictobj: python dictionary (for pythoncontrollers)
+ */
+ virtual void ConvertScene(
+ const STR_String& scenename,
+ class KX_Scene* destinationscene,
+ PyObject* dictobj,
+ class SCA_IInputDevice* keyinputdev,
+ class RAS_IRenderTools* rendertools,
+ class RAS_ICanvas* canvas
+ );
+
+ void SetNewFileName(const STR_String& filename);
+ bool TryAndLoadNewFile();
+
+ void SetAlwaysUseExpandFraming(bool to_what);
+
+ void RegisterGameObject(KX_GameObject *gameobject, struct Object *for_blenderobject);
+ KX_GameObject *FindGameObject(struct Object *for_blenderobject);
+ struct Object *FindBlenderObject(KX_GameObject *for_gameobject);
+
+ void RegisterGameMesh(RAS_MeshObject *gamemesh, struct Mesh *for_blendermesh);
+ RAS_MeshObject *FindGameMesh(struct Mesh *for_blendermesh, unsigned int onlayer);
+
+// void RegisterSumoShape(DT_ShapeHandle shape, RAS_MeshObject *for_gamemesh);
+// DT_ShapeHandle FindSumoShape(RAS_MeshObject *for_gamemesh);
+
+ void RegisterPolyMaterial(RAS_IPolyMaterial *polymat);
+
+ void RegisterInterpolatorList(BL_InterpolatorList *ipoList, struct Ipo *for_ipo);
+ BL_InterpolatorList *FindInterpolatorList(struct Ipo *for_ipo);
+
+ void RegisterGameActuator(SCA_IActuator *act, struct bActuator *for_actuator);
+ SCA_IActuator *FindGameActuator(struct bActuator *for_actuator);
+
+ void RegisterGameController(SCA_IController *cont, struct bController *for_controller);
+ SCA_IController *FindGameController(struct bController *for_controller);
+
+ void RegisterWorldInfo(KX_WorldInfo *worldinfo);
+};
+
+#endif //__KX_BLENDERSCENECONVERTER_H
diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp
new file mode 100644
index 00000000000..2628441ba72
--- /dev/null
+++ b/source/gameengine/Converter/KX_ConvertActuators.cpp
@@ -0,0 +1,909 @@
+/**
+* $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 *****
+* Convert Blender actuators for use in the GameEngine
+*/
+
+#ifdef WIN32
+#pragma warning (disable : 4786)
+#endif //WIN32
+
+#define BLENDER_HACK_DTIME 0.02
+
+#include "KX_BlenderSceneConverter.h"
+#include "KX_ConvertActuators.h"
+
+// Actuators
+//SCA logiclibrary native logicbricks
+#include "SCA_PropertyActuator.h"
+#include "SCA_LogicManager.h"
+#include "SCA_RandomActuator.h"
+
+
+// Ketsji specific logicbricks
+#include "KX_SceneActuator.h"
+#include "KX_IpoActuator.h"
+#include "KX_SoundActuator.h"
+#include "KX_CDActuator.h"
+#include "KX_ObjectActuator.h"
+#include "KX_TrackToActuator.h"
+#include "KX_ConstraintActuator.h"
+#include "KX_CameraActuator.h"
+#include "KX_GameActuator.h"
+#include "KX_VisibilityActuator.h"
+#include "KX_SCA_AddObjectActuator.h"
+#include "KX_SCA_EndObjectActuator.h"
+#include "KX_SCA_ReplaceMeshActuator.h"
+
+#include "KX_Scene.h"
+#include "KX_KetsjiEngine.h"
+
+#include "IntValue.h"
+#include "KX_GameObject.h"
+
+/* This little block needed for linking to Blender... */
+
+#include "BLI_blenlib.h"
+
+#include "KX_NetworkMessageActuator.h"
+
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
+#include "DNA_object_types.h"
+#include "DNA_sound_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_actuator_types.h"
+#include "DNA_packedFile_types.h"
+#include "BL_ActionActuator.h"
+/* end of blender include block */
+
+#include "BL_BlenderDataConversion.h"
+
+/**
+KX_BLENDERTRUNC needed to round 'almost' zero values to zero, else velocities etc. are incorrectly set
+*/
+
+#define KX_BLENDERTRUNC(x) (( x < 0.0001 && x > -0.0001 ) ? 0.0 : x)
+
+void BL_ConvertActuators(char* maggiename,
+ struct Object* blenderobject,
+ KX_GameObject* gameobj,
+ SCA_LogicManager* logicmgr,
+ KX_Scene* scene,
+ KX_KetsjiEngine* ketsjiEngine,
+ int & executePriority,
+ int activeLayerBitInfo,
+ bool isInActiveLayer,
+ RAS_IRenderTools* rendertools,
+ KX_BlenderSceneConverter* converter
+ )
+{
+
+ int uniqueint = 0;
+ bActuator* bact = (bActuator*) blenderobject->actuators.first;
+ while(bact)
+ {
+ STR_String uniquename = bact->name;
+ STR_String objectname = gameobj->GetName();
+
+ SCA_IActuator* baseact = NULL;
+ switch (bact->type)
+ {
+ case ACT_OBJECT:
+ {
+ bObjectActuator* obact = (bObjectActuator*) bact->data;
+ MT_Vector3 forcevec(KX_BLENDERTRUNC(obact->forceloc[0]),
+ KX_BLENDERTRUNC(obact->forceloc[1]),
+ KX_BLENDERTRUNC(obact->forceloc[2]));
+ MT_Vector3 torquevec(obact->forcerot[0],obact->forcerot[1],obact->forcerot[2]);
+ MT_Vector3 dlocvec ( KX_BLENDERTRUNC(obact->dloc[0]),
+ KX_BLENDERTRUNC(obact->dloc[1]),
+ KX_BLENDERTRUNC(obact->dloc[2]));
+ MT_Vector3 drotvec ( KX_BLENDERTRUNC(obact->drot[0]),obact->drot[1],obact->drot[2]);
+ MT_Vector3 linvelvec ( KX_BLENDERTRUNC(obact->linearvelocity[0]),
+ KX_BLENDERTRUNC(obact->linearvelocity[1]),
+ KX_BLENDERTRUNC(obact->linearvelocity[2]));
+ MT_Vector3 angvelvec ( KX_BLENDERTRUNC(obact->angularvelocity[0]),
+ KX_BLENDERTRUNC(obact->angularvelocity[1]),
+ KX_BLENDERTRUNC(obact->angularvelocity[2]));
+
+ drotvec /= BLENDER_HACK_DTIME;
+ //drotvec /= BLENDER_HACK_DTIME;
+ drotvec *= MT_2_PI/360.0;
+ //dlocvec /= BLENDER_HACK_DTIME;
+ //linvelvec /= BLENDER_HACK_DTIME;
+ //angvelvec /= BLENDER_HACK_DTIME;
+
+ /* Blender uses a bit vector internally for the local-flags. In */
+ /* KX, we have four bools. The compiler should be smart enough */
+ /* to do the right thing. We need to explicitly convert here! */
+
+ KX_LocalFlags bitLocalFlag;
+
+ bitLocalFlag.Force = bool((obact->flag & ACT_FORCE_LOCAL)!=0);
+ bitLocalFlag.Torque = bool((obact->flag & ACT_TORQUE_LOCAL) !=0);//rlocal;
+ bitLocalFlag.DLoc = bool((obact->flag & ACT_DLOC_LOCAL)!=0);
+ bitLocalFlag.DRot = bool((obact->flag & ACT_DROT_LOCAL)!=0);
+ bitLocalFlag.LinearVelocity = bool((obact->flag & ACT_LIN_VEL_LOCAL)!=0);
+ bitLocalFlag.AngularVelocity = bool((obact->flag & ACT_ANG_VEL_LOCAL)!=0);
+
+ bitLocalFlag.AddOrSetLinV = bool((obact->flag & ACT_ADD_LIN_VEL)!=0);
+
+
+ KX_ObjectActuator* tmpbaseact = new KX_ObjectActuator(gameobj,
+ forcevec.getValue(),
+ torquevec.getValue(),
+ dlocvec.getValue(),
+ drotvec.getValue(),
+ linvelvec.getValue(),
+ angvelvec.getValue(),
+ bitLocalFlag
+ );
+ baseact = tmpbaseact;
+ break;
+ }
+ case ACT_ACTION:
+ {
+ if (blenderobject->type==OB_ARMATURE){
+ bActionActuator* actact = (bActionActuator*) bact->data;
+ STR_String propname = (actact->name ? actact->name : "");
+
+ BL_ActionActuator* tmpbaseact = new BL_ActionActuator(
+ gameobj,
+ propname,
+ actact->sta,
+ actact->end,
+ actact->act,
+ actact->type, // + 1, because Blender starts to count at zero,
+ actact->blendin,
+ actact->priority,
+ actact->stridelength
+ // Ketsji at 1, because zero is reserved for "NoDef"
+ );
+ baseact= tmpbaseact;
+ break;
+ }
+ else
+ printf ("Discarded action actuator from non-armature object [%s]\n", blenderobject->id.name+2);
+ }
+ case ACT_IPO:
+ {
+ bIpoActuator* ipoact = (bIpoActuator*) bact->data;
+ bool ipochild = (ipoact->flag & ACT_IPOCHILD) !=0;
+ STR_String propname = ( ipoact->name ? ipoact->name : "");
+ // first bit?
+ bool ipo_as_force = (ipoact->flag & ACT_IPOFORCE);
+ bool force_local = (ipoact->flag & ACT_IPOFORCE_LOCAL);
+
+ KX_IpoActuator* tmpbaseact = new KX_IpoActuator(
+ gameobj,
+ propname ,
+ ipoact->sta,
+ ipoact->end,
+ ipochild,
+ ipoact->type + 1, // + 1, because Blender starts to count at zero,
+ // Ketsji at 1, because zero is reserved for "NoDef"
+ ipo_as_force,
+ force_local
+ );
+ baseact = tmpbaseact;
+ break;
+ }
+ case ACT_LAMP:
+ {
+ break;
+ }
+ case ACT_CAMERA:
+ {
+ bCameraActuator *camact = (bCameraActuator *) bact->data;
+ if (camact->ob) {
+ KX_GameObject *tmpgob = converter->FindGameObject(camact->ob);
+
+ /* visifac, fac and axis are not copied from the struct... */
+ /* that's some internal state... */
+ KX_CameraActuator *tmpcamact
+ = new KX_CameraActuator(gameobj,
+ tmpgob,
+ camact->height,
+ camact->min,
+ camact->max,
+ camact->axis=='x');
+ baseact = tmpcamact;
+ }
+ break;
+ }
+ case ACT_MESSAGE:
+ {
+ bMessageActuator *msgAct = (bMessageActuator *) bact->data;
+
+ /**
+ * Get the name of the properties that objects must own that
+ * we're sending to, if present
+ */
+ STR_String toPropName = (msgAct->toPropName
+ ? (char*) msgAct->toPropName
+ : "");
+ /**
+ * Get the Message Subject to send.
+ */
+ STR_String subject = (msgAct->subject
+ ? (char*) msgAct->subject
+ : "");
+
+ /**
+ * Get the bodyType
+ */
+ int bodyType = msgAct->bodyType;
+
+ /**
+ * Get the body (text message or property name whose value
+ * we'll be sending, might be empty
+ */
+ STR_String body = (msgAct->body
+ ? (char*) msgAct->body
+ : "");
+
+ KX_NetworkMessageActuator *tmpmsgact =
+ new KX_NetworkMessageActuator(
+ gameobj, // actuator controlling object
+ scene->GetNetworkScene(), // needed for replication
+ toPropName,
+ subject,
+ bodyType,
+ body);
+ baseact = tmpmsgact;
+ break;
+ }
+ case ACT_MATERIAL:
+ {
+ break;
+ }
+ case ACT_SOUND:
+ {
+ bSoundActuator* soundact = (bSoundActuator*) bact->data;
+ /* get type, and possibly a start and end frame */
+ short startFrame = soundact->sta, stopFrame = soundact->end;
+ KX_SoundActuator::KX_SOUNDACT_TYPE
+ soundActuatorType = KX_SoundActuator::KX_SOUNDACT_NODEF;
+
+ switch(soundact->type) {
+ case ACT_SND_PLAY_STOP_SOUND:
+ soundActuatorType = KX_SoundActuator::KX_SOUNDACT_PLAYSTOP;
+ break;
+ case ACT_SND_PLAY_END_SOUND:
+ soundActuatorType = KX_SoundActuator::KX_SOUNDACT_PLAYEND;
+ break;
+ case ACT_SND_LOOP_STOP_SOUND:
+ soundActuatorType = KX_SoundActuator::KX_SOUNDACT_LOOPSTOP;
+ break;
+ case ACT_SND_LOOP_END_SOUND:
+ soundActuatorType = KX_SoundActuator::KX_SOUNDACT_LOOPEND;
+ break;
+ case ACT_SND_LOOP_BIDIRECTIONAL_SOUND:
+ soundActuatorType = KX_SoundActuator::KX_SOUNDACT_LOOPBIDIRECTIONAL;
+ break;
+ case ACT_SND_LOOP_BIDIRECTIONAL_STOP_SOUND:
+ soundActuatorType = KX_SoundActuator::KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP;
+ break;
+
+ default:
+ /* This is an error!!! */
+ soundActuatorType = KX_SoundActuator::KX_SOUNDACT_NODEF;
+ }
+
+ if (soundActuatorType != KX_SoundActuator::KX_SOUNDACT_NODEF)
+ {
+ SND_SoundObject* sndobj = NULL;
+
+ if (soundact->sound)
+ {
+ SND_Scene* soundscene = scene->GetSoundScene();
+ STR_String samplename = soundact->sound->name;
+
+ bool sampleisloaded = false;
+
+ /* let's see if the sample was already loaded */
+ if (soundscene->IsSampleLoaded(samplename))
+ {
+ sampleisloaded = true;
+ }
+ else
+ {
+ /* if not, make it so */
+ PackedFile* pf = soundact->sound->newpackedfile;
+
+ /* but we need a packed file then */
+ if (pf)
+ {
+ if (soundscene->LoadSample(samplename, pf->data, pf->size) > -1)
+ sampleisloaded = true;
+ }
+ /* or else load it from disk */
+ else
+ {
+ /* but we need to convert the samplename into absolute pathname first */
+ BLI_convertstringcode(soundact->sound->name, maggiename, 0);
+ samplename = soundact->sound->name;
+
+ /* and now we can load it */
+ if (soundscene->LoadSample(samplename, NULL, 0) > -1)
+ sampleisloaded = true;
+ }
+ }
+
+ if (sampleisloaded)
+ {
+ sndobj = new SND_SoundObject();
+ sndobj->SetSampleName(samplename.Ptr());
+ sndobj->SetObjectName(bact->name);
+ sndobj->SetRollOffFactor(soundact->sound->attenuation);
+ sndobj->SetGain(soundact->sound->volume);
+ sndobj->SetPitch(exp((soundact->sound->pitch / 12.0) * log(2.0)));
+ // sndobj->SetLoopStart(soundact->sound->loopstart);
+ // sndobj->SetLoopStart(soundact->sound->loopend);
+ if (soundact->sound->flags & SOUND_FLAGS_LOOP)
+ {
+ if (soundact->sound->flags & SOUND_FLAGS_BIDIRECTIONAL_LOOP)
+ sndobj->SetLoopMode(SND_LOOP_BIDIRECTIONAL);
+ else
+ sndobj->SetLoopMode(SND_LOOP_NORMAL);
+ }
+ else
+ sndobj->SetLoopMode(SND_LOOP_OFF);
+
+ if (soundact->sound->flags & SOUND_FLAGS_PRIORITY)
+ sndobj->SetHighPriority(true);
+ else
+ sndobj->SetHighPriority(false);
+
+ if (soundact->sound->flags & SOUND_FLAGS_3D)
+ sndobj->Set3D(true);
+ else
+ sndobj->Set3D(false);
+
+ KX_SoundActuator* tmpsoundact =
+ new KX_SoundActuator(gameobj,
+ sndobj,
+ scene->GetSoundScene(), // needed for replication!
+ soundActuatorType,
+ startFrame,
+ stopFrame);
+
+ tmpsoundact->SetName(bact->name);
+ baseact = tmpsoundact;
+ soundscene->AddObject(sndobj);
+ }
+ }
+ }
+ break;
+ }
+ case ACT_CD:
+ {
+ bCDActuator* cdact = (bCDActuator*) bact->data;
+ /* get type, and possibly a start and end frame */
+ short startFrame = cdact->sta, stopFrame = cdact->end;
+ KX_CDActuator::KX_CDACT_TYPE
+ cdActuatorType = KX_CDActuator::KX_CDACT_NODEF;
+
+ switch(cdact->type)
+ {
+ case ACT_CD_PLAY_ALL:
+ cdActuatorType = KX_CDActuator::KX_CDACT_PLAY_ALL;
+ break;
+ case ACT_CD_PLAY_TRACK:
+ cdActuatorType = KX_CDActuator::KX_CDACT_PLAY_TRACK;
+ break;
+ case ACT_CD_LOOP_TRACK:
+ cdActuatorType = KX_CDActuator::KX_CDACT_LOOP_TRACK;
+ break;
+ case ACT_CD_VOLUME:
+ cdActuatorType = KX_CDActuator::KX_CDACT_VOLUME;
+ break;
+ case ACT_CD_STOP:
+ cdActuatorType = KX_CDActuator::KX_CDACT_STOP;
+ break;
+ case ACT_CD_PAUSE:
+ cdActuatorType = KX_CDActuator::KX_CDACT_PAUSE;
+ break;
+ case ACT_CD_RESUME:
+ cdActuatorType = KX_CDActuator::KX_CDACT_RESUME;
+ break;
+
+ default:
+ /* This is an error!!! */
+ cdActuatorType = KX_CDActuator::KX_CDACT_NODEF;
+ }
+
+ if (cdActuatorType != KX_CDActuator::KX_CDACT_NODEF)
+ {
+ SND_Scene* soundscene = scene->GetSoundScene();
+ SND_CDObject* pCD = SND_CDObject::Instance();
+
+ if (pCD)
+ {
+ pCD->SetGain(cdact->volume);
+
+ KX_CDActuator* tmpcdact =
+ new KX_CDActuator(gameobj,
+ scene->GetSoundScene(), // needed for replication!
+ cdActuatorType,
+ cdact->track,
+ startFrame,
+ stopFrame);
+
+ tmpcdact->SetName(bact->name);
+ baseact = tmpcdact;
+ }
+ }
+ break;
+ }
+ case ACT_PROPERTY:
+ {
+ bPropertyActuator* propact = (bPropertyActuator*) bact->data;
+ CValue* destinationObj = NULL;
+
+ /*
+ here the destinationobject is searched. problem with multiple scenes: other scenes
+ have not been converted yet, so the destobj will not be found, so the prop will
+ not be copied.
+ possible solutions:
+ - convert everything when possible and not realtime only when needed.
+ - let the object-with-property report itself to the act when converted
+ */
+ if (propact->ob)
+ {
+ KX_GameObject* tempObj = converter->FindGameObject(propact->ob);
+ if (tempObj)
+ {
+ destinationObj = tempObj;
+ }
+ }
+
+ SCA_PropertyActuator* tmppropact = new SCA_PropertyActuator(
+ gameobj,
+ destinationObj,
+ propact->name,
+ propact->value,
+ propact->type+1); // + 1 because Ketsji Logic starts
+ // with 0 for KX_ACT_PROP_NODEF
+ baseact = tmppropact;
+ break;
+ }
+ case ACT_EDIT_OBJECT:
+ {
+ bEditObjectActuator *editobact
+ = (bEditObjectActuator *) bact->data;
+ /* There are four different kinds of 'edit object' thingies */
+ /* The alternative to this lengthy conversion is packing */
+ /* several actuators in one, which is not very nice design.. */
+ switch (editobact->type) {
+ case ACT_EDOB_ADD_OBJECT:
+ {
+
+ // does the 'original' for replication exists, and
+ // is it in a non-active layer ?
+ if (editobact->ob && !(editobact->ob->lay & activeLayerBitInfo))
+ {
+ CValue* originalval = converter->FindGameObject(editobact->ob);
+
+ if (originalval)
+ {
+ MT_Vector3 linvelvec ( KX_BLENDERTRUNC(editobact->linVelocity[0]),
+ KX_BLENDERTRUNC(editobact->linVelocity[1]),
+ KX_BLENDERTRUNC(editobact->linVelocity[2]));
+ KX_SCA_AddObjectActuator* tmpaddact =
+ new KX_SCA_AddObjectActuator(
+
+ gameobj,
+ originalval,
+ editobact->time,
+ scene,
+ linvelvec.getValue(),
+ editobact->localflag!=0
+
+ );
+
+ //editobact->ob to gameobj
+ baseact = tmpaddact;
+ }
+ else
+ {
+ // let's pretend this never happened
+ exit(0);
+ }
+ } else
+ {
+ printf ("ERROR: GameObject %s has a AddObjectActuator %s without object (in 'nonactive' layer)\n",
+ objectname.ReadPtr(),
+ uniquename.ReadPtr() );
+ }
+ }
+ break;
+ case ACT_EDOB_END_OBJECT:
+ {
+ KX_SCA_EndObjectActuator* tmpendact
+ = new KX_SCA_EndObjectActuator(gameobj,scene);
+ baseact = tmpendact;
+ }
+ break;
+ case ACT_EDOB_REPLACE_MESH:
+ {
+ if (editobact->me)
+ {
+ RAS_MeshObject *tmpmesh = BL_ConvertMesh(
+ editobact->me,
+ blenderobject,
+ rendertools,
+ scene,
+ converter
+ );
+ KX_SCA_ReplaceMeshActuator* tmpreplaceact
+ = new KX_SCA_ReplaceMeshActuator(
+ gameobj,
+ tmpmesh,
+ scene
+ );
+
+ baseact = tmpreplaceact;
+ }
+ else
+ {
+ printf ("ERROR: GameObject %s ReplaceMeshActuator %s without object\n",
+ objectname.ReadPtr(),
+ uniquename.ReadPtr());
+ }
+ }
+ break;
+ case ACT_EDOB_TRACK_TO:
+ {
+ if (editobact->ob)
+ {
+ SCA_IObject* originalval = converter->FindGameObject(editobact->ob);
+
+ KX_TrackToActuator* tmptrackact
+ = new KX_TrackToActuator(gameobj,
+ originalval,
+ editobact->time,
+ editobact->flag,
+ blenderobject->trackflag,
+ blenderobject->upflag
+ );
+ baseact = tmptrackact;
+ }
+ else
+ {
+ printf("ERROR: GameObject %s no object in EditObjectActuator %s\n",
+ objectname.ReadPtr(),
+ uniquename.ReadPtr() );
+
+
+ }
+ }
+ }
+ break;
+ }
+ case ACT_CONSTRAINT:
+ {
+ float min = 0.0, max = 0.0;
+ int locrot;
+ bConstraintActuator *conact
+ = (bConstraintActuator*) bact->data;
+ /* convert settings... degrees in the ui become radians */
+ /* internally */
+ switch (conact->flag) {
+ case ACT_CONST_LOCX:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCX;
+ min = conact->minloc[0];
+ max = conact->maxloc[0];
+ break;
+ case ACT_CONST_LOCY:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCY;
+ min = conact->minloc[1];
+ max = conact->maxloc[1];
+ break;
+ case ACT_CONST_LOCZ:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCZ;
+ min = conact->minloc[2];
+ max = conact->maxloc[2];
+ break;
+ case ACT_CONST_ROTX:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTX;
+ min = MT_2_PI * conact->minrot[0] / 360.0;
+ max = MT_2_PI * conact->maxrot[0] / 360.0;
+ break;
+ case ACT_CONST_ROTY:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTY;
+ min = MT_2_PI * conact->minrot[1] / 360.0;
+ max = MT_2_PI * conact->maxrot[1] / 360.0;
+ break;
+ case ACT_CONST_ROTZ:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTZ;
+ min = MT_2_PI * conact->minrot[2] / 360.0;
+ max = MT_2_PI * conact->maxrot[2] / 360.0;
+ break;
+ default:
+ ; /* error */
+ }
+ KX_ConstraintActuator *tmpconact
+ = new KX_ConstraintActuator(gameobj,
+ conact->damp,
+ min,
+ max,
+ locrot);
+ baseact = tmpconact;
+ break;
+ }
+ case ACT_GROUP:
+ {
+ // deprecated
+ }
+ break;
+ case ACT_SCENE:
+ {
+ bSceneActuator *sceneact = (bSceneActuator *) bact->data;
+ bool scenevalid = true;
+ STR_String nextSceneName;
+
+ KX_SceneActuator* tmpsceneact;
+ int mode = KX_SceneActuator::KX_SCENE_NODEF;
+ KX_Camera *cam = NULL;
+ //KX_Scene* scene = NULL;
+ switch (sceneact->type)
+ {
+ case ACT_SCENE_RESUME:
+ case ACT_SCENE_SUSPEND:
+ case ACT_SCENE_ADD_FRONT:
+ case ACT_SCENE_ADD_BACK:
+ case ACT_SCENE_REMOVE:
+ case ACT_SCENE_SET:
+ {
+ switch (sceneact->type)
+ {
+ case ACT_SCENE_RESUME:
+ mode = KX_SceneActuator::KX_SCENE_RESUME;
+ break;
+ case ACT_SCENE_SUSPEND:
+ mode = KX_SceneActuator::KX_SCENE_SUSPEND;
+ break;
+ case ACT_SCENE_ADD_FRONT:
+ mode = KX_SceneActuator::KX_SCENE_ADD_FRONT_SCENE;
+ break;
+ case ACT_SCENE_ADD_BACK:
+ mode = KX_SceneActuator::KX_SCENE_ADD_BACK_SCENE;
+ break;
+ case ACT_SCENE_REMOVE:
+ mode = KX_SceneActuator::KX_SCENE_REMOVE_SCENE;
+ break;
+ case ACT_SCENE_SET:
+ default:
+ mode = KX_SceneActuator::KX_SCENE_SET_SCENE;
+ break;
+ };
+
+ if (sceneact->scene)
+ {
+ nextSceneName = sceneact->scene->id.name + 2; // this '2' is necessary to remove prefix 'SC'
+ }
+
+ if (!nextSceneName.Length())
+ {
+ printf ("ERROR: GameObject %s has a SceneActuator %s (SetScene) without scene\n",
+ objectname.ReadPtr(),
+ uniquename.ReadPtr());
+ scenevalid = false;
+
+ }
+ break;
+ }
+ case ACT_SCENE_CAMERA:
+ if (sceneact->camera)
+ {
+ mode = KX_SceneActuator::KX_SCENE_SET_CAMERA;
+ cam = (KX_Camera*) converter->FindGameObject(sceneact->camera);
+ }
+ else
+ {
+ // TODO:warn user
+ }
+ break;
+ case ACT_SCENE_RESTART:
+ {
+
+ mode = KX_SceneActuator::KX_SCENE_RESTART;
+ break;
+ }
+ default:
+ ; /* flag error */
+ }
+ if (scenevalid )
+ {
+ tmpsceneact = new KX_SceneActuator(gameobj,
+ mode,
+ scene,
+ ketsjiEngine,
+ nextSceneName,
+ cam);
+ baseact = tmpsceneact;
+ }
+ break;
+ }
+ case ACT_GAME:
+ {
+ bGameActuator *gameact = (bGameActuator *) bact->data;
+ KX_GameActuator* tmpgameact;
+ STR_String filename = maggiename;
+ STR_String loadinganimationname = "";
+ int mode = KX_GameActuator::KX_GAME_NODEF;
+ switch (gameact->type)
+ {
+ case ACT_GAME_LOAD:
+ {
+ mode = KX_GameActuator::KX_GAME_LOAD;
+ filename = gameact->filename;
+ loadinganimationname = gameact->loadaniname;
+ break;
+ }
+ case ACT_GAME_START:
+ {
+ mode = KX_GameActuator::KX_GAME_START;
+ filename = gameact->filename;
+ loadinganimationname = gameact->loadaniname;
+ break;
+ }
+ case ACT_GAME_RESTART:
+ {
+ mode = KX_GameActuator::KX_GAME_RESTART;
+ break;
+ }
+ case ACT_GAME_QUIT:
+ {
+ mode = KX_GameActuator::KX_GAME_QUIT;
+ break;
+ }
+ default:
+ ; /* flag error */
+ }
+ tmpgameact = new KX_GameActuator(gameobj,
+ mode,
+ filename,
+ loadinganimationname,
+ scene,
+ ketsjiEngine);
+ baseact = tmpgameact;
+
+ break;
+ }
+ case ACT_RANDOM:
+ {
+ bRandomActuator *randAct
+ = (bRandomActuator *) bact->data;
+
+ unsigned long seedArg = randAct->seed;
+ SCA_RandomActuator::KX_RANDOMACT_MODE modeArg
+ = SCA_RandomActuator::KX_RANDOMACT_NODEF;
+ SCA_RandomActuator *tmprandomact;
+ float paraArg1 = 0.0;
+ float paraArg2 = 0.0;
+
+ switch (randAct->distribution) {
+ case ACT_RANDOM_BOOL_CONST:
+ modeArg = SCA_RandomActuator::KX_RANDOMACT_BOOL_CONST;
+ paraArg1 = (float) randAct->int_arg_1;
+ break;
+ case ACT_RANDOM_BOOL_UNIFORM:
+ modeArg = SCA_RandomActuator::KX_RANDOMACT_BOOL_UNIFORM;
+ break;
+ case ACT_RANDOM_BOOL_BERNOUILLI:
+ paraArg1 = randAct->float_arg_1;
+ modeArg = SCA_RandomActuator::KX_RANDOMACT_BOOL_BERNOUILLI;
+ break;
+ case ACT_RANDOM_INT_CONST:
+ modeArg = SCA_RandomActuator::KX_RANDOMACT_INT_CONST;
+ paraArg1 = (float) randAct->int_arg_1;
+ break;
+ case ACT_RANDOM_INT_UNIFORM:
+ paraArg1 = (float) randAct->int_arg_1;
+ paraArg2 = (float) randAct->int_arg_2;
+ modeArg = SCA_RandomActuator::KX_RANDOMACT_INT_UNIFORM;
+ break;
+ case ACT_RANDOM_INT_POISSON:
+ paraArg1 = randAct->float_arg_1;
+ modeArg = SCA_RandomActuator::KX_RANDOMACT_INT_POISSON;
+ break;
+ case ACT_RANDOM_FLOAT_CONST:
+ paraArg1 = randAct->float_arg_1;
+ modeArg = SCA_RandomActuator::KX_RANDOMACT_FLOAT_CONST;
+ break;
+ case ACT_RANDOM_FLOAT_UNIFORM:
+ paraArg1 = randAct->float_arg_1;
+ paraArg2 = randAct->float_arg_2;
+ modeArg = SCA_RandomActuator::KX_RANDOMACT_FLOAT_UNIFORM;
+ break;
+ case ACT_RANDOM_FLOAT_NORMAL:
+ paraArg1 = randAct->float_arg_1;
+ paraArg2 = randAct->float_arg_2;
+ modeArg = SCA_RandomActuator::KX_RANDOMACT_FLOAT_NORMAL;
+ break;
+ case ACT_RANDOM_FLOAT_NEGATIVE_EXPONENTIAL:
+ paraArg1 = randAct->float_arg_1;
+ modeArg = SCA_RandomActuator::KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL;
+ break;
+ default:
+ ; /* error */
+ }
+ tmprandomact = new SCA_RandomActuator(gameobj,
+ seedArg,
+ modeArg,
+ paraArg1,
+ paraArg2,
+ randAct->propname);
+ baseact = tmprandomact;
+ }
+ break;
+
+ case ACT_VISIBILITY:
+ {
+ bVisibilityActuator *vis_act = (bVisibilityActuator *) bact->data;
+ KX_VisibilityActuator * tmp_vis_act = NULL;
+ bool v = ((vis_act->flag & ACT_VISIBILITY_INVISIBLE) != 0);
+
+ tmp_vis_act =
+ new KX_VisibilityActuator(gameobj,
+ !v);
+
+ baseact = tmp_vis_act;
+ }
+ break;
+
+ default:
+ ; /* generate some error */
+ }
+
+ if (baseact)
+ {
+ baseact->SetExecutePriority(executePriority++);
+ uniquename += "#ACT#";
+ uniqueint++;
+ CIntValue* uniqueval = new CIntValue(uniqueint);
+ uniquename += uniqueval->GetText();
+ uniqueval->Release();
+ baseact->SetName(STR_String(bact->name));
+ //gameobj->SetProperty(uniquename,baseact);
+ gameobj->AddActuator(baseact);
+
+ converter->RegisterGameActuator(baseact, bact);
+ }
+
+ bact = bact->next;
+ }
+}
+
diff --git a/source/gameengine/Converter/KX_ConvertActuators.h b/source/gameengine/Converter/KX_ConvertActuators.h
new file mode 100644
index 00000000000..80aa64a19ef
--- /dev/null
+++ b/source/gameengine/Converter/KX_ConvertActuators.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_CONVERTACTUATORS_H
+#define __KX_CONVERTACTUATORS_H
+
+void BL_ConvertActuators(char* maggiename,
+ struct Object* blenderobject,
+ class KX_GameObject* gameobj,
+ class SCA_LogicManager* logicmgr,
+ class KX_Scene* scene,
+ class KX_KetsjiEngine* ketsjiEngine,
+ int & executePriority,
+ int activeLayerBitInfo,
+ bool isInActiveLayer,
+ class RAS_IRenderTools* rendertools,
+ class KX_BlenderSceneConverter* converter);
+
+
+#endif //__KX_CONVERTACTUATORS_H
diff --git a/source/gameengine/Converter/KX_ConvertControllers.cpp b/source/gameengine/Converter/KX_ConvertControllers.cpp
new file mode 100644
index 00000000000..1a958744d70
--- /dev/null
+++ b/source/gameengine/Converter/KX_ConvertControllers.cpp
@@ -0,0 +1,179 @@
+/**
+ * $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 "MEM_guardedalloc.h"
+
+
+#include "KX_BlenderSceneConverter.h"
+#include "KX_ConvertControllers.h"
+#include "KX_Python.h"
+
+// Controller
+#include "SCA_ANDController.h"
+#include "SCA_ORController.h"
+#include "SCA_PythonController.h"
+#include "SCA_ExpressionController.h"
+
+#include "SCA_LogicManager.h"
+#include "KX_GameObject.h"
+#include "IntValue.h"
+
+/* This little block needed for linking to Blender... */
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
+#include "DNA_object_types.h"
+#include "DNA_controller_types.h"
+#include "DNA_text_types.h"
+
+#include "BKE_text.h"
+
+#include "BLI_blenlib.h"
+
+/* end of blender include block */
+
+
+ static void
+LinkControllerToActuators(
+ SCA_IController *game_controller,
+ bController* bcontr,
+ SCA_LogicManager* logicmgr,
+ KX_BlenderSceneConverter* converter
+) {
+ // Iterate through the actuators of the game blender
+ // controller and find the corresponding ketsji actuator.
+
+ for (int i=0;i<bcontr->totlinks;i++)
+ {
+ bActuator* bact = (bActuator*) bcontr->links[i];
+ SCA_IActuator *game_actuator = converter->FindGameActuator(bact);
+ if (game_actuator) {
+ logicmgr->RegisterToActuator(game_controller, game_actuator);
+ }
+ }
+}
+
+
+void BL_ConvertControllers(
+ struct Object* blenderobject,
+ class KX_GameObject* gameobj,
+ SCA_LogicManager* logicmgr,
+ PyObject* pythondictionary,
+ int &executePriority,
+ int activeLayerBitInfo,
+ bool isInActiveLayer,
+ KX_BlenderSceneConverter* converter
+) {
+ int uniqueint=0;
+ bController* bcontr = (bController*)blenderobject->controllers.first;
+ while (bcontr)
+ {
+ SCA_IController* gamecontroller = NULL;
+ switch(bcontr->type)
+ {
+ case CONT_LOGIC_AND:
+ {
+ gamecontroller = new SCA_ANDController(gameobj);
+ LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter);
+ break;
+ }
+ case CONT_LOGIC_OR:
+ {
+ gamecontroller = new SCA_ORController(gameobj);
+ LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter);
+ break;
+ }
+ case CONT_EXPRESSION:
+ {
+ bExpressionCont* bexpcont = (bExpressionCont*) bcontr->data;
+ STR_String expressiontext = STR_String(bexpcont->str);
+ if (expressiontext.Length() > 0)
+ {
+ gamecontroller = new SCA_ExpressionController(gameobj,expressiontext);
+ LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter);
+
+ }
+ break;
+ }
+ case CONT_PYTHON:
+ {
+
+ // we should create a Python controller here
+
+ SCA_PythonController* pyctrl = new SCA_PythonController(gameobj);
+ gamecontroller = pyctrl;
+
+ bPythonCont* pycont = (bPythonCont*) bcontr->data;
+ pyctrl->SetDictionary(pythondictionary);
+
+ if (pycont->text)
+ {
+ char *buf;
+ // this is some blender specific code
+ buf= txt_to_buf(pycont->text);
+ if (buf)
+ {
+ pyctrl->SetScriptText(STR_String(buf));
+ pyctrl->SetScriptName(pycont->text->id.name+2);
+ MEM_freeN(buf);
+ }
+
+ }
+
+ LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter);
+ break;
+ }
+ default:
+ {
+
+ }
+ }
+
+ if (gamecontroller)
+ {
+ gamecontroller->SetExecutePriority(executePriority++);
+ STR_String uniquename = bcontr->name;
+ uniquename += "#CONTR#";
+ uniqueint++;
+ CIntValue* uniqueval = new CIntValue(uniqueint);
+ uniquename += uniqueval->GetText();
+ uniqueval->Release();
+ gamecontroller->SetName(uniquename);
+ gameobj->AddController(gamecontroller);
+
+ converter->RegisterGameController(gamecontroller, bcontr);
+ }
+
+ bcontr = bcontr->next;
+ }
+
+}
diff --git a/source/gameengine/Converter/KX_ConvertControllers.h b/source/gameengine/Converter/KX_ConvertControllers.h
new file mode 100644
index 00000000000..637780a7dbd
--- /dev/null
+++ b/source/gameengine/Converter/KX_ConvertControllers.h
@@ -0,0 +1,51 @@
+/**
+ * $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_CONVERTCONTROLLERS_H
+#define __KX_CONVERTCONTROLLERS_H
+
+#include "KX_Python.h"
+
+void BL_ConvertControllers(
+ struct Object* blenderobject,
+ class KX_GameObject* gameobj,
+ class SCA_LogicManager* logicmgr,
+ PyObject* pythondictionary,
+ int & executePriority,
+ int activeLayerBitInfo,
+ bool isInActiveLayer,
+ class KX_BlenderSceneConverter* converter
+);
+
+
+
+
+#endif //__KX_CONVERTCONTROLLERS_H
diff --git a/source/gameengine/Converter/KX_ConvertProperties.cpp b/source/gameengine/Converter/KX_ConvertProperties.cpp
new file mode 100644
index 00000000000..e3cbadc5808
--- /dev/null
+++ b/source/gameengine/Converter/KX_ConvertProperties.cpp
@@ -0,0 +1,134 @@
+/**
+ * $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 "KX_ConvertProperties.h"
+
+
+/* This little block needed for linking to Blender... */
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
+#include "DNA_object_types.h"
+#include "DNA_property_types.h"
+/* end of blender include block */
+
+#include "Value.h"
+#include "VectorValue.h"
+#include "BoolValue.h"
+#include "StringValue.h"
+#include "FloatValue.h"
+#include "KX_GameObject.h"
+//#include "ListValue.h"
+#include "IntValue.h"
+#include "SCA_TimeEventManager.h"
+#include "SCA_IScene.h"
+
+
+void BL_ConvertProperties(Object* object,KX_GameObject* gameobj,SCA_TimeEventManager* timemgr,SCA_IScene* scene, bool isInActiveLayer)
+{
+
+ bProperty* prop = (bProperty*)object->prop.first;
+ CValue* propval;
+ bool show_debug_info;
+ while(prop)
+ {
+
+ propval = NULL;
+ show_debug_info = bool (prop->flag & PROP_DEBUG);
+
+ switch(prop->type) {
+ case PROP_BOOL:
+ {
+ propval = new CBoolValue((bool)(prop->data != 0));
+ gameobj->SetProperty(prop->name,propval);
+ //promp->poin= &prop->data;
+ break;
+ }
+ case PROP_INT:
+ {
+ propval = new CIntValue((int)prop->data);
+ gameobj->SetProperty(prop->name,propval);
+ break;
+ }
+ case PROP_FLOAT:
+ {
+ //prop->poin= &prop->data;
+ float floatprop = *((float*)&prop->data);
+ propval = new CFloatValue(floatprop);
+ gameobj->SetProperty(prop->name,propval);
+ }
+ break;
+ case PROP_STRING:
+ {
+ //prop->poin= callocN(MAX_PROPSTRING, "property string");
+ propval = new CStringValue((char*)prop->poin,"");
+ gameobj->SetProperty(prop->name,propval);
+ break;
+ }
+ case PROP_TIME:
+ {
+ float floatprop = *((float*)&prop->data);
+
+ CValue* timeval = new CFloatValue(floatprop);
+ // set a subproperty called 'timer' so that
+ // we can register the replica of this property
+ // at the time a game object is replicated (AddObjectActuator triggers this)
+
+ timeval->SetProperty("timer",new CBoolValue(true));
+ if (isInActiveLayer)
+ {
+ timemgr->AddTimeProperty(timeval);
+ }
+
+ propval = timeval;
+ gameobj->SetProperty(prop->name,timeval);
+
+ }
+ default:
+ {
+ // todo make an assert etc.
+ }
+ }
+
+ if (propval)
+ {
+ if (show_debug_info)
+ {
+ scene->AddDebugProperty(gameobj,STR_String(prop->name));
+ }
+ }
+
+ prop = prop->next;
+ }
+
+
+}
diff --git a/source/gameengine/Converter/KX_ConvertProperties.h b/source/gameengine/Converter/KX_ConvertProperties.h
new file mode 100644
index 00000000000..7360baa2e47
--- /dev/null
+++ b/source/gameengine/Converter/KX_ConvertProperties.h
@@ -0,0 +1,41 @@
+/**
+ * $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_CONVERTPROPERTIES
+#define __KX_CONVERTPROPERTIES
+
+void BL_ConvertProperties(struct Object* object,
+ class KX_GameObject* gameobj,
+ class SCA_TimeEventManager* timemgr,
+ class SCA_IScene* scene,
+ bool isInActiveLayer);
+
+#endif //__KX_CONVERTPROPERTIES
diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp
new file mode 100644
index 00000000000..42be5354d20
--- /dev/null
+++ b/source/gameengine/Converter/KX_ConvertSensors.cpp
@@ -0,0 +1,658 @@
+/**
+ * $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 *****
+ * Conversion of Blender data blocks to KX sensor system
+ */
+
+#ifdef WIN32
+#pragma warning (disable : 4786)
+#endif //WIN32
+
+#include "KX_BlenderSceneConverter.h"
+#include "KX_ConvertSensors.h"
+
+/* This little block needed for linking to Blender... */
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
+#include "DNA_object_types.h"
+#include "DNA_material_types.h"
+#include "DNA_sensor_types.h"
+#include "DNA_actuator_types.h" /* for SENS_ALL_KEYS ? this define is
+probably misplaced */
+/* end of blender include block */
+
+#include "RAS_IPolygonMaterial.h"
+// Sensors
+#include "KX_GameObject.h"
+#include "RAS_MeshObject.h"
+#include "SCA_KeyboardSensor.h"
+#include "SCA_MouseSensor.h"
+#include "SCA_AlwaysSensor.h"
+#include "KX_TouchSensor.h"
+#include "KX_NearSensor.h"
+#include "KX_RadarSensor.h"
+#include "KX_MouseFocusSensor.h"
+
+#include "KX_NetworkMessageSensor.h"
+
+#include "SCA_PropertySensor.h"
+#include "SCA_RandomSensor.h"
+#include "KX_RaySensor.h"
+#include "SCA_EventManager.h"
+#include "SCA_LogicManager.h"
+#include "KX_BlenderInputDevice.h"
+#include "KX_Scene.h"
+#include "IntValue.h"
+#include "KX_BlenderKeyboardDevice.h"
+#include "KX_BlenderGL.h"
+#include "RAS_ICanvas.h"
+
+#include "KX_KetsjiEngine.h"
+#include "KX_BlenderSceneConverter.h"
+
+// this map is Blender specific: a conversion between blender and ketsji enums
+std::map<int,SCA_IInputDevice::KX_EnumInputs> gReverseKeyTranslateTable;
+
+
+void BL_ConvertSensors(struct Object* blenderobject,
+ class KX_GameObject* gameobj,
+ SCA_LogicManager* logicmgr,
+ KX_Scene* kxscene,
+ SCA_IInputDevice* keydev,
+ int & executePriority,
+ int activeLayerBitInfo,
+ bool isInActiveLayer,
+ RAS_ICanvas* canvas,
+ KX_BlenderSceneConverter* converter
+ )
+{
+
+
+
+ /* The reverse table. In order to not confuse ourselves, we */
+ /* immediately convert all events that come in to KX codes. */
+ gReverseKeyTranslateTable[LEFTMOUSE ] = SCA_IInputDevice::KX_LEFTMOUSE;
+ gReverseKeyTranslateTable[MIDDLEMOUSE ] = SCA_IInputDevice::KX_MIDDLEMOUSE;
+ gReverseKeyTranslateTable[RIGHTMOUSE ] = SCA_IInputDevice::KX_RIGHTMOUSE;
+ gReverseKeyTranslateTable[MOUSEX ] = SCA_IInputDevice::KX_MOUSEX;
+ gReverseKeyTranslateTable[MOUSEY ] = SCA_IInputDevice::KX_MOUSEY;
+
+ // TIMERS
+
+ gReverseKeyTranslateTable[TIMER0 ] = SCA_IInputDevice::KX_TIMER0;
+ gReverseKeyTranslateTable[TIMER1 ] = SCA_IInputDevice::KX_TIMER1;
+ gReverseKeyTranslateTable[TIMER2 ] = SCA_IInputDevice::KX_TIMER2;
+ gReverseKeyTranslateTable[TIMER3 ] = SCA_IInputDevice::KX_TIMER3;
+
+ // SYSTEM
+
+ gReverseKeyTranslateTable[KEYBD ] = SCA_IInputDevice::KX_KEYBD;
+ gReverseKeyTranslateTable[RAWKEYBD ] = SCA_IInputDevice::KX_RAWKEYBD;
+ gReverseKeyTranslateTable[REDRAW ] = SCA_IInputDevice::KX_REDRAW;
+ gReverseKeyTranslateTable[INPUTCHANGE ] = SCA_IInputDevice::KX_INPUTCHANGE;
+ gReverseKeyTranslateTable[QFULL ] = SCA_IInputDevice::KX_QFULL;
+ gReverseKeyTranslateTable[WINFREEZE ] = SCA_IInputDevice::KX_WINFREEZE;
+ gReverseKeyTranslateTable[WINTHAW ] = SCA_IInputDevice::KX_WINTHAW;
+ gReverseKeyTranslateTable[WINCLOSE ] = SCA_IInputDevice::KX_WINCLOSE;
+ gReverseKeyTranslateTable[WINQUIT ] = SCA_IInputDevice::KX_WINQUIT;
+ gReverseKeyTranslateTable[Q_FIRSTTIME ] = SCA_IInputDevice::KX_Q_FIRSTTIME;
+
+ // standard keyboard
+
+ gReverseKeyTranslateTable[AKEY ] = SCA_IInputDevice::KX_AKEY;
+ gReverseKeyTranslateTable[BKEY ] = SCA_IInputDevice::KX_BKEY;
+ gReverseKeyTranslateTable[CKEY ] = SCA_IInputDevice::KX_CKEY;
+ gReverseKeyTranslateTable[DKEY ] = SCA_IInputDevice::KX_DKEY;
+ gReverseKeyTranslateTable[EKEY ] = SCA_IInputDevice::KX_EKEY;
+ gReverseKeyTranslateTable[FKEY ] = SCA_IInputDevice::KX_FKEY;
+ gReverseKeyTranslateTable[GKEY ] = SCA_IInputDevice::KX_GKEY;
+ gReverseKeyTranslateTable[HKEY ] = SCA_IInputDevice::KX_HKEY;
+ gReverseKeyTranslateTable[IKEY ] = SCA_IInputDevice::KX_IKEY;
+ gReverseKeyTranslateTable[JKEY ] = SCA_IInputDevice::KX_JKEY;
+ gReverseKeyTranslateTable[KKEY ] = SCA_IInputDevice::KX_KKEY;
+ gReverseKeyTranslateTable[LKEY ] = SCA_IInputDevice::KX_LKEY;
+ gReverseKeyTranslateTable[MKEY ] = SCA_IInputDevice::KX_MKEY;
+ gReverseKeyTranslateTable[NKEY ] = SCA_IInputDevice::KX_NKEY;
+ gReverseKeyTranslateTable[OKEY ] = SCA_IInputDevice::KX_OKEY;
+ gReverseKeyTranslateTable[PKEY ] = SCA_IInputDevice::KX_PKEY;
+ gReverseKeyTranslateTable[QKEY ] = SCA_IInputDevice::KX_QKEY;
+ gReverseKeyTranslateTable[RKEY ] = SCA_IInputDevice::KX_RKEY;
+ gReverseKeyTranslateTable[SKEY ] = SCA_IInputDevice::KX_SKEY;
+ gReverseKeyTranslateTable[TKEY ] = SCA_IInputDevice::KX_TKEY;
+ gReverseKeyTranslateTable[UKEY ] = SCA_IInputDevice::KX_UKEY;
+ gReverseKeyTranslateTable[VKEY ] = SCA_IInputDevice::KX_VKEY;
+ gReverseKeyTranslateTable[WKEY ] = SCA_IInputDevice::KX_WKEY;
+ gReverseKeyTranslateTable[XKEY ] = SCA_IInputDevice::KX_XKEY;
+ gReverseKeyTranslateTable[YKEY ] = SCA_IInputDevice::KX_YKEY;
+ gReverseKeyTranslateTable[ZKEY ] = SCA_IInputDevice::KX_ZKEY;
+
+ gReverseKeyTranslateTable[ZEROKEY ] = SCA_IInputDevice::KX_ZEROKEY;
+ gReverseKeyTranslateTable[ONEKEY ] = SCA_IInputDevice::KX_ONEKEY;
+ gReverseKeyTranslateTable[TWOKEY ] = SCA_IInputDevice::KX_TWOKEY;
+ gReverseKeyTranslateTable[THREEKEY ] = SCA_IInputDevice::KX_THREEKEY;
+ gReverseKeyTranslateTable[FOURKEY ] = SCA_IInputDevice::KX_FOURKEY;
+ gReverseKeyTranslateTable[FIVEKEY ] = SCA_IInputDevice::KX_FIVEKEY;
+ gReverseKeyTranslateTable[SIXKEY ] = SCA_IInputDevice::KX_SIXKEY;
+ gReverseKeyTranslateTable[SEVENKEY ] = SCA_IInputDevice::KX_SEVENKEY;
+ gReverseKeyTranslateTable[EIGHTKEY ] = SCA_IInputDevice::KX_EIGHTKEY;
+ gReverseKeyTranslateTable[NINEKEY ] = SCA_IInputDevice::KX_NINEKEY;
+
+ gReverseKeyTranslateTable[CAPSLOCKKEY ] = SCA_IInputDevice::KX_CAPSLOCKKEY;
+
+ gReverseKeyTranslateTable[LEFTCTRLKEY ] = SCA_IInputDevice::KX_LEFTCTRLKEY;
+ gReverseKeyTranslateTable[LEFTALTKEY ] = SCA_IInputDevice::KX_LEFTALTKEY;
+ gReverseKeyTranslateTable[RIGHTALTKEY ] = SCA_IInputDevice::KX_RIGHTALTKEY;
+ gReverseKeyTranslateTable[RIGHTCTRLKEY ] = SCA_IInputDevice::KX_RIGHTCTRLKEY;
+ gReverseKeyTranslateTable[RIGHTSHIFTKEY ] = SCA_IInputDevice::KX_RIGHTSHIFTKEY;
+ gReverseKeyTranslateTable[LEFTSHIFTKEY ] = SCA_IInputDevice::KX_LEFTSHIFTKEY;
+
+ gReverseKeyTranslateTable[ESCKEY ] = SCA_IInputDevice::KX_ESCKEY;
+ gReverseKeyTranslateTable[TABKEY ] = SCA_IInputDevice::KX_TABKEY;
+ gReverseKeyTranslateTable[RETKEY ] = SCA_IInputDevice::KX_RETKEY;
+ gReverseKeyTranslateTable[SPACEKEY ] = SCA_IInputDevice::KX_SPACEKEY;
+ gReverseKeyTranslateTable[LINEFEEDKEY ] = SCA_IInputDevice::KX_LINEFEEDKEY;
+ gReverseKeyTranslateTable[BACKSPACEKEY ] = SCA_IInputDevice::KX_BACKSPACEKEY;
+ gReverseKeyTranslateTable[DELKEY ] = SCA_IInputDevice::KX_DELKEY;
+ gReverseKeyTranslateTable[SEMICOLONKEY ] = SCA_IInputDevice::KX_SEMICOLONKEY;
+ gReverseKeyTranslateTable[PERIODKEY ] = SCA_IInputDevice::KX_PERIODKEY;
+ gReverseKeyTranslateTable[COMMAKEY ] = SCA_IInputDevice::KX_COMMAKEY;
+ gReverseKeyTranslateTable[QUOTEKEY ] = SCA_IInputDevice::KX_QUOTEKEY;
+ gReverseKeyTranslateTable[ACCENTGRAVEKEY ] = SCA_IInputDevice::KX_ACCENTGRAVEKEY;
+ gReverseKeyTranslateTable[MINUSKEY ] = SCA_IInputDevice::KX_MINUSKEY;
+ gReverseKeyTranslateTable[SLASHKEY ] = SCA_IInputDevice::KX_SLASHKEY;
+ gReverseKeyTranslateTable[BACKSLASHKEY ] = SCA_IInputDevice::KX_BACKSLASHKEY;
+ gReverseKeyTranslateTable[EQUALKEY ] = SCA_IInputDevice::KX_EQUALKEY;
+ gReverseKeyTranslateTable[LEFTBRACKETKEY ] = SCA_IInputDevice::KX_LEFTBRACKETKEY;
+ gReverseKeyTranslateTable[RIGHTBRACKETKEY ] = SCA_IInputDevice::KX_RIGHTBRACKETKEY;
+
+ gReverseKeyTranslateTable[LEFTARROWKEY ] = SCA_IInputDevice::KX_LEFTARROWKEY;
+ gReverseKeyTranslateTable[DOWNARROWKEY ] = SCA_IInputDevice::KX_DOWNARROWKEY;
+ gReverseKeyTranslateTable[RIGHTARROWKEY ] = SCA_IInputDevice::KX_RIGHTARROWKEY;
+ gReverseKeyTranslateTable[UPARROWKEY ] = SCA_IInputDevice::KX_UPARROWKEY;
+
+ gReverseKeyTranslateTable[PAD2 ] = SCA_IInputDevice::KX_PAD2;
+ gReverseKeyTranslateTable[PAD4 ] = SCA_IInputDevice::KX_PAD4;
+ gReverseKeyTranslateTable[PAD6 ] = SCA_IInputDevice::KX_PAD6;
+ gReverseKeyTranslateTable[PAD8 ] = SCA_IInputDevice::KX_PAD8;
+
+ gReverseKeyTranslateTable[PAD1 ] = SCA_IInputDevice::KX_PAD1;
+ gReverseKeyTranslateTable[PAD3 ] = SCA_IInputDevice::KX_PAD3;
+ gReverseKeyTranslateTable[PAD5 ] = SCA_IInputDevice::KX_PAD5;
+ gReverseKeyTranslateTable[PAD7 ] = SCA_IInputDevice::KX_PAD7;
+ gReverseKeyTranslateTable[PAD9 ] = SCA_IInputDevice::KX_PAD9;
+
+ gReverseKeyTranslateTable[PADPERIOD ] = SCA_IInputDevice::KX_PADPERIOD;
+ gReverseKeyTranslateTable[PADSLASHKEY ] = SCA_IInputDevice::KX_PADSLASHKEY;
+ gReverseKeyTranslateTable[PADASTERKEY ] = SCA_IInputDevice::KX_PADASTERKEY;
+
+ gReverseKeyTranslateTable[PAD0 ] = SCA_IInputDevice::KX_PAD0;
+ gReverseKeyTranslateTable[PADMINUS ] = SCA_IInputDevice::KX_PADMINUS;
+ gReverseKeyTranslateTable[PADENTER ] = SCA_IInputDevice::KX_PADENTER;
+ gReverseKeyTranslateTable[PADPLUSKEY ] = SCA_IInputDevice::KX_PADPLUSKEY;
+
+
+ gReverseKeyTranslateTable[F1KEY ] = SCA_IInputDevice::KX_F1KEY;
+ gReverseKeyTranslateTable[F2KEY ] = SCA_IInputDevice::KX_F2KEY;
+ gReverseKeyTranslateTable[F3KEY ] = SCA_IInputDevice::KX_F3KEY;
+ gReverseKeyTranslateTable[F4KEY ] = SCA_IInputDevice::KX_F4KEY;
+ gReverseKeyTranslateTable[F5KEY ] = SCA_IInputDevice::KX_F5KEY;
+ gReverseKeyTranslateTable[F6KEY ] = SCA_IInputDevice::KX_F6KEY;
+ gReverseKeyTranslateTable[F7KEY ] = SCA_IInputDevice::KX_F7KEY;
+ gReverseKeyTranslateTable[F8KEY ] = SCA_IInputDevice::KX_F8KEY;
+ gReverseKeyTranslateTable[F9KEY ] = SCA_IInputDevice::KX_F9KEY;
+ gReverseKeyTranslateTable[F10KEY ] = SCA_IInputDevice::KX_F10KEY;
+ gReverseKeyTranslateTable[F11KEY ] = SCA_IInputDevice::KX_F11KEY;
+ gReverseKeyTranslateTable[F12KEY ] = SCA_IInputDevice::KX_F12KEY;
+
+ gReverseKeyTranslateTable[PAUSEKEY ] = SCA_IInputDevice::KX_PAUSEKEY;
+ gReverseKeyTranslateTable[INSERTKEY ] = SCA_IInputDevice::KX_INSERTKEY;
+ gReverseKeyTranslateTable[HOMEKEY ] = SCA_IInputDevice::KX_HOMEKEY;
+ gReverseKeyTranslateTable[PAGEUPKEY ] = SCA_IInputDevice::KX_PAGEUPKEY;
+ gReverseKeyTranslateTable[PAGEDOWNKEY ] = SCA_IInputDevice::KX_PAGEDOWNKEY;
+ gReverseKeyTranslateTable[ENDKEY ] = SCA_IInputDevice::KX_ENDKEY;
+
+ int uniqueint = 0;
+ bSensor* sens = (bSensor*)blenderobject->sensors.first;
+ bool pos_pulsemode = false;
+ bool neg_pulsemode = false;
+ int frequency = 0;
+ bool invert = false;
+
+ while(sens)
+ {
+ SCA_ISensor* gamesensor=NULL;
+ /* All sensors have a pulse toggle, frequency, and invert field. */
+ /* These are extracted here, and set when the sensor is added to the */
+ /* list. */
+ pos_pulsemode = (sens->pulse & SENS_PULSE_REPEAT)!=0;
+ neg_pulsemode = (sens->pulse & SENS_NEG_PULSE_MODE)!=0;
+
+ frequency = sens->freq;
+ invert = !(sens->invert == 0);
+
+ switch (sens->type)
+ {
+ case SENS_ALWAYS:
+ {
+
+ SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::ALWAYS_EVENTMGR);
+ if (eventmgr)
+ {
+ gamesensor = new SCA_AlwaysSensor(eventmgr, gameobj);
+ }
+
+ break;
+ }
+
+ case SENS_COLLISION:
+ {
+ SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
+ if (eventmgr)
+ {
+ // collision sensor can sense both materials and properties.
+
+ bool bFindMaterial = false;
+
+ bCollisionSensor* blendertouchsensor = (bCollisionSensor*)sens->data;
+
+ bFindMaterial = (blendertouchsensor->mode
+ & SENS_COLLISION_MATERIAL);
+
+
+ STR_String touchPropOrMatName = ( bFindMaterial ?
+ blendertouchsensor->materialName:
+ (blendertouchsensor->name ? blendertouchsensor->name: ""));
+
+
+ //if (gameobj->GetSumoObject())
+ //{
+ // gamesensor = 0;
+ //new KX_TouchSensor(eventmgr,
+ //gameobj,
+ //gameobj->GetSumoObject(),
+ //bFindMaterial,
+ //touchPropOrMatName);
+ //}
+
+ }
+
+ break;
+ }
+ case SENS_TOUCH:
+ {
+ SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
+ if (eventmgr)
+ {
+ STR_String touchpropertyname;
+ bTouchSensor* blendertouchsensor = (bTouchSensor*)sens->data;
+
+ if (blendertouchsensor->ma)
+ {
+ touchpropertyname = (char*) (blendertouchsensor->ma->id.name+2);
+ }
+ bool bFindMaterial = true;
+ //if (gameobj->GetSumoObject())
+ //{
+ // gamesensor = 0;
+ //new KX_TouchSensor(eventmgr,
+ // gameobj,
+ // gameobj->GetSumoObject(),
+ // bFindMaterial,
+ // touchpropertyname);
+ //}
+ }
+ break;
+ }
+ case SENS_MESSAGE:
+ {
+ KX_NetworkEventManager* eventmgr = (KX_NetworkEventManager*)
+ logicmgr->FindEventManager(SCA_EventManager::NETWORK_EVENTMGR);
+ if (eventmgr) {
+ bMessageSensor* msgSens = (bMessageSensor*) sens->data;
+
+ /* Get our NetworkScene */
+ NG_NetworkScene *NetworkScene = kxscene->GetNetworkScene();
+ /* filter on the incoming subjects, might be empty */
+ STR_String subject = (msgSens->subject
+ ? (char*)msgSens->subject
+ : "");
+
+ gamesensor = new KX_NetworkMessageSensor(
+ eventmgr, // our eventmanager
+ NetworkScene, // our NetworkScene
+ gameobj, // the sensor controlling object
+ subject); // subject to filter on
+ }
+ break;
+ }
+ case SENS_NEAR:
+ {
+
+ SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
+ if (eventmgr)
+ {
+ STR_String nearpropertyname;
+ bNearSensor* blendernearsensor = (bNearSensor*)sens->data;
+ if (blendernearsensor->name)
+ {
+ // only objects that own this property will be taken into account
+ nearpropertyname = (char*) blendernearsensor->name;
+ }
+
+ //DT_ShapeHandle shape = DT_Sphere(0.0);
+
+ // this sumoObject is not deleted by a gameobj, so delete it ourself
+ // later (memleaks)!
+ //SM_Object* sumoObj = new SM_Object(shape,NULL,NULL,NULL);
+ //sumoObj->setMargin(blendernearsensor->dist);
+ //sumoObj->setPosition(gameobj->NodeGetWorldPosition());
+ bool bFindMaterial = false;
+ gamesensor = 0;//new KX_NearSensor(eventmgr,gameobj,blendernearsensor->dist,blendernearsensor->resetdist,bFindMaterial,nearpropertyname,kxscene);
+
+ }
+ break;
+ }
+
+
+ case SENS_KEYBOARD:
+ {
+ /* temporary input device, for converting the code for the keyboard sensor */
+
+ bKeyboardSensor* blenderkeybdsensor = (bKeyboardSensor*)sens->data;
+ SCA_KeyboardManager* eventmgr = (SCA_KeyboardManager*) logicmgr->FindEventManager(SCA_EventManager::KEYBOARD_EVENTMGR);
+ if (eventmgr)
+ {
+ gamesensor = new SCA_KeyboardSensor(eventmgr,
+ gReverseKeyTranslateTable[blenderkeybdsensor->key],
+ blenderkeybdsensor->qual,
+ blenderkeybdsensor->qual2,
+ (blenderkeybdsensor->type == SENS_ALL_KEYS),
+ blenderkeybdsensor->targetName,
+ blenderkeybdsensor->toggleName,
+ gameobj); // blenderkeybdsensor->pad);
+
+ }
+
+ break;
+ }
+ case SENS_MOUSE:
+ {
+ int keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_NODEF;
+ bool trackfocus = false;
+ bMouseSensor *bmouse = (bMouseSensor *)sens->data;
+
+ /* There are two main types of mouse sensors. If there is
+ * no focus-related behaviour requested, we can make do
+ * with a basic sensor. This cuts down memory usage and
+ * gives a slight performance gain. */
+
+ SCA_MouseManager *eventmgr
+ = (SCA_MouseManager*) logicmgr->FindEventManager(SCA_EventManager::MOUSE_EVENTMGR);
+ if (eventmgr) {
+
+ /* Determine key mode. There is at most one active mode. */
+ switch (bmouse->type) {
+ case BL_SENS_MOUSE_LEFT_BUTTON:
+ keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_LEFTBUTTON;
+ break;
+ case BL_SENS_MOUSE_MIDDLE_BUTTON:
+ keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_MIDDLEBUTTON;
+ break;
+ case BL_SENS_MOUSE_RIGHT_BUTTON:
+ keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_RIGHTBUTTON;
+ break;
+ case BL_SENS_MOUSE_MOVEMENT:
+ keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_MOVEMENT;
+ break;
+ case BL_SENS_MOUSE_MOUSEOVER:
+ trackfocus = true;
+ break;
+ default:
+ ; /* error */
+ }
+
+ /* initial mouse position */
+ int startx = canvas->GetWidth()/2;
+ int starty = canvas->GetHeight()/2;
+
+ if (!trackfocus) {
+ /* plain, simple mouse sensor */
+ gamesensor = new SCA_MouseSensor(eventmgr,
+ startx,starty,
+ keytype,
+ gameobj);
+ } else {
+ /* give us a focus-aware sensor */
+ gamesensor = new KX_MouseFocusSensor(eventmgr,
+ startx,
+ starty,
+ keytype,
+ trackfocus,
+ canvas,
+ kxscene,
+ gameobj);
+ }
+ } else {
+ // cout << "\n Could't find mouse event manager..."; - should throw an error here...
+ }
+ break;
+ }
+ case SENS_PROPERTY:
+ {
+ bPropertySensor* blenderpropsensor = (bPropertySensor*) sens->data;
+ SCA_EventManager* eventmgr
+ = logicmgr->FindEventManager(SCA_EventManager::PROPERTY_EVENTMGR);
+ if (eventmgr)
+ {
+ STR_String propname=blenderpropsensor->name;
+ STR_String propval=blenderpropsensor->value;
+ STR_String propmaxval=blenderpropsensor->maxvalue;
+
+ SCA_PropertySensor::KX_PROPSENSOR_TYPE
+ propchecktype = SCA_PropertySensor::KX_PROPSENSOR_NODEF;
+
+ /* Better do an explicit conversion here! (was implicit */
+ /* before...) */
+ switch(blenderpropsensor->type) {
+ case SENS_PROP_EQUAL:
+ propchecktype = SCA_PropertySensor::KX_PROPSENSOR_EQUAL;
+ break;
+ case SENS_PROP_NEQUAL:
+ propchecktype = SCA_PropertySensor::KX_PROPSENSOR_NOTEQUAL;
+ break;
+ case SENS_PROP_INTERVAL:
+ propchecktype = SCA_PropertySensor::KX_PROPSENSOR_INTERVAL;
+ break;
+ case SENS_PROP_CHANGED:
+ propchecktype = SCA_PropertySensor::KX_PROPSENSOR_CHANGED;
+ break;
+ case SENS_PROP_EXPRESSION:
+ propchecktype = SCA_PropertySensor::KX_PROPSENSOR_EXPRESSION;
+ /* error */
+ break;
+ default:
+ ; /* error */
+ }
+ gamesensor = new SCA_PropertySensor(eventmgr,gameobj,propname,propval,propmaxval,propchecktype);
+ }
+
+ break;
+ }
+
+ case SENS_RADAR:
+ {
+ /*
+ SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
+ if (eventmgr)
+ {
+ STR_String radarpropertyname;
+ STR_String touchpropertyname;
+ bRadarSensor* blenderradarsensor = (bRadarSensor*) sens->data;
+
+ int radaraxis = blenderradarsensor->axis;
+
+ if (blenderradarsensor->name)
+ {
+ // only objects that own this property will be taken into account
+ radarpropertyname = (char*) blenderradarsensor->name;
+ }
+
+ MT_Scalar coneheight = blenderradarsensor->range;
+
+ // janco: the angle was doubled, so should I divide the factor in 2
+ // or the blenderradarsensor->angle?
+ // nzc: the angle is the opening angle. We need to init with
+ // the axis-hull angle,so /2.0.
+ MT_Scalar factor = tan(MT_radians((blenderradarsensor->angle)/2.0));
+ //MT_Scalar coneradius = coneheight * (factor / 2);
+ MT_Scalar coneradius = coneheight * factor;
+
+ DT_ShapeHandle shape = DT_Cone(coneradius,coneheight);
+
+ // this sumoObject is not deleted by a gameobj, so delete it ourself
+ // later (memleaks)!
+ SM_Object* sumoObj = new SM_Object(shape,NULL,NULL,NULL);
+ sumoObj->setMargin(0.0);
+
+ sumoObj->setPosition(gameobj->NodeGetWorldPosition());
+ MT_Scalar smallmargin = 0.0;
+ MT_Scalar largemargin = 0.1;
+
+ bool bFindMaterial = false;
+ gamesensor = new KX_RadarSensor(
+ eventmgr,
+ gameobj,
+ coneradius,
+ coneheight,
+ radaraxis,
+ smallmargin,
+ largemargin,
+ sumoObj,
+ bFindMaterial,
+ radarpropertyname,
+ kxscene);
+
+ }
+ */
+ break;
+ }
+ case SENS_RAY:
+ {
+ bRaySensor* blenderraysensor = (bRaySensor*) sens->data;
+
+ //blenderradarsensor->angle;
+ SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::RAY_EVENTMGR);
+ if (eventmgr)
+ {
+ bool bFindMaterial = (blenderraysensor->mode & SENS_COLLISION_MATERIAL);
+
+ STR_String checkname = (bFindMaterial? blenderraysensor->matname : blenderraysensor->propname);
+
+ // don't want to get rays of length 0.0 or so
+ double distance = (blenderraysensor->range < 0.01 ? 0.01 : blenderraysensor->range );
+ int axis = blenderraysensor->axisflag;
+
+
+ gamesensor = 0;
+ /*new KX_RaySensor(eventmgr,
+ gameobj,
+ checkname,
+ bFindMaterial,
+ distance,
+ axis,
+ kxscene->GetSumoScene());
+ */
+
+ }
+ break;
+ }
+
+ case SENS_RANDOM:
+ {
+ bRandomSensor* blenderrndsensor = (bRandomSensor*) sens->data;
+ // some files didn't write randomsensor, avoid crash now for NULL ptr's
+ if (blenderrndsensor)
+ {
+ SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::RANDOM_EVENTMGR);
+ if (eventmgr)
+ {
+ int randomSeed = blenderrndsensor->seed;
+ gamesensor = new SCA_RandomSensor(eventmgr, gameobj, randomSeed);
+ }
+ }
+ break;
+ }
+ default:
+ {
+ }
+ }
+
+ if (gamesensor)
+ {
+ gamesensor->SetExecutePriority(executePriority++);
+ STR_String uniquename = sens->name;
+ uniquename += "#SENS#";
+ uniqueint++;
+ CIntValue* uniqueval = new CIntValue(uniqueint);
+ uniquename += uniqueval->GetText();
+ uniqueval->Release();
+
+ /* Conversion succeeded, so we can set the generic props here. */
+ gamesensor->SetPulseMode(pos_pulsemode,
+ neg_pulsemode,
+ frequency);
+ gamesensor->SetInvert(invert);
+ gamesensor->SetName(STR_String(sens->name));
+
+ gameobj->AddSensor(gamesensor);
+
+ // only register to manager if it's in an active layer
+
+ if (isInActiveLayer)
+ gamesensor->RegisterToManager();
+
+
+ for (int i=0;i<sens->totlinks;i++)
+ {
+ bController* linkedcont = (bController*) sens->links[i];
+ SCA_IController* gamecont = converter->FindGameController(linkedcont);
+
+ if (gamecont) {
+ logicmgr->RegisterToSensor(gamecont,gamesensor);
+ }
+ }
+
+ }
+ sens=sens->next;
+ }
+}
+
diff --git a/source/gameengine/Converter/KX_ConvertSensors.h b/source/gameengine/Converter/KX_ConvertSensors.h
new file mode 100644
index 00000000000..ed7dccf87a9
--- /dev/null
+++ b/source/gameengine/Converter/KX_ConvertSensors.h
@@ -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 *****
+ */
+#ifndef __KX_CONVERTSENSOR_H
+#define __KX_CONVERTSENSOR_H
+
+void BL_ConvertSensors(struct Object* blenderobject,
+ class KX_GameObject* gameobj,
+ class SCA_LogicManager* logicmgr,
+ class KX_Scene* kxscene,
+ class SCA_IInputDevice* keydev,
+ int & executePriority ,
+ int activeLayerBitInfo,
+ bool isInActiveLayer,
+ class RAS_ICanvas* canvas,
+ class KX_BlenderSceneConverter* converter);
+
+
+#endif //__KX_CONVERTSENSOR_H
diff --git a/source/gameengine/Converter/KX_IpoConvert.cpp b/source/gameengine/Converter/KX_IpoConvert.cpp
new file mode 100644
index 00000000000..46c9ef0ef13
--- /dev/null
+++ b/source/gameengine/Converter/KX_IpoConvert.cpp
@@ -0,0 +1,559 @@
+/**
+ * $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
+
+// don't show stl-warnings
+#pragma warning (disable:4786)
+#endif
+
+
+#include "KX_GameObject.h"
+#include "KX_IpoConvert.h"
+#include "KX_IInterpolator.h"
+#include "KX_ScalarInterpolator.h"
+
+#include "KX_BlenderScalarInterpolator.h"
+#include "KX_BlenderSceneConverter.h"
+
+
+/* This little block needed for linking to Blender... */
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
+#include "DNA_object_types.h"
+#include "DNA_ipo_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_world_types.h"
+#include "DNA_camera_types.h"
+/* end of blender include block */
+
+#include "KX_IPO_SGController.h"
+#include "KX_LightIpoSGController.h"
+#include "KX_CameraIpoSGController.h"
+#include "KX_WorldIpoController.h"
+#include "KX_ObColorIpoSGController.h"
+
+#include "SG_Node.h"
+
+static BL_InterpolatorList *GetIpoList(struct Ipo *for_ipo, KX_BlenderSceneConverter *converter) {
+ BL_InterpolatorList *ipoList= converter->FindInterpolatorList(for_ipo);
+
+ if (!ipoList) {
+ ipoList = new BL_InterpolatorList(for_ipo);
+ converter->RegisterInterpolatorList(ipoList, for_ipo);
+ }
+
+ return ipoList;
+}
+
+void BL_ConvertIpos(struct Object* blenderobject,KX_GameObject* gameobj,KX_BlenderSceneConverter *converter)
+{
+ if (blenderobject->ipo) {
+
+ KX_IpoSGController* ipocontr = new KX_IpoSGController();
+ gameobj->GetSGNode()->AddSGController(ipocontr);
+ ipocontr->SetObject(gameobj->GetSGNode());
+
+ // For ipo_as_force, we need to know which SM object and Scene the
+ // object associated with this ipo is in. Is this already known here?
+ // I think not.... then it must be done later :(
+// ipocontr->SetSumoReference(gameobj->GetSumoScene(),
+// gameobj->GetSumoObject());
+
+ ipocontr->SetGameObject(gameobj);
+
+ ipocontr->GetIPOTransform().SetPosition(
+ MT_Point3(
+ blenderobject->loc[0]+blenderobject->dloc[0],
+ blenderobject->loc[1]+blenderobject->dloc[1],
+ blenderobject->loc[2]+blenderobject->dloc[2]
+ )
+ );
+ ipocontr->GetIPOTransform().SetEulerAngles(
+ MT_Vector3(
+ blenderobject->rot[0],
+ blenderobject->rot[1],
+ blenderobject->rot[2]
+ )
+ );
+ ipocontr->GetIPOTransform().SetScaling(
+ MT_Vector3(
+ blenderobject->size[0],
+ blenderobject->size[1],
+ blenderobject->size[2]
+ )
+ );
+
+ BL_InterpolatorList *ipoList= GetIpoList(blenderobject->ipo, converter);
+
+ // For each active channel in the ipoList add an
+ // interpolator to the game object.
+
+ KX_IScalarInterpolator *ipo;
+
+ ipo = ipoList->GetScalarInterpolator(OB_LOC_X);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetPosition()[0]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyPosition(true);
+
+ }
+
+ ipo = ipoList->GetScalarInterpolator(OB_LOC_Y);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetPosition()[1]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyPosition(true);
+ }
+
+ ipo = ipoList->GetScalarInterpolator(OB_LOC_Z);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetPosition()[2]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyPosition(true);
+ }
+
+ // Master the art of cut & paste programming...
+
+ ipo = ipoList->GetScalarInterpolator(OB_DLOC_X);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetDeltaPosition()[0]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyPosition(true);
+ }
+
+ ipo = ipoList->GetScalarInterpolator(OB_DLOC_Y);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetDeltaPosition()[1]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyPosition(true);
+ }
+
+ ipo = ipoList->GetScalarInterpolator(OB_DLOC_Z);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetDeltaPosition()[2]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyPosition(true);
+ }
+
+ // Explore the finesse of reuse and slight modification
+
+ ipo = ipoList->GetScalarInterpolator(OB_ROT_X);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetEulerAngles()[0]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyOrientation(true);
+ }
+ ipo = ipoList->GetScalarInterpolator(OB_ROT_Y);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetEulerAngles()[1]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyOrientation(true);
+ }
+ ipo = ipoList->GetScalarInterpolator(OB_ROT_Z);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetEulerAngles()[2]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyOrientation(true);
+ }
+
+ // Hmmm, the need for a macro comes to mind...
+
+ ipo = ipoList->GetScalarInterpolator(OB_DROT_X);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetDeltaEulerAngles()[0]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyOrientation(true);
+ }
+ ipo = ipoList->GetScalarInterpolator(OB_DROT_Y);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetDeltaEulerAngles()[1]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyOrientation(true);
+ }
+ ipo = ipoList->GetScalarInterpolator(OB_DROT_Z);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetDeltaEulerAngles()[2]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyOrientation(true);
+ }
+
+ // Hang on, almost there...
+
+ ipo = ipoList->GetScalarInterpolator(OB_SIZE_X);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetScaling()[0]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyScaling(true);
+ }
+ ipo = ipoList->GetScalarInterpolator(OB_SIZE_Y);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetScaling()[1]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyScaling(true);
+ }
+ ipo = ipoList->GetScalarInterpolator(OB_SIZE_Z);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetScaling()[2]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyScaling(true);
+ }
+
+ // The last few...
+
+ ipo = ipoList->GetScalarInterpolator(OB_DSIZE_X);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetDeltaScaling()[0]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyScaling(true);
+ }
+ ipo = ipoList->GetScalarInterpolator(OB_DSIZE_Y);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetDeltaScaling()[1]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyScaling(true);
+ }
+ ipo = ipoList->GetScalarInterpolator(OB_DSIZE_Z);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetDeltaScaling()[2]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyScaling(true);
+ }
+
+ {
+ KX_ObColorIpoSGController* ipocontr=NULL;
+
+ ipo = ipoList->GetScalarInterpolator(OB_COL_R);
+ if (ipo)
+ {
+ if (!ipocontr)
+ {
+ ipocontr = new KX_ObColorIpoSGController();
+ gameobj->GetSGNode()->AddSGController(ipocontr);
+ ipocontr->SetObject(gameobj->GetSGNode());
+ }
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &ipocontr->m_rgba[0],
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ }
+ ipo = ipoList->GetScalarInterpolator(OB_COL_G);
+ if (ipo)
+ {
+ if (!ipocontr)
+ {
+ ipocontr = new KX_ObColorIpoSGController();
+ gameobj->GetSGNode()->AddSGController(ipocontr);
+ ipocontr->SetObject(gameobj->GetSGNode());
+ }
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &ipocontr->m_rgba[1],
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ }
+ ipo = ipoList->GetScalarInterpolator(OB_COL_B);
+ if (ipo)
+ {
+ if (!ipocontr)
+ {
+ ipocontr = new KX_ObColorIpoSGController();
+ gameobj->GetSGNode()->AddSGController(ipocontr);
+ ipocontr->SetObject(gameobj->GetSGNode());
+ }
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &ipocontr->m_rgba[2],
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ }
+ ipo = ipoList->GetScalarInterpolator(OB_COL_A);
+ if (ipo)
+ {
+ if (!ipocontr)
+ {
+ ipocontr = new KX_ObColorIpoSGController();
+ gameobj->GetSGNode()->AddSGController(ipocontr);
+ ipocontr->SetObject(gameobj->GetSGNode());
+ }
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &ipocontr->m_rgba[3],
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ }
+ }
+
+
+ }
+
+
+}
+
+void BL_ConvertLampIpos(struct Lamp* blenderlamp, KX_GameObject *lightobj,KX_BlenderSceneConverter *converter)
+{
+
+ if (blenderlamp->ipo) {
+
+ KX_LightIpoSGController* ipocontr = new KX_LightIpoSGController();
+ lightobj->GetSGNode()->AddSGController(ipocontr);
+ ipocontr->SetObject(lightobj->GetSGNode());
+
+ ipocontr->m_energy = blenderlamp->energy;
+ ipocontr->m_col_rgb[0] = blenderlamp->r;
+ ipocontr->m_col_rgb[1] = blenderlamp->g;
+ ipocontr->m_col_rgb[2] = blenderlamp->b;
+ ipocontr->m_dist = blenderlamp->dist;
+
+ BL_InterpolatorList *ipoList= GetIpoList(blenderlamp->ipo, converter);
+
+ // For each active channel in the ipoList add an
+ // interpolator to the game object.
+
+ KX_IScalarInterpolator *ipo;
+
+ ipo = ipoList->GetScalarInterpolator(LA_ENERGY);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(&ipocontr->m_energy, ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyEnergy(true);
+ }
+
+ ipo = ipoList->GetScalarInterpolator(LA_DIST);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(&ipocontr->m_dist, ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyDist(true);
+ }
+
+ ipo = ipoList->GetScalarInterpolator(LA_COL_R);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(&ipocontr->m_col_rgb[0], ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyColor(true);
+ }
+
+ ipo = ipoList->GetScalarInterpolator(LA_COL_G);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(&ipocontr->m_col_rgb[1], ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyColor(true);
+ }
+
+ ipo = ipoList->GetScalarInterpolator(LA_COL_B);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(&ipocontr->m_col_rgb[2], ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyColor(true);
+ }
+ }
+}
+
+
+
+
+void BL_ConvertCameraIpos(struct Camera* blendercamera, KX_GameObject *cameraobj,KX_BlenderSceneConverter *converter)
+{
+
+ if (blendercamera->ipo) {
+
+ KX_CameraIpoSGController* ipocontr = new KX_CameraIpoSGController();
+ cameraobj->GetSGNode()->AddSGController(ipocontr);
+ ipocontr->SetObject(cameraobj->GetSGNode());
+
+ ipocontr->m_lens = blendercamera->lens;
+ ipocontr->m_clipstart = blendercamera->clipsta;
+ ipocontr->m_clipend = blendercamera->clipend;
+
+ BL_InterpolatorList *ipoList= GetIpoList(blendercamera->ipo, converter);
+
+ // For each active channel in the ipoList add an
+ // interpolator to the game object.
+
+ KX_IScalarInterpolator *ipo;
+
+ ipo = ipoList->GetScalarInterpolator(CAM_LENS);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(&ipocontr->m_lens, ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyLens(true);
+ }
+
+ ipo = ipoList->GetScalarInterpolator(CAM_STA);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(&ipocontr->m_clipstart, ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyClipStart(true);
+ }
+
+ ipo = ipoList->GetScalarInterpolator(CAM_END);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(&ipocontr->m_clipend, ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyClipEnd(true);
+ }
+
+ }
+}
+
+
+void BL_ConvertWorldIpos(struct World* blenderworld,KX_BlenderSceneConverter *converter)
+{
+
+ if (blenderworld->ipo) {
+
+ KX_WorldIpoController* ipocontr = new KX_WorldIpoController();
+
+// Erwin, hook up the world ipo controller here
+// Gino: hook it up to what ?
+// is there a userinterface element for that ?
+// for now, we have some new python hooks to access the data, for a work-around
+
+ ipocontr->m_mist_start = blenderworld->miststa;
+ ipocontr->m_mist_dist = blenderworld->mistdist;
+ ipocontr->m_mist_rgb[0] = blenderworld->horr;
+ ipocontr->m_mist_rgb[1] = blenderworld->horg;
+ ipocontr->m_mist_rgb[2] = blenderworld->horb;
+
+ BL_InterpolatorList *ipoList= GetIpoList(blenderworld->ipo, converter);
+
+ // For each active channel in the ipoList add an
+ // interpolator to the game object.
+
+ KX_IScalarInterpolator *ipo;
+
+ ipo = ipoList->GetScalarInterpolator(WO_HOR_R);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(&ipocontr->m_mist_rgb[0], ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyMistColor(true);
+ }
+
+ ipo = ipoList->GetScalarInterpolator(WO_HOR_G);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(&ipocontr->m_mist_rgb[1], ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyMistColor(true);
+ }
+
+ ipo = ipoList->GetScalarInterpolator(WO_HOR_B);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(&ipocontr->m_mist_rgb[2], ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyMistColor(true);
+ }
+
+ ipo = ipoList->GetScalarInterpolator(WO_MISTDI);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(&ipocontr->m_mist_dist, ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyMistDist(true);
+ }
+
+ ipo = ipoList->GetScalarInterpolator(WO_MISTSTA);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(&ipocontr->m_mist_start, ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyMistStart(true);
+ }
+ }
+}
+
diff --git a/source/gameengine/Converter/KX_IpoConvert.h b/source/gameengine/Converter/KX_IpoConvert.h
new file mode 100644
index 00000000000..5686ca866eb
--- /dev/null
+++ b/source/gameengine/Converter/KX_IpoConvert.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_IPOCONVERT_H
+#define __KX_IPOCONVERT_H
+
+struct Object;
+
+void BL_ConvertIpos(struct Object* blenderobject,
+ class KX_GameObject* gameobj,
+ class KX_BlenderSceneConverter *converter
+ );
+
+void BL_ConvertLampIpos(struct Lamp* blenderlight,
+ class KX_GameObject* lightobj,
+ class KX_BlenderSceneConverter *converter);
+
+void BL_ConvertWorldIpos(struct World* blenderworld,
+ class KX_BlenderSceneConverter *converter);
+
+void BL_ConvertCameraIpos(struct Camera* blendercamera,
+ class KX_GameObject* cameraobj,
+ class KX_BlenderSceneConverter *converter);
+
+
+#endif //__KX_IPOCONVERT_H
diff --git a/source/gameengine/Converter/Makefile b/source/gameengine/Converter/Makefile
new file mode 100644
index 00000000000..8f85e4c1a58
--- /dev/null
+++ b/source/gameengine/Converter/Makefile
@@ -0,0 +1,60 @@
+#
+# $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 = blconverter
+DIR = $(OCGDIR)/gameengine/$(LIBNAME)
+
+include nan_compile.mk
+
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+CPPFLAGS += -I$(OPENGL_HEADERS)
+CPPFLAGS += -I$(NAN_STRING)/include
+CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
+CPPFLAGS += -I$(NAN_FUZZICS)/include -I$(NAN_SUMO)/include -I$(NAN_MOTO)/include
+CPPFLAGS += -I../../blender
+# these two needed because of blenkernel
+CPPFLAGS += -I../../blender/imbuf
+CPPFLAGS += -I../../blender/makesdna
+CPPFLAGS += -I../../blender/include
+CPPFLAGS += -I../../blender/blenlib
+CPPFLAGS += -I../../blender/blenkernel
+CPPFLAGS += -I../../blender/render/extern/include
+CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
+CPPFLAGS += -I../Expressions -I../Rasterizer -I../GameLogic -I../SoundSystem
+CPPFLAGS += -I../Ketsji -I../BlenderRoutines -I../SceneGraph
+CPPFLAGS += -I../../kernel/gen_system
+CPPFLAGS += -I../Rasterizer/RAS_OpenGLRasterizer
+CPPFLAGS += -I../Network -I../Ketsji/KXNetwork
+CPPFLAGS += -I../Physics/common -I../Physics/Dummy
+
diff --git a/source/gameengine/Expressions/BoolValue.cpp b/source/gameengine/Expressions/BoolValue.cpp
new file mode 100644
index 00000000000..544b760f4e9
--- /dev/null
+++ b/source/gameengine/Expressions/BoolValue.cpp
@@ -0,0 +1,213 @@
+
+// BoolValue.cpp: implementation of the CBoolValue class.
+/*
+ * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+
+
+#include "BoolValue.h"
+#include "StringValue.h"
+#include "ErrorValue.h"
+#include "VoidValue.h"
+//#include "FactoryManager.h"
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+
+CBoolValue::CBoolValue()
+/*
+pre: false
+effect: constructs a new CBoolValue
+*/
+{
+ trace("Bool constructor error");
+}
+
+
+
+CBoolValue::CBoolValue(bool inBool)
+: m_bool(inBool)
+{
+} // Constructs a new CBoolValue containing <inBool>
+
+
+
+CBoolValue::CBoolValue(bool innie,STR_String name,AllocationTYPE alloctype)
+{
+ m_bool = innie;
+ SetName(name);
+
+ if (alloctype == CValue::STACKVALUE)
+ CValue::DisableRefCount();
+}
+
+
+
+void CBoolValue::SetValue(CValue* newval)
+{
+ m_bool = (newval->GetNumber() != 0);
+ SetModified(true);
+}
+
+
+
+CValue* CBoolValue::Calc(VALUE_OPERATOR op, CValue *val)
+/*
+pre:
+ret: a new object containing the result of applying operator op to this
+object and val
+*/
+{
+ switch (op)
+ {
+ case VALUE_POS_OPERATOR:
+ case VALUE_NEG_OPERATOR:
+ {
+ return new CErrorValue (op2str(op) + GetText());
+ break;
+ }
+ case VALUE_NOT_OPERATOR:
+ {
+ return new CBoolValue (!m_bool);
+ break;
+ }
+ default:
+ {
+ return val->CalcFinal(VALUE_BOOL_TYPE, op, this);
+ break;
+ }
+ }
+}
+
+
+
+CValue* CBoolValue::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val)
+/*
+pre: the type of val is dtype
+ret: a new object containing the result of applying operator op to val and
+this object
+*/
+{
+ CValue *ret;
+
+ switch(dtype)
+ {
+ case VALUE_EMPTY_TYPE:
+ case VALUE_BOOL_TYPE:
+ {
+ switch(op)
+ {
+ case VALUE_AND_OPERATOR:
+ {
+ ret = new CBoolValue (((CBoolValue *) val)->GetBool() && m_bool);
+ break;
+ }
+ case VALUE_OR_OPERATOR:
+ {
+ ret = new CBoolValue (((CBoolValue *) val)->GetBool() || m_bool);
+ break;
+ }
+ case VALUE_EQL_OPERATOR:
+ {
+ ret = new CBoolValue (((CBoolValue *) val)->GetBool() == m_bool);
+ break;
+ }
+ case VALUE_NEQ_OPERATOR:
+ {
+ ret = new CBoolValue (((CBoolValue *) val)->GetBool() != m_bool);
+ break;
+ }
+ case VALUE_NOT_OPERATOR:
+ {
+ return new CBoolValue (!m_bool);
+ break;
+ }
+ default:
+ {
+ ret = new CErrorValue(val->GetText() + op2str(op) +
+ "[operator not allowed on booleans]");
+ break;
+ }
+ }
+ break;
+ }
+ case VALUE_STRING_TYPE:
+ {
+ switch(op)
+ {
+ case VALUE_ADD_OPERATOR:
+ {
+ ret = new CStringValue(val->GetText() + GetText(),"");
+ break;
+ }
+ default:
+ {
+ ret = new CErrorValue(val->GetText() + op2str(op) + "[Only + allowed on boolean and string]");
+ break;
+ }
+ }
+ break;
+ }
+ default:
+ ret = new CErrorValue("[type mismatch]" + op2str(op) + GetText());
+ }
+
+ return ret;
+}
+
+
+
+bool CBoolValue::GetBool()
+/*
+pre:
+ret: the bool stored in the object
+*/
+{
+ return m_bool;
+}
+
+
+
+float CBoolValue::GetNumber()
+{
+ return (float)m_bool;
+}
+
+
+
+const STR_String& CBoolValue::GetText()
+{
+ static STR_String sTrueString = STR_String("TRUE");
+ static STR_String sFalseString = STR_String("FALSE");
+
+ return m_bool ? sTrueString : sFalseString;
+}
+
+
+
+CValue* CBoolValue::GetReplica()
+{
+ CBoolValue* replica = new CBoolValue(*this);
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+PyObject* CBoolValue::ConvertValueToPython()
+{
+ return PyInt_FromLong(m_bool != 0);
+}
diff --git a/source/gameengine/Expressions/BoolValue.h b/source/gameengine/Expressions/BoolValue.h
new file mode 100644
index 00000000000..e78ff2ef4bf
--- /dev/null
+++ b/source/gameengine/Expressions/BoolValue.h
@@ -0,0 +1,51 @@
+/*
+ * BoolValue.h: interface for the CBoolValue class.
+ * $Id$
+ * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+#if !defined _BOOLVALUE_H
+#define _BOOLVALUE_H
+
+#include "Value.h"
+
+/**
+ * Smart Boolean Value class.
+ * Is used by parser when an expression tree is build containing booleans.
+ */
+
+class CBoolValue : public CPropValue
+{
+
+ //PLUGIN_DECLARE_SERIAL(CBoolValue,CValue)
+
+public:
+ CBoolValue();
+ CBoolValue(bool inBool);
+ CBoolValue(bool innie, STR_String name, AllocationTYPE alloctype = CValue::HEAPVALUE);
+
+ virtual const STR_String& GetText();
+ virtual float GetNumber();
+ bool GetBool();
+ virtual void SetValue(CValue* newval);
+
+ virtual CValue* Calc(VALUE_OPERATOR op, CValue *val);
+ virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val);
+
+ void Configure(CValue* menuvalue);
+ virtual CValue* GetReplica();
+ virtual PyObject* ConvertValueToPython();
+
+private:
+ bool m_bool;
+};
+
+#endif // !defined _BOOLVALUE_H
diff --git a/source/gameengine/Expressions/ConstExpr.cpp b/source/gameengine/Expressions/ConstExpr.cpp
new file mode 100644
index 00000000000..c8b4c311b7c
--- /dev/null
+++ b/source/gameengine/Expressions/ConstExpr.cpp
@@ -0,0 +1,132 @@
+// ConstExpr.cpp: implementation of the CConstExpr class.
+
+/*
+ * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+
+
+#include "Value.h" // for precompiled header
+
+#include "ConstExpr.h"
+#include "VectorValue.h"
+
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CConstExpr::CConstExpr()
+{
+}
+
+
+
+CConstExpr::CConstExpr(CValue* constval)
+/*
+pre:
+effect: constructs a CConstExpr cointing the value constval
+*/
+{
+ m_value = constval;
+// m_bModified=true;
+}
+
+
+
+CConstExpr::~CConstExpr()
+/*
+pre:
+effect: deletes the object
+*/
+{
+ if (m_value)
+ m_value->Release();
+}
+
+
+
+unsigned char CConstExpr::GetExpressionID()
+{
+ return CCONSTEXPRESSIONID;
+}
+
+
+
+CValue* CConstExpr::Calculate()
+/*
+pre:
+ret: a new object containing the value of the stored CValue
+*/
+{
+ return m_value->AddRef();
+}
+
+
+
+void CConstExpr::ClearModified()
+{
+ if (m_value)
+ {
+ m_value->SetModified(false);
+ m_value->SetAffected(false);
+ }
+}
+
+
+
+float CConstExpr::GetNumber()
+{
+ return -1;
+}
+
+
+
+bool CConstExpr::NeedsRecalculated()
+{
+ return m_value->IsAffected(); // IsAffected is m_bModified OR m_bAffected !!!
+}
+
+
+
+CExpression* CConstExpr::CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks)
+{
+// parent checks if child is still usefull.
+// When for example it's value it's deleted flag set
+// then release Value, and return NULL in case of constexpression
+// else return this...
+
+ assertd(m_value);
+ if (m_value->IsReleaseRequested())
+ {
+ AddRef(); //numchanges++;
+ return Release();
+ }
+ else
+ return this;
+}
+
+
+
+void CConstExpr::BroadcastOperators(VALUE_OPERATOR op)
+{
+ assertd(m_value);
+ m_value->SetColorOperator(op);
+}
+
+
+
+bool CConstExpr::MergeExpression(CExpression *otherexpr)
+{
+ assertd(false);
+ return false;
+}
diff --git a/source/gameengine/Expressions/ConstExpr.h b/source/gameengine/Expressions/ConstExpr.h
new file mode 100644
index 00000000000..4c01c142d32
--- /dev/null
+++ b/source/gameengine/Expressions/ConstExpr.h
@@ -0,0 +1,46 @@
+/*
+ * ConstExpr.h: interface for the CConstExpr class.
+ * $Id$
+ * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef __CONSTEXPR_H__
+#define __CONSTEXPR_H__
+
+#include "Expression.h"
+#include "Value.h" // Added by ClassView
+
+class CConstExpr : public CExpression
+{
+ //PLUGIN_DECLARE_SERIAL_EXPRESSION (CConstExpr,CExpression)
+public:
+ virtual bool MergeExpression(CExpression* otherexpr);
+
+ void BroadcastOperators(VALUE_OPERATOR op);
+
+ virtual unsigned char GetExpressionID();
+ CExpression* CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks);
+ //bool IsInside(float x,float y,float z,bool bBorderInclude=true);
+ bool NeedsRecalculated();
+ void ClearModified();
+ virtual float GetNumber();
+ virtual CValue* Calculate();
+ CConstExpr(CValue* constval);
+ CConstExpr();
+ virtual ~CConstExpr();
+
+
+private:
+ CValue* m_value;
+};
+
+#endif // !defined(AFX_CONSTEXPR_H__061ECFC3_BE87_11D1_A51C_00A02472FC58__INCLUDED_)
diff --git a/source/gameengine/Expressions/EXP_C-Api.cpp b/source/gameengine/Expressions/EXP_C-Api.cpp
new file mode 100644
index 00000000000..4d45fd556eb
--- /dev/null
+++ b/source/gameengine/Expressions/EXP_C-Api.cpp
@@ -0,0 +1,124 @@
+/**
+ * $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 "EXP_C-Api.h"
+#include "IntValue.h"
+#include "BoolValue.h"
+#include "StringValue.h"
+#include "ErrorValue.h"
+#include "InputParser.h"
+
+
+EXP_ValueHandle EXP_CreateInt(int innie)
+{
+ return (EXP_ValueHandle) new CIntValue(innie);
+}
+
+
+
+EXP_ValueHandle EXP_CreateBool(int innie)
+{
+ return (EXP_ValueHandle) new CBoolValue(innie!=0);
+}
+
+
+
+EXP_ValueHandle EXP_CreateString(const char* str)
+{
+
+ return (EXP_ValueHandle) new CStringValue(str,"");
+}
+
+
+
+void EXP_SetName(EXP_ValueHandle inval,const char* newname)
+{
+ ((CValue*) inval)->SetName(newname);
+}
+
+
+
+/* calculate expression from inputtext */
+EXP_ValueHandle EXP_ParseInput(const char* inputtext)
+{
+ CValue* resultval=NULL;
+ CParser parser;
+ CExpression* expr = parser.ProcessText(inputtext);
+ if (expr)
+ {
+ resultval = expr->Calculate();
+ expr->Release();
+ }
+ else
+ {
+ resultval = new CErrorValue("couldn't parsetext");
+ }
+
+ return (EXP_ValueHandle) resultval;
+}
+
+
+
+void EXP_ReleaseValue(EXP_ValueHandle inval)
+{
+ ((CValue*) inval)->Release();
+}
+
+
+
+int EXP_IsValid(EXP_ValueHandle inval)
+{
+ return !((CValue*) inval)->IsError();
+}
+
+
+
+/* assign property 'propval' to 'destinationval' */
+void EXP_SetProperty(EXP_ValueHandle destinationval,
+ const char* propname,
+ EXP_ValueHandle propval)
+{
+ ((CValue*) destinationval)->SetProperty(propname,(CValue*)propval);
+}
+
+
+
+const char* EXP_GetText(EXP_ValueHandle inval)
+{
+ return ((CValue*) inval)->GetText();
+}
+
+
+
+EXP_ValueHandle EXP_GetProperty(EXP_ValueHandle inval,const char* propname)
+{
+ return (EXP_ValueHandle) ((CValue*)inval)->GetProperty(propname);
+}
diff --git a/source/gameengine/Expressions/EXP_C-Api.h b/source/gameengine/Expressions/EXP_C-Api.h
new file mode 100644
index 00000000000..e99152294f1
--- /dev/null
+++ b/source/gameengine/Expressions/EXP_C-Api.h
@@ -0,0 +1,68 @@
+/**
+ * $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 __EXPRESSION_INCLUDE
+#define __EXPRESSION_INCLUDE
+
+
+#define EXP_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
+
+EXP_DECLARE_HANDLE(EXP_ValueHandle);
+EXP_DECLARE_HANDLE(EXP_ExpressionHandle);
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EXP_ValueHandle EXP_CreateInt(int innie);
+extern EXP_ValueHandle EXP_CreateBool(int innie);
+extern EXP_ValueHandle EXP_CreateString(const char* str);
+extern void EXP_SetName(EXP_ValueHandle,const char* newname);
+
+/* calculate expression from inputtext */
+extern EXP_ValueHandle EXP_ParseInput(const char* inputtext);
+extern void EXP_ReleaseValue(EXP_ValueHandle);
+extern int EXP_IsValid(EXP_ValueHandle);
+
+/* assign property 'propval' to 'destinationval' */
+extern void EXP_SetProperty(EXP_ValueHandle propval,EXP_ValueHandle destinationval);
+
+/* returns NULL if property doesn't exist */
+extern EXP_ValueHandle EXP_GetProperty(EXP_ValueHandle inval,const char* propname);
+
+const char* EXP_GetText(EXP_ValueHandle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //__EXPRESSION_INCLUDE
diff --git a/source/gameengine/Expressions/EmptyValue.cpp b/source/gameengine/Expressions/EmptyValue.cpp
new file mode 100644
index 00000000000..25c0b6af5d7
--- /dev/null
+++ b/source/gameengine/Expressions/EmptyValue.cpp
@@ -0,0 +1,127 @@
+
+// EmptyValue.cpp: implementation of the CEmptyValue class.
+/*
+ * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+
+
+
+#include "EmptyValue.h"
+#include "IntValue.h"
+#include "FloatValue.h"
+#include "StringValue.h"
+#include "ErrorValue.h"
+#include "ListValue.h"
+#include "VoidValue.h"
+
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CEmptyValue::CEmptyValue()
+/*
+pre:
+effect: constructs a new CEmptyValue
+*/
+{
+ SetModified(false);
+}
+
+
+
+CEmptyValue::~CEmptyValue()
+/*
+pre:
+effect: deletes the object
+*/
+{
+
+}
+
+
+
+CValue * CEmptyValue::Calc(VALUE_OPERATOR op, CValue * val)
+/*
+pre:
+ret: a new object containing the result of applying operator op to this
+object and val
+*/
+{
+ return val->CalcFinal(VALUE_EMPTY_TYPE, op, this);
+
+}
+
+
+
+CValue * CEmptyValue::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue * val)
+/*
+pre: the type of val is dtype
+ret: a new object containing the result of applying operator op to val and
+this object
+*/
+{
+ return val->AddRef();
+}
+
+
+
+float CEmptyValue::GetNumber()
+{
+ return 0;
+}
+
+
+
+CListValue* CEmptyValue::GetPolySoup()
+{
+ CListValue* soup = new CListValue();
+ //don't add any poly, while it's an empty value
+ return soup;
+}
+
+
+
+bool CEmptyValue::IsInside(CValue* testpoint,bool bBorderInclude)
+{
+ // empty space is solid, so always inside
+ return true;
+}
+
+
+
+double* CEmptyValue::GetVector3(bool bGetTransformedVec)
+{
+ assertd(false); // don't get vector from me
+ return ZeroVector();
+}
+
+
+
+static STR_String emptyString = STR_String("");
+
+
+const STR_String & CEmptyValue::GetText()
+{
+ return emptyString;
+}
+
+
+
+CValue* CEmptyValue::GetReplica()
+{
+ CEmptyValue* replica = new CEmptyValue(*this);
+ CValue::AddDataToReplica(replica);
+ return replica;
+}
+
diff --git a/source/gameengine/Expressions/EmptyValue.h b/source/gameengine/Expressions/EmptyValue.h
new file mode 100644
index 00000000000..d400cd065f5
--- /dev/null
+++ b/source/gameengine/Expressions/EmptyValue.h
@@ -0,0 +1,39 @@
+/*
+ * EmptyValue.h: interface for the CEmptyValue class.
+ * $Id$
+ * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+#if !defined _EMPTYVALUE_H
+#define _EMPTYVALUE_H
+
+#include "Value.h"
+
+class CListValue;
+
+class CEmptyValue : public CPropValue
+{
+ //PLUGIN_DECLARE_SERIAL (CEmptyValue,CValue)
+public:
+ CEmptyValue();
+ virtual ~CEmptyValue();
+
+ virtual const STR_String & GetText();
+ virtual float GetNumber();
+ CListValue* GetPolySoup();
+ virtual double* GetVector3(bool bGetTransformedVec=false);
+ bool IsInside(CValue* testpoint,bool bBorderInclude=true);
+ CValue * Calc(VALUE_OPERATOR op, CValue *val);
+ CValue * CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val);
+ virtual CValue* GetReplica();
+};
+
+#endif // !defined _EMPTYVALUE_H
diff --git a/source/gameengine/Expressions/ErrorValue.cpp b/source/gameengine/Expressions/ErrorValue.cpp
new file mode 100644
index 00000000000..fd1ba7399b3
--- /dev/null
+++ b/source/gameengine/Expressions/ErrorValue.cpp
@@ -0,0 +1,125 @@
+// ErrorValue.cpp: implementation of the CErrorValue class.
+/*
+ * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+
+
+
+
+
+#include "ErrorValue.h"
+
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CErrorValue::CErrorValue()
+/*
+pre:
+effect: constructs a new CErrorValue containing errormessage "Error"
+*/
+{
+ m_strErrorText = "Error";
+ SetError(true);
+}
+
+
+
+CErrorValue::CErrorValue(STR_String errmsg)
+/*
+pre:
+effect: constructs a new CErrorValue containing errormessage errmsg
+*/
+{
+ m_strErrorText = "[" + errmsg + "]";
+ SetError(true);
+}
+
+
+
+CErrorValue::~CErrorValue()
+/*
+pre:
+effect: deletes the object
+*/
+{
+
+}
+
+
+
+CValue* CErrorValue::Calc(VALUE_OPERATOR op, CValue *val)
+/*
+pre:
+ret: a new object containing the result of applying operator op to this
+ object and val
+*/
+{
+ CValue* errorval;
+
+ switch (op)
+ {
+ case VALUE_POS_OPERATOR:
+ case VALUE_NEG_OPERATOR:
+ case VALUE_NOT_OPERATOR:
+ {
+ errorval = new CErrorValue (op2str(op) + GetText());
+ break;
+ }
+ default:
+ {
+ errorval = val->CalcFinal(VALUE_ERROR_TYPE, op, this);
+ break;
+ }
+ }
+
+ return errorval;
+}
+
+
+
+CValue* CErrorValue::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val)
+/*
+pre: the type of val is dtype
+ret: a new object containing the result of applying operator op to val and
+ this object
+*/
+{
+ return new CErrorValue (val->GetText() + op2str(op) + GetText());
+}
+
+
+
+float CErrorValue::GetNumber()
+{
+ return -1;
+}
+
+
+
+const STR_String & CErrorValue::GetText()
+{
+ return m_strErrorText;
+}
+
+
+
+CValue* CErrorValue::GetReplica()
+{
+ // who would want a copy of an error ?
+ trace ("Error: ErrorValue::GetReplica() not implemented yet");
+ assertd(false);
+
+ return NULL;
+} \ No newline at end of file
diff --git a/source/gameengine/Expressions/ErrorValue.h b/source/gameengine/Expressions/ErrorValue.h
new file mode 100644
index 00000000000..8a4726e196d
--- /dev/null
+++ b/source/gameengine/Expressions/ErrorValue.h
@@ -0,0 +1,38 @@
+/*
+ * ErrorValue.h: interface for the CErrorValue class.
+ * $Id$
+ * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#if !defined _ERRORVALUE_H
+#define _ERRORVALUE_H
+
+#include "Value.h"
+
+class CErrorValue : public CPropValue
+{
+
+public:
+ virtual const STR_String & GetText();
+ virtual float GetNumber();
+ CErrorValue();
+ CErrorValue(STR_String errmsg);
+ virtual ~CErrorValue();
+ virtual CValue* Calc(VALUE_OPERATOR op, CValue* val);
+ virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val);
+ virtual CValue* GetReplica();
+
+private:
+ STR_String m_strErrorText;
+};
+
+#endif // !defined _ERRORVALUE_H
diff --git a/source/gameengine/Expressions/Expression.cpp b/source/gameengine/Expressions/Expression.cpp
new file mode 100644
index 00000000000..5e7950fbcf0
--- /dev/null
+++ b/source/gameengine/Expressions/Expression.cpp
@@ -0,0 +1,75 @@
+// Expression.cpp: implementation of the CExpression class.
+/*
+ * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+
+
+#include "Expression.h"
+#include "ErrorValue.h"
+//#include "FactoryManager.h"
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CExpression::CExpression()// : m_cached_calculate(NULL)
+{
+ m_refcount = 1;
+#ifdef _DEBUG
+ //gRefCountExpr++;
+#endif
+}
+
+CExpression::~CExpression()
+{
+ assert (m_refcount == 0);
+}
+
+
+
+// destuctor for CBrokenLinkInfo
+CBrokenLinkInfo::~CBrokenLinkInfo()
+{
+ if (m_pExpr && !m_bRestored)
+ m_pExpr->Release();
+}
+
+
+void CBrokenLinkInfo::RestoreLink()
+{
+
+
+ assertd(m_pExpr);
+
+ if (m_pExpr)
+ {
+ if (!m_bRestored){
+ m_bRestored=true;
+
+ }
+ if (*m_pmemExpr)
+ {
+ (*m_pmemExpr)->Release();
+ }
+ *m_pmemExpr = m_pExpr;
+
+// m_pExpr=NULL;
+ }
+}
+
+void CBrokenLinkInfo::BreakLink()
+{
+ m_bRestored=false;
+ m_pExpr->AddRef();
+}
+
diff --git a/source/gameengine/Expressions/Expression.h b/source/gameengine/Expressions/Expression.h
new file mode 100644
index 00000000000..f48ac7eb160
--- /dev/null
+++ b/source/gameengine/Expressions/Expression.h
@@ -0,0 +1,133 @@
+/*
+ * Expression.h: interface for the CExpression class.
+ * $Id$
+ * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#if !defined _EXPRESSION_H
+#define _EXPRESSION_H
+
+#include "Value.h"
+
+//extern int gRefCountExpr; // only for debugging purposes (detect mem.leaks)
+
+
+
+
+#define PLUGIN_DECLARE_SERIAL_EXPRESSION(class_name,base_class_name) \
+public: \
+ virtual base_class_name * Copy() { return new class_name; } \
+ virtual bool EdSerialize(CompressorArchive& arch,class CFactoryManager* facmgr,bool bIsStoring); \
+ virtual bool EdIdSerialize(CompressorArchive& arch,class CFactoryManager* facmgr,bool bIsStoring) \
+{ \
+ if (bIsStoring) \
+ { \
+ unsigned char exprID = GetExpressionID(); \
+ arch << exprID; \
+ } \
+ return true; \
+} \
+
+
+
+class CExpression;
+
+
+// for undo/redo system the deletion in the expressiontree can be restored by replacing broken links 'inplace'
+class CBrokenLinkInfo
+{
+ public:
+ CBrokenLinkInfo(CExpression** pmemexpr,CExpression* expr)
+ :m_pmemExpr(pmemexpr),
+ m_pExpr(expr)
+ {
+ assertd(pmemexpr);
+ m_bRestored=false;
+ };
+
+ virtual ~CBrokenLinkInfo();
+ void RestoreLink();
+ void BreakLink();
+
+
+ // members vars
+ private:
+ CExpression** m_pmemExpr;
+ CExpression* m_pExpr;
+ bool m_bRestored;
+
+};
+
+
+
+
+
+
+
+
+class CExpression
+{
+public:
+ enum {
+ COPERATOR1EXPRESSIONID = 1,
+ COPERATOR2EXPRESSIONID = 2,
+ CCONSTEXPRESSIONID = 3,
+ CIFEXPRESSIONID = 4,
+ COPERATORVAREXPRESSIONID = 5,
+ CIDENTIFIEREXPRESSIONID = 6
+ };
+
+
+protected:
+ virtual ~CExpression() = 0; //pure virtual
+public:
+ virtual bool MergeExpression(CExpression* otherexpr) = 0;
+ CExpression();
+
+
+ virtual CValue* Calculate() = 0; //pure virtual
+ virtual unsigned char GetExpressionID() = 0;
+ //virtual bool IsInside(float x,float y,float z,bool bBorderInclude=true) = 0; //pure virtual
+ virtual bool NeedsRecalculated() = 0; // another pure one
+ virtual CExpression * CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks) =0; // another pure one
+ virtual void ClearModified() = 0; // another pure one
+ //virtual CExpression * Copy() =0;
+ virtual void BroadcastOperators(VALUE_OPERATOR op) =0;
+
+ virtual CExpression * AddRef() { // please leave multiline, for debugger !!!
+
+#ifdef _DEBUG
+ //gRefCountExpr++;
+ assertd(m_refcount < 255);
+#endif
+ m_refcount++;
+ return this;
+ };
+ virtual CExpression* Release(CExpression* complicatedtrick=NULL) {
+#ifdef _DEBUG
+ //gRefCountExpr--;
+#endif
+ if (--m_refcount < 1)
+ {
+ delete this;
+ } //else
+ // return this;
+ return complicatedtrick;
+ };
+
+
+protected:
+
+ int m_refcount;
+};
+
+#endif // !defined _EXPRESSION_H
diff --git a/source/gameengine/Expressions/FloatValue.cpp b/source/gameengine/Expressions/FloatValue.cpp
new file mode 100644
index 00000000000..78185bbe163
--- /dev/null
+++ b/source/gameengine/Expressions/FloatValue.cpp
@@ -0,0 +1,316 @@
+// FloatValue.cpp: implementation of the CFloatValue class.
+/*
+ * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+
+#include "FloatValue.h"
+#include "IntValue.h"
+#include "StringValue.h"
+#include "BoolValue.h"
+#include "ErrorValue.h"
+#include "VoidValue.h"
+
+///#include "..\..\menuvalue.h"
+//#include "FactoryManager.h"
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CFloatValue::CFloatValue()
+/*
+pre: false
+effect: constructs a new CFloatValue
+*/
+{
+ m_pstrRep=NULL;
+}
+
+
+
+CFloatValue::CFloatValue(float fl)
+/*
+pre:
+effect: constructs a new CFloatValue containing value fl
+*/
+{
+ m_float = fl;
+ m_pstrRep=NULL;
+}
+
+
+
+CFloatValue::CFloatValue(float fl,STR_String name,AllocationTYPE alloctype)
+/*
+pre:
+effect: constructs a new CFloatValue containing value fl
+*/
+{
+
+ m_float = fl;
+ SetName(name);
+ if (alloctype==CValue::STACKVALUE)
+ {
+ CValue::DisableRefCount();
+
+ }
+ m_pstrRep=NULL;
+}
+
+
+
+CFloatValue::~CFloatValue()
+/*
+pre:
+effect: deletes the object
+*/
+{
+ if (m_pstrRep)
+ delete m_pstrRep;
+}
+
+
+
+CValue* CFloatValue::Calc(VALUE_OPERATOR op, CValue *val)
+/*
+pre:
+ret: a new object containing the result of applying operator op to this
+ object and val
+*/
+{
+ //return val->CalcFloat(op, this);
+ switch (op)
+ {
+ case VALUE_POS_OPERATOR:
+ return new CFloatValue (m_float);
+ break;
+ case VALUE_NEG_OPERATOR:
+ return new CFloatValue (-m_float);
+ break;
+ case VALUE_NOT_OPERATOR:
+ return new CErrorValue (op2str(op) + "only allowed on booleans");
+ break;
+ case VALUE_AND_OPERATOR:
+ case VALUE_OR_OPERATOR:
+ return new CErrorValue(val->GetText() + op2str(op) + "only allowed on booleans");
+ break;
+ default:
+ return val->CalcFinal(VALUE_FLOAT_TYPE, op, this);
+ break;
+ }
+}
+
+
+
+CValue* CFloatValue::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val)
+/*
+pre: the type of val is dtype
+ret: a new object containing the result of applying operator op to val and
+ this object
+*/
+{
+ CValue *ret;
+
+ switch(dtype)
+ {
+ case VALUE_INT_TYPE:
+ {
+ switch (op)
+ {
+ case VALUE_ADD_OPERATOR:
+ ret = new CFloatValue(((CIntValue *) val)->GetInt() + m_float);
+ break;
+ case VALUE_SUB_OPERATOR:
+ ret = new CFloatValue(((CIntValue *) val)->GetInt() - m_float);
+ break;
+ case VALUE_MUL_OPERATOR:
+ ret = new CFloatValue(((CIntValue *) val)->GetInt() * m_float);
+ break;
+ case VALUE_DIV_OPERATOR:
+ if (m_float == 0)
+ ret = new CErrorValue("Division by zero");
+ else
+ ret = new CFloatValue (((CIntValue *) val)->GetInt() / m_float);
+ break;
+ case VALUE_EQL_OPERATOR:
+ ret = new CBoolValue(((CIntValue *) val)->GetInt() == m_float);
+ break;
+ case VALUE_NEQ_OPERATOR:
+ ret = new CBoolValue(((CIntValue *) val)->GetInt() != m_float);
+ break;
+ case VALUE_GRE_OPERATOR:
+ ret = new CBoolValue(((CIntValue *) val)->GetInt() > m_float);
+ break;
+ case VALUE_LES_OPERATOR:
+ ret = new CBoolValue(((CIntValue *) val)->GetInt() < m_float);
+ break;
+ case VALUE_GEQ_OPERATOR:
+ ret = new CBoolValue(((CIntValue *) val)->GetInt() >= m_float);
+ break;
+ case VALUE_LEQ_OPERATOR:
+ ret = new CBoolValue(((CIntValue *) val)->GetInt() <= m_float);
+ break;
+ default:
+ ret = new CErrorValue("illegal operator. please send a bug report.");
+ break;
+ }
+ break;
+ }
+ case VALUE_EMPTY_TYPE:
+ case VALUE_FLOAT_TYPE:
+ {
+ switch (op)
+ {
+ case VALUE_ADD_OPERATOR:
+ ret = new CFloatValue(((CFloatValue *) val)->GetFloat() + m_float);
+ break;
+ case VALUE_SUB_OPERATOR:
+ ret = new CFloatValue(((CFloatValue *) val)->GetFloat() - m_float);
+ break;
+ case VALUE_MUL_OPERATOR:
+ ret = new CFloatValue(((CFloatValue *) val)->GetFloat() * m_float);
+ break;
+ case VALUE_DIV_OPERATOR:
+ if (m_float == 0)
+ ret = new CErrorValue("Division by zero");
+ else
+ ret = new CFloatValue (((CFloatValue *) val)->GetFloat() / m_float);
+ break;
+ case VALUE_EQL_OPERATOR:
+ ret = new CBoolValue(((CFloatValue *) val)->GetFloat() == m_float);
+ break;
+ case VALUE_NEQ_OPERATOR:
+ ret = new CBoolValue(((CFloatValue *) val)->GetFloat() != m_float);
+ break;
+ case VALUE_GRE_OPERATOR:
+ ret = new CBoolValue(((CFloatValue *) val)->GetFloat() > m_float);
+ break;
+ case VALUE_LES_OPERATOR:
+ ret = new CBoolValue(((CFloatValue *) val)->GetFloat() < m_float);
+ break;
+ case VALUE_GEQ_OPERATOR:
+ ret = new CBoolValue(((CFloatValue *) val)->GetFloat() >= m_float);
+ break;
+ case VALUE_LEQ_OPERATOR:
+ ret = new CBoolValue(((CFloatValue *) val)->GetFloat() <= m_float);
+ break;
+ case VALUE_NEG_OPERATOR:
+ ret = new CFloatValue (-m_float);
+ break;
+ case VALUE_POS_OPERATOR:
+ ret = new CFloatValue (m_float);
+ break;
+
+ default:
+ ret = new CErrorValue("illegal operator. please send a bug report.");
+ break;
+ }
+ break;
+ }
+ case VALUE_STRING_TYPE:
+ {
+ switch(op)
+ {
+ case VALUE_ADD_OPERATOR:
+ ret = new CStringValue(val->GetText() + GetText(),"");
+ break;
+ case VALUE_EQL_OPERATOR:
+ case VALUE_NEQ_OPERATOR:
+ case VALUE_GRE_OPERATOR:
+ case VALUE_LES_OPERATOR:
+ case VALUE_GEQ_OPERATOR:
+ case VALUE_LEQ_OPERATOR:
+ ret = new CErrorValue("[Cannot compare string with float]" + op2str(op) + GetText());
+ break;
+ default:
+ ret = new CErrorValue("[operator not allowed on strings]" + op2str(op) + GetText());
+ break;
+ }
+ break;
+ }
+ case VALUE_BOOL_TYPE:
+ ret = new CErrorValue("[operator not valid on boolean and float]" + op2str(op) + GetText());
+ break;
+ case VALUE_ERROR_TYPE:
+ ret = new CErrorValue(val->GetText() + op2str(op) + GetText());
+ break;
+ default:
+ ret = new CErrorValue("illegal type. contact your dealer (if any)");
+ break;
+ }
+ return ret;
+}
+
+
+
+void CFloatValue::SetFloat(float fl)
+{
+ m_float = fl;
+ SetModified(true);
+}
+
+
+
+float CFloatValue::GetFloat()
+/*
+pre:
+ret: the float stored in the object
+*/
+{
+ return m_float;
+}
+
+
+
+float CFloatValue::GetNumber()
+{
+ return m_float;
+}
+
+
+
+void CFloatValue::SetValue(CValue* newval)
+{
+ m_float = newval->GetNumber();
+ SetModified(true);
+}
+
+
+
+const STR_String & CFloatValue::GetText()
+{
+ if (!m_pstrRep)
+ m_pstrRep = new STR_String();
+
+ m_pstrRep->Format("%f",m_float);
+ return *m_pstrRep;
+}
+
+
+
+CValue* CFloatValue::GetReplica()
+{
+ CFloatValue* replica = new CFloatValue(*this);
+ replica->m_pstrRep = NULL;
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+PyObject* CFloatValue::ConvertValueToPython()
+{
+ return PyFloat_FromDouble(m_float);
+}
+
diff --git a/source/gameengine/Expressions/FloatValue.h b/source/gameengine/Expressions/FloatValue.h
new file mode 100644
index 00000000000..4dce35ebfa0
--- /dev/null
+++ b/source/gameengine/Expressions/FloatValue.h
@@ -0,0 +1,48 @@
+/*
+ * FloatValue.h: interface for the CFloatValue class.
+ * $Id$
+ * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+#if !defined _FLOATVALUE_H
+#define _FLOATVALUE_H
+
+#include "Value.h"
+
+
+class CFloatValue : public CPropValue
+{
+ //PLUGIN_DECLARE_SERIAL (CFloatValue,CValue)
+public:
+ CFloatValue();
+ CFloatValue(float fl);
+ CFloatValue(float fl,STR_String name,AllocationTYPE alloctype=CValue::HEAPVALUE);
+
+ virtual const STR_String & GetText();
+
+ void Configure(CValue* menuvalue);
+ virtual float GetNumber();
+ virtual void SetValue(CValue* newval);
+ float GetFloat();
+ void SetFloat(float fl);
+ virtual ~CFloatValue();
+ virtual CValue* GetReplica();
+ virtual CValue* Calc(VALUE_OPERATOR op, CValue *val);
+ virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val);
+ virtual PyObject* ConvertValueToPython();
+
+protected:
+ float m_float;
+ STR_String* m_pstrRep;
+
+};
+
+#endif // !defined _FLOATVALUE_H
diff --git a/source/gameengine/Expressions/IdentifierExpr.cpp b/source/gameengine/Expressions/IdentifierExpr.cpp
new file mode 100644
index 00000000000..ff517aa7636
--- /dev/null
+++ b/source/gameengine/Expressions/IdentifierExpr.cpp
@@ -0,0 +1,103 @@
+/**
+ * $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 "IdentifierExpr.h"
+
+
+CIdentifierExpr::CIdentifierExpr(const STR_String& identifier,CValue* id_context)
+:m_identifier(identifier)
+{
+ if (id_context)
+ m_idContext = id_context->AddRef();
+ else
+ m_idContext=NULL;
+}
+
+
+CIdentifierExpr::~CIdentifierExpr()
+{
+ if (m_idContext)
+ m_idContext->Release();
+}
+
+
+
+CValue* CIdentifierExpr::Calculate()
+{
+ CValue* result = NULL;
+ if (m_idContext)
+ result = m_idContext->FindIdentifier(m_identifier);
+
+ return result;
+}
+
+
+
+bool CIdentifierExpr::MergeExpression(CExpression* otherexpr)
+{
+ return false;
+}
+
+
+
+unsigned char CIdentifierExpr::GetExpressionID()
+{
+ return CIDENTIFIEREXPRESSIONID;
+}
+
+
+
+bool CIdentifierExpr::NeedsRecalculated()
+{
+ return true;
+}
+
+
+
+CExpression* CIdentifierExpr::CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks)
+{
+ assertd(false); // not implemented yet
+ return NULL;
+}
+
+
+
+void CIdentifierExpr::ClearModified()
+{
+ assertd(false); // not implemented yet
+}
+
+
+
+void CIdentifierExpr::BroadcastOperators(VALUE_OPERATOR op)
+{
+ assertd(false); // not implemented yet
+} \ No newline at end of file
diff --git a/source/gameengine/Expressions/IdentifierExpr.h b/source/gameengine/Expressions/IdentifierExpr.h
new file mode 100644
index 00000000000..dbffe7c02bc
--- /dev/null
+++ b/source/gameengine/Expressions/IdentifierExpr.h
@@ -0,0 +1,55 @@
+/**
+ * $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 __IDENTIFIER_EXPR
+#define __IDENTIFIER_EXPR
+
+#include "Expression.h"
+
+class CIdentifierExpr : public CExpression
+{
+ CValue* m_idContext;
+ STR_String m_identifier;
+public:
+ CIdentifierExpr(const STR_String& identifier,CValue* id_context);
+ virtual ~CIdentifierExpr();
+
+ virtual CValue* Calculate();
+ virtual bool MergeExpression(CExpression* otherexpr);
+ virtual unsigned char GetExpressionID();
+ virtual bool NeedsRecalculated();
+ virtual CExpression* CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks);
+ virtual void ClearModified();
+ virtual void BroadcastOperators(VALUE_OPERATOR op);
+};
+
+#endif //__IDENTIFIER_EXPR
+
diff --git a/source/gameengine/Expressions/IfExpr.cpp b/source/gameengine/Expressions/IfExpr.cpp
new file mode 100644
index 00000000000..bcb365b87cc
--- /dev/null
+++ b/source/gameengine/Expressions/IfExpr.cpp
@@ -0,0 +1,141 @@
+// IfExpr.cpp: implementation of the CIfExpr class.
+/*
+ * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#include "IfExpr.h"
+#include "EmptyValue.h"
+#include "ErrorValue.h"
+
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+
+CIfExpr::CIfExpr()
+{
+}
+
+
+
+CIfExpr::CIfExpr(CExpression *guard, CExpression *e1, CExpression *e2)
+/*
+pre:
+effect: constructs an CifExpr-object corresponding to IF(guard, e1, e2)
+*/
+{
+ m_guard = guard;
+ m_e1 = e1;
+ m_e2 = e2;
+}
+
+
+
+CIfExpr::~CIfExpr()
+/*
+pre:
+effect: dereferences the object
+*/
+{
+ if (m_guard)
+ m_guard->Release();
+
+ if (m_e1)
+ m_e1->Release();
+
+ if (m_e2)
+ m_e2->Release();
+}
+
+
+
+CValue* CIfExpr::Calculate()
+/*
+pre:
+ret: a new object containing the value of m_e1 if m_guard is a boolean TRUE
+ a new object containing the value of m_e2 if m_guard is a boolean FALSE
+ an new errorvalue if m_guard is not a boolean
+*/
+{
+ CValue *guardval;
+ guardval = m_guard->Calculate();
+ STR_String text = guardval->GetText();
+ guardval->Release();
+
+ if (text == STR_String("TRUE"))
+ {
+ return m_e1->Calculate();
+ }
+ else if (text == STR_String("FALSE"))
+ {
+ return m_e2->Calculate();
+ }
+ else
+ {
+ return new CErrorValue("Guard should be of boolean type");
+ }
+}
+
+
+
+bool CIfExpr::MergeExpression(CExpression *otherexpr)
+{
+ assertd(false);
+ return false;
+}
+
+
+
+bool CIfExpr::IsInside(float x,float y,float z,bool bBorderInclude)
+{
+ assertd(false);
+ return false;
+}
+
+
+
+bool CIfExpr::NeedsRecalculated()
+{
+ return (m_guard->NeedsRecalculated() ||
+ m_e1->NeedsRecalculated() ||
+ m_e2->NeedsRecalculated());
+}
+
+
+
+CExpression* CIfExpr::CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks)
+{
+ assertd(false);
+ return NULL;
+}
+
+
+
+void CIfExpr::ClearModified()
+{
+ assertd(false);
+}
+
+
+
+void CIfExpr::BroadcastOperators(VALUE_OPERATOR op)
+{
+ assertd(false);
+}
+
+
+
+unsigned char CIfExpr::GetExpressionID()
+{
+ return CIFEXPRESSIONID;
+} \ No newline at end of file
diff --git a/source/gameengine/Expressions/IfExpr.h b/source/gameengine/Expressions/IfExpr.h
new file mode 100644
index 00000000000..192edfe8fee
--- /dev/null
+++ b/source/gameengine/Expressions/IfExpr.h
@@ -0,0 +1,49 @@
+/*
+ * IfExpr.h: interface for the CIfExpr class.
+ * $Id$
+ * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+#if !defined(AFX_IFEXPR_H__1F691841_C5C7_11D1_A863_0000B4542BD8__INCLUDED_)
+#define AFX_IFEXPR_H__1F691841_C5C7_11D1_A863_0000B4542BD8__INCLUDED_
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+
+#include "Expression.h"
+
+class CIfExpr : public CExpression
+{
+ //PLUGIN_DECLARE_SERIAL_EXPRESSION (CIfExpr,CExpression)
+
+private:
+ CExpression *m_guard, *m_e1, *m_e2;
+
+public:
+ virtual bool MergeExpression(CExpression* otherexpr);
+ CIfExpr(CExpression *guard, CExpression *e1, CExpression *e2);
+ CIfExpr();
+
+ virtual unsigned char GetExpressionID();
+ virtual ~CIfExpr();
+ virtual CValue* Calculate();
+
+ virtual bool IsInside(float x,float y,float z,bool bBorderInclude=true);
+ virtual bool NeedsRecalculated();
+
+
+ virtual CExpression* CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks);
+ virtual void ClearModified();
+ virtual void BroadcastOperators(VALUE_OPERATOR op);
+};
+
+#endif // !defined(AFX_IFEXPR_H__1F691841_C5C7_11D1_A863_0000B4542BD8__INCLUDED_)
diff --git a/source/gameengine/Expressions/InputParser.cpp b/source/gameengine/Expressions/InputParser.cpp
new file mode 100644
index 00000000000..efb5e277737
--- /dev/null
+++ b/source/gameengine/Expressions/InputParser.cpp
@@ -0,0 +1,648 @@
+// Parser.cpp: implementation of the CParser class.
+/*
+ * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#include <stdlib.h>
+
+#include "Value.h"
+#include "InputParser.h"
+#include "ErrorValue.h"
+#include "IntValue.h"
+#include "StringValue.h"
+#include "FloatValue.h"
+#include "BoolValue.h"
+#include "EmptyValue.h"
+#include "ConstExpr.h"
+#include "Operator2Expr.h"
+#include "Operator1Expr.h"
+#include "IdentifierExpr.h"
+
+// this is disable at the moment, I expected a memleak from it, but the error-cleanup was the reason
+// well, looks we don't need it anyway, until maybe the Curved Surfaces are integrated into CSG
+// cool things like (IF(LOD==1,CCurvedValue,IF(LOD==2,CCurvedValue2)) etc...
+#include "IfExpr.h"
+
+
+#define NUM_PRIORITY 6
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CParser::CParser() : m_identifierContext(NULL)
+{
+}
+
+
+
+CParser::~CParser()
+{
+ if (m_identifierContext)
+ m_identifierContext->Release();
+}
+
+
+
+void CParser::ScanError(STR_String str)
+{
+ // sets the global variable errmsg to an errormessage with
+ // contents str, appending if it already exists
+ // AfxMessageBox("Parse Error:"+str,MB_ICONERROR);
+ if (errmsg)
+ errmsg = new COperator2Expr(VALUE_ADD_OPERATOR, errmsg, Error(str));
+ else
+ errmsg = Error(str);
+
+ sym = errorsym;
+}
+
+
+
+CExpression* CParser::Error(STR_String str)
+{
+ // makes and returns a new CConstExpr filled with an CErrorValue
+ // with string str
+ // AfxMessageBox("Error:"+str,MB_ICONERROR);
+ return new CConstExpr(new CErrorValue(str));
+}
+
+
+
+void CParser::NextCh()
+{
+ // sets the global variable ch to the next character, if it exists
+ // and increases the global variable chcount
+ chcount++;
+
+ if (chcount < text.Length())
+ ch = text[chcount];
+ else
+ ch = 0x00;
+}
+
+
+
+void CParser::TermChar(char c)
+{
+ // generates an error if the next char isn't the specified char c,
+ // otherwise, skip the char
+ if(ch == c)
+ {
+ NextCh();
+ }
+ else
+ {
+ STR_String str;
+ str.Format("Warning: %c expected\ncontinuing without it", c);
+ trace(str);
+ }
+}
+
+
+
+void CParser::DigRep()
+{
+ // changes the current character to the first character that
+ // isn't a decimal
+ while ((ch >= '0') && (ch <= '9'))
+ NextCh();
+}
+
+
+
+void CParser::CharRep()
+{
+ // changes the current character to the first character that
+ // isn't an alphanumeric character
+ while (((ch >= '0') && (ch <= '9'))
+ || ((ch >= 'a') && (ch <= 'z'))
+ || ((ch >= 'A') && (ch <= 'Z'))
+ || (ch == '.') || (ch == '_'))
+ NextCh();
+}
+
+
+
+void CParser::GrabString(int start)
+{
+ // puts part of the input string into the global variable
+ // const_as_string, from position start, to position chchount
+ const_as_string = text.Mid(start, chcount-start);
+}
+
+
+
+void CParser::NextSym()
+{
+ // sets the global variable sym to the next symbol, and
+ // if it is an operator
+ // sets the global variable opkind to the kind of operator
+ // if it is a constant
+ // sets the global variable constkind to the kind of operator
+ // if it is a reference to a cell
+ // sets the global variable cellcoord to the kind of operator
+
+ errmsg = NULL;
+ while(ch == ' ' || ch == 0x9)
+ NextCh();
+
+ switch(ch)
+ {
+ case '(':
+ sym = lbracksym; NextCh();
+ break;
+ case ')':
+ sym = rbracksym; NextCh();
+ break;
+ case ',':
+ sym = commasym; NextCh();
+ break;
+ case '+' :
+ sym = opsym; opkind = OPplus; NextCh();
+ break;
+ case '-' :
+ sym = opsym; opkind = OPminus; NextCh();
+ break;
+ case '*' :
+ sym = opsym; opkind = OPtimes; NextCh();
+ break;
+ case '/' :
+ sym = opsym; opkind = OPdivide; NextCh();
+ break;
+ case '&' :
+ sym = opsym; opkind = OPand; NextCh(); TermChar('&');
+ break;
+ case '|' :
+ sym = opsym; opkind = OPor; NextCh(); TermChar('|');
+ break;
+ case '=' :
+ sym = opsym; opkind = OPequal; NextCh(); TermChar('=');
+ break;
+ case '!' :
+ sym = opsym;
+ NextCh();
+ if (ch == '=')
+ {
+ opkind = OPunequal;
+ NextCh();
+ }
+ else
+ {
+ opkind = OPnot;
+ }
+ break;
+ case '>':
+ sym = opsym;
+ NextCh();
+ if (ch == '=')
+ {
+ opkind = OPgreaterequal;
+ NextCh();
+ }
+ else
+ {
+ opkind = OPgreater;
+ }
+ break;
+ case '<':
+ sym = opsym;
+ NextCh();
+ if (ch == '=') {
+ opkind = OPlessequal;
+ NextCh();
+ } else {
+ opkind = OPless;
+ }
+ break;
+ case '\"' : {
+ int start;
+ sym = constsym;
+ constkind = stringtype;
+ NextCh();
+ start = chcount;
+ while ((ch != '\"') && (ch != 0x0))
+ NextCh();
+ GrabString(start);
+ TermChar('\"'); // check for eol before '\"'
+ break;
+ }
+ case 0x0: sym = eolsym; break;
+ default:
+ {
+ int start;
+ start = chcount;
+ DigRep();
+ if ((start != chcount) || (ch == '.')) { // number
+ sym = constsym;
+ if (ch == '.') {
+ constkind = floattype;
+ NextCh();
+ DigRep();
+ }
+ else constkind = inttype;
+ if ((ch == 'e') || (ch == 'E')) {
+ int mark;
+ constkind = floattype;
+ NextCh();
+ if ((ch == '+') || (ch == '-')) NextCh();
+ mark = chcount;
+ DigRep();
+ if (mark == chcount) {
+ ScanError("Number expected after 'E'");
+ return;
+ }
+ }
+ GrabString(start);
+ } else if (((ch >= 'a') && (ch <= 'z'))
+ || ((ch >= 'A') && (ch <= 'Z')))
+ { // reserved word?
+ int start;
+ STR_String funstr;
+ start = chcount;
+ CharRep();
+ GrabString(start);
+ funstr = const_as_string;
+ funstr.Upper();
+ if (funstr == STR_String("SUM")) {
+ sym = sumsym;
+ }
+ else if (funstr == STR_String("NOT")) {
+ sym = opsym;
+ opkind = OPnot;
+ }
+ else if (funstr == STR_String("AND")) {
+ sym = opsym; opkind = OPand;
+ }
+ else if (funstr == STR_String("OR")) {
+ sym = opsym; opkind = OPor;
+ }
+ else if (funstr == STR_String("IF")) {
+ sym = ifsym;
+ } else if (funstr == STR_String("WHOMADE")) {
+ sym = whocodedsym;
+ } else if (funstr == STR_String("FALSE")) {
+ sym = constsym; constkind = booltype; boolvalue = false;
+ } else if (funstr == STR_String("TRUE")) {
+ sym = constsym; constkind = booltype; boolvalue = true;
+ } else {
+ sym = idsym;
+ //STR_String str;
+ //str.Format("'%s' makes no sense here", (const char*)funstr);
+ //ScanError(str);
+ }
+ } else { // unknown symbol
+ STR_String str;
+ str.Format("Unexpected character '%c'", ch);
+ NextCh();
+ ScanError(str);
+ return;
+ }
+ }
+ }
+}
+
+int CParser::MakeInt() {
+ // returns the integer representation of the value in the global
+ // variable const_as_string
+ // pre: const_as_string contains only numercal chars
+ return atoi(const_as_string);
+}
+
+STR_String CParser::Symbol2Str(int s) {
+ // returns a string representation of of symbol s,
+ // for use in Term when generating an error
+ switch(s) {
+ case errorsym: return "error";
+ case lbracksym: return "(";
+ case rbracksym: return ")";
+ case commasym: return ",";
+ case opsym: return "operator";
+ case constsym: return "constant";
+ case sumsym: return "SUM";
+ case ifsym: return "IF";
+ case whocodedsym: return "WHOMADE";
+ case eolsym: return "end of line";
+ case idsym: return "identifier";
+ default: return "unknown"; // should not happen
+ }
+}
+
+void CParser::Term(int s) {
+ // generates an error if the next symbol isn't the specified symbol s
+ // otherwise, skip the symbol
+ if(s == sym) NextSym();
+ else {
+ STR_String msg;
+ msg.Format("Warning: " + Symbol2Str(s) + " expected\ncontinuing without it");
+
+// AfxMessageBox(msg,MB_ICONERROR);
+
+ trace(msg);
+ }
+}
+
+int CParser::Priority(int optorkind) {
+ // returns the priority of an operator
+ // higher number means higher priority
+ switch(optorkind) {
+ case OPor: return 1;
+ case OPand: return 2;
+ case OPgreater:
+ case OPless:
+ case OPgreaterequal:
+ case OPlessequal:
+ case OPequal:
+ case OPunequal: return 3;
+ case OPplus:
+ case OPminus: return 4;
+ case OPtimes:
+ case OPdivide: return 5;
+ }
+ assert(false);
+ return 0; // should not happen
+}
+
+CExpression *CParser::Ex(int i) {
+ // parses an expression in the imput, starting at priority i, and
+ // returns an CExpression, containing the parsed input
+ CExpression *e1 = NULL, *e2 = NULL;
+ int opkind2;
+
+ if (i < NUM_PRIORITY) {
+ e1 = Ex(i + 1);
+ while ((sym == opsym) && (Priority(opkind) == i)) {
+ opkind2 = opkind;
+ NextSym();
+ e2 = Ex(i + 1);
+ switch(opkind2) {
+ case OPplus: e1 = new COperator2Expr(VALUE_ADD_OPERATOR,e1, e2); break;
+ case OPminus: e1 = new COperator2Expr(VALUE_SUB_OPERATOR,e1, e2); break;
+ case OPtimes: e1 = new COperator2Expr(VALUE_MUL_OPERATOR,e1, e2); break;
+ case OPdivide: e1 = new COperator2Expr(VALUE_DIV_OPERATOR,e1, e2); break;
+ case OPand: e1 = new COperator2Expr(VALUE_AND_OPERATOR,e1, e2); break;
+ case OPor: e1 = new COperator2Expr(VALUE_OR_OPERATOR,e1, e2); break;
+ case OPequal: e1 = new COperator2Expr(VALUE_EQL_OPERATOR,e1, e2); break;
+ case OPunequal: e1 = new COperator2Expr(VALUE_NEQ_OPERATOR,e1, e2); break;
+ case OPgreater: e1 = new COperator2Expr(VALUE_GRE_OPERATOR,e1, e2); break;
+ case OPless: e1 = new COperator2Expr(VALUE_LES_OPERATOR,e1, e2); break;
+ case OPgreaterequal: e1 = new COperator2Expr(VALUE_GEQ_OPERATOR,e1, e2); break;
+ case OPlessequal: e1 = new COperator2Expr(VALUE_LEQ_OPERATOR,e1, e2); break;
+ default: assert(false); break; // should not happen
+ }
+ }
+ } else if (i == NUM_PRIORITY) {
+ if ((sym == opsym)
+ && ( (opkind == OPminus) || (opkind == OPnot) || (opkind == OPplus) )
+ )
+ {
+ NextSym();
+ switch(opkind) {
+ /* +1 is also a valid number! */
+ case OPplus: e1 = new COperator1Expr(VALUE_POS_OPERATOR, Ex(NUM_PRIORITY)); break;
+ case OPminus: e1 = new COperator1Expr(VALUE_NEG_OPERATOR, Ex(NUM_PRIORITY)); break;
+ case OPnot: e1 = new COperator1Expr(VALUE_NOT_OPERATOR, Ex(NUM_PRIORITY)); break;
+ default: {
+ // should not happen
+ e1 = Error("operator +, - or ! expected");
+ }
+ }
+ }
+ else {
+ switch(sym) {
+ case constsym: {
+ switch(constkind) {
+ case booltype:
+ e1 = new CConstExpr(new CBoolValue(boolvalue));
+ break;
+ case inttype:
+ {
+ int temp;
+ temp = atoi(const_as_string);
+ e1 = new CConstExpr(new CIntValue(temp));
+ break;
+ }
+ case floattype:
+ {
+ double temp;
+ temp = atof(const_as_string);
+ e1 = new CConstExpr(new CFloatValue(temp));
+ break;
+ }
+ case stringtype:
+ e1 = new CConstExpr(new CStringValue(const_as_string,""));
+ break;
+ default :
+ assert(false);
+ break;
+ }
+ NextSym();
+ break;
+ }
+ case lbracksym:
+ NextSym();
+ e1 = Ex(1);
+ Term(rbracksym);
+ break;
+ case ifsym:
+ {
+ CExpression *e3;
+ NextSym();
+ Term(lbracksym);
+ e1 = Ex(1);
+ Term(commasym);
+ e2 = Ex(1);
+ if (sym == commasym) {
+ NextSym();
+ e3 = Ex(1);
+ } else {
+ e3 = new CConstExpr(new CEmptyValue());
+ }
+ Term(rbracksym);
+ e1 = new CIfExpr(e1, e2, e3);
+ break;
+ }
+ case idsym:
+ {
+ e1 = new CIdentifierExpr(const_as_string,m_identifierContext);
+ NextSym();
+
+ break;
+ }
+ case errorsym:
+ {
+ assert(!e1);
+ STR_String errtext="[no info]";
+ if (errmsg)
+ {
+ CValue* errmsgval = errmsg->Calculate();
+ errtext=errmsgval->GetText();
+ errmsgval->Release();
+
+ //e1 = Error(errmsg->Calculate()->GetText());//new CConstExpr(errmsg->Calculate());
+
+ if ( !(errmsg->Release()) )
+ {
+ errmsg=NULL;
+ } else {
+ // does this happen ?
+ assert ("does this happen");
+ }
+ }
+ e1 = Error(errtext);
+
+ break;
+ }
+ default:
+ NextSym();
+ //return Error("Expression expected");
+ assert(!e1);
+ e1 = Error("Expression expected");
+ }
+ }
+ }
+ return e1;
+}
+
+CExpression *CParser::Expr() {
+ // parses an expression in the imput, and
+ // returns an CExpression, containing the parsed input
+ return Ex(1);
+}
+
+CExpression* CParser::ProcessText
+(STR_String intext) {
+
+ // and parses the string in intext and returns it.
+
+
+ CExpression* expr;
+ text = intext;
+
+
+ chcount = 0;
+ if (text.Length() == 0) {
+ return NULL;
+ }
+
+ ch = text[0];
+ /*if (ch != '=') {
+ expr = new CConstExpr(new CStringValue(text));
+ *dependant = deplist;
+ return expr;
+ } else
+ */
+ // NextCh();
+ NextSym();
+ expr = Expr();
+ if (sym != eolsym) {
+ CExpression* oldexpr = expr;
+ expr = new COperator2Expr(VALUE_ADD_OPERATOR,
+ oldexpr, Error(STR_String("Extra characters after expression")));//new CConstExpr(new CErrorValue("Extra characters after expression")));
+ }
+ if (errmsg)
+ errmsg->Release();
+
+ return expr;
+}
+
+
+
+float CParser::GetFloat(STR_String txt)
+{
+ // returns parsed text into a float
+ // empty string returns -1
+
+// AfxMessageBox("parsed string="+txt);
+ CValue* val=NULL;
+ float result=-1;
+// String tmpstr;
+
+ CExpression* expr = ProcessText(txt);
+ if (expr) {
+ val = expr->Calculate();
+ result=val->GetNumber();
+
+
+
+ val->Release();
+ expr->Release();
+ }
+// tmpstr.Format("parseresult=%g",result);
+// AfxMessageBox(tmpstr);
+ return result;
+}
+
+CValue* CParser::GetValue(STR_String txt, bool bFallbackToText)
+{
+ // returns parsed text into a value,
+ // empty string returns NULL value !
+ // if bFallbackToText then unparsed stuff is put into text
+
+ CValue* result=NULL;
+ CExpression* expr = ProcessText(txt);
+ if (expr) {
+ result = expr->Calculate();
+ expr->Release();
+ }
+ if (result)
+ {
+ // if the parsed stuff lead to an errorvalue, don't return errors, just NULL
+ if (result->IsError()) {
+ result->Release();
+ result=NULL;
+ if (bFallbackToText) {
+ if (txt.Length()>0)
+ {
+ result = new CStringValue(txt,"");
+ }
+ }
+ }
+ }
+ return result;
+}
+
+void CParser::SetContext(CValue* context)
+{
+ if (m_identifierContext)
+ {
+ m_identifierContext->Release();
+ }
+ m_identifierContext = context;
+}
+
+
+
+
+PyObject* CParserPyMake(PyObject* ignored,PyObject* args)
+{
+ char* txt;
+ Py_Try(PyArg_ParseTuple(args,"s",&txt));
+ CParser parser;
+ CExpression* expr = parser.ProcessText(txt);
+ CValue* val = expr->Calculate();
+ expr->Release();
+ return val;
+}
+
+static PyMethodDef CParserMethods[] =
+{
+ { "calc", CParserPyMake , Py_NEWARGS},
+ { NULL,NULL} // Sentinel
+};
+
+extern "C" {
+ void initExpressionModule(void)
+ {
+ Py_InitModule("Expression",CParserMethods);
+ }
+}
+
diff --git a/source/gameengine/Expressions/InputParser.h b/source/gameengine/Expressions/InputParser.h
new file mode 100644
index 00000000000..43832f9c350
--- /dev/null
+++ b/source/gameengine/Expressions/InputParser.h
@@ -0,0 +1,105 @@
+/*
+ * Parser.h: interface for the CParser class.
+ * Eindhoven University of Technology 1997
+ * OOPS team (Serge vd Boom, Erwin Coumans, Tom Geelen, Wynke Stuylemeier)
+ * $Id$
+ * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+#ifndef __INPUTPARSER_H__
+#define __INPUTPARSER_H__
+
+class CParser;
+#include "Expression.h"
+
+
+class CParser
+{
+public:
+ CParser();
+ virtual ~CParser();
+
+ float GetFloat(STR_String txt);
+ CValue* GetValue(STR_String txt, bool bFallbackToText=false);
+ CExpression* ProcessText(STR_String intext);
+ void SetContext(CValue* context);
+
+private:
+ enum symbols {
+ errorsym,
+ lbracksym,
+ rbracksym,
+ cellsym,
+ commasym,
+ opsym,
+ constsym,
+ sumsym,
+ ifsym,
+ whocodedsym,
+ eolsym,
+ idsym
+ }; // all kinds of symbols
+
+ enum optype {
+ OPplus,
+ OPminus,
+ OPtimes,
+ OPdivide,
+ OPand,
+ OPor,
+ OPequal,
+ OPunequal,
+ OPgreater,
+ OPless,
+ OPgreaterequal,
+ OPlessequal,
+ OPnot
+ }; // all kinds of operators
+
+ enum consttype {
+ booltype,
+ inttype,
+ floattype,
+ stringtype
+ }; // all kinds of constants
+
+ int sym, // current symbol
+ opkind, // kind of operator, if symbol is an operator
+ constkind; // kind of operator, if symbol is a constant
+
+ char ch; // current character
+ int chcount; // index to character in input string
+ CExpression *errmsg; // contains a errormessage, if scanner error
+
+ STR_String text, // contains a copy of the original text
+ const_as_string; // string representation of the symbol, if symbol is a constant
+ bool boolvalue; // value of the boolean, if symbol is a constant of type boolean
+ CValue* m_identifierContext;// context in which identifiers are looked up
+
+
+ void ScanError(STR_String str);
+ CExpression* Error(STR_String str);
+ void NextCh();
+ void TermChar(char c);
+ void DigRep();
+ void CharRep();
+ void GrabString(int start);
+ void NextSym();
+ int MakeInt();
+ STR_String Symbol2Str(int s);
+ void Term(int s);
+ int Priority(int optor);
+ CExpression *Ex(int i);
+ CExpression *Expr();
+
+};
+
+#endif
diff --git a/source/gameengine/Expressions/IntValue.cpp b/source/gameengine/Expressions/IntValue.cpp
new file mode 100644
index 00000000000..591fe76cd48
--- /dev/null
+++ b/source/gameengine/Expressions/IntValue.cpp
@@ -0,0 +1,325 @@
+// IntValue.cpp: implementation of the CIntValue class.
+/*
+* Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+*
+* Permission to use, copy, modify, distribute and sell this software
+* and its documentation for any purpose is hereby granted without fee,
+* provided that the above copyright notice appear in all copies and
+* that both that copyright notice and this permission notice appear
+* in supporting documentation. Erwin Coumans makes no
+* representations about the suitability of this software for any
+* purpose. It is provided "as is" without express or implied warranty.
+*
+*/
+
+
+#include "IntValue.h"
+#include "ErrorValue.h"
+#include "FloatValue.h"
+#include "BoolValue.h"
+#include "StringValue.h"
+#include "VoidValue.h"
+//#include "FactoryManager.h"
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CIntValue::CIntValue()
+/*
+pre: false
+effect: constructs a new CIntValue
+*/
+{
+
+#ifdef _DEBUG_
+ m_textval = "Int illegal constructor";
+#endif
+ m_pstrRep=NULL;
+}
+
+
+
+CIntValue::CIntValue(int innie)
+/*
+pre:
+effect: constructs a new CIntValue containing int innie
+*/
+{
+ m_int = innie;
+ m_pstrRep=NULL;
+}
+
+
+
+CIntValue::CIntValue(int innie,STR_String name,AllocationTYPE alloctype)
+{
+ m_int = innie;
+ SetName(name);
+
+ if (alloctype==CValue::STACKVALUE)
+ {
+ CValue::DisableRefCount();
+ }
+ m_pstrRep=NULL;
+
+}
+
+
+
+CIntValue::~CIntValue()
+/*
+pre:
+effect: deletes the object
+*/
+{
+ if (m_pstrRep)
+ delete m_pstrRep;
+}
+
+
+
+CValue* CIntValue::Calc(VALUE_OPERATOR op, CValue *val)
+/*
+pre:
+ret: a new object containing the result of applying operator op to this
+object and val
+*/
+{
+ //return val->CalcInt(op, this);
+ switch (op) {
+ case VALUE_POS_OPERATOR:
+ return new CIntValue (m_int);
+ break;
+ case VALUE_NEG_OPERATOR:
+ return new CIntValue (-m_int);
+ break;
+ case VALUE_NOT_OPERATOR:
+ return new CErrorValue (op2str(op) + "only allowed on booleans");
+ break;
+ case VALUE_AND_OPERATOR:
+ case VALUE_OR_OPERATOR:
+ return new CErrorValue(val->GetText() + op2str(op) + "only allowed on booleans");
+ break;
+ default:
+ return val->CalcFinal(VALUE_INT_TYPE, op, this);
+ break;
+ }
+}
+
+
+
+CValue* CIntValue::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val)
+/*
+pre: the type of val is dtype
+ret: a new object containing the result of applying operator op to val and
+this object
+*/
+{
+ CValue *ret;
+
+ switch(dtype) {
+ case VALUE_EMPTY_TYPE:
+ case VALUE_INT_TYPE:
+ {
+ switch (op) {
+ case VALUE_ADD_OPERATOR:
+ ret = new CIntValue (((CIntValue *) val)->GetInt() + m_int);
+ break;
+ case VALUE_SUB_OPERATOR:
+ ret = new CIntValue (((CIntValue *) val)->GetInt() - m_int);
+ break;
+ case VALUE_MUL_OPERATOR:
+ ret = new CIntValue (((CIntValue *) val)->GetInt() * m_int);
+ break;
+ case VALUE_DIV_OPERATOR:
+ if (m_int == 0)
+ {
+ if (val->GetNumber() == 0)
+ {
+ ret = new CErrorValue("Not a Number");
+ } else
+ {
+ ret = new CErrorValue("Division by zero");
+ }
+ }
+ else
+ ret = new CIntValue (((CIntValue *) val)->GetInt() / m_int);
+ break;
+ case VALUE_EQL_OPERATOR:
+ ret = new CBoolValue(((CIntValue *) val)->GetInt() == m_int);
+ break;
+ case VALUE_NEQ_OPERATOR:
+ ret = new CBoolValue(((CIntValue *) val)->GetInt() != m_int);
+ break;
+ case VALUE_GRE_OPERATOR:
+ ret = new CBoolValue(((CIntValue *) val)->GetInt() > m_int);
+ break;
+ case VALUE_LES_OPERATOR:
+ ret = new CBoolValue(((CIntValue *) val)->GetInt() < m_int);
+ break;
+ case VALUE_GEQ_OPERATOR:
+ ret = new CBoolValue(((CIntValue *) val)->GetInt() >= m_int);
+ break;
+ case VALUE_LEQ_OPERATOR:
+ ret = new CBoolValue(((CIntValue *) val)->GetInt() <= m_int);
+ break;
+ case VALUE_NEG_OPERATOR:
+ ret = new CIntValue (-m_int);
+ break;
+ case VALUE_POS_OPERATOR:
+ ret = new CIntValue (m_int);
+ break;
+ default:
+ ret = new CErrorValue("illegal operator. please send a bug report.");
+ break;
+ }
+ break;
+ }
+ case VALUE_FLOAT_TYPE:
+ {
+ switch (op) {
+ case VALUE_ADD_OPERATOR:
+ ret = new CFloatValue (((CFloatValue *) val)->GetFloat() + m_int);
+ break;
+ case VALUE_SUB_OPERATOR:
+ ret = new CFloatValue (((CFloatValue *) val)->GetFloat() - m_int);
+ break;
+ case VALUE_MUL_OPERATOR:
+ ret = new CFloatValue (((CFloatValue *) val)->GetFloat() * m_int);
+ break;
+ case VALUE_DIV_OPERATOR:
+ if (m_int == 0)
+ ret = new CErrorValue("Division by zero");
+ else
+ ret = new CFloatValue (((CFloatValue *) val)->GetFloat() / m_int);
+ break;
+ case VALUE_EQL_OPERATOR:
+ ret = new CBoolValue(((CFloatValue *) val)->GetFloat() == m_int);
+ break;
+ case VALUE_NEQ_OPERATOR:
+ ret = new CBoolValue(((CFloatValue *) val)->GetFloat() != m_int);
+ break;
+ case VALUE_GRE_OPERATOR:
+ ret = new CBoolValue(((CFloatValue *) val)->GetFloat() > m_int);
+ break;
+ case VALUE_LES_OPERATOR:
+ ret = new CBoolValue(((CFloatValue *) val)->GetFloat() < m_int);
+ break;
+ case VALUE_GEQ_OPERATOR:
+ ret = new CBoolValue(((CFloatValue *) val)->GetFloat() >= m_int);
+ break;
+ case VALUE_LEQ_OPERATOR:
+ ret = new CBoolValue(((CFloatValue *) val)->GetFloat() <= m_int);
+ break;
+ default:
+ ret = new CErrorValue("illegal operator. please send a bug report.");
+ break;
+ }
+ break;
+ }
+ case VALUE_STRING_TYPE:
+ {
+ switch(op) {
+ case VALUE_ADD_OPERATOR:
+ ret = new CStringValue(val->GetText() + GetText(),"");
+ break;
+ case VALUE_EQL_OPERATOR:
+ case VALUE_NEQ_OPERATOR:
+ case VALUE_GRE_OPERATOR:
+ case VALUE_LES_OPERATOR:
+ case VALUE_GEQ_OPERATOR:
+ case VALUE_LEQ_OPERATOR:
+ ret = new CErrorValue("[Cannot compare string with integer]" + op2str(op) + GetText());
+ break;
+ default:
+ ret = new CErrorValue("[operator not allowed on strings]" + op2str(op) + GetText());
+ break;
+ }
+ break;
+ }
+ case VALUE_BOOL_TYPE:
+ ret = new CErrorValue("[operator not valid on boolean and integer]" + op2str(op) + GetText());
+ break;
+ /*
+ case VALUE_EMPTY_TYPE:
+ {
+ switch(op) {
+
+ case VALUE_ADD_OPERATOR:
+ ret = new CIntValue (m_int);
+ break;
+ case VALUE_SUB_OPERATOR:
+ ret = new CIntValue (-m_int);
+ break;
+ default:
+ {
+ ret = new CErrorValue(op2str(op) + GetText());
+ }
+ }
+ break;
+ }
+ */
+ case VALUE_ERROR_TYPE:
+ ret = new CErrorValue(val->GetText() + op2str(op) + GetText());
+ break;
+ default:
+ ret = new CErrorValue("illegal type. contact your dealer (if any)");
+ break;
+ }
+ return ret;
+}
+
+
+
+int CIntValue::GetInt()
+/*
+pre:
+ret: the int stored in the object
+*/
+{
+ return m_int;
+}
+
+
+
+float CIntValue::GetNumber()
+{
+ return (float) m_int;
+}
+
+
+
+const STR_String & CIntValue::GetText()
+{
+ if (!m_pstrRep)
+ m_pstrRep=new STR_String();
+ m_pstrRep->Format("%d",m_int);
+
+ return *m_pstrRep;
+}
+
+
+
+CValue* CIntValue::GetReplica() {
+ CIntValue* replica = new CIntValue(*this);
+ CValue::AddDataToReplica(replica);
+ replica->m_pstrRep = NULL;
+
+ return replica;
+}
+
+
+
+void CIntValue::SetValue(CValue* newval)
+{
+ m_int = (int)newval->GetNumber();
+ SetModified(true);
+}
+
+
+
+PyObject* CIntValue::ConvertValueToPython()
+{
+ return PyInt_FromLong(m_int);
+} \ No newline at end of file
diff --git a/source/gameengine/Expressions/IntValue.h b/source/gameengine/Expressions/IntValue.h
new file mode 100644
index 00000000000..8174c863895
--- /dev/null
+++ b/source/gameengine/Expressions/IntValue.h
@@ -0,0 +1,60 @@
+/*
+ * IntValue.h: interface for the CIntValue class.
+ * $Id$
+ * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+#if !defined _INTVALUE_H
+#define _INTVALUE_H
+
+
+#include "Value.h"
+
+
+class CIntValue : public CPropValue
+{
+ //PLUGIN_DECLARE_SERIAL (CIntValue,CValue)
+
+public:
+ virtual const STR_String& GetText();
+ virtual float GetNumber();
+
+ int GetInt();
+ CIntValue();
+ CIntValue(int innie);
+ CIntValue(int innie,
+ STR_String name,
+ AllocationTYPE alloctype=CValue::HEAPVALUE);
+
+ virtual CValue* Calc(VALUE_OPERATOR op,
+ CValue *val);
+
+ virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype,
+ VALUE_OPERATOR op,
+ CValue *val);
+
+ virtual void SetValue(CValue* newval);
+
+ void Configure(CValue* menuvalue);
+ void AddConfigurationData(CValue* menuvalue);
+ virtual CValue* GetReplica();
+ virtual PyObject* ConvertValueToPython();
+
+protected:
+ virtual ~CIntValue();
+
+private:
+ int m_int;
+ STR_String* m_pstrRep;
+
+};
+
+#endif // !defined _INTVALUE_H
diff --git a/source/gameengine/Expressions/KX_HashedPtr.cpp b/source/gameengine/Expressions/KX_HashedPtr.cpp
new file mode 100644
index 00000000000..7d573ebc37d
--- /dev/null
+++ b/source/gameengine/Expressions/KX_HashedPtr.cpp
@@ -0,0 +1,58 @@
+/**
+ * $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 "KX_HashedPtr.h"
+
+unsigned int KX_Hash(unsigned int inDWord)
+{
+ unsigned int key = inDWord;
+ key += ~(key << 16);
+ key ^= (key >> 5);
+ key += (key << 3);
+ key ^= (key >> 13);
+ key += ~(key << 9);
+ key ^= (key >> 17);
+ return key;
+};
+
+
+
+CHashedPtr::CHashedPtr(void* val) : m_valptr(val)
+{
+}
+
+
+
+unsigned int CHashedPtr::hash() const
+{
+ return KX_Hash((unsigned int) m_valptr);
+}
diff --git a/source/gameengine/Expressions/KX_HashedPtr.h b/source/gameengine/Expressions/KX_HashedPtr.h
new file mode 100644
index 00000000000..eccd23991bc
--- /dev/null
+++ b/source/gameengine/Expressions/KX_HashedPtr.h
@@ -0,0 +1,53 @@
+/**
+ * $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_HASHEDPTR
+#define __KX_HASHEDPTR
+
+unsigned int KX_Hash(unsigned int inDWord);
+
+
+class CHashedPtr
+{
+ void* m_valptr;
+
+public:
+ CHashedPtr(void* val);
+
+ unsigned int hash() const;
+
+ inline friend bool operator ==( const CHashedPtr & rhs,const CHashedPtr & lhs)
+ {
+ return rhs.m_valptr == lhs.m_valptr;
+ }
+};
+
+#endif //__KX_HASHEDPTR
diff --git a/source/gameengine/Expressions/ListValue.cpp b/source/gameengine/Expressions/ListValue.cpp
new file mode 100644
index 00000000000..25723350f36
--- /dev/null
+++ b/source/gameengine/Expressions/ListValue.cpp
@@ -0,0 +1,536 @@
+// ListValue.cpp: implementation of the CListValue class.
+//
+//////////////////////////////////////////////////////////////////////
+/*
+ * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+
+#include "ListValue.h"
+#include "StringValue.h"
+#include "VoidValue.h"
+#include <algorithm>
+
+int listvalue_bufferlen(PyObject* list)
+{
+ return ( ((CListValue*)list)->GetCount());
+}
+
+
+
+PyObject* listvalue_buffer_item(PyObject* list,int index)
+{
+ if (index >= 0 && index < ((CListValue*) list)->GetCount())
+ {
+ PyObject* pyobj = ((CListValue*) list)->GetValue(index)->ConvertValueToPython();
+ if (pyobj)
+ return pyobj;
+ else
+ return ((CListValue*) list)->GetValue(index)->AddRef();
+
+ }
+ Py_Error(PyExc_IndexError, "Python ListIndex out of range");
+ return NULL;
+}
+
+
+
+/* just slice it into a python list... */
+PyObject* listvalue_buffer_slice(PyObject* list,int ilow, int ihigh)
+{
+ int i, j;
+ PyListObject *newlist;
+
+ if (ilow < 0) ilow = 0;
+
+ int n = ((CListValue*) list)->GetCount();
+
+ if (ihigh >= n)
+ ihigh = n;
+ if (ihigh < ilow)
+ ihigh = ilow;
+
+ newlist = (PyListObject *) PyList_New(ihigh - ilow);
+ if (!newlist)
+ return NULL;
+
+ for (i = ilow, j = 0; i < ihigh; i++, j++)
+ {
+ PyObject* pyobj = ((CListValue*) list)->GetValue(i)->ConvertValueToPython();
+ if (!pyobj)
+ pyobj = ((CListValue*) list)->GetValue(i)->AddRef();
+ newlist->ob_item[j] = pyobj;
+ }
+ return (PyObject *) newlist;
+}
+
+
+
+static PyObject *
+listvalue_buffer_concat(PyObject * self, PyObject * other)
+{
+ // for now, we support CListValue concatenated with items
+ // and CListValue concatenated to Python Lists
+ // and CListValue concatenated with another CListValue
+
+ CListValue* listval = (CListValue*) self;
+ listval->AddRef();
+ if (other->ob_type == &PyList_Type)
+ {
+ bool error = false;
+
+ int i;
+ int numitems = PyList_Size(other);
+ for (i=0;i<numitems;i++)
+ {
+ PyObject* listitem = PyList_GetItem(other,i);
+ CValue* listitemval = listval->ConvertPythonToValue(listitem);
+ if (listitemval)
+ {
+ listval->Add(listitemval);
+ } else
+ {
+ error = true;
+ }
+ }
+
+ if (error)
+ Py_Error(PyExc_SystemError, "Python Error: couldn't add one or more items to a list");
+
+
+ } else
+ {
+ if (other->ob_type == &CListValue::Type)
+ {
+ // add items from otherlist to this list
+ CListValue* otherval = (CListValue*) other;
+
+
+ for (int i=0;i<otherval->GetCount();i++)
+ {
+ otherval->Add(listval->GetValue(i)->AddRef());
+ }
+ }
+ else
+ {
+ CValue* objval = listval->ConvertPythonToValue(other);
+ if (objval)
+ {
+ listval->Add(objval);
+ } else
+ {
+ Py_Error(PyExc_SystemError, "Python Error: couldn't add item to a list");
+ // bad luck
+ }
+ }
+ }
+
+ return self;
+}
+
+
+
+static PySequenceMethods listvalue_as_sequence = {
+ (inquiry)listvalue_bufferlen,//(inquiry)buffer_length, /*sq_length*/
+ (binaryfunc)listvalue_buffer_concat, /*sq_concat*/
+ 0,//(intargfunc)buffer_repeat, /*sq_repeat*/
+ (intargfunc)listvalue_buffer_item, /*sq_item*/
+ (intintargfunc)listvalue_buffer_slice, /*sq_slice*/
+ 0,//(intobjargproc)buffer_ass_item, /*sq_ass_item*/
+ 0,//(intintobjargproc)buffer_ass_slice, /*sq_ass_slice*/
+};
+
+
+
+/* Is this one used ? */
+static PyMappingMethods instance_as_mapping = {
+ (inquiry)listvalue_bufferlen, /*mp_length*/
+ 0,//(binaryfunc)instance_subscript, /*mp_subscript*/
+ 0,//(objobjargproc)instance_ass_subscript, /*mp_ass_subscript*/
+};
+
+
+
+PyTypeObject CListValue::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /*ob_size*/
+ "CListValue", /*tp_name*/
+ sizeof(CListValue), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ PyDestructor, /*tp_dealloc*/
+ 0, /*tp_print*/
+ __getattr, /*tp_getattr*/
+ __setattr, /*tp_setattr*/
+ 0, /*tp_compare*/
+ __repr, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &listvalue_as_sequence, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call */
+};
+
+
+
+PyParentObject CListValue::Parents[] = {
+ &CListValue::Type,
+ &CValue::Type,
+ NULL
+};
+
+
+
+
+PyMethodDef CListValue::Methods[] = {
+ {"append", (PyCFunction)CListValue::sPyappend,METH_VARARGS},
+ {"reverse", (PyCFunction)CListValue::sPyreverse,METH_VARARGS},
+ {"index", (PyCFunction)CListValue::sPyindex,METH_VARARGS},
+ {"count", (PyCFunction)CListValue::sPycount,METH_VARARGS},
+
+ {NULL,NULL} //Sentinel
+};
+
+
+
+PyObject* CListValue::_getattr(char* attr) {
+ _getattr_up(CValue);
+}
+
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CListValue::CListValue(PyTypeObject *T )
+: CPropValue(T)
+{
+ m_bReleaseContents=true;
+}
+
+
+
+CListValue::~CListValue()
+{
+
+ if (m_bReleaseContents) {
+ for (int i=0;i<m_pValueArray.size();i++) {
+ m_pValueArray[i]->Release();
+ }
+ }
+}
+
+
+static STR_String gstrListRep=STR_String("List");
+
+const STR_String & CListValue::GetText()
+{
+ gstrListRep = "[";
+ STR_String commastr = "";
+
+ for (int i=0;i<GetCount();i++)
+ {
+ gstrListRep += commastr;
+ gstrListRep += GetValue(i)->GetText();
+ commastr = ",";
+ }
+ gstrListRep += "]";
+
+ return gstrListRep;
+}
+
+
+
+CValue* CListValue::GetReplica() {
+ CListValue* replica = new CListValue(*this);
+
+ CValue::AddDataToReplica(replica);
+
+ replica->m_bReleaseContents=true; // for copy, complete array is copied for now...
+ // copy all values
+ int numelements = m_pValueArray.size();
+ int i=0;
+ replica->m_pValueArray.resize(numelements);
+ for (i=0;i<m_pValueArray.size();i++)
+ replica->m_pValueArray[i] = m_pValueArray[i]->GetReplica();
+
+
+ return replica;
+};
+
+
+
+void CListValue::SetValue(int i, CValue *val)
+{
+ assertd(i < m_pValueArray.size());
+ m_pValueArray[i]=val;
+}
+
+
+
+void CListValue::Resize(int num)
+{
+ m_pValueArray.resize(num);
+}
+
+
+
+void CListValue::Remove(int i)
+{
+ assertd(i<m_pValueArray.size());
+ m_pValueArray.erase(m_pValueArray.begin()+i);
+}
+
+
+
+void CListValue::ReleaseAndRemoveAll()
+{
+ for (int i=0;i<m_pValueArray.size();i++)
+ m_pValueArray[i]->Release();
+ m_pValueArray.clear();//.Clear();
+}
+
+
+
+CValue* CListValue::FindValue(const STR_String & name)
+{
+ CValue* resultval = NULL;
+ int i=0;
+
+ while (!resultval && i < GetCount())
+ {
+ CValue* myval = GetValue(i);
+
+ if (myval->GetName() == name)
+ resultval = GetValue(i)->AddRef(); // add referencecount
+ else
+ i++;
+
+ }
+ return resultval;
+}
+
+
+
+bool CListValue::SearchValue(CValue *val)
+{
+ for (int i=0;i<GetCount();i++)
+ if (val == GetValue(i))
+ return true;
+ return false;
+}
+
+
+
+void CListValue::SetReleaseOnDestruct(bool bReleaseContents)
+{
+ m_bReleaseContents = bReleaseContents;
+}
+
+
+
+bool CListValue::RemoveValue(CValue *val)
+{
+ bool result=false;
+
+ for (int i=GetCount()-1;i>=0;i--)
+ if (val == GetValue(i))
+ {
+ Remove(i);
+ result=true;
+ }
+ return result;
+}
+
+
+
+void CListValue::MergeList(CListValue *otherlist)
+{
+
+ int numelements = this->GetCount();
+ int numotherelements = otherlist->GetCount();
+
+
+ Resize(numelements+numotherelements);
+
+ for (int i=0;i<numotherelements;i++)
+ {
+ SetValue(i+numelements,otherlist->GetValue(i)->AddRef());
+ }
+
+}
+
+
+
+PyObject* CListValue::Pyappend(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+
+ PyObject* pyobj = NULL;
+ if (PyArg_ParseTuple(args,"O",&pyobj))
+ {
+ return listvalue_buffer_concat(self,pyobj);
+ }
+ else
+ {
+ return NULL;
+ }
+
+
+}
+
+
+
+PyObject* CListValue::Pyreverse(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ std::reverse(m_pValueArray.begin(),m_pValueArray.end());
+
+ Py_Return;
+
+}
+
+
+
+bool CListValue::CheckEqual(CValue* first,CValue* second)
+{
+ bool result = false;
+
+ CValue* eqval = ((CValue*)first)->Calc(VALUE_EQL_OPERATOR,(CValue*)second);
+ STR_String txt = eqval->GetText();
+ eqval->Release();
+ if (txt=="TRUE")
+ {
+ result = true;
+ }
+ return result;
+
+}
+
+
+
+PyObject* CListValue::Pyindex(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ PyObject* result = NULL;
+
+ PyObject* pyobj = NULL;
+ if (PyArg_ParseTuple(args,"O",&pyobj))
+ {
+
+ CValue* checkobj = ConvertPythonToValue(pyobj);
+ int numelem = GetCount();
+ for (int i=0;i<numelem;i++)
+ {
+ CValue* elem = GetValue(i);
+ if (CheckEqual(checkobj,elem))
+ {
+ result = PyInt_FromLong(i);
+ break;
+ }
+ }
+ checkobj->Release();
+ }
+
+ return result;
+
+}
+
+
+
+PyObject* CListValue::Pycount(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+
+ int numfound = 0;
+
+ PyObject* pyobj = NULL;
+ if (PyArg_ParseTuple(args,"O",&pyobj))
+ {
+ CValue* checkobj = ConvertPythonToValue(pyobj);
+ int numelem = GetCount();
+ for (int i=0;i<numelem;i++)
+ {
+ CValue* elem = GetValue(i);
+ if (CheckEqual(checkobj,elem))
+ {
+ numfound ++;
+ }
+ }
+ checkobj->Release();
+ }
+
+ return PyInt_FromLong(numfound);
+}
+
+
+
+/* ---------------------------------------------------------------------
+ * Some stuff taken from the header
+ * --------------------------------------------------------------------- */
+CValue* CListValue::Calc(VALUE_OPERATOR op,CValue *val)
+{
+ assert(false); // todo: implement me!
+ return NULL;
+}
+
+
+
+CValue* CListValue::CalcFinal(VALUE_DATA_TYPE dtype,
+ VALUE_OPERATOR op,
+ CValue* val)
+{
+ assert(false); // todo: implement me!
+ return NULL;
+}
+
+
+
+void CListValue::Add(CValue* value)
+{
+ m_pValueArray.push_back(value);
+}
+
+
+
+float CListValue::GetNumber()
+{
+ return -1;
+}
+
+
+
+void CListValue::SetModified(bool bModified)
+{
+ CValue::SetModified(bModified);
+ int numels = GetCount();
+
+ for (int i=0;i<numels;i++)
+ GetValue(i)->SetModified(bModified);
+}
+
+
+
+bool CListValue::IsModified()
+{
+ bool bmod = CValue::IsModified(); //normal own flag
+ int numels = GetCount();
+
+ for (int i=0;i<numels;i++)
+ bmod = bmod || GetValue(i)->IsModified();
+
+ return bmod;
+} \ No newline at end of file
diff --git a/source/gameengine/Expressions/ListValue.h b/source/gameengine/Expressions/ListValue.h
new file mode 100644
index 00000000000..fce4e9da8c2
--- /dev/null
+++ b/source/gameengine/Expressions/ListValue.h
@@ -0,0 +1,77 @@
+/*
+ * ListValue.h: interface for the CListValue class.
+ * $Id$
+ * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#if !defined _LISTVALUE_H
+#define _LISTVALUE_H
+
+
+#include "Value.h"
+
+class CListValue : public CPropValue
+{
+ Py_Header;
+ //PLUGIN_DECLARE_SERIAL (CListValue,CValue)
+
+public:
+ CListValue(PyTypeObject *T = &Type);
+ virtual ~CListValue();
+
+ void AddConfigurationData(CValue* menuvalue);
+ void Configure(CValue* menuvalue);
+ void Add(CValue* value);
+
+ /** @attention not implemented yet :( */
+ virtual CValue* Calc(VALUE_OPERATOR op,CValue *val);
+ virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype,
+ VALUE_OPERATOR op,
+ CValue* val);
+ virtual float GetNumber();
+ virtual CValue* GetReplica();
+
+public:
+ void MergeList(CListValue* otherlist);
+ bool RemoveValue(CValue* val);
+ void SetReleaseOnDestruct(bool bReleaseContents);
+ bool SearchValue(CValue* val);
+
+ CValue* FindValue(const STR_String & name);
+
+ void ReleaseAndRemoveAll();
+ virtual void SetModified(bool bModified);
+ virtual inline bool IsModified();
+ void Remove(int i);
+ void Resize(int num);
+ void SetValue(int i,CValue* val);
+ CValue* GetValue(int i){ assertd(i < m_pValueArray.size()); return m_pValueArray[i];}
+ int GetCount() { return m_pValueArray.size();};
+ virtual const STR_String & GetText();
+
+ bool CheckEqual(CValue* first,CValue* second);
+
+ virtual PyObject* _getattr(char *attr);
+
+ KX_PYMETHOD(CListValue,append);
+ KX_PYMETHOD(CListValue,reverse);
+ KX_PYMETHOD(CListValue,index);
+ KX_PYMETHOD(CListValue,count);
+
+
+private:
+
+ std::vector<CValue*> m_pValueArray;
+ bool m_bReleaseContents;
+};
+
+#endif // !defined _LISTVALUE_H
diff --git a/source/gameengine/Expressions/Makefile b/source/gameengine/Expressions/Makefile
new file mode 100644
index 00000000000..9199698d3e9
--- /dev/null
+++ b/source/gameengine/Expressions/Makefile
@@ -0,0 +1,45 @@
+#
+# $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 = expression
+DIR = $(OCGDIR)/gameengine/$(LIBNAME)
+
+include nan_compile.mk
+
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
+CPPFLAGS += -I$(NAN_STRING)/include
+CPPFLAGS += -I../../kernel/gen_system
+CPPFLAGS += -I../Ketsji
+
diff --git a/source/gameengine/Expressions/Operator1Expr.cpp b/source/gameengine/Expressions/Operator1Expr.cpp
new file mode 100644
index 00000000000..91a3a02aabe
--- /dev/null
+++ b/source/gameengine/Expressions/Operator1Expr.cpp
@@ -0,0 +1,148 @@
+// Operator1Expr.cpp: implementation of the COperator1Expr class.
+/*
+ * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#include "Operator1Expr.h"
+//#include "FactoryManager.h"
+#include "EmptyValue.h"
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+COperator1Expr::COperator1Expr()
+/*
+pre:
+effect: constucts an empty COperator1Expr
+*/
+{
+ m_lhs = NULL;
+}
+
+COperator1Expr::COperator1Expr(VALUE_OPERATOR op, CExpression * lhs)
+/*
+pre:
+effect: constucts a COperator1Expr with op and lhs in it
+*/
+{
+ m_lhs = lhs;
+ m_op = op;
+}
+
+COperator1Expr::~COperator1Expr()
+/*
+pre:
+effect: deletes the object
+*/
+{
+ if (m_lhs) m_lhs->Release();
+}
+
+CValue * COperator1Expr::Calculate()
+/*
+pre:
+ret: a new object containing the result of applying the operator m_op to the
+ value of m_lhs
+*/
+{
+ CValue *ret;
+ CValue *temp = m_lhs->Calculate();
+ CValue* empty = new CEmptyValue();
+ ret = empty->Calc(m_op, temp);
+ empty->Release();
+ temp->Release();
+
+ return ret;
+}
+
+/*
+bool COperator1Expr::IsInside(float x, float y, float z,bool bBorderInclude)
+{
+
+ bool result = true;
+ switch (m_op)
+ {
+
+ case VALUE_ADD_OPERATOR:
+ {
+
+ if (m_lhs)
+ {
+ result = result || m_lhs->IsInside(x,y,z,bBorderInclude);
+ }
+ break;
+ }
+ case VALUE_SUB_OPERATOR:
+ {
+ result = true;
+ if (m_lhs)
+ {
+ result = result && (!m_lhs->IsInside(x,y,z,bBorderInclude));
+ }
+ break;
+ }
+ }
+ return result;
+}
+
+*/
+bool COperator1Expr::NeedsRecalculated() {
+
+ return m_lhs->NeedsRecalculated();
+
+}
+
+CExpression* COperator1Expr::CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks) {
+
+ CExpression* newlhs = m_lhs->CheckLink(brokenlinks);
+
+ if (newlhs)
+ {
+ if (newlhs==m_lhs) {
+ // not changed
+ } else {
+ // changed
+ //numchanges++;
+ newlhs->AddRef();
+
+ //m_lhs->Release();
+ brokenlinks.push_back(new CBrokenLinkInfo(&m_lhs,m_lhs));
+
+ m_lhs = newlhs;
+ }
+ return this;
+ } else {
+ //numchanges++;
+ AddRef();
+
+ return Release();
+ }
+
+}
+
+void COperator1Expr::BroadcastOperators(VALUE_OPERATOR op)
+{
+ if (m_lhs)
+ m_lhs->BroadcastOperators(m_op);
+}
+
+
+
+
+bool COperator1Expr::MergeExpression(CExpression *otherexpr)
+{
+ if (m_lhs)
+ return m_lhs->MergeExpression(otherexpr);
+
+ assertd(false); // should not get here, expression is not compatible for merge
+ return false;
+}
diff --git a/source/gameengine/Expressions/Operator1Expr.h b/source/gameengine/Expressions/Operator1Expr.h
new file mode 100644
index 00000000000..9362c568dc9
--- /dev/null
+++ b/source/gameengine/Expressions/Operator1Expr.h
@@ -0,0 +1,53 @@
+/*
+ * Operator1Expr.h: interface for the COperator1Expr class.
+ * $Id$
+ * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#if !defined(AFX_OPERATOR1EXPR_H__A1653901_BF41_11D1_A51C_00A02472FC58__INCLUDED_)
+#define AFX_OPERATOR1EXPR_H__A1653901_BF41_11D1_A51C_00A02472FC58__INCLUDED_
+
+
+
+#include "Expression.h"
+
+class COperator1Expr : public CExpression
+{
+ //PLUGIN_DECLARE_SERIAL_EXPRESSION (COperator1Expr,CExpression)
+
+
+
+public:
+ virtual bool MergeExpression(CExpression* otherexpr);
+ void virtual BroadcastOperators(VALUE_OPERATOR op);
+
+ virtual unsigned char GetExpressionID() { return COPERATOR1EXPRESSIONID;};
+ CExpression* CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks);
+ //virtual bool IsInside(float x,float y,float z,bool bBorderInclude = true);
+ virtual bool NeedsRecalculated();
+ void ClearModified() {
+ if (m_lhs)
+ m_lhs->ClearModified();
+ }
+ virtual CValue* Calculate();
+ COperator1Expr(VALUE_OPERATOR op, CExpression *lhs);
+ COperator1Expr();
+ virtual ~COperator1Expr();
+
+
+
+private:
+ VALUE_OPERATOR m_op;
+ CExpression * m_lhs;
+};
+
+#endif // !defined(AFX_OPERATOR1EXPR_H__A1653901_BF41_11D1_A51C_00A02472FC58__INCLUDED_)
diff --git a/source/gameengine/Expressions/Operator2Expr.cpp b/source/gameengine/Expressions/Operator2Expr.cpp
new file mode 100644
index 00000000000..33223b2ae3d
--- /dev/null
+++ b/source/gameengine/Expressions/Operator2Expr.cpp
@@ -0,0 +1,275 @@
+// Operator2Expr.cpp: implementation of the COperator2Expr class.
+/*
+ * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+// 31 dec 1998 - big update: try to use the cached data for updating, instead of
+// rebuilding completely it from left and right node. Modified flags and bounding boxes
+// have to do the trick
+// when expression is cached, there will be a call to UpdateCalc() instead of Calc()
+
+
+
+#include "Operator2Expr.h"
+#include "StringValue.h"
+#include "VoidValue.h"
+//#include "FactoryManager.h"
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+COperator2Expr::COperator2Expr(VALUE_OPERATOR op, CExpression *lhs, CExpression *rhs)
+:
+m_cached_calculate(NULL),
+m_op(op),
+m_lhs(lhs),
+m_rhs(rhs)
+/*
+pre:
+effect: constucts a COperator2Expr with op, lhs and rhs in it
+*/
+{
+
+}
+
+COperator2Expr::COperator2Expr():
+m_cached_calculate(NULL),
+m_lhs(NULL),
+m_rhs(NULL)
+
+/*
+pre:
+effect: constucts an empty COperator2Expr
+*/
+{
+
+}
+
+COperator2Expr::~COperator2Expr()
+/*
+pre:
+effect: deletes the object
+*/
+{
+ if (m_lhs)
+ m_lhs->Release();
+ if (m_rhs)
+ m_rhs->Release();
+ if (m_cached_calculate)
+ m_cached_calculate->Release();
+
+}
+CValue* COperator2Expr::Calculate()
+/*
+pre:
+ret: a new object containing the result of applying operator m_op to m_lhs
+and m_rhs
+*/
+{
+
+ bool leftmodified,rightmodified;
+ leftmodified = m_lhs->NeedsRecalculated();
+ rightmodified = m_rhs->NeedsRecalculated();
+
+ // if no modifications on both left and right subtree, and result is already calculated
+ // then just return cached result...
+ if (!leftmodified && !rightmodified && (m_cached_calculate))
+ {
+ // not modified, just return m_cached_calculate
+ } else {
+ // if not yet calculated, or modified...
+
+
+ if (m_cached_calculate) {
+ m_cached_calculate->Release();
+ m_cached_calculate=NULL;
+ }
+
+ CValue* ffleft = m_lhs->Calculate();
+ CValue* ffright = m_rhs->Calculate();
+
+ ffleft->SetOwnerExpression(this);//->m_pOwnerExpression=this;
+ ffright->SetOwnerExpression(this);//->m_pOwnerExpression=this;
+
+ m_cached_calculate = ffleft->Calc(m_op,ffright);
+
+ //if (m_cached_calculate)
+ // m_cached_calculate->Action(CValue::SETOWNEREXPR,&CVoidValue(this,false,CValue::STACKVALUE));
+
+ ffleft->Release();
+ ffright->Release();
+ }
+
+ return m_cached_calculate->AddRef();
+
+}
+
+/*
+bool COperator2Expr::IsInside(float x, float y, float z,bool bBorderInclude)
+{
+ bool inside;
+ inside = false;
+
+ switch (m_op)
+ {
+ case VALUE_ADD_OPERATOR: {
+ // inside = first || second; // optimized with early out if first is inside
+ // todo: calculate smallest leaf first ! is much faster...
+
+ bool second;//first ;//,second;
+
+ //first = m_lhs->IsInside(x,y,z) ;
+ second = m_rhs->IsInside(x,y,z,bBorderInclude) ;
+ if (second)
+ return true; //early out
+
+ // second = m_rhs->IsInside(x,y,z) ;
+
+ return m_lhs->IsInside(x,y,z,bBorderInclude) ;
+
+ break;
+ }
+
+ case VALUE_SUB_OPERATOR: {
+ //inside = first && !second; // optimized with early out
+ // todo: same as with add_operator: calc smallest leaf first
+
+ bool second;//first ;//,second;
+ //first = m_lhs->IsInside(x,y,z) ;
+ second = m_rhs->IsInside(x,y,z,bBorderInclude);
+ if (second)
+ return false;
+
+ // second space get subtracted -> negate!
+ //second = m_rhs->IsInside(x,y,z);
+
+ return (m_lhs->IsInside(x,y,z,bBorderInclude));
+
+
+ break;
+ }
+ default:{
+ assert(false);
+ // not yet implemented, only add or sub csg operations
+ }
+ }
+
+ return inside;
+}
+
+
+
+bool COperator2Expr::IsRightInside(float x, float y, float z,bool bBorderInclude) {
+
+ return m_rhs->IsInside(x,y,z,bBorderInclude) ;
+
+}
+
+bool COperator2Expr::IsLeftInside(float x, float y, float z,bool bBorderInclude) {
+ return m_lhs->IsInside(x,y,z,bBorderInclude);
+}
+*/
+bool COperator2Expr::NeedsRecalculated() {
+ // added some lines, just for debugging purposes, it could be a one-liner :)
+ //bool modleft
+ //bool modright;
+ assertd(m_lhs);
+ assertd(m_rhs);
+
+ //modright = m_rhs->NeedsRecalculated();
+ if (m_rhs->NeedsRecalculated()) // early out
+ return true;
+ return m_lhs->NeedsRecalculated();
+ //modleft = m_lhs->NeedsRecalculated();
+ //return (modleft || modright);
+
+}
+
+
+
+CExpression* COperator2Expr::CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks) {
+// if both children are 'dead', return NULL
+// if only one child is alive, return that child
+// if both childresn are alive, return this
+
+
+// bool leftalive = true,rightalive=true;
+ /* Does this mean the function will always bomb? */
+ assertd(false);
+ assert(m_lhs);
+ assert(m_rhs);
+/*
+ if (m_cached_calculate)
+ m_cached_calculate->Action(CValue::REFRESH_CACHE);
+
+ CExpression* newlhs = m_lhs->CheckLink(brokenlinks);
+ CExpression* newrhs = m_rhs->CheckLink(brokenlinks);
+
+ if (m_lhs != newlhs)
+ {
+ brokenlinks.push_back(new CBrokenLinkInfo(&m_lhs,m_lhs));
+ }
+
+ if (m_rhs != newrhs)
+ {
+ brokenlinks.push_back(new CBrokenLinkInfo(&m_rhs,m_rhs));
+ }
+
+
+
+ m_lhs = newlhs;
+ m_rhs = newrhs;
+
+ if (m_lhs && m_rhs) {
+ return this;
+ }
+
+ AddRef();
+ if (m_lhs)
+ return Release(m_lhs->AddRef());
+
+ if (m_rhs)
+ return Release(m_rhs->AddRef());
+/
+
+ */
+ return Release();
+
+
+
+}
+
+
+bool COperator2Expr::MergeExpression(CExpression *otherexpr)
+{
+ if (m_lhs)
+ {
+ if (m_lhs->GetExpressionID() == CExpression::CCONSTEXPRESSIONID)
+ {
+ // cross fingers ;) replace constexpr by new tree...
+ m_lhs->Release();
+ m_lhs = otherexpr->AddRef();
+ return true;
+ }
+ }
+
+ assertd(false);
+ return false;
+}
+
+
+void COperator2Expr::BroadcastOperators(VALUE_OPERATOR op)
+{
+ if (m_lhs)
+ m_lhs->BroadcastOperators(m_op);
+ if (m_rhs)
+ m_rhs->BroadcastOperators(m_op);
+}
diff --git a/source/gameengine/Expressions/Operator2Expr.h b/source/gameengine/Expressions/Operator2Expr.h
new file mode 100644
index 00000000000..7e1dc3ed250
--- /dev/null
+++ b/source/gameengine/Expressions/Operator2Expr.h
@@ -0,0 +1,59 @@
+/*
+ * Operator2Expr.h: interface for the COperator2Expr class.
+ * $Id$
+ * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#if !defined _OPERATOR2EXPR_H
+#define _OPERATOR2EXPR_H
+
+
+#include "Expression.h"
+#include "Value.h" // Added by ClassView
+
+
+class COperator2Expr : public CExpression
+{
+ //PLUGIN_DECLARE_SERIAL_EXPRESSION (COperator2Expr,CExpression)
+
+public:
+ virtual bool MergeExpression(CExpression* otherexpr);
+ virtual unsigned char GetExpressionID() { return COPERATOR2EXPRESSIONID;};
+ virtual void BroadcastOperators(VALUE_OPERATOR op);
+ CExpression* CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks);
+ //virtual bool IsInside(float x,float y,float z,bool bBorderInclude=true);
+ //virtual bool IsLeftInside(float x,float y,float z,bool bBorderInclude);
+ //virtual bool IsRightInside(float x,float y,float z,bool bBorderInclude);
+ bool NeedsRecalculated();
+ void ClearModified() {
+ if (m_lhs)
+ m_lhs->ClearModified();
+ if (m_rhs)
+ m_rhs->ClearModified();
+ }
+ virtual CValue* Calculate();
+ COperator2Expr(VALUE_OPERATOR op, CExpression *lhs, CExpression *rhs);
+ COperator2Expr();
+ virtual ~COperator2Expr();
+
+
+protected:
+ CExpression * m_rhs;
+ CExpression * m_lhs;
+ CValue* m_cached_calculate; // cached result
+
+private:
+ VALUE_OPERATOR m_op;
+
+};
+
+#endif // !defined _OPERATOR2EXPR_H
diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp
new file mode 100644
index 00000000000..7b93b1d4daa
--- /dev/null
+++ b/source/gameengine/Expressions/PyObjectPlus.cpp
@@ -0,0 +1,157 @@
+/**
+ * $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 NO_EXP_PYTHON_EMBEDDING
+
+/*------------------------------
+ * PyObjectPlus cpp
+ *
+ * C++ library routines for Crawl 3.2
+ *
+ * Derived from work by
+ * David Redish
+ * graduate student
+ * Computer Science Department
+ * Carnegie Mellon University (CMU)
+ * Center for the Neural Basis of Cognition (CNBC)
+ * http://www.python.org/doc/PyCPP.html
+ *
+------------------------------*/
+#include <assert.h>
+#include "stdlib.h"
+#include "PyObjectPlus.h"
+#include "STR_String.h"
+/*------------------------------
+ * PyObjectPlus Type -- Every class, even the abstract one should have a Type
+------------------------------*/
+
+PyTypeObject PyObjectPlus::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /*ob_size*/
+ "PyObjectPlus", /*tp_name*/
+ sizeof(PyObjectPlus), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ PyDestructor, /*tp_dealloc*/
+ 0, /*tp_print*/
+ __getattr, /*tp_getattr*/
+ __setattr, /*tp_setattr*/
+ 0, /*tp_compare*/
+ __repr, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call */
+};
+
+PyObjectPlus::PyObjectPlus(PyTypeObject *T) // constructor
+{
+ assert(T != NULL);
+ this->ob_type = T;
+ _Py_NewReference(this);
+};
+
+/*------------------------------
+ * PyObjectPlus Methods -- Every class, even the abstract one should have a Methods
+------------------------------*/
+PyMethodDef PyObjectPlus::Methods[] = {
+ {"isA", (PyCFunction) sPy_isA, Py_NEWARGS},
+ {NULL, NULL} /* Sentinel */
+};
+
+/*------------------------------
+ * PyObjectPlus Parents -- Every class, even the abstract one should have parents
+------------------------------*/
+PyParentObject PyObjectPlus::Parents[] = {&PyObjectPlus::Type, NULL};
+
+/*------------------------------
+ * PyObjectPlus attributes -- attributes
+------------------------------*/
+PyObject *PyObjectPlus::_getattr(char *attr)
+{
+ //if (streq(attr, "type"))
+ // return Py_BuildValue("s", (*(GetParents()))->tp_name);
+
+ return Py_FindMethod(Methods, this, attr);
+}
+
+int PyObjectPlus::_setattr(char *attr, PyObject *value)
+{
+ //return PyObject::_setattr(attr,value);
+ //cerr << "Unknown attribute" << endl;
+ return 1;
+}
+
+/*------------------------------
+ * PyObjectPlus repr -- representations
+------------------------------*/
+PyObject *PyObjectPlus::_repr(void)
+{
+ Py_Error(PyExc_SystemError, "Representation not overridden by object.");
+}
+
+/*------------------------------
+ * PyObjectPlus isA -- the isA functions
+------------------------------*/
+bool PyObjectPlus::isA(PyTypeObject *T) // if called with a Type, use "typename"
+{
+ return isA(T->tp_name);
+}
+
+
+bool PyObjectPlus::isA(const char *mytypename) // check typename of each parent
+{
+ int i;
+ PyParentObject P;
+ PyParentObject *Ps = GetParents();
+
+ for (P = Ps[i=0]; P != NULL; P = Ps[i++])
+ {
+ if (STR_String(P->tp_name) == STR_String(mytypename) )
+ return true;
+ }
+
+ return false;
+}
+
+PyObject *PyObjectPlus::Py_isA(PyObject *args) // Python wrapper for isA
+{
+ char *mytypename;
+ Py_Try(PyArg_ParseTuple(args, "s", &mytypename));
+ if(isA(mytypename))
+ {Py_INCREF(Py_True); return Py_True;}
+ else
+ {Py_INCREF(Py_False); return Py_False;};
+}
+
+#endif //NO_EXP_PYTHON_EMBEDDING
+
diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h
new file mode 100644
index 00000000000..e88ea2b255a
--- /dev/null
+++ b/source/gameengine/Expressions/PyObjectPlus.h
@@ -0,0 +1,135 @@
+/**
+ * $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 NO_EXP_PYTHON_EMBEDDING
+
+#ifndef _adr_py_lib_h_ // only process once,
+#define _adr_py_lib_h_ // even if multiply included
+
+#ifndef __cplusplus // c++ only
+#error Must be compiled with C++
+#endif
+
+#include "KX_Python.h"
+
+/*------------------------------
+ * Python defines
+------------------------------*/
+
+ // some basic python macros
+#define Py_NEWARGS 1
+#define Py_Return Py_INCREF(Py_None); return Py_None;
+
+#define Py_Error(E, M) {PyErr_SetString(E, M); return NULL;}
+#define Py_Try(F) {if (!(F)) return NULL;}
+#define Py_Assert(A,E,M) {if (!(A)) {PyErr_SetString(E, M); return NULL;}}
+
+inline void Py_Fatal(char *M) {
+ //cout << M << endl;
+ exit(-1);
+};
+
+ // This must be the first line of each
+ // PyC++ class
+#define Py_Header \
+ public: \
+ static PyTypeObject Type; \
+ static PyMethodDef Methods[]; \
+ static PyParentObject Parents[]; \
+ virtual PyTypeObject *GetType(void) {return &Type;}; \
+ virtual PyParentObject *GetParents(void) {return Parents;}
+
+ // This defines the _getattr_up macro
+ // which allows attribute and method calls
+ // to be properly passed up the hierarchy.
+#define _getattr_up(Parent) \
+ PyObject *rvalue = Py_FindMethod(Methods, this, attr); \
+ if (rvalue == NULL) \
+ { \
+ PyErr_Clear(); \
+ return Parent::_getattr(attr); \
+ } \
+ else \
+ return rvalue
+
+
+/*------------------------------
+ * PyObjectPlus
+------------------------------*/
+typedef PyTypeObject * PyParentObject; // Define the PyParent Object
+
+class PyObjectPlus : public PyObject { // The PyObjectPlus abstract class
+
+ Py_Header; // Always start with Py_Header
+
+ public:
+ PyObjectPlus(PyTypeObject *T);
+
+ virtual ~PyObjectPlus() {}; // destructor
+ static void PyDestructor(PyObject *P) // python wrapper
+ {
+ delete ((PyObjectPlus *) P);
+ };
+
+ //void INCREF(void) {
+// Py_INCREF(this);
+// }; // incref method
+ //void DECREF(void) {
+// Py_DECREF(this);
+// }; // decref method
+
+ virtual PyObject *_getattr(char *attr); // _getattr method
+ static PyObject *__getattr(PyObject * PyObj, char *attr) // This should be the entry in Type.
+ { return ((PyObjectPlus*) PyObj)->_getattr(attr); };
+
+ virtual int _setattr(char *attr, PyObject *value); // _setattr method
+ static int __setattr(PyObject *PyObj, // This should be the entry in Type.
+ char *attr,
+ PyObject *value)
+ { return ((PyObjectPlus*) PyObj)->_setattr(attr, value); };
+
+ virtual PyObject *_repr(void); // _repr method
+ static PyObject *__repr(PyObject *PyObj) // This should be the entry in Type.
+ { return ((PyObjectPlus*) PyObj)->_repr(); };
+
+
+ // isA methods
+ bool isA(PyTypeObject *T);
+ bool isA(const char *mytypename);
+ PyObject *Py_isA(PyObject *args);
+ static PyObject *sPy_isA(PyObject *self, PyObject *args, PyObject *kwd)
+ {return ((PyObjectPlus*)self)->Py_isA(args);};
+};
+
+#endif // _adr_py_lib_h_
+
+#endif //NO_EXP_PYTHON_EMBEDDING
+
diff --git a/source/gameengine/Expressions/StringValue.cpp b/source/gameengine/Expressions/StringValue.cpp
new file mode 100644
index 00000000000..7bdb841e1e4
--- /dev/null
+++ b/source/gameengine/Expressions/StringValue.cpp
@@ -0,0 +1,139 @@
+// StringValue.cpp: implementation of the CStringValue class.
+/*
+ * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+
+#include "StringValue.h"
+#include "BoolValue.h"
+#include "ErrorValue.h"
+#include "VoidValue.h"
+//#include "FactoryManager.h"
+
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CStringValue::CStringValue()
+/*
+pre: false
+effect: constructs a new CStringValue
+*/
+{
+ m_strString = "[Illegal String constructor call]";
+}
+
+CStringValue::CStringValue(STR_String txt,STR_String name,AllocationTYPE alloctype)
+/*
+pre:
+effect: constructs a new CStringValue containing text txt
+*/
+{
+ m_strString = txt;
+ SetName(name);
+
+ if (alloctype==CValue::STACKVALUE)
+ {
+ CValue::DisableRefCount();
+
+ }
+
+
+}
+
+
+CValue* CStringValue::Calc(VALUE_OPERATOR op, CValue *val)
+/*
+pre:
+ret: a new object containing the result of applying operator op to this
+object and val
+*/
+{
+ //return val->CalrcString(op, this);
+ return val->CalcFinal(VALUE_STRING_TYPE, op, this);
+}
+
+CValue* CStringValue::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val)
+/*
+pre: the type of val is dtype
+ret: a new object containing the result of applying operator op to val and
+this object
+*/
+{
+ CValue *ret;
+
+ if (op == VALUE_ADD_OPERATOR) {
+ if (dtype == VALUE_ERROR_TYPE)
+ ret = new CErrorValue(val->GetText() + op2str(op) + GetText());
+ else
+ ret = new CStringValue(val->GetText() + GetText(),"");
+ } else {
+
+ if (dtype == VALUE_STRING_TYPE || dtype == VALUE_EMPTY_TYPE) {
+ switch(op) {
+ case VALUE_EQL_OPERATOR:
+ ret = new CBoolValue(val->GetText() == GetText());
+ break;
+ case VALUE_NEQ_OPERATOR:
+ ret = new CBoolValue(val->GetText() != GetText());
+ break;
+ case VALUE_GRE_OPERATOR:
+ ret = new CBoolValue(val->GetText() > GetText());
+ break;
+ case VALUE_LES_OPERATOR:
+ ret = new CBoolValue(val->GetText() < GetText());
+ break;
+ case VALUE_GEQ_OPERATOR:
+ ret = new CBoolValue(val->GetText() >= GetText());
+ break;
+ case VALUE_LEQ_OPERATOR:
+ ret = new CBoolValue(val->GetText() <= GetText());
+ break;
+ default:
+ ret = new CErrorValue(val->GetText() + op2str(op) + "[operator not allowed on strings]");
+ break;
+ }
+ } else {
+ ret = new CErrorValue(val->GetText() + op2str(op) + "[operator not allowed on strings]");
+ }
+ }
+ return ret;
+}
+
+
+
+float CStringValue::GetNumber()
+{
+ return -1;
+}
+
+
+
+const STR_String & CStringValue::GetText()
+{
+ return m_strString;
+}
+
+bool CStringValue::IsEqual(const STR_String & other)
+{
+ return (m_strString == other);
+}
+
+CValue* CStringValue::GetReplica()
+{
+ CStringValue* replica = new CStringValue(*this);
+ CValue::AddDataToReplica(replica);
+ return replica;
+};
+
+
diff --git a/source/gameengine/Expressions/StringValue.h b/source/gameengine/Expressions/StringValue.h
new file mode 100644
index 00000000000..6f90536a98b
--- /dev/null
+++ b/source/gameengine/Expressions/StringValue.h
@@ -0,0 +1,51 @@
+/*
+ * StringValue.h: interface for the CStringValue class.
+ * $Id$
+ * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef __STRINGVALUE_H__
+#define __STRINGVALUE_H__
+
+#include "Value.h"
+
+class CStringValue : public CPropValue
+{
+
+
+ //PLUGIN_DECLARE_SERIAL(CStringValue,CValue)
+public:
+ /// Construction / destruction
+ CStringValue();
+ CStringValue (STR_String txt, STR_String name , AllocationTYPE alloctype = CValue::HEAPVALUE);
+
+ virtual ~CStringValue() {
+ };
+ /// CValue implementation
+ virtual bool IsEqual(const STR_String & other);
+ virtual const STR_String & GetText();
+ virtual float GetNumber();
+
+ virtual CValue* Calc(VALUE_OPERATOR op, CValue *val);
+ virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val);
+ virtual void SetValue(CValue* newval) { m_strString = newval->GetText(); SetModified(true); };
+ virtual CValue* GetReplica();
+ virtual PyObject* ConvertValueToPython() {
+ return PyString_FromString(m_strString.Ptr());
+ }
+
+private:
+ // data member
+ STR_String m_strString;
+};
+
+#endif
diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp
new file mode 100644
index 00000000000..e2a7189fb02
--- /dev/null
+++ b/source/gameengine/Expressions/Value.cpp
@@ -0,0 +1,767 @@
+// Value.cpp: implementation of the CValue class.
+// developed at Eindhoven University of Technology, 1997
+// by the OOPS team
+//////////////////////////////////////////////////////////////////////
+/*
+ * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+
+#include "Value.h"
+#include "FloatValue.h"
+#include "IntValue.h"
+#include "VectorValue.h"
+#include "VoidValue.h"
+#include "StringValue.h"
+#include "ErrorValue.h"
+#include "ListValue.h"
+
+//#include "FactoryManager.h"
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+double CValue::m_sZeroVec[3] = {0.0,0.0,0.0};
+
+#ifndef NO_EXP_PYTHON_EMBEDDING
+
+PyObject* cvalue_add(PyObject*v, PyObject*w)
+{
+ return ((CValue*)v)->Calc(VALUE_ADD_OPERATOR,(CValue*)w);
+}
+PyObject* cvalue_sub(PyObject*v, PyObject*w)
+{
+ return ((CValue*)v)->Calc(VALUE_SUB_OPERATOR,(CValue*)w);
+}
+PyObject* cvalue_mul(PyObject*v, PyObject*w)
+{
+ return ((CValue*)v)->Calc(VALUE_MUL_OPERATOR,(CValue*)w);
+}
+PyObject* cvalue_div(PyObject*v, PyObject*w)
+{
+ return ((CValue*)v)->Calc(VALUE_DIV_OPERATOR,(CValue*)w);
+}
+PyObject* cvalue_neg(PyObject*v)
+{
+ return ((CValue*)v)->Calc(VALUE_NEG_OPERATOR,(CValue*)v);
+}
+PyObject* cvalue_pos(PyObject*v)
+{
+ return ((CValue*)v)->Calc(VALUE_POS_OPERATOR,(CValue*)v);
+}
+
+
+int MyPyCompare (PyObject* v,PyObject* w)
+{
+ CValue* eqval = ((CValue*)v)->Calc(VALUE_EQL_OPERATOR,(CValue*)w);
+ STR_String txt = eqval->GetText();
+ eqval->Release();
+ if (txt=="TRUE")
+ return 0;
+ CValue* lessval = ((CValue*)v)->Calc(VALUE_LES_OPERATOR,(CValue*)w);
+ txt = lessval->GetText();
+ lessval->Release();
+ if (txt=="TRUE")
+ return -1;
+
+ return 1;
+}
+
+
+int cvalue_coerce(PyObject** pv,PyObject** pw)
+{
+ if (PyInt_Check(*pw)) {
+ double db = (double)PyInt_AsLong(*pw);
+ *pw = new CIntValue(db);
+ Py_INCREF(*pv);
+ return 0;
+ }
+ else if (PyLong_Check(*pw)) {
+ double db = PyLong_AsDouble(*pw);
+ *pw = new CFloatValue(db);
+ Py_INCREF(*pv);
+ return 0;
+ }
+ else if (PyFloat_Check(*pw)) {
+ double db = PyFloat_AsDouble(*pw);
+ *pw = new CFloatValue(db);
+ Py_INCREF(*pv);
+ return 0;
+ } else if (PyString_Check(*pw)) {
+ const STR_String str = PyString_AsString(*pw);
+ *pw = new CStringValue(str,"");
+ Py_INCREF(*pv);
+ return 0;
+ }
+ return 1; /* Can't do it */
+
+}
+static PyNumberMethods cvalue_as_number = {
+ (binaryfunc)cvalue_add, /*nb_add*/
+ (binaryfunc)cvalue_sub, /*nb_subtract*/
+ (binaryfunc)cvalue_mul, /*nb_multiply*/
+ (binaryfunc)cvalue_div, /*nb_divide*/
+ 0,//(binaryfunc)cvalue_remainder, /*nb_remainder*/
+ 0,//(binaryfunc)cvalue_divmod, /*nb_divmod*/
+ 0,//0,//0,//0,//(ternaryfunc)cvalue_pow, /*nb_power*/
+ (unaryfunc)cvalue_neg, /*nb_negative*/
+ 0,//(unaryfunc)cvalue_pos, /*nb_positive*/
+ 0,//(unaryfunc)cvalue_abs, /*nb_absolute*/
+ 0,//(inquiry)cvalue_nonzero, /*nb_nonzero*/
+ 0, /*nb_invert*/
+ 0, /*nb_lshift*/
+ 0, /*nb_rshift*/
+ 0, /*nb_and*/
+ 0, /*nb_xor*/
+ 0, /*nb_or*/
+ (coercion)cvalue_coerce, /*nb_coerce*/
+ 0,//(unaryfunc)cvalue_int, /*nb_int*/
+ 0,//(unaryfunc)cvalue_long, /*nb_long*/
+ 0,//(unaryfunc)cvalue_float, /*nb_float*/
+ 0, /*nb_oct*/
+ 0, /*nb_hex*/
+};
+
+
+PyTypeObject CValue::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "CValue",
+ sizeof(CValue),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ &MyPyCompare,
+ __repr,
+ &cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject CValue::Parents[] = {
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef CValue::Methods[] = {
+// { "printHello", (PyCFunction) CValue::sPyPrintHello, Py_NEWARGS},
+ { "getName", (PyCFunction) CValue::sPyGetName, Py_NEWARGS},
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* CValue::PyGetName(PyObject* self,PyObject* args,PyObject* kwds)
+{
+ PyObject* pyname = PyString_FromString(this->GetName());
+ return pyname;
+}
+
+
+
+CValue::CValue(PyTypeObject *T)
+ : PyObjectPlus(T),
+#else
+CValue::CValue()
+:
+#endif //NO_EXP_PYTHON_EMBEDDING
+
+m_refcount(1),
+m_pNamedPropertyArray(NULL)
+/*
+pre: false
+effect: constucts a CValue
+*/
+{
+ //debug(gRefCountValue++) // debugging
+}
+
+
+
+CValue::~CValue()
+/*
+pre:
+effect: deletes the object
+*/
+{
+ ClearProperties();
+
+ assertd (m_refcount==0);
+}
+
+
+
+
+#define VALUE_SUB(val1, val2) (val1)->Calc(VALUE_SUB_OPERATOR, val2)
+#define VALUE_MUL(val1, val2) (val1)->Calc(VALUE_MUL_OPERATOR, val2)
+#define VALUE_DIV(val1, val2) (val1)->Calc(VALUE_DIV_OPERATOR, val2)
+#define VALUE_NEG(val1) (val1)->Calc(VALUE_NEG_OPERATOR, val1)
+#define VALUE_POS(val1) (val1)->Calc(VALUE_POS_OPERATOR, val1)
+
+
+STR_String CValue::op2str (VALUE_OPERATOR op)
+{
+ //pre:
+ //ret: the stringrepresentation of operator op
+
+ STR_String opmsg;
+ switch (op) {
+ case VALUE_ADD_OPERATOR:
+ opmsg = " + ";
+ break;
+ case VALUE_SUB_OPERATOR:
+ opmsg = " - ";
+ break;
+ case VALUE_MUL_OPERATOR:
+ opmsg = " * ";
+ break;
+ case VALUE_DIV_OPERATOR:
+ opmsg = " / ";
+ break;
+ case VALUE_NEG_OPERATOR:
+ opmsg = " -";
+ break;
+ case VALUE_POS_OPERATOR:
+ opmsg = " +";
+ break;
+ case VALUE_AND_OPERATOR:
+ opmsg = " & ";
+ break;
+ case VALUE_OR_OPERATOR:
+ opmsg = " | ";
+ break;
+ case VALUE_EQL_OPERATOR:
+ opmsg = " = ";
+ break;
+ case VALUE_NEQ_OPERATOR:
+ opmsg = " != ";
+ break;
+ case VALUE_NOT_OPERATOR:
+ opmsg = " !";
+ break;
+ default:
+ opmsg="Error in Errorhandling routine.";
+ // AfxMessageBox("Invalid operator");
+ break;
+ }
+ return opmsg;
+}
+
+
+
+
+
+//---------------------------------------------------------------------------------------------------------------------
+// Property Management
+//---------------------------------------------------------------------------------------------------------------------
+
+
+
+//
+// Set property <ioProperty>, overwrites and releases a previous property with the same name if needed
+//
+void CValue::SetProperty(const STR_String & name,CValue* ioProperty)
+{
+ // Check if somebody is setting an empty property
+ if (ioProperty==NULL)
+ {
+ trace("Warning:trying to set empty property!");
+ return;
+ }
+
+ // Make sure we have a property array
+ if (m_pNamedPropertyArray == NULL)
+ m_pNamedPropertyArray = new std::map<const STR_String,CValue *>;
+
+ // Try to replace property (if so -> exit as soon as we replaced it)
+ CValue* oldval = (*m_pNamedPropertyArray)[name];
+ if (oldval)
+ {
+ oldval->Release();
+ }
+
+ // Add property at end of array
+ (*m_pNamedPropertyArray)[name] = ioProperty;//->Add(ioProperty);
+}
+
+
+
+//
+// Get pointer to a property with name <inName>, returns NULL if there is no property named <inName>
+//
+CValue* CValue::GetProperty(const STR_String & inName)
+{
+ // Check properties, as soon as we found it -> Return a pointer to the property
+ CValue* result = NULL;
+ if (m_pNamedPropertyArray)
+ {
+ std::map<const STR_String,CValue*>::iterator it = (*m_pNamedPropertyArray).find(inName);
+ if (!( it==m_pNamedPropertyArray->end()))
+ {
+ result = (*it).second;
+ }
+
+ }
+ //for (int i=0; i<m_pValuePropertyArray->size(); i++)
+ // if ((*m_pValuePropertyArray)[i]->GetName() == inName)
+ // return (*m_pValuePropertyArray)[i];
+
+ // Did not find property with name <inName>, return NULL property pointer
+ return result;
+}
+
+
+
+//
+// Get text description of property with name <inName>, returns an empty string if there is no property named <inName>
+//
+STR_String CValue::GetPropertyText(const STR_String & inName,const STR_String& deftext)
+{
+ CValue *property = GetProperty(inName);
+ if (property)
+ return property->GetText();
+ else
+ return deftext;//String::sEmpty;
+}
+
+float CValue::GetPropertyNumber(const STR_String& inName,float defnumber)
+{
+ CValue *property = GetProperty(inName);
+ if (property)
+ return property->GetNumber();
+ else
+ return defnumber;
+}
+
+
+
+//
+// Remove the property named <inName>, returns true if the property was succesfully removed, false if property was not found or could not be removed
+//
+bool CValue::RemoveProperty(const STR_String & inName)
+{
+ // Check if there are properties at all which can be removed
+ if (m_pNamedPropertyArray == NULL)
+ return false;
+
+ // Scan all properties, as soon as we find one with <inName> -> Remove it
+// CValue* val = (*m_pNamedPropertyArray)[inName];
+ if (m_pNamedPropertyArray->erase(inName)) return true;
+
+ return false;
+}
+
+
+
+//
+// Clear all properties
+//
+void CValue::ClearProperties()
+{
+ // Check if we have any properties
+ if (m_pNamedPropertyArray == NULL)
+ return;
+
+ // Remove all properties
+ for ( std::map<const STR_String,CValue*>::iterator it = m_pNamedPropertyArray->begin();
+ !(it == m_pNamedPropertyArray->end());it++)
+ {
+ CValue* tmpval = (*it).second;
+ STR_String name = (*it).first;
+ tmpval->Release();
+ }
+
+ // Delete property array
+ delete m_pNamedPropertyArray;
+ m_pNamedPropertyArray=NULL;
+}
+
+
+
+//
+// Set all properties' modified flag to <inModified>
+//
+void CValue::SetPropertiesModified(bool inModified)
+{
+ int numprops = GetPropertyCount();
+ for (int i=0; i<numprops; i++)
+ GetProperty(i)->SetModified(inModified);
+}
+
+
+
+//
+// Check if any of the properties in this value have been modified
+//
+bool CValue::IsAnyPropertyModified()
+{
+ int numprops = GetPropertyCount();
+ for (int i=0;i<numprops;i++)
+ if (GetProperty(i)->IsModified())
+ return true;
+
+ return false;
+}
+
+
+
+//
+// Get property number <inIndex>
+//
+
+CValue* CValue::GetProperty(int inIndex)
+{
+
+ int count=0;
+ CValue* result = NULL;
+
+ if (m_pNamedPropertyArray)
+ {
+ for ( std::map<const STR_String,CValue*>::iterator it = m_pNamedPropertyArray->begin();
+ !(it == m_pNamedPropertyArray->end());it++)
+ {
+ if (count++==inIndex)
+ {
+ result = (*it).second;
+ break;
+ }
+ }
+
+ }
+ return result;
+}
+
+
+
+//
+// Get the amount of properties assiocated with this value
+//
+int CValue::GetPropertyCount()
+{
+ if (m_pNamedPropertyArray)
+ return m_pNamedPropertyArray->size();
+ else
+ return 0;
+}
+
+
+
+
+
+void CValue::CloneProperties(CValue *replica)
+{
+
+ if (m_pNamedPropertyArray)
+ {
+ replica->m_pNamedPropertyArray=NULL;
+ for ( std::map<const STR_String,CValue*>::iterator it = m_pNamedPropertyArray->begin();
+ !(it == m_pNamedPropertyArray->end());it++)
+ {
+
+ replica->SetProperty((*it).first,(*it).second->GetReplica());
+ }
+ }
+
+
+}
+
+
+
+
+
+
+double* CValue::GetVector3(bool bGetTransformedVec)
+{
+ assertd(false); // don;t get vector from me
+ return m_sZeroVec;//::sZero;
+}
+
+
+
+
+
+
+/*---------------------------------------------------------------------------------------------------------------------
+ Reference Counting
+---------------------------------------------------------------------------------------------------------------------*/
+
+
+
+//
+// Add a reference to this value
+//
+CValue *CValue::AddRef()
+{
+ // Increase global reference count, used to see at the end of the program
+ // if all CValue-derived classes have been dereferenced to 0
+ //debug(gRefCountValue++);
+ m_refcount++;
+ return this;
+}
+
+
+
+//
+// Release a reference to this value (when reference count reaches 0, the value is removed from the heap)
+//
+int CValue::Release()
+{
+ // Decrease global reference count, used to see at the end of the program
+ // if all CValue-derived classes have been dereferenced to 0
+ //debug(gRefCountValue--);
+
+ // Decrease local reference count, if it reaches 0 the object should be freed
+ if (--m_refcount > 0)
+ {
+ // Reference count normal, return new reference count
+ return m_refcount;
+ }
+ else
+ {
+ // Reference count reached 0, delete ourselves and return 0
+// assert(m_refcount==0, "Reference count reached sub-zero, object released too much");
+ delete this;
+ return 0;
+ }
+
+}
+
+
+
+//
+// Disable reference counting for this value
+//
+void CValue::DisableRefCount()
+{
+ assertd(m_refcount == 1);
+ m_refcount--;
+
+ //debug(gRefCountValue--);
+ m_ValFlags.RefCountDisabled=true;
+}
+
+
+
+void CValue::AddDataToReplica(CValue *replica)
+{
+ replica->m_refcount = 1;
+#ifdef _DEBUG
+ //gRefCountValue++;
+#endif
+ replica->m_ValFlags.RefCountDisabled = false;
+
+ replica->ReplicaSetName(GetName());
+
+ //copy all props
+ CloneProperties(replica);
+}
+
+
+
+CValue* CValue::FindIdentifier(const STR_String& identifiername)
+{
+
+ CValue* result = NULL;
+
+ int pos = 0;
+ // if a dot exists, explode the name into pieces to get the subcontext
+ if ((pos=identifiername.Find('.'))>=0)
+ {
+ const STR_String rightstring = identifiername.Right(identifiername.Length() -1 - pos);
+ const STR_String leftstring = identifiername.Left(pos);
+ CValue* tempresult = GetProperty(leftstring);
+ if (tempresult)
+ {
+ result=tempresult->FindIdentifier(rightstring);
+ }
+ } else
+ {
+ result = GetProperty(identifiername);
+ }
+ if (result)
+ return result->AddRef();
+ // warning here !!!
+ result = new CErrorValue(identifiername+" not found");
+ return result;
+}
+
+
+#ifndef NO_EXP_PYTHON_EMBEDDING
+
+
+static PyMethodDef CValueMethods[] =
+{
+ //{ "new", CValue::PyMake , Py_NEWARGS},
+ { NULL,NULL} // Sentinel
+};
+
+
+PyObject* CValue::_getattr(char* attr)
+{
+ CValue* resultattr = FindIdentifier(attr);
+ STR_String text;
+ if (resultattr)
+ {
+ if (resultattr->IsError())
+ {
+ resultattr->Release();
+ } else
+ {
+ // to avoid some compare problems, return a real pythonthing
+ PyObject* pyconvert = resultattr->ConvertValueToPython();
+ if (pyconvert)
+ {
+ resultattr->Release();
+ return pyconvert;
+ } else
+ {
+ // also check if it's already in pythoninterpreter!
+ return resultattr;
+ }
+
+ }
+ }
+ _getattr_up(PyObjectPlus);
+}
+
+CValue* CValue::ConvertPythonToValue(PyObject* pyobj)
+{
+
+ CValue* vallie = NULL;
+
+ PyTypeObject* type = pyobj->ob_type;
+
+ if (type == &PyList_Type)
+ {
+ CListValue* listval = new CListValue();
+ bool error = false;
+
+ int i;
+ int numitems = PyList_Size(pyobj);
+ for (i=0;i<numitems;i++)
+ {
+ PyObject* listitem = PyList_GetItem(pyobj,i);
+ CValue* listitemval = ConvertPythonToValue(listitem);
+ if (listitemval)
+ {
+ listval->Add(listitemval);
+ } else
+ {
+ error = true;
+ }
+ }
+ if (!error)
+ {
+ // jippie! could be converted
+ vallie = listval;
+ } else
+ {
+ // list could not be converted... bad luck
+ listval->Release();
+ }
+
+ } else
+ if (type == &PyFloat_Type)
+ {
+ float fl;
+ PyArg_Parse(pyobj,"f",&fl);
+ vallie = new CFloatValue(fl);
+ } else
+ if (type==&PyInt_Type)
+ {
+ int innie;
+ PyArg_Parse(pyobj,"i",&innie);
+ vallie = new CIntValue(innie);
+ } else
+
+ if (type==&PyString_Type)
+ {
+ vallie = new CStringValue(PyString_AsString(pyobj),"");
+ } else
+ if (type==&CValue::Type || type==&CListValue::Type)
+ {
+ vallie = ((CValue*) pyobj)->AddRef();
+ }
+ return vallie;
+
+}
+int CValue::_setattr(char* attr,PyObject* pyobj)
+{
+
+ if (!pyobj) { // member deletion
+ RemoveProperty(attr);
+ return 0;
+ }
+
+ CValue* vallie = ConvertPythonToValue(pyobj);
+ if (vallie)
+ {
+ CValue* oldprop = GetProperty(attr);
+
+ if (oldprop)
+ {
+ oldprop->SetValue(vallie);
+ } else
+ {
+ SetProperty(attr,vallie->AddRef());
+ }
+ vallie->Release();
+ }
+
+ //PyObjectPlus::_setattr(attr,value);
+ return 0;
+};
+/*
+PyObject* CValue::PyMake(PyObject* ignored,PyObject* args)
+{
+
+ //Py_Try(PyArg_ParseTuple(args,"s",&name));
+ Py_INCREF(Py_None);
+ return Py_None;//new CValue();
+}
+*/
+
+extern "C" {
+ void initCValue(void)
+ {
+ Py_InitModule("CValue",CValueMethods);
+ }
+}
+
+
+
+#endif //NO_EXP_PYTHON_EMBEDDING
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
+/* These implementations were moved out of the header */
+
+void CValue::SetOwnerExpression(class CExpression* expr)
+{
+ /* intentionally empty */
+}
+
+void CValue::SetColorOperator(VALUE_OPERATOR op)
+{
+ /* intentionally empty */
+}
+void CValue::SetValue(CValue* newval)
+{
+ // no one should get here
+ assertd(newval->GetNumber() == 10121969);
+}
+///////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
+
diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h
new file mode 100644
index 00000000000..8131cc152bc
--- /dev/null
+++ b/source/gameengine/Expressions/Value.h
@@ -0,0 +1,467 @@
+/*
+ * Value.h: interface for the CValue class.
+ * $Id$
+ * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifdef WIN32
+#pragma warning (disable:4786)
+#endif //WIN32
+
+/////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////
+////
+//// Baseclass CValue
+//// Together with CExpression, CValue and it's derived classes can be used to
+//// parse expressions into a parsetree with error detecting/correcting capabilities
+//// also expandible by a CFactory pluginsystem
+////
+//// Features:
+//// Reference Counting (AddRef() / Release())
+//// Calculations (Calc() / CalcFinal())
+//// Configuration (Configure())
+//// Serialization (EdSerialize() / EdIdSerialize() / EdPtrSerialize() and macro PLUGIN_DECLARE_SERIAL
+//// Property system (SetProperty() / GetProperty() / FindIdentifier())
+//// Replication (GetReplica())
+//// Flags (IsSelected() / IsModified() / SetSelected()...)
+////
+//// Some small editor-specific things added
+//// A helperclass CompressorArchive handles the serialization
+////
+////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////
+#ifndef __VALUE_H__
+#define __VALUE_H__
+
+#include <map> // array functionality for the propertylist
+#include "STR_String.h" // STR_String class
+
+
+
+
+#ifndef GEN_NO_ASSERT
+#undef assert
+#define assert(exp) ((void)NULL)
+#endif
+
+
+#ifndef GEN_NO_TRACE
+#undef trace
+#define trace(exp) ((void)NULL)
+#endif
+
+#ifndef GEN_NO_DEBUG
+#undef debug
+#define debug(exp) ((void)NULL)
+#endif
+
+
+
+
+#ifndef GEN_NO_ASSERTD
+#undef assertd
+#define assertd(exp) ((void)NULL)
+#endif
+
+
+#ifndef USE_PRAGMA_ONCE
+#ifdef WIN32
+ #pragma once
+
+#endif //WIN32
+#endif
+
+#define EDITOR_LEVEL_VERSION 0x06
+
+enum VALUE_OPERATOR {
+
+ VALUE_ADD_OPERATOR, // +
+ VALUE_SUB_OPERATOR, // -
+ VALUE_MUL_OPERATOR, // *
+ VALUE_DIV_OPERATOR, // /
+ VALUE_NEG_OPERATOR, // -
+ VALUE_POS_OPERATOR, // +
+ VALUE_AND_OPERATOR, // &&
+ VALUE_OR_OPERATOR, // ||
+ VALUE_EQL_OPERATOR, // ==
+ VALUE_NEQ_OPERATOR, // !=
+ VALUE_GRE_OPERATOR, // >
+ VALUE_LES_OPERATOR, // <
+ VALUE_GEQ_OPERATOR, // >=
+ VALUE_LEQ_OPERATOR, // <=
+ VALUE_NOT_OPERATOR, // !
+ VALUE_NO_OPERATOR // no operation at all
+};
+
+enum VALUE_DATA_TYPE {
+ VALUE_NO_TYPE, // abstract baseclass
+ VALUE_INT_TYPE,
+ VALUE_FLOAT_TYPE,
+ VALUE_STRING_TYPE,
+ VALUE_BOOL_TYPE,
+ VALUE_ERROR_TYPE,
+ VALUE_EMPTY_TYPE,
+ VALUE_SOLID_TYPE,
+ VALUE_COMBISOLID_TYPE,
+ VALUE_VECTOR_TYPE,
+ VALUE_MENU_TYPE,
+ VALUE_ACTOR_TYPE,
+ VALUE_MAX_TYPE //only here to provide number of types
+};
+
+
+
+#ifdef _DEBUG
+//extern int gRefCountValue; // debugonly variable to check if all CValue Refences are Dereferenced at programexit
+#endif
+
+struct HashableInt
+{
+ HashableInt(int id) : mData(id) { }
+
+ unsigned long Hash() const { return 0;} ////}gHash(&mData, sizeof(int));}
+
+ bool operator==(HashableInt rhs) { return mData == rhs.mData; }
+
+ int mData;
+};
+
+
+//
+// Bitfield that stores the flags for each CValue derived class
+//
+struct ValueFlags {
+ ValueFlags() :
+ Modified(true),
+ Selected(false),
+ Affected(false),
+ ReleaseRequested(false),
+ Error(false),
+ RefCountDisabled(false),
+ HasProperties(false),
+ HasName(false),
+ Visible(true),
+ CustomFlag1(false),
+ CustomFlag2(false)
+ {
+ }
+
+ unsigned short Modified : 1;
+ unsigned short Selected : 1;
+ unsigned short Affected : 1;
+ unsigned short ReleaseRequested : 1;
+ unsigned short Error : 1;
+ unsigned short RefCountDisabled : 1;
+ unsigned short HasProperties : 1;
+ unsigned short HasName : 1;
+ unsigned short Visible : 1;
+ unsigned short CustomFlag1 : 1;
+ unsigned short CustomFlag2 : 1;
+
+
+};
+
+/**
+ * Base Class for all Actions performed on CValue's. Can be extended for undo/redo system in future.
+*/
+class CAction
+{
+public:
+ CAction() {
+ };
+ virtual ~CAction(){
+ };
+ virtual void Execute() const =0;
+};
+
+//
+// CValue
+//
+// Base class for all editor functionality, flexible object type that allows
+// calculations and uses reference counting for memory management.
+//
+//
+
+/**
+ * These macros are helpfull when embedding Python routines. The second
+ * macro is one that also requires a documentation string
+ */
+#define KX_PYMETHOD(class_name, method_name) \
+ PyObject* Py##method_name(PyObject* self, PyObject* args, PyObject* kwds); \
+ static PyObject* sPy##method_name( PyObject* self, PyObject* args, PyObject* kwds) { \
+ return ((class_name*) self)->Py##method_name(self, args, kwds); \
+ }; \
+
+#define KX_PYMETHOD_DOC(class_name, method_name) \
+ PyObject* Py##method_name(PyObject* self, PyObject* args, PyObject* kwds); \
+ static PyObject* sPy##method_name( PyObject* self, PyObject* args, PyObject* kwds) { \
+ return ((class_name*) self)->Py##method_name(self, args, kwds); \
+ }; \
+ static char method_name##_doc[]; \
+
+/* The line above should remain empty */
+
+#ifndef NO_EXP_PYTHON_EMBEDDING
+#include "PyObjectPlus.h"
+#include "object.h"
+class CValue : public PyObjectPlus
+#else
+class CValue
+#endif //NO_EXP_PYTHON_EMBEDDING
+
+
+{
+#ifndef NO_EXP_PYTHON_EMBEDDING
+Py_Header;
+#endif //NO_EXP_PYTHON_EMBEDDING
+public:
+ enum AllocationTYPE {
+ STACKVALUE = 0,
+ HEAPVALUE = 1
+ };
+
+ enum DrawTYPE {
+ STARTFRAME = 0,
+ ENDFRAME = 1,
+ INTERFRAME = 2
+ };
+
+
+ // Construction / Destruction
+#ifndef NO_EXP_PYTHON_EMBEDDING
+
+ CValue(PyTypeObject *T = &Type);
+ //static PyObject* PyMake(PyObject*,PyObject*);
+ virtual PyObject *_repr(void)
+ {
+ return Py_BuildValue("s",(const char*)GetText());
+ }
+
+
+
+ PyObject* _getattr(char* attr);
+
+ void SpecialRelease()
+ {
+ int i=0;
+ if (ob_refcnt == 0)
+ {
+ _Py_NewReference(this);
+
+ } else
+ {
+ i++;
+ }
+ Release();
+ }
+ static void PyDestructor(PyObject *P) // python wrapper
+ {
+ ((CValue*)P)->SpecialRelease();
+ };
+
+ virtual PyObject* ConvertValueToPython() {
+ return NULL;
+ }
+
+ virtual CValue* ConvertPythonToValue(PyObject* pyobj);
+
+
+ int _setattr(char* attr,PyObject* value);
+
+ KX_PYMETHOD(CValue,GetName);
+
+#else
+ CValue();
+#endif //NO_EXP_PYTHON_EMBEDDING
+
+
+
+ // Expression Calculation
+ virtual CValue* Calc(VALUE_OPERATOR op, CValue *val) = 0;
+ virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val) = 0;
+ virtual void SetOwnerExpression(class CExpression* expr);
+
+
+
+ void Execute(const CAction& a)
+ {
+ a.Execute();
+ };
+
+ /// Reference Counting
+ int GetRefCount() { return m_refcount; }
+ virtual CValue* AddRef(); // Add a reference to this value
+ virtual int Release(); // Release a reference to this value (when reference count reaches 0, the value is removed from the heap)
+
+ /// Property Management
+ virtual void SetProperty(const STR_String& name,CValue* ioProperty); // Set property <ioProperty>, overwrites and releases a previous property with the same name if needed
+ virtual CValue* GetProperty(const STR_String & inName); // Get pointer to a property with name <inName>, returns NULL if there is no property named <inName>
+ STR_String GetPropertyText(const STR_String & inName,const STR_String& deftext=""); // Get text description of property with name <inName>, returns an empty string if there is no property named <inName>
+ float GetPropertyNumber(const STR_String& inName,float defnumber);
+ virtual bool RemoveProperty(const STR_String & inName); // Remove the property named <inName>, returns true if the property was succesfully removed, false if property was not found or could not be removed
+ virtual void ClearProperties(); // Clear all properties
+
+ virtual void SetPropertiesModified(bool inModified); // Set all properties' modified flag to <inModified>
+ virtual bool IsAnyPropertyModified(); // Check if any of the properties in this value have been modified
+
+ virtual CValue* GetProperty(int inIndex); // Get property number <inIndex>
+ virtual int GetPropertyCount(); // Get the amount of properties assiocated with this value
+
+ virtual void CloneProperties(CValue* replica);
+ virtual CValue* FindIdentifier(const STR_String& identifiername);
+ /** Set the wireframe color of this value depending on the CSG
+ * operator type <op>
+ * @attention: not implemented */
+ virtual void SetColorOperator(VALUE_OPERATOR op);
+
+ virtual const STR_String & GetText() = 0;
+ virtual float GetNumber() = 0;
+ double* ZeroVector() { return m_sZeroVec; };
+ virtual double* GetVector3(bool bGetTransformedVec = false);
+
+ virtual STR_String GetName() = 0; // Retrieve the name of the value
+ virtual void SetName(STR_String name) = 0; // Set the name of the value
+ virtual void ReplicaSetName(STR_String name) = 0;
+ /** Sets the value to this cvalue.
+ * @attention this particular function should never be called. Why not abstract? */
+ virtual void SetValue(CValue* newval);
+ virtual CValue* GetReplica() =0;
+ //virtual CValue* Copy() = 0;
+
+
+ STR_String op2str(VALUE_OPERATOR op);
+
+ // setting / getting flags
+ inline void SetSelected(bool bSelected) { m_ValFlags.Selected = bSelected; }
+ virtual void SetModified(bool bModified) { m_ValFlags.Modified = bModified; }
+ virtual void SetAffected(bool bAffected=true) { m_ValFlags.Affected = bAffected; }
+ inline void SetReleaseRequested(bool bReleaseRequested) { m_ValFlags.ReleaseRequested=bReleaseRequested; }
+ inline void SetError(bool err) { m_ValFlags.Error=err; }
+ inline void SetVisible (bool vis) { m_ValFlags.Visible=vis; }
+
+ virtual bool IsModified() { return m_ValFlags.Modified; }
+ inline bool IsError() { return m_ValFlags.Error; }
+ virtual bool IsAffected() { return m_ValFlags.Affected || m_ValFlags.Modified; }
+ virtual bool IsSelected() { return m_ValFlags.Selected; }
+ inline bool IsReleaseRequested() { return m_ValFlags.ReleaseRequested; }
+ virtual bool IsVisible() { return m_ValFlags.Visible;}
+ virtual void SetCustomFlag1(bool bCustomFlag) { m_ValFlags.CustomFlag1 = bCustomFlag;};
+ virtual bool IsCustomFlag1() { return m_ValFlags.CustomFlag1;};
+
+ virtual void SetCustomFlag2(bool bCustomFlag) { m_ValFlags.CustomFlag2 = bCustomFlag;};
+ virtual bool IsCustomFlag2() { return m_ValFlags.CustomFlag2;};
+
+protected:
+ virtual void DisableRefCount(); // Disable reference counting for this value
+ virtual void AddDataToReplica(CValue* replica);
+ virtual ~CValue();
+private:
+ // Member variables
+ std::map<const STR_String,CValue*>* m_pNamedPropertyArray; // Properties for user/game etc
+ ValueFlags m_ValFlags; // Frequently used flags in a bitfield (low memoryusage)
+ int m_refcount; // Reference Counter
+ static double m_sZeroVec[3];
+
+};
+
+
+
+//
+// Declare a CValue or CExpression or CWhatever to be serialized by the editor.
+//
+// This macro introduces the EdSerialize() function (which must be implemented by
+// the client) and the EdIdSerialize() function (which is implemented by this macro).
+//
+// The generated Copy() function returns a pointer to <root_base_class_name> type
+// of object. So, for *any* CValue-derived object this should be set to CValue,
+// for *any* CExpression-derived object this should be set to CExpression.
+//
+#define PLUGIN_DECLARE_SERIAL(class_name, root_base_class_name) \
+public: \
+ virtual root_base_class_name * Copy() { return new class_name; } \
+ virtual bool EdSerialize(CompressorArchive& arch,class CFactoryManager* facmgr,bool bIsStoring); \
+ virtual bool EdIdSerialize(CompressorArchive& arch,class CFactoryManager* facmgr,bool bIsStoring) \
+{ \
+ if (bIsStoring) \
+ arch.StoreString(#class_name); \
+ \
+ return false; \
+} \
+
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+// CPropValue is a CValue derived class, that implements the identification (String name)
+// SetName() / GetName(),
+// normal classes should derive from CPropValue, real lightweight classes straight from CValue
+
+
+class CPropValue : public CValue
+{
+public:
+
+#ifndef NO_EXP_PYTHON_EMBEDDING
+ CPropValue(PyTypeObject* T=&Type) :
+ CValue(T),
+#else
+ CPropValue() :
+#endif //NO_EXP_PYTHON_EMBEDDING
+ m_pstrNewName(NULL)
+
+ {
+ }
+
+ virtual ~CPropValue()
+ {
+ if (m_pstrNewName)
+ {
+ delete m_pstrNewName;
+ m_pstrNewName = NULL;
+ }
+ }
+
+ virtual void SetName(STR_String name) {
+ if (m_pstrNewName)
+ {
+ delete m_pstrNewName;
+ m_pstrNewName = NULL;
+ }
+ if (name.Length())
+ m_pstrNewName = new STR_String(name);
+ }
+ virtual void ReplicaSetName(STR_String name) {
+ m_pstrNewName=NULL;
+ if (name.Length())
+ m_pstrNewName = new STR_String(name);
+ }
+
+ virtual STR_String GetName() {
+ //STR_String namefromprop = GetPropertyText("Name");
+ //if (namefromprop.Length() > 0)
+ // return namefromprop;
+
+ if (m_pstrNewName)
+ {
+ return *m_pstrNewName;
+ }
+ return STR_String("");
+ }; // name of Value
+
+protected:
+ STR_String* m_pstrNewName; // Identification
+};
+
+
+
+#endif // !defined _VALUEBASECLASS_H
diff --git a/source/gameengine/Expressions/VectorValue.cpp b/source/gameengine/Expressions/VectorValue.cpp
new file mode 100644
index 00000000000..6aa7926bfa7
--- /dev/null
+++ b/source/gameengine/Expressions/VectorValue.cpp
@@ -0,0 +1,213 @@
+// VectorValue.cpp: implementation of the CVectorValue class.
+/*
+ * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifdef WIN32
+#pragma warning (disable:4786)
+#endif
+
+#include "Value.h"
+#include "VectorValue.h"
+#include "ErrorValue.h"
+//#include "MatrixValue.h"
+#include "VoidValue.h"
+#include "StringValue.h"
+//#include "FactoryManager.h"
+
+
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CVectorValue::CVectorValue(float x,float y,float z, AllocationTYPE alloctype)
+{
+ SetCustomFlag1(false);//FancyOutput=false;
+
+ if (alloctype == STACKVALUE)
+ {
+ CValue::DisableRefCount();
+ };
+
+ m_vec[KX_X] = m_transformedvec[KX_X] = x;
+ m_vec[KX_Y] = m_transformedvec[KX_Y] = y;
+ m_vec[KX_Z] = m_transformedvec[KX_Z] = z;
+
+}
+CVectorValue::CVectorValue(double vec[],STR_String name,AllocationTYPE alloctype) {
+
+ SetCustomFlag1(false);//FancyOutput=false;
+
+ m_vec[KX_X] = m_transformedvec[KX_X] = vec[KX_X];
+ m_vec[KX_Y] = m_transformedvec[KX_Y] = vec[KX_Y];
+ m_vec[KX_Z] = m_transformedvec[KX_Z] = vec[KX_Z];
+
+ if (alloctype == STACKVALUE)
+ {
+ CValue::DisableRefCount();
+
+ }
+
+ SetName(name);
+}
+
+CVectorValue::CVectorValue(double vec[],AllocationTYPE alloctype) {
+
+ SetCustomFlag1(false);//FancyOutput=false;
+
+ m_vec[KX_X] = m_transformedvec[KX_X] = vec[KX_X];
+ m_vec[KX_Y] = m_transformedvec[KX_Y] = vec[KX_Y];
+ m_vec[KX_Z] = m_transformedvec[KX_Z] = vec[KX_Z];
+
+ if (alloctype == STACKVALUE)
+ {
+ CValue::DisableRefCount();
+
+ }
+
+
+}
+CVectorValue::~CVectorValue()
+{
+
+}
+
+CValue* CVectorValue::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val)
+/*
+pre: the type of val is dtype
+ret: a new object containing the result of applying operator op to val and
+this object
+*/
+{
+ CValue *ret = NULL;
+
+ switch(op)
+ {
+ case VALUE_ADD_OPERATOR:
+ {
+ switch (dtype)
+ {
+ case VALUE_EMPTY_TYPE:
+ case VALUE_VECTOR_TYPE:
+ {
+ ret = new CVectorValue(
+ val->GetVector3()[KX_X] + GetVector3()[KX_X],
+ val->GetVector3()[KX_Y] + GetVector3()[KX_Y],
+ val->GetVector3()[KX_Z] + GetVector3()[KX_Z],
+ CValue::HEAPVALUE);
+ ret->SetName(GetName());
+ break;
+ }
+
+ default:
+ ret = new CErrorValue(val->GetText() + op2str(op) + GetText());
+ }
+ break;
+ }
+ case VALUE_MUL_OPERATOR:
+ {
+ switch (dtype)
+ {
+
+ case VALUE_EMPTY_TYPE:
+ case VALUE_VECTOR_TYPE:
+ {
+ //MT_Vector3 supports 'scaling' by another vector, instead of using general transform, Gino?
+ //ret = new CVectorValue(val->GetVector3().Scaled(GetVector3()),GetName());
+ break;
+ }
+ case VALUE_FLOAT_TYPE:
+ {
+ ret = new CVectorValue(
+ val->GetVector3()[KX_X] * GetVector3()[KX_X],
+ val->GetVector3()[KX_Y] * GetVector3()[KX_Y],
+ val->GetVector3()[KX_Z] * GetVector3()[KX_Z],
+ CValue::HEAPVALUE);
+ ret->SetName(GetName());
+ break;
+ }
+
+ default:
+ ret = new CErrorValue(val->GetText() + op2str(op) + GetText());
+ }
+ break;
+
+ }
+
+ default:
+ ret = new CErrorValue(val->GetText() + op2str(op) + GetText());
+ }
+
+
+ return ret;
+}
+
+float CVectorValue::GetNumber()
+{
+ return m_vec[KX_X];
+}
+
+
+double* CVectorValue::GetVector3(bool bGetTransformedVec)
+{
+ if (bGetTransformedVec)
+ return m_transformedvec;
+ // else
+ return m_vec;
+}
+
+
+
+
+
+void CVectorValue::SetVector(double newvec[])
+{
+ m_vec[KX_X] = m_transformedvec[KX_X] = newvec[KX_X];
+ m_vec[KX_Y] = m_transformedvec[KX_Y] = newvec[KX_Y];
+ m_vec[KX_Z] = m_transformedvec[KX_Z] = newvec[KX_Z];
+
+ SetModified(true);
+}
+
+
+void CVectorValue::SetValue(CValue *newval)
+{
+
+ double* newvec = ((CVectorValue*)newval)->GetVector3();
+ m_vec[KX_X] = m_transformedvec[KX_X] = newvec[KX_X];
+ m_vec[KX_Y] = m_transformedvec[KX_Y] = newvec[KX_Y];
+ m_vec[KX_Z] = m_transformedvec[KX_Z] = newvec[KX_Z];
+
+ SetModified(true);
+}
+
+static const STR_String gstrVectorStr=STR_String();
+const STR_String & CVectorValue::GetText()
+{
+ assertd(false);
+ return gstrVectorStr;
+}
+
+CValue* CVectorValue::GetReplica() {
+ CVectorValue* replica = new CVectorValue(*this);
+ CValue::AddDataToReplica(replica);
+ return replica;
+};
+
+/*void CVectorValue::Transform(rcMatrix4x4 mat)
+{
+ m_transformedvec = mat*m_vec;
+}
+*/
+
+
diff --git a/source/gameengine/Expressions/VectorValue.h b/source/gameengine/Expressions/VectorValue.h
new file mode 100644
index 00000000000..8ed671721a3
--- /dev/null
+++ b/source/gameengine/Expressions/VectorValue.h
@@ -0,0 +1,86 @@
+/*
+ * VectorValue.h: interface for the CVectorValue class.
+ * $Id$
+ * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+#if !defined _VECTORVALUE_H
+#define _VECTORVALUE_H
+
+
+#include "Value.h"
+
+#define KX_X 0
+#define KX_Y 1
+#define KX_Z 2
+
+
+class CVectorValue : public CPropValue
+{
+ //PLUGIN_DECLARE_SERIAL(CVectorValue,CValue)
+
+public:
+ //void Transform(rcMatrix4x4 mat);
+ virtual void SetValue(CValue* newval);
+ void SetVector(double newvec[]);
+ void Configure(CValue* menuvalue);
+ virtual double* GetVector3(bool bGetTransformedVec=false);
+ virtual float GetNumber();
+
+ CValue* Calc(VALUE_OPERATOR op, CValue *val) {
+ return val->CalcFinal(VALUE_VECTOR_TYPE, op, this);
+ }
+
+ CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val);
+
+
+ CVectorValue(double vec[],STR_String name,AllocationTYPE alloctype=CValue::HEAPVALUE);
+ CVectorValue() {};
+
+ CVectorValue(double vec[],AllocationTYPE alloctype=CValue::HEAPVALUE);
+ CVectorValue(float x,float y,float z, AllocationTYPE alloctype = CValue::HEAPVALUE);
+ virtual ~CVectorValue();
+ //virtual bool ExportT3D(File *txtfile,bool bNoName=false);
+ void AddConfigurationData(CValue* menuvalue);
+
+
+
+ virtual CValue* GetReplica();
+ virtual const STR_String & GetText();
+
+/*
+ void SnapPoint(float num,int snap)
+ {
+ if (num > 0) num += ((float)snap / 2);
+ else num -= ((float)snap / 2);
+ num = (long)(((long)(num / snap)) * snap);
+ };
+
+ void SnapPosition(const double snapvec[])
+ {
+
+ if (snapvec[KX_X] >= 1)
+ SnapPoint(m_vec[KX_X],snapvec[KX_X]);
+ if (snapvec[KX_Y] >= 1)
+ SnapPoint(m_vec[KX_Y],snapvec[KX_Y]);
+ if (snapvec[KX_Z] >= 1)
+ SnapPoint(m_vec[KX_Z],snapvec[KX_Z]);
+
+ }
+*/
+
+protected:
+ double m_vec[3];
+ double m_transformedvec[3];
+};
+
+#endif // !defined _VECTORVALUE_H
+
diff --git a/source/gameengine/Expressions/VoidValue.h b/source/gameengine/Expressions/VoidValue.h
new file mode 100644
index 00000000000..5cf40268b97
--- /dev/null
+++ b/source/gameengine/Expressions/VoidValue.h
@@ -0,0 +1,68 @@
+/**
+ * VoidValue.h: interface for the CVoidValue class.
+ * $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 __VOIDVALUE_H__
+#define __VOIDVALUE_H__
+
+#include "Value.h"
+
+
+//
+// Void value, used to transport *any* type of data
+//
+class CVoidValue : public CPropValue
+{
+ //PLUGIN_DECLARE_SERIAL (CVoidValue,CValue)
+
+public:
+ /// Construction/destruction
+ CVoidValue() : m_pAnything(NULL), m_bDeleteOnDestruct(false) { }
+ CVoidValue(void * voidptr, bool bDeleteOnDestruct, AllocationTYPE alloctype) : m_pAnything(voidptr), m_bDeleteOnDestruct(bDeleteOnDestruct) { if (alloctype == STACKVALUE) CValue::DisableRefCount(); }
+ virtual ~CVoidValue(); // Destruct void value, delete memory if we're owning it
+
+ /// Value -> String or number
+ virtual const STR_String & GetText(); // Get string description of void value (unimplemented)
+ virtual float GetNumber() { return -1; }
+
+ /// Value calculation
+ virtual CValue* Calc(VALUE_OPERATOR op, CValue *val);
+ virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue* val);
+
+ /// Value replication
+ virtual CValue* GetReplica();
+
+ /// Data members
+ bool m_bDeleteOnDestruct;
+ void* m_pAnything;
+};
+
+#endif // !defined _VOIDVALUE_H
diff --git a/source/gameengine/GameLogic/Makefile b/source/gameengine/GameLogic/Makefile
new file mode 100644
index 00000000000..6de9ba0b145
--- /dev/null
+++ b/source/gameengine/GameLogic/Makefile
@@ -0,0 +1,47 @@
+#
+# $Id$
+#
+# ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version. The Blender
+# Foundation also sells licenses for use in proprietary software under
+# the Blender License. See http://www.blender.org/BL/ for information
+# about this.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): none yet.
+#
+# ***** END GPL/BL DUAL LICENSE BLOCK *****
+#
+#
+
+LIBNAME = logic
+DIR = $(OCGDIR)/gameengine/$(LIBNAME)
+
+include nan_compile.mk
+
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+CPPFLAGS += -I../Expressions
+CPPFLAGS += -I$(NAN_STRING)/include
+CPPFLAGS += -I$(NAN_MOTO)/include
+CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
+CPPFLAGS += -I../../kernel/gen_system
+CPPFLAGS += -I../Ketsji
+
diff --git a/source/gameengine/GameLogic/SCA_ANDController.cpp b/source/gameengine/GameLogic/SCA_ANDController.cpp
new file mode 100644
index 00000000000..3dc20490819
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_ANDController.cpp
@@ -0,0 +1,143 @@
+/**
+ * 'And' together all inputs
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "SCA_ANDController.h"
+#include "SCA_ISensor.h"
+#include "SCA_LogicManager.h"
+#include "BoolValue.h"
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_ANDController::SCA_ANDController(SCA_IObject* gameobj,
+ PyTypeObject* T)
+ :
+ SCA_IController(gameobj,T)
+{
+}
+
+
+
+SCA_ANDController::~SCA_ANDController()
+{
+}
+
+
+
+void SCA_ANDController::Trigger(SCA_LogicManager* logicmgr)
+{
+
+ bool sensorresult = true;
+
+ for (vector<SCA_ISensor*>::const_iterator is=m_linkedsensors.begin();
+ !(is==m_linkedsensors.end());is++)
+ {
+ SCA_ISensor* sensor = *is;
+ if (!sensor->IsPositiveTrigger())
+ {
+ sensorresult = false;
+ break;
+ }
+ }
+
+ CValue* newevent = new CBoolValue(sensorresult);
+
+ for (vector<SCA_IActuator*>::const_iterator i=m_linkedactuators.begin();
+ !(i==m_linkedactuators.end());i++)
+ {
+ SCA_IActuator* actua = *i;//m_linkedactuators.at(i);
+ logicmgr->AddActiveActuator(actua,newevent);
+ }
+
+ // every actuator that needs the event, has a it's own reference to it now so
+ // release it (so to be clear: if there is no actuator, it's deleted right now)
+ newevent->Release();
+
+}
+
+
+
+CValue* SCA_ANDController::GetReplica()
+{
+ CValue* replica = new SCA_ANDController(*this);
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_ANDController::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_ANDController",
+ sizeof(SCA_ANDController),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_ANDController::Parents[] = {
+ &SCA_ANDController::Type,
+ &SCA_IController::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef SCA_ANDController::Methods[] = {
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* SCA_ANDController::_getattr(char* attr) {
+ _getattr_up(SCA_IController);
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_ANDController.h b/source/gameengine/GameLogic/SCA_ANDController.h
new file mode 100644
index 00000000000..a7d54004f90
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_ANDController.h
@@ -0,0 +1,58 @@
+/**
+ * SCA_ANDController.h
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_ANDCONTROLLER
+#define __KX_ANDCONTROLLER
+
+#include "SCA_IController.h"
+
+class SCA_ANDController : public SCA_IController
+{
+ Py_Header;
+ //virtual void Trigger(class SCA_LogicManager* logicmgr);
+public:
+ SCA_ANDController(SCA_IObject* gameobj,PyTypeObject* T=&Type);
+ virtual ~SCA_ANDController();
+ virtual CValue* GetReplica();
+ virtual void Trigger(SCA_LogicManager* logicmgr);
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(char *attr);
+
+};
+
+#endif //__KX_ANDCONTROLLER
diff --git a/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp b/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp
new file mode 100644
index 00000000000..0e2db162ec3
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp
@@ -0,0 +1,67 @@
+/**
+ * Manager for 'always' events. Since always sensors can operate in pulse
+ * mode, they need to be activated.
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "SCA_AlwaysEventManager.h"
+#include "SCA_LogicManager.h"
+#include <vector>
+#include "SCA_ISensor.h"
+
+using namespace std;
+
+
+
+SCA_AlwaysEventManager::SCA_AlwaysEventManager(class SCA_LogicManager* logicmgr)
+ : m_logicmgr(logicmgr),
+ SCA_EventManager(ALWAYS_EVENTMGR)
+{
+}
+
+
+
+void SCA_AlwaysEventManager::NextFrame(double curtime,double deltatime)
+{
+ for (vector<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++)
+ {
+ SCA_ISensor* sensor = *i;
+ sensor->Activate(m_logicmgr, NULL);
+ }
+}
+
+
+
+void SCA_AlwaysEventManager::RegisterSensor(SCA_ISensor* sensor)
+{
+ m_sensors.push_back(sensor);
+}
diff --git a/source/gameengine/GameLogic/SCA_AlwaysEventManager.h b/source/gameengine/GameLogic/SCA_AlwaysEventManager.h
new file mode 100644
index 00000000000..0fbf02c5212
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_AlwaysEventManager.h
@@ -0,0 +1,48 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef __KX_ALWAYSEVENTMGR
+#define __KX_ALWAYSEVENTMGR
+#include "SCA_EventManager.h"
+#include <vector>
+using namespace std;
+class SCA_AlwaysEventManager : public SCA_EventManager
+{
+
+ class SCA_LogicManager* m_logicmgr;
+public:
+ SCA_AlwaysEventManager(class SCA_LogicManager* logicmgr);
+ virtual void NextFrame(double curtime,double deltatime);
+ virtual void RegisterSensor(SCA_ISensor* sensor);
+
+
+};
+#endif //__KX_ALWAYSEVENTMGR
diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp
new file mode 100644
index 00000000000..cf78d109e16
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp
@@ -0,0 +1,138 @@
+/**
+ * Always trigger
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifdef WIN32
+// This warning tells us about truncation of __long__ stl-generated names.
+// It can occasionally cause DevStudio to have internal compiler warnings.
+#pragma warning( disable : 4786 )
+#endif
+
+#include "SCA_AlwaysSensor.h"
+#include "SCA_LogicManager.h"
+#include "SCA_EventManager.h"
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_AlwaysSensor::SCA_AlwaysSensor(class SCA_EventManager* eventmgr,
+ SCA_IObject* gameobj,
+ PyTypeObject* T)
+ : SCA_ISensor(gameobj,eventmgr, T)
+{
+ //SetDrawColor(255,0,0);
+ m_alwaysresult = true;
+}
+
+
+
+SCA_AlwaysSensor::~SCA_AlwaysSensor()
+{
+ /* intentionally empty */
+}
+
+
+
+CValue* SCA_AlwaysSensor::GetReplica()
+{
+ CValue* replica = new SCA_AlwaysSensor(*this);//m_float,GetName());
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+bool SCA_AlwaysSensor::IsPositiveTrigger()
+{
+ return (m_invert ? false : true);
+}
+
+
+
+bool SCA_AlwaysSensor::Evaluate(CValue* event)
+{
+ /* Nice! :) */
+ //return true;
+ /* even nicer ;) */
+ //return false;
+
+ /* nicest ! */
+ bool result = m_alwaysresult;
+ m_alwaysresult = false;
+ return result;
+}
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_AlwaysSensor::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_AlwaysSensor",
+ sizeof(SCA_AlwaysSensor),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_AlwaysSensor::Parents[] = {
+ &SCA_AlwaysSensor::Type,
+ &SCA_ISensor::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef SCA_AlwaysSensor::Methods[] = {
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* SCA_AlwaysSensor::_getattr(char* attr) {
+ _getattr_up(SCA_ISensor);
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.h b/source/gameengine/GameLogic/SCA_AlwaysSensor.h
new file mode 100644
index 00000000000..c6ff571be8a
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.h
@@ -0,0 +1,62 @@
+/**
+ * SCA_AlwaysSensor.h
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_ALWAYSSENSOR
+#define __KX_ALWAYSSENSOR
+#include "SCA_ISensor.h"
+
+
+class SCA_AlwaysSensor : public SCA_ISensor
+{
+ Py_Header;
+ bool m_alwaysresult;
+public:
+ SCA_AlwaysSensor(class SCA_EventManager* eventmgr,
+ SCA_IObject* gameobj,
+ PyTypeObject* T =&Type);
+ virtual ~SCA_AlwaysSensor();
+ virtual CValue* GetReplica();
+ virtual bool Evaluate(CValue* event);
+ virtual bool IsPositiveTrigger();
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(char *attr);
+
+
+};
+
+#endif //__KX_ALWAYSSENSOR
diff --git a/source/gameengine/GameLogic/SCA_EventManager.cpp b/source/gameengine/GameLogic/SCA_EventManager.cpp
new file mode 100644
index 00000000000..a6ce3a1af25
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_EventManager.cpp
@@ -0,0 +1,71 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+
+#include "SCA_EventManager.h"
+
+
+
+SCA_EventManager::SCA_EventManager(EVENT_MANAGER_TYPE mgrtype)
+ :m_mgrtype(mgrtype)
+{
+}
+
+
+
+SCA_EventManager::~SCA_EventManager()
+{
+}
+
+
+
+void SCA_EventManager::RemoveSensor(class SCA_ISensor* sensor)
+{
+ std::vector<SCA_ISensor*>::iterator i =
+ std::find(m_sensors.begin(), m_sensors.end(), sensor);
+ if (!(i == m_sensors.end()))
+ {
+ std::swap(*i, m_sensors.back());
+ m_sensors.pop_back();
+ }
+}
+
+
+void SCA_EventManager::EndFrame()
+{
+}
+
+
+
+int SCA_EventManager::GetType()
+{
+ return (int) m_mgrtype;
+}
diff --git a/source/gameengine/GameLogic/SCA_EventManager.h b/source/gameengine/GameLogic/SCA_EventManager.h
new file mode 100644
index 00000000000..30928af5354
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_EventManager.h
@@ -0,0 +1,69 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef __KX_EVENTMANAGER
+#define __KX_EVENTMANAGER
+
+#include <vector>
+#include <algorithm>
+
+class SCA_EventManager
+{
+protected:
+ std::vector <class SCA_ISensor*> m_sensors;
+
+public:
+ enum EVENT_MANAGER_TYPE {
+ KEYBOARD_EVENTMGR = 0,
+ MOUSE_EVENTMGR,
+ ALWAYS_EVENTMGR,
+ TOUCH_EVENTMGR,
+ PROPERTY_EVENTMGR,
+ TIME_EVENTMGR,
+ RANDOM_EVENTMGR,
+ RAY_EVENTMGR,
+ RADAR_EVENTMGR,
+ NETWORK_EVENTMGR
+ };
+
+ SCA_EventManager(EVENT_MANAGER_TYPE mgrtype);
+ virtual ~SCA_EventManager();
+
+ virtual void RemoveSensor(class SCA_ISensor* sensor);
+ virtual void NextFrame(double curtime,double deltatime)=0;
+ virtual void EndFrame();
+ virtual void RegisterSensor(class SCA_ISensor* sensor)=0;
+ int GetType();
+
+protected:
+ EVENT_MANAGER_TYPE m_mgrtype;
+};
+#endif
diff --git a/source/gameengine/GameLogic/SCA_ExpressionController.cpp b/source/gameengine/GameLogic/SCA_ExpressionController.cpp
new file mode 100644
index 00000000000..56934a695f2
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_ExpressionController.cpp
@@ -0,0 +1,161 @@
+/**
+ * 'Expression Controller enables to calculate an expression that wires inputs to output
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+
+#include "SCA_ExpressionController.h"
+#include "SCA_ISensor.h"
+#include "SCA_LogicManager.h"
+#include "BoolValue.h"
+#include "InputParser.h"
+
+#include "MT_Transform.h" // for fuzzyZero
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_ExpressionController::SCA_ExpressionController(SCA_IObject* gameobj,
+ const STR_String& exprtext,
+ PyTypeObject* T)
+ :SCA_IController(gameobj,T),
+ m_exprText(exprtext)
+{
+}
+
+
+
+SCA_ExpressionController::~SCA_ExpressionController()
+{
+}
+
+
+
+CValue* SCA_ExpressionController::GetReplica()
+{
+ SCA_ExpressionController* replica = new SCA_ExpressionController(*this);
+ replica->m_exprText = m_exprText;
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+void SCA_ExpressionController::Trigger(SCA_LogicManager* logicmgr)
+{
+
+ bool expressionresult = false;
+
+ CParser parser;
+ parser.SetContext(this->AddRef());
+ CExpression* expr = parser.ProcessText(m_exprText);
+ if (expr)
+ {
+ CValue* value = expr->Calculate();
+ if (value)
+ {
+ if (value->IsError())
+ {
+ printf(value->GetText());
+ } else
+ {
+ float num = value->GetNumber();
+ expressionresult = !MT_fuzzyZero(num);
+ }
+ value->Release();
+
+ }
+ expr->Release();
+ }
+
+ /*
+
+ for (vector<SCA_ISensor*>::const_iterator is=m_linkedsensors.begin();
+ !(is==m_linkedsensors.end());is++)
+ {
+ SCA_ISensor* sensor = *is;
+ if (!sensor->IsPositiveTrigger())
+ {
+ sensorresult = false;
+ break;
+ }
+ }
+
+ */
+
+ CValue* newevent = new CBoolValue(expressionresult);
+
+ for (vector<SCA_IActuator*>::const_iterator i=m_linkedactuators.begin();
+ !(i==m_linkedactuators.end());i++)
+ {
+ SCA_IActuator* actua = *i;
+ logicmgr->AddActiveActuator(actua,newevent);
+ }
+ //printf("expr %d.",expressionresult);
+ // every actuator that needs the event, has a it's own reference to it now so
+ // release it (so to be clear: if there is no actuator, it's deleted right now)
+ newevent->Release();
+}
+
+
+
+CValue* SCA_ExpressionController::FindIdentifier(const STR_String& identifiername)
+{
+
+ CValue* identifierval = NULL;
+
+ for (vector<SCA_ISensor*>::const_iterator is=m_linkedsensors.begin();
+ !(is==m_linkedsensors.end());is++)
+ {
+ SCA_ISensor* sensor = *is;
+ if (sensor->GetName() == identifiername)
+ {
+ identifierval = new CBoolValue(sensor->IsPositiveTrigger());
+ //identifierval = sensor->AddRef();
+ }
+
+ //if (!sensor->IsPositiveTrigger())
+ //{
+ // sensorresult = false;
+ // break;
+ //}
+ }
+
+ if (identifierval)
+ return identifierval;
+
+ return GetParent()->FindIdentifier(identifiername);
+
+}
diff --git a/source/gameengine/GameLogic/SCA_ExpressionController.h b/source/gameengine/GameLogic/SCA_ExpressionController.h
new file mode 100644
index 00000000000..59f8b7a3e04
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_ExpressionController.h
@@ -0,0 +1,64 @@
+/**
+ * KX_EXPRESSIONController.h
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_EXPRESSIONCONTROLLER
+#define __KX_EXPRESSIONCONTROLLER
+
+#include "SCA_IController.h"
+
+
+class SCA_ExpressionController : public SCA_IController
+{
+// Py_Header;
+ STR_String m_exprText;
+
+public:
+ SCA_ExpressionController(SCA_IObject* gameobj,
+ const STR_String& exprtext,
+ PyTypeObject* T=&Type );
+
+ virtual ~SCA_ExpressionController();
+ virtual CValue* GetReplica();
+ virtual void Trigger(SCA_LogicManager* logicmgr);
+ virtual CValue* FindIdentifier(const STR_String& identifiername);
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+// virtual PyObject* _getattr(char *attr);
+
+};
+
+#endif //__KX_EXPRESSIONCONTROLLER
diff --git a/source/gameengine/GameLogic/SCA_IActuator.cpp b/source/gameengine/GameLogic/SCA_IActuator.cpp
new file mode 100644
index 00000000000..81efeb6e647
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_IActuator.cpp
@@ -0,0 +1,104 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "SCA_IActuator.h"
+
+
+using namespace std;
+
+SCA_IActuator::SCA_IActuator(SCA_IObject* gameobj,
+ PyTypeObject* T) :
+ SCA_ILogicBrick(gameobj,T)
+{
+ // nothing to do
+}
+
+
+
+void SCA_IActuator::AddEvent(CValue* event)
+{
+ m_events.push_back(event);
+}
+
+
+
+void SCA_IActuator::RemoveAllEvents()
+{ // remove event queue!
+ for (vector<CValue*>::iterator i=m_events.begin(); !(i==m_events.end());i++)
+ {
+ (*i)->Release();
+ }
+ m_events.clear();
+}
+
+
+
+bool SCA_IActuator::Update(double curtime,double deltatime)
+{
+ return true;
+}
+
+
+
+bool SCA_IActuator::IsNegativeEvent() const
+{
+ bool bPositiveEvent(false);
+ bool bNegativeEvent(false);
+
+ for (vector<CValue*>::const_iterator i=m_events.begin(); i!=m_events.end();++i)
+ {
+ if ((*i)->GetNumber() == 0.0f)
+ {
+ bNegativeEvent = true;
+ } else {
+ bPositiveEvent = true;
+ }
+ }
+
+ // if at least 1 positive event, return false
+
+ return !bPositiveEvent && bNegativeEvent;
+}
+
+
+
+void SCA_IActuator::ProcessReplica()
+{
+ m_events.clear();
+}
+
+
+
+SCA_IActuator::~SCA_IActuator()
+{
+ RemoveAllEvents();
+}
+
diff --git a/source/gameengine/GameLogic/SCA_IActuator.h b/source/gameengine/GameLogic/SCA_IActuator.h
new file mode 100644
index 00000000000..67dd374b216
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_IActuator.h
@@ -0,0 +1,81 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef __KX_IACTUATOR
+#define __KX_IACTUATOR
+
+#include "SCA_ILogicBrick.h"
+#include <vector>
+
+class SCA_IActuator : public SCA_ILogicBrick
+{
+protected:
+ std::vector<CValue*> m_events;
+ void RemoveAllEvents();
+
+public:
+ /**
+ * This class also inherits the default copy constructors
+ */
+
+ SCA_IActuator(SCA_IObject* gameobj,
+ PyTypeObject* T =&Type);
+
+ /**
+ * Update(...)
+ * Update the actuator based upon the events received since
+ * the last call to Update, the current time and deltatime the
+ * time elapsed in this frame ?
+ * It is the responsibility of concrete Actuators to clear
+ * their event's. This is usually done in the Update() method via
+ * a call to RemoveAllEvents()
+ */
+
+
+ virtual bool Update(double curtime,
+ double deltatime);
+
+ /**
+ * Add an event to an actuator.
+ */
+ void AddEvent(CValue* event);
+ virtual void ProcessReplica();
+
+ /**
+ * Return true iff all the current events
+ * are negative. The definition of negative event is
+ * not immediately clear. But usually refers to key-up events
+ * or events where no action is required.
+ */
+ bool IsNegativeEvent() const;
+ virtual ~SCA_IActuator();
+};
+#endif //__KX_IACTUATOR
diff --git a/source/gameengine/GameLogic/SCA_IController.cpp b/source/gameengine/GameLogic/SCA_IController.cpp
new file mode 100644
index 00000000000..78f1980afde
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_IController.cpp
@@ -0,0 +1,120 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "SCA_IController.h"
+
+#include "SCA_LogicManager.h"
+#include "SCA_IActuator.h"
+
+SCA_IController::SCA_IController(SCA_IObject* gameobj,
+ PyTypeObject* T)
+ :
+ SCA_ILogicBrick(gameobj,T)
+{
+}
+
+
+
+SCA_IController::~SCA_IController()
+{
+}
+
+
+
+const std::vector<class SCA_ISensor*>& SCA_IController::GetLinkedSensors()
+{
+ return m_linkedsensors;
+}
+
+
+
+const std::vector<class SCA_IActuator*>& SCA_IController::GetLinkedActuators()
+{
+ return m_linkedactuators;
+}
+
+
+
+void SCA_IController::UnlinkAllSensors()
+{
+ m_linkedsensors.clear();
+}
+
+
+
+void SCA_IController::UnlinkAllActuators()
+{
+ m_linkedactuators.clear();
+}
+
+
+
+/*
+void SCA_IController::Trigger(SCA_LogicManager* logicmgr)
+{
+ //for (int i=0;i<m_linkedactuators.size();i++)
+ for (vector<SCA_IActuator*>::const_iterator i=m_linkedactuators.begin();
+ !(i==m_linkedactuators.end());i++)
+ {
+ SCA_IActuator* actua = *i;//m_linkedactuators.at(i);
+
+ logicmgr->AddActiveActuator(actua);
+ }
+
+}
+*/
+
+void SCA_IController::LinkToActuator(SCA_IActuator* actua)
+{
+ m_linkedactuators.push_back(actua);
+}
+
+void SCA_IController::UnlinkActuator(class SCA_IActuator* actua)
+{
+ std::vector<class SCA_IActuator*>::iterator actit;
+ std::vector<class SCA_IActuator*>::iterator actfound = m_linkedactuators.end();
+ for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit)
+ {
+ if ((*actit) == actua)
+ actfound = actit;
+
+ }
+ if (!(actfound==m_linkedactuators.end()))
+ {
+ m_linkedactuators.erase(actfound);
+ }
+
+}
+
+void SCA_IController::LinkToSensor(SCA_ISensor* sensor)
+{
+ m_linkedsensors.push_back(sensor);
+}
diff --git a/source/gameengine/GameLogic/SCA_IController.h b/source/gameengine/GameLogic/SCA_IController.h
new file mode 100644
index 00000000000..4f30e5ad71d
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_IController.h
@@ -0,0 +1,56 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef __KX_ICONTROLLER
+#define __KX_ICONTROLLER
+
+#include "SCA_ILogicBrick.h"
+
+class SCA_IController : public SCA_ILogicBrick
+{
+protected:
+ std::vector<class SCA_ISensor*> m_linkedsensors;
+ std::vector<class SCA_IActuator*> m_linkedactuators;
+public:
+ SCA_IController(SCA_IObject* gameobj,PyTypeObject* T);
+ virtual ~SCA_IController();
+ virtual void Trigger(class SCA_LogicManager* logicmgr)=0;
+ void LinkToSensor(SCA_ISensor* sensor);
+ void LinkToActuator(SCA_IActuator*);
+ const std::vector<class SCA_ISensor*>& GetLinkedSensors();
+ const std::vector<class SCA_IActuator*>& GetLinkedActuators();
+ void UnlinkAllSensors();
+ void UnlinkAllActuators();
+ void UnlinkActuator(class SCA_IActuator* actua);
+
+
+};
+#endif
diff --git a/source/gameengine/GameLogic/SCA_IInputDevice.cpp b/source/gameengine/GameLogic/SCA_IInputDevice.cpp
new file mode 100644
index 00000000000..75a78fe5871
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_IInputDevice.cpp
@@ -0,0 +1,138 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <iostream.h>
+
+#include "SCA_IInputDevice.h"
+
+
+
+SCA_IInputDevice::SCA_IInputDevice()
+ :
+ m_currentTable(0)
+{
+ ClearStatusTable(0);
+ ClearStatusTable(1);
+}
+
+
+
+SCA_IInputDevice::~SCA_IInputDevice()
+{
+}
+
+
+
+void SCA_IInputDevice::ClearStatusTable(int tableid)
+{
+ for (int i=0;i<SCA_IInputDevice::KX_MAX_KEYS;i++)
+ m_eventStatusTables[tableid][i]=SCA_InputEvent(SCA_InputEvent::KX_NO_INPUTSTATUS,0);
+}
+
+
+
+const SCA_InputEvent& SCA_IInputDevice::GetEventValue(SCA_IInputDevice::KX_EnumInputs inputcode)
+{
+ // cerr << "SCA_IInputDevice::GetEventValue" << endl;
+ return m_eventStatusTables[m_currentTable][inputcode];
+}
+
+
+
+int SCA_IInputDevice::GetNumActiveEvents()
+{
+ int num = 0;
+
+ // cerr << "SCA_IInputDevice::GetNumActiveEvents" << endl;
+
+ for (int i=0;i<SCA_IInputDevice::KX_MAX_KEYS;i++)
+ {
+ const SCA_InputEvent& event = m_eventStatusTables[m_currentTable][i];
+ if ((event.m_status == SCA_InputEvent::KX_JUSTACTIVATED)
+ || (event.m_status == SCA_InputEvent::KX_ACTIVE))
+ num++;
+ }
+
+ return num;
+}
+
+
+
+int SCA_IInputDevice::GetNumJustEvents()
+{
+ int num = 0;
+
+ // cerr << "SCA_IInputDevice::GetNumJustEvents" << endl;
+
+ for (int i=0;i<SCA_IInputDevice::KX_MAX_KEYS;i++)
+ {
+ const SCA_InputEvent& event = m_eventStatusTables[m_currentTable][i];
+ if ((event.m_status == SCA_InputEvent::KX_JUSTACTIVATED)
+ || (event.m_status == SCA_InputEvent::KX_JUSTRELEASED))
+ num++;
+ }
+
+ return num;
+}
+
+
+
+void SCA_IInputDevice::NextFrame()
+{
+ m_currentTable = 1 - m_currentTable;
+
+ // cerr << "SCA_IInputDevice::NextFrame " << GetNumActiveEvents() << endl;
+
+ for (int i=0;i<SCA_IInputDevice::KX_MAX_KEYS;i++)
+ {
+ switch (m_eventStatusTables[1 - m_currentTable][i].m_status)
+ {
+ case SCA_InputEvent::KX_NO_INPUTSTATUS:
+ m_eventStatusTables[m_currentTable][i]
+ = SCA_InputEvent(SCA_InputEvent::KX_NO_INPUTSTATUS, 1);
+ break;
+ case SCA_InputEvent::KX_JUSTACTIVATED:
+ m_eventStatusTables[m_currentTable][i]
+ = SCA_InputEvent(SCA_InputEvent::KX_ACTIVE, 1);
+ break;
+ case SCA_InputEvent::KX_ACTIVE:
+ m_eventStatusTables[m_currentTable][i]
+ = SCA_InputEvent(SCA_InputEvent::KX_ACTIVE, 1);
+ break;
+ case SCA_InputEvent::KX_JUSTRELEASED:
+ m_eventStatusTables[m_currentTable][i]
+ = SCA_InputEvent(SCA_InputEvent::KX_NO_INPUTSTATUS, 1);
+ break;
+ default:
+ ; /* error */
+ }
+ }
+}
diff --git a/source/gameengine/GameLogic/SCA_IInputDevice.h b/source/gameengine/GameLogic/SCA_IInputDevice.h
new file mode 100644
index 00000000000..861b4bffb5e
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_IInputDevice.h
@@ -0,0 +1,307 @@
+/**
+ * Interface for input devices. The defines for keyboard/system/mouse events
+ * here are for internal use in the KX module.
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef KX_INPUTDEVICE_H
+#define KX_INPUTDEVICE_H
+
+
+class SCA_InputEvent
+{
+
+public:
+ enum SCA_EnumInputs {
+
+ KX_NO_INPUTSTATUS = 0,
+ KX_JUSTACTIVATED,
+ KX_ACTIVE,
+ KX_JUSTRELEASED,
+ KX_MAX_INPUTSTATUS
+ };
+
+ SCA_InputEvent(SCA_EnumInputs status=KX_NO_INPUTSTATUS,int eventval=0)
+ : m_status(status),
+ m_eventval(eventval)
+ {
+
+ }
+
+ SCA_EnumInputs m_status;
+ int m_eventval;
+};
+
+class SCA_IInputDevice
+{
+
+
+public:
+
+ SCA_IInputDevice();
+ virtual ~SCA_IInputDevice();
+
+ enum KX_EnumInputs {
+
+ KX_NOKEY = 0,
+
+ // TIMERS
+
+ KX_TIMER0,
+ KX_TIMER1,
+ KX_TIMER2,
+ KX_TIMER3,
+
+ // SYSTEM
+
+ /* Moved to avoid clashes with KX_RETKEY */
+ KX_KEYBD,
+ KX_RAWKEYBD,
+ KX_REDRAW,
+ KX_INPUTCHANGE,
+ KX_QFULL,
+ KX_WINFREEZE,
+ KX_WINTHAW,
+ /* thaw is 11 */
+
+ /* move past retkey*/
+ KX_WINCLOSE = 14,
+ KX_WINQUIT,
+ KX_Q_FIRSTTIME,
+ /* sequence ends on 16 */
+
+ // standard keyboard
+
+ /* Because of the above preamble, KX_BEGINKEY is 15 ! This
+ * means that KX_RETKEY on 13d (0Dh)) will double up with
+ * KX_WINQUIT! Why is it 13? Because ascii 13d is Ctrl-M aka
+ * CR! Its little brother, LF has 10d (0Ah). This is
+ * dangerous, since the keyboards start scanning at
+ * KX_BEGINKEY. I think the keyboard system should push its
+ * key events instead of demanding the user to poll the
+ * table... But that's for another time... The fix for now is
+ * to move the above system events into a 'safe' (ie. unused)
+ * range. I am loathe to move it away from this 'magical'
+ * coincidence.. it's probably exploited somewhere. I hope the
+ * close and quit events don't mess up 'normal' kb code
+ * scanning.
+ * */
+ KX_BEGINKEY = 12,
+
+ KX_RETKEY = 13,
+ KX_SPACEKEY = 32,
+ KX_PADASTERKEY = 42,
+ KX_COMMAKEY = 44,
+ KX_MINUSKEY = 45,
+ KX_PERIODKEY = 46,
+ KX_ZEROKEY = 48,
+
+ KX_ONEKEY, // =49
+ KX_TWOKEY,
+ KX_THREEKEY,
+ KX_FOURKEY,
+ KX_FIVEKEY,
+ KX_SIXKEY,
+ KX_SEVENKEY,
+ KX_EIGHTKEY,
+ KX_NINEKEY, // = 57
+
+ KX_AKEY = 97,
+ KX_BKEY,
+ KX_CKEY,
+ KX_DKEY,
+ KX_EKEY,
+ KX_FKEY,
+ KX_GKEY,
+ KX_HKEY,
+ KX_IKEY,
+ KX_JKEY,
+ KX_KKEY,
+ KX_LKEY,
+ KX_MKEY,
+ KX_NKEY, // =110
+ KX_OKEY,
+ KX_PKEY,
+ KX_QKEY,
+ KX_RKEY,
+ KX_SKEY,
+ KX_TKEY,
+ KX_UKEY,
+ KX_VKEY,
+ KX_WKEY,
+ KX_XKEY, // =120
+ KX_YKEY,
+ KX_ZKEY, // =122
+
+
+
+ KX_CAPSLOCKKEY, // 123
+
+ KX_LEFTCTRLKEY, // 124
+ KX_LEFTALTKEY,
+ KX_RIGHTALTKEY,
+ KX_RIGHTCTRLKEY,
+ KX_RIGHTSHIFTKEY,
+ KX_LEFTSHIFTKEY,// 129
+
+ KX_ESCKEY, // 130
+ KX_TABKEY, //131
+
+
+ KX_LINEFEEDKEY, // 132
+ KX_BACKSPACEKEY,
+ KX_DELKEY,
+ KX_SEMICOLONKEY, // 135
+
+
+ KX_QUOTEKEY, //136
+ KX_ACCENTGRAVEKEY, //137
+
+ KX_SLASHKEY, //138
+ KX_BACKSLASHKEY,
+ KX_EQUALKEY,
+ KX_LEFTBRACKETKEY,
+ KX_RIGHTBRACKETKEY, // 142
+
+ KX_LEFTARROWKEY, // 145
+ KX_DOWNARROWKEY,
+ KX_RIGHTARROWKEY,
+ KX_UPARROWKEY, // 148
+
+ KX_PAD2 ,
+ KX_PAD4 ,
+ KX_PAD6 ,
+ KX_PAD8 ,
+
+ KX_PAD1 ,
+ KX_PAD3 ,
+ KX_PAD5 ,
+ KX_PAD7 ,
+ KX_PAD9 ,
+
+ KX_PADPERIOD,
+ KX_PADSLASHKEY,
+
+
+
+ KX_PAD0 ,
+ KX_PADMINUS,
+ KX_PADENTER,
+ KX_PADPLUSKEY,
+
+
+ KX_F1KEY ,
+ KX_F2KEY ,
+ KX_F3KEY ,
+ KX_F4KEY ,
+ KX_F5KEY ,
+ KX_F6KEY ,
+ KX_F7KEY ,
+ KX_F8KEY ,
+ KX_F9KEY ,
+ KX_F10KEY,
+ KX_F11KEY,
+ KX_F12KEY,
+
+ KX_PAUSEKEY,
+ KX_INSERTKEY,
+ KX_HOMEKEY ,
+ KX_PAGEUPKEY,
+ KX_PAGEDOWNKEY,
+ KX_ENDKEY,
+
+ // MOUSE
+ KX_BEGINMOUSE,
+
+ KX_BEGINMOUSEBUTTONS,
+
+ KX_LEFTMOUSE,
+ KX_MIDDLEMOUSE,
+ KX_RIGHTMOUSE,
+
+ KX_ENDMOUSEBUTTONS,
+
+ KX_MOUSEX,
+ KX_MOUSEY,
+
+ KX_ENDMOUSE,
+
+
+
+ KX_MAX_KEYS
+
+ } ; // enum
+
+
+protected:
+ /**
+ m_eventStatusTables are two tables that contain current and previous
+ status of all events
+ */
+
+ SCA_InputEvent m_eventStatusTables[2][SCA_IInputDevice::KX_MAX_KEYS];
+ /**
+ m_currentTable is index for m_keyStatusTable that toggle between 0 or 1
+ */
+ int m_currentTable;
+ void ClearStatusTable(int tableid);
+
+public:
+ virtual bool IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)=0;
+ virtual const SCA_InputEvent& GetEventValue(SCA_IInputDevice::KX_EnumInputs inputcode);
+
+ /**
+ * Count active events(active and just_activated)
+ */
+ virtual int GetNumActiveEvents();
+
+ /**
+ * Get the number of ramping events (just_activated, just_released)
+ */
+ virtual int GetNumJustEvents();
+
+ /* Next frame: we calculate the new key states. This goes as follows:
+ *
+ * KX_NO_INPUTSTATUS -> KX_NO_INPUTSTATUS
+ * KX_JUSTACTIVATED -> KX_ACTIVE
+ * KX_ACTIVE -> KX_ACTIVE
+ * KX_JUSTRELEASED -> KX_NO_INPUTSTATUS
+ *
+ * Getting new events provides the
+ * KX_NO_INPUTSTATUS->KX_JUSTACTIVATED and
+ * KX_ACTIVE->KX_JUSTRELEASED transitions.
+ */
+ virtual void NextFrame();
+
+};
+
+#endif //KX_INPUTDEVICE_H
diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp
new file mode 100644
index 00000000000..ce90a17fe0d
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp
@@ -0,0 +1,325 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "SCA_ILogicBrick.h"
+
+
+
+SCA_LogicManager* SCA_ILogicBrick::m_sCurrentLogicManager = NULL;
+
+SCA_ILogicBrick::SCA_ILogicBrick(SCA_IObject* gameobj,
+ PyTypeObject* T)
+ :
+ CValue(T),
+ m_gameobj(gameobj),
+ m_Execute_Priority(0),
+ m_Execute_Ueber_Priority(0),
+ m_bActive(false),
+ m_eventval(0)
+{
+ m_text = "KX_LogicBrick";
+}
+
+
+
+SCA_ILogicBrick::~SCA_ILogicBrick()
+{
+ RemoveEvent();
+}
+
+
+
+void SCA_ILogicBrick::SetExecutePriority(int execute_Priority)
+{
+ m_Execute_Priority = execute_Priority;
+}
+
+
+
+void SCA_ILogicBrick::SetUeberExecutePriority(int execute_Priority)
+{
+ m_Execute_Ueber_Priority = execute_Priority;
+}
+
+
+
+SCA_IObject* SCA_ILogicBrick::GetParent()
+{
+ return m_gameobj;
+}
+
+
+
+void SCA_ILogicBrick::ReParent(SCA_IObject* parent)
+{
+ m_gameobj = parent;
+}
+
+
+
+CValue* SCA_ILogicBrick::Calc(VALUE_OPERATOR op, CValue *val)
+{
+ CValue* temp = new CBoolValue(false,"");
+ CValue* result = temp->Calc(op,val);
+ temp->Release();
+
+ return result;
+}
+
+
+
+CValue* SCA_ILogicBrick::CalcFinal(VALUE_DATA_TYPE dtype,
+ VALUE_OPERATOR op,
+ CValue *val)
+{
+ // same as bool implementation, so...
+ CValue* temp = new CBoolValue(false,"");
+ CValue* result = temp->CalcFinal(dtype,op,val);
+ temp->Release();
+
+ return result;
+}
+
+
+
+const STR_String& SCA_ILogicBrick::GetText()
+{
+ if (m_name.Length())
+ return m_name;
+
+ return m_text;
+}
+
+
+
+float SCA_ILogicBrick::GetNumber()
+{
+ return -1;
+}
+
+
+
+STR_String SCA_ILogicBrick::GetName()
+{
+ return m_name;
+}
+
+
+
+void SCA_ILogicBrick::SetName(STR_String name)
+{
+ m_name = name;
+}
+
+
+
+void SCA_ILogicBrick::ReplicaSetName(STR_String name)
+{
+ m_name = name;
+}
+
+
+
+bool SCA_ILogicBrick::IsActive()
+{
+ return m_bActive;
+}
+
+
+
+bool SCA_ILogicBrick::LessComparedTo(SCA_ILogicBrick* other)
+{
+ return (this->m_Execute_Ueber_Priority < other->m_Execute_Ueber_Priority)
+ || ((this->m_Execute_Ueber_Priority == other->m_Execute_Ueber_Priority) &&
+ (this->m_Execute_Priority < other->m_Execute_Priority));
+}
+
+
+
+void SCA_ILogicBrick::SetActive(bool active)
+{
+ m_bActive=active;
+ if (active)
+ {
+ //m_gameobj->SetDebugColor(GetDrawColor());
+ } else
+ {
+ //m_gameobj->ResetDebugColor();
+ }
+}
+
+
+
+void SCA_ILogicBrick::RegisterEvent(CValue* eventval)
+{
+ if (m_eventval)
+ m_eventval->Release();
+
+ m_eventval = eventval->AddRef();
+}
+
+
+void SCA_ILogicBrick::RemoveEvent()
+{
+ if (m_eventval)
+ {
+ m_eventval->Release();
+ m_eventval = NULL;
+ }
+}
+
+
+
+CValue* SCA_ILogicBrick::GetEvent()
+{
+ if (m_eventval)
+ {
+ return m_eventval->AddRef();
+ }
+
+ return NULL;
+}
+
+
+
+
+/* python stuff */
+
+PyTypeObject SCA_ILogicBrick::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_ILogicBrick",
+ sizeof(SCA_ILogicBrick),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+
+
+PyParentObject SCA_ILogicBrick::Parents[] = {
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+
+
+PyMethodDef SCA_ILogicBrick::Methods[] = {
+ {"getOwner", (PyCFunction) SCA_ILogicBrick::sPyGetOwner, METH_VARARGS},
+ {"getExecutePriority", (PyCFunction) SCA_ILogicBrick::sPySetExecutePriority, METH_VARARGS},
+ {"setExecutePriority", (PyCFunction) SCA_ILogicBrick::sPySetExecutePriority, METH_VARARGS},
+ {NULL,NULL} //Sentinel
+};
+
+
+
+PyObject*
+SCA_ILogicBrick::_getattr(char* attr)
+{
+ _getattr_up(CValue);
+}
+
+
+
+PyObject* SCA_ILogicBrick::PyGetOwner(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ CValue* parent = GetParent();
+ if (parent)
+ {
+ parent->AddRef();
+ return parent;
+ }
+
+ printf("ERROR: Python scriptblock without owner\n");
+ Py_INCREF(Py_None);
+ return Py_None;//Int_FromLong(IsPositiveTrigger());
+}
+
+
+
+PyObject* SCA_ILogicBrick::PySetExecutePriority(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+
+ int priority=0;
+
+ if (!PyArg_ParseTuple(args, "i", &priority)) {
+ return NULL;
+ }
+
+ m_Execute_Ueber_Priority = priority;
+
+ Py_Return;
+}
+
+
+
+PyObject* SCA_ILogicBrick::PyGetExecutePriority(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ return PyInt_FromLong(m_Execute_Ueber_Priority);
+}
+
+
+
+/* Conversions for making life better. */
+bool SCA_ILogicBrick::PyArgToBool(int boolArg)
+{
+ if (boolArg == KX_TRUE) {
+ return true;
+ } else if (boolArg == KX_FALSE){
+ return false;
+ } else {
+ ; /* error: bad conversion: how to catch this? */
+ return false;
+ }
+}
+
+
+
+PyObject* SCA_ILogicBrick::BoolToPyArg(bool boolarg)
+{
+ return PyInt_FromLong(boolarg? KX_TRUE: KX_FALSE);
+}
diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.h b/source/gameengine/GameLogic/SCA_ILogicBrick.h
new file mode 100644
index 00000000000..9e293136e21
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_ILogicBrick.h
@@ -0,0 +1,111 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef __KX_ILOGICBRICK
+#define __KX_ILOGICBRICK
+
+#include "Value.h"
+#include "SCA_IObject.h"
+#include "BoolValue.h"
+class SCA_ILogicBrick : public CValue
+{
+ Py_Header;
+ SCA_IObject* m_gameobj;
+ int m_Execute_Priority;
+ int m_Execute_Ueber_Priority;
+
+ bool m_bActive;
+ CValue* m_eventval;
+ STR_String m_text;
+ STR_String m_name;
+ //unsigned long m_drawcolor;
+protected:
+ void RegisterEvent(CValue* eventval);
+ void RemoveEvent();
+ CValue* GetEvent();
+
+public:
+ SCA_ILogicBrick(SCA_IObject* gameobj,PyTypeObject* T );
+ virtual ~SCA_ILogicBrick();
+
+ void SetExecutePriority(int execute_Priority);
+ void SetUeberExecutePriority(int execute_Priority);
+
+ SCA_IObject* GetParent();
+ virtual void ReParent(SCA_IObject* parent);
+
+ // act as a BoolValue (with value IsPositiveTrigger)
+ virtual CValue* Calc(VALUE_OPERATOR op, CValue *val);
+ virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val);
+
+ virtual const STR_String & GetText();
+ virtual float GetNumber();
+ virtual STR_String GetName();
+ virtual void SetName(STR_String name);
+ virtual void ReplicaSetName(STR_String name);
+
+ bool IsActive();
+ void SetActive(bool active) ;
+
+ virtual bool LessComparedTo(SCA_ILogicBrick* other);
+
+ virtual PyObject* _getattr(char *attr);
+
+ static class SCA_LogicManager* m_sCurrentLogicManager;
+
+
+ // python methods
+
+ KX_PYMETHOD(SCA_ILogicBrick,GetOwner);
+ KX_PYMETHOD(SCA_ILogicBrick,SetExecutePriority);
+ KX_PYMETHOD(SCA_ILogicBrick,GetExecutePriority);
+
+ enum KX_BOOL_TYPE {
+ KX_BOOL_NODEF = 0,
+ KX_TRUE,
+ KX_FALSE,
+ KX_BOOL_MAX
+ };
+
+
+protected:
+ /* Some conversions to go with the bool type. */
+ /** Convert a KX_TRUE, KX_FALSE in Python to a c++ value. */
+ bool PyArgToBool(int boolArg);
+
+ /** Convert a a c++ value to KX_TRUE, KX_FALSE in Python. */
+ PyObject* BoolToPyArg(bool);
+
+
+};
+
+
+#endif
diff --git a/source/gameengine/GameLogic/SCA_IObject.cpp b/source/gameengine/GameLogic/SCA_IObject.cpp
new file mode 100644
index 00000000000..012479ba2d3
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_IObject.cpp
@@ -0,0 +1,363 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+
+#include "SCA_IObject.h"
+#include "SCA_ISensor.h"
+#include "SCA_IController.h"
+#include "SCA_IActuator.h"
+#include "MT_Point3.h"
+
+#include "ListValue.h"
+
+MT_Point3 SCA_IObject::m_sDummy=MT_Point3(0,0,0);
+
+SCA_IObject::SCA_IObject(PyTypeObject* T): CValue(T)
+{
+ m_suspended = false;
+}
+
+
+
+SCA_IObject::~SCA_IObject()
+{
+ SCA_SensorList::iterator its;
+ for (its = m_sensors.begin(); !(its == m_sensors.end()); ++its)
+ {
+ ((CValue*)(*its))->Release();
+ }
+ SCA_ControllerList::iterator itc;
+ for (itc = m_controllers.begin(); !(itc == m_controllers.end()); ++itc)
+ {
+ ((CValue*)(*itc))->Release();
+ }
+ SCA_ActuatorList::iterator ita;
+ for (ita = m_actuators.begin(); !(ita==m_actuators.end()); ++ita)
+ {
+ ((CValue*)(*ita))->Release();
+ }
+
+ //T_InterpolatorList::iterator i;
+ //for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) {
+ // delete *i;
+ //}
+}
+
+
+
+SCA_ControllerList& SCA_IObject::GetControllers()
+{
+ return m_controllers;
+}
+
+
+
+SCA_SensorList& SCA_IObject::GetSensors()
+{
+ return m_sensors;
+}
+
+
+
+SCA_ActuatorList& SCA_IObject::GetActuators()
+{
+ return m_actuators;
+}
+
+
+
+void SCA_IObject::AddSensor(SCA_ISensor* act)
+{
+ m_sensors.push_back(act);
+}
+
+
+
+void SCA_IObject::AddController(SCA_IController* act)
+{
+ m_controllers.push_back(act);
+}
+
+
+
+void SCA_IObject::AddActuator(SCA_IActuator* act)
+{
+ m_actuators.push_back(act);
+}
+
+
+
+void SCA_IObject::SetIgnoreActivityCulling(bool b)
+{
+ m_ignore_activity_culling = b;
+}
+
+
+
+bool SCA_IObject::GetIgnoreActivityCulling()
+{
+ return m_ignore_activity_culling;
+}
+
+
+
+void SCA_IObject::ReParentLogic()
+{
+ SCA_SensorList& oldsensors = GetSensors();
+
+ int sen = 0;
+ SCA_SensorList::iterator its;
+ for (its = oldsensors.begin(); !(its==oldsensors.end()); ++its)
+ {
+ SCA_ISensor* newsensor = (SCA_ISensor*)(*its)->GetReplica();
+ newsensor->ReParent(this);
+ oldsensors[sen++] = newsensor;
+ }
+
+ SCA_ControllerList& oldcontrollers = GetControllers();
+ int con = 0;
+ SCA_ControllerList::iterator itc;
+ for (itc = oldcontrollers.begin(); !(itc==oldcontrollers.end()); ++itc)
+ {
+ SCA_IController* newcontroller = (SCA_IController*)(*itc)->GetReplica();
+ newcontroller->ReParent(this);
+ oldcontrollers[con++]=newcontroller;
+
+ }
+ SCA_ActuatorList& oldactuators = GetActuators();
+
+ int act = 0;
+ SCA_ActuatorList::iterator ita;
+ for (ita = oldactuators.begin(); !(ita==oldactuators.end()); ++ita)
+ {
+ SCA_IActuator* newactuator = (SCA_IActuator*) (*ita)->GetReplica();
+ newactuator->ReParent(this);
+ newactuator->SetActive(false);
+ oldactuators[act++] = newactuator;
+ }
+
+}
+
+
+
+SCA_ISensor* SCA_IObject::FindSensor(const STR_String& sensorname)
+{
+ SCA_ISensor* foundsensor = NULL;
+
+ for (SCA_SensorList::iterator its = m_sensors.begin();!(its==m_sensors.end());its++)
+ {
+ if ((*its)->GetName() == sensorname)
+ {
+ foundsensor = (*its);
+ break;
+ }
+ }
+ return foundsensor;
+}
+
+
+
+SCA_IController* SCA_IObject::FindController(const STR_String& controllername)
+{
+ SCA_IController* foundcontroller = NULL;
+
+ for (SCA_ControllerList::iterator itc = m_controllers.begin();!(itc==m_controllers.end());itc++)
+ {
+ if ((*itc)->GetName() == controllername)
+ {
+ foundcontroller = (*itc);
+ break;
+ }
+ }
+ return foundcontroller;
+}
+
+
+
+SCA_IActuator* SCA_IObject::FindActuator(const STR_String& actuatorname)
+{
+ SCA_IActuator* foundactuator = NULL;
+
+ for (SCA_ActuatorList::iterator ita = m_actuators.begin();!(ita==m_actuators.end());ita++)
+ {
+ if ((*ita)->GetName() == actuatorname)
+ {
+ foundactuator = (*ita);
+ break;
+ }
+ }
+
+ return foundactuator;
+}
+
+
+
+void SCA_IObject::SetCurrentTime(float currentTime) {
+ //T_InterpolatorList::iterator i;
+ //for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) {
+ // (*i)->Execute(currentTime);
+ //}
+}
+
+
+
+const MT_Point3& SCA_IObject::ConvertPythonPylist(PyObject* pylist)
+{
+ bool error = false;
+ m_sDummy = MT_Vector3(0,0,0);
+ if (pylist->ob_type == &CListValue::Type)
+ {
+ CListValue* listval = (CListValue*) pylist;
+ int numelem = listval->GetCount();
+ if ( numelem <= 3)
+ {
+ int index;
+ for (index = 0;index<numelem;index++)
+ {
+ m_sDummy[index] = listval->GetValue(index)->GetNumber();
+ }
+ } else
+ {
+ error = true;
+ }
+
+ } else
+ {
+
+ // assert the list is long enough...
+ int numitems = PyList_Size(pylist);
+ if (numitems <= 3)
+ {
+ int index;
+ for (index=0;index<numitems;index++)
+ {
+ m_sDummy[index] = PyFloat_AsDouble(PyList_GetItem(pylist,index));
+ }
+ }
+ else
+ {
+ error = true;
+ }
+
+ }
+ return m_sDummy;
+}
+
+
+
+const MT_Point3& SCA_IObject::ConvertPythonVectorArg(PyObject* args)
+{
+
+ PyObject* pylist;
+ PyArg_ParseTuple(args,"O",&pylist);
+ m_sDummy = ConvertPythonPylist(pylist);
+ return m_sDummy;
+}
+
+
+
+void SCA_IObject::Suspend(void)
+{
+ if ((!m_ignore_activity_culling)
+ && (!m_suspended)) {
+ m_suspended = true;
+ /* flag suspend for all sensors */
+ SCA_SensorList::iterator i = m_sensors.begin();
+ while (i != m_sensors.end()) {
+ (*i)->Suspend();
+ i++;
+ }
+ }
+}
+
+
+
+void SCA_IObject::Resume(void)
+{
+ if (m_suspended) {
+ m_suspended = false;
+ /* unflag suspend for all sensors */
+ SCA_SensorList::iterator i = m_sensors.begin();
+ while (i != m_sensors.end()) {
+ (*i)->Resume();
+ i++;
+ }
+ }
+}
+
+
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_IObject::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_IObject",
+ sizeof(SCA_IObject),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+
+
+PyParentObject SCA_IObject::Parents[] = {
+ &SCA_IObject::Type,
+ &CValue::Type,
+ NULL
+};
+
+
+
+PyMethodDef SCA_IObject::Methods[] = {
+ //{"setOrientation", (PyCFunction) SCA_IObject::sPySetOrientation, METH_VARARGS},
+ //{"getOrientation", (PyCFunction) SCA_IObject::sPyGetOrientation, METH_VARARGS},
+ {NULL,NULL} //Sentinel
+};
+
+
+
+PyObject* SCA_IObject::_getattr(char* attr) {
+ _getattr_up(CValue);
+}
+
diff --git a/source/gameengine/GameLogic/SCA_IObject.h b/source/gameengine/GameLogic/SCA_IObject.h
new file mode 100644
index 00000000000..e3c06a92b9f
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_IObject.h
@@ -0,0 +1,126 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * An abstract object that has some logic, python scripting and
+ * reference counting Note: transformation stuff has been moved to
+ * SceneGraph
+ */
+
+#ifndef SCA_IOBJECT_H
+#define SCA_IOBJECT_H
+
+#include "Value.h"
+#include <vector>
+
+class SCA_ISensor;
+class SCA_IController;
+class SCA_IActuator;
+
+
+typedef std::vector<SCA_ISensor *> SCA_SensorList;
+typedef std::vector<SCA_IController *> SCA_ControllerList;
+typedef std::vector<SCA_IActuator *> SCA_ActuatorList;
+
+
+class SCA_IObject : public CValue
+{
+
+ Py_Header;
+
+protected:
+ SCA_SensorList m_sensors;
+ SCA_ControllerList m_controllers;
+ SCA_ActuatorList m_actuators;
+ static class MT_Point3 m_sDummy;
+
+ /**
+ * Ignore activity culling requests?
+ */
+ bool m_ignore_activity_culling;
+
+ /**
+ * Ignore updates?
+ */
+ bool m_suspended;
+
+public:
+
+ SCA_IObject(PyTypeObject* T=&Type);
+ virtual ~SCA_IObject();
+
+ SCA_ControllerList& GetControllers();
+ SCA_SensorList& GetSensors();
+ SCA_ActuatorList& GetActuators();
+
+ void AddSensor(SCA_ISensor* act);
+ void AddController(SCA_IController* act);
+ void AddActuator(SCA_IActuator* act);
+
+ SCA_ISensor* FindSensor(const STR_String& sensorname);
+ SCA_IActuator* FindActuator(const STR_String& actuatorname);
+ SCA_IController* FindController(const STR_String& controllername);
+
+ void SetCurrentTime(float currentTime);
+
+ void ReParentLogic();
+
+ /**
+ * Set whether or not to ignore activity culling requests
+ */
+ void SetIgnoreActivityCulling(bool b);
+
+ /**
+ * Set whether or not this object wants to ignore activity culling
+ * requests
+ */
+ bool GetIgnoreActivityCulling();
+
+ /**
+ * Suspend all progress.
+ */
+ void Suspend(void);
+
+ /**
+ * Resume progress
+ */
+ void Resume(void);
+
+ const class MT_Point3& ConvertPythonPylist(PyObject* pylist);
+ const class MT_Point3& ConvertPythonVectorArg(PyObject* args);
+
+ // here come the python forwarded methods
+ PyObject* _getattr(char* attr);
+
+};
+#endif //SCA_IOBJECT_H
+
+
+
+
diff --git a/source/gameengine/GameLogic/SCA_IScene.cpp b/source/gameengine/GameLogic/SCA_IScene.cpp
new file mode 100644
index 00000000000..e9ed8232824
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_IScene.cpp
@@ -0,0 +1,67 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "SCA_IScene.h"
+
+
+
+SCA_IScene::SCA_IScene()
+{
+}
+
+
+
+SCA_IScene::~SCA_IScene()
+{
+ // release debugprop list
+ for (std::vector<SCA_DebugProp*>::iterator it = m_debugList.begin();
+ !(it==m_debugList.end());it++)
+ {
+ delete (*it);
+ }
+}
+
+
+std::vector<SCA_DebugProp*>& SCA_IScene::GetDebugProperties()
+{
+ return m_debugList;
+}
+
+
+
+void SCA_IScene::AddDebugProperty(class CValue* debugprop,
+ const STR_String &name)
+{
+ SCA_DebugProp* dprop = new SCA_DebugProp();
+ dprop->m_obj = debugprop;
+ dprop->m_name = name;
+ m_debugList.push_back(dprop);
+}
diff --git a/source/gameengine/GameLogic/SCA_IScene.h b/source/gameengine/GameLogic/SCA_IScene.h
new file mode 100644
index 00000000000..a8893fe9c59
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_IScene.h
@@ -0,0 +1,62 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef __KX_ISCENE_H
+#define __KX_ISCENE_H
+
+#include <vector>
+
+#include "STR_String.h"
+
+struct SCA_DebugProp
+{
+ class CValue* m_obj;
+ STR_String m_name;
+};
+
+class SCA_IScene
+{
+ std::vector<SCA_DebugProp*> m_debugList;
+public:
+ SCA_IScene();
+ virtual ~SCA_IScene();
+ virtual class SCA_IObject* AddReplicaObject(class CValue* gameobj,
+ class CValue* locationobj,
+ int lifespan=0)=0;
+ virtual void RemoveObject(class CValue* gameobj)=0;
+ virtual void DelayedRemoveObject(class CValue* gameobj)=0;
+ virtual void ReplaceMesh(class CValue* gameobj,
+ void* meshobj)=0;
+ std::vector<SCA_DebugProp*>& GetDebugProperties();
+ void AddDebugProperty(class CValue* debugprop,
+ const STR_String &name);
+};
+#endif //__KX_ISCENE_H
diff --git a/source/gameengine/GameLogic/SCA_ISensor.cpp b/source/gameengine/GameLogic/SCA_ISensor.cpp
new file mode 100644
index 00000000000..be26f1d503e
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_ISensor.cpp
@@ -0,0 +1,328 @@
+/**
+ * Abstract class for sensor logic bricks
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "SCA_ISensor.h"
+#include "SCA_EventManager.h"
+#include "SCA_LogicManager.h"
+
+/* Native functions */
+
+
+void SCA_ISensor::ReParent(SCA_IObject* parent)
+{
+ SCA_ILogicBrick::ReParent(parent);
+ m_eventmgr->RegisterSensor(this);
+ this->SetActive(false);
+}
+
+
+SCA_ISensor::SCA_ISensor(SCA_IObject* gameobj,
+ class SCA_EventManager* eventmgr,
+ PyTypeObject* T ) :
+ SCA_ILogicBrick(gameobj,T),
+ m_triggered(false)
+{
+ m_suspended = false;
+ m_invert = false;
+ m_pos_ticks = 0;
+ m_neg_ticks = 0;
+ m_pos_pulsemode = false;
+ m_neg_pulsemode = false;
+ m_pulse_frequency = 0;
+
+ m_eventmgr = eventmgr;
+}
+
+
+SCA_ISensor::~SCA_ISensor()
+{
+ // intentionally empty
+}
+
+bool SCA_ISensor::IsPositiveTrigger() {
+ bool result = false;
+
+ if (m_eventval) {
+ result = (m_eventval->GetNumber() != 0.0);
+ }
+ if (m_invert) {
+ result = !result;
+ }
+
+ return result;
+}
+
+void SCA_ISensor::SetPulseMode(bool posmode,
+ bool negmode,
+ int freq) {
+ m_pos_pulsemode = posmode;
+ m_neg_pulsemode = negmode;
+ m_pulse_frequency = freq;
+}
+
+void SCA_ISensor::SetInvert(bool inv) {
+ m_invert = inv;
+}
+
+
+float SCA_ISensor::GetNumber() {
+ return IsPositiveTrigger();
+}
+
+void SCA_ISensor::Suspend() {
+ m_suspended = true;
+}
+
+bool SCA_ISensor::IsSuspended() {
+ return m_suspended;
+}
+
+void SCA_ISensor::Resume() {
+ m_suspended = false;
+}
+
+/* python integration */
+
+PyTypeObject SCA_ISensor::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_ISensor",
+ sizeof(SCA_ISensor),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_ISensor::Parents[] = {
+ &SCA_ISensor::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+PyMethodDef SCA_ISensor::Methods[] = {
+ {"isPositive", (PyCFunction) SCA_ISensor::sPyIsPositive,
+ METH_VARARGS, IsPositive_doc},
+ {"getUsePosPulseMode", (PyCFunction) SCA_ISensor::sPyGetUsePosPulseMode,
+ METH_VARARGS, GetUsePosPulseMode_doc},
+ {"setUsePosPulseMode", (PyCFunction) SCA_ISensor::sPySetUsePosPulseMode,
+ METH_VARARGS, SetUsePosPulseMode_doc},
+ {"getFrequency", (PyCFunction) SCA_ISensor::sPyGetFrequency,
+ METH_VARARGS, GetFrequency_doc},
+ {"setFrequency", (PyCFunction) SCA_ISensor::sPySetFrequency,
+ METH_VARARGS, SetFrequency_doc},
+ {"getUseNegPulseMode", (PyCFunction) SCA_ISensor::sPyGetUseNegPulseMode,
+ METH_VARARGS, GetUseNegPulseMode_doc},
+ {"setUseNegPulseMode", (PyCFunction) SCA_ISensor::sPySetUseNegPulseMode,
+ METH_VARARGS, SetUseNegPulseMode_doc},
+ {NULL,NULL} //Sentinel
+};
+
+
+PyObject*
+SCA_ISensor::_getattr(char* attr)
+{
+ _getattr_up(SCA_ILogicBrick);
+}
+
+
+void SCA_ISensor::RegisterToManager()
+{
+ m_eventmgr->RegisterSensor(this);
+}
+
+void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr, CValue* event)
+{
+
+ // calculate if a __triggering__ is wanted
+ if (!m_suspended) {
+ bool result = this->Evaluate(event);
+ if (result) {
+ logicmgr->AddActivatedSensor(this);
+ } else
+ {
+ /* First, the pulsing behaviour, if pulse mode is
+ * active. It seems something goes wrong if pulse mode is
+ * not set :( */
+ if (m_pos_pulsemode) {
+ m_pos_ticks++;
+ if (m_pos_ticks > m_pulse_frequency) {
+ if ( this->IsPositiveTrigger() )
+ {
+ logicmgr->AddActivatedSensor(this);
+ }
+ m_pos_ticks = 0;
+ }
+ }
+
+ if (m_neg_pulsemode)
+ {
+ m_neg_ticks++;
+ if (m_neg_ticks > m_pulse_frequency) {
+ if (!this->IsPositiveTrigger() )
+ {
+ logicmgr->AddActivatedSensor(this);
+ }
+ m_neg_ticks = 0;
+ }
+ }
+ }
+ }
+}
+
+/* Python functions: */
+char SCA_ISensor::IsPositive_doc[] =
+"isPositive()\n"
+"\tReturns whether the sensor is registered a positive event.\n";
+PyObject* SCA_ISensor::PyIsPositive(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int retval = IsPositiveTrigger();
+ return PyInt_FromLong(retval);
+}
+
+/**
+ * getUsePulseMode: getter for the pulse mode (KX_TRUE = on)
+ */
+char SCA_ISensor::GetUsePosPulseMode_doc[] =
+"getUsePosPulseMode()\n"
+"\tReturns whether positive pulse mode is active.\n";
+PyObject* SCA_ISensor::PyGetUsePosPulseMode(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return BoolToPyArg(m_pos_pulsemode);
+}
+
+/**
+ * setUsePulseMode: setter for the pulse mode (KX_TRUE = on)
+ */
+char SCA_ISensor::SetUsePosPulseMode_doc[] =
+"setUsePosPulseMode(pulse?)\n"
+"\t - pulse? : Pulse when a positive event occurs?\n"
+"\t (KX_TRUE, KX_FALSE)\n"
+"\tSet whether to do pulsing when positive pulses occur.\n";
+PyObject* SCA_ISensor::PySetUsePosPulseMode(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int pyarg = 0;
+ if(!PyArg_ParseTuple(args, "i", &pyarg)) { return NULL; }
+ m_pos_pulsemode = PyArgToBool(pyarg);
+ Py_Return;
+}
+
+/**
+ * getFrequency: getter for the pulse mode interval
+ */
+char SCA_ISensor::GetFrequency_doc[] =
+"getFrequency()\n"
+"\tReturns the frequency of the updates in pulse mode.\n" ;
+PyObject* SCA_ISensor::PyGetFrequency(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return PyInt_FromLong(m_pulse_frequency);
+}
+
+/**
+ * setFrequency: setter for the pulse mode (KX_TRUE = on)
+ */
+char SCA_ISensor::SetFrequency_doc[] =
+"setFrequency(pulse_frequency)\n"
+"\t- pulse_frequency: The frequency of the updates in pulse mode (integer)"
+"\tSet the frequency of the updates in pulse mode.\n"
+"\tIf the frequency is negative, it is set to 0.\n" ;
+PyObject* SCA_ISensor::PySetFrequency(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int pulse_frequencyArg = 0;
+
+ if(!PyArg_ParseTuple(args, "i", &pulse_frequencyArg)) {
+ return NULL;
+ }
+
+ /* We can do three things here: clip, ignore and raise an exception. */
+ /* Exceptions don't work yet, ignoring is not desirable now... */
+ if (pulse_frequencyArg < 0) {
+ pulse_frequencyArg = 0;
+ };
+ m_pulse_frequency = pulse_frequencyArg;
+
+ Py_Return;
+}
+
+
+char SCA_ISensor::GetInvert_doc[] =
+"getInvert()\n"
+"\tReturns whether or not pulses from this sensor are inverted.\n" ;
+PyObject* SCA_ISensor::PyGetInvert(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return BoolToPyArg(m_invert);
+}
+
+char SCA_ISensor::SetInvert_doc[] =
+"setInvert(invert?)\n"
+"\t- invert?: Invert the event-values? (KX_TRUE, KX_FALSE)\n"
+"\tSet whether to invert pulses.\n";
+PyObject* SCA_ISensor::PySetInvert(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int pyarg = 0;
+ if(!PyArg_ParseTuple(args, "i", &pyarg)) { return NULL; }
+ m_invert = PyArgToBool(pyarg);
+ Py_Return;
+}
+
+char SCA_ISensor::GetUseNegPulseMode_doc[] =
+"getUseNegPulseMode()\n"
+"\tReturns whether negative pulse mode is active.\n";
+PyObject* SCA_ISensor::PyGetUseNegPulseMode(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return BoolToPyArg(m_neg_pulsemode);
+}
+
+char SCA_ISensor::SetUseNegPulseMode_doc[] =
+"setUseNegPulseMode(pulse?)\n"
+"\t - pulse? : Pulse when a negative event occurs?\n"
+"\t (KX_TRUE, KX_FALSE)\n"
+"\tSet whether to do pulsing when negative pulses occur.\n";
+PyObject* SCA_ISensor::PySetUseNegPulseMode(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int pyarg = 0;
+ if(!PyArg_ParseTuple(args, "i", &pyarg)) { return NULL; }
+ m_neg_pulsemode = PyArgToBool(pyarg);
+ Py_Return;
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h
new file mode 100644
index 00000000000..ef3f037be96
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_ISensor.h
@@ -0,0 +1,130 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * Interface Class for all logic Sensors. Implements
+ * pulsemode and pulsefrequency, and event suppression.
+ */
+
+#ifndef __SCA_ISENSOR
+#define __SCA_ISENSOR
+
+#include "SCA_ILogicBrick.h"
+
+
+
+/**
+ * Interface Class for all logic Sensors. Implements
+ * pulsemode,pulsefrequency */
+class SCA_ISensor : public SCA_ILogicBrick
+{
+ Py_Header;
+ class SCA_EventManager* m_eventmgr;
+ bool m_triggered;
+
+ /* Pulse positive pulses? */
+ bool m_pos_pulsemode;
+
+ /** Pulse negative pulses? */
+ bool m_neg_pulsemode;
+
+ /** Repeat frequency in pulse mode. */
+ int m_pulse_frequency;
+
+ /** Number of ticks since the last positive pulse. */
+ int m_pos_ticks;
+
+ /** Number of ticks since the last negative pulse. */
+ int m_neg_ticks;
+
+ /* invert the output signal*/
+ bool m_invert;
+
+ /** Sensor must ignore updates? */
+ bool m_suspended;
+
+ /** Pass the activation on to the logic manager.*/
+ void SignalActivation(class SCA_LogicManager* logicmgr);
+
+public:
+ SCA_ISensor(SCA_IObject* gameobj,
+ class SCA_EventManager* eventmgr,
+ PyTypeObject* T );;
+ ~SCA_ISensor();
+ virtual void ReParent(SCA_IObject* parent);
+
+ /* Because we want sensors to share some behaviour, the Activate has */
+ /* an implementation on this level. It requires an evaluate on the lower */
+ /* level of individual sensors. Mapping the old activate()s is easy. */
+ /* The IsPosTrig() also has to change, to keep things consistent. */
+ void Activate(class SCA_LogicManager* logicmgr,CValue* event);
+ virtual bool Evaluate(CValue* event) = 0;
+ virtual bool IsPositiveTrigger();
+
+ virtual PyObject* _getattr(char *attr);
+ virtual CValue* GetReplica()=0;
+
+ /** Set parameters for the pulsing behaviour.
+ * @param posmode Trigger positive pulses?
+ * @param negmode Trigger negative pulses?
+ * @param freq Frequency to use when doing pulsing.
+ */
+ void SetPulseMode(bool posmode,
+ bool negmode,
+ int freq);
+
+ /** Set inversion of pulses on or off. */
+ void SetInvert(bool inv);
+
+ void RegisterToManager();
+ virtual float GetNumber();
+
+ /** Stop sensing for a while. */
+ void Suspend();
+
+ /** Is this sensor switched off? */
+ bool IsSuspended();
+
+ /** Resume sensing. */
+ void Resume();
+
+ /* Python functions: */
+ KX_PYMETHOD_DOC(SCA_ISensor,IsPositive);
+ KX_PYMETHOD_DOC(SCA_ISensor,GetUsePosPulseMode);
+ KX_PYMETHOD_DOC(SCA_ISensor,SetUsePosPulseMode);
+ KX_PYMETHOD_DOC(SCA_ISensor,GetFrequency);
+ KX_PYMETHOD_DOC(SCA_ISensor,SetFrequency);
+ KX_PYMETHOD_DOC(SCA_ISensor,GetUseNegPulseMode);
+ KX_PYMETHOD_DOC(SCA_ISensor,SetUseNegPulseMode);
+ KX_PYMETHOD_DOC(SCA_ISensor,GetInvert);
+ KX_PYMETHOD_DOC(SCA_ISensor,SetInvert);
+
+};
+
+#endif //__SCA_ISENSOR
diff --git a/source/gameengine/GameLogic/SCA_KeyboardManager.cpp b/source/gameengine/GameLogic/SCA_KeyboardManager.cpp
new file mode 100644
index 00000000000..46223aa11af
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_KeyboardManager.cpp
@@ -0,0 +1,91 @@
+/**
+ * Manager for keyboard events
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <iostream.h>
+#include "BoolValue.h"
+#include "SCA_KeyboardManager.h"
+#include "SCA_KeyboardSensor.h"
+#include "IntValue.h"
+#include <vector>
+
+SCA_KeyboardManager::SCA_KeyboardManager(SCA_LogicManager* logicmgr,
+ SCA_IInputDevice* inputdev)
+ : SCA_EventManager(KEYBOARD_EVENTMGR),
+ m_logicmanager(logicmgr),
+ m_inputDevice(inputdev)
+{
+}
+
+
+
+SCA_KeyboardManager::~SCA_KeyboardManager()
+{
+}
+
+
+
+SCA_IInputDevice* SCA_KeyboardManager::GetInputDevice()
+{
+ return m_inputDevice;
+}
+
+
+
+void SCA_KeyboardManager::NextFrame(double curtime,double deltatime)
+{
+ //const SCA_InputEvent& event = GetEventValue(SCA_IInputDevice::KX_EnumInputs inputcode)=0;
+ // cerr << "SCA_KeyboardManager::NextFrame"<< endl;
+ for (int i=0;i<m_sensors.size();i++)
+ {
+ SCA_KeyboardSensor* keysensor = (SCA_KeyboardSensor*)m_sensors[i];
+ keysensor->Activate(m_logicmanager,NULL);
+ }
+
+}
+
+
+
+void SCA_KeyboardManager::RegisterSensor(SCA_ISensor* keysensor)
+{
+ m_sensors.push_back(keysensor);
+}
+
+
+
+bool SCA_KeyboardManager::IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)
+{
+ return false;
+ //return m_kxsystem->IsPressed(inputcode);
+}
+
diff --git a/source/gameengine/GameLogic/SCA_KeyboardManager.h b/source/gameengine/GameLogic/SCA_KeyboardManager.h
new file mode 100644
index 00000000000..1c665ef2b88
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_KeyboardManager.h
@@ -0,0 +1,66 @@
+/**
+ * Manager for keyboard events
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_KEYBOARDMANAGER
+#define __KX_KEYBOARDMANAGER
+
+
+#include "SCA_EventManager.h"
+
+#include <vector>
+
+using namespace std;
+
+#include "SCA_IInputDevice.h"
+
+
+class SCA_KeyboardManager : public SCA_EventManager
+{
+ class SCA_IInputDevice* m_inputDevice;
+ class SCA_LogicManager* m_logicmanager;
+
+
+public:
+ SCA_KeyboardManager(class SCA_LogicManager* logicmgr,class SCA_IInputDevice* inputdev);
+ virtual ~SCA_KeyboardManager();
+
+ bool IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode);
+
+
+ virtual void NextFrame(double curtime,double deltatime);
+ virtual void RegisterSensor(class SCA_ISensor* sensor);
+ SCA_IInputDevice* GetInputDevice();
+};
+
+#endif //__KX_KEYBOARDMANAGER
diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
new file mode 100644
index 00000000000..834c9254cc0
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
@@ -0,0 +1,675 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * Sensor for keyboard input
+ */
+#include "SCA_KeyboardSensor.h"
+#include "SCA_KeyboardManager.h"
+#include "SCA_LogicManager.h"
+#include "StringValue.h"
+#include "SCA_IInputDevice.h"
+
+
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_KeyboardSensor::SCA_KeyboardSensor(SCA_KeyboardManager* keybdmgr,
+ short int hotkey,
+ short int qual,
+ short int qual2,
+ bool bAllKeys,
+ const STR_String& targetProp,
+ const STR_String& toggleProp,
+ SCA_IObject* gameobj,
+ PyTypeObject* T )
+ :SCA_ISensor(gameobj,keybdmgr,T),
+ m_pKeyboardMgr(keybdmgr),
+ m_hotkey(hotkey),
+ m_qual(qual),
+ m_qual2(qual2),
+ m_bAllKeys(bAllKeys),
+ m_targetprop(targetProp),
+ m_toggleprop(toggleProp)
+{
+
+// SetDrawColor(0xff0000ff);
+ m_val=0;
+}
+
+
+
+SCA_KeyboardSensor::~SCA_KeyboardSensor()
+{
+}
+
+
+
+CValue* SCA_KeyboardSensor::GetReplica()
+{
+ CValue* replica = new SCA_KeyboardSensor(*this);
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+short int SCA_KeyboardSensor::GetHotkey()
+{
+ return m_hotkey;
+}
+
+
+
+bool SCA_KeyboardSensor::IsPositiveTrigger()
+{
+ bool result = (m_val != 0);
+
+ if (m_invert)
+ result = !result;
+
+ return result;
+}
+
+
+
+bool SCA_KeyboardSensor::TriggerOnAllKeys()
+{
+ return m_bAllKeys;
+}
+
+
+
+bool SCA_KeyboardSensor::Evaluate(CValue* eventval)
+{
+ bool result = false;
+ SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice();
+
+ // cerr << "SCA_KeyboardSensor::Eval event, sensing for "<< m_hotkey << " at device " << inputdev << "\n";
+
+ /* See if we need to do logging: togPropState exists and is
+ * different from 0 */
+ CValue* myparent = GetParent();
+ CValue* togPropState = myparent->GetProperty(m_toggleprop);
+ if (togPropState &&
+ (((int)togPropState->GetNumber()) != 0) )
+ {
+ LogKeystrokes();
+ }
+
+
+
+ /* Now see whether events must be bounced. */
+ if (m_bAllKeys)
+ {
+ bool justactivated = false;
+ bool justreleased = false;
+
+ for (int i=SCA_IInputDevice::KX_BEGINKEY ; i< SCA_IInputDevice::KX_ENDKEY;i++)
+ {
+ const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i);
+ if (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED)
+ {
+ justactivated = true;
+ }
+ if (inevent.m_status == SCA_InputEvent::KX_JUSTRELEASED)
+ {
+ justreleased = true;
+ }
+ }
+
+ if (justactivated)
+ {
+ m_val=1;
+ result = true;
+ } else
+ {
+ if (justreleased)
+ {
+ m_val=0;
+ result = true;
+ }
+ }
+
+
+ } else
+ {
+
+ // cerr << "======= SCA_KeyboardSensor::Evaluate:: peeking at key status" << endl;
+ const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) m_hotkey);
+
+ // cerr << "======= SCA_KeyboardSensor::Evaluate:: status: " << inevent.m_status << endl;
+
+ if (inevent.m_status == SCA_InputEvent::KX_NO_INPUTSTATUS)
+ {
+ int i=4;
+ } else
+ {
+ if (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED)
+ {
+ m_val=1;
+ result = true;
+ } else
+ {
+ if (inevent.m_status == SCA_InputEvent::KX_JUSTRELEASED)
+ {
+ m_val = 0;
+ result = true;
+ }
+ }
+ }
+ }
+
+ return result;
+
+}
+
+void SCA_KeyboardSensor::AddToTargetProp(int keyIndex)
+{
+ if (IsPrintable(keyIndex)) {
+ CValue* tprop = GetParent()->GetProperty(m_targetprop);
+
+ if (tprop) {
+ /* overwrite the old property */
+ if (IsDelete(keyIndex)) {
+ /* strip one char, if possible */
+ STR_String newprop = tprop->GetText();
+ int oldlength = newprop.Length();
+ if (oldlength >= 1 ) {
+ newprop.SetLength(oldlength - 1);
+ CStringValue * newstringprop = new CStringValue(newprop, m_targetprop);
+ GetParent()->SetProperty(m_targetprop, newstringprop);
+ }
+ } else {
+ /* append */
+ char pchar = ToCharacter(keyIndex, IsShifted());
+ STR_String newprop = tprop->GetText() + pchar;
+ CStringValue * newstringprop = new CStringValue(newprop, m_targetprop);
+ GetParent()->SetProperty(m_targetprop, newstringprop);
+ }
+ } else {
+ if (!IsDelete(keyIndex)) {
+ /* Make a new property. Deletes can be ignored. */
+ char pchar = ToCharacter(keyIndex, IsShifted());
+ STR_String newprop = pchar;
+ CStringValue * newstringprop = new CStringValue(newprop, m_targetprop);
+ GetParent()->SetProperty(m_targetprop, newstringprop);
+ }
+ }
+ }
+
+}
+
+/**
+ * Determine whether this character can be printed. We cannot use
+ * the library functions here, because we need to test our own
+ * keycodes. */
+bool SCA_KeyboardSensor::IsPrintable(int keyIndex)
+{
+ /* only print
+ * - numerals: KX_ZEROKEY to KX_NINEKEY
+ * - alphas: KX_AKEY to KX_ZKEY.
+ * - specials: KX_RETKEY, KX_PADASTERKEY, KX_PADCOMMAKEY to KX_PERIODKEY,
+ * KX_TABKEY , KX_SEMICOLONKEY to KX_RIGHTBRACKETKEY,
+ * KX_PAD2 to KX_PADPLUSKEY
+ * - delete and backspace: also printable in the sense that they modify
+ * the string
+ * - retkey: should this be printable?
+ * - virgule: prints a space... don't know which key that's supposed
+ * to be...
+ */
+ if ( ((keyIndex >= SCA_IInputDevice::KX_ZEROKEY)
+ && (keyIndex <= SCA_IInputDevice::KX_NINEKEY))
+ || ((keyIndex >= SCA_IInputDevice::KX_AKEY)
+ && (keyIndex <= SCA_IInputDevice::KX_ZKEY))
+ || (keyIndex == SCA_IInputDevice::KX_SPACEKEY)
+/* || (keyIndex == KX_RETKEY) */
+ || (keyIndex == SCA_IInputDevice::KX_PADASTERKEY)
+ || (keyIndex == SCA_IInputDevice::KX_TABKEY)
+ || ((keyIndex >= SCA_IInputDevice::KX_COMMAKEY)
+ && (keyIndex <= SCA_IInputDevice::KX_PERIODKEY))
+ || ((keyIndex >= SCA_IInputDevice::KX_SEMICOLONKEY)
+ && (keyIndex <= SCA_IInputDevice::KX_RIGHTBRACKETKEY))
+ || ((keyIndex >= SCA_IInputDevice::KX_PAD2)
+ && (keyIndex <= SCA_IInputDevice::KX_PADPLUSKEY))
+ || (keyIndex == SCA_IInputDevice::KX_DELKEY)
+ || (keyIndex == SCA_IInputDevice::KX_BACKSPACEKEY)
+ )
+ {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+// this code looks ugly, please use an ordinary hashtable
+
+char SCA_KeyboardSensor::ToCharacter(int keyIndex, bool shifted)
+{
+ /* numerals */
+ if ( (keyIndex >= SCA_IInputDevice::KX_ZEROKEY)
+ && (keyIndex <= SCA_IInputDevice::KX_NINEKEY) ) {
+ if (shifted) {
+ char numshift[] = ")!@#$%^&*(";
+ return numshift[keyIndex - '0'];
+ } else {
+ return keyIndex - SCA_IInputDevice::KX_ZEROKEY + '0';
+ }
+ }
+
+ /* letters... always lowercase... is that desirable? */
+ if ( (keyIndex >= SCA_IInputDevice::KX_AKEY)
+ && (keyIndex <= SCA_IInputDevice::KX_ZKEY) ) {
+ if (shifted) {
+ return keyIndex - SCA_IInputDevice::KX_AKEY + 'A';
+ } else {
+ return keyIndex - SCA_IInputDevice::KX_AKEY + 'a';
+ }
+ }
+
+ if (keyIndex == SCA_IInputDevice::KX_SPACEKEY) {
+ return ' ';
+ }
+
+/* || (keyIndex == SCA_IInputDevice::KX_RETKEY) */
+
+ if (keyIndex == SCA_IInputDevice::KX_PADASTERKEY) {
+ return '*';
+ }
+
+ if (keyIndex == SCA_IInputDevice::KX_TABKEY) {
+ return '\t';
+ }
+
+ /* comma to period */
+ char commatoperiod[] = ",-.";
+ char commatoperiodshifted[] = "<_>";
+ if (keyIndex == SCA_IInputDevice::KX_COMMAKEY) {
+ if (shifted) {
+ return commatoperiodshifted[0];
+ } else {
+ return commatoperiod[0];
+ }
+ }
+ if (keyIndex == SCA_IInputDevice::KX_MINUSKEY) {
+ if (shifted) {
+ return commatoperiodshifted[1];
+ } else {
+ return commatoperiod[1];
+ }
+ }
+ if (keyIndex == SCA_IInputDevice::KX_PERIODKEY) {
+ if (shifted) {
+ return commatoperiodshifted[2];
+ } else {
+ return commatoperiod[2];
+ }
+ }
+
+ /* semicolon to rightbracket */
+ char semicolontorightbracket[] = ";\'` /\\=[]";
+ char semicolontorightbracketshifted[] = ":\"~ \?|+{}";
+ if ((keyIndex >= SCA_IInputDevice::KX_SEMICOLONKEY)
+ && (keyIndex <= SCA_IInputDevice::KX_RIGHTBRACKETKEY)) {
+ if (shifted) {
+ return semicolontorightbracketshifted[keyIndex - SCA_IInputDevice::KX_SEMICOLONKEY];
+ } else {
+ return semicolontorightbracket[keyIndex - SCA_IInputDevice::KX_SEMICOLONKEY];
+ }
+ }
+
+ /* keypad2 to padplus */
+ char pad2topadplus[] = "246813579. 0- +";
+ if ((keyIndex >= SCA_IInputDevice::KX_PAD2)
+ && (keyIndex <= SCA_IInputDevice::KX_PADPLUSKEY)) {
+ return pad2topadplus[keyIndex - SCA_IInputDevice::KX_PAD2];
+ }
+
+ return '!';
+}
+
+/**
+ * Tests whether this is a delete key.
+ */
+bool SCA_KeyboardSensor::IsDelete(int keyIndex)
+{
+ if ( (keyIndex == SCA_IInputDevice::KX_DELKEY)
+ || (keyIndex == SCA_IInputDevice::KX_BACKSPACEKEY) ) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+/**
+ * Tests whether shift is pressed
+ */
+bool SCA_KeyboardSensor::IsShifted(void)
+{
+ SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice();
+
+ if ( (inputdev->GetEventValue(SCA_IInputDevice::KX_RIGHTSHIFTKEY).m_status
+ == SCA_InputEvent::KX_ACTIVE)
+ || (inputdev->GetEventValue(SCA_IInputDevice::KX_RIGHTSHIFTKEY).m_status
+ == SCA_InputEvent::KX_JUSTACTIVATED)
+ || (inputdev->GetEventValue(SCA_IInputDevice::KX_LEFTSHIFTKEY).m_status
+ == SCA_InputEvent::KX_ACTIVE)
+ || (inputdev->GetEventValue(SCA_IInputDevice::KX_LEFTSHIFTKEY).m_status
+ == SCA_InputEvent::KX_JUSTACTIVATED)
+ ) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void SCA_KeyboardSensor::LogKeystrokes(void)
+{
+ SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice();
+ int num = inputdev->GetNumActiveEvents();
+
+ /* weird loop, this one... */
+ if (num > 0)
+ {
+
+ int index = 0;
+ /* Check on all keys whether they were pushed. This does not
+ * untangle the ordering, so don't type too fast :) */
+ for (int i=SCA_IInputDevice::KX_BEGINKEY ; i< SCA_IInputDevice::KX_ENDKEY;i++)
+ {
+ const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i);
+ if (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED) //NO_INPUTSTATUS)
+ {
+ if (index < num)
+ {
+ AddToTargetProp(i);
+ index++;
+ }
+ }
+ }
+ }
+}
+
+
+/* ------------------------------------------------------------------------- */
+/* Python functions : specific */
+/* ------------------------------------------------------------------------- */
+
+
+PyObject* SCA_KeyboardSensor::PySetAllMode(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ bool allkeys;
+
+ if (!PyArg_ParseTuple(args, "i", &allkeys))
+ {
+ return NULL;
+ }
+
+ m_bAllKeys = allkeys;
+ Py_Return
+}
+
+
+
+PyObject* SCA_KeyboardSensor::sPySetAllMode(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+// printf("sPyIsPositive\n");
+ return ((SCA_KeyboardSensor*) self)->PyIsPositive(self, args, kwds);
+}
+
+
+/** 1. GetKey : check which key this sensor looks at */
+char SCA_KeyboardSensor::GetKey_doc[] =
+"getKey()\n"
+"\tReturn the code of the key this sensor is listening to.\n" ;
+PyObject* SCA_KeyboardSensor::PyGetKey(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return PyInt_FromLong(m_hotkey);
+}
+
+/** 2. SetKey: change the key to look at */
+char SCA_KeyboardSensor::SetKey_doc[] =
+"setKey(keycode)\n"
+"\t- keycode: any code from GameKeys\n"
+"\tSet the key this sensor should listen to.\n" ;
+PyObject* SCA_KeyboardSensor::PySetKey(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int keyCode;
+
+ if(!PyArg_ParseTuple(args, "i", &keyCode)) {
+ return NULL;
+ }
+
+ /* Since we have symbolic constants for this in Python, we don't guard */
+ /* anything. It's up to the user to provide a sensible number. */
+ m_hotkey = keyCode;
+
+ Py_Return;
+}
+
+/** 3. GetHold1 : set the first bucky bit */
+char SCA_KeyboardSensor::GetHold1_doc[] =
+"getHold1()\n"
+"\tReturn the code of the first key modifier to the key this \n"
+"\tsensor is listening to.\n" ;
+PyObject* SCA_KeyboardSensor::PyGetHold1(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return PyInt_FromLong(m_qual);
+}
+
+/** 4. SetHold1: change the first bucky bit */
+char SCA_KeyboardSensor::SetHold1_doc[] =
+"setHold1(keycode)\n"
+"\t- keycode: any code from GameKeys\n"
+"\tSet the first modifier to the key this sensor should listen to.\n" ;
+PyObject* SCA_KeyboardSensor::PySetHold1(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int keyCode;
+
+ if(!PyArg_ParseTuple(args, "i", &keyCode)) {
+ return NULL;
+ }
+
+ /* Since we have symbolic constants for this in Python, we don't guard */
+ /* anything. It's up to the user to provide a sensible number. */
+ m_qual = keyCode;
+
+ Py_Return;
+}
+
+/** 5. GetHold2 : get the second bucky bit */
+char SCA_KeyboardSensor::GetHold2_doc[] =
+"getHold2()\n"
+"\tReturn the code of the second key modifier to the key this \n"
+"\tsensor is listening to.\n" ;
+PyObject* SCA_KeyboardSensor::PyGetHold2(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return PyInt_FromLong(m_qual2);
+}
+
+/** 6. SetHold2: change the second bucky bit */
+char SCA_KeyboardSensor::SetHold2_doc[] =
+"setHold2(keycode)\n"
+"\t- keycode: any code from GameKeys\n"
+"\tSet the first modifier to the key this sensor should listen to.\n" ;
+PyObject* SCA_KeyboardSensor::PySetHold2(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int keyCode;
+
+ if(!PyArg_ParseTuple(args, "i", &keyCode)) {
+ return NULL;
+ }
+
+ /* Since we have symbolic constants for this in Python, we don't guard */
+ /* anything. It's up to the user to provide a sensible number. */
+ m_qual2 = keyCode;
+
+ Py_Return;
+}
+
+
+char SCA_KeyboardSensor::GetPressedKeys_doc[] =
+"getPressedKeys()\n"
+"\tGet a list of pressed keys that have either been pressed, or just released this frame.\n" ;
+
+PyObject* SCA_KeyboardSensor::PyGetPressedKeys(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice();
+
+ int num = inputdev->GetNumJustEvents();
+ PyObject* resultlist = PyList_New(num);
+
+ if (num > 0)
+ {
+
+ int index = 0;
+
+ for (int i=SCA_IInputDevice::KX_BEGINKEY ; i< SCA_IInputDevice::KX_ENDKEY;i++)
+ {
+ const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i);
+ if ((inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED)
+ || (inevent.m_status == SCA_InputEvent::KX_JUSTRELEASED))
+ {
+ if (index < num)
+ {
+ PyObject* keypair = PyList_New(2);
+ PyList_SetItem(keypair,0,PyInt_FromLong(i));
+ PyList_SetItem(keypair,1,PyInt_FromLong(inevent.m_status));
+ PyList_SetItem(resultlist,index,keypair);
+ index++;
+ }
+ }
+ }
+ if (index>0) return resultlist;
+ }
+
+ Py_Return;
+}
+
+
+
+char SCA_KeyboardSensor::GetCurrentlyPressedKeys_doc[] =
+"getCurrentlyPressedKeys()\n"
+"\tGet a list of keys that are currently pressed.\n" ;
+
+PyObject* SCA_KeyboardSensor::PyGetCurrentlyPressedKeys(PyObject* self, PyObject* args, PyObject* kwds)
+{
+SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice();
+
+ int num = inputdev->GetNumActiveEvents();
+ PyObject* resultlist = PyList_New(num);
+
+ if (num > 0)
+ {
+ int index = 0;
+
+ for (int i=SCA_IInputDevice::KX_BEGINKEY ; i< SCA_IInputDevice::KX_ENDKEY;i++)
+ {
+ const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i);
+ if ( (inevent.m_status == SCA_InputEvent::KX_ACTIVE)
+ || (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED))
+ {
+ if (index < num)
+ {
+ PyObject* keypair = PyList_New(2);
+ PyList_SetItem(keypair,0,PyInt_FromLong(i));
+ PyList_SetItem(keypair,1,PyInt_FromLong(inevent.m_status));
+ PyList_SetItem(resultlist,index,keypair);
+ index++;
+ }
+ }
+ }
+
+ /* why?*/
+ if (index > 0) return resultlist;
+ }
+
+ Py_Return;
+}
+
+/* ------------------------------------------------------------------------- */
+/* Python functions : integration hooks */
+/* ------------------------------------------------------------------------- */
+
+PyTypeObject SCA_KeyboardSensor::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_KeyboardSensor",
+ sizeof(SCA_KeyboardSensor),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_KeyboardSensor::Parents[] = {
+ &SCA_KeyboardSensor::Type,
+ &SCA_ISensor::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef SCA_KeyboardSensor::Methods[] = {
+ {"getKey", (PyCFunction) SCA_KeyboardSensor::sPyGetKey, METH_VARARGS, GetKey_doc},
+ {"setKey", (PyCFunction) SCA_KeyboardSensor::sPySetKey, METH_VARARGS, SetKey_doc},
+ {"getHold1", (PyCFunction) SCA_KeyboardSensor::sPyGetHold1, METH_VARARGS, GetHold1_doc},
+ {"setHold1", (PyCFunction) SCA_KeyboardSensor::sPySetHold1, METH_VARARGS, SetHold1_doc},
+ {"getHold2", (PyCFunction) SCA_KeyboardSensor::sPyGetHold2, METH_VARARGS, GetHold2_doc},
+ {"setHold2", (PyCFunction) SCA_KeyboardSensor::sPySetHold2, METH_VARARGS, SetHold2_doc},
+// {"getUseAllKeys", (PyCFunction) SCA_KeyboardSensor::sPyGetUseAllKeys, METH_VARARGS, GetUseAllKeys_doc},
+// {"setUseAllKeys", (PyCFunction) SCA_KeyboardSensor::sPySetUseAllKeys, METH_VARARGS, SetUseAllKeys_doc},
+ {"getPressedKeys", (PyCFunction) SCA_KeyboardSensor::sPyGetPressedKeys, METH_VARARGS, GetPressedKeys_doc},
+ {"getCurrentlyPressedKeys", (PyCFunction) SCA_KeyboardSensor::sPyGetCurrentlyPressedKeys, METH_VARARGS, GetCurrentlyPressedKeys_doc},
+// {"getKeyEvents", (PyCFunction) SCA_KeyboardSensor::sPyGetKeyEvents, METH_VARARGS, GetKeyEvents_doc},
+ {NULL,NULL} //Sentinel
+};
+
+PyObject*
+SCA_KeyboardSensor::_getattr(char* attr)
+{
+ _getattr_up(SCA_ISensor);
+}
+
diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.h b/source/gameengine/GameLogic/SCA_KeyboardSensor.h
new file mode 100644
index 00000000000..f9de2a0e715
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.h
@@ -0,0 +1,158 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * Sensor for keyboard input
+ */
+
+#ifndef __KX_KEYBOARDSENSOR
+#define __KX_KEYBOARDSENSOR
+
+#include "SCA_ISensor.h"
+#include "BoolValue.h"
+#include <list>
+
+/**
+ * The keyboard sensor listens to the keyboard, and passes on events
+ * on selected keystrokes. It has an alternate mode in which it logs
+ * keypresses to a property. Note that these modes are not mutually
+ * exclusive. */
+class SCA_KeyboardSensor : public SCA_ISensor
+{
+ Py_Header;
+ class SCA_KeyboardManager* m_pKeyboardMgr;
+
+
+ /**
+ * the key this sensor is sensing for
+ */
+ int m_hotkey;
+ short int m_qual,m_qual2;
+ short int m_val;
+ /**
+ * If this toggle is true, all incoming key events generate a
+ * response.
+ */
+ bool m_bAllKeys;
+
+ /**
+ * The name of the property to which logged text is appended. If
+ * this property is not defined, no logging takes place.
+ */
+ STR_String m_targetprop;
+ /**
+ * The property that indicates whether or not to log text when in
+ * loggin mode. If the property equals 0, no loggin is done. For
+ * all other values, logging is active. Logging can only become
+ * active if there is a property to log to. Logging is independant
+ * from hotkey settings. */
+ STR_String m_toggleprop;
+
+ /**
+ * Log the keystrokes from the current input buffer.
+ */
+ void LogKeystrokes(void);
+
+ /**
+ * Adds this key-code to the target prop.
+ */
+ void AddToTargetProp(int keyIndex);
+
+ /**
+ * Determine whether this character can be printed. We cannot use
+ * the library functions here, because we need to test our own
+ * keycodes. */
+ bool IsPrintable(int keyIndex);
+
+ /**
+ * Transform keycodes to something printable.
+ */
+ char ToCharacter(int keyIndex, bool shifted);
+
+ /**
+ * Tests whether this is a delete key.
+ */
+ bool IsDelete(int keyIndex);
+
+ /**
+ * Tests whether shift is pressed.
+ */
+ bool IsShifted(void);
+
+public:
+ SCA_KeyboardSensor(class SCA_KeyboardManager* keybdmgr,
+ short int hotkey,
+ short int qual,
+ short int qual2,
+ bool bAllKeys,
+ const STR_String& targetProp,
+ const STR_String& toggleProp,
+ SCA_IObject* gameobj,
+ PyTypeObject* T=&Type );
+ virtual ~SCA_KeyboardSensor();
+ virtual CValue* GetReplica();
+
+ short int GetHotkey();
+ virtual bool Evaluate(CValue* event);
+ virtual bool IsPositiveTrigger();
+ bool TriggerOnAllKeys();
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(char *attr);
+
+
+ PyObject* PySetAllMode(PyObject* self,
+ PyObject* args,
+ PyObject* kwds);
+ static PyObject* sPySetAllMode(PyObject* self,
+ PyObject* args,
+ PyObject* kwds);
+
+ /** 1. GetKey : check which key this sensor looks at */
+ KX_PYMETHOD_DOC(SCA_KeyboardSensor,GetKey);
+ /** 2. SetKey: change the key to look at */
+ KX_PYMETHOD_DOC(SCA_KeyboardSensor,SetKey);
+ /** 3. GetHold1 : set the first bucky bit */
+ KX_PYMETHOD_DOC(SCA_KeyboardSensor,GetHold1);
+ /** 4. SetHold1: change the first bucky bit */
+ KX_PYMETHOD_DOC(SCA_KeyboardSensor,SetHold1);
+ /** 5. GetHold2 : set the second bucky bit */
+ KX_PYMETHOD_DOC(SCA_KeyboardSensor,GetHold2);
+ /** 6. SetHold2: change the second bucky bit */
+ KX_PYMETHOD_DOC(SCA_KeyboardSensor,SetHold2);
+ /** 9. GetPressedKeys: */
+ KX_PYMETHOD_DOC(SCA_KeyboardSensor,GetPressedKeys);
+ /** 9. GetCurrrentlyPressedKeys: */
+ KX_PYMETHOD_DOC(SCA_KeyboardSensor,GetCurrentlyPressedKeys);
+};
+
+#endif //__KX_KEYBOARDSENSOR
diff --git a/source/gameengine/GameLogic/SCA_LogicManager.cpp b/source/gameengine/GameLogic/SCA_LogicManager.cpp
new file mode 100644
index 00000000000..a29d6d19729
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_LogicManager.cpp
@@ -0,0 +1,461 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * Regulates the top-level logic behaviour for one scene.
+ */
+#include "Value.h"
+#include "SCA_LogicManager.h"
+
+#include "SCA_ISensor.h"
+#include "SCA_IController.h"
+#include "SCA_IActuator.h"
+#include "SCA_EventManager.h"
+
+#include <set>
+
+SCA_LogicManager::SCA_LogicManager()
+{
+}
+
+
+
+SCA_LogicManager::~SCA_LogicManager()
+{
+ for (vector<SCA_EventManager*>::iterator it = m_eventmanagers.begin();!(it==m_eventmanagers.end());it++)
+ {
+ delete (*it);
+ }
+ m_eventmanagers.clear();
+ m_sensorcontrollermapje.clear();
+
+ int numgameobj = m_mapStringToGameObjects.size();
+ for (int i = 0; i < numgameobj; i++)
+ {
+ CValue** gameobjptr = m_mapStringToGameObjects.at(i);
+ assert(gameobjptr);
+ if (gameobjptr)
+ (*gameobjptr)->Release();
+
+ }
+
+ /*for (int i=0;i<m_sensorcontrollermap.size();i++)
+ {
+ vector<SCA_IController*>* controllerarray = *(m_sensorcontrollermap[i]);
+ delete controllerarray;
+ }
+ */
+}
+
+
+/*
+// this kind of fixes bug 398 but breakes games, so better leave it out for now.
+// a removed object's gameobject (and logicbricks and stuff) didn't get released
+// because it was still in the m_mapStringToGameObjects map.
+void SCA_LogicManager::RemoveGameObject(const STR_String& gameobjname)
+{
+ int numgameobj = m_mapStringToGameObjects.size();
+ for (int i = 0; i < numgameobj; i++)
+ {
+ CValue** gameobjptr = m_mapStringToGameObjects.at(i);
+ assert(gameobjptr);
+
+ if (gameobjptr)
+ {
+ if ((*gameobjptr)->GetName() == gameobjname)
+ (*gameobjptr)->Release();
+ }
+ }
+
+ m_mapStringToGameObjects.remove(gameobjname);
+}
+*/
+
+
+void SCA_LogicManager::RegisterEventManager(SCA_EventManager* eventmgr)
+{
+ m_eventmanagers.push_back(eventmgr);
+}
+
+
+
+void SCA_LogicManager::RegisterGameObjectName(const STR_String& gameobjname,
+ CValue* gameobj)
+{
+ STR_HashedString mn = gameobjname;
+ m_mapStringToGameObjects.insert(mn,gameobj);
+}
+
+
+
+CValue* SCA_LogicManager::GetGameObjectByName(const STR_String& gameobjname)
+{
+ STR_HashedString mn = "OB"+gameobjname;
+ CValue** gameptr = m_mapStringToGameObjects[mn];
+
+ if (gameptr)
+ return *gameptr;
+
+ return NULL;
+}
+
+
+
+void SCA_LogicManager::RemoveSensor(SCA_ISensor* sensor)
+{
+ m_sensorcontrollermapje.erase(sensor);
+
+ for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin();
+ !(ie==m_eventmanagers.end());ie++)
+ {
+ (*ie)->RemoveSensor(sensor);
+ }
+}
+
+
+
+void SCA_LogicManager::RemoveDestroyedActuator(SCA_IActuator* actuator)
+{
+
+ m_removedActuators.push_back(SmartActuatorPtr(actuator,0));
+ // take care that no controller can use this actuator again !
+
+ std::map<SCA_ISensor*,controllerlist>::const_iterator sit;
+ for (sit = m_sensorcontrollermapje.begin();!(sit==m_sensorcontrollermapje.end());++sit)
+ {
+ controllerlist contlist = (*sit).second;
+ for (list<SCA_IController*>::const_iterator c= contlist.begin();!(c==contlist.end());c++)
+ {
+ (*c)->UnlinkActuator(actuator);
+ }
+ }
+}
+
+
+
+void SCA_LogicManager::RegisterToSensor(SCA_IController* controller,SCA_ISensor* sensor)
+{
+ m_sensorcontrollermapje[sensor].push_back(controller);
+ controller->LinkToSensor(sensor);
+}
+
+
+
+void SCA_LogicManager::RegisterToActuator(SCA_IController* controller,SCA_IActuator* actua)
+{
+ controller->LinkToActuator(actua);
+}
+
+
+
+void SCA_LogicManager::BeginFrame(double curtime,double deltatime)
+{
+ for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin();
+ !(ie==m_eventmanagers.end());ie++)
+ {
+ (*ie)->NextFrame(curtime,deltatime);
+ }
+
+ // for this frame, look up for activated sensors, and build the collection of triggered controllers
+ int numsensors = this->m_activatedsensors.size();
+
+ set<SmartControllerPtr> triggeredControllerSet;
+
+ for (vector<SCA_ISensor*>::const_iterator is=m_activatedsensors.begin();
+ !(is==m_activatedsensors.end());is++)
+ {
+ SCA_ISensor* sensor = *is;
+ controllerlist contlist = m_sensorcontrollermapje[sensor];
+ for (list<SCA_IController*>::const_iterator c= contlist.begin();
+ !(c==contlist.end());c++)
+ {
+ SCA_IController* contr = *c;//controllerarray->at(c);
+ triggeredControllerSet.insert(SmartControllerPtr(contr,0));
+ }
+ //sensor->SetActive(false);
+ }
+
+
+ int numtriggered = triggeredControllerSet.size();
+ for (set<SmartControllerPtr>::iterator tit=triggeredControllerSet.begin();
+ !(tit==triggeredControllerSet.end());tit++)
+ {
+ (*tit)->Trigger(this);
+ }
+ triggeredControllerSet.clear();
+}
+
+
+
+void SCA_LogicManager::UpdateFrame(double curtime,double deltatime)
+{
+ vector<SmartActuatorPtr>::iterator ra;
+ for (ra = m_removedActuators.begin();
+ !(ra == m_removedActuators.end());ra++)
+ {
+ m_activeActuators.erase(*ra);
+ (*ra)->SetActive(false);
+ }
+ m_removedActuators.clear();
+
+ for (set<SmartActuatorPtr>::iterator ia = m_activeActuators.begin();!(ia==m_activeActuators.end());ia++)
+ {
+ //SCA_IActuator* actua = *ia;
+ if (!(*ia)->Update(curtime,deltatime))
+ {
+ //*ia = m_activeactuators.back();
+ m_removedActuators.push_back(*ia);
+
+ (*ia)->SetActive(false);
+ //m_activeactuators.pop_back();
+ }
+ }
+
+ for ( ra = m_removedActuators.begin();
+ !(ra == m_removedActuators.end());ra++)
+ {
+ m_activeActuators.erase(*ra);
+ (*ra)->SetActive(false);
+ }
+ m_removedActuators.clear();
+}
+
+
+
+void* SCA_LogicManager::GetActionByName (const STR_String& actname)
+{
+ STR_HashedString an = "AC"+actname;
+ void** actptr = m_mapStringToActions[an];
+
+ if (actptr)
+ return *actptr;
+
+ return NULL;
+}
+
+
+
+void* SCA_LogicManager::GetMeshByName(const STR_String& meshname)
+{
+ STR_HashedString mn = "ME"+meshname;
+ void** meshptr = m_mapStringToMeshes[mn];
+
+ if (meshptr)
+ return *meshptr;
+
+ return NULL;
+}
+
+
+
+void SCA_LogicManager::RegisterMeshName(const STR_String& meshname,void* mesh)
+{
+ STR_HashedString mn = meshname;
+ m_mapStringToMeshes.insert(mn,mesh);
+}
+
+
+
+void SCA_LogicManager::RegisterActionName(const STR_String& actname,void* action)
+{
+ STR_HashedString an = actname;
+ m_mapStringToActions.insert(an, action);
+}
+
+
+
+void SCA_LogicManager::EndFrame()
+{
+ for (vector<SCA_ISensor*>::const_iterator is=m_activatedsensors.begin();
+ !(is==m_activatedsensors.end());is++)
+ {
+ SCA_ISensor* sensor = *is;
+ sensor->SetActive(false);
+ }
+ m_activatedsensors.clear();
+
+ for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin();
+ !(ie==m_eventmanagers.end());ie++)
+ {
+ (*ie)->EndFrame();
+ }
+
+
+}
+
+
+
+void SCA_LogicManager::AddActivatedSensor(SCA_ISensor* sensor)
+{
+ // each frame, only add sensor once, and to avoid a seek, or bloated container
+ // hold a flag in each sensor, with the 'framenr'
+ if (!sensor->IsActive())
+ {
+ sensor->SetActive(true);
+ m_activatedsensors.push_back(sensor);
+ }
+}
+
+
+
+void SCA_LogicManager::AddActiveActuator(SCA_IActuator* actua,CValue* event)
+{
+ if (!actua->IsActive())
+ {
+ actua->SetActive(true);
+ m_activeActuators.insert(SmartActuatorPtr(actua,0));
+ }
+ actua->AddEvent(event->AddRef());
+}
+
+
+
+SCA_EventManager* SCA_LogicManager::FindEventManager(int eventmgrtype)
+{
+ // find an eventmanager of a certain type
+ SCA_EventManager* eventmgr = NULL;
+
+ for (vector<SCA_EventManager*>::const_iterator i=
+ m_eventmanagers.begin();!(i==m_eventmanagers.end());i++)
+ {
+ SCA_EventManager* emgr = *i;
+ if (emgr->GetType() == eventmgrtype)
+ {
+ eventmgr = emgr;
+ break;
+ }
+ }
+ return eventmgr;
+}
+
+
+
+SmartActuatorPtr::SmartActuatorPtr(const SmartActuatorPtr& other)
+{
+ this->m_actuator = other.m_actuator;
+ this->m_actuator->AddRef();
+}
+
+
+
+SmartActuatorPtr::SmartActuatorPtr(SCA_IActuator* actua,int dummy)
+: m_actuator(actua)
+{
+ actua->AddRef();
+}
+
+
+
+SmartActuatorPtr::~SmartActuatorPtr()
+{
+ m_actuator->Release();
+}
+
+
+
+bool SmartActuatorPtr::operator <(const SmartActuatorPtr& other) const
+{
+
+ return m_actuator->LessComparedTo(*other);
+}
+
+
+
+bool SmartActuatorPtr::operator ==(const SmartActuatorPtr& other) const
+{
+ bool result2 = other->LessComparedTo(m_actuator);
+ return (m_actuator->LessComparedTo(*other) && result2);
+}
+
+
+
+SCA_IActuator* SmartActuatorPtr::operator->() const
+{
+ return m_actuator;
+}
+
+
+
+SCA_IActuator* SmartActuatorPtr::operator*() const
+{
+ return m_actuator;
+}
+
+
+
+SmartControllerPtr::SmartControllerPtr(const SmartControllerPtr& copy)
+{
+ this->m_controller = copy.m_controller;
+ this->m_controller->AddRef();
+}
+
+
+
+SmartControllerPtr::SmartControllerPtr(SCA_IController* contr,int dummy)
+: m_controller(contr)
+{
+ m_controller->AddRef();
+}
+
+
+
+SmartControllerPtr::~SmartControllerPtr()
+{
+ m_controller->Release();
+}
+
+
+
+bool SmartControllerPtr::operator <(const SmartControllerPtr& other) const
+{
+ return m_controller->LessComparedTo(*other);
+}
+
+
+
+bool SmartControllerPtr::operator ==(const SmartControllerPtr& other) const
+{
+ return (m_controller->LessComparedTo(*other) && other->LessComparedTo(m_controller));
+}
+
+
+
+SCA_IController* SmartControllerPtr::operator->() const
+{
+ return m_controller;
+}
+
+
+
+SCA_IController* SmartControllerPtr::operator*() const
+{
+ return m_controller;
+}
+
+
diff --git a/source/gameengine/GameLogic/SCA_LogicManager.h b/source/gameengine/GameLogic/SCA_LogicManager.h
new file mode 100644
index 00000000000..f79b19a0dbf
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_LogicManager.h
@@ -0,0 +1,154 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * Regulates the top-level logic behaviour for one scene.
+ */
+#ifndef __KX_LOGICMANAGER
+#define __KX_LOGICMANAGER
+
+#ifdef WIN32
+#pragma warning (disable:4786)
+#endif
+
+#include <vector>
+//#include "GEN_Map.h"
+#include <set>
+#include <map>
+#include <list>
+
+#include "GEN_Map.h"
+#include "STR_HashedString.h"
+#include "Value.h"
+
+using namespace std;
+typedef list<class SCA_IController*> controllerlist;
+
+/**
+ * This manager handles sensor, controllers and actuators.
+ * logic executes each frame the following way:
+ * find triggering sensors
+ * build list of controllers that are triggered by these triggering sensors
+ * process all triggered controllers
+ * during this phase actuators can be added to the active actuator list
+ * process all active actuators
+ * clear triggering sensors
+ * clear triggered controllers
+ * (actuators may be active during a longer timeframe)
+*/
+
+#include "SCA_ILogicBrick.h"
+
+// todo: make this into a template, but first I want to think about what exactly to put in
+class SmartActuatorPtr
+{
+ SCA_IActuator* m_actuator;
+public:
+ SmartActuatorPtr(SCA_IActuator* actua,int dummy);
+ SmartActuatorPtr(const SmartActuatorPtr& other);
+ virtual ~SmartActuatorPtr();
+ bool operator <(const SmartActuatorPtr& other) const;
+ bool operator ==(const SmartActuatorPtr& other) const;
+ SCA_IActuator* operator->() const;
+ SCA_IActuator* operator*() const;
+
+};
+
+class SmartControllerPtr
+{
+ SCA_IController* m_controller;
+public:
+ SmartControllerPtr(const SmartControllerPtr& copy);
+ SmartControllerPtr(SCA_IController* contr,int dummy);
+ virtual ~SmartControllerPtr();
+ bool operator <(const SmartControllerPtr& other) const;
+ bool operator ==(const SmartControllerPtr& other) const;
+ SCA_IController* operator->() const;
+ SCA_IController* operator*() const;
+
+};
+
+
+
+class SCA_LogicManager
+{
+ vector<class SCA_EventManager*> m_eventmanagers;
+
+ vector<class SCA_ISensor*> m_activatedsensors;
+ set<class SmartActuatorPtr> m_activeActuators;
+
+ map<SCA_ISensor*,controllerlist > m_sensorcontrollermapje;
+
+ // need to find better way for this
+ // also known as FactoryManager...
+ GEN_Map<STR_HashedString,CValue*> m_mapStringToGameObjects;
+ GEN_Map<STR_HashedString,void*> m_mapStringToMeshes;
+ GEN_Map<STR_HashedString,void*> m_mapStringToActions;
+
+ vector<SmartActuatorPtr> m_removedActuators;
+
+public:
+ SCA_LogicManager();
+ virtual ~SCA_LogicManager();
+ //void SetKeyboardManager(SCA_KeyboardManager* keyboardmgr) { m_keyboardmgr=keyboardmgr;}
+ void RegisterEventManager(SCA_EventManager* eventmgr);
+ void RegisterToSensor(SCA_IController* controller,
+ class SCA_ISensor* sensor);
+ void RegisterToActuator(SCA_IController* controller,
+ class SCA_IActuator* actuator);
+
+ void BeginFrame(double curtime,double deltatime);
+ void UpdateFrame(double curtime,double deltatime);
+ void EndFrame();
+ void AddActivatedSensor(SCA_ISensor* sensor);
+ void AddActiveActuator(SCA_IActuator* sensor,class CValue* event);
+ SCA_EventManager* FindEventManager(int eventmgrtype);
+
+ void RemoveGameObject(const STR_String& gameobjname);
+
+ /**
+ * remove Logic Bricks from the running logicmanager
+ */
+ void RemoveSensor(SCA_ISensor* sensor);
+ void RemoveController(SCA_IController* controller);
+ void RemoveDestroyedActuator(SCA_IActuator* actuator);
+
+
+ // for the scripting... needs a FactoryManager later (if we would have time... ;)
+ void RegisterMeshName(const STR_String& meshname,void* mesh);
+ void RegisterActionName(const STR_String& actname,void* action);
+
+ void* GetActionByName (const STR_String& actname);
+ void* GetMeshByName(const STR_String& meshname);
+
+ void RegisterGameObjectName(const STR_String& gameobjname,CValue* gameobj);
+ class CValue* GetGameObjectByName(const STR_String& gameobjname);
+};
+
+#endif //__KX_LOGICMANAGER
diff --git a/source/gameengine/GameLogic/SCA_MouseManager.cpp b/source/gameengine/GameLogic/SCA_MouseManager.cpp
new file mode 100644
index 00000000000..580c77ee61f
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_MouseManager.cpp
@@ -0,0 +1,116 @@
+/**
+ * Manager for mouse events
+ *
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifdef WIN32
+// This warning tells us about truncation of __long__ stl-generated names.
+// It can occasionally cause DevStudio to have internal compiler warnings.
+#pragma warning( disable : 4786 )
+#endif
+
+#include "BoolValue.h"
+#include "SCA_MouseManager.h"
+#include "SCA_MouseSensor.h"
+#include "IntValue.h"
+
+
+SCA_MouseManager::SCA_MouseManager(SCA_LogicManager* logicmgr,
+ SCA_IInputDevice* mousedev)
+ : SCA_EventManager(MOUSE_EVENTMGR),
+ m_logicmanager(logicmgr),
+ m_mousedevice (mousedev)
+{
+ m_xpos = 0;
+ m_ypos = 0;
+}
+
+
+
+SCA_MouseManager::~SCA_MouseManager()
+{
+}
+
+
+
+SCA_IInputDevice* SCA_MouseManager::GetInputDevice()
+{
+ return m_mousedevice;
+}
+
+
+
+void SCA_MouseManager::NextFrame(double curtime,double deltatime)
+{
+ if (m_mousedevice)
+ {
+ for (int i = 0; i < m_sensors.size(); i++)
+ {
+ SCA_MouseSensor* mousesensor = (SCA_MouseSensor*) m_sensors[i];
+ // (0,0) is the Upper Left corner in our local window
+ // coordinates
+ if (!mousesensor->IsSuspended())
+ {
+ const SCA_InputEvent& event =
+ m_mousedevice->GetEventValue(SCA_IInputDevice::KX_MOUSEX);
+ int mx = event.m_eventval;
+ const SCA_InputEvent& event2 =
+ m_mousedevice->GetEventValue(SCA_IInputDevice::KX_MOUSEY);
+ int my = event2.m_eventval;
+
+ mousesensor->setX(mx);
+ mousesensor->setY(my);
+
+ mousesensor->Activate(m_logicmanager,NULL);
+ }
+ }
+ }
+}
+
+
+
+void SCA_MouseManager::RegisterSensor(SCA_ISensor* keysensor)
+{
+ m_sensors.push_back(keysensor);
+}
+
+
+
+bool SCA_MouseManager::IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)
+{
+ /* We should guard for non-mouse events maybe? A rather silly side */
+ /* effect here is that position-change events are considered presses as */
+ /* well. */
+
+ return m_mousedevice->IsPressed(inputcode);
+}
diff --git a/source/gameengine/GameLogic/SCA_MouseManager.h b/source/gameengine/GameLogic/SCA_MouseManager.h
new file mode 100644
index 00000000000..9f26a706c17
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_MouseManager.h
@@ -0,0 +1,72 @@
+/**
+ * Manager for mouse events
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+
+#ifndef __KX_MOUSEMANAGER
+#define __KX_MOUSEMANAGER
+
+
+#include "SCA_EventManager.h"
+
+#include <vector>
+
+using namespace std;
+
+#include "SCA_IInputDevice.h"
+
+
+class SCA_MouseManager : public SCA_EventManager
+{
+
+ class SCA_IInputDevice* m_mousedevice;
+ class SCA_LogicManager* m_logicmanager;
+
+ unsigned short m_xpos; // Cached location of the mouse pointer
+ unsigned short m_ypos;
+
+public:
+ SCA_MouseManager(class SCA_LogicManager* logicmgr,class SCA_IInputDevice* mousedev);
+ virtual ~SCA_MouseManager();
+
+ /**
+ * Checks whether a mouse button is depressed. Ignores requests on non-
+ * mouse related evenst. Can also flag mouse movement.
+ */
+ bool IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode);
+ virtual void NextFrame(double curtime,double deltatime);
+ virtual void RegisterSensor(class SCA_ISensor* sensor);
+ SCA_IInputDevice* GetInputDevice();
+};
+
+#endif //__KX_MOUSEMANAGER
diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.cpp b/source/gameengine/GameLogic/SCA_MouseSensor.cpp
new file mode 100644
index 00000000000..f21e4c1b07e
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_MouseSensor.cpp
@@ -0,0 +1,273 @@
+/**
+ * Sensor for mouse input
+ *
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "SCA_MouseSensor.h"
+#include "SCA_EventManager.h"
+#include "SCA_MouseManager.h"
+#include "SCA_LogicManager.h"
+#include "SCA_IInputDevice.h"
+#include "ConstExpr.h"
+#include <iostream>
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_MouseSensor::SCA_MouseSensor(SCA_MouseManager* eventmgr,
+ int startx,int starty,
+ short int mousemode,
+ SCA_IObject* gameobj,
+ PyTypeObject* T)
+ : SCA_ISensor(gameobj,eventmgr, T),
+ m_pMouseMgr(eventmgr),
+ m_x(startx),
+ m_y(starty)
+{
+ m_mousemode = mousemode;
+ m_triggermode = true;
+ m_val = 0; /* stores the latest attribute */
+
+ switch (m_mousemode) {
+ case KX_MOUSESENSORMODE_LEFTBUTTON:
+ m_hotkey = SCA_IInputDevice::KX_LEFTMOUSE;
+ break;
+ case KX_MOUSESENSORMODE_MIDDLEBUTTON:
+ m_hotkey = SCA_IInputDevice::KX_MIDDLEMOUSE;
+ break;
+ case KX_MOUSESENSORMODE_RIGHTBUTTON:
+ m_hotkey = SCA_IInputDevice::KX_RIGHTMOUSE;
+ break;
+ default:
+ ; /* ignore, no hotkey */
+ }
+
+}
+
+SCA_MouseSensor::~SCA_MouseSensor()
+{
+ /* Nothing to be done here. */
+}
+
+
+
+CValue* SCA_MouseSensor::GetReplica()
+{
+ CValue* replica = new SCA_MouseSensor(*this);
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+bool SCA_MouseSensor::IsPositiveTrigger()
+{
+ bool result = (m_val != 0);
+ if (m_invert)
+ result = !result;
+
+ return result;
+}
+
+
+
+short int SCA_MouseSensor::GetModeKey()
+{
+ return m_mousemode;
+}
+
+
+
+SCA_IInputDevice::KX_EnumInputs SCA_MouseSensor::GetHotKey()
+{
+ return m_hotkey;
+}
+
+
+
+bool SCA_MouseSensor::Evaluate(CValue* event)
+{
+ bool result = false;
+ SCA_IInputDevice* mousedev = m_pMouseMgr->GetInputDevice();
+
+
+
+// SCA_ILogicBrick::RegisterEvent(event);
+// if (m_mousemode == KX_MOUSESENSORMODE_MOVEMENT) cout << "\nChecking for movement...";
+//CValue* val = event->GetProperty("val");
+
+ /* both MOUSEX and MOUSEY. Treat all of these as key-presses. */
+ /* So, treat KX_MOUSESENSORMODE_POSITION as */
+ /* KX_MOUSESENSORMODE_POSITIONX || KX_MOUSESENSORMODE_POSITIONY */
+
+ switch (m_mousemode) {
+ case KX_MOUSESENSORMODE_LEFTBUTTON:
+ case KX_MOUSESENSORMODE_MIDDLEBUTTON:
+ case KX_MOUSESENSORMODE_RIGHTBUTTON:
+ {
+ const SCA_InputEvent& event = mousedev->GetEventValue(m_hotkey);
+ if (event.m_status == SCA_InputEvent::KX_JUSTACTIVATED)
+ {
+ m_val = 1;
+ result = true;
+ } else
+ {
+ if (event.m_status == SCA_InputEvent::KX_JUSTRELEASED)
+ {
+ m_val = 0;
+ result = true;
+ }
+ }
+ break;
+ }
+ case KX_MOUSESENSORMODE_MOVEMENT:
+
+ {
+ const SCA_InputEvent& eventX = mousedev->GetEventValue(SCA_IInputDevice::KX_MOUSEX);
+ const SCA_InputEvent& eventY = mousedev->GetEventValue(SCA_IInputDevice::KX_MOUSEY);
+
+ if (eventX.m_status == SCA_InputEvent::KX_JUSTACTIVATED ||
+ eventY.m_status == SCA_InputEvent::KX_JUSTACTIVATED ||
+ eventX.m_status == SCA_InputEvent::KX_ACTIVE ||
+ eventY.m_status == SCA_InputEvent::KX_ACTIVE)
+
+ {
+ m_val = 1;
+ result = true;
+ } else
+ {
+ if (eventX.m_status == SCA_InputEvent::KX_JUSTRELEASED ||
+ eventY.m_status == SCA_InputEvent::KX_JUSTRELEASED )
+ {
+ m_val = 0;
+ result = true;
+ }
+ }
+ break;
+ }
+ default:
+ ; /* error */
+ }
+
+ return result;
+}
+
+void SCA_MouseSensor::setX(short x)
+{
+ m_x = x;
+}
+
+void SCA_MouseSensor::setY(short y)
+{
+ m_y = y;
+}
+
+bool SCA_MouseSensor::isValid(SCA_MouseSensor::KX_MOUSESENSORMODE m)
+{
+ bool res = false;
+
+ res = ((m > KX_MOUSESENSORMODE_NODEF) && (m < KX_MOUSESENSORMODE_MAX));
+
+ return res;
+}
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_MouseSensor::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_MouseSensor",
+ sizeof(SCA_MouseSensor),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_MouseSensor::Parents[] = {
+ &SCA_MouseSensor::Type,
+ &SCA_ISensor::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef SCA_MouseSensor::Methods[] = {
+ {"getXPosition", (PyCFunction) SCA_MouseSensor::sPyGetXPosition, METH_VARARGS, GetXPosition_doc},
+ {"getYPosition", (PyCFunction) SCA_MouseSensor::sPyGetYPosition, METH_VARARGS, GetYPosition_doc},
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* SCA_MouseSensor::_getattr(char* attr) {
+ _getattr_up(SCA_ISensor);
+}
+
+/* get x position ---------------------------------------------------------- */
+char SCA_MouseSensor::GetXPosition_doc[] =
+"getXPosition\n"
+"\tReturns the x-coordinate of the mouse sensor, in frame coordinates.\n"
+"\tThe lower-left corner is the origin. The coordinate is given in\n"
+"\tpixels\n";
+PyObject* SCA_MouseSensor::PyGetXPosition(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ return PyInt_FromLong(m_x);
+}
+
+/* get y position ---------------------------------------------------------- */
+char SCA_MouseSensor::GetYPosition_doc[] =
+"getYPosition\n"
+"\tReturns the y-coordinate of the mouse sensor, in frame coordinates.\n"
+"\tThe lower-left corner is the origin. The coordinate is given in\n"
+"\tpixels\n";
+PyObject* SCA_MouseSensor::PyGetYPosition(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ return PyInt_FromLong(m_y);
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.h b/source/gameengine/GameLogic/SCA_MouseSensor.h
new file mode 100644
index 00000000000..dd6230f421c
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_MouseSensor.h
@@ -0,0 +1,120 @@
+/**
+ * Senses mouse events
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_MOUSESENSOR
+#define __KX_MOUSESENSOR
+
+#include "SCA_ISensor.h"
+#include "BoolValue.h"
+#include "SCA_IInputDevice.h"
+
+class SCA_MouseSensor : public SCA_ISensor
+{
+ Py_Header;
+ class SCA_MouseManager* m_pMouseMgr;
+
+ /**
+ * Use SCA_IInputDevice values to encode the mouse mode for now.
+ */
+ short int m_mousemode;
+ /**
+ * Triggermode true means all mouse events trigger. Useful mainly
+ * for button presses.
+ */
+ bool m_triggermode;
+ /**
+ * Remember the last state update
+ */
+ int m_val;
+
+ SCA_IInputDevice::KX_EnumInputs m_hotkey;
+
+ /**
+ * valid x coordinate
+ */
+ short m_x;
+
+ /**
+ * valid y coordinate
+ */
+ short m_y;
+
+ public:
+ /**
+ * Allowable modes for the trigger status of the mouse sensor.
+ */
+ enum KX_MOUSESENSORMODE {
+ KX_MOUSESENSORMODE_NODEF = 0,
+ KX_MOUSESENSORMODE_LEFTBUTTON,
+ KX_MOUSESENSORMODE_MIDDLEBUTTON,
+ KX_MOUSESENSORMODE_RIGHTBUTTON,
+ KX_MOUSESENSORMODE_POSITION,
+ KX_MOUSESENSORMODE_POSITIONX,
+ KX_MOUSESENSORMODE_POSITIONY,
+ KX_MOUSESENSORMODE_MOVEMENT,
+ KX_MOUSESENSORMODE_MAX
+ };
+
+ bool isValid(KX_MOUSESENSORMODE);
+
+ SCA_MouseSensor(class SCA_MouseManager* keybdmgr,
+ int startx,int starty,
+ short int mousemode,
+ SCA_IObject* gameobj,
+ PyTypeObject* T=&Type );
+
+ virtual ~SCA_MouseSensor();
+ virtual CValue* GetReplica();
+ virtual bool Evaluate(CValue* event);
+
+ virtual bool IsPositiveTrigger();
+ short int GetModeKey();
+ SCA_IInputDevice::KX_EnumInputs GetHotKey();
+ void setX(short x);
+ void setY(short y);
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(char *attr);
+
+ /* read x-coordinate */
+ KX_PYMETHOD_DOC(SCA_MouseSensor,GetXPosition);
+ /* read y-coordinate */
+ KX_PYMETHOD_DOC(SCA_MouseSensor,GetYPosition);
+
+};
+
+#endif //__KX_MOUSESENSOR
diff --git a/source/gameengine/GameLogic/SCA_ORController.cpp b/source/gameengine/GameLogic/SCA_ORController.cpp
new file mode 100644
index 00000000000..966884da809
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_ORController.cpp
@@ -0,0 +1,135 @@
+/**
+ * 'Or' together all inputs
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "SCA_ORController.h"
+#include "SCA_ISensor.h"
+#include "SCA_LogicManager.h"
+#include "BoolValue.h"
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_ORController::SCA_ORController(SCA_IObject* gameobj,
+ PyTypeObject* T)
+ :SCA_IController(gameobj, T)
+{
+}
+
+
+
+SCA_ORController::~SCA_ORController()
+{
+}
+
+
+
+CValue* SCA_ORController::GetReplica()
+{
+ CValue* replica = new SCA_ORController(*this);
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+void SCA_ORController::Trigger(SCA_LogicManager* logicmgr)
+{
+
+ bool sensorresult = false;
+ SCA_ISensor* sensor;
+
+ vector<SCA_ISensor*>::const_iterator is=m_linkedsensors.begin();
+ while ( (!sensorresult) && (!(is==m_linkedsensors.end())) )
+ {
+ sensor = *is;
+ if (sensor->IsPositiveTrigger()) sensorresult = true;
+ is++;
+ }
+
+ CValue* newevent = new CBoolValue(sensorresult);
+
+ for (vector<SCA_IActuator*>::const_iterator i=m_linkedactuators.begin();
+ !(i==m_linkedactuators.end());i++)
+ {
+ SCA_IActuator* actua = *i;//m_linkedactuators.at(i);
+ logicmgr->AddActiveActuator(actua,newevent);
+ }
+
+
+ newevent->Release();
+}
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_ORController::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_ORController",
+ sizeof(SCA_ORController),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_ORController::Parents[] = {
+ &SCA_ORController::Type,
+ &SCA_IController::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef SCA_ORController::Methods[] = {
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* SCA_ORController::_getattr(char* attr) {
+ _getattr_up(SCA_IController);
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_ORController.h b/source/gameengine/GameLogic/SCA_ORController.h
new file mode 100644
index 00000000000..89dab8731ca
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_ORController.h
@@ -0,0 +1,58 @@
+/**
+ * SCA_ORController.h
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_ORCONTROLLER
+#define __KX_ORCONTROLLER
+
+#include "SCA_IController.h"
+
+class SCA_ORController : public SCA_IController
+{
+ Py_Header;
+ //virtual void Trigger(class SCA_LogicManager* logicmgr);
+public:
+ SCA_ORController(SCA_IObject* gameobj, PyTypeObject* T=&Type);
+
+ virtual ~SCA_ORController();
+ virtual CValue* GetReplica();
+ virtual void Trigger(SCA_LogicManager* logicmgr);
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(char *attr);
+};
+
+#endif //__KX_ORCONTROLLER
diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp
new file mode 100644
index 00000000000..893db892ef0
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp
@@ -0,0 +1,285 @@
+/**
+ * Assign, change, copy properties
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "SCA_PropertyActuator.h"
+#include "InputParser.h"
+
+#include "Operator2Expr.h"
+#include "ConstExpr.h"
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_PropertyActuator::SCA_PropertyActuator(SCA_IObject* gameobj,CValue* sourceObj,const STR_String& propname,const STR_String& expr,int acttype,PyTypeObject* T )
+: SCA_IActuator(gameobj,T),
+m_propname(propname),
+m_exprtxt(expr),
+m_type(acttype),
+m_sourceObj(sourceObj)
+{
+}
+
+SCA_PropertyActuator::~SCA_PropertyActuator()
+{
+}
+
+bool SCA_PropertyActuator::Update(double curtime,double deltatime)
+{
+ bool result = false;
+
+ bool bNegativeEvent = IsNegativeEvent();
+ RemoveAllEvents();
+
+
+ if (bNegativeEvent)
+ return false; // do nothing on negative events
+
+
+ CValue* propowner = GetParent();
+ CParser parser;
+ parser.SetContext( propowner->AddRef());
+
+ CExpression* userexpr = parser.ProcessText(m_exprtxt);
+ if (userexpr)
+ {
+
+
+ switch (m_type)
+ {
+
+ case KX_ACT_PROP_ASSIGN:
+ {
+
+ CValue* newval = userexpr->Calculate();
+ CValue* oldprop = propowner->GetProperty(m_propname);
+ if (oldprop)
+ {
+ oldprop->SetValue(newval);
+ newval->Release();
+ } else
+ {
+ propowner->SetProperty(m_propname,newval);
+ }
+
+ break;
+ }
+ case KX_ACT_PROP_ADD:
+ {
+ CValue* oldprop = propowner->GetProperty(m_propname);
+ if (oldprop)
+ {
+ int waarde = (int)oldprop->GetNumber();
+ CExpression* expr = new COperator2Expr(VALUE_ADD_OPERATOR,new CConstExpr(oldprop->AddRef()),
+ userexpr->AddRef());
+
+ CValue* newprop = expr->Calculate();
+ oldprop->SetValue(newprop);
+ newprop->Release();
+ expr->Release();
+
+ }
+
+ break;
+ }
+ case KX_ACT_PROP_COPY:
+ {
+ if (m_sourceObj)
+ {
+ CValue* copyprop = m_sourceObj->GetProperty(m_exprtxt);
+ if (copyprop)
+ {
+ GetParent()->SetProperty(
+ m_propname,
+ copyprop->GetReplica());
+
+ }
+ }
+ break;
+ }
+ default:
+ {
+
+ }
+ }
+
+ userexpr->Release();
+ }
+
+ return result;
+}
+
+ bool
+
+SCA_PropertyActuator::
+
+isValid(
+
+ SCA_PropertyActuator::KX_ACT_PROP_MODE mode
+
+){
+ bool res = false;
+ res = ((mode > KX_ACT_PROP_NODEF) && (mode < KX_ACT_PROP_MAX));
+ return res;
+}
+
+
+ CValue*
+
+SCA_PropertyActuator::
+
+GetReplica() {
+
+ SCA_PropertyActuator* replica = new SCA_PropertyActuator(*this);
+
+ replica->ProcessReplica();
+
+ // this will copy properties and so on...
+
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+
+};
+
+
+
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_PropertyActuator::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_PropertyActuator",
+ sizeof(SCA_PropertyActuator),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_PropertyActuator::Parents[] = {
+ &SCA_PropertyActuator::Type,
+ &SCA_IActuator::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef SCA_PropertyActuator::Methods[] = {
+ {"setProperty", (PyCFunction) SCA_PropertyActuator::sPySetProperty, METH_VARARGS, SetProperty_doc},
+ {"getProperty", (PyCFunction) SCA_PropertyActuator::sPyGetProperty, METH_VARARGS, GetProperty_doc},
+ {"setValue", (PyCFunction) SCA_PropertyActuator::sPySetValue, METH_VARARGS, SetValue_doc},
+ {"getValue", (PyCFunction) SCA_PropertyActuator::sPyGetValue, METH_VARARGS, GetValue_doc},
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* SCA_PropertyActuator::_getattr(char* attr) {
+ _getattr_up(SCA_IActuator);
+}
+
+/* 1. setProperty */
+char SCA_PropertyActuator::SetProperty_doc[] =
+"setProperty(name)\n"
+"\t- name: string\n"
+"\tSet the property on which to operate. If there is no property\n"
+"\tof this name, the call is ignored.\n";
+PyObject* SCA_PropertyActuator::PySetProperty(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ /* Check whether the name exists first ! */
+ char *nameArg;
+ if (!PyArg_ParseTuple(args, "s", &nameArg)) {
+ return NULL;
+ }
+
+ CValue* prop = GetParent()->FindIdentifier(nameArg);
+
+ if (prop) {
+ m_propname = nameArg;
+ } else {
+ ; /* not found ... */
+ }
+
+ Py_Return;
+}
+
+/* 2. getProperty */
+char SCA_PropertyActuator::GetProperty_doc[] =
+"getProperty(name)\n"
+"\tReturn the property on which the actuator operates.\n";
+PyObject* SCA_PropertyActuator::PyGetProperty(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return PyString_FromString(m_propname);
+}
+
+/* 3. setValue */
+char SCA_PropertyActuator::SetValue_doc[] =
+"setValue(value)\n"
+"\t- value: string\n"
+"\tSet the value with which the actuator operates. If the value\n"
+"\tis not compatible with the type of the property, the subsequent\n"
+"\t action is ignored.\n";
+PyObject* SCA_PropertyActuator::PySetValue(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ char *valArg;
+ if(!PyArg_ParseTuple(args, "s", &valArg)) {
+ return NULL;
+ }
+
+ if (valArg) m_exprtxt = valArg;
+
+ Py_Return;
+}
+
+/* 4. getValue */
+char SCA_PropertyActuator::GetValue_doc[] =
+"getValue()\n"
+"\tReturns the value with which the actuator operates.\n";
+PyObject* SCA_PropertyActuator::PyGetValue(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return PyString_FromString(m_exprtxt);
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.h b/source/gameengine/GameLogic/SCA_PropertyActuator.h
new file mode 100644
index 00000000000..7d09a8683cf
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_PropertyActuator.h
@@ -0,0 +1,116 @@
+/**
+ * SCA_PropertyActuator.h
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_PROPERTYACTUATOR
+#define __KX_PROPERTYACTUATOR
+
+#include "SCA_IActuator.h"
+
+class SCA_PropertyActuator : public SCA_IActuator
+{
+ Py_Header;
+
+ enum KX_ACT_PROP_MODE {
+ KX_ACT_PROP_NODEF = 0,
+ KX_ACT_PROP_ASSIGN,
+ KX_ACT_PROP_ADD,
+ KX_ACT_PROP_COPY,
+ KX_ACT_PROP_MAX
+ };
+
+ /**check whether this value is valid */
+ bool isValid(KX_ACT_PROP_MODE mode);
+
+ int m_type;
+ STR_String m_propname;
+ STR_String m_exprtxt;
+ CValue* m_sourceObj; // for copy property actuator
+
+public:
+
+
+
+ SCA_PropertyActuator(
+
+ SCA_IObject* gameobj,
+
+ CValue* sourceObj,
+
+ const STR_String& propname,
+
+ const STR_String& expr,
+
+ int acttype,
+
+ PyTypeObject* T=&Type
+
+ );
+
+
+ ~SCA_PropertyActuator();
+
+
+ CValue*
+
+ GetReplica(
+
+ );
+
+
+ bool
+
+ Update(
+
+ double curtime,
+
+ double deltatime
+
+ );
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ PyObject* _getattr(char *attr);
+
+ // python wrapped methods
+ KX_PYMETHOD_DOC(SCA_PropertyActuator,SetProperty);
+ KX_PYMETHOD_DOC(SCA_PropertyActuator,GetProperty);
+ KX_PYMETHOD_DOC(SCA_PropertyActuator,SetValue);
+ KX_PYMETHOD_DOC(SCA_PropertyActuator,GetValue);
+
+ /* 5. - ... setObject, getObject, setProp2, getProp2, setMode, getMode*/
+
+};
+#endif //__KX_PROPERTYACTUATOR_DOC
diff --git a/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp b/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp
new file mode 100644
index 00000000000..2b3ad1d2c1c
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp
@@ -0,0 +1,67 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "SCA_ISensor.h"
+
+#include "SCA_PropertyEventManager.h"
+
+
+
+SCA_PropertyEventManager::SCA_PropertyEventManager(class SCA_LogicManager* logicmgr)
+ : SCA_EventManager(PROPERTY_EVENTMGR),
+ m_logicmgr(logicmgr)
+{
+}
+
+
+
+SCA_PropertyEventManager::~SCA_PropertyEventManager()
+{
+
+}
+
+
+
+void SCA_PropertyEventManager::RegisterSensor(SCA_ISensor* sensor)
+{
+ m_sensors.push_back(sensor);
+}
+
+
+
+void SCA_PropertyEventManager::NextFrame(double curtime,double deltatime)
+{
+ // check for changed properties
+ for (vector<SCA_ISensor*>::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++)
+ {
+ (*it)->Activate(m_logicmgr,NULL);
+ }
+}
diff --git a/source/gameengine/GameLogic/SCA_PropertyEventManager.h b/source/gameengine/GameLogic/SCA_PropertyEventManager.h
new file mode 100644
index 00000000000..db203b7d92b
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_PropertyEventManager.h
@@ -0,0 +1,52 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef __KX_PROPERTYEVENTMANAGER
+#define __KX_PROPERTYEVENTMANAGER
+
+#include "SCA_EventManager.h"
+
+#include <vector>
+using namespace std;
+
+
+class SCA_PropertyEventManager : public SCA_EventManager
+{
+ class SCA_LogicManager* m_logicmgr;
+
+public:
+ SCA_PropertyEventManager(class SCA_LogicManager* logicmgr);
+ virtual ~SCA_PropertyEventManager();
+ virtual void NextFrame(double curtime,double deltatime);
+ virtual void RegisterSensor(SCA_ISensor* sensor);
+ //SCA_LogicManager* GetLogicManager() { return m_logicmgr;}
+};
+#endif //__KX_PROPERTYEVENTMANAGER
diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.cpp b/source/gameengine/GameLogic/SCA_PropertySensor.cpp
new file mode 100644
index 00000000000..52642c6757f
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_PropertySensor.cpp
@@ -0,0 +1,420 @@
+/**
+ * Property sensor
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <iostream>
+#include "SCA_PropertySensor.h"
+#include "Operator2Expr.h"
+#include "ConstExpr.h"
+#include "InputParser.h"
+#include "StringValue.h"
+#include "SCA_EventManager.h"
+#include "SCA_LogicManager.h"
+
+SCA_PropertySensor::SCA_PropertySensor(SCA_EventManager* eventmgr,
+ SCA_IObject* gameobj,
+ const STR_String& propname,
+ const STR_String& propval,
+ const STR_String& propmaxval,
+ KX_PROPSENSOR_TYPE checktype,
+ PyTypeObject* T )
+ : SCA_ISensor(gameobj,eventmgr,T),
+ m_checkpropname(propname),
+ m_checkpropval(propval),
+ m_checkpropmaxval(propmaxval),
+ m_checktype(checktype),
+ m_range_expr(NULL),
+ m_lastresult(false)
+{
+ m_recentresult=false;
+ //CParser pars;
+ //pars.SetContext(this->AddRef());
+ //CValue* resultval = m_rightexpr->Calculate();
+
+ CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname);
+ if (orgprop)
+ {
+ m_previoustext = orgprop->GetText();
+ orgprop->Release();
+ }
+
+ if (m_checktype==KX_PROPSENSOR_INTERVAL)
+ {
+ PrecalculateRangeExpression();
+ }
+
+}
+
+void SCA_PropertySensor::PrecalculateRangeExpression()
+{
+ CParser pars;
+ pars.SetContext(this->AddRef());
+ STR_String checkstr = "(" + m_checkpropval + " <= "
+ + m_checkpropname + ") && ( "
+ + m_checkpropname + " <= "
+ + m_checkpropmaxval;
+
+ m_range_expr = pars.ProcessText(checkstr);
+}
+
+
+
+CValue* SCA_PropertySensor::GetReplica()
+{
+ SCA_PropertySensor* replica = new SCA_PropertySensor(*this);
+ // m_range_expr must be recalculated on replica!
+ CValue::AddDataToReplica(replica);
+
+ replica->m_range_expr = NULL;
+ if (replica->m_checktype==KX_PROPSENSOR_INTERVAL)
+ {
+ replica->PrecalculateRangeExpression();
+ }
+
+
+ return replica;
+}
+
+
+
+bool SCA_PropertySensor::IsPositiveTrigger()
+{
+ bool result = m_recentresult;//CheckPropertyCondition();
+ if (m_invert)
+ result = !result;
+
+ return result;
+}
+
+
+
+SCA_PropertySensor::~SCA_PropertySensor()
+{
+ //if (m_rightexpr)
+ // m_rightexpr->Release();
+
+ if (m_range_expr)
+ {
+ m_range_expr->Release();
+ m_range_expr=NULL;
+ }
+
+}
+
+
+
+bool SCA_PropertySensor::Evaluate(CValue* event)
+{
+ bool result = CheckPropertyCondition();
+
+ if (m_lastresult!=result)
+ {
+ m_lastresult = result;
+ return true;
+ }
+
+ return false;
+}
+
+
+bool SCA_PropertySensor::CheckPropertyCondition()
+{
+
+ m_recentresult=false;
+ bool result=false;
+ bool reverse = false;
+ switch (m_checktype)
+ {
+ case KX_PROPSENSOR_NOTEQUAL:
+ reverse = true;
+ case KX_PROPSENSOR_EQUAL:
+ {
+ CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname);
+ if (orgprop)
+ {
+ STR_String testprop = orgprop->GetText();
+ // Force strings to upper case, to avoid confusion in
+ // bool tests. It's stupid the prop's identity is lost
+ // on the way here...
+ if ((testprop == "TRUE") || (testprop == "FALSE")) {
+ STR_String checkprop = m_checkpropval;
+ checkprop.Upper();
+ result = (testprop == checkprop);
+ } else {
+ result = (orgprop->GetText() == m_checkpropval);
+ }
+ orgprop->Release();
+
+ }
+
+ if (reverse)
+ result = !result;
+ break;
+
+ }
+
+ case KX_PROPSENSOR_EXPRESSION:
+ {
+ /*
+ if (m_rightexpr)
+ {
+ CValue* resultval = m_rightexpr->Calculate();
+ if (resultval->IsError())
+ {
+ int i=0;
+ STR_String errortest = resultval->GetText();
+ printf(errortest);
+
+ } else
+ {
+ result = resultval->GetNumber() != 0;
+ }
+ }
+ */
+ break;
+ }
+ case KX_PROPSENSOR_INTERVAL:
+ {
+ //CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname);
+ //if (orgprop)
+ //{
+ if (m_range_expr)
+ {
+ CValue* vallie = m_range_expr->Calculate();
+ if (vallie)
+ {
+ STR_String errtext = vallie->GetText();
+ if (errtext == "TRUE")
+ {
+ result = true;
+ } else
+ {
+ if (vallie->IsError())
+ {
+ //printf (errtext.ReadPtr());
+ }
+ }
+
+ vallie->Release();
+ }
+ }
+
+
+ //}
+
+ //cout << " \nSens:Prop:interval!"; /* need implementation here!!! */
+
+ break;
+ }
+ case KX_PROPSENSOR_CHANGED:
+ {
+ CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname);
+
+ if (orgprop)
+ {
+ if (m_previoustext != orgprop->GetText())
+ {
+ m_previoustext = orgprop->GetText();
+ result = true;
+ }
+ orgprop->Release();
+ }
+
+ //cout << " \nSens:Prop:changed!"; /* need implementation here!!! */
+ break;
+ }
+ default:
+ ; /* error */
+ }
+ m_recentresult=result;
+ return result;
+}
+
+CValue* SCA_PropertySensor::FindIdentifier(const STR_String& identifiername)
+{
+ return GetParent()->FindIdentifier(identifiername);
+}
+
+bool SCA_PropertySensor::validValueForProperty(char *val, STR_String &prop)
+{
+ bool result = true;
+ /* There is no type checking at this moment, unfortunately... */
+ return result;
+}
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_PropertySensor::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_PropertySensor",
+ sizeof(SCA_PropertySensor),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_PropertySensor::Parents[] = {
+ &SCA_PropertySensor::Type,
+ &SCA_ISensor::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef SCA_PropertySensor::Methods[] = {
+ {"getType", (PyCFunction) SCA_PropertySensor::sPyGetType, METH_VARARGS, GetType_doc},
+ {"setType", (PyCFunction) SCA_PropertySensor::sPySetType, METH_VARARGS, SetType_doc},
+ {"getProperty", (PyCFunction) SCA_PropertySensor::sPyGetProperty, METH_VARARGS, GetProperty_doc},
+ {"setProperty", (PyCFunction) SCA_PropertySensor::sPySetProperty, METH_VARARGS, SetProperty_doc},
+ {"getValue", (PyCFunction) SCA_PropertySensor::sPyGetValue, METH_VARARGS, GetValue_doc},
+ {"setValue", (PyCFunction) SCA_PropertySensor::sPySetValue, METH_VARARGS, SetValue_doc},
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* SCA_PropertySensor::_getattr(char* attr) {
+ _getattr_up(SCA_ISensor); /* implicit return! */
+}
+
+/* 1. getType */
+char SCA_PropertySensor::GetType_doc[] =
+"getType()\n"
+"\tReturns the type of check this sensor performs.\n";
+PyObject* SCA_PropertySensor::PyGetType(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return PyInt_FromLong(m_checktype);
+}
+
+/* 2. setType */
+char SCA_PropertySensor::SetType_doc[] =
+"setType(type)\n"
+"\t- type: KX_PROPSENSOR_EQUAL, KX_PROPSENSOR_NOTEQUAL,\n"
+"\t KX_PROPSENSOR_INTERVAL, KX_PROPSENSOR_CHANGED,\n"
+"\t or KX_PROPSENSOR_EXPRESSION.\n"
+"\tSet the type of check to perform.\n";
+PyObject* SCA_PropertySensor::PySetType(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int typeArg;
+
+ if (!PyArg_ParseTuple(args, "i", &typeArg)) {
+ return NULL;
+ }
+
+ if ( (typeArg > KX_PROPSENSOR_NODEF)
+ && (typeArg < KX_PROPSENSOR_MAX) ) {
+ m_checktype = typeArg;
+ }
+
+ Py_Return;
+}
+
+/* 3. getProperty */
+char SCA_PropertySensor::GetProperty_doc[] =
+"getProperty()\n"
+"\tReturn the property with which the sensor operates.\n";
+PyObject* SCA_PropertySensor::PyGetProperty(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return PyString_FromString(m_checkpropname);
+}
+
+/* 4. setProperty */
+char SCA_PropertySensor::SetProperty_doc[] =
+"setProperty(name)\n"
+"\t- name: string\n"
+"\tSets the property with which to operate. If there is no property\n"
+"\tof this name, the call is ignored.\n";
+PyObject* SCA_PropertySensor::PySetProperty(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ /* We should query whether the name exists. Or should we create a prop */
+ /* on the fly? */
+ char *propNameArg = NULL;
+
+ if (!PyArg_ParseTuple(args, "s", &propNameArg)) {
+ return NULL;
+ }
+
+ if (FindIdentifier(STR_String(propNameArg))) {
+ m_checkpropname = propNameArg;
+ } else {
+ ; /* error: bad property name */
+ }
+
+ Py_Return;
+}
+
+/* 5. getValue */
+char SCA_PropertySensor::GetValue_doc[] =
+"getValue()\n"
+"\tReturns the value with which the sensor operates.\n";
+PyObject* SCA_PropertySensor::PyGetValue(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return PyString_FromString(m_checkpropval);
+}
+
+/* 6. setValue */
+char SCA_PropertySensor::SetValue_doc[] =
+"setValue(value)\n"
+"\t- value: string\n"
+"\tSet the value with which the sensor operates. If the value\n"
+"\tis not compatible with the type of the property, the subsequent\n"
+"\t action is ignored.\n";
+PyObject* SCA_PropertySensor::PySetValue(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ /* Here, we need to check whether the value is 'valid' for this property.*/
+ /* We know that the property exists, or is NULL. */
+ char *propValArg = NULL;
+
+ if(!PyArg_ParseTuple(args, "s", &propValArg)) {
+ return NULL;
+ }
+
+ if (validValueForProperty(propValArg, m_checkpropname)) {
+ m_checkpropval = propValArg;
+ }
+
+ Py_Return;
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.h b/source/gameengine/GameLogic/SCA_PropertySensor.h
new file mode 100644
index 00000000000..89debebda3d
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_PropertySensor.h
@@ -0,0 +1,109 @@
+/**
+ * Property sensor
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_PROPERTYSENSOR
+#define __KX_PROPERTYSENSOR
+
+#include "SCA_ISensor.h"
+
+class SCA_PropertySensor : public SCA_ISensor
+{
+ Py_Header;
+ //class CExpression* m_rightexpr;
+ int m_checktype;
+ STR_String m_checkpropval;
+ STR_String m_checkpropmaxval;
+ STR_String m_checkpropname;
+ STR_String m_previoustext;
+ bool m_lastresult;
+ bool m_recentresult;
+ CExpression* m_range_expr;
+
+ /**
+ * Test whether this is a sensible value (type check)
+ */
+ bool validValueForProperty(char *val, STR_String &prop);
+ protected:
+
+public:
+ enum KX_PROPSENSOR_TYPE {
+ KX_PROPSENSOR_NODEF = 0,
+ KX_PROPSENSOR_EQUAL,
+ KX_PROPSENSOR_NOTEQUAL,
+ KX_PROPSENSOR_INTERVAL,
+ KX_PROPSENSOR_CHANGED,
+ KX_PROPSENSOR_EXPRESSION,
+ KX_PROPSENSOR_MAX
+ };
+
+ const STR_String S_KX_PROPSENSOR_EQ_STRING;
+
+ SCA_PropertySensor(class SCA_EventManager* eventmgr,
+ SCA_IObject* gameobj,
+ const STR_String& propname,
+ const STR_String& propval,
+ const STR_String& propmaxval,
+ KX_PROPSENSOR_TYPE checktype,
+ PyTypeObject* T=&Type );
+
+ virtual ~SCA_PropertySensor();
+ virtual CValue* GetReplica();
+ void PrecalculateRangeExpression();
+ bool CheckPropertyCondition();
+
+ virtual bool Evaluate(CValue* event);
+ virtual bool IsPositiveTrigger();
+ virtual CValue* FindIdentifier(const STR_String& identifiername);
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(char *attr);
+
+ /* 1. getType */
+ KX_PYMETHOD_DOC(SCA_PropertySensor,GetType);
+ /* 2. setType */
+ KX_PYMETHOD_DOC(SCA_PropertySensor,SetType);
+ /* 3. setProperty */
+ KX_PYMETHOD_DOC(SCA_PropertySensor,SetProperty);
+ /* 4. getProperty */
+ KX_PYMETHOD_DOC(SCA_PropertySensor,GetProperty);
+ /* 5. getValue */
+ KX_PYMETHOD_DOC(SCA_PropertySensor,GetValue);
+ /* 6. setValue */
+ KX_PYMETHOD_DOC(SCA_PropertySensor,SetValue);
+
+};
+#endif
diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp
new file mode 100644
index 00000000000..2d57a5f116d
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_PythonController.cpp
@@ -0,0 +1,400 @@
+/**
+ * Execute Python scripts
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "SCA_PythonController.h"
+#include "SCA_LogicManager.h"
+#include "SCA_ISensor.h"
+#include "SCA_IActuator.h"
+#include "compile.h"
+#include "eval.h"
+
+
+// initialize static member variables
+SCA_PythonController* SCA_PythonController::m_sCurrentController = NULL;
+
+
+SCA_PythonController::SCA_PythonController(SCA_IObject* gameobj,
+ PyTypeObject* T)
+ : SCA_IController(gameobj, T),
+ m_pythondictionary(NULL),
+ m_bytecode(NULL),
+ m_bModified(true)
+{
+}
+
+
+
+SCA_PythonController::~SCA_PythonController()
+{
+ if (m_bytecode)
+ {
+ //
+ //printf("released python byte script\n");
+ Py_DECREF(m_bytecode);
+ }
+}
+
+
+
+CValue* SCA_PythonController::GetReplica()
+{
+ SCA_PythonController* replica = new SCA_PythonController(*this);
+ replica->m_bytecode = NULL;
+ replica->m_bModified = true;
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+void SCA_PythonController::SetScriptText(const STR_String& text)
+{
+ m_scriptText = text;
+ m_bModified = true;
+}
+
+
+
+void SCA_PythonController::SetScriptName(const STR_String& name)
+{
+ m_scriptName = name;
+}
+
+
+
+void SCA_PythonController::SetDictionary(PyObject* pythondictionary)
+{
+ m_pythondictionary = pythondictionary;
+}
+
+
+static char* sPyGetCurrentController__doc__;
+
+
+PyObject* SCA_PythonController::sPyGetCurrentController(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ m_sCurrentController->AddRef();
+ return m_sCurrentController;
+}
+
+
+static char* sPyAddActiveActuator__doc__;
+
+
+PyObject* SCA_PythonController::sPyAddActiveActuator(
+
+ PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+
+ PyObject* ob1;
+ int activate;
+ if (!PyArg_ParseTuple(args, "Oi", &ob1,&activate))
+ {
+ return NULL;
+
+ }
+ // for safety, todo: only allow for registered actuators (pointertable)
+ // we don't want to crash gameengine/blender by python scripts
+
+ CValue* ac = (CValue*)ob1;
+ CValue* boolval = new CBoolValue(activate!=0);
+ m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)ac,boolval);
+ boolval->Release();
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+char* SCA_PythonController::sPyGetCurrentController__doc__ = "getCurrentController()";
+char* SCA_PythonController::sPyAddActiveActuator__doc__= "addActiveActuator(actuator,bool)";
+char SCA_PythonController::GetActuators_doc[] = "getActuator";
+
+PyTypeObject SCA_PythonController::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_PythonController",
+ sizeof(SCA_PythonController),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_PythonController::Parents[] = {
+ &SCA_PythonController::Type,
+ &SCA_IController::Type,
+ &CValue::Type,
+ NULL
+};
+PyMethodDef SCA_PythonController::Methods[] = {
+ {"getActuators", (PyCFunction) SCA_PythonController::sPyGetActuators,
+ METH_VARARGS, SCA_PythonController::GetActuators_doc},
+ {"getActuator", (PyCFunction) SCA_PythonController::sPyGetActuator,
+ METH_VARARGS, SCA_PythonController::GetActuator_doc},
+ {"getSensors", (PyCFunction) SCA_PythonController::sPyGetSensors,
+ METH_VARARGS, SCA_PythonController::GetSensors_doc},
+ {"getSensor", (PyCFunction) SCA_PythonController::sPyGetSensor,
+ METH_VARARGS, SCA_PythonController::GetSensor_doc}
+ ,
+ {NULL,NULL} //Sentinel
+};
+
+
+
+ /* XXX, function should be removed and PyDict_Copy used
+ * once we switch to all builds using Python 2.0 - zr */
+static PyObject *myPyDict_Copy(PyObject *odict)
+{
+ PyObject *ndict= PyDict_New();
+ PyObject *key, *val;
+ int ppos= 0;
+
+ while (PyDict_Next(odict, &ppos, &key, &val))
+ PyDict_SetItem(ndict, key, val);
+
+ return ndict;
+}
+
+void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr)
+{
+ m_sCurrentController = this;
+ m_sCurrentLogicManager = logicmgr;
+
+ if (m_bModified)
+ {
+ // if a script already exists, decref it before replace the pointer to a new script
+ if (m_bytecode)
+ {
+ Py_DECREF(m_bytecode);
+ m_bytecode=NULL;
+ }
+ // recompile the scripttext into bytecode
+ m_bytecode = Py_CompileString(m_scriptText.Ptr(), m_scriptName.Ptr(), Py_file_input);
+ if (m_bytecode)
+ {
+ // store the
+ int i=0;
+ i+=2; // so compiler doesn't complain about unused variable
+ PyRun_SimpleString("import GameLogic\n");
+ } else
+ {
+ // didn't compile, so instead of compile, complain
+ int i=0;
+ i++; // so compiler doesn't complain about unused variable
+ }
+ m_bModified=false;
+ }
+
+ /*
+ * This part here with excdict is a temporary patch
+ * to avoid python/gameengine crashes when python
+ * inadvertently holds references to game objects
+ * in global variables.
+ *
+ * The idea is always make a fresh dictionary, and
+ * destroy it right after it is used to make sure
+ * python won't hold any gameobject references.
+ *
+ * Note that the PyDict_Clear _is_ necessary before
+ * the Py_DECREF() because it is possible for the
+ * variables inside the dictionary to hold references
+ * to the dictionary (ie. generate a cycle), so we
+ * break it by hand, then DECREF (which in this case
+ * should always ensure excdict is cleared).
+ */
+ PyObject *excdict= myPyDict_Copy(m_pythondictionary);
+ struct _object* resultobj = PyEval_EvalCode((PyCodeObject*)m_bytecode,
+ excdict,
+ excdict
+ );
+ PyDict_Clear(excdict);
+ Py_DECREF(excdict);
+
+ if (resultobj)
+ {
+ Py_DECREF(resultobj);
+ } else
+ {
+ // something is wrong, tell the user what went wrong
+ printf("PYTHON SCRIPT ERROR:\n");
+ PyRun_SimpleString(m_scriptText.Ptr());
+ }
+
+ m_sCurrentController = NULL;
+}
+
+
+
+PyObject* SCA_PythonController::_getattr(char* attr)
+{
+ _getattr_up(SCA_IController);
+}
+
+
+
+PyObject* SCA_PythonController::PyGetActuators(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ int index;
+
+ PyObject* resultlist = PyList_New(m_linkedactuators.size());
+ for (index=0;index<m_linkedactuators.size();index++)
+ {
+ PyList_SetItem(resultlist,index,m_linkedactuators[index]->AddRef());
+ }
+
+ return resultlist;
+}
+
+char SCA_PythonController::GetSensor_doc[] =
+"GetSensor (char sensorname) return linked sensor that is named [sensorname]\n";
+PyObject*
+SCA_PythonController::PyGetSensor(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+
+ char *scriptArg;
+
+ if (!PyArg_ParseTuple(args, "s", &scriptArg)) {
+ return NULL;
+ }
+
+ int index;
+ for (index=0;index<m_linkedsensors.size();index++)
+ {
+ SCA_ISensor* sensor = m_linkedsensors[index];
+ STR_String realname = sensor->GetName();
+ if (realname == scriptArg)
+ {
+ return sensor->AddRef();
+ }
+ }
+
+ PyErr_SetString(PyExc_AttributeError, "Unable to find requested sensor");
+ return NULL;
+}
+
+
+
+char SCA_PythonController::GetActuator_doc[] =
+"GetActuator (char sensorname) return linked actuator that is named [actuatorname]\n";
+PyObject*
+SCA_PythonController::PyGetActuator(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+
+ char *scriptArg;
+
+ if (!PyArg_ParseTuple(args, "s", &scriptArg)) {
+ return NULL;
+ }
+
+ int index;
+ for (index=0;index<m_linkedactuators.size();index++)
+ {
+ SCA_IActuator* actua = m_linkedactuators[index];
+ STR_String realname = actua->GetName();
+ if (realname == scriptArg)
+ {
+ return actua->AddRef();
+ }
+ }
+
+ PyErr_SetString(PyExc_AttributeError, "Unable to find requested actuator");
+ return NULL;
+}
+
+
+char SCA_PythonController::GetSensors_doc[] = "getSensors returns a list of all attached sensors";
+PyObject*
+SCA_PythonController::PyGetSensors(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ int index;
+
+ PyObject* resultlist = PyList_New(m_linkedsensors.size());
+ for (index=0;index<m_linkedsensors.size();index++)
+ {
+ PyList_SetItem(resultlist,index,m_linkedsensors[index]->AddRef());
+ }
+
+ return resultlist;
+}
+
+/* 1. getScript */
+PyObject* SCA_PythonController::PyGetScript(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ return PyString_FromString(m_scriptText);
+}
+
+/* 2. setScript */
+PyObject* SCA_PythonController::PySetScript(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ char *scriptArg;
+ if (!PyArg_ParseTuple(args, "s", &scriptArg)) {
+ return NULL;
+ }
+
+ /* set scripttext sets m_bModified to true,
+ so next time the script is needed, a reparse into byte code is done */
+
+ this->SetScriptText(scriptArg);
+
+ Py_Return;
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_PythonController.h b/source/gameengine/GameLogic/SCA_PythonController.h
new file mode 100644
index 00000000000..f19fcac72f3
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_PythonController.h
@@ -0,0 +1,88 @@
+/**
+ * Execute Python scripts
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef KX_PYTHONCONTROLLER_H
+#define KX_PYTHONCONTROLLER_H
+
+#include "SCA_IController.h"
+#include "SCA_LogicManager.h"
+#include "BoolValue.h"
+
+class SCA_IObject;
+class SCA_PythonController : public SCA_IController
+{
+ Py_Header;
+ struct _object * m_bytecode;
+ bool m_bModified;
+
+ protected:
+ STR_String m_scriptText;
+ STR_String m_scriptName;
+ PyObject* m_pythondictionary;
+
+ public:
+ static SCA_PythonController* m_sCurrentController; // protected !!!
+
+ SCA_PythonController(SCA_IObject* gameobj,PyTypeObject* T = &Type);
+ virtual ~SCA_PythonController();
+
+ virtual CValue* GetReplica();
+ virtual void Trigger(class SCA_LogicManager* logicmgr);
+
+ void SetScriptText(const STR_String& text);
+ void SetScriptName(const STR_String& name);
+ void SetDictionary(PyObject* pythondictionary);
+
+ static char* sPyGetCurrentController__doc__;
+ static PyObject* sPyGetCurrentController(PyObject* self,
+ PyObject* args,
+ PyObject* kwds);
+ static char* sPyAddActiveActuator__doc__;
+ static PyObject* sPyAddActiveActuator(PyObject* self,
+ PyObject* args,
+ PyObject* kwds);
+ virtual PyObject* _getattr(char *attr);
+
+ KX_PYMETHOD_DOC(SCA_PythonController,GetSensors);
+ KX_PYMETHOD_DOC(SCA_PythonController,GetSensor);
+ KX_PYMETHOD_DOC(SCA_PythonController,GetActuator);
+ KX_PYMETHOD_DOC(SCA_PythonController,GetActuators);
+ KX_PYMETHOD(SCA_PythonController,SetScript);
+ KX_PYMETHOD(SCA_PythonController,GetScript);
+
+
+};
+
+#endif //KX_PYTHONCONTROLLER_H
+
diff --git a/source/gameengine/GameLogic/SCA_RandomActuator.cpp b/source/gameengine/GameLogic/SCA_RandomActuator.cpp
new file mode 100644
index 00000000000..50acf24251f
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_RandomActuator.cpp
@@ -0,0 +1,630 @@
+/**
+ * Set random/camera stuff
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "BoolValue.h"
+#include "IntValue.h"
+#include "FloatValue.h"
+#include "SCA_IActuator.h"
+#include "SCA_RandomActuator.h"
+#include "math.h"
+
+#include "MT_Transform.h"
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_RandomActuator::SCA_RandomActuator(SCA_IObject *gameobj,
+ long seed,
+ SCA_RandomActuator::KX_RANDOMACT_MODE mode,
+ float para1,
+ float para2,
+ const STR_String &propName,
+ PyTypeObject* T)
+ : SCA_IActuator(gameobj, T),
+ m_distribution(mode),
+ m_propname(propName),
+ m_parameter1(para1),
+ m_parameter2(para2)
+{
+ m_base = new SCA_RandomNumberGenerator(seed);
+ m_counter = 0;
+ enforceConstraints();
+}
+
+
+
+SCA_RandomActuator::~SCA_RandomActuator()
+{
+ /* intentionally empty */
+}
+
+
+
+CValue* SCA_RandomActuator::GetReplica()
+{
+ SCA_RandomActuator* replica = new SCA_RandomActuator(*this);
+ replica->ProcessReplica();
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+bool SCA_RandomActuator::Update(double curtime,double deltatime)
+{
+ bool result = false;
+ bool bNegativeEvent = IsNegativeEvent();
+
+ RemoveAllEvents();
+
+
+ CValue *tmpval;
+
+ if (bNegativeEvent)
+ return false; // do nothing on negative events
+
+ switch (m_distribution) {
+ case KX_RANDOMACT_BOOL_CONST: {
+ /* un petit peu filthy */
+ bool res = !(m_parameter1 < 0.5);
+ tmpval = new CBoolValue(res);
+ }
+ break;
+ case KX_RANDOMACT_BOOL_UNIFORM: {
+ /* flip a coin */
+ bool res;
+ if (m_counter > 31) {
+ m_previous = m_base->Draw();
+ res = ((m_previous & 0x1) == 0);
+ m_counter = 1;
+ } else {
+ res = (((m_previous >> m_counter) & 0x1) == 0);
+ m_counter++;
+ }
+ tmpval = new CBoolValue(res);
+ }
+ break;
+ case KX_RANDOMACT_BOOL_BERNOUILLI: {
+ /* 'percentage' */
+ bool res;
+ res = (m_base->DrawFloat() < m_parameter1);
+ tmpval = new CBoolValue(res);
+ }
+ break;
+ case KX_RANDOMACT_INT_CONST: {
+ /* constant */
+ tmpval = new CIntValue((int) floor(m_parameter1));
+ }
+ break;
+ case KX_RANDOMACT_INT_UNIFORM: {
+ /* uniform (toss a die) */
+ int res;
+ /* The [0, 1] interval is projected onto the [min, max+1] domain, */
+ /* and then rounded. */
+ res = (int) floor( ((m_parameter2 - m_parameter1 + 1) * m_base->DrawFloat())
+ + m_parameter1);
+ tmpval = new CIntValue(res);
+ }
+ break;
+ case KX_RANDOMACT_INT_POISSON: {
+ /* poisson (queues) */
+ /* If x_1, x_2, ... is a sequence of random numbers with uniform */
+ /* distribution between zero and one, k is the first integer for */
+ /* which the product x_1*x_2*...*x_k < exp(-\lamba). */
+ float a = 0.0, b = 0.0;
+ int res = 0;
+ /* The - sign is important here! The number to test for, a, must be */
+ /* between 0 and 1. */
+ a = exp(-m_parameter1);
+ /* a quickly reaches 0.... so we guard explicitly for that. */
+ if (a < FLT_MIN) a = FLT_MIN;
+ b = m_base->DrawFloat();
+ while (b >= a) {
+ b = b * m_base->DrawFloat();
+ res++;
+ };
+ tmpval = new CIntValue(res);
+ }
+ break;
+ case KX_RANDOMACT_FLOAT_CONST: {
+ /* constant */
+ tmpval = new CFloatValue(m_parameter1);
+ }
+ break;
+ case KX_RANDOMACT_FLOAT_UNIFORM: {
+ float res = ((m_parameter2 - m_parameter1) * m_base->DrawFloat())
+ + m_parameter1;
+ tmpval = new CFloatValue(res);
+ }
+ break;
+ case KX_RANDOMACT_FLOAT_NORMAL: {
+ /* normal (big numbers): para1 = mean, para2 = std dev */
+
+ /*
+
+ 070301 - nzc - Changed the termination condition. I think I
+ made a small mistake here, but it only affects distro's where
+ the seed equals 0. In that case, the algorithm locks. Let's
+ just guard that case separately.
+
+ */
+
+ float x = 0.0, y = 0.0, s = 0.0, t = 0.0;
+ if (m_base->GetSeed() == 0) {
+ /*
+
+ 070301 - nzc
+ Just taking the mean here seems reasonable.
+
+ */
+ tmpval = new CFloatValue(m_parameter1);
+ } else {
+ /*
+
+ 070301 - nzc
+ Now, with seed != 0, we will most assuredly get some
+ sensible values. The termination condition states two
+ things:
+ 1. s >= 0 is not allowed: to prevent the distro from
+ getting a bias towards high values. This is a small
+ correction, really, and might also be left out.
+ 2. s == 0 is not allowed: to prevent a division by zero
+ when renormalising the drawn value to the desired
+ distribution shape. As a side effect, the distro will
+ never yield the exact mean.
+ I am not sure whether this is consistent, since the error
+ cause by #2 is of the same magnitude as the one
+ prevented by #1. The error introduced into the SD will be
+ improved, though. By how much? Hard to say... If you like
+ the maths, feel free to analyse. Be aware that this is
+ one of the really old standard algorithms. I think the
+ original came in Fortran, was translated to Pascal, and
+ then someone came up with the C code. My guess it that
+ this will be quite sufficient here.
+
+ */
+ do
+ {
+ x = 2.0 * m_base->DrawFloat() - 1.0;
+ y = 2.0 * m_base->DrawFloat() - 1.0;
+ s = x*x + y*y;
+ } while ( (s >= 1.0) || (s == 0.0) );
+ t = x * sqrt( (-2.0 * log(s)) / s);
+ tmpval = new CFloatValue(m_parameter1 + m_parameter2 * t);
+ }
+ }
+ break;
+ case KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL: {
+ /* 1st order fall-off. I am very partial to using the half-life as */
+ /* controlling parameter. Using the 'normal' exponent is not very */
+ /* intuitive... */
+ /* tmpval = new CFloatValue( (1.0 / m_parameter1) */
+ tmpval = new CFloatValue( (m_parameter1)
+ * (-log(1.0 - m_base->DrawFloat())) );
+
+ }
+ break;
+ default:
+ ; /* unknown distribution... */
+ }
+
+ /* Round up: assign it */
+ CValue *prop = GetParent()->GetProperty(m_propname);
+ if (prop) {
+ prop->SetValue(tmpval);
+ }
+ tmpval->Release();
+
+ return false;
+}
+
+void SCA_RandomActuator::enforceConstraints() {
+ /* The constraints that are checked here are the ones fundamental to */
+ /* the various distributions. Limitations of the algorithms are checked */
+ /* elsewhere (or they should be... ). */
+ switch (m_distribution) {
+ case KX_RANDOMACT_BOOL_CONST:
+ case KX_RANDOMACT_BOOL_UNIFORM:
+ case KX_RANDOMACT_INT_CONST:
+ case KX_RANDOMACT_INT_UNIFORM:
+ case KX_RANDOMACT_FLOAT_UNIFORM:
+ case KX_RANDOMACT_FLOAT_CONST:
+ ; /* Nothing to be done here. We allow uniform distro's to have */
+ /* 'funny' domains, i.e. max < min. This does not give problems. */
+ break;
+ case KX_RANDOMACT_BOOL_BERNOUILLI:
+ /* clamp to [0, 1] */
+ if (m_parameter1 < 0.0) {
+ m_parameter1 = 0.0;
+ } else if (m_parameter1 > 1.0) {
+ m_parameter1 = 1.0;
+ }
+ break;
+ case KX_RANDOMACT_INT_POISSON:
+ /* non-negative */
+ if (m_parameter1 < 0.0) {
+ m_parameter1 = 0.0;
+ }
+ break;
+ case KX_RANDOMACT_FLOAT_NORMAL:
+ /* standard dev. is non-negative */
+ if (m_parameter2 < 0.0) {
+ m_parameter2 = 0.0;
+ }
+ break;
+ case KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL:
+ /* halflife must be non-negative */
+ if (m_parameter1 < 0.0) {
+ m_parameter1 = 0.0;
+ }
+ break;
+ default:
+ ; /* unknown distribution... */
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_RandomActuator::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_RandomActuator",
+ sizeof(SCA_RandomActuator),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_RandomActuator::Parents[] = {
+ &SCA_RandomActuator::Type,
+ &SCA_IActuator::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef SCA_RandomActuator::Methods[] = {
+ {"setSeed", (PyCFunction) SCA_RandomActuator::sPySetSeed, METH_VARARGS, SetSeed_doc},
+ {"getSeed", (PyCFunction) SCA_RandomActuator::sPyGetSeed, METH_VARARGS, GetSeed_doc},
+ {"getPara1", (PyCFunction) SCA_RandomActuator::sPyGetPara1, METH_VARARGS, GetPara1_doc},
+ {"getPara2", (PyCFunction) SCA_RandomActuator::sPyGetPara2, METH_VARARGS, GetPara2_doc},
+ {"getDistribution", (PyCFunction) SCA_RandomActuator::sPyGetDistribution, METH_VARARGS, GetDistribution_doc},
+ {"setProperty", (PyCFunction) SCA_RandomActuator::sPySetProperty, METH_VARARGS, SetProperty_doc},
+ {"getProperty", (PyCFunction) SCA_RandomActuator::sPyGetProperty, METH_VARARGS, GetProperty_doc},
+ {"setBoolConst", (PyCFunction) SCA_RandomActuator::sPySetBoolConst, METH_VARARGS, SetBoolConst_doc},
+ {"setBoolUniform", (PyCFunction) SCA_RandomActuator::sPySetBoolUniform, METH_VARARGS, SetBoolUniform_doc},
+ {"setBoolBernouilli",(PyCFunction) SCA_RandomActuator::sPySetBoolBernouilli, METH_VARARGS, SetBoolBernouilli_doc},
+ {"setIntConst", (PyCFunction) SCA_RandomActuator::sPySetIntConst, METH_VARARGS, SetIntConst_doc},
+ {"setIntUniform", (PyCFunction) SCA_RandomActuator::sPySetIntUniform, METH_VARARGS, SetIntUniform_doc},
+ {"setIntPoisson", (PyCFunction) SCA_RandomActuator::sPySetIntPoisson, METH_VARARGS, SetIntPoisson_doc},
+ {"setFloatConst", (PyCFunction) SCA_RandomActuator::sPySetFloatConst, METH_VARARGS, SetFloatConst_doc},
+ {"setFloatUniform", (PyCFunction) SCA_RandomActuator::sPySetFloatUniform, METH_VARARGS, SetFloatUniform_doc},
+ {"setFloatNormal", (PyCFunction) SCA_RandomActuator::sPySetFloatNormal, METH_VARARGS, SetFloatNormal_doc},
+ {"setFloatNegativeExponential", (PyCFunction) SCA_RandomActuator::sPySetFloatNegativeExponential, METH_VARARGS, SetFloatNegativeExponential_doc},
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* SCA_RandomActuator::_getattr(char* attr) {
+ _getattr_up(SCA_IActuator);
+}
+
+/* 1. setSeed */
+char SCA_RandomActuator::SetSeed_doc[] =
+"setSeed(seed)\n"
+"\t- seed: integer\n"
+"\tSet the initial seed of the generator. Equal seeds produce\n"
+"\tequal series. If the seed is 0, the generator will produce\n"
+"\tthe same value on every call.\n";
+PyObject* SCA_RandomActuator::PySetSeed(PyObject* self, PyObject* args, PyObject* kwds) {
+ long seedArg;
+ if(!PyArg_ParseTuple(args, "i", &seedArg)) {
+ return NULL;
+ }
+
+ m_base->SetSeed(seedArg);
+
+ Py_Return;
+}
+/* 2. getSeed */
+char SCA_RandomActuator::GetSeed_doc[] =
+"getSeed()\n"
+"\tReturns the initial seed of the generator. Equal seeds produce\n"
+"\tequal series.\n";
+PyObject* SCA_RandomActuator::PyGetSeed(PyObject* self, PyObject* args, PyObject* kwds) {
+ return PyInt_FromLong(m_base->GetSeed());
+}
+
+/* 4. getPara1 */
+char SCA_RandomActuator::GetPara1_doc[] =
+"getPara1()\n"
+"\tReturns the first parameter of the active distribution. Refer\n"
+"\tto the documentation of the generator types for the meaning\n"
+"\tof this value.";
+PyObject* SCA_RandomActuator::PyGetPara1(PyObject* self, PyObject* args, PyObject* kwds) {
+ return PyFloat_FromDouble(m_parameter1);
+}
+
+/* 6. getPara2 */
+char SCA_RandomActuator::GetPara2_doc[] =
+"getPara2()\n"
+"\tReturns the first parameter of the active distribution. Refer\n"
+"\tto the documentation of the generator types for the meaning\n"
+"\tof this value.";
+PyObject* SCA_RandomActuator::PyGetPara2(PyObject* self, PyObject* args, PyObject* kwds) {
+ return PyFloat_FromDouble(m_parameter2);
+}
+
+/* 8. getDistribution */
+char SCA_RandomActuator::GetDistribution_doc[] =
+"getDistribution()\n"
+"\tReturns the type of the active distribution.\n";
+PyObject* SCA_RandomActuator::PyGetDistribution(PyObject* self, PyObject* args, PyObject* kwds) {
+ return PyInt_FromLong(m_distribution);
+}
+
+/* 9. setProperty */
+char SCA_RandomActuator::SetProperty_doc[] =
+"setProperty(name)\n"
+"\t- name: string\n"
+"\tSet the property to which the random value is assigned. If the \n"
+"\tgenerator and property types do not match, the assignment is ignored.\n";
+PyObject* SCA_RandomActuator::PySetProperty(PyObject* self, PyObject* args, PyObject* kwds) {
+ char *nameArg;
+ if (!PyArg_ParseTuple(args, "s", &nameArg)) {
+ return NULL;
+ }
+
+ CValue* prop = GetParent()->FindIdentifier(nameArg);
+
+ if (prop) {
+ m_propname = nameArg;
+ prop->Release();
+ } else {
+ ; /* not found ... */
+ }
+
+ Py_Return;
+}
+/* 10. getProperty */
+char SCA_RandomActuator::GetProperty_doc[] =
+"getProperty(name)\n"
+"\tReturn the property to which the random value is assigned. If the \n"
+"\tgenerator and property types do not match, the assignment is ignored.\n";
+PyObject* SCA_RandomActuator::PyGetProperty(PyObject* self, PyObject* args, PyObject* kwds) {
+ return PyString_FromString(m_propname);
+}
+
+/* 11. setBoolConst */
+char SCA_RandomActuator::SetBoolConst_doc[] =
+"setBoolConst(value)\n"
+"\t- value: 0 or 1\n"
+"\tSet this generator to produce a constant boolean value.\n";
+PyObject* SCA_RandomActuator::PySetBoolConst(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ int paraArg;
+ if(!PyArg_ParseTuple(args, "i", &paraArg)) {
+ return NULL;
+ }
+
+ m_distribution = KX_RANDOMACT_BOOL_CONST;
+ if (paraArg == KX_TRUE) {
+ m_parameter1 = 1;
+ }
+
+ Py_Return;
+}
+/* 12. setBoolUniform, */
+char SCA_RandomActuator::SetBoolUniform_doc[] =
+"setBoolUniform()\n"
+"\tSet this generator to produce true and false, each with 50%% chance of occuring\n";
+PyObject* SCA_RandomActuator::PySetBoolUniform(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ /* no args */
+ m_distribution = KX_RANDOMACT_BOOL_UNIFORM;
+ enforceConstraints();
+ Py_Return;
+}
+/* 13. setBoolBernouilli, */
+char SCA_RandomActuator::SetBoolBernouilli_doc[] =
+"setBoolBernouilli(value)\n"
+"\t- value: a float between 0 and 1\n"
+"\tReturn false value * 100%% of the time.\n";
+PyObject* SCA_RandomActuator::PySetBoolBernouilli(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ float paraArg;
+ if(!PyArg_ParseTuple(args, "f", &paraArg)) {
+ return NULL;
+ }
+
+ m_distribution = KX_RANDOMACT_BOOL_CONST;
+ m_parameter1 = paraArg;
+ enforceConstraints();
+ Py_Return;
+}
+/* 14. setIntConst,*/
+char SCA_RandomActuator::SetIntConst_doc[] =
+"setIntConst(value)\n"
+"\t- value: integer\n"
+"\tAlways return value\n";
+PyObject* SCA_RandomActuator::PySetIntConst(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ int paraArg;
+ if(!PyArg_ParseTuple(args, "i", &paraArg)) {
+ return NULL;
+ }
+
+ m_distribution = KX_RANDOMACT_INT_CONST;
+ m_parameter1 = paraArg;
+ enforceConstraints();
+ Py_Return;
+}
+/* 15. setIntUniform,*/
+char SCA_RandomActuator::SetIntUniform_doc[] =
+"setIntUniform(lower_bound, upper_bound)\n"
+"\t- lower_bound: integer\n"
+"\t- upper_bound: integer\n"
+"\tReturn a random integer between lower_bound and\n"
+"\tupper_bound. The boundaries are included.\n";
+PyObject* SCA_RandomActuator::PySetIntUniform(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ int paraArg1, paraArg2;
+ if(!PyArg_ParseTuple(args, "ii", &paraArg1, &paraArg2)) {
+ return NULL;
+ }
+
+ m_distribution = KX_RANDOMACT_INT_UNIFORM;
+ m_parameter1 = paraArg1;
+ m_parameter2 = paraArg2;
+ enforceConstraints();
+ Py_Return;
+}
+/* 16. setIntPoisson, */
+char SCA_RandomActuator::SetIntPoisson_doc[] =
+"setIntPoisson(value)\n"
+"\t- value: float\n"
+"\tReturn a Poisson-distributed number. This performs a series\n"
+"\tof Bernouilli tests with parameter value. It returns the\n"
+"\tnumber of tries needed to achieve succes.\n";
+PyObject* SCA_RandomActuator::PySetIntPoisson(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ float paraArg;
+ if(!PyArg_ParseTuple(args, "f", &paraArg)) {
+ return NULL;
+ }
+
+ m_distribution = KX_RANDOMACT_INT_POISSON;
+ m_parameter1 = paraArg;
+ enforceConstraints();
+ Py_Return;
+}
+/* 17. setFloatConst,*/
+char SCA_RandomActuator::SetFloatConst_doc[] =
+"setFloatConst(value)\n"
+"\t- value: float\n"
+"\tAlways return value\n";
+PyObject* SCA_RandomActuator::PySetFloatConst(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ float paraArg;
+ if(!PyArg_ParseTuple(args, "f", &paraArg)) {
+ return NULL;
+ }
+
+ m_distribution = KX_RANDOMACT_FLOAT_CONST;
+ m_parameter1 = paraArg;
+ enforceConstraints();
+ Py_Return;
+}
+/* 18. setFloatUniform, */
+char SCA_RandomActuator::SetFloatUniform_doc[] =
+"setFloatUniform(lower_bound, upper_bound)\n"
+"\t- lower_bound: float\n"
+"\t- upper_bound: float\n"
+"\tReturn a random integer between lower_bound and\n"
+"\tupper_bound.\n";
+PyObject* SCA_RandomActuator::PySetFloatUniform(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ float paraArg1, paraArg2;
+ if(!PyArg_ParseTuple(args, "ff", &paraArg1, &paraArg2)) {
+ return NULL;
+ }
+
+ m_distribution = KX_RANDOMACT_FLOAT_UNIFORM;
+ m_parameter1 = paraArg1;
+ m_parameter2 = paraArg2;
+ enforceConstraints();
+ Py_Return;
+}
+/* 19. setFloatNormal, */
+char SCA_RandomActuator::SetFloatNormal_doc[] =
+"setFloatNormal(mean, standard_deviation)\n"
+"\t- mean: float\n"
+"\t- standard_deviation: float\n"
+"\tReturn normal-distributed numbers. The average is mean, and the\n"
+"\tdeviation from the mean is characterized by standard_deviation.\n";
+PyObject* SCA_RandomActuator::PySetFloatNormal(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ float paraArg1, paraArg2;
+ if(!PyArg_ParseTuple(args, "ff", &paraArg1, &paraArg2)) {
+ return NULL;
+ }
+
+ m_distribution = KX_RANDOMACT_FLOAT_NORMAL;
+ m_parameter1 = paraArg1;
+ m_parameter2 = paraArg2;
+ enforceConstraints();
+ Py_Return;
+}
+/* 20. setFloatNegativeExponential, */
+char SCA_RandomActuator::SetFloatNegativeExponential_doc[] =
+"setFloatNegativeExponential(half_life)\n"
+"\t- half_life: float\n"
+"\tReturn negative-exponentially distributed numbers. The half-life 'time'\n"
+"\tis characterized by half_life.\n";
+PyObject* SCA_RandomActuator::PySetFloatNegativeExponential(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ float paraArg;
+ if(!PyArg_ParseTuple(args, "f", &paraArg)) {
+ return NULL;
+ }
+
+ m_distribution = KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL;
+ m_parameter1 = paraArg;
+ enforceConstraints();
+ Py_Return;
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_RandomActuator.h b/source/gameengine/GameLogic/SCA_RandomActuator.h
new file mode 100644
index 00000000000..236d41c5154
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_RandomActuator.h
@@ -0,0 +1,144 @@
+/**
+ * Draw a random number, and put it in a property
+ *
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_RANDOMACTUATOR
+#define __KX_RANDOMACTUATOR
+
+#include "SCA_IActuator.h"
+#include "SCA_RandomNumberGenerator.h"
+
+class SCA_RandomActuator : public SCA_IActuator
+{
+ Py_Header;
+ /** Property to assign to */
+ STR_String m_propname;
+
+ /** First parameter. The meaning of the parameters depends on the
+ * distribution */
+ float m_parameter1;
+ /** Second parameter. The meaning of the parameters depends on the
+ * distribution */
+ float m_parameter2;
+
+ /** The base generator */
+ SCA_RandomNumberGenerator *m_base;
+
+ /** just a generic, persistent counter */
+ int m_counter;
+
+ /** cache for the previous draw */
+ long m_previous;
+
+ /** apply constraints for the chosen distribution to the parameters */
+ void enforceConstraints(void);
+
+ public:
+
+ enum KX_RANDOMACT_MODE {
+ KX_RANDOMACT_NODEF,
+ KX_RANDOMACT_BOOL_CONST,
+ KX_RANDOMACT_BOOL_UNIFORM,
+ KX_RANDOMACT_BOOL_BERNOUILLI,
+ KX_RANDOMACT_INT_CONST,
+ KX_RANDOMACT_INT_UNIFORM,
+ KX_RANDOMACT_INT_POISSON,
+ KX_RANDOMACT_FLOAT_CONST,
+ KX_RANDOMACT_FLOAT_UNIFORM,
+ KX_RANDOMACT_FLOAT_NORMAL,
+ KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL,
+ KX_RANDOMACT_MAX
+ };
+ /** distribution type */
+ KX_RANDOMACT_MODE m_distribution;
+
+ SCA_RandomActuator(class SCA_IObject* gameobj,
+ long seed,
+ KX_RANDOMACT_MODE mode,
+ float para1,
+ float para2,
+ const STR_String &propName,
+ PyTypeObject* T=&Type);
+ virtual ~SCA_RandomActuator();
+ virtual bool Update(double curtime,double deltatime);
+
+ virtual CValue* GetReplica();
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(char *attr);
+
+ /* 1. setSeed */
+ KX_PYMETHOD_DOC(SCA_RandomActuator,SetSeed);
+ /* 2. getSeed */
+ KX_PYMETHOD_DOC(SCA_RandomActuator,GetSeed);
+ /* 3. setPara1 -removed- */
+ /* 4. getPara1 */
+ KX_PYMETHOD_DOC(SCA_RandomActuator,GetPara1);
+ /* 5. setPara2 -removed- */
+ /* 6. getPara2 */
+ KX_PYMETHOD_DOC(SCA_RandomActuator,GetPara2);
+ /* 7. setDistribution -removed- */
+ /* 8. getDistribution */
+ KX_PYMETHOD_DOC(SCA_RandomActuator,GetDistribution);
+ /* 9. setProperty */
+ KX_PYMETHOD_DOC(SCA_RandomActuator,SetProperty);
+ /* 10. getProperty */
+ KX_PYMETHOD_DOC(SCA_RandomActuator,GetProperty);
+ /* 11. setBoolConst */
+ KX_PYMETHOD_DOC(SCA_RandomActuator,SetBoolConst);
+ /* 12. setBoolUniform, */
+ KX_PYMETHOD_DOC(SCA_RandomActuator,SetBoolUniform);
+ /* 13. setBoolBernouilli, */
+ KX_PYMETHOD_DOC(SCA_RandomActuator,SetBoolBernouilli);
+ /* 14. setIntConst,*/
+ KX_PYMETHOD_DOC(SCA_RandomActuator,SetIntConst);
+ /* 15. setIntUniform,*/
+ KX_PYMETHOD_DOC(SCA_RandomActuator,SetIntUniform);
+ /* 16. setIntPoisson, */
+ KX_PYMETHOD_DOC(SCA_RandomActuator,SetIntPoisson);
+ /* 17. setFloatConst,*/
+ KX_PYMETHOD_DOC(SCA_RandomActuator,SetFloatConst);
+ /* 18. setFloatUniform, */
+ KX_PYMETHOD_DOC(SCA_RandomActuator,SetFloatUniform);
+ /* 19. setFloatNormal, */
+ KX_PYMETHOD_DOC(SCA_RandomActuator,SetFloatNormal);
+ /* 20. setFloatNegativeExponential, */
+ KX_PYMETHOD_DOC(SCA_RandomActuator,SetFloatNegativeExponential);
+
+}; /* end of class KX_EditObjectActuator : public SCA_PropertyActuator */
+
+#endif
diff --git a/source/gameengine/GameLogic/SCA_RandomEventManager.cpp b/source/gameengine/GameLogic/SCA_RandomEventManager.cpp
new file mode 100644
index 00000000000..12cf78d234a
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_RandomEventManager.cpp
@@ -0,0 +1,64 @@
+/**
+ * Manager for random events
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#include "SCA_RandomEventManager.h"
+#include "SCA_LogicManager.h"
+#include "SCA_ISensor.h"
+#include <vector>
+using namespace std;
+
+#include <iostream>
+#include <stdio.h>
+
+SCA_RandomEventManager::SCA_RandomEventManager(class SCA_LogicManager* logicmgr)
+ : m_logicmgr(logicmgr),
+ SCA_EventManager(RANDOM_EVENTMGR)
+{
+}
+
+
+void SCA_RandomEventManager::NextFrame(double curtime,double deltatime)
+{
+ for (vector<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++)
+ {
+ SCA_ISensor *sensor = *i;
+ sensor->Activate(m_logicmgr, NULL);
+ }
+}
+
+
+
+void SCA_RandomEventManager::RegisterSensor(SCA_ISensor* sensor)
+{
+ m_sensors.push_back(sensor);
+};
diff --git a/source/gameengine/GameLogic/SCA_RandomEventManager.h b/source/gameengine/GameLogic/SCA_RandomEventManager.h
new file mode 100644
index 00000000000..1014bddcd82
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_RandomEventManager.h
@@ -0,0 +1,53 @@
+/**
+ * Manager for random events
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_RANDOMEVENTMGR
+#define __KX_RANDOMEVENTMGR
+
+#include "SCA_EventManager.h"
+#include <vector>
+
+using namespace std;
+
+class SCA_RandomEventManager : public SCA_EventManager
+{
+ class SCA_LogicManager* m_logicmgr;
+
+public:
+ SCA_RandomEventManager(class SCA_LogicManager* logicmgr);
+
+ virtual void NextFrame(double curtime,double deltatime);
+ virtual void RegisterSensor(SCA_ISensor* sensor);
+};
+#endif //__KX_RANDOMEVENTMGR
diff --git a/source/gameengine/GameLogic/SCA_RandomNumberGenerator.cpp b/source/gameengine/GameLogic/SCA_RandomNumberGenerator.cpp
new file mode 100644
index 00000000000..7faa76fd01d
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_RandomNumberGenerator.cpp
@@ -0,0 +1,125 @@
+/**
+ * Generate random numbers that can be used by other components. We
+ * convert to different types/distributions elsewhere. This just
+ * delivers a clean, random bitvector.
+ *
+ * $Id$
+ */
+
+/* A C-program for MT19937: Real number version */
+/* genrand() generates one pseudorandom real number (double) */
+/* which is uniformly distributed on [0,1]-interval, for each */
+/* call. sgenrand(seed) set initial values to the working area */
+/* of 624 words. Before genrand(), sgenrand(seed) must be */
+/* called once. (seed is any 32-bit integer except for 0). */
+/* Integer generator is obtained by modifying two lines. */
+/* Coded by Takuji Nishimura, considering the suggestions by */
+/* Topher Cooper and Marc Rieffel in July-Aug. 1997. */
+
+/* This library is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU Library General Public */
+/* License as published by the Free Software Foundation; either */
+/* version 2 of the License, or (at your option) any later */
+/* version. */
+/* This library is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */
+/* See the GNU Library General Public License for more details. */
+/* You should have received a copy of the GNU Library General */
+/* Public License along with this library; if not, write to the */
+/* Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA */
+/* 02111-1307 USA */
+
+/* Copyright (C) 1997 Makoto Matsumoto and Takuji Nishimura. */
+/* When you use this, send an email to: matumoto@math.keio.ac.jp */
+/* with an appropriate reference to your work. */
+
+#include <limits.h>
+#include "SCA_RandomNumberGenerator.h"
+
+/* Period parameters */
+#define N 624
+#define M 397
+#define MATRIX_A 0x9908b0df /* constant vector a */
+#define UPPER_MASK 0x80000000 /* most significant w-r bits */
+#define LOWER_MASK 0x7fffffff /* least significant r bits */
+
+/* Tempering parameters */
+#define TEMPERING_MASK_B 0x9d2c5680
+#define TEMPERING_MASK_C 0xefc60000
+#define TEMPERING_SHIFT_U(y) (y >> 11)
+#define TEMPERING_SHIFT_S(y) (y << 7)
+#define TEMPERING_SHIFT_T(y) (y << 15)
+#define TEMPERING_SHIFT_L(y) (y >> 18)
+
+SCA_RandomNumberGenerator::SCA_RandomNumberGenerator(long seed) {
+ int mti = N + 1;
+ m_seed = seed;
+ SetStartVector();
+}
+
+SCA_RandomNumberGenerator::~SCA_RandomNumberGenerator() {
+ /* intentionally empty */
+}
+
+void SCA_RandomNumberGenerator::SetStartVector(void) {
+ /* setting initial seeds to mt[N] using */
+ /* the generator Line 25 of Table 1 in */
+ /* [KNUTH 1981, The Art of Computer Programming */
+ /* Vol. 2 (2nd Ed.), pp102] */
+ mt[0] = m_seed & 0xffffffff;
+ for (mti = 1; mti < N; mti++)
+ mt[mti] = (69069 * mt[mti-1]) & 0xffffffff;
+}
+
+long SCA_RandomNumberGenerator::GetSeed() { return m_seed; }
+void SCA_RandomNumberGenerator::SetSeed(long newseed)
+{
+ m_seed = newseed;
+ SetStartVector();
+}
+
+/**
+ * This is the important part: copied verbatim :)
+ */
+unsigned long SCA_RandomNumberGenerator::Draw() {
+ static unsigned long mag01[2] = { 0x0, MATRIX_A };
+ /* mag01[x] = x * MATRIX_A for x=0,1 */
+
+ unsigned long y;
+
+ if (mti >= N) { /* generate N words at one time */
+ int kk;
+
+ /* I set this in the constructor, so it is always satisfied ! */
+// if (mti == N+1) /* if sgenrand() has not been called, */
+// GEN_srand(4357); /* a default initial seed is used */
+
+ for (kk = 0; kk < N - M; kk++) {
+ y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
+ mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1];
+ }
+ for (; kk < N-1; kk++) {
+ y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
+ mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1];
+ }
+ y = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
+ mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1];
+
+ mti = 0;
+ }
+
+ y = mt[mti++];
+ y ^= TEMPERING_SHIFT_U(y);
+ y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B;
+ y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C;
+ y ^= TEMPERING_SHIFT_L(y);
+
+ return y;
+}
+
+float SCA_RandomNumberGenerator::DrawFloat() {
+ return ( (float) Draw()/ (unsigned long) 0xffffffff );
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_RandomNumberGenerator.h b/source/gameengine/GameLogic/SCA_RandomNumberGenerator.h
new file mode 100644
index 00000000000..c6cd52dd3db
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_RandomNumberGenerator.h
@@ -0,0 +1,65 @@
+/**
+ * Generate random numbers that can be used by other components. Each
+ * generator needs its own generator, so that the seed can be set
+ * on a per-generator basis.
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_RANDOMNUMBERGENERATOR
+#define __KX_RANDOMNUMBERGENERATOR
+
+
+class SCA_RandomNumberGenerator {
+
+ /** base seed */
+ long m_seed;
+
+ /* A bit silly.. The N parameter is a define in the .cpp file */
+ /** the array for the state vector */
+ /* unsigned long mt[N]; */
+ unsigned long mt[624];
+
+ /** mti==N+1 means mt[KX_MT_VectorLenght] is not initialized */
+ int mti; /* initialised in the cpp file */
+
+ /** Calculate a start vector */
+ void SetStartVector(void);
+ public:
+ SCA_RandomNumberGenerator(long seed);
+ ~SCA_RandomNumberGenerator();
+ unsigned long Draw();
+ float DrawFloat();
+ long GetSeed();
+ void SetSeed(long newseed);
+};
+
+#endif /* __KX_RANDOMNUMBERGENERATOR */
diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.cpp b/source/gameengine/GameLogic/SCA_RandomSensor.cpp
new file mode 100644
index 00000000000..7f3f2f93315
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_RandomSensor.cpp
@@ -0,0 +1,191 @@
+/**
+ * Generate random pulses
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "SCA_RandomSensor.h"
+#include "SCA_EventManager.h"
+#include "SCA_RandomEventManager.h"
+#include "SCA_LogicManager.h"
+#include "ConstExpr.h"
+#include <iostream>
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_RandomSensor::SCA_RandomSensor(SCA_EventManager* eventmgr,
+ SCA_IObject* gameobj,
+ int startseed,
+ PyTypeObject* T)
+ : SCA_ISensor(gameobj,eventmgr, T)
+{
+ m_iteration = 0;
+ m_lastdraw = false;
+
+ m_basegenerator = new SCA_RandomNumberGenerator(startseed);
+ m_currentDraw = m_basegenerator->Draw();
+ RegisterToManager();
+}
+
+
+
+SCA_RandomSensor::~SCA_RandomSensor()
+{
+ /* Nothing to be done here. */
+}
+
+
+
+CValue* SCA_RandomSensor::GetReplica()
+{
+ CValue* replica = new SCA_RandomSensor(*this);
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+bool SCA_RandomSensor::IsPositiveTrigger()
+{
+ return (m_invert !=m_lastdraw);
+}
+
+
+bool SCA_RandomSensor::Evaluate(CValue* event)
+{
+ /* Random generator is the generator from Line 25 of Table 1 in */
+ /* [KNUTH 1981, The Art of Computer Programming Vol. 2 */
+ /* (2nd Ed.), pp102] */
+ /* It's a very simple max. length sequence generator. We can */
+ /* draw 32 bool values before having to generate the next */
+ /* sequence value. There are some theorems that will tell you */
+ /* this is a reasonable way of generating bools. Check Knuth. */
+ /* Furthermore, we only draw each <delay>-eth frame. */
+
+ bool drawResult = false;
+
+ if (m_iteration > 31) {
+ m_currentDraw = m_basegenerator->Draw();
+ drawResult = (m_currentDraw & 0x1) == 0;
+ m_iteration = 1;
+ } else {
+ drawResult = ((m_currentDraw >> m_iteration) & 0x1) == 0;
+ m_iteration++;
+ }
+
+ /* now pass this result to some controller */
+ m_lastdraw = drawResult;
+ return drawResult;
+}
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_RandomSensor::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_RandomSensor",
+ sizeof(SCA_RandomSensor),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_RandomSensor::Parents[] = {
+ &SCA_RandomSensor::Type,
+ &SCA_ISensor::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef SCA_RandomSensor::Methods[] = {
+ {"setSeed", (PyCFunction) SCA_RandomSensor::sPySetSeed, METH_VARARGS, SetSeed_doc},
+ {"getSeed", (PyCFunction) SCA_RandomSensor::sPyGetSeed, METH_VARARGS, GetSeed_doc},
+ {"getLastDraw", (PyCFunction) SCA_RandomSensor::sPyGetLastDraw, METH_VARARGS, GetLastDraw_doc},
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* SCA_RandomSensor::_getattr(char* attr) {
+ _getattr_up(SCA_ISensor);
+}
+
+/* 1. setSeed */
+char SCA_RandomSensor::SetSeed_doc[] =
+"setSeed(seed)\n"
+"\t- seed: integer\n"
+"\tSet the initial seed of the generator. Equal seeds produce\n"
+"\tequal series. If the seed is 0, the generator will produce\n"
+"\tthe same value on every call.\n";
+PyObject* SCA_RandomSensor::PySetSeed(PyObject* self, PyObject* args, PyObject* kwds) {
+ long seedArg;
+ if(!PyArg_ParseTuple(args, "i", &seedArg)) {
+ return NULL;
+ }
+
+ m_basegenerator->SetSeed(seedArg);
+
+ Py_Return;
+}
+
+/* 2. getSeed */
+char SCA_RandomSensor::GetSeed_doc[] =
+"getSeed()\n"
+"\tReturns the initial seed of the generator. Equal seeds produce\n"
+"\tequal series.\n";
+PyObject* SCA_RandomSensor::PyGetSeed(PyObject* self, PyObject* args, PyObject* kwds) {
+ return PyInt_FromLong(m_basegenerator->GetSeed());
+}
+
+/* 3. getLastDraw */
+char SCA_RandomSensor::GetLastDraw_doc[] =
+"getLastDraw()\n"
+"\tReturn the last value that was drawn.\n";
+PyObject* SCA_RandomSensor::PyGetLastDraw(PyObject* self, PyObject* args, PyObject* kwds) {
+ return PyInt_FromLong(m_lastdraw);
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.h b/source/gameengine/GameLogic/SCA_RandomSensor.h
new file mode 100644
index 00000000000..6a77f289be5
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_RandomSensor.h
@@ -0,0 +1,75 @@
+/**
+ * Generate random pulses
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_RANDOMSENSOR
+#define __KX_RANDOMSENSOR
+
+#include "SCA_ISensor.h"
+#include "BoolValue.h"
+#include "SCA_RandomNumberGenerator.h"
+
+class SCA_RandomSensor : public SCA_ISensor
+{
+ Py_Header;
+
+ unsigned int m_currentDraw;
+ int m_iteration;
+ SCA_RandomNumberGenerator *m_basegenerator;
+ bool m_lastdraw;
+public:
+ SCA_RandomSensor(class SCA_EventManager* rndmgr,
+ SCA_IObject* gameobj,
+ int startseed,
+ PyTypeObject* T=&Type);
+ virtual ~SCA_RandomSensor();
+ virtual CValue* GetReplica();
+ virtual bool Evaluate(CValue* event);
+ virtual bool IsPositiveTrigger();
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(char *attr);
+
+ /* 1. setSeed */
+ KX_PYMETHOD_DOC(SCA_RandomSensor,SetSeed);
+ /* 2. getSeed */
+ KX_PYMETHOD_DOC(SCA_RandomSensor,GetSeed);
+ /* 3. getSeed */
+ KX_PYMETHOD_DOC(SCA_RandomSensor,GetLastDraw);
+
+};
+
+#endif //__KX_RANDOMSENSOR
diff --git a/source/gameengine/GameLogic/SCA_TimeEventManager.cpp b/source/gameengine/GameLogic/SCA_TimeEventManager.cpp
new file mode 100644
index 00000000000..784afcce298
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_TimeEventManager.cpp
@@ -0,0 +1,110 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifdef WIN32
+
+// This warning tells us about truncation of __long__ stl-generated names.
+// It can occasionally cause DevStudio to have internal compiler warnings.
+#pragma warning( disable : 4786 )
+#endif
+
+#include "SCA_TimeEventManager.h"
+
+#include "SCA_LogicManager.h"
+#include "FloatValue.h"
+
+SCA_TimeEventManager::SCA_TimeEventManager(SCA_LogicManager* logicmgr)
+: SCA_EventManager(TIME_EVENTMGR)
+{
+}
+
+
+
+SCA_TimeEventManager::~SCA_TimeEventManager()
+{
+ for (vector<CValue*>::iterator it = m_timevalues.begin();
+ !(it == m_timevalues.end()); it++)
+ {
+ (*it)->Release();
+ }
+}
+
+
+
+void SCA_TimeEventManager::RegisterSensor(SCA_ISensor* sensor)
+{
+ // not yet
+}
+
+
+
+void SCA_TimeEventManager::NextFrame(double curtime,double deltatime)
+{
+ if (m_timevalues.size() > 0)
+ {
+ CFloatValue* floatval = new CFloatValue(curtime);
+
+ // update sensors, but ... need deltatime !
+ for (vector<CValue*>::iterator it = m_timevalues.begin();
+ !(it == m_timevalues.end()); it++)
+ {
+ float newtime = (*it)->GetNumber() + deltatime;
+ floatval->SetFloat(newtime);
+ (*it)->SetValue(floatval);
+ }
+
+ floatval->Release();
+ }
+}
+
+
+
+void SCA_TimeEventManager::AddTimeProperty(CValue* timeval)
+{
+ timeval->AddRef();
+ m_timevalues.push_back(timeval);
+}
+
+
+
+void SCA_TimeEventManager::RemoveTimeProperty(CValue* timeval)
+{
+ for (vector<CValue*>::iterator it = m_timevalues.begin();
+ !(it == m_timevalues.end()); it++)
+ {
+ if ((*it) == timeval)
+ {
+ this->m_timevalues.erase(it);
+ timeval->Release();
+ break;
+ }
+ }
+}
diff --git a/source/gameengine/GameLogic/SCA_TimeEventManager.h b/source/gameengine/GameLogic/SCA_TimeEventManager.h
new file mode 100644
index 00000000000..880659e1a87
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_TimeEventManager.h
@@ -0,0 +1,54 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef __KX_TIMEEVENTMANAGER
+#define __KX_TIMEEVENTMANAGER
+
+#include "SCA_EventManager.h"
+#include "Value.h"
+#include <vector>
+
+using namespace std;
+
+class SCA_TimeEventManager : public SCA_EventManager
+{
+ vector<CValue*> m_timevalues; // values that need their time updated regularly
+
+public:
+ SCA_TimeEventManager(class SCA_LogicManager* logicmgr);
+ virtual ~SCA_TimeEventManager();
+
+ virtual void NextFrame(double curtime,double deltatime);
+ virtual void RegisterSensor(class SCA_ISensor* sensor);
+ void AddTimeProperty(CValue* timeval);
+ void RemoveTimeProperty(CValue* timeval);
+};
+#endif //__KX_TIMEEVENTMANAGER
diff --git a/source/gameengine/GamePlayer/Makefile b/source/gameengine/GamePlayer/Makefile
new file mode 100644
index 00000000000..49f47a4d4a0
--- /dev/null
+++ b/source/gameengine/GamePlayer/Makefile
@@ -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 *****
+#
+# Bounces make to subdirectories.
+
+include nan_definitions.mk
+
+SOURCEDIR = source/gameengine/GamePlayer
+DIR = $(OCGDIR)/gameengine/GamePlayer
+DIRS = common ghost
+
+ifeq ($(OS),$(findstring $(OS), "freebsd irix windows"))
+ DIRS += netscape
+endif
+
+ifeq ($(OS),$(findstring $(OS), "linux"))
+ ifeq ($(CPU),i386)
+ DIRS += netscape
+ endif
+endif
+
+ifeq ($(OS),$(findstring $(OS), "solaris"))
+ ifeq ($(CPU),sparc)
+ DIRS += netscape
+ endif
+endif
+
+include nan_subdirs.mk
diff --git a/source/gameengine/GamePlayer/common/GPC_Canvas.cpp b/source/gameengine/GamePlayer/common/GPC_Canvas.cpp
new file mode 100644
index 00000000000..4e59863f510
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/GPC_Canvas.cpp
@@ -0,0 +1,371 @@
+/**
+ * $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
+#include <windows.h>
+#endif
+
+#include "RAS_IPolygonMaterial.h"
+#include "GPC_Canvas.h"
+
+GPC_Canvas::TBannerId GPC_Canvas::s_bannerId = 0;
+
+
+GPC_Canvas::GPC_Canvas(
+ int width,
+ int height
+) :
+ m_width(width),
+ m_height(height),
+ m_bannersEnabled(false)
+{
+}
+
+
+GPC_Canvas::~GPC_Canvas()
+{
+ DisposeAllBanners();
+}
+
+
+// void GPC_Canvas::InitPostRenderingContext(void)
+// {
+// glViewport(0, 0, m_width, m_height);
+// glMatrixMode(GL_PROJECTION);
+// glLoadIdentity();
+
+// glOrtho(-2.0, 2.0, -2.0, 2.0, -20.0, 20.0);
+
+// glMatrixMode(GL_MODELVIEW);
+// glLoadIdentity();
+
+// glEnable(GL_DEPTH_TEST);
+
+// glDepthFunc(GL_LESS);
+
+// glShadeModel(GL_SMOOTH);
+// }
+
+void GPC_Canvas::Resize(int width, int height)
+{
+ m_width = width;
+ m_height = height;
+}
+
+void GPC_Canvas::EndFrame()
+{
+ if (m_bannersEnabled)
+ DrawAllBanners();
+}
+
+
+void GPC_Canvas::ClearColor(float r, float g, float b, float a)
+{
+ ::glClearColor(r,g,b,a);
+}
+
+void GPC_Canvas::SetViewPort(int x1, int y1, int x2, int y2)
+{
+ /* XXX, nasty, this needs to go somewhere else,
+ * but where... definitly need to clean up this
+ * whole canvas/rendertools mess.
+ */
+ glEnable(GL_SCISSOR_TEST);
+
+ glViewport(x1,y1,x2-x1 + 1,y2-y1 + 1);
+ glScissor(x1,y1,x2-x1 + 1,y2-y1 + 1);
+};
+
+
+void GPC_Canvas::ClearBuffer(
+ int type
+){
+
+ int ogltype = 0;
+ if (type & RAS_ICanvas::COLOR_BUFFER )
+ ogltype |= GL_COLOR_BUFFER_BIT;
+ if (type & RAS_ICanvas::DEPTH_BUFFER )
+ ogltype |= GL_DEPTH_BUFFER_BIT;
+
+ ::glClear(ogltype);
+
+}
+
+
+GPC_Canvas::TBannerId GPC_Canvas::AddBanner(
+ unsigned int bannerWidth, unsigned int bannerHeight,
+ unsigned int imageWidth, unsigned int imageHeight,
+ unsigned char* imageData,
+ TBannerAlignment alignment, bool enabled)
+{
+ TBannerData banner;
+
+ banner.alignment = alignment;
+ banner.enabled = enabled;
+ banner.displayWidth = bannerWidth;
+ banner.displayHeight = bannerHeight;
+ banner.imageWidth = imageWidth;
+ banner.imageHeight = imageHeight;
+ unsigned int bannerDataSize = imageWidth*imageHeight*4;
+ banner.imageData = new unsigned char [bannerDataSize];
+ ::memcpy(banner.imageData, imageData, bannerDataSize);
+ banner.textureName = 0;
+
+ m_banners.insert(TBannerMap::value_type(++s_bannerId, banner));
+ return s_bannerId;
+}
+
+
+void GPC_Canvas::DisposeBanner(TBannerId id)
+{
+ TBannerMap::iterator it = m_banners.find(id);
+ if (it != m_banners.end()) {
+ DisposeBanner(it->second);
+ m_banners.erase(it);
+ }
+}
+
+void GPC_Canvas::DisposeAllBanners()
+{
+ TBannerMap::iterator it = m_banners.begin();
+ while (it != m_banners.end()) {
+ DisposeBanner(it->second);
+ it++;
+ }
+}
+
+void GPC_Canvas::SetBannerEnabled(TBannerId id, bool enabled)
+{
+ TBannerMap::iterator it = m_banners.find(id);
+ if (it != m_banners.end()) {
+ it->second.enabled = enabled;
+ }
+}
+
+
+void GPC_Canvas::SetBannerDisplayEnabled(bool enabled)
+{
+ m_bannersEnabled = enabled;
+}
+
+
+void GPC_Canvas::DisposeBanner(TBannerData& banner)
+{
+ if (banner.imageData) {
+ delete [] banner.imageData;
+ banner.imageData = 0;
+ }
+ if (banner.textureName) {
+ ::glDeleteTextures(1, (GLuint*)&banner.textureName);
+ }
+}
+
+void GPC_Canvas::DrawAllBanners(void)
+{
+ if(!m_bannersEnabled || (m_banners.size() < 1))
+ return;
+
+ // Save the old rendering parameters.
+
+ CanvasRenderState render_state;
+ PushRenderState(render_state);
+
+ // Set up everything for banner display.
+
+ // Set up OpenGL matrices
+ SetOrthoProjection();
+ // Activate OpenGL settings needed for display of the texture
+ ::glDisable(GL_LIGHTING);
+ ::glDisable(GL_DEPTH_TEST);
+ ::glDisable(GL_FOG);
+ ::glEnable(GL_TEXTURE_2D);
+ ::glEnable(GL_BLEND);
+ ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ TBannerMap::iterator it = m_banners.begin();
+ while (it != m_banners.end()) {
+ if (it->second.enabled) {
+ DrawBanner(it->second);
+ }
+ it++;
+ }
+
+ PopRenderState(render_state);
+}
+
+
+void GPC_Canvas::DrawBanner(TBannerData& banner)
+{
+ if(!banner.enabled)
+ return;
+
+ // Set up coordinates
+ int coords[4][2];
+ if (banner.alignment == alignTopLeft) {
+ // Upper left
+ coords[0][0] = 0;
+ coords[0][1] = ((int)m_height)-banner.displayHeight;
+ coords[1][0] = banner.displayWidth;
+ coords[1][1] = ((int)m_height)-banner.displayHeight;
+ coords[2][0] = banner.displayWidth;
+ coords[2][1] = ((int)m_height);
+ coords[3][0] = 0;
+ coords[3][1] = ((int)m_height);
+ }
+ else {
+ // Lower right
+ coords[0][0] = (int)m_width - banner.displayWidth;
+ coords[0][1] = 0;
+ coords[1][0] = m_width;
+ coords[1][1] = 0;
+ coords[2][0] = m_width;
+ coords[2][1] = banner.displayHeight;
+ coords[3][0] = (int)m_width - banner.displayWidth;
+ coords[3][1] = banner.displayHeight;
+ }
+ // Set up uvs
+ int uvs[4][2] = {
+ { 0, 1},
+ { 1, 1},
+ { 1, 0},
+ { 0, 0}
+ };
+
+ if (!banner.textureName) {
+ ::glGenTextures(1, (GLuint*)&banner.textureName);
+ ::glBindTexture(GL_TEXTURE_2D, banner.textureName);
+ ::glTexImage2D(
+ GL_TEXTURE_2D, // target
+ 0, // level
+ 4, // components
+ banner.imageWidth, // width
+ banner.displayHeight, // height
+ 0, // border
+ GL_RGBA, // format
+ GL_UNSIGNED_BYTE, // type
+ banner.imageData); // image data
+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ }
+ else {
+ ::glBindTexture(GL_TEXTURE_2D, banner.textureName);
+ }
+
+ // Draw the rectangle with the texture on it
+ ::glBegin(GL_QUADS);
+ ::glColor4f(1.f, 1.f, 1.f, 1.f);
+ ::glTexCoord2iv((GLint*)uvs[0]);
+ ::glVertex2iv((GLint*)coords[0]);
+ ::glTexCoord2iv((GLint*)uvs[1]);
+ ::glVertex2iv((GLint*)coords[1]);
+ ::glTexCoord2iv((GLint*)uvs[2]);
+ ::glVertex2iv((GLint*)coords[2]);
+ ::glTexCoord2iv((GLint*)uvs[3]);
+ ::glVertex2iv((GLint*)coords[3]);
+ ::glEnd();
+}
+
+ void
+GPC_Canvas::
+PushRenderState(
+ CanvasRenderState & render_state
+){
+#if 0
+
+ ::glMatrixMode(GL_PROJECTION);
+ ::glPushMatrix();
+ ::glMatrixMode(GL_MODELVIEW);
+ ::glPushMatrix();
+ ::glMatrixMode(GL_TEXTURE);
+ ::glPushMatrix();
+ // Save old OpenGL settings
+ ::glGetIntegerv(GL_LIGHTING, (GLint*)&(render_state.oldLighting));
+ ::glGetIntegerv(GL_DEPTH_TEST, (GLint*)&(render_state.oldDepthTest));
+ ::glGetIntegerv(GL_FOG, (GLint*)&(render_state.oldFog));
+ ::glGetIntegerv(GL_TEXTURE_2D, (GLint*)&(render_state.oldTexture2D));
+ ::glGetIntegerv(GL_BLEND, (GLint*)&(render_state.oldBlend));
+ ::glGetIntegerv(GL_BLEND_SRC, (GLint*)&(render_state.oldBlendSrc));
+ ::glGetIntegerv(GL_BLEND_DST, (GLint*)&(render_state.oldBlendDst));
+ ::glGetFloatv(GL_CURRENT_COLOR, render_state.oldColor);
+ ::glGetIntegerv(GL_DEPTH_WRITEMASK,(GLint*)&(render_state.oldWriteMask));
+#else
+
+ glPushAttrib(GL_ALL_ATTRIB_BITS);
+
+#endif
+}
+
+ void
+GPC_Canvas::
+PopRenderState(
+ const CanvasRenderState & render_state
+){
+#if 0
+ // Restore OpenGL settings
+ render_state.oldLighting ? ::glEnable(GL_LIGHTING) : glDisable(GL_LIGHTING);
+ render_state.oldDepthTest ? ::glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
+ render_state.oldFog ? ::glEnable(GL_FOG) : ::glDisable(GL_FOG);
+ render_state.oldTexture2D ? ::glEnable(GL_TEXTURE_2D) : glDisable(GL_TEXTURE_2D);
+ render_state.oldBlend ? glEnable(GL_BLEND) : ::glDisable(GL_BLEND);
+ ::glBlendFunc((GLenum)render_state.oldBlendSrc, (GLenum)render_state.oldBlendDst);
+ render_state.oldWriteMask ? ::glEnable(GL_DEPTH_WRITEMASK) : glDisable(GL_DEPTH_WRITEMASK);
+
+ ::glColor4fv(render_state.oldColor);
+ // Restore OpenGL matrices
+ ::glMatrixMode(GL_TEXTURE);
+ ::glPopMatrix();
+ ::glMatrixMode(GL_PROJECTION);
+ ::glPopMatrix();
+ ::glMatrixMode(GL_MODELVIEW);
+ ::glPopMatrix();
+
+#else
+
+ glPopAttrib();
+#endif
+}
+
+ void
+GPC_Canvas::
+SetOrthoProjection(
+){
+ // Set up OpenGL matrices
+ ::glViewport(0, 0, m_width, m_height);
+ ::glScissor(0, 0, m_width, m_height);
+ ::glMatrixMode(GL_PROJECTION);
+ ::glLoadIdentity();
+ ::glOrtho(0, m_width, 0, m_height, -1, 1);
+ ::glMatrixMode(GL_MODELVIEW);
+ ::glLoadIdentity();
+ ::glMatrixMode(GL_TEXTURE);
+ ::glLoadIdentity();
+}
diff --git a/source/gameengine/GamePlayer/common/GPC_Canvas.h b/source/gameengine/GamePlayer/common/GPC_Canvas.h
new file mode 100644
index 00000000000..51061301b55
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/GPC_Canvas.h
@@ -0,0 +1,275 @@
+/**
+ * $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 _GPC_CANVAS_H_
+#define _GPC_CANVAS_H_
+
+#include "RAS_ICanvas.h"
+#include "RAS_Rect.h"
+
+#if defined(WIN32) || defined(__APPLE__)
+ #ifdef WIN32
+ #pragma warning (disable:4786) // suppress stl-MSVC debug info warning
+ #include <windows.h>
+ #include <GL/gl.h>
+ #else // WIN32
+ // __APPLE__ is defined
+ #include <AGL/gl.h>
+ #endif // WIN32
+#else //defined(WIN32) || defined(__APPLE__)
+ #include <GL/gl.h>
+#endif //defined(WIN32) || defined(__APPLE__)
+
+#include <map>
+
+
+class GPC_Canvas : public RAS_ICanvas
+{
+public:
+ /**
+ * Used to position banners in the canvas.
+ */
+ typedef enum {
+ alignTopLeft,
+ alignBottomRight
+ } TBannerAlignment;
+
+ typedef int TBannerId;
+
+protected:
+ /**
+ * Used to store info for banners drawn on top of the canvas.
+ */
+ typedef struct {
+ /** Where the banner will be displayed. */
+ TBannerAlignment alignment;
+ /** Banner display enabled. */
+ bool enabled;
+ /** Banner display width. */
+ unsigned int displayWidth;
+ /** Banner display height. */
+ unsigned int displayHeight;
+ /** Banner image width. */
+ unsigned int imageWidth;
+ /** Banner image height. */
+ unsigned int imageHeight;
+ /** Banner image data. */
+ unsigned char* imageData;
+ /** Banner OpenGL texture name. */
+ unsigned int textureName;
+ } TBannerData;
+ typedef std::map<TBannerId, TBannerData> TBannerMap;
+
+ /** Width of the context. */
+ int m_width;
+ /** Height of the context. */
+ int m_height;
+ /** Rect that defines the area used for rendering,
+ relative to the context */
+ RAS_Rect m_displayarea;
+
+ /** Storage for the banners to display. */
+ TBannerMap m_banners;
+ /** State of banner display. */
+ bool m_bannersEnabled;
+
+public:
+
+ GPC_Canvas(int width, int height);
+
+ virtual ~GPC_Canvas();
+
+ void Resize(int width, int height);
+
+
+ /**
+ * @section Methods inherited from abstract base class RAS_ICanvas.
+ */
+
+ int
+ GetWidth(
+ ) const {
+ return m_width;
+ }
+
+ int
+ GetHeight(
+ ) const {
+ return m_height;
+ }
+
+ const
+ RAS_Rect &
+ GetDisplayArea(
+ ) const {
+ return m_displayarea;
+ };
+
+ RAS_Rect &
+ GetDisplayArea(
+ ) {
+ return m_displayarea;
+ };
+
+ void
+ BeginFrame(
+ ) {};
+
+ /**
+ * Draws overlay banners and progress bars.
+ */
+ void
+ EndFrame(
+ );
+
+ void SetViewPort(int x1, int y1, int x2, int y2);
+
+ void ClearColor(float r, float g, float b, float a);
+
+ /**
+ * @section Methods inherited from abstract base class RAS_ICanvas.
+ * Semantics are not yet honoured.
+ */
+
+ void SetMouseState(RAS_MouseState mousestate)
+ {
+ // not yet
+ }
+
+ void SetMousePosition(int x, int y)
+ {
+ // not yet
+ }
+
+ void MakeScreenShot(const char* filename)
+ {
+ // not yet
+ }
+
+ void ClearBuffer(int type);
+
+ /**
+ * @section Services provided by this class.
+ */
+
+ /**
+ * Enables display of a banner.
+ * The image data is copied inside.
+ * @param bannerWidth Display width of the banner.
+ * @param bannerHeight Display height of the banner.
+ * @param imageWidth Width of the banner image in pixels.
+ * @param imageHeight Height of the banner image in pixels.
+ * @param imageData Pointer to the pixels of the image to display.
+ * @param alignement Where the banner will be positioned on the canvas.
+ * @param enabled Whether the banner will be displayed intiallly.
+ * @return A banner id.
+ */
+ TBannerId AddBanner(
+ unsigned int bannerWidth, unsigned int bannerHeight,
+ unsigned int imageWidth, unsigned int imageHeight,
+ unsigned char* imageData, TBannerAlignment alignment = alignTopLeft,
+ bool enabled = true);
+
+ /**
+ * Disposes a banner.
+ * @param id Bannner to be disposed.
+ */
+ void DisposeBanner(TBannerId id);
+
+ /**
+ * Disposes all the banners.
+ */
+ void DisposeAllBanners();
+
+ /**
+ * Enables or disables display of a banner.
+ * @param id Banner id of the banner to be enabled/disabled.
+ * @param enabled New state of the banner.
+ */
+ void SetBannerEnabled(TBannerId id, bool enabled = true);
+
+ /**
+ * Enables or disables display of all banners.
+ * @param enabled New state of the banners.
+ */
+ void SetBannerDisplayEnabled(bool enabled = true);
+
+protected:
+ /**
+ * Disposes a banner.
+ * @param it Bannner to be disposed.
+ */
+ void DisposeBanner(TBannerData& banner);
+
+ /**
+ * Draws all the banners enabled.
+ */
+ void DrawAllBanners(void);
+
+ /**
+ * Draws a banner.
+ */
+ void DrawBanner(TBannerData& banner);
+
+ struct CanvasRenderState {
+ int oldLighting;
+ int oldDepthTest;
+ int oldFog;
+ int oldTexture2D;
+ int oldBlend;
+ int oldBlendSrc;
+ int oldBlendDst;
+ float oldColor[4];
+ int oldWriteMask;
+ };
+
+ void
+ PushRenderState(
+ CanvasRenderState & render_state
+ );
+ void
+ PopRenderState(
+ const CanvasRenderState & render_state
+ );
+
+ /**
+ * Set up an orthogonal viewing,model and texture matrix
+ * for banners and progress bars.
+ */
+ void
+ SetOrthoProjection(
+ );
+
+ static TBannerId s_bannerId;
+};
+
+#endif // _GPC_CANVAS_H_
diff --git a/source/gameengine/GamePlayer/common/GPC_Engine.cpp b/source/gameengine/GamePlayer/common/GPC_Engine.cpp
new file mode 100644
index 00000000000..8c54362e17a
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/GPC_Engine.cpp
@@ -0,0 +1,337 @@
+/**
+ * $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
+ #pragma warning (disable:4786) // suppress stl-MSVC debug info warning
+#endif // WIN32
+
+#include <iostream>
+
+#include "BKE_blender.h" // initglobals()
+#include "BKE_global.h" // Global G
+#include "DNA_scene_types.h"
+#include "DNA_camera_types.h" // Camera
+#include "DNA_object_types.h" // Object
+
+#include "BLO_readfile.h"
+#include "BLI_blenlib.h"
+
+// include files needed by "KX_BlenderSceneConverter.h"
+
+#include "GEN_Map.h"
+#include "SCA_IActuator.h"
+#include "RAS_MeshObject.h"
+
+#include "KX_BlenderSceneConverter.h"
+#include "KX_KetsjiEngine.h"
+#include "NG_LoopBackNetworkDeviceInterface.h"
+
+#include "RAS_IRenderTools.h"
+#include "SND_DeviceManager.h"
+
+#include "GPC_Engine.h"
+#include "GPC_KeyboardDevice.h"
+#include "GPC_MouseDevice.h"
+#include "GPC_RawImage.h"
+#include "GPC_RawLoadDotBlendArray.h"
+
+
+
+GPC_Engine::GPC_Engine(char *customLoadingAnimationURL,
+ int foregroundColor, int backgroundColor, int frameRate) :
+ m_initialized(false), m_running(false), m_loading(false),
+ m_customLoadingAnimation(false), m_previousProgress(0.0),
+ m_system(NULL), m_keyboarddev(NULL),
+ m_mousedev(NULL), m_canvas(NULL), m_rendertools(NULL),
+ m_portal(NULL), m_sceneconverter(NULL), m_networkdev(NULL),
+ m_audiodevice(NULL), m_curarea(NULL),
+ m_customLoadingAnimationURL(NULL),
+ m_foregroundColor(foregroundColor), m_backgroundColor(backgroundColor),
+ m_frameRate(frameRate),
+ m_BlenderLogo(0), m_Blender3DLogo(0)/*, m_NaNLogo(0)*/
+{
+ if(customLoadingAnimationURL[0] != '\0')
+ {
+ m_customLoadingAnimationURL = new char[sizeof(customLoadingAnimationURL)];
+// not yet, need to be implemented first... m_customLoadingAnimation = true;
+ }
+
+ // load the Blender logo into memory
+ m_BlenderLogo = new GPC_RawImage();
+ // blender3d size is 115 x 32 so make resulting texture 128 x 128
+ if(!m_BlenderLogo->Load("BlenderLogo", 128, 128, GPC_RawImage::alignTopLeft, 8, 8))
+ m_BlenderLogo = 0;
+
+ // load the Blender3D logo into memory
+ m_Blender3DLogo = new GPC_RawImage();
+ // blender3d size is 136 x 11 so make resulting texture 256 x 256
+ if(!m_Blender3DLogo->Load("Blender3DLogo", 256, 256, GPC_RawImage::alignBottomRight, 8, 8))
+ m_Blender3DLogo = 0;
+
+#if 0
+ // obsolete logo
+ // load the NaN logo into memory
+ m_NaNLogo = new GPC_RawImage();
+ // blender3d size is 32 x 31 so make resulting texture 64 x 64
+ if(!m_NaNLogo->Load("NaNLogo", 64, 64, GPC_RawImage::alignBottomRight, 8, 8))
+ m_NaNLogo = 0;
+#endif
+}
+
+
+GPC_Engine::~GPC_Engine()
+{
+ // deleting everything in reverse order of creation
+#if 0
+// hmm deleted in Stop() delete m_portal;
+// hmm deleted in Stop() delete m_sceneconverter;
+ delete m_system;
+ delete m_networkdev;
+ delete m_rendertools;
+ delete m_canvas;
+ delete m_mousedev;
+ delete m_keyboarddev;
+// not yet used so be careful and not delete them
+// delete m_WaveCache;
+// delete m_curarea; // for future use, not used yet
+#endif
+ delete m_BlenderLogo;
+ delete m_Blender3DLogo;
+#if 0
+ delete m_NaNLogo;
+#endif
+}
+
+
+bool GPC_Engine::Start(char *filename)
+{
+ BlendReadError error;
+ BlendFileData *bfd= BLO_read_from_file(filename, &error);
+
+ if (!bfd) {
+ // XXX, deal with error here
+ cout << "Unable to load: " << filename << endl;
+ return false;
+ }
+
+ StartKetsji();
+
+ if(bfd->type == BLENFILETYPE_PUB)
+ m_canvas->SetBannerDisplayEnabled(false);
+
+ return true;
+}
+
+
+bool GPC_Engine::Start(unsigned char *blenderDataBuffer,
+ unsigned int blenderDataBufferSize)
+{
+ BlendReadError error;
+ BlendFileData *bfd= BLO_read_from_memory(blenderDataBuffer, blenderDataBufferSize, &error);
+
+ if (!bfd) {
+ // XXX, deal with error here
+ cout << "Unable to load. " << endl;
+ return false;
+ }
+
+ StartKetsji();
+
+ if(bfd->type == BLENFILETYPE_PUB)
+ m_canvas->SetBannerDisplayEnabled(false);
+
+ return true;
+}
+
+
+bool GPC_Engine::StartKetsji(void)
+{
+ STR_String startSceneName = G.scene->id.name + 2;
+/*
+ KX_KetsjiEngine* ketsjieng = new KX_KetsjiEngine(m_system);
+ m_portal = new KetsjiPortal(ketsjieng);
+ m_portal->setSecurity(psl_Highest);
+
+ KX_ISceneConverter *sceneconverter = new KX_BlenderSceneConverter(G.main, ketsjieng);
+
+ m_portal->Enter(
+ startSceneName,
+ sceneconverter,
+ m_canvas,
+ m_rendertools,
+ m_keyboarddev,
+ m_mousedev,
+ m_networkdev,
+ m_audiodevice,
+ m_system);
+
+ m_system->SetMainLoop(m_portal->m_ketsjieng);
+
+ m_running = true;
+ */
+ return true;
+}
+
+
+void GPC_Engine::StartLoadingAnimation()
+{
+ if(m_customLoadingAnimation)
+ {
+ }
+ else
+ {
+ unsigned char *blenderDataBuffer;
+ int blenderDataBufferSize;
+ GetRawLoadingAnimation(&blenderDataBuffer, &blenderDataBufferSize);
+ if(!Start(blenderDataBuffer, blenderDataBufferSize))
+ cout << "something went wrong when starting the engine" << endl;
+ delete blenderDataBuffer; // created with 'new' in GetRawLoadingAnimation()
+ }
+}
+
+
+// will be platform dependant
+float GPC_Engine::DetermineProgress(void)
+{
+#if 0
+ float progress;
+ if ((m_blenderData.m_ulProgress > 0) &&
+ (m_blenderData.m_ulProgressMax != m_blenderData.m_ulProgress)) {
+ progress = (float)m_blenderData.m_ulProgress;
+ progress /= (float)m_blenderData.m_ulProgressMax;
+ }
+ else {
+ progress = 0.f;
+ }
+ progress *= 100.f;
+ return (unsigned int) progress ;
+#endif
+ return m_previousProgress + 0.01; // temporary TODO
+}
+
+
+void GPC_Engine::UpdateLoadingAnimation(void)
+{
+ int delta;
+
+ float progress = DetermineProgress();
+
+ if(progress > m_previousProgress)
+ {
+ delta = progress - m_previousProgress;
+ m_previousProgress = progress;
+ if(m_previousProgress > 1.0)
+ m_previousProgress = 1.0; // limit to 1.0 (has to change !)
+// m_engine->m_previousProgress = 0.0;
+ }
+
+ STR_String to = "";
+ STR_String from = "";
+ STR_String subject = "progress";
+ STR_String body;
+ body.Format("%f", progress); // a number between 0.0 and 1.0
+
+ if(m_networkdev)
+ {
+ // Store a progress message in the network device.
+ NG_NetworkMessage* msg = new NG_NetworkMessage(to, from, subject, body);
+ m_networkdev->SendNetworkMessage(msg);
+ msg->Release();
+ }
+}
+
+
+void GPC_Engine::Stop()
+{
+ // only delete things that are created in StartKetsji()
+/* if(m_portal)
+ {
+ m_portal->Leave();
+ delete m_portal; // also gets rid of KX_KetsjiEngine (says Maarten)
+ m_portal = 0;
+ }
+*/ if(m_sceneconverter)
+ {
+ delete m_sceneconverter;
+ m_sceneconverter = 0;
+ }
+#if 0
+ if(m_frameTimerID)
+ {
+ ::KillTimer(0, m_frameTimerID);
+ m_frameTimerID = 0;
+ }
+ m_engineRunning = false;
+#endif
+
+ m_running = false;
+}
+
+
+void GPC_Engine::Exit()
+{
+ if(m_running)
+ Stop();
+
+ if (m_system) {
+ delete m_system;
+ m_system = 0;
+ }
+ if (m_keyboarddev) {
+ delete m_keyboarddev;
+ m_keyboarddev = 0;
+ }
+ if (m_mousedev) {
+ delete m_mousedev;
+ m_mousedev = 0;
+ }
+ if (m_canvas) {
+ delete m_canvas;
+ m_canvas = 0;
+ }
+ if (m_rendertools) {
+ delete m_rendertools;
+ m_rendertools = 0;
+ }
+ if (m_networkdev) {
+ delete m_networkdev;
+ m_networkdev = 0;
+ }
+
+ if (m_audiodevice)
+ {
+ SND_DeviceManager::Unsubscribe();
+ m_audiodevice = 0;
+ }
+
+ m_initialized = false;
+}
+
diff --git a/source/gameengine/GamePlayer/common/GPC_Engine.h b/source/gameengine/GamePlayer/common/GPC_Engine.h
new file mode 100644
index 00000000000..ccf2997eba6
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/GPC_Engine.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 *****
+ */
+
+#ifndef __GPC_ENGINE_H
+#define __GPC_ENGINE_H
+
+
+#include "GPC_Canvas.h"
+#include "GPC_System.h"
+
+class GPC_KeyboardDevice;
+class GPC_MouseDevice;
+
+class RAS_IRenderTools;
+class KetsjiPortal;
+class KX_ISceneConverter;
+class NG_LoopBackNetworkDeviceInterface;
+class SND_IAudioDevice;
+class GPC_RawImage;
+
+
+class GPC_Engine
+{
+//protected:
+public:
+ /** Engine construction state. */
+ bool m_initialized;
+ /** Engine state. */
+ bool m_running;
+ /** loading state, ie a file is requested and is being loaded. Different
+ * from initialized and/or running */
+ bool m_loading;
+
+ bool m_customLoadingAnimation;
+
+ /** Last file download progress measurement. */
+ float m_previousProgress;
+
+ /** The game engine's system abstraction. */
+ GPC_System* m_system;
+ /** The game engine's keyboard abstraction. */
+ GPC_KeyboardDevice* m_keyboarddev;
+ /** The game engine's mouse abstraction. */
+ GPC_MouseDevice* m_mousedev;
+ /** The game engine's canvas abstraction. */
+ GPC_Canvas* m_canvas;
+ /** The game engine's platform dependent render tools. */
+ RAS_IRenderTools* m_rendertools;
+ /** The portal used to start the engine. */
+ KetsjiPortal* m_portal;
+ /** Converts Blender data files. */
+ KX_ISceneConverter* m_sceneconverter;
+ /** Network interface. */
+ NG_LoopBackNetworkDeviceInterface* m_networkdev;
+ /** Audiodevice interface */
+ SND_IAudioDevice* m_audiodevice;
+
+ struct ScrArea *m_curarea; // for future use, not used yet
+
+ char *m_customLoadingAnimationURL;
+ int m_foregroundColor;
+ int m_backgroundColor;
+ int m_frameRate;
+
+ GPC_RawImage *m_BlenderLogo;
+ GPC_Canvas::TBannerId m_BlenderLogoId;
+ GPC_RawImage *m_Blender3DLogo;
+ GPC_Canvas::TBannerId m_Blender3DLogoId;
+#if 0
+ GPC_RawImage *m_NaNLogo;
+ GPC_Canvas::TBannerId m_NaNLogoId;
+#endif
+
+public:
+ GPC_Engine(char *customLoadingAnimation,
+ int foregroundColor, int backgroundColor, int frameRate);
+ ~GPC_Engine();
+ // Initialize() functions are not put here since they have
+ // different prototypes for Unix and Windows
+ void StartLoadingAnimation();
+ bool Start(char *filename); // file-on-disk starter
+ bool Start(unsigned char *blenderDataBuffer,
+ unsigned int blenderDataBufferSize); // file-in-memory starter
+
+ void Stop();
+ virtual void Exit();
+
+ bool Initialized(void) {return m_initialized;}
+ bool Loading(void) {return m_loading;}
+ bool Running(void) const {return m_running;}
+
+ virtual float DetermineProgress(void); // will be platform dependant
+ void UpdateLoadingAnimation(void);
+
+private:
+ bool StartKetsji(void);
+
+};
+
+
+#endif // __GPC_ENGINE_H
diff --git a/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.cpp b/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.cpp
new file mode 100644
index 00000000000..7cd1e48f9b3
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.cpp
@@ -0,0 +1,124 @@
+/**
+ * $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 "GPC_KeyboardDevice.h"
+
+
+/**
+ * NextFrame toggles currentTable with previousTable,
+ * and copies relevant event information from previous to current table
+ * (pressed keys need to be remembered).
+ */
+void GPC_KeyboardDevice::NextFrame()
+{
+ SCA_IInputDevice::NextFrame();
+
+ // Now convert justpressed key events into regular (active) keyevents
+ int previousTable = 1-m_currentTable;
+ for (int keyevent= KX_BEGINKEY; keyevent< KX_ENDKEY;keyevent++)
+ {
+ SCA_InputEvent& oldevent = m_eventStatusTables[previousTable][keyevent];
+ if (oldevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED ||
+ oldevent.m_status == SCA_InputEvent::KX_ACTIVE )
+ {
+ m_eventStatusTables[m_currentTable][keyevent] = oldevent;
+ m_eventStatusTables[m_currentTable][keyevent].m_status = SCA_InputEvent::KX_ACTIVE;
+ //m_eventStatusTables[m_currentTable][keyevent].m_status = SCA_InputEvent::KX_JUSTACTIVATED ;
+ }
+ }
+}
+
+
+
+/**
+ * ConvertBPEvent translates Windows keyboard events into ketsji kbd events.
+ * Extra event information is stored, like ramp-mode (just released/pressed)
+ */
+bool GPC_KeyboardDevice::ConvertEvent(int incode, int val)
+{
+ bool result = false;
+
+ // convert event
+ KX_EnumInputs kxevent = this->ToNative(incode);
+
+ // only process it, if it's a key
+ if (kxevent >= KX_BEGINKEY && kxevent < KX_ENDKEY)
+ {
+ int previousTable = 1-m_currentTable;
+
+ if (val > 0)
+ {
+ if (kxevent == SCA_IInputDevice::KX_ESCKEY && val != 0)
+ result = true;
+
+ // todo: convert val ??
+ m_eventStatusTables[m_currentTable][kxevent].m_eventval = val ; //???
+
+ switch (m_eventStatusTables[previousTable][kxevent].m_status)
+ {
+ case SCA_InputEvent::KX_JUSTACTIVATED:
+ case SCA_InputEvent::KX_ACTIVE:
+ {
+ m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_ACTIVE;
+ break;
+ }
+
+ case SCA_InputEvent::KX_NO_INPUTSTATUS:
+ default:
+ {
+ m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_JUSTACTIVATED;
+ }
+ }
+
+ } else
+ {
+
+ switch (m_eventStatusTables[previousTable][kxevent].m_status)
+ {
+ case SCA_InputEvent::KX_JUSTACTIVATED:
+ case SCA_InputEvent::KX_ACTIVE:
+ {
+ m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_JUSTRELEASED;
+ break;
+ }
+ default:
+ {
+ m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_NO_INPUTSTATUS;
+ }
+ }
+ }
+ } else {
+ exit(1);
+ }
+ return result;
+}
diff --git a/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.h b/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.h
new file mode 100644
index 00000000000..a247de301b9
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.h
@@ -0,0 +1,87 @@
+/**
+ * $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 __GPC_KEYBOARDDEVICE_H
+#define __GPC_KEYBOARDDEVICE_H
+
+#ifdef WIN32
+#pragma warning (disable : 4786)
+#endif // WIN32
+
+#include "SCA_IInputDevice.h"
+
+#include <map>
+
+
+/**
+ * System independent implementation of SCA_IInputDevice.
+ * System dependent keyboard devices need only to inherit this class
+ * and fill the m_reverseKeyTranslateTable key translation map.
+ * @see SCA_IInputDevice
+ */
+
+class GPC_KeyboardDevice : public SCA_IInputDevice
+{
+protected:
+
+ /**
+ * This map converts system dependent keyboard codes into Ketsji codes.
+ * System dependent keyboard codes are stored as ints.
+ */
+ std::map<int, KX_EnumInputs> m_reverseKeyTranslateTable;
+
+public:
+ GPC_KeyboardDevice()
+ {
+ }
+
+ virtual ~GPC_KeyboardDevice(void)
+ {
+ }
+
+ virtual bool IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)
+ {
+ return false;
+ }
+
+ virtual void NextFrame();
+
+ virtual KX_EnumInputs ToNative(int incode)
+ {
+ return m_reverseKeyTranslateTable[incode];
+ }
+
+ virtual bool ConvertEvent(int incode, int val);
+};
+
+
+#endif // _GPC_KEYBOARDDEVICE_H
diff --git a/source/gameengine/GamePlayer/common/GPC_MouseDevice.cpp b/source/gameengine/GamePlayer/common/GPC_MouseDevice.cpp
new file mode 100644
index 00000000000..a6ce7b3ae0d
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/GPC_MouseDevice.cpp
@@ -0,0 +1,207 @@
+/**
+ * $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 "GPC_MouseDevice.h"
+
+
+GPC_MouseDevice::GPC_MouseDevice()
+{
+
+}
+GPC_MouseDevice::~GPC_MouseDevice()
+{
+
+}
+
+/**
+ * IsPressed gives boolean information about mouse status, true if pressed, false if not.
+ */
+bool GPC_MouseDevice::IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)
+{
+ const SCA_InputEvent & inevent = m_eventStatusTables[m_currentTable][inputcode];
+ bool pressed = (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED ||
+ inevent.m_status == SCA_InputEvent::KX_ACTIVE);
+ return pressed;
+}
+
+
+/**
+ * NextFrame toggles currentTable with previousTable,
+ * and copies relevant event information from previous to current table
+ * (pressed keys need to be remembered).
+ */
+void GPC_MouseDevice::NextFrame()
+{
+ SCA_IInputDevice::NextFrame();
+
+ // Convert just pressed events into regular (active) events
+ int previousTable = 1-m_currentTable;
+ for (int mouseevent= KX_BEGINMOUSE; mouseevent< KX_ENDMOUSEBUTTONS; mouseevent++) {
+ SCA_InputEvent& oldevent = m_eventStatusTables[previousTable][mouseevent];
+ if (oldevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED ||
+ oldevent.m_status == SCA_InputEvent::KX_ACTIVE) {
+ m_eventStatusTables[m_currentTable][mouseevent] = oldevent;
+ m_eventStatusTables[m_currentTable][mouseevent].m_status = SCA_InputEvent::KX_ACTIVE;
+ }
+ }
+ for (int mousemove= KX_ENDMOUSEBUTTONS; mousemove< KX_ENDMOUSE; mousemove++) {
+ SCA_InputEvent& oldevent = m_eventStatusTables[previousTable][mousemove];
+ m_eventStatusTables[m_currentTable][mousemove] = oldevent;
+ if (oldevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED ||
+ oldevent.m_status == SCA_InputEvent::KX_ACTIVE) {
+ m_eventStatusTables[m_currentTable][mousemove].m_status = SCA_InputEvent::KX_JUSTRELEASED;
+ }
+ else {
+ if (oldevent.m_status == SCA_InputEvent::KX_JUSTRELEASED) {
+ m_eventStatusTables[m_currentTable][mousemove].m_status = SCA_InputEvent::KX_NO_INPUTSTATUS ;
+ }
+ }
+ }
+}
+
+
+bool GPC_MouseDevice::ConvertButtonEvent(TButtonId button, bool isDown)
+{
+ bool result = false;
+
+ switch (button)
+ {
+ case buttonLeft:
+ result = ConvertEvent(KX_LEFTMOUSE, isDown);
+ break;
+ case buttonMiddle:
+ result = ConvertEvent(KX_MIDDLEMOUSE, isDown);
+ break;
+ case buttonRight:
+ result = ConvertEvent(KX_RIGHTMOUSE, isDown);
+ break;
+ default:
+ // Should not happen!
+ break;
+ }
+
+ return result;
+}
+
+/**
+ * Splits combined button and x,y cursor move events into separate Ketsji
+ * x and y move and button events.
+ */
+bool GPC_MouseDevice::ConvertButtonEvent(TButtonId button, bool isDown, int x, int y)
+{
+ // First update state tables for cursor move.
+ bool result = ConvertMoveEvent(x, y);
+
+ // Now update for button state.
+ if (result) {
+ result = ConvertButtonEvent(button, isDown);
+ }
+
+ return result;
+}
+
+/**
+ * Splits combined x,y move into separate Ketsji x and y move events.
+ */
+bool GPC_MouseDevice::ConvertMoveEvent(int x, int y)
+{
+ bool result;
+
+ // Convert to local coordinates?
+ result = ConvertEvent(KX_MOUSEX, x);
+ if (result) {
+ result = ConvertEvent(KX_MOUSEY, y);
+ }
+
+ return result;
+}
+
+
+bool GPC_MouseDevice::ConvertEvent(KX_EnumInputs kxevent, int eventval)
+{
+ bool result = true;
+
+ // Only process it, if it's a mouse event
+ if (kxevent > KX_BEGINMOUSE && kxevent < KX_ENDMOUSE) {
+ int previousTable = 1-m_currentTable;
+
+ if (eventval > 0) {
+ m_eventStatusTables[m_currentTable][kxevent].m_eventval = eventval;
+
+ switch (m_eventStatusTables[previousTable][kxevent].m_status)
+ {
+ case SCA_InputEvent::KX_ACTIVE:
+ case SCA_InputEvent::KX_JUSTACTIVATED:
+ {
+ m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_ACTIVE;
+ break;
+ }
+ case SCA_InputEvent::KX_JUSTRELEASED:
+ {
+ if ( kxevent > KX_BEGINMOUSEBUTTONS && kxevent < KX_ENDMOUSEBUTTONS)
+ {
+ m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_JUSTACTIVATED;
+ } else
+ {
+ m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_ACTIVE;
+
+ }
+ break;
+ }
+ default:
+ {
+ m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_JUSTACTIVATED;
+ }
+ }
+
+ }
+ else {
+ switch (m_eventStatusTables[previousTable][kxevent].m_status)
+ {
+ case SCA_InputEvent::KX_JUSTACTIVATED:
+ case SCA_InputEvent::KX_ACTIVE:
+ {
+ m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_JUSTRELEASED;
+ break;
+ }
+ default:
+ {
+ m_eventStatusTables[m_currentTable][kxevent].m_status = SCA_InputEvent::KX_NO_INPUTSTATUS;
+ }
+ }
+ }
+ }
+ else {
+ result = false;
+ }
+ return result;
+}
diff --git a/source/gameengine/GamePlayer/common/GPC_MouseDevice.h b/source/gameengine/GamePlayer/common/GPC_MouseDevice.h
new file mode 100644
index 00000000000..51e3339a063
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/GPC_MouseDevice.h
@@ -0,0 +1,105 @@
+/**
+ * $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 __GPC_MOUSE_DEVICE_H
+#define __GPC_MOUSE_DEVICE_H
+
+#ifdef WIN32
+#pragma warning (disable : 4786)
+#endif // WIN32
+
+#include "SCA_IInputDevice.h"
+
+
+/**
+ * Generic Ketsji mouse device.
+ * @see SCA_IInputDevice
+ */
+class GPC_MouseDevice : public SCA_IInputDevice
+{
+public:
+ /**
+ * Button identifier.
+ */
+ typedef enum {
+ buttonLeft,
+ buttonMiddle,
+ buttonRight
+ } TButtonId;
+
+ GPC_MouseDevice();
+ virtual ~GPC_MouseDevice(void);
+
+ virtual bool IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode);
+ virtual void NextFrame();
+
+ /**
+ * Call this routine to update the mouse device when a button state changes.
+ * @param button Which button state changes.
+ * @param isDown The new state of the button.
+ * @param x Position x-coordinate of the cursor at the time of the state change.
+ * @param y Position y-coordinate of the cursor at the time of the state change.
+ * @return Indication as to whether the event was processed.
+ */
+ virtual bool ConvertButtonEvent(TButtonId button, bool isDown);
+
+ /**
+ * Call this routine to update the mouse device when a button state and
+ * cursor position changes at the same time (e.g. in Win32 messages).
+ * @param button Which button state changes.
+ * @param isDown The new state of the button.
+ * @param x Position x-coordinate of the cursor at the time of the state change.
+ * @param y Position y-coordinate of the cursor at the time of the state change.
+ * @return Indication as to whether the event was processed.
+ */
+ virtual bool ConvertButtonEvent(TButtonId button, bool isDown, int x, int y);
+
+ /**
+ * Call this routine to update the mouse device when the cursor has moved.
+ * @param x Position x-coordinate of the cursor.
+ * @param y Position y-coordinate of the cursor.
+ * @return Indication as to whether the event was processed.
+ */
+ virtual bool ConvertMoveEvent(int x, int y);
+
+protected:
+ /**
+ * This routine converts a single mouse event to a Ketsji mouse event.
+ * @param kxevent Ketsji event code.
+ * @param eventval Value for this event.
+ * @return Indication as to whether the event was processed.
+ */
+ virtual bool ConvertEvent(KX_EnumInputs kxevent, int eventval);
+};
+
+
+#endif // __GPC_MOUSE_DEVICE_H
diff --git a/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp b/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp
new file mode 100644
index 00000000000..77488597a70
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp
@@ -0,0 +1,410 @@
+/**
+ * $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 "GPC_PolygonMaterial.h"
+
+#include "MT_Vector3.h"
+
+#include "RAS_IRasterizer.h"
+
+/* This list includes only data type definitions */
+#include "DNA_object_types.h"
+#include "DNA_material_types.h"
+#include "DNA_image_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_group_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_camera_types.h"
+#include "DNA_property_types.h"
+#include "DNA_text_types.h"
+#include "DNA_sensor_types.h"
+#include "DNA_controller_types.h"
+#include "DNA_actuator_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_world_types.h"
+
+#include "BKE_global.h"
+#include "BKE_image.h"
+#include "BKE_mesh.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "IMB_imbuf_types.h"
+/* end of blender include block */
+
+#ifdef WIN32
+#include <windows.h>
+#endif // WIN32
+#include "GL/gl.h"
+#include "GL/glu.h"
+
+static Image *fCurpage=0;
+static int fCurtile=0, fCurmode=0, fCurTileXRep=0, fCurTileYRep=0;
+static short fTexWindx, fTexWindy, fTexWinsx, fTexWinsy;
+static int fDoMipMap = 1;
+static int fLinearMipMap=1;
+static int fAlphamode= -1;
+
+ /* (n&(n-1)) zeros the least significant bit of n */
+static int is_pow2(int num) {
+ return ((num)&(num-1))==0;
+}
+static int smaller_pow2(int num) {
+ while (!is_pow2(num))
+ num= num&(num-1);
+ return num;
+}
+
+static void my_make_repbind(Image *ima)
+{
+ if(ima==0 || ima->ibuf==0) return;
+
+ if(ima->repbind) {
+ glDeleteTextures(ima->totbind, (GLuint*)ima->repbind);
+ delete (ima->repbind);
+ ima->repbind= 0;
+ }
+ ima->totbind= ima->xrep*ima->yrep;
+ if(ima->totbind>1) {
+ ima->repbind= (unsigned int *) malloc(sizeof(int)*ima->totbind);
+ for (int i=0;i<ima->totbind;i++)
+ ((int*)ima->repbind)[i] = 0;
+ }
+}
+
+
+int my_set_tpage(TFace *tface)
+{
+ static TFace *lasttface= 0;
+ Image *ima;
+ unsigned int *rect, *bind;
+ int tpx, tpy, tilemode, tileXRep,tileYRep;
+
+ /* afschakelen */
+ if(tface==0) {
+ if(lasttface==0) return 0;
+
+ lasttface= 0;
+ fCurtile= 0;
+ fCurpage= 0;
+ if(fCurmode!=0) {
+ glMatrixMode(GL_TEXTURE);
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ }
+ fCurmode= 0;
+ fCurTileXRep=0;
+ fCurTileYRep=0;
+ fAlphamode= -1;
+
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_TEXTURE_GEN_S);
+ glDisable(GL_TEXTURE_GEN_T);
+ return 0;
+ }
+ lasttface= tface;
+
+ if( fAlphamode != tface->transp) {
+ fAlphamode= tface->transp;
+
+ if(fAlphamode) {
+ glEnable(GL_BLEND);
+
+ if(fAlphamode==TF_ADD) {
+ glBlendFunc(GL_ONE, GL_ONE);
+ /* glBlendEquationEXT(GL_FUNC_ADD_EXT); */
+ }
+ else if(fAlphamode==TF_ALPHA) {
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ /* glBlendEquationEXT(GL_FUNC_ADD_EXT); */
+ }
+ /* else { */
+ /* glBlendFunc(GL_ONE, GL_ONE); */
+ /* glBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT); */
+ /* } */
+ }
+ else glDisable(GL_BLEND);
+ }
+
+ ima= (struct Image *) tface->tpage;
+
+ /* Enable or disable environment mapping */
+ if (ima && (ima->flag & IMA_REFLECT)){
+
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+
+ glEnable(GL_TEXTURE_GEN_S);
+ glEnable(GL_TEXTURE_GEN_T);
+ }
+ else{
+ glDisable(GL_TEXTURE_GEN_S);
+ glDisable(GL_TEXTURE_GEN_T);
+ }
+
+ tilemode= tface->mode & TF_TILES;
+ tileXRep = 0;
+ tileYRep = 0;
+ if (ima)
+ {
+ tileXRep = ima->xrep;
+ tileYRep = ima->yrep;
+ }
+
+
+ if(ima==fCurpage && fCurtile==tface->tile && tilemode==fCurmode && fCurTileXRep==tileXRep && fCurTileYRep == tileYRep) return ima!=0;
+
+ if(tilemode!=fCurmode || fCurTileXRep!=tileXRep || fCurTileYRep != tileYRep)
+ {
+ glMatrixMode(GL_TEXTURE);
+ glLoadIdentity();
+
+ if(tilemode && ima!=0)
+ glScalef(ima->xrep, ima->yrep, 1.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ }
+
+ if(ima==0 || ima->ok==0) {
+ glDisable(GL_TEXTURE_2D);
+
+ fCurtile= tface->tile;
+ fCurpage= 0;
+ fCurmode= tilemode;
+ fCurTileXRep = tileXRep;
+ fCurTileYRep = tileYRep;
+
+ return 0;
+ }
+
+ if(ima->ibuf==0) {
+ load_image(ima, IB_rect, "", 0);
+
+ if(ima->ibuf==0) {
+ ima->ok= 0;
+
+ fCurtile= tface->tile;
+ fCurpage= 0;
+ fCurmode= tilemode;
+ fCurTileXRep = tileXRep;
+ fCurTileYRep = tileYRep;
+
+ glDisable(GL_TEXTURE_2D);
+ return 0;
+ }
+
+ }
+
+ if(ima->tpageflag & IMA_TWINANIM) fCurtile= ima->lastframe;
+ else fCurtile= tface->tile;
+
+ if(tilemode) {
+
+ if(ima->repbind==0) my_make_repbind(ima);
+
+ if(fCurtile>=ima->totbind) fCurtile= 0;
+
+ /* this happens when you change repeat buttons */
+ if(ima->repbind) bind= ima->repbind+fCurtile;
+ else bind= &ima->bindcode;
+
+ if(*bind==0) {
+
+ fTexWindx= ima->ibuf->x/ima->xrep;
+ fTexWindy= ima->ibuf->y/ima->yrep;
+
+ if(fCurtile>=ima->xrep*ima->yrep) fCurtile= ima->xrep*ima->yrep-1;
+
+ fTexWinsy= fCurtile / ima->xrep;
+ fTexWinsx= fCurtile - fTexWinsy*ima->xrep;
+
+ fTexWinsx*= fTexWindx;
+ fTexWinsy*= fTexWindy;
+
+ tpx= fTexWindx;
+ tpy= fTexWindy;
+
+ rect= ima->ibuf->rect + fTexWinsy*ima->ibuf->x + fTexWinsx;
+ }
+ }
+ else {
+ bind= &ima->bindcode;
+
+ if(*bind==0) {
+ tpx= ima->ibuf->x;
+ tpy= ima->ibuf->y;
+ rect= ima->ibuf->rect;
+ }
+ }
+
+ if(*bind==0) {
+ int rectw= tpx, recth= tpy;
+ unsigned int *tilerect= NULL, *scalerect= NULL;
+
+ /*
+ * Maarten:
+ * According to Ton this code is not needed anymore. It was used only
+ * in really old Blenders.
+ * Reevan:
+ * Actually it is needed for backwards compatibility. Simpledemo 6 does not display correctly without it.
+ */
+#if 1
+ if (tilemode) {
+ int y;
+
+ tilerect= (unsigned int*)MEM_mallocN(rectw*recth*sizeof(*tilerect), "tilerect");
+ for (y=0; y<recth; y++) {
+ unsigned int *rectrow= &rect[y*ima->ibuf->x];
+ unsigned int *tilerectrow= &tilerect[y*rectw];
+
+ memcpy(tilerectrow, rectrow, tpx*sizeof(*rectrow));
+ }
+
+ rect= tilerect;
+ }
+#endif
+ if (!is_pow2(rectw) || !is_pow2(recth)) {
+ rectw= smaller_pow2(rectw);
+ recth= smaller_pow2(recth);
+
+ scalerect= (unsigned int *)MEM_mallocN(rectw*recth*sizeof(*scalerect), "scalerect");
+ gluScaleImage(GL_RGBA, tpx, tpy, GL_UNSIGNED_BYTE, rect, rectw, recth, GL_UNSIGNED_BYTE, scalerect);
+ rect= scalerect;
+ }
+
+ glGenTextures(1, (GLuint*)bind);
+
+ /*
+ if(G.f & G_DEBUG) {
+ printf("var1: %s\n", ima->id.name+2);
+ printf("var1: %d, var2: %d\n", *bind, tpx);
+ printf("var1: %d, var2: %d\n", fCurtile, tilemode);
+ }
+ */
+ glBindTexture( GL_TEXTURE_2D, *bind);
+
+ if (!fDoMipMap)
+ {
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ } else
+ {
+ int minfilter= fLinearMipMap?GL_LINEAR_MIPMAP_LINEAR:GL_LINEAR_MIPMAP_NEAREST;
+
+ gluBuild2DMipmaps(GL_TEXTURE_2D, 4, rectw, recth, GL_RGBA, GL_UNSIGNED_BYTE, rect);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minfilter);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ }
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+ if (tilerect)
+ MEM_freeN(tilerect);
+ if (scalerect)
+ MEM_freeN(scalerect);
+ }
+ else glBindTexture( GL_TEXTURE_2D, *bind);
+
+
+
+ glEnable(GL_TEXTURE_2D);
+
+ fCurpage= ima;
+ fCurmode= tilemode;
+ fCurTileXRep = tileXRep;
+ fCurTileYRep = tileYRep;
+
+ return 1;
+}
+
+
+GPC_PolygonMaterial::GPC_PolygonMaterial(const STR_String& texname, bool ba, const STR_String& matname,
+ int tile, int tileXrep, int tileYrep, int mode, int transparant,
+ int lightlayer, bool bIsTriangle, void* clientobject, void* tpage) :
+ RAS_IPolyMaterial(texname, ba, matname, tile, tileXrep, tileYrep, mode,
+ transparant, lightlayer, bIsTriangle, clientobject), m_tface((struct TFace*)tpage)
+{
+ // clear local caching info
+ my_set_tpage(0);
+}
+
+
+GPC_PolygonMaterial::~GPC_PolygonMaterial(void)
+{
+}
+
+
+void GPC_PolygonMaterial::Activate(RAS_IRasterizer* rasty, TCachingInfo& cachingInfo) const
+{
+ if (GetCachingInfo() != cachingInfo)
+ {
+ if (!cachingInfo)
+ {
+ my_set_tpage(0);
+ }
+ cachingInfo = GetCachingInfo();
+
+ if ((m_drawingmode & 4)&& (rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) )
+ {
+ update_realtime_texture((struct TFace*) m_tface, rasty->GetTime());
+ my_set_tpage(m_tface);
+ rasty->EnableTextures(true);
+ } else
+ {
+ my_set_tpage(0);
+ rasty->EnableTextures(false);
+ }
+
+ //TF_TWOSIDE == 512, todo, make this a ketsji enum
+ if(m_drawingmode & 512) {
+ rasty->SetCullFace(false);
+ }
+
+ else
+ {
+ rasty->SetCullFace(true);;//glEnable(GL_CULL_FACE);
+ //else glDisable(GL_CULL_FACE);
+ }
+ }
+ rasty->SetSpecularity(m_specular[0],m_specular[1],m_specular[2],m_specularity);
+ rasty->SetShinyness(m_shininess);
+ rasty->SetDiffuse(m_diffuse[0], m_diffuse[1],m_diffuse[2], 1.0);
+}
+
+
+void GPC_PolygonMaterial::SetMipMappingEnabled(bool enabled)
+{
+ fDoMipMap = enabled ? 1 : 0;
+}
diff --git a/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.h b/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.h
new file mode 100644
index 00000000000..392e27209e2
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.h
@@ -0,0 +1,87 @@
+/**
+ * $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 __GPC_POLYGONMATERIAL
+#define __GPC_POLYGONMATERIAL
+
+#include "RAS_IPolygonMaterial.h"
+
+
+class GPC_PolygonMaterial : public RAS_IPolyMaterial
+{
+ struct TFace* m_tface;
+
+public:
+ GPC_PolygonMaterial(const STR_String& texname, bool ba, const STR_String& matname,
+ int tile, int tileXrep, int tileYrep, int mode, int transparant,
+ int lightlayer, bool bIsTriangle, void* clientobject, void* tpage);
+
+ virtual ~GPC_PolygonMaterial(void);
+
+ /**
+ * Returns the caching information for this material,
+ * This can be used to speed up the rasterizing process.
+ * @return The caching information.
+ */
+ virtual TCachingInfo GetCachingInfo(void) const;
+
+ /**
+ * Activates the material in the (OpenGL) rasterizer.
+ * On entry, the cachingInfo contains info about the last activated material.
+ * On exit, the cachingInfo should contain updated info about this material.
+ * @param rasty The rasterizer in which the material should be active.
+ * @param cachingInfo The information about the material used to speed up rasterizing.
+ */
+ virtual void Activate(RAS_IRasterizer* rasty, TCachingInfo& cachingInfo) const;
+
+ /**
+ * Returns the Blender texture face structure that is used for this material.
+ * @return The material's texture face.
+ */
+ TFace* GetTFace(void) const;
+
+ static void SetMipMappingEnabled(bool enabled = false);
+};
+
+
+inline TFace* GPC_PolygonMaterial::GetTFace(void) const
+{
+ return m_tface;
+}
+
+inline GPC_PolygonMaterial::TCachingInfo GPC_PolygonMaterial::GetCachingInfo(void) const
+{
+ return GetTFace();
+}
+
+
+#endif // __GPC_POLYGONMATERIAL_H
diff --git a/source/gameengine/GamePlayer/common/GPC_RawImage.cpp b/source/gameengine/GamePlayer/common/GPC_RawImage.cpp
new file mode 100644
index 00000000000..0a4b6ff3df6
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/GPC_RawImage.cpp
@@ -0,0 +1,135 @@
+/**
+ * $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 <string.h>
+
+#include "GPC_RawImage.h"
+
+#include "GPC_RawLogoArrays.h"
+
+
+GPC_RawImage::GPC_RawImage()
+ : m_data(0), m_dataSize(0), m_width(0), m_height(0)
+{
+}
+
+
+bool GPC_RawImage::Load(
+ char *srcName,
+ int destWidth, int destHeight,
+ TImageAlignment alignment, int offsetX, int offsetY)
+{
+ int srcWidth, srcHeight;
+ bool success = true;
+ if(strcmp(srcName, "BlenderLogo") == 0)
+ GetRawBlenderLogo(&m_data, &srcWidth, &srcHeight);
+ else
+ if(strcmp(srcName, "Blender3DLogo") == 0)
+ GetRawBlender3DLogo(&m_data, &srcWidth, &srcHeight);
+#if 0
+ else
+ if(strcmp(srcName, "NaNLogo") == 0)
+ GetRawNaNLogo(&m_data, &srcWidth, &srcHeight);
+#endif
+ else // unknown image
+ success = false;
+
+ if(success)
+ {
+ unsigned char *tempData = m_data;
+
+ int numBytes = destWidth * destHeight * 4;
+ m_data = new unsigned char[numBytes]; // re-use m_data ('unsigned char' was 'char')
+ if(m_data)
+ {
+ ::memset(m_data, 0x00000000, numBytes);
+ m_width = destWidth;
+ m_height = destHeight;
+
+ int srcBytesWidth = srcWidth * 4;
+ int dstBytesWidth = m_width * 4;
+ int numRows = (srcHeight + offsetY) < m_height ? srcHeight : m_height - offsetY;
+ numBytes = (srcWidth + offsetX) < m_width ? srcBytesWidth : (m_width - offsetX) * 4;
+
+ if((offsetX < m_width) && (offsetY < m_height))
+ {
+ unsigned char* src = (unsigned char*)tempData;
+ unsigned char* dst = (unsigned char*)m_data;
+ if(alignment == alignTopLeft)
+ {
+ // Put original in upper left corner
+
+ // Add vertical offset
+ dst += offsetY * dstBytesWidth;
+ // Add horizontal offset
+ dst += offsetX * 4;
+ for (int row = 0; row < numRows; row++)
+ {
+ ::memcpy(dst, src, numBytes);
+ src += srcBytesWidth;
+ dst += dstBytesWidth;
+ }
+ }
+ else
+ {
+ // Put original in lower right corner
+
+ // Add vertical offset
+ dst += (m_height - (srcHeight + offsetY)) * dstBytesWidth;
+ // Add horizontal offset
+ if (m_width > (srcWidth + offsetX)) {
+ dst += (m_width - (srcWidth + offsetX)) * 4;
+ }
+ else {
+ src += (srcWidth + offsetX - m_width) * 4;
+ }
+ for (int row = 0; row < numRows; row++) {
+ ::memcpy(dst, src, numBytes);
+ src += srcBytesWidth;
+ dst += dstBytesWidth;
+ }
+ }
+ }
+// doesn't compile under Linux delete [] tempData;
+ delete tempData;
+ }
+ else {
+ // Allocation failed, restore old data
+ m_data = tempData;
+ success = false;
+ }
+ }
+
+ return success;
+}
+
diff --git a/source/gameengine/GamePlayer/common/GPC_RawImage.h b/source/gameengine/GamePlayer/common/GPC_RawImage.h
new file mode 100644
index 00000000000..ac9dad77d2f
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/GPC_RawImage.h
@@ -0,0 +1,122 @@
+/**
+ * $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 __GPC_RAWIMAGE_H__
+#define __GPC_RAWIMAGE_H__
+
+/**
+ * This memory resource reads images from the application resources.
+ * Images are expected to be stored as raw RGBA bytes.
+ * You can generate these images by exporting images with an alpha
+ * channel from Photoshop in RAW format with interleaved channels.
+ */
+
+class GPC_RawImage
+{
+public:
+ GPC_RawImage();
+
+ typedef enum {
+ alignTopLeft,
+ alignBottomRight
+ } TImageAlignment;
+
+ /**
+ * Loads the image form the resource into memory.
+ * Converts size of the image and places it with given alignment.
+ * @param hInstApp The application's instance (location of the resources).
+ * @param lpName Name of the resource.
+ * @param lpType Type of the resource.
+ * @param srcWidth The width of the resource image.
+ * @param srcHeight The height of the resource image.
+ * @param width The width of the image created.
+ * @param height The height of the image created.
+ * @param alignment How the resource image is located in the image created.
+ * @param offsetX Amount of horzontal offset applied to the resource image.
+ * @param offsetY Amount of vertical offset applied to the resource image.
+ */
+ virtual bool Load(char *srcName,
+ int destWidth, int destHeight,
+ TImageAlignment alignment = alignTopLeft,
+ int offsetX = 0, int offsetY = 0);
+
+ /**
+ * Returns the width of the image.
+ * @return The width of the image.
+ */
+ virtual int Width() const
+ {
+ return m_width;
+ }
+
+ /**
+ * Returns the height of the image.
+ * @return The height of the image.
+ */
+ virtual int Height() const
+ {
+ return m_height;
+ }
+
+ /**
+ * Returns a pointer to the data loaded from the resource.
+ * @return A pointer to the data loaded from the resource.
+ */
+ virtual unsigned char *Data() const
+ {
+ return m_data;
+ }
+
+ /**
+ * Returns the size of the data loaded from the resource.
+ * @return The size of the loaded from the resource.
+ */
+ virtual int DataSize() const
+ {
+ return m_dataSize;
+ }
+
+protected:
+ /**
+ * Disposes the data stored at the m_data member.
+ */
+// virtual void disposeData(void);
+
+protected:
+ unsigned char *m_data;
+ int m_dataSize;
+ int m_width;
+ int m_height;
+};
+
+
+#endif // __GPC_RAWIMAGE_H__
diff --git a/source/gameengine/GamePlayer/common/GPC_RawLoadDotBlendArray.cpp b/source/gameengine/GamePlayer/common/GPC_RawLoadDotBlendArray.cpp
new file mode 100644
index 00000000000..6ab2f1220e5
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/GPC_RawLoadDotBlendArray.cpp
@@ -0,0 +1,9312 @@
+/**
+ * $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 *****
+ */
+
+// This file is automatically generated. Do not edit by hand!
+
+
+
+#include "GPC_RawLoadDotBlendArray.h"
+
+
+void GetRawLoadingAnimation(unsigned char **data, int *dataSize)
+{
+ // create an array that will automatically be deleted when)
+ // we're outta this scope
+ static unsigned char load_blend[]= { 66, 76, 69, 78, 68, 70,
+ 73, 10, 0, 2, 21, 0, 0, 2, 22, 0, 0, 0, 0, 0, 0,
+ 2, 30, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 65, 25, 242, 2, 0, 2, 29, 253, 0, 0, 0, 4, 160, 249, 227,
+ 5, 65, 25, 242, 2, 0, 2, 29, 237, 0, 0, 0, 10, 39, 161,
+ 89, 128, 65, 248, 18, 0, 0, 2, 28, 205, 179, 76, 248, 13, 9,
+ 10, 156, 188, 58, 101, 43, 138, 63, 142, 132, 111, 231, 106, 44, 72,
+ 171, 116, 148, 204, 204, 104, 121, 88, 224, 36, 141, 195, 251, 160, 141,
+ 162, 12, 177, 93, 203, 236, 68, 235, 2, 137, 27, 34, 49, 52, 25,
+ 83, 60, 100, 208, 12, 234, 185, 206, 97, 0, 109, 170, 238, 253, 66,
+ 0, 68, 0, 0, 236, 253, 127, 0, 246, 18, 0, 82, 0, 0, 0,
+ 42, 247, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0,
+ 0, 0, 0, 0, 0, 36, 0, 2, 0, 0, 236, 253, 127, 0, 224,
+ 253, 127, 0, 224, 253, 127, 72, 249, 18, 0, 219, 128, 251, 119, 104,
+ 78, 249, 119, 255, 255, 255, 255, 0, 0, 0, 64, 111, 122, 152, 187,
+ 158, 149, 34, 236, 158, 103, 110, 35, 246, 67, 137, 177, 29, 56, 22,
+ 101, 64, 134, 124, 38, 155, 203, 128, 162, 3, 184, 27, 114, 80, 94,
+ 145, 136, 82, 121, 92, 7, 241, 119, 134, 12, 246, 193, 229, 95, 180,
+ 47, 135, 212, 231, 14, 59, 120, 218, 79, 151, 205, 221, 116, 27, 122,
+ 92, 0, 68, 0, 111, 0, 99, 0, 117, 0, 109, 0, 101, 0, 110,
+ 0, 116, 0, 115, 0, 82, 145, 252, 119, 255, 255, 255, 255, 60, 247,
+ 18, 0, 0, 0, 0, 0, 92, 247, 18, 0, 0, 16, 0, 0, 4,
+ 0, 0, 0, 0, 0, 242, 2, 0, 0, 242, 2, 32, 110, 172, 7,
+ 3, 239, 0, 0, 0, 0, 162, 7, 0, 0, 0, 64, 149, 244, 255,
+ 174, 70, 126, 180, 169, 78, 97, 78, 32, 67, 111, 110, 116, 101, 110,
+ 116, 32, 84, 101, 97, 109, 0, 247, 18, 0, 0, 16, 0, 0, 4,
+ 0, 0, 0, 0, 0, 242, 2, 0, 0, 242, 2, 80, 33, 90, 7,
+ 2, 32, 0, 0, 0, 0, 72, 7, 82, 145, 252, 119, 255, 255, 255,
+ 255, 168, 247, 18, 0, 0, 0, 0, 0, 200, 247, 18, 0, 0, 16,
+ 0, 0, 4, 0, 0, 0, 0, 0, 242, 2, 0, 0, 242, 2, 64,
+ 33, 88, 7, 2, 67, 0, 0, 0, 0, 72, 7, 216, 69, 0, 2,
+ 99, 111, 110, 116, 101, 110, 116, 99, 114, 101, 97, 116, 105, 111, 110,
+ 64, 98, 108, 101, 110, 100, 101, 114, 46, 110, 108, 0, 2, 81, 67,
+ 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 216, 69, 0, 0, 0,
+ 0, 72, 7, 116, 249, 18, 0, 127, 164, 252, 119, 0, 0, 242, 2,
+ 103, 154, 252, 119, 0, 0, 0, 0, 128, 26, 2, 0, 112, 112, 247,
+ 2, 12, 155, 252, 119, 255, 255, 255, 255, 40, 248, 18, 0, 0, 0,
+ 0, 0, 124, 249, 18, 0, 0, 16, 0, 0, 0, 236, 179, 7, 120,
+ 1, 242, 2, 48, 62, 8, 0, 184, 250, 18, 0, 0, 0, 72, 7,
+ 0, 112, 166, 7, 0, 0, 242, 2, 80, 0, 242, 2, 80, 0, 242,
+ 2, 0, 0, 226, 7, 0, 16, 162, 7, 0, 240, 5, 0, 248, 3,
+ 242, 2, 248, 3, 242, 2, 10, 0, 0, 0, 1, 0, 0, 0, 248,
+ 3, 242, 2, 120, 1, 242, 2, 112, 236, 179, 7, 120, 1, 242, 2,
+ 120, 1, 242, 2, 104, 236, 179, 7, 0, 16, 0, 0, 4, 0, 0,
+ 0, 0, 0, 242, 2, 0, 0, 242, 2, 64, 0, 162, 7, 3, 239,
+ 0, 0, 0, 0, 162, 7, 112, 236, 179, 7, 96, 157, 12, 3, 112,
+ 236, 179, 7, 120, 1, 242, 2, 104, 236, 179, 7, 18, 0, 0, 0,
+ 168, 248, 18, 0, 166, 166, 252, 119, 0, 0, 72, 7, 0, 48, 84,
+ 7, 64, 27, 84, 7, 0, 0, 242, 2, 236, 248, 18, 0, 176, 160,
+ 252, 119, 0, 0, 72, 7, 0, 32, 84, 7, 0, 16, 0, 0, 0,
+ 0, 242, 2, 64, 27, 84, 7, 1, 0, 0, 0, 136, 4, 0, 0,
+ 0, 27, 84, 7, 144, 1, 161, 7, 0, 0, 0, 0, 0, 0, 0,
+ 0, 145, 0, 0, 0, 145, 0, 0, 0, 152, 0, 0, 0, 0, 0,
+ 72, 7, 144, 249, 18, 0, 9, 151, 252, 119, 0, 32, 84, 7, 0,
+ 16, 0, 0, 143, 157, 252, 119, 86, 250, 18, 0, 72, 27, 84, 7,
+ 32, 0, 226, 7, 8, 0, 0, 0, 193, 0, 0, 0, 25, 0, 0,
+ 0, 0, 0, 242, 2, 135, 2, 0, 0, 112, 236, 179, 7, 64, 33,
+ 88, 7, 19, 0, 0, 0, 0, 249, 18, 0, 0, 67, 0, 0, 72,
+ 27, 84, 7, 0, 0, 0, 0, 0, 0, 0, 0, 200, 59, 90, 7,
+ 0, 0, 0, 0, 63, 0, 0, 0, 72, 33, 88, 7, 128, 26, 2,
+ 0, 112, 112, 247, 2, 0, 0, 0, 0, 16, 0, 0, 0, 224, 249,
+ 18, 0, 255, 255, 223, 255, 32, 0, 0, 0, 252, 24, 242, 2, 144,
+ 0, 0, 0, 8, 0, 0, 0, 77, 26, 2, 0, 1, 120, 64, 0,
+ 80, 6, 242, 2, 109, 26, 228, 7, 210, 119, 64, 0, 16, 0, 0,
+ 0, 191, 119, 64, 0, 65, 97, 108, 46, 0, 2, 26, 101, 0, 0,
+ 0, 6, 77, 194, 164, 27, 66, 114, 105, 0, 0, 2, 26, 77, 0,
+ 7, 126, 76, 0, 0, 0, 1, 121, 216, 88, 60, 9, 46, 197, 144,
+ 120, 249, 120, 38, 9, 47, 236, 125, 7, 120, 19, 71, 211, 240, 158,
+ 108, 176, 1, 3, 162, 155, 46, 211, 171, 113, 161, 186, 232, 132, 49,
+ 29, 131, 232, 132, 18, 100, 192, 96, 83, 140, 177, 77, 77, 192, 162,
+ 147, 64, 192, 9, 189, 37, 14, 16, 8, 9, 197, 96, 211, 193, 18,
+ 37, 116, 136, 147, 80, 2, 164, 152, 150, 0, 129, 196, 132, 22, 170,
+ 254, 153, 211, 173, 180, 42, 167, 147, 49, 223, 251, 230, 251, 126, 204,
+ 115, 104, 110, 119, 102, 118, 118, 119, 118, 102, 118, 111, 116, 106, 25,
+ 61, 210, 159, 120, 77, 9, 35, 132, 40, 178, 238, 111, 237, 30, 209,
+ 169, 117, 231, 200, 214, 221, 6, 142, 11, 10, 10, 234, 6, 160, 10,
+ 42, 110, 60, 43, 73, 240, 143, 131, 43, 24, 174, 182, 112, 141, 138,
+ 142, 139, 39, 78, 254, 186, 119, 35, 100, 8, 124, 166, 206, 138, 247,
+ 106, 43, 210, 56, 226, 36, 13, 78, 140, 137, 113, 160, 167, 184, 26,
+ 160, 205, 158, 22, 239, 165, 135, 43, 125, 85, 188, 87, 218, 202, 120,
+ 47, 213, 23, 112, 191, 35, 222, 139, 16, 147, 39, 92, 30, 164, 0,
+ 241, 84, 136, 20, 28, 241, 38, 145, 45, 123, 180, 44, 45, 210, 182,
+ 19, 121, 229, 206, 68, 124, 219, 63, 138, 135, 117, 20, 47, 13, 96,
+ 164, 19, 81, 60, 89, 188, 52, 6, 79, 11, 176, 133, 103, 1, 91,
+ 60, 45, 131, 71, 0, 78, 179, 226, 217, 180, 75, 24, 188, 244, 25,
+ 241, 94, 90, 171, 140, 28, 139, 135, 117, 20, 79, 7, 48, 177, 242,
+ 179, 193, 211, 49, 120, 74, 128, 145, 206, 204, 238, 150, 7, 139, 167,
+ 100, 240, 140, 211, 227, 189, 116, 20, 175, 128, 45, 30, 214, 81, 188,
+ 4, 128, 149, 34, 158, 81, 97, 219, 110, 2, 131, 167, 2, 24, 233,
+ 204, 120, 182, 252, 84, 12, 30, 206, 105, 130, 5, 175, 143, 13, 30,
+ 214, 181, 99, 116, 64, 53, 157, 202, 103, 197, 243, 133, 79, 212, 137,
+ 246, 34, 94, 192, 52, 51, 78, 154, 56, 47, 28, 51, 199, 190, 98,
+ 61, 197, 205, 153, 106, 214, 39, 173, 56, 215, 246, 184, 88, 79, 113,
+ 83, 1, 22, 120, 75, 224, 166, 50, 184, 26, 128, 145, 150, 206, 165,
+ 61, 174, 134, 193, 205, 213, 199, 123, 165, 138, 184, 132, 209, 77, 138,
+ 139, 245, 20, 55, 13, 96, 164, 197, 121, 114, 214, 183, 52, 6, 87,
+ 11, 48, 210, 226, 92, 165, 57, 193, 213, 50, 184, 217, 159, 1, 142,
+ 136, 107, 209, 1, 6, 23, 235, 41, 174, 30, 96, 164, 21, 230, 214,
+ 137, 188, 122, 6, 55, 0, 96, 164, 69, 220, 116, 39, 124, 3, 24,
+ 220, 156, 79, 97, 46, 62, 51, 235, 130, 51, 25, 176, 222, 50, 23,
+ 0, 7, 136, 184, 74, 39, 184, 169, 12, 174, 6, 96, 164, 77, 96,
+ 244, 209, 102, 46, 24, 220, 220, 213, 48, 23, 159, 138, 237, 59, 25,
+ 51, 172, 183, 204, 5, 192, 72, 171, 146, 224, 155, 198, 224, 106, 1,
+ 70, 90, 196, 77, 112, 130, 171, 101, 112, 9, 192, 72, 139, 186, 143,
+ 125, 179, 151, 129, 48, 184, 104, 7, 181, 34, 110, 186, 19, 92, 172,
+ 111, 207, 218, 91, 17, 87, 101, 39, 195, 79, 40, 47, 216, 211, 14,
+ 212, 22, 44, 55, 215, 11, 246, 111, 166, 85, 143, 177, 44, 231, 202,
+ 99, 133, 112, 253, 104, 190, 200, 155, 248, 19, 237, 225, 75, 230, 254,
+ 182, 221, 189, 96, 189, 4, 67, 92, 128, 40, 136, 167, 39, 87, 224,
+ 54, 241, 128, 127, 21, 61, 204, 190, 5, 255, 18, 230, 69, 146, 180,
+ 211, 17, 36, 189, 113, 71, 98, 92, 25, 41, 92, 217, 43, 160, 207,
+ 112, 41, 253, 158, 40, 148, 31, 63, 81, 96, 127, 211, 80, 167, 161,
+ 76, 99, 231, 139, 60, 89, 153, 114, 62, 139, 52, 3, 67, 90, 225,
+ 255, 133, 78, 173, 141, 28, 58, 180, 230, 65, 122, 159, 183, 63, 61,
+ 208, 212, 137, 32, 228, 56, 240, 188, 138, 244, 252, 213, 73, 153, 60,
+ 182, 206, 9, 158, 170, 56, 20, 121, 19, 205, 153, 120, 47, 147, 201,
+ 158, 118, 9, 71, 231, 8, 231, 133, 206, 145, 102, 169, 217, 7, 82,
+ 91, 128, 107, 156, 174, 133, 156, 243, 48, 55, 231, 223, 208, 220, 48,
+ 115, 240, 135, 7, 51, 72, 226, 189, 201, 131, 153, 35, 79, 243, 85,
+ 80, 144, 209, 203, 139, 43, 128, 189, 243, 224, 54, 42, 172, 115, 36,
+ 216, 102, 152, 163, 236, 79, 204, 195, 155, 0, 115, 164, 93, 6, 250,
+ 5, 87, 118, 201, 103, 10, 188, 176, 191, 26, 232, 36, 150, 69, 216,
+ 205, 81, 1, 6, 46, 139, 113, 67, 203, 94, 173, 85, 61, 90, 118,
+ 107, 219, 210, 86, 220, 193, 33, 253, 35, 71, 15, 30, 59, 42, 38,
+ 62, 57, 73, 21, 29, 63, 68, 213, 61, 38, 57, 57, 46, 126, 88,
+ 82, 255, 68, 184, 139, 30, 57, 178, 127, 100, 76, 210, 136, 228, 209,
+ 9, 253, 7, 38, 140, 29, 52, 50, 46, 41, 54, 38, 177, 97, 66,
+ 98, 204, 200, 209, 209, 67, 98, 18, 251, 147, 255, 109, 127, 133, 48,
+ 88, 131, 43, 150, 176, 211, 110, 213, 38, 170, 67, 168, 55, 22, 29,
+ 74, 5, 219, 181, 220, 188, 198, 81, 143, 88, 27, 153, 243, 61, 232,
+ 16, 92, 185, 103, 30, 43, 30, 194, 181, 58, 180, 132, 198, 190, 205,
+ 242, 166, 162, 14, 101, 43, 90, 234, 13, 160, 239, 6, 122, 223, 142,
+ 139, 202, 162, 240, 1, 16, 205, 3, 26, 190, 233, 97, 123, 95, 142,
+ 179, 222, 251, 138, 245, 94, 176, 30, 64, 123, 184, 44, 197, 89, 5,
+ 106, 209, 82, 70, 135, 210, 39, 152, 215, 121, 218, 216, 86, 196, 8,
+ 48, 94, 250, 197, 96, 167, 182, 64, 63, 114, 31, 40, 240, 194, 254,
+ 206, 3, 94, 88, 30, 78, 237, 240, 34, 115, 223, 204, 205, 233, 121,
+ 39, 235, 212, 85, 153, 30, 175, 139, 133, 159, 25, 205, 101, 121, 166,
+ 23, 254, 128, 94, 131, 101, 175, 59, 158, 15, 170, 61, 212, 32, 143,
+ 157, 159, 93, 85, 219, 227, 54, 56, 242, 155, 67, 153, 177, 74, 165,
+ 67, 158, 23, 63, 51, 210, 251, 195, 241, 190, 17, 185, 117, 210, 52,
+ 246, 114, 125, 81, 106, 155, 70, 33, 174, 47, 142, 185, 170, 192, 60,
+ 16, 226, 19, 129, 248, 103, 78, 159, 134, 161, 124, 214, 170, 125, 211,
+ 118, 124, 159, 210, 133, 52, 179, 222, 25, 8, 124, 141, 141, 115, 158,
+ 24, 194, 219, 69, 157, 228, 209, 126, 13, 228, 134, 113, 120, 61, 48,
+ 157, 86, 60, 55, 157, 19, 148, 177, 52, 211, 142, 106, 177, 121, 14,
+ 112, 126, 106, 136, 247, 97, 18, 123, 2, 176, 20, 116, 60, 248, 246,
+ 138, 213, 150, 88, 51, 77, 156, 75, 106, 191, 181, 31, 67, 236, 0,
+ 124, 164, 236, 247, 212, 217, 51, 91, 133, 188, 120, 63, 114, 205, 179,
+ 174, 135, 59, 191, 188, 252, 198, 237, 183, 66, 88, 103, 10, 187, 21,
+ 103, 107, 191, 179, 21, 102, 57, 223, 161, 190, 27, 116, 21, 251, 80,
+ 24, 109, 88, 235, 78, 173, 91, 245, 80, 181, 143, 106, 217, 182, 181,
+ 61, 117, 57, 17, 255, 20, 215, 29, 56, 212, 113, 42, 157, 55, 252,
+ 171, 66, 62, 81, 212, 130, 207, 108, 248, 204, 129, 207, 199, 240, 57,
+ 11, 40, 94, 1, 77, 49, 143, 79, 20, 175, 160, 172, 152, 71, 37,
+ 82, 139, 236, 80, 108, 82, 148, 129, 242, 101, 138, 115, 92, 25, 146,
+ 24, 61, 104, 80, 92, 114, 191, 192, 1, 254, 201, 195, 162, 255, 11,
+ 118, 171, 149, 172, 157, 142, 154, 168, 178, 96, 56, 55, 214, 137, 49,
+ 73, 49, 209, 137, 131, 99, 95, 199, 106, 255, 255, 222, 127, 171, 167,
+ 48, 107, 174, 73, 252, 115, 151, 46, 231, 241, 99, 133, 242, 122, 7,
+ 66, 125, 54, 234, 53, 235, 179, 81, 231, 89, 159, 221, 144, 250, 236,
+ 54, 237, 59, 181, 38, 221, 222, 177, 153, 139, 16, 9, 103, 156, 135,
+ 177, 32, 20, 242, 31, 52, 50, 38, 126, 72, 255, 30, 49, 19, 146,
+ 251, 147, 193, 201, 253, 253, 253, 243, 237, 212, 19, 7, 37, 155, 121,
+ 55, 28, 26, 23, 31, 61, 210, 220, 66, 62, 248, 121, 139, 159, 211,
+ 37, 34, 28, 139, 207, 78, 181, 250, 108, 60, 243, 64, 31, 142, 126,
+ 26, 227, 120, 26, 251, 11, 182, 254, 212, 99, 5, 94, 169, 39, 204,
+ 215, 244, 65, 213, 29, 252, 193, 149, 203, 39, 194, 237, 203, 70, 151,
+ 244, 216, 199, 250, 56, 243, 165, 231, 15, 139, 14, 1, 125, 116, 79,
+ 240, 201, 236, 61, 250, 108, 122, 239, 43, 214, 23, 34, 133, 65, 198,
+ 130, 5, 213, 10, 181, 2, 99, 243, 170, 30, 142, 113, 95, 234, 229,
+ 246, 2, 172, 252, 50, 146, 228, 108, 134, 125, 220, 122, 216, 115, 173,
+ 123, 162, 192, 11, 251, 187, 10, 117, 10, 202, 35, 169, 109, 223, 108,
+ 238, 91, 65, 7, 123, 76, 63, 171, 100, 17, 253, 120, 176, 197, 15,
+ 15, 16, 141, 51, 255, 235, 248, 167, 86, 216, 126, 186, 250, 11, 200,
+ 137, 197, 246, 45, 126, 25, 73, 110, 153, 238, 155, 80, 58, 148, 183,
+ 143, 40, 99, 107, 122, 46, 179, 9, 246, 155, 112, 95, 136, 234, 255,
+ 72, 115, 28, 94, 195, 66, 13, 222, 20, 46, 244, 165, 56, 211, 37,
+ 224, 234, 6, 87, 15, 113, 230, 75, 136, 88, 219, 57, 199, 51, 170,
+ 253, 34, 127, 158, 238, 65, 191, 2, 31, 2, 109, 217, 118, 163, 116,
+ 4, 240, 62, 112, 230, 244, 60, 158, 222, 3, 166, 145, 250, 82, 37,
+ 213, 101, 206, 220, 214, 100, 177, 29, 37, 177, 222, 151, 16, 235, 11,
+ 95, 172, 30, 134, 23, 209, 13, 111, 67, 200, 164, 72, 54, 214, 116,
+ 246, 167, 187, 19, 239, 229, 107, 185, 235, 18, 225, 112, 208, 198, 200,
+ 70, 227, 51, 236, 3, 141, 207, 2, 54, 66, 252, 182, 201, 188, 143,
+ 29, 245, 21, 207, 115, 85, 234, 31, 152, 244, 110, 93, 161, 31, 21,
+ 51, 235, 242, 95, 230, 244, 9, 111, 22, 192, 11, 177, 144, 222, 231,
+ 189, 125, 199, 134, 167, 240, 75, 126, 255, 64, 208, 231, 175, 30, 53,
+ 81, 199, 214, 62, 23, 94, 179, 227, 68, 53, 234, 238, 72, 160, 71,
+ 154, 239, 139, 188, 39, 232, 246, 163, 202, 245, 15, 108, 6, 250, 163,
+ 64, 131, 247, 200, 183, 41, 240, 90, 38, 210, 31, 27, 176, 40, 235,
+ 210, 225, 209, 225, 115, 47, 61, 56, 128, 244, 31, 172, 127, 24, 126,
+ 233, 238, 172, 125, 101, 70, 111, 222, 139, 245, 143, 87, 255, 24, 126,
+ 134, 251, 58, 244, 234, 209, 195, 33, 120, 255, 113, 11, 213, 222, 160,
+ 152, 19, 225, 57, 77, 139, 238, 193, 251, 171, 17, 183, 194, 180, 237,
+ 106, 135, 125, 219, 198, 180, 7, 233, 115, 107, 47, 209, 68, 62, 152,
+ 161, 169, 179, 249, 8, 78, 27, 25, 224, 121, 41, 107, 199, 172, 66,
+ 252, 139, 199, 126, 194, 78, 37, 98, 232, 23, 135, 75, 239, 216, 219,
+ 170, 222, 166, 130, 135, 216, 246, 231, 137, 237, 247, 122, 233, 207, 63,
+ 233, 85, 221, 208, 177, 233, 196, 172, 115, 15, 167, 103, 125, 49, 255,
+ 184, 134, 106, 16, 27, 159, 153, 255, 204, 241, 153, 48, 87, 16, 159,
+ 1, 47, 245, 149, 195, 163, 15, 64, 95, 108, 214, 58, 198, 103, 126,
+ 220, 82, 14, 47, 155, 89, 113, 50, 151, 212, 158, 227, 156, 80, 123,
+ 142, 107, 21, 231, 139, 181, 231, 133, 109, 236, 185, 157, 189, 12, 249,
+ 119, 111, 174, 44, 246, 60, 32, 40, 223, 182, 156, 181, 231, 174, 246,
+ 96, 24, 7, 226, 56, 190, 195, 204, 31, 142, 49, 142, 99, 183, 214,
+ 218, 78, 45, 91, 181, 118, 26, 8, 122, 137, 248, 213, 185, 193, 240,
+ 81, 149, 169, 41, 98, 23, 7, 190, 226, 204, 113, 224, 43, 206, 28,
+ 7, 190, 226, 254, 230, 204, 113, 96, 83, 197, 43, 14, 227, 192, 166,
+ 10, 140, 3, 253, 132, 248, 239, 21, 241, 84, 188, 32, 52, 14, 12,
+ 246, 31, 158, 48, 204, 226, 66, 251, 39, 131, 243, 28, 155, 24, 211,
+ 31, 43, 243, 24, 168, 228, 121, 46, 36, 116, 133, 138, 64, 250, 19,
+ 27, 246, 46, 113, 95, 59, 14, 252, 87, 247, 223, 230, 239, 77, 247,
+ 63, 191, 113, 96, 238, 163, 199, 138, 156, 180, 54, 150, 152, 5, 227,
+ 148, 14, 236, 243, 155, 84, 235, 249, 39, 158, 83, 101, 139, 231, 244,
+ 169, 71, 33, 86, 193, 235, 176, 249, 122, 83, 49, 75, 63, 15, 243,
+ 57, 2, 123, 63, 154, 185, 79, 16, 235, 139, 128, 55, 134, 29, 28,
+ 68, 44, 227, 132, 243, 196, 43, 156, 227, 121, 162, 242, 120, 123, 146,
+ 134, 48, 92, 1, 235, 32, 254, 74, 131, 190, 116, 125, 166, 80, 142,
+ 249, 71, 65, 253, 50, 150, 83, 191, 156, 176, 214, 220, 55, 91, 191,
+ 60, 223, 206, 47, 207, 119, 234, 151, 199, 137, 126, 248, 165, 157, 95,
+ 126, 41, 250, 101, 172, 151, 243, 203, 218, 162, 175, 20, 246, 118, 31,
+ 253, 242, 159, 146, 126, 121, 190, 173, 95, 22, 251, 48, 155, 238, 85,
+ 63, 135, 56, 13, 250, 231, 35, 198, 46, 230, 179, 3, 218, 46, 126,
+ 98, 63, 166, 69, 152, 239, 239, 70, 248, 43, 172, 177, 213, 56, 113,
+ 114, 26, 42, 172, 253, 161, 247, 180, 63, 214, 63, 228, 53, 41, 210,
+ 124, 206, 160, 106, 89, 88, 12, 185, 18, 166, 91, 207, 50, 105, 220,
+ 128, 50, 209, 184, 1, 231, 3, 229, 125, 27, 55, 252, 123, 226, 6,
+ 156, 19, 118, 31, 136, 243, 245, 54, 110, 120, 189, 184, 161, 59, 236,
+ 114, 230, 128, 173, 210, 237, 143, 247, 10, 165, 207, 225, 118, 216, 62,
+ 199, 238, 222, 42, 208, 41, 111, 58, 254, 186, 109, 241, 94, 250, 94,
+ 214, 117, 164, 4, 94, 154, 61, 86, 30, 67, 253, 2, 3, 99, 253,
+ 182, 165, 195, 231, 1, 206, 215, 25, 159, 96, 210, 22, 44, 227, 16,
+ 219, 115, 77, 187, 253, 150, 94, 145, 195, 133, 1, 206, 71, 68, 195,
+ 105, 56, 78, 60, 31, 3, 55, 146, 178, 124, 249, 30, 126, 197, 242,
+ 229, 203, 79, 159, 190, 235, 100, 143, 102, 110, 112, 32, 88, 135, 2,
+ 226, 136, 148, 23, 85, 207, 254, 172, 181, 81, 163, 127, 247, 57, 124,
+ 163, 70, 137, 160, 16, 49, 137, 141, 254, 181, 242, 145, 234, 228, 237,
+ 223, 27, 251, 67, 123, 87, 73, 92, 79, 45, 232, 243, 211, 125, 226,
+ 186, 82, 90, 215, 159, 222, 167, 187, 66, 119, 57, 222, 139, 226, 35,
+ 14, 197, 79, 0, 24, 233, 17, 95, 97, 193, 223, 173, 208, 252, 108,
+ 197, 79, 96, 240, 85, 0, 11, 109, 0, 190, 135, 5, 127, 191, 34,
+ 221, 104, 197, 87, 49, 248, 217, 123, 193, 63, 138, 248, 158, 22, 252,
+ 158, 16, 111, 89, 241, 17, 135, 226, 235, 1, 70, 122, 142, 57, 141,
+ 42, 170, 240, 228, 52, 247, 172, 248, 122, 6, 63, 0, 96, 164, 71,
+ 67, 70, 207, 105, 52, 10, 13, 135, 231, 1, 20, 63, 128, 193, 207,
+ 1, 187, 131, 244, 40, 15, 53, 64, 248, 204, 32, 224, 132, 21, 31,
+ 113, 40, 126, 42, 192, 1, 34, 62, 181, 149, 222, 138, 126, 156, 178,
+ 123, 172, 5, 63, 149, 193, 71, 187, 134, 244, 28, 19, 19, 233, 125,
+ 98, 56, 180, 129, 20, 95, 195, 224, 19, 145, 30, 249, 23, 102, 248,
+ 231, 148, 136, 245, 162, 182, 23, 237, 109, 40, 107, 79, 247, 91, 109,
+ 103, 247, 86, 66, 230, 147, 127, 64, 64, 160, 243, 220, 165, 51, 182,
+ 182, 55, 0, 120, 105, 50, 65, 198, 76, 199, 92, 36, 142, 188, 181,
+ 189, 111, 109, 239, 219, 191, 188, 216, 94, 92, 79, 22, 219, 146, 105,
+ 125, 198, 75, 215, 82, 57, 197, 66, 69, 234, 119, 140, 109, 201, 100,
+ 108, 11, 192, 72, 207, 49, 49, 178, 222, 103, 132, 2, 215, 172, 197,
+ 182, 48, 248, 116, 221, 34, 236, 97, 225, 223, 90, 65, 90, 91, 109,
+ 145, 38, 211, 206, 182, 136, 248, 212, 246, 126, 194, 45, 84, 232, 47,
+ 198, 123, 117, 129, 0, 121, 147, 194, 28, 155, 53, 165, 252, 207, 216,
+ 218, 132, 46, 17, 173, 162, 71, 197, 36, 70, 75, 217, 137, 34, 121,
+ 28, 51, 180, 177, 194, 30, 113, 241, 35, 135, 211, 111, 109, 110, 172,
+ 151, 187, 124, 30, 6, 220, 210, 196, 237, 95, 123, 240, 224, 225, 230,
+ 54, 153, 23, 35, 63, 159, 158, 217, 39, 246, 87, 99, 189, 161, 107,
+ 53, 10, 176, 29, 96, 126, 28, 158, 149, 167, 248, 46, 225, 39, 118,
+ 186, 159, 113, 118, 255, 11, 181, 252, 51, 116, 235, 253, 207, 77, 2,
+ 249, 199, 134, 230, 252, 244, 51, 235, 49, 229, 148, 108, 136, 92, 144,
+ 245, 219, 136, 15, 212, 117, 158, 142, 16, 112, 60, 58, 213, 227, 111,
+ 247, 169, 110, 232, 48, 243, 168, 192, 87, 245, 67, 64, 75, 242, 229,
+ 188, 131, 135, 4, 25, 245, 188, 98, 89, 18, 191, 54, 121, 181, 58,
+ 113, 231, 178, 12, 172, 7, 56, 11, 203, 174, 133, 148, 204, 20, 198,
+ 122, 102, 209, 224, 133, 173, 190, 13, 166, 109, 30, 139, 45, 100, 220,
+ 190, 232, 156, 166, 193, 208, 181, 70, 231, 207, 246, 243, 246, 103, 181,
+ 237, 5, 184, 46, 17, 70, 111, 171, 158, 14, 97, 250, 170, 231, 11,
+ 214, 29, 194, 139, 207, 219, 133, 126, 152, 239, 237, 207, 19, 254, 211,
+ 127, 212, 23, 88, 199, 129, 234, 47, 234, 44, 213, 95, 212, 47, 212,
+ 103, 123, 253, 181, 119, 142, 175, 171, 191, 174, 254, 140, 105, 238, 235,
+ 47, 253, 51, 231, 99, 184, 223, 103, 182, 82, 154, 70, 234, 62, 127,
+ 57, 35, 175, 75, 47, 93, 246, 154, 250, 27, 105, 214, 95, 47, 9,
+ 253, 45, 124, 177, 122, 56, 171, 191, 230, 243, 28, 187, 252, 58, 251,
+ 231, 200, 233, 96, 87, 225, 50, 158, 54, 95, 90, 241, 202, 151, 190,
+ 106, 92, 207, 37, 218, 235, 78, 98, 219, 49, 78, 98, 47, 142, 249,
+ 63, 41, 38, 62, 105, 116, 162, 235, 22, 211, 210, 109, 229, 69, 254,
+ 158, 76, 185, 176, 55, 56, 109, 246, 43, 90, 17, 142, 117, 26, 243,
+ 217, 158, 210, 12, 30, 29, 159, 44, 215, 91, 157, 68, 219, 58, 166,
+ 109, 173, 216, 118, 152, 8, 143, 115, 210, 118, 17, 40, 193, 53, 25,
+ 61, 216, 117, 147, 202, 211, 214, 60, 30, 165, 120, 63, 74, 228, 231,
+ 105, 23, 35, 83, 59, 129, 182, 129, 218, 9, 220, 123, 176, 190, 174,
+ 75, 196, 96, 193, 78, 116, 27, 157, 76, 98, 163, 135, 140, 30, 79,
+ 70, 70, 199, 199, 88, 229, 227, 94, 83, 11, 178, 251, 59, 230, 65,
+ 42, 35, 221, 183, 19, 172, 63, 99, 203, 251, 4, 55, 108, 172, 251,
+ 252, 165, 225, 210, 55, 51, 121, 41, 59, 129, 190, 4, 124, 74, 198,
+ 235, 218, 9, 244, 71, 248, 217, 169, 78, 204, 6, 44, 51, 251, 38,
+ 161, 60, 3, 224, 12, 138, 103, 43, 163, 158, 143, 243, 91, 19, 28,
+ 235, 183, 38, 195, 202, 83, 207, 31, 111, 182, 37, 56, 78, 40, 35,
+ 36, 113, 122, 51, 161, 110, 56, 224, 225, 125, 244, 231, 47, 249, 31,
+ 191, 153, 105, 88, 221, 230, 187, 204, 55, 97, 39, 44, 135, 217, 145,
+ 156, 194, 153, 159, 107, 158, 185, 228, 132, 75, 59, 225, 196, 209, 25,
+ 143, 131, 93, 128, 75, 35, 94, 250, 99, 230, 43, 251, 168, 249, 250,
+ 159, 182, 19, 26, 81, 134, 190, 118, 186, 152, 28, 55, 42, 70, 24,
+ 211, 209, 9, 78, 185, 23, 176, 201, 88, 37, 228, 238, 113, 235, 186,
+ 65, 219, 131, 125, 121, 19, 182, 135, 28, 119, 190, 254, 105, 185, 16,
+ 215, 30, 179, 218, 30, 132, 223, 148, 237, 209, 28, 115, 222, 54, 45,
+ 23, 206, 32, 142, 90, 109, 15, 194, 227, 156, 246, 153, 19, 202, 228,
+ 108, 79, 194, 81, 235, 24, 6, 136, 247, 9, 22, 126, 5, 225, 243,
+ 132, 101, 94, 228, 254, 168, 109, 66, 123, 68, 109, 19, 158, 163, 208,
+ 56, 217, 140, 211, 41, 122, 84, 130, 195, 246, 222, 34, 127, 225, 215,
+ 212, 188, 4, 226, 104, 155, 178, 179, 221, 183, 77, 213, 71, 8, 71,
+ 236, 228, 138, 218, 43, 194, 133, 126, 107, 172, 151, 237, 223, 229, 226,
+ 237, 249, 188, 218, 166, 135, 158, 77, 4, 62, 15, 60, 155, 24, 109,
+ 219, 48, 255, 61, 16, 235, 41, 158, 173, 140, 249, 143, 97, 128, 191,
+ 90, 108, 135, 217, 59, 232, 45, 240, 223, 158, 77, 178, 216, 250, 232,
+ 105, 207, 240, 57, 142, 126, 228, 96, 254, 160, 192, 83, 201, 198, 48,
+ 172, 198, 187, 105, 155, 254, 211, 49, 183, 198, 189, 24, 28, 117, 214,
+ 178, 135, 252, 57, 222, 11, 245, 217, 65, 127, 131, 254, 93, 250, 11,
+ 253, 104, 138, 250, 241, 58, 250, 251, 208, 115, 199, 6, 212, 223, 203,
+ 197, 79, 240, 121, 209, 223, 25, 237, 99, 26, 163, 110, 90, 245, 87,
+ 111, 4, 95, 217, 152, 35, 250, 47, 241, 110, 26, 212, 163, 14, 83,
+ 253, 181, 149, 49, 255, 250, 11, 252, 97, 22, 244, 89, 230, 79, 179,
+ 158, 66, 251, 65, 84, 95, 5, 253, 109, 50, 106, 29, 171, 191, 170,
+ 191, 191, 108, 252, 127, 93, 127, 81, 103, 169, 254, 226, 57, 57, 234,
+ 179, 131, 254, 6, 255, 235, 236, 47, 62, 131, 109, 246, 58, 250, 91,
+ 109, 153, 234, 75, 179, 254, 182, 215, 228, 209, 254, 26, 103, 180, 191,
+ 217, 152, 234, 111, 156, 95, 181, 29, 168, 195, 189, 43, 95, 255, 146,
+ 218, 229, 105, 80, 207, 216, 95, 70, 198, 55, 98, 127, 179, 98, 253,
+ 170, 101, 60, 16, 237, 44, 200, 34, 232, 243, 116, 225, 147, 234, 239,
+ 61, 59, 253, 173, 211, 228, 255, 186, 254, 162, 206, 82, 253, 197, 179,
+ 61, 212, 103, 7, 253, 109, 252, 111, 179, 191, 154, 93, 168, 31, 175,
+ 163, 191, 165, 238, 124, 42, 232, 239, 245, 83, 75, 242, 164, 191, 69,
+ 166, 164, 239, 64, 29, 102, 236, 175, 166, 248, 242, 167, 59, 106, 30,
+ 208, 109, 20, 198, 2, 234, 177, 206, 106, 127, 89, 25, 243, 175, 191,
+ 208, 62, 238, 125, 212, 230, 79, 97, 189, 100, 21, 91, 254, 212, 162,
+ 207, 168, 191, 153, 125, 163, 215, 179, 250, 187, 69, 149, 186, 227, 255,
+ 186, 254, 162, 206, 90, 246, 230, 223, 197, 123, 161, 62, 91, 113, 180,
+ 184, 25, 119, 8, 32, 94, 119, 111, 142, 252, 241, 51, 189, 175, 163,
+ 254, 170, 90, 185, 175, 191, 251, 163, 106, 26, 157, 237, 205, 67, 151,
+ 253, 206, 31, 26, 30, 166, 153, 251, 233, 217, 64, 115, 110, 203, 155,
+ 59, 195, 91, 253, 209, 23, 161, 108, 205, 18, 239, 241, 181, 214, 246,
+ 226, 248, 221, 27, 75, 218, 12, 14, 150, 9, 243, 173, 226, 248, 195,
+ 32, 75, 212, 142, 206, 25, 206, 228, 168, 51, 233, 97, 45, 44, 11,
+ 168, 249, 113, 144, 179, 54, 71, 125, 62, 189, 49, 244, 81, 83, 207,
+ 114, 6, 157, 63, 122, 235, 25, 158, 243, 189, 249, 235, 156, 225, 105,
+ 192, 87, 227, 69, 46, 154, 47, 227, 121, 243, 149, 125, 206, 124, 253,
+ 39, 246, 230, 216, 190, 253, 222, 60, 33, 113, 244, 176, 196, 152, 164,
+ 36, 210, 173, 75, 219, 110, 173, 187, 119, 183, 223, 164, 43, 236, 78,
+ 212, 71, 26, 109, 247, 230, 216, 23, 251, 189, 121, 97, 225, 59, 14,
+ 156, 219, 123, 115, 205, 5, 24, 139, 11, 206, 247, 199, 180, 92, 56,
+ 23, 60, 111, 222, 31, 71, 138, 52, 67, 152, 118, 45, 253, 200, 199,
+ 115, 50, 173, 216, 134, 179, 61, 191, 135, 216, 31, 15, 55, 247, 252,
+ 26, 224, 163, 63, 239, 188, 79, 180, 92, 216, 243, 159, 51, 247, 201,
+ 83, 164, 25, 70, 207, 33, 71, 62, 86, 88, 206, 2, 206, 229, 243,
+ 44, 224, 156, 221, 89, 192, 57, 219, 179, 128, 188, 140, 159, 229, 44,
+ 224, 59, 102, 47, 117, 15, 250, 122, 209, 153, 45, 12, 126, 35, 182,
+ 208, 229, 179, 186, 150, 238, 219, 66, 214, 230, 73, 157, 95, 162, 77,
+ 162, 87, 222, 158, 251, 56, 191, 119, 198, 199, 85, 153, 173, 140, 255,
+ 162, 231, 113, 130, 45, 116, 244, 229, 249, 121, 158, 241, 95, 221, 75,
+ 221, 99, 246, 82, 119, 226, 189, 168, 191, 181, 209, 223, 160, 55, 171,
+ 191, 105, 203, 28, 159, 39, 235, 195, 229, 245, 87, 43, 202, 198, 230,
+ 31, 190, 206, 89, 150, 251, 190, 220, 158, 159, 251, 101, 182, 50, 254,
+ 139, 158, 199, 17, 231, 250, 75, 99, 81, 169, 231, 201, 158, 132, 227,
+ 200, 127, 237, 207, 185, 47, 247, 100, 116, 130, 179, 223, 99, 221, 177,
+ 234, 53, 230, 102, 161, 158, 91, 245, 58, 105, 68, 204, 200, 152, 228,
+ 209, 241, 206, 99, 212, 242, 175, 251, 252, 104, 145, 173, 94, 167, 105,
+ 99, 189, 84, 49, 238, 191, 91, 3, 159, 19, 105, 27, 249, 105, 204,
+ 207, 137, 24, 191, 101, 83, 238, 252, 249, 17, 158, 109, 37, 78, 111,
+ 22, 156, 215, 51, 174, 56, 225, 185, 142, 158, 55, 63, 231, 17, 238,
+ 51, 146, 129, 15, 251, 60, 8, 203, 226, 196, 231, 63, 125, 156, 202,
+ 98, 253, 91, 244, 109, 187, 218, 66, 140, 89, 104, 209, 54, 103, 109,
+ 142, 9, 110, 152, 9, 244, 70, 160, 55, 188, 145, 231, 71, 222, 249,
+ 124, 126, 228, 132, 101, 78, 54, 196, 5, 112, 229, 220, 6, 157, 185,
+ 21, 239, 149, 246, 27, 92, 55, 224, 186, 14, 215, 63, 255, 153, 24,
+ 21, 101, 160, 49, 42, 202, 130, 117, 227, 163, 71, 142, 16, 158, 85,
+ 36, 71, 39, 38, 11, 128, 109, 144, 106, 126, 126, 116, 220, 178, 63,
+ 247, 249, 206, 26, 239, 104, 68, 62, 108, 220, 139, 109, 196, 13, 129,
+ 133, 224, 200, 202, 41, 79, 164, 91, 149, 109, 27, 247, 226, 24, 209,
+ 184, 87, 119, 219, 126, 108, 204, 45, 13, 141, 75, 76, 74, 30, 154,
+ 24, 13, 173, 72, 70, 192, 1, 217, 206, 99, 68, 90, 46, 124, 135,
+ 245, 55, 115, 140, 216, 73, 108, 203, 18, 111, 223, 50, 207, 149, 167,
+ 101, 54, 205, 237, 226, 120, 13, 141, 139, 199, 175, 6, 136, 78, 218,
+ 182, 117, 61, 208, 169, 110, 59, 111, 151, 150, 11, 246, 227, 166, 185,
+ 221, 88, 145, 102, 160, 88, 78, 23, 182, 227, 188, 216, 245, 141, 96,
+ 180, 217, 180, 185, 148, 86, 52, 49, 35, 184, 140, 201, 59, 137, 253,
+ 100, 247, 24, 58, 177, 207, 236, 243, 63, 156, 79, 75, 159, 157, 140,
+ 182, 234, 119, 216, 99, 252, 46, 177, 199, 248, 157, 25, 235, 27, 214,
+ 62, 35, 141, 125, 159, 45, 122, 35, 21, 143, 202, 172, 132, 38, 1,
+ 238, 237, 67, 112, 206, 99, 153, 121, 176, 213, 45, 15, 203, 157, 91,
+ 121, 15, 191, 57, 246, 219, 135, 41, 23, 250, 13, 107, 60, 247, 42,
+ 236, 69, 175, 89, 159, 127, 98, 187, 84, 6, 213, 77, 179, 61, 176,
+ 202, 160, 176, 145, 33, 72, 46, 246, 185, 233, 40, 131, 55, 83, 46,
+ 60, 83, 52, 1, 124, 213, 218, 190, 138, 105, 31, 231, 37, 231, 166,
+ 115, 27, 132, 237, 7, 190, 230, 126, 15, 249, 178, 251, 61, 149, 216,
+ 134, 121, 191, 231, 109, 25, 233, 228, 241, 113, 201, 131, 99, 3, 73,
+ 108, 220, 224, 88, 212, 1, 123, 126, 74, 224, 163, 189, 225, 216, 71,
+ 21, 250, 234, 27, 204, 154, 122, 9, 122, 248, 10, 238, 225, 83, 245,
+ 34, 222, 75, 243, 60, 222, 75, 247, 12, 246, 79, 79, 205, 54, 150,
+ 234, 36, 242, 163, 123, 193, 156, 62, 214, 189, 32, 206, 19, 221, 11,
+ 226, 92, 177, 90, 33, 124, 183, 107, 244, 184, 152, 161, 163, 19, 199,
+ 71, 39, 14, 33, 206, 182, 133, 154, 235, 182, 123, 65, 188, 79, 96,
+ 250, 95, 134, 212, 204, 211, 24, 134, 137, 114, 80, 153, 80, 135, 210,
+ 196, 54, 138, 139, 23, 218, 9, 146, 28, 147, 0, 251, 212, 184, 209,
+ 241, 32, 150, 221, 100, 233, 174, 89, 101, 10, 19, 239, 135, 83, 31,
+ 32, 126, 175, 45, 47, 114, 217, 203, 135, 50, 89, 246, 207, 162, 142,
+ 211, 157, 47, 94, 184, 158, 5, 25, 99, 146, 98, 146, 5, 192, 172,
+ 86, 84, 169, 19, 174, 218, 218, 126, 188, 143, 183, 219, 7, 200, 217,
+ 194, 134, 1, 254, 104, 8, 253, 131, 131, 228, 229, 37, 140, 188, 184,
+ 38, 114, 175, 218, 142, 103, 82, 92, 50, 113, 181, 229, 79, 205, 177,
+ 29, 79, 188, 183, 140, 167, 206, 60, 158, 193, 194, 219, 72, 95, 111,
+ 60, 81, 38, 42, 159, 160, 203, 87, 29, 199, 19, 101, 180, 172, 79,
+ 187, 9, 15, 48, 217, 142, 39, 222, 219, 143, 167, 197, 206, 198, 153,
+ 71, 211, 126, 68, 97, 60, 155, 187, 43, 47, 202, 56, 142, 89, 127,
+ 233, 38, 58, 158, 156, 48, 158, 160, 151, 193, 46, 247, 95, 175, 108,
+ 199, 19, 239, 233, 120, 166, 142, 123, 172, 240, 16, 96, 249, 112, 55,
+ 72, 66, 62, 148, 201, 162, 159, 212, 62, 216, 202, 231, 250, 124, 231,
+ 165, 173, 124, 120, 79, 229, 11, 8, 115, 95, 190, 210, 82, 250, 200,
+ 200, 135, 54, 43, 231, 165, 131, 124, 46, 205, 111, 234, 11, 59, 125,
+ 124, 97, 149, 47, 61, 144, 202, 231, 245, 218, 242, 161, 76, 84, 62,
+ 180, 167, 196, 81, 62, 151, 238, 41, 253, 185, 173, 124, 120, 79, 229,
+ 83, 109, 116, 127, 252, 138, 75, 200, 135, 50, 81, 249, 208, 214, 171,
+ 94, 56, 200, 215, 216, 229, 254, 234, 153, 173, 124, 120, 79, 229, 211,
+ 125, 234, 190, 124, 133, 37, 228, 67, 153, 168, 124, 232, 135, 52, 207,
+ 29, 228, 107, 226, 138, 111, 238, 83, 91, 249, 240, 158, 202, 151, 179,
+ 208, 253, 249, 149, 146, 15, 101, 162, 242, 161, 143, 212, 61, 115, 144,
+ 175, 169, 43, 190, 74, 59, 249, 148, 140, 124, 233, 183, 168, 124, 133,
+ 100, 229, 43, 47, 33, 31, 202, 196, 158, 207, 234, 159, 58, 200, 215,
+ 204, 229, 25, 230, 63, 182, 242, 225, 61, 149, 47, 247, 35, 247, 231,
+ 183, 138, 19, 249, 210, 112, 126, 159, 196, 123, 77, 167, 246, 234, 177,
+ 109, 140, 130, 47, 132, 75, 154, 173, 52, 12, 104, 84, 215, 80, 253,
+ 131, 249, 65, 182, 123, 51, 199, 253, 179, 231, 129, 78, 1, 243, 74,
+ 198, 212, 194, 187, 196, 71, 211, 131, 241, 187, 11, 21, 227, 183, 172,
+ 199, 251, 23, 203, 18, 214, 255, 176, 96, 81, 45, 74, 151, 8, 124,
+ 251, 1, 223, 122, 34, 223, 132, 152, 145, 227, 226, 146, 228, 109, 118,
+ 154, 40, 39, 149, 217, 248, 8, 230, 252, 137, 85, 110, 47, 79, 233,
+ 115, 146, 225, 175, 82, 248, 249, 179, 84, 33, 126, 29, 190, 10, 169,
+ 164, 250, 53, 116, 199, 211, 20, 126, 77, 205, 129, 97, 245, 14, 212,
+ 21, 190, 171, 238, 229, 59, 112, 127, 14, 148, 77, 189, 176, 70, 248,
+ 174, 249, 254, 115, 245, 66, 239, 4, 127, 186, 119, 191, 201, 252, 221,
+ 245, 65, 89, 115, 50, 218, 77, 43, 210, 184, 66, 185, 194, 130, 204,
+ 67, 99, 70, 141, 77, 244, 135, 189, 69, 178, 188, 204, 40, 39, 149,
+ 57, 247, 97, 188, 23, 59, 214, 174, 100, 254, 12, 218, 206, 44, 22,
+ 186, 111, 194, 217, 81, 33, 171, 74, 157, 223, 59, 23, 238, 79, 143,
+ 234, 185, 111, 198, 194, 187, 194, 247, 227, 223, 221, 223, 35, 116, 49,
+ 244, 43, 182, 246, 62, 161, 15, 95, 23, 248, 43, 164, 247, 227, 189,
+ 161, 63, 188, 50, 203, 92, 235, 66, 98, 198, 199, 77, 67, 50, 195,
+ 238, 238, 17, 100, 78, 142, 27, 20, 23, 237, 166, 204, 40, 39, 149,
+ 89, 5, 48, 246, 193, 29, 153, 191, 130, 182, 115, 175, 105, 67, 74,
+ 239, 138, 10, 137, 243, 57, 27, 186, 239, 89, 10, 191, 80, 217, 57,
+ 172, 100, 204, 105, 65, 230, 210, 5, 59, 239, 199, 178, 221, 13, 190,
+ 23, 198, 121, 112, 193, 111, 67, 248, 37, 223, 238, 61, 47, 142, 243,
+ 246, 6, 199, 130, 134, 110, 73, 207, 56, 197, 63, 51, 203, 28, 157,
+ 152, 52, 54, 201, 181, 208, 84, 102, 21, 35, 179, 246, 1, 196, 71,
+ 15, 221, 147, 249, 224, 243, 20, 126, 99, 196, 201, 61, 186, 97, 123,
+ 247, 234, 238, 53, 223, 239, 253, 87, 10, 175, 184, 181, 123, 127, 212,
+ 227, 16, 225, 121, 229, 202, 187, 187, 195, 218, 66, 89, 239, 243, 45,
+ 133, 62, 248, 126, 223, 98, 95, 197, 175, 187, 133, 236, 22, 101, 62,
+ 186, 46, 36, 176, 207, 39, 202, 192, 67, 185, 251, 133, 179, 249, 81,
+ 49, 201, 209, 114, 114, 91, 222, 197, 248, 192, 42, 179, 254, 111, 240,
+ 1, 110, 202, 236, 108, 13, 22, 43, 181, 122, 187, 49, 178, 189, 16,
+ 16, 7, 63, 235, 45, 172, 65, 221, 237, 87, 194, 26, 60, 247, 243,
+ 246, 218, 247, 31, 159, 89, 79, 233, 74, 54, 59, 158, 113, 186, 192,
+ 209, 237, 154, 155, 61, 132, 117, 57, 114, 236, 168, 65, 209, 137, 238,
+ 173, 65, 148, 147, 202, 156, 126, 31, 246, 55, 15, 94, 95, 230, 247,
+ 54, 181, 202, 24, 55, 38, 184, 54, 222, 253, 82, 96, 181, 48, 126,
+ 217, 33, 53, 4, 153, 149, 15, 252, 191, 120, 117, 226, 75, 139, 204,
+ 115, 171, 182, 200, 168, 115, 236, 122, 70, 234, 137, 80, 65, 230, 228,
+ 216, 209, 137, 209, 19, 220, 147, 25, 229, 164, 50, 231, 228, 194, 190,
+ 234, 239, 215, 151, 185, 235, 160, 105, 25, 161, 187, 102, 9, 50, 159,
+ 173, 91, 93, 144, 153, 12, 60, 33, 188, 166, 108, 237, 198, 102, 27,
+ 114, 219, 101, 91, 108, 93, 181, 58, 75, 130, 118, 39, 148, 201, 56,
+ 253, 219, 118, 33, 15, 61, 58, 121, 100, 180, 220, 195, 52, 42, 51,
+ 202, 105, 209, 231, 170, 177, 94, 216, 7, 70, 102, 165, 187, 50, 163,
+ 30, 244, 251, 114, 94, 80, 179, 47, 139, 9, 227, 250, 237, 170, 221,
+ 194, 243, 244, 250, 57, 105, 27, 240, 254, 201, 241, 254, 27, 2, 254,
+ 46, 93, 147, 210, 205, 78, 90, 147, 241, 211, 59, 5, 27, 71, 206,
+ 230, 4, 153, 7, 39, 70, 199, 199, 141, 29, 229, 150, 204, 40, 167,
+ 69, 159, 171, 196, 122, 97, 31, 94, 119, 156, 79, 70, 85, 220, 238,
+ 125, 171, 136, 16, 163, 29, 110, 84, 172, 49, 150, 149, 93, 244, 129,
+ 112, 223, 33, 180, 238, 182, 57, 202, 140, 109, 156, 72, 119, 196, 187,
+ 110, 70, 192, 215, 21, 131, 125, 118, 157, 222, 142, 120, 49, 209, 114,
+ 214, 153, 209, 231, 42, 86, 153, 211, 43, 199, 122, 97, 31, 220, 145,
+ 249, 200, 31, 41, 60, 247, 217, 151, 33, 190, 201, 203, 246, 30, 83,
+ 158, 218, 223, 126, 107, 10, 255, 147, 71, 199, 3, 79, 90, 148, 22,
+ 236, 198, 242, 151, 29, 194, 213, 80, 54, 255, 157, 6, 194, 125, 245,
+ 37, 149, 246, 133, 158, 172, 177, 111, 181, 104, 55, 86, 53, 90, 16,
+ 124, 225, 114, 151, 224, 117, 69, 218, 10, 231, 203, 177, 99, 71, 197,
+ 36, 202, 24, 59, 139, 62, 87, 182, 202, 156, 83, 41, 214, 11, 251,
+ 224, 142, 204, 107, 110, 167, 240, 87, 27, 165, 238, 171, 176, 238, 242,
+ 222, 125, 250, 239, 195, 202, 111, 76, 225, 183, 79, 238, 22, 254, 145,
+ 161, 163, 32, 227, 157, 119, 187, 29, 184, 187, 62, 133, 63, 247, 97,
+ 9, 225, 29, 42, 153, 131, 226, 246, 29, 219, 87, 44, 172, 252, 75,
+ 179, 204, 119, 213, 33, 25, 218, 235, 189, 130, 55, 221, 231, 5, 29,
+ 26, 59, 50, 94, 206, 165, 88, 245, 185, 146, 85, 102, 37, 192, 216,
+ 7, 119, 100, 238, 15, 62, 37, 56, 76, 21, 114, 48, 236, 241, 222,
+ 223, 110, 253, 18, 58, 1, 252, 244, 142, 159, 223, 13, 27, 115, 116,
+ 156, 32, 115, 231, 251, 239, 238, 191, 14, 101, 185, 57, 171, 4, 159,
+ 178, 98, 235, 216, 125, 199, 23, 173, 221, 59, 89, 28, 103, 245, 189,
+ 78, 25, 151, 135, 254, 180, 93, 105, 200, 10, 16, 244, 57, 58, 49,
+ 193, 93, 159, 162, 100, 100, 214, 84, 4, 125, 174, 228, 158, 204, 187,
+ 115, 83, 248, 132, 65, 53, 246, 104, 31, 166, 135, 4, 206, 75, 223,
+ 127, 237, 80, 10, 95, 126, 90, 192, 129, 49, 19, 2, 4, 95, 221,
+ 124, 106, 64, 120, 213, 195, 16, 111, 92, 58, 36, 188, 203, 166, 64,
+ 191, 192, 208, 19, 23, 102, 182, 56, 36, 202, 124, 175, 76, 227, 237,
+ 11, 78, 126, 26, 212, 237, 214, 150, 237, 212, 167, 200, 201, 77, 101,
+ 70, 57, 169, 204, 9, 21, 98, 189, 148, 110, 202, 236, 204, 110, 164,
+ 156, 43, 24, 252, 119, 61, 95, 97, 205, 253, 120, 83, 41, 204, 249,
+ 239, 138, 115, 219, 241, 190, 232, 158, 141, 219, 127, 234, 153, 20, 72,
+ 215, 224, 170, 155, 126, 65, 233, 23, 210, 50, 14, 55, 127, 25, 68,
+ 215, 96, 98, 220, 176, 88, 119, 116, 3, 229, 164, 50, 167, 149, 143,
+ 245, 194, 62, 184, 35, 243, 47, 176, 6, 189, 27, 71, 182, 240, 235,
+ 144, 30, 82, 217, 120, 114, 255, 68, 88, 111, 107, 182, 118, 56, 176,
+ 255, 162, 121, 156, 215, 165, 119, 8, 207, 128, 178, 230, 161, 159, 183,
+ 16, 124, 76, 90, 163, 208, 0, 159, 223, 247, 208, 113, 78, 232, 241,
+ 65, 112, 246, 186, 61, 193, 95, 126, 29, 97, 179, 6, 93, 201, 77,
+ 101, 70, 57, 169, 204, 217, 190, 177, 94, 216, 7, 119, 100, 174, 126,
+ 39, 133, 95, 31, 172, 15, 125, 191, 251, 223, 33, 247, 87, 100, 135,
+ 205, 255, 42, 133, 239, 180, 76, 27, 126, 199, 63, 70, 144, 249, 193,
+ 68, 237, 129, 87, 95, 166, 240, 95, 100, 112, 194, 54, 59, 35, 42,
+ 37, 244, 227, 208, 151, 251, 62, 16, 215, 160, 255, 239, 253, 130, 139,
+ 254, 84, 47, 35, 123, 246, 141, 0, 203, 26, 148, 25, 104, 203, 187,
+ 251, 125, 173, 50, 19, 128, 177, 15, 238, 200, 220, 9, 214, 160, 41,
+ 116, 102, 200, 210, 220, 59, 45, 166, 14, 185, 29, 218, 3, 214, 219,
+ 161, 161, 113, 97, 27, 106, 14, 19, 98, 162, 164, 129, 113, 251, 155,
+ 65, 153, 97, 125, 1, 97, 77, 94, 220, 19, 31, 82, 61, 219, 115,
+ 223, 5, 113, 156, 107, 141, 168, 17, 172, 25, 210, 44, 40, 186, 207,
+ 198, 64, 102, 13, 186, 148, 154, 202, 76, 24, 153, 3, 202, 197, 122,
+ 97, 31, 220, 145, 217, 15, 214, 224, 59, 41, 197, 246, 20, 235, 181,
+ 109, 239, 136, 187, 25, 251, 103, 27, 193, 246, 229, 4, 31, 232, 182,
+ 53, 80, 144, 113, 221, 213, 224, 240, 163, 80, 54, 106, 237, 187, 194,
+ 26, 188, 246, 91, 192, 190, 39, 159, 110, 110, 97, 20, 101, 38, 3,
+ 74, 52, 234, 240, 105, 169, 224, 62, 41, 5, 236, 215, 160, 164, 220,
+ 84, 102, 148, 147, 202, 172, 43, 11, 242, 186, 41, 115, 79, 24, 231,
+ 163, 97, 109, 247, 62, 136, 222, 191, 215, 123, 217, 245, 208, 56, 24,
+ 211, 201, 159, 13, 14, 27, 180, 53, 84, 144, 217, 56, 111, 240, 254,
+ 149, 80, 118, 253, 210, 9, 97, 220, 179, 74, 132, 239, 155, 178, 250,
+ 72, 200, 70, 81, 230, 73, 55, 87, 103, 172, 59, 154, 153, 209, 179,
+ 72, 197, 12, 235, 62, 197, 181, 114, 88, 246, 131, 101, 173, 50, 167,
+ 150, 137, 245, 194, 62, 184, 35, 243, 18, 104, 59, 84, 23, 25, 90,
+ 239, 97, 220, 222, 150, 29, 127, 222, 59, 11, 238, 87, 174, 25, 176,
+ 111, 226, 186, 91, 130, 61, 206, 205, 237, 31, 154, 4, 253, 242, 159,
+ 120, 68, 232, 67, 177, 54, 127, 236, 157, 212, 230, 200, 190, 221, 226,
+ 62, 101, 217, 184, 155, 129, 154, 161, 177, 193, 79, 251, 173, 204, 176,
+ 238, 83, 220, 147, 25, 229, 180, 236, 7, 75, 199, 122, 9, 99, 237,
+ 134, 204, 95, 66, 219, 53, 198, 118, 221, 91, 191, 85, 231, 189, 159,
+ 175, 58, 27, 186, 19, 246, 36, 103, 211, 58, 135, 61, 249, 235, 180,
+ 32, 51, 191, 164, 243, 254, 29, 80, 86, 242, 240, 247, 194, 56, 151,
+ 88, 244, 237, 222, 128, 218, 217, 33, 84, 159, 183, 127, 118, 109, 91,
+ 197, 140, 45, 219, 195, 127, 217, 18, 204, 236, 83, 220, 210, 103, 148,
+ 115, 58, 115, 46, 128, 125, 112, 71, 230, 72, 216, 167, 44, 79, 56,
+ 18, 82, 179, 171, 49, 164, 224, 95, 45, 247, 247, 189, 151, 194, 55,
+ 189, 118, 112, 255, 119, 105, 17, 130, 221, 216, 248, 240, 96, 88, 111,
+ 40, 43, 94, 43, 66, 24, 231, 238, 207, 194, 67, 181, 25, 109, 246,
+ 141, 16, 101, 126, 209, 162, 80, 224, 195, 234, 47, 183, 246, 186, 186,
+ 97, 187, 221, 62, 197, 165, 62, 123, 139, 207, 238, 103, 80, 125, 134,
+ 61, 55, 246, 129, 230, 22, 96, 62, 1, 205, 45, 192, 247, 202, 96,
+ 174, 1, 155, 91, 16, 23, 31, 68, 236, 147, 96, 173, 57, 51, 121,
+ 203, 4, 162, 188, 85, 11, 173, 185, 5, 248, 44, 32, 245, 93, 176,
+ 191, 141, 29, 115, 102, 2, 210, 31, 43, 132, 11, 234, 115, 123, 130,
+ 108, 90, 215, 121, 53, 125, 220, 204, 45, 192, 45, 86, 94, 115, 11,
+ 134, 139, 185, 5, 135, 123, 19, 75, 110, 193, 88, 23, 185, 5, 11,
+ 180, 154, 140, 97, 191, 52, 48, 60, 122, 220, 66, 67, 191, 155, 26,
+ 103, 247, 221, 212, 109, 245, 155, 137, 223, 87, 21, 254, 50, 40, 158,
+ 16, 203, 13, 237, 100, 44, 94, 231, 79, 254, 163, 228, 176, 198, 255,
+ 137, 239, 166, 202, 231, 124, 57, 230, 204, 232, 85, 16, 187, 194, 165,
+ 43, 33, 94, 74, 243, 21, 48, 208, 124, 185, 47, 92, 1, 161, 253,
+ 186, 220, 28, 245, 79, 143, 102, 171, 221, 205, 45, 16, 190, 231, 45,
+ 234, 4, 103, 151, 115, 128, 114, 73, 230, 197, 74, 228, 7, 176, 121,
+ 177, 72, 183, 73, 21, 107, 243, 76, 3, 251, 40, 151, 23, 59, 42,
+ 105, 152, 152, 26, 235, 60, 61, 32, 7, 198, 71, 163, 138, 117, 254,
+ 189, 81, 149, 181, 47, 56, 142, 52, 47, 22, 105, 254, 39, 242, 98,
+ 177, 141, 55, 145, 23, 155, 6, 115, 157, 51, 208, 121, 159, 104, 185,
+ 224, 255, 7, 198, 90, 158, 133, 34, 141, 179, 188, 88, 196, 113, 149,
+ 23, 27, 151, 48, 58, 122, 112, 242, 216, 232, 100, 24, 91, 103, 143,
+ 80, 178, 223, 141, 181, 121, 22, 138, 247, 175, 155, 23, 75, 237, 39,
+ 218, 167, 25, 118, 50, 97, 93, 3, 148, 23, 234, 154, 208, 56, 114,
+ 128, 185, 109, 107, 236, 156, 56, 122, 172, 19, 77, 203, 169, 111, 238,
+ 111, 3, 145, 134, 210, 39, 0, 140, 252, 108, 246, 191, 206, 88, 248,
+ 91, 233, 19, 24, 122, 37, 192, 200, 143, 238, 249, 157, 183, 14, 122,
+ 86, 194, 74, 175, 100, 232, 211, 251, 195, 88, 193, 189, 249, 156, 67,
+ 138, 26, 244, 166, 148, 149, 30, 105, 40, 189, 22, 96, 228, 39, 158,
+ 237, 72, 50, 208, 151, 177, 210, 107, 25, 250, 220, 126, 176, 175, 132,
+ 123, 241, 60, 75, 146, 62, 173, 156, 149, 30, 105, 40, 125, 42, 192,
+ 200, 79, 60, 147, 150, 238, 192, 96, 43, 125, 42, 67, 31, 0, 48,
+ 242, 179, 217, 203, 35, 151, 247, 109, 201, 141, 117, 173, 244, 1, 12,
+ 125, 118, 223, 88, 175, 84, 134, 94, 74, 7, 52, 126, 204, 252, 247,
+ 101, 230, 31, 96, 228, 103, 221, 151, 59, 239, 66, 90, 109, 102, 254,
+ 25, 122, 37, 192, 200, 143, 221, 83, 56, 229, 80, 140, 153, 127, 134,
+ 62, 253, 29, 24, 59, 184, 103, 247, 170, 206, 232, 245, 53, 153, 249,
+ 127, 135, 153, 127, 128, 149, 86, 122, 201, 37, 144, 83, 132, 153, 127,
+ 134, 62, 183, 15, 204, 63, 220, 219, 239, 151, 237, 89, 232, 170, 51,
+ 243, 223, 135, 153, 127, 128, 181, 182, 244, 78, 101, 48, 22, 98, 230,
+ 159, 161, 15, 0, 24, 249, 49, 207, 7, 156, 14, 95, 142, 142, 153,
+ 127, 134, 62, 187, 55, 204, 191, 133, 94, 218, 2, 164, 121, 49, 243,
+ 223, 155, 153, 127, 128, 145, 31, 115, 214, 239, 92, 1, 170, 48, 243,
+ 207, 208, 43, 1, 70, 126, 108, 12, 238, 116, 254, 10, 48, 243, 207,
+ 208, 167, 247, 130, 249, 71, 122, 230, 252, 219, 25, 125, 78, 69, 102,
+ 254, 123, 49, 243, 15, 176, 210, 74, 47, 169, 129, 58, 15, 102, 254,
+ 25, 122, 140, 241, 144, 159, 195, 25, 188, 253, 252, 149, 103, 230, 191,
+ 167, 149, 158, 136, 252, 28, 98, 99, 123, 17, 166, 60, 86, 208, 248,
+ 23, 99, 94, 26, 255, 226, 187, 204, 48, 30, 182, 139, 127, 37, 223,
+ 111, 248, 186, 241, 175, 205, 115, 126, 136, 127, 85, 221, 98, 189, 140,
+ 69, 156, 196, 191, 127, 67, 236, 11, 151, 177, 43, 200, 213, 22, 230,
+ 182, 219, 219, 248, 247, 223, 20, 255, 234, 96, 62, 116, 221, 98, 189,
+ 242, 45, 155, 16, 105, 189, 94, 252, 75, 117, 194, 62, 254, 69, 185,
+ 242, 27, 255, 206, 235, 102, 141, 165, 112, 192, 80, 79, 165, 226, 32,
+ 212, 81, 186, 14, 141, 93, 242, 30, 7, 33, 13, 165, 215, 1, 140,
+ 252, 242, 18, 7, 233, 24, 122, 130, 244, 93, 242, 22, 7, 17, 134,
+ 62, 173, 51, 204, 107, 151, 188, 197, 65, 72, 67, 233, 53, 0, 35,
+ 191, 188, 196, 65, 26, 134, 62, 39, 42, 214, 11, 249, 229, 37, 14,
+ 66, 26, 74, 175, 7, 24, 249, 229, 37, 14, 210, 51, 244, 42, 128,
+ 145, 95, 94, 226, 32, 21, 67, 111, 236, 4, 251, 194, 168, 188, 197,
+ 65, 72, 99, 153, 127, 128, 145, 95, 94, 226, 32, 29, 67, 79, 0,
+ 70, 126, 121, 137, 131, 8, 67, 159, 214, 17, 230, 191, 83, 222, 226,
+ 32, 164, 177, 204, 63, 192, 164, 83, 222, 226, 32, 13, 67, 159, 211,
+ 1, 230, 191, 99, 222, 226, 32, 164, 177, 204, 63, 192, 154, 142, 121,
+ 139, 131, 244, 12, 189, 10, 96, 228, 151, 151, 56, 72, 197, 208, 27,
+ 219, 195, 252, 119, 200, 91, 28, 132, 52, 150, 249, 7, 24, 249, 229,
+ 37, 14, 210, 49, 244, 4, 96, 228, 151, 151, 56, 136, 48, 244, 105,
+ 237, 96, 254, 219, 231, 45, 14, 66, 26, 203, 252, 3, 76, 218, 231,
+ 45, 14, 210, 48, 244, 232, 235, 145, 95, 94, 226, 32, 164, 97, 227,
+ 32, 77, 187, 188, 197, 65, 24, 251, 52, 101, 232, 49, 46, 178, 198,
+ 65, 248, 107, 114, 142, 195, 159, 223, 239, 193, 59, 251, 83, 181, 200,
+ 219, 59, 234, 126, 241, 244, 62, 232, 234, 123, 240, 111, 250, 93, 150,
+ 246, 223, 243, 148, 251, 30, 60, 202, 18, 212, 182, 136, 230, 175, 166,
+ 211, 223, 208, 247, 224, 243, 247, 247, 127, 237, 187, 159, 81, 173, 9,
+ 193, 135, 221, 248, 110, 195, 32, 106, 191, 236, 222, 165, 16, 213, 154,
+ 126, 119, 185, 185, 211, 177, 208, 61, 122, 252, 198, 95, 49, 203, 17,
+ 87, 207, 106, 217, 252, 62, 79, 27, 92, 218, 31, 236, 3, 237, 15,
+ 126, 31, 154, 125, 119, 163, 165, 63, 129, 1, 78, 219, 204, 126, 232,
+ 186, 63, 250, 174, 102, 94, 170, 8, 176, 51, 17, 174, 215, 155, 39,
+ 177, 126, 15, 97, 95, 84, 77, 152, 13, 77, 227, 74, 61, 95, 6,
+ 31, 0, 56, 62, 120, 142, 218, 177, 63, 156, 67, 124, 40, 124, 39,
+ 3, 218, 105, 36, 242, 219, 31, 245, 133, 38, 1, 104, 145, 143, 240,
+ 172, 58, 69, 97, 194, 178, 216, 224, 57, 89, 108, 25, 124, 236, 24,
+ 234, 80, 166, 111, 156, 108, 71, 75, 191, 251, 130, 253, 170, 103, 25,
+ 7, 15, 136, 102, 57, 8, 251, 77, 130, 12, 237, 196, 254, 54, 176,
+ 153, 27, 103, 239, 168, 53, 207, 145, 233, 229, 203, 151, 166, 165, 75,
+ 151, 10, 215, 139, 23, 47, 164, 102, 149, 206, 23, 206, 17, 157, 47,
+ 252, 254, 47, 171, 131, 214, 249, 146, 120, 79, 190, 204, 124, 25, 121,
+ 51, 175, 4, 53, 248, 37, 141, 235, 249, 242, 102, 230, 76, 228, 46,
+ 228, 33, 55, 153, 222, 80, 115, 232, 204, 57, 181, 156, 254, 89, 158,
+ 39, 106, 204, 243, 133, 252, 112, 174, 19, 132, 185, 22, 115, 11, 82,
+ 136, 9, 203, 112, 190, 236, 202, 140, 67, 237, 202, 246, 66, 89, 178,
+ 29, 109, 240, 244, 134, 198, 227, 130, 44, 214, 50, 144, 207, 184, 231,
+ 204, 185, 44, 187, 50, 205, 126, 39, 101, 135, 236, 104, 233, 89, 47,
+ 142, 83, 61, 139, 141, 226, 72, 65, 130, 63, 109, 208, 83, 200, 179,
+ 45, 0, 119, 8, 43, 64, 47, 60, 225, 14, 97, 220, 117, 121, 17,
+ 79, 1, 22, 190, 215, 195, 153, 199, 184, 129, 141, 157, 115, 161, 35,
+ 41, 41, 41, 236, 229, 218, 27, 230, 157, 15, 247, 47, 231, 67, 117,
+ 31, 245, 221, 98, 123, 193, 127, 179, 239, 111, 176, 232, 190, 196, 247,
+ 238, 211, 31, 72, 235, 190, 6, 248, 42, 67, 204, 188, 210, 51, 75,
+ 122, 212, 33, 81, 46, 117, 191, 43, 49, 255, 96, 169, 147, 254, 182,
+ 52, 95, 246, 186, 79, 159, 117, 152, 203, 45, 207, 97, 194, 173, 123,
+ 234, 180, 2, 230, 103, 22, 61, 10, 226, 175, 80, 71, 9, 107, 162,
+ 171, 184, 44, 217, 239, 204, 163, 30, 154, 203, 136, 179, 50, 98, 87,
+ 70, 28, 241, 244, 70, 137, 50, 59, 90, 163, 51, 126, 248, 142, 166,
+ 198, 78, 240, 236, 101, 57, 200, 57, 148, 9, 120, 45, 29, 249, 25,
+ 53, 142, 101, 44, 158, 130, 182, 235, 76, 230, 150, 142, 109, 24, 157,
+ 180, 235, 48, 126, 196, 121, 153, 209, 201, 152, 26, 157, 180, 235, 116,
+ 62, 90, 58, 226, 57, 200, 162, 177, 47, 227, 204, 188, 236, 199, 165,
+ 165, 253, 24, 112, 102, 58, 39, 120, 206, 218, 112, 24, 43, 137, 50,
+ 135, 254, 74, 148, 57, 140, 115, 99, 39, 178, 56, 105, 67, 160, 117,
+ 210, 174, 109, 25, 252, 241, 142, 122, 37, 240, 215, 56, 41, 35, 142,
+ 101, 122, 39, 99, 224, 172, 93, 7, 221, 213, 176, 186, 207, 200, 119,
+ 208, 201, 56, 27, 157, 204, 165, 209, 137, 124, 7, 109, 117, 215, 232,
+ 132, 159, 94, 162, 93, 7, 126, 18, 101, 14, 242, 101, 74, 224, 57,
+ 41, 115, 218, 95, 103, 253, 112, 82, 166, 119, 50, 6, 196, 73, 153,
+ 62, 195, 201, 250, 176, 111, 215, 104, 50, 165, 24, 157, 172, 203, 12,
+ 39, 54, 204, 232, 100, 237, 27, 157, 216, 23, 39, 101, 246, 50, 147,
+ 131, 78, 218, 61, 248, 202, 100, 50, 56, 177, 37, 70, 39, 246, 202,
+ 89, 187, 7, 157, 216, 48, 59, 61, 208, 59, 195, 35, 206, 203, 28,
+ 100, 118, 38, 139, 51, 126, 78, 250, 171, 119, 160, 69, 63, 131, 65,
+ 9, 250, 188, 122, 150, 133, 82, 90, 136, 208, 148, 226, 243, 134, 2,
+ 16, 193, 208, 223, 198, 196, 39, 244, 74, 209, 135, 41, 136, 249, 21,
+ 125, 158, 16, 177, 21, 20, 226, 27, 164, 84, 194, 157, 57, 217, 220,
+ 155, 20, 130, 88, 7, 99, 160, 106, 112, 21, 133, 59, 111, 1, 46,
+ 76, 124, 72, 17, 82, 28, 224, 96, 248, 191, 8, 212, 40, 133, 242,
+ 98, 80, 83, 156, 148, 5, 184, 4, 252, 143, 245, 165, 197, 35, 244,
+ 18, 164, 36, 41, 37, 192, 126, 164, 12, 64, 37, 5, 28, 252, 30,
+ 95, 41, 1, 31, 191, 215, 91, 12, 160, 82, 66, 121, 5, 226, 11,
+ 126, 182, 156, 0, 151, 3, 168, 50, 169, 36, 224, 148, 135, 154, 114,
+ 164, 34, 192, 203, 225, 255, 114, 80, 90, 7, 224, 57, 128, 81, 21,
+ 90, 175, 44, 224, 248, 18, 21, 220, 85, 17, 104, 171, 66, 59, 37,
+ 4, 217, 33, 198, 128, 150, 75, 66, 137, 82, 40, 41, 1, 253, 175,
+ 46, 148, 87, 7, 136, 39, 53, 5, 184, 50, 212, 84, 39, 53, 4,
+ 184, 6, 64, 53, 73, 61, 1, 174, 69, 234, 146, 48, 82, 91, 104,
+ 171, 14, 180, 90, 23, 74, 16, 174, 11, 88, 245, 160, 6, 113, 42,
+ 1, 117, 13, 40, 65, 184, 62, 9, 36, 65, 196, 95, 128, 253, 1,
+ 106, 64, 2, 0, 142, 36, 33, 80, 227, 79, 26, 10, 180, 13, 1,
+ 10, 32, 141, 0, 62, 13, 24, 193, 164, 49, 96, 33, 78, 32, 105,
+ 6, 119, 65, 2, 109, 48, 105, 66, 58, 66, 13, 150, 55, 35, 157,
+ 224, 46, 88, 40, 175, 73, 112, 139, 219, 84, 128, 155, 2, 212, 9,
+ 106, 17, 174, 7, 53, 77, 73, 115, 1, 110, 14, 80, 51, 224, 134,
+ 112, 11, 18, 10, 45, 135, 8, 237, 214, 6, 121, 67, 161, 4, 225,
+ 80, 192, 10, 132, 26, 196, 9, 3, 234, 230, 80, 162, 20, 206, 244,
+ 11, 128, 129, 8, 23, 224, 112, 128, 212, 164, 139, 0, 243, 80, 19,
+ 14, 237, 41, 5, 61, 11, 135, 210, 78, 2, 220, 146, 68, 144, 86,
+ 128, 165, 20, 178, 114, 10, 194, 93, 75, 1, 142, 32, 173, 65, 242,
+ 86, 130, 110, 96, 92, 221, 26, 74, 16, 110, 5, 165, 109, 73, 27,
+ 1, 110, 3, 80, 123, 210, 14, 224, 161, 192, 161, 21, 220, 107, 5,
+ 90, 45, 64, 237, 72, 7, 161, 239, 77, 72, 20, 233, 12, 35, 129,
+ 112, 39, 104, 53, 10, 74, 16, 39, 10, 176, 58, 64, 13, 150, 119,
+ 1, 106, 45, 148, 40, 197, 152, 12, 38, 91, 136, 255, 26, 176, 206,
+ 195, 85, 252, 58, 97, 194, 4, 83, 100, 100, 164, 240, 121, 246, 236,
+ 89, 172, 249, 39, 133, 216, 127, 233, 66, 158, 79, 76, 76, 140, 41,
+ 36, 36, 196, 212, 186, 117, 107, 211, 196, 137, 19, 205, 124, 184, 188,
+ 243, 65, 122, 228, 131, 252, 242, 195, 231, 201, 147, 39, 216, 31, 225,
+ 83, 252, 141, 226, 215, 234, 23, 142, 75, 131, 6, 13, 76, 205, 154,
+ 53, 51, 45, 88, 176, 224, 181, 249, 168, 84, 42, 147, 183, 183, 183,
+ 169, 116, 233, 210, 216, 191, 215, 238, 23, 210, 163, 13, 196, 171, 66,
+ 133, 10, 175, 205, 167, 84, 169, 82, 22, 62, 208, 191, 215, 238, 23,
+ 229, 33, 94, 111, 132, 15, 140, 211, 107, 247, 235, 77, 241, 161, 227,
+ 131, 159, 176, 62, 164, 251, 101, 75, 103, 207, 87, 208, 31, 208, 27,
+ 65, 127, 222, 196, 56, 227, 252, 187, 156, 119, 25, 121, 80, 15, 113,
+ 125, 33, 159, 55, 49, 206, 56, 62, 111, 162, 95, 226, 120, 231, 139,
+ 15, 174, 47, 113, 157, 189, 17, 253, 177, 200, 227, 241, 223, 235, 151,
+ 56, 190, 212, 78, 191, 17, 253, 201, 207, 248, 136, 250, 71, 237, 116,
+ 190, 198, 89, 161, 80, 228, 123, 93, 208, 245, 37, 218, 251, 124, 249,
+ 47, 240, 55, 166, 201, 147, 39, 231, 203, 239, 208, 245, 37, 250, 195,
+ 215, 230, 35, 250, 99, 161, 95, 249, 241, 59, 162, 125, 23, 198, 25,
+ 198, 59, 223, 235, 75, 244, 63, 249, 210, 31, 26, 39, 228, 215, 127,
+ 209, 184, 37, 63, 250, 67, 249, 188, 41, 251, 99, 99, 55, 184, 255,
+ 46, 159, 55, 225, 151, 169, 253, 201, 47, 159, 55, 229, 119, 168, 253,
+ 201, 239, 248, 188, 41, 191, 44, 198, 151, 111, 204, 254, 228, 215, 174,
+ 138, 241, 247, 27, 179, 63, 111, 194, 239, 160, 254, 188, 137, 245, 133,
+ 243, 254, 166, 236, 79, 126, 227, 4, 113, 63, 144, 111, 251, 35, 218,
+ 247, 55, 182, 255, 18, 215, 217, 107, 247, 75, 244, 127, 111, 108, 255,
+ 37, 174, 179, 124, 239, 191, 100, 227, 112, 55, 214, 5, 213, 159, 55,
+ 181, 255, 202, 175, 254, 96, 252, 147, 223, 253, 23, 187, 143, 123, 83,
+ 251, 175, 252, 172, 47, 186, 207, 125, 83, 251, 175, 252, 246, 75, 180,
+ 239, 52, 222, 204, 151, 254, 80, 255, 149, 159, 184, 69, 244, 127, 111,
+ 196, 127, 209, 184, 197, 133, 254, 88, 114, 36, 90, 88, 159, 59, 226,
+ 247, 7, 217, 247, 110, 71, 181, 142, 138, 73, 138, 149, 206, 203, 200,
+ 249, 197, 245, 51, 119, 93, 19, 51, 175, 101, 71, 58, 121, 213, 209,
+ 118, 116, 249, 220, 177, 59, 92, 29, 173, 188, 51, 105, 249, 181, 19,
+ 69, 53, 213, 43, 239, 116, 235, 153, 251, 251, 248, 124, 17, 218, 105,
+ 36, 242, 67, 90, 205, 212, 245, 251, 216, 243, 225, 156, 19, 47, 121,
+ 219, 50, 133, 80, 182, 106, 193, 193, 3, 44, 94, 141, 225, 94, 26,
+ 103, 101, 187, 38, 36, 218, 60, 75, 159, 100, 80, 104, 126, 109, 52,
+ 221, 166, 236, 200, 194, 231, 252, 143, 237, 102, 219, 148, 133, 237, 185,
+ 202, 55, 175, 218, 202, 166, 44, 107, 211, 69, 158, 52, 158, 185, 151,
+ 45, 91, 181, 224, 42, 31, 52, 83, 99, 243, 108, 254, 167, 107, 79,
+ 249, 139, 237, 102, 219, 148, 45, 123, 228, 169, 57, 154, 243, 190, 77,
+ 217, 241, 28, 31, 77, 226, 143, 237, 212, 108, 223, 176, 236, 157, 191,
+ 150, 218, 224, 53, 232, 234, 169, 41, 122, 118, 171, 77, 89, 114, 205,
+ 103, 188, 121, 156, 173, 180, 127, 7, 254, 200, 247, 11, 155, 106, 131,
+ 215, 255, 131, 147, 40, 179, 205, 152, 78, 123, 112, 17, 250, 102, 59,
+ 6, 169, 7, 159, 34, 63, 155, 178, 206, 241, 5, 52, 41, 239, 108,
+ 205, 98, 219, 192, 57, 58, 244, 116, 153, 13, 94, 205, 225, 94, 198,
+ 46, 241, 219, 108, 218, 189, 126, 162, 168, 93, 153, 130, 150, 217, 208,
+ 174, 59, 252, 155, 193, 182, 76, 33, 148, 141, 92, 55, 221, 161, 13,
+ 251, 178, 242, 171, 126, 53, 216, 63, 131, 171, 150, 253, 189, 161, 92,
+ 151, 41, 54, 120, 43, 34, 210, 13, 246, 125, 251, 227, 229, 60, 67,
+ 192, 31, 147, 237, 240, 244, 14, 252, 230, 214, 254, 200, 16, 229, 167,
+ 87, 219, 62, 199, 16, 248, 217, 148, 93, 94, 252, 189, 97, 251, 47,
+ 41, 54, 101, 187, 38, 124, 239, 192, 111, 234, 250, 227, 134, 160, 239,
+ 91, 58, 240, 179, 215, 151, 254, 97, 75, 29, 240, 94, 196, 124, 228,
+ 192, 15, 241, 186, 196, 183, 204, 178, 231, 103, 175, 207, 216, 174, 214,
+ 14, 175, 207, 154, 178, 134, 170, 211, 51, 108, 117, 119, 113, 29, 187,
+ 50, 5, 140, 105, 178, 193, 126, 222, 254, 57, 213, 215, 97, 222, 194,
+ 70, 70, 26, 110, 167, 151, 176, 193, 155, 241, 224, 126, 150, 125, 153,
+ 247, 138, 67, 89, 246, 180, 233, 31, 207, 207, 178, 111, 3, 172, 157,
+ 33, 226, 94, 7, 27, 249, 206, 69, 123, 24, 82, 147, 251, 216, 172,
+ 243, 119, 63, 8, 113, 40, 211, 251, 116, 118, 224, 167, 153, 253, 81,
+ 184, 125, 89, 218, 184, 205, 234, 176, 61, 99, 109, 202, 98, 15, 252,
+ 170, 182, 31, 231, 221, 19, 182, 171, 87, 68, 36, 216, 200, 162, 79,
+ 156, 27, 110, 175, 247, 98, 187, 54, 101, 26, 191, 236, 3, 35, 214,
+ 77, 183, 157, 243, 142, 61, 194, 237, 203, 180, 126, 115, 212, 197, 42,
+ 182, 176, 41, 203, 105, 244, 181, 131, 44, 217, 147, 22, 168, 67, 70,
+ 214, 176, 29, 171, 138, 113, 225, 246, 235, 3, 219, 181, 47, 83, 86,
+ 172, 203, 219, 203, 231, 187, 170, 56, 111, 191, 86, 197, 50, 103, 180,
+ 54, 243, 118, 164, 205, 94, 71, 126, 93, 182, 56, 242, 131, 50, 207,
+ 21, 17, 182, 54, 118, 228, 16, 7, 218, 78, 126, 90, 7, 90, 177,
+ 204, 134, 246, 75, 101, 172, 131, 44, 88, 118, 114, 18, 111, 59, 31,
+ 239, 108, 117, 160, 21, 101, 206, 178, 127, 14, 57, 195, 195, 236, 3,
+ 235, 137, 190, 205, 151, 148, 37, 229, 8, 17, 158, 237, 248, 146, 138,
+ 112, 71, 132, 103, 62, 190, 164, 2, 220, 81, 24, 159, 234, 17, 225,
+ 89, 98, 117, 82, 11, 74, 136, 240, 60, 167, 22, 241, 19, 225, 106,
+ 194, 147, 184, 90, 34, 92, 27, 202, 107, 137, 56, 181, 133, 167, 122,
+ 230, 242, 74, 128, 83, 93, 44, 175, 68, 106, 8, 111, 9, 198, 242,
+ 58, 128, 83, 91, 44, 199, 39, 116, 149, 44, 112, 125, 82, 67, 196,
+ 169, 11, 56, 117, 196, 242, 186, 164, 42, 220, 153, 203, 235, 1, 92,
+ 215, 130, 95, 15, 40, 104, 57, 62, 113, 52, 195, 85, 224, 174, 178,
+ 136, 227, 79, 26, 144, 134, 98, 127, 253, 133, 39, 122, 230, 56, 164,
+ 49, 244, 173, 129, 136, 239, 79, 154, 146, 198, 34, 220, 68, 120, 238,
+ 71, 105, 3, 72, 83, 17, 63, 0, 106, 154, 138, 56, 1, 36, 144,
+ 52, 17, 224, 18, 0, 5, 139, 48, 62, 87, 108, 36, 188, 99, 92,
+ 41, 60, 45, 12, 38, 129, 2, 220, 147, 52, 35, 106, 18, 46, 242,
+ 84, 147, 48, 17, 174, 6, 48, 79, 194, 68, 62, 60, 9, 21, 225,
+ 106, 128, 143, 120, 102, 88, 3, 229, 188, 72, 171, 33, 33, 36, 84,
+ 44, 111, 9, 176, 70, 44, 143, 0, 184, 165, 5, 110, 65, 66, 68,
+ 156, 86, 0, 71, 136, 229, 173, 72, 115, 210, 194, 194, 31, 159, 246,
+ 81, 184, 57, 220, 153, 101, 104, 75, 90, 147, 54, 226, 88, 181, 37,
+ 237, 224, 206, 220, 151, 206, 164, 19, 137, 18, 203, 59, 19, 45, 233,
+ 36, 246, 87, 11, 26, 213, 73, 228, 211, 145, 180, 39, 29, 68, 156,
+ 142, 164, 27, 220, 153, 203, 59, 147, 46, 68, 43, 242, 233, 10, 53,
+ 90, 81, 158, 174, 128, 211, 81, 108, 87, 73, 138, 9, 239, 226, 68,
+ 90, 124, 166, 93, 76, 164, 85, 146, 194, 112, 103, 110, 171, 176, 240,
+ 76, 219, 140, 95, 132, 248, 136, 48, 62, 123, 45, 36, 188, 155, 84,
+ 41, 60, 65, 46, 36, 224, 34, 255, 18, 194, 147, 114, 90, 238, 37,
+ 228, 63, 34, 92, 18, 224, 18, 34, 142, 66, 140, 245, 148, 164, 160,
+ 144, 67, 168, 16, 96, 79, 82, 134, 152, 191, 201, 165, 20, 158, 212,
+ 151, 17, 225, 72, 160, 45, 40, 188, 41, 21, 249, 20, 128, 114, 79,
+ 177, 188, 20, 148, 151, 20, 225, 130, 80, 94, 192, 82, 94, 70, 248,
+ 166, 186, 82, 120, 166, 94, 90, 224, 139, 50, 227, 186, 244, 45, 99,
+ 142, 73, 27, 136, 235, 210, 241, 185, 136, 109, 153, 201, 238, 143, 198,
+ 230, 210, 57, 138, 121, 227, 195, 189, 229, 243, 150, 207, 91, 62, 111,
+ 249, 188, 229, 243, 150, 207, 91, 62, 111, 249, 188, 229, 243, 150, 207,
+ 91, 62, 111, 249, 188, 229, 243, 150, 207, 91, 62, 111, 249, 188, 229,
+ 243, 191, 132, 143, 212, 111, 245, 254, 111, 231, 243, 118, 222, 255, 127,
+ 228, 67, 115, 4, 48, 47, 128, 230, 8, 224, 59, 214, 48, 103, 64,
+ 151, 104, 126, 182, 31, 213, 26, 223, 239, 70, 95, 111, 220, 204, 33,
+ 71, 64, 229, 226, 187, 201, 1, 192, 183, 78, 128, 143, 240, 138, 84,
+ 227, 192, 142, 94, 198, 7, 237, 189, 234, 144, 158, 146, 121, 2, 103,
+ 224, 10, 225, 204, 188, 151, 181, 141, 48, 36, 92, 95, 139, 121, 1,
+ 153, 138, 196, 233, 154, 187, 15, 234, 105, 140, 123, 207, 56, 228, 8,
+ 40, 152, 94, 89, 126, 67, 182, 177, 245, 187, 201, 57, 30, 226, 251,
+ 84, 149, 32, 3, 180, 223, 72, 108, 167, 195, 198, 233, 134, 221, 101,
+ 234, 24, 106, 142, 86, 242, 234, 39, 222, 207, 151, 167, 16, 211, 207,
+ 156, 191, 161, 107, 169, 97, 134, 209, 85, 7, 240, 225, 5, 54, 94,
+ 214, 78, 34, 166, 105, 191, 63, 10, 63, 60, 38, 214, 80, 3, 240,
+ 30, 112, 3, 158, 223, 76, 81, 152, 254, 60, 119, 196, 208, 254, 244,
+ 117, 67, 187, 216, 123, 234, 121, 109, 21, 75, 86, 62, 35, 166, 91,
+ 23, 46, 27, 102, 241, 223, 26, 10, 247, 111, 200, 39, 60, 46, 253,
+ 119, 206, 20, 98, 154, 161, 254, 219, 176, 40, 108, 167, 128, 55, 251,
+ 73, 175, 103, 75, 128, 246, 94, 124, 5, 227, 173, 141, 255, 24, 102,
+ 76, 250, 65, 93, 61, 55, 253, 21, 129, 118, 75, 173, 43, 101, 252,
+ 114, 122, 33, 227, 135, 35, 235, 242, 145, 59, 159, 13, 91, 82, 132,
+ 152, 234, 61, 44, 102, 60, 221, 95, 105, 68, 188, 201, 161, 91, 230,
+ 47, 121, 69, 76, 85, 207, 55, 53, 206, 158, 90, 194, 168, 91, 90,
+ 153, 247, 206, 217, 60, 190, 153, 74, 97, 106, 24, 94, 213, 24, 31,
+ 84, 194, 120, 123, 108, 16, 223, 161, 114, 244, 7, 87, 47, 17, 83,
+ 185, 254, 213, 141, 199, 122, 61, 51, 196, 71, 29, 81, 255, 241, 115,
+ 183, 247, 198, 189, 32, 166, 217, 217, 26, 129, 54, 197, 84, 67, 125,
+ 238, 215, 244, 73, 231, 255, 84, 88, 218, 189, 153, 89, 87, 29, 220,
+ 186, 248, 226, 185, 62, 214, 126, 140, 250, 106, 166, 250, 158, 199, 55,
+ 164, 164, 158, 152, 126, 129, 113, 209, 194, 184, 244, 215, 44, 83, 207,
+ 47, 84, 236, 214, 231, 211, 136, 165, 221, 230, 11, 23, 133, 143, 185,
+ 243, 193, 248, 117, 23, 21, 166, 1, 91, 226, 13, 207, 135, 151, 50,
+ 206, 219, 145, 193, 55, 189, 186, 117, 124, 55, 63, 133, 73, 85, 239,
+ 70, 86, 169, 65, 127, 24, 106, 173, 89, 192, 95, 120, 53, 75, 249,
+ 199, 20, 133, 233, 157, 6, 93, 213, 149, 55, 191, 52, 248, 70, 207,
+ 230, 163, 148, 127, 78, 233, 175, 32, 166, 202, 123, 86, 242, 61, 111,
+ 221, 53, 204, 239, 59, 154, 31, 86, 170, 208, 227, 170, 48, 126, 126,
+ 223, 127, 206, 127, 80, 253, 39, 3, 231, 49, 134, 15, 46, 193, 229,
+ 126, 63, 153, 152, 38, 141, 249, 73, 29, 215, 53, 35, 107, 157, 223,
+ 42, 190, 65, 241, 90, 127, 158, 159, 172, 48, 205, 76, 175, 148, 85,
+ 201, 191, 180, 177, 94, 253, 61, 124, 56, 41, 54, 239, 228, 9, 133,
+ 233, 175, 42, 105, 106, 44, 219, 123, 55, 133, 47, 224, 179, 87, 191,
+ 255, 41, 49, 69, 102, 252, 200, 79, 25, 95, 214, 184, 179, 121, 123,
+ 126, 72, 248, 226, 212, 95, 238, 43, 76, 21, 14, 63, 231, 3, 215,
+ 43, 132, 178, 145, 222, 15, 114, 207, 129, 124, 91, 23, 255, 196, 79,
+ 168, 30, 97, 184, 117, 62, 133, 255, 165, 200, 236, 63, 195, 65, 150,
+ 176, 167, 243, 213, 63, 21, 169, 199, 123, 167, 110, 231, 15, 150, 56,
+ 153, 123, 17, 218, 93, 61, 244, 10, 255, 207, 186, 245, 89, 229, 160,
+ 31, 83, 189, 130, 254, 250, 10, 240, 252, 85, 31, 242, 77, 46, 174,
+ 225, 251, 244, 220, 196, 15, 171, 181, 162, 224, 31, 19, 137, 233, 82,
+ 216, 51, 126, 205, 79, 83, 248, 169, 189, 151, 241, 171, 154, 15, 233,
+ 61, 186, 131, 194, 20, 30, 179, 90, 125, 243, 153, 143, 81, 55, 99,
+ 61, 223, 250, 217, 168, 247, 134, 249, 17, 211, 177, 31, 15, 243, 117,
+ 39, 251, 24, 145, 159, 230, 214, 236, 232, 37, 233, 196, 148, 116, 225,
+ 59, 254, 220, 225, 39, 134, 87, 218, 15, 248, 93, 53, 54, 223, 49,
+ 76, 32, 166, 86, 157, 55, 240, 43, 119, 55, 50, 68, 116, 201, 228,
+ 163, 203, 85, 186, 249, 23, 232, 233, 211, 144, 84, 222, 72, 78, 134,
+ 125, 165, 63, 193, 231, 60, 27, 124, 181, 193, 251, 196, 116, 254, 199,
+ 157, 252, 198, 35, 65, 134, 47, 238, 204, 228, 239, 87, 223, 92, 239,
+ 219, 121, 196, 212, 125, 210, 167, 252, 238, 161, 235, 213, 158, 119, 143,
+ 242, 47, 94, 252, 94, 240, 40, 62, 215, 175, 252, 55, 223, 174, 228,
+ 169, 3, 89, 176, 190, 30, 20, 41, 255, 240, 42, 140, 193, 142, 163,
+ 87, 120, 255, 250, 233, 134, 6, 7, 134, 243, 247, 254, 220, 118, 101,
+ 238, 68, 51, 237, 94, 160, 93, 191, 184, 35, 191, 224, 236, 136, 178,
+ 229, 230, 153, 219, 189, 10, 237, 246, 25, 217, 134, 175, 127, 243, 7,
+ 238, 231, 105, 102, 249, 86, 128, 124, 103, 230, 132, 242, 59, 95, 164,
+ 120, 181, 214, 91, 251, 177, 119, 84, 5, 126, 87, 161, 93, 5, 63,
+ 210, 91, 251, 59, 103, 163, 47, 223, 254, 69, 165, 30, 177, 58, 24,
+ 103, 113, 92, 254, 172, 25, 197, 207, 243, 153, 59, 173, 96, 89, 98,
+ 154, 35, 206, 111, 242, 199, 60, 95, 170, 112, 165, 121, 67, 154, 40,
+ 76, 23, 135, 204, 16, 116, 237, 72, 217, 113, 188, 239, 149, 51, 19,
+ 180, 127, 40, 76, 81, 220, 71, 198, 73, 171, 187, 25, 134, 213, 237,
+ 208, 120, 208, 201, 99, 115, 241, 81, 109, 159, 3, 223, 26, 230, 15,
+ 255, 152, 111, 182, 45, 84, 29, 243, 234, 94, 85, 229, 12, 98, 186,
+ 204, 253, 144, 53, 126, 110, 45, 205, 182, 244, 202, 124, 173, 87, 183,
+ 91, 205, 90, 72, 76, 189, 7, 220, 205, 122, 39, 129, 215, 212, 78,
+ 155, 192, 239, 250, 235, 218, 128, 185, 95, 41, 76, 29, 58, 22, 54,
+ 46, 184, 81, 86, 19, 152, 51, 144, 79, 184, 249, 115, 212, 131, 213,
+ 196, 116, 113, 97, 35, 227, 205, 140, 177, 252, 135, 165, 14, 170, 253,
+ 188, 13, 229, 43, 131, 78, 86, 107, 81, 193, 184, 239, 230, 112, 94,
+ 147, 229, 167, 110, 121, 34, 240, 102, 242, 2, 98, 90, 49, 166, 149,
+ 113, 218, 218, 52, 126, 147, 166, 126, 227, 162, 30, 253, 174, 205, 154,
+ 78, 76, 235, 199, 61, 51, 140, 223, 245, 55, 255, 217, 129, 106, 234,
+ 34, 79, 155, 54, 59, 48, 79, 97, 218, 149, 18, 105, 248, 231, 85,
+ 3, 141, 102, 67, 5, 222, 244, 244, 188, 246, 239, 85, 196, 244, 235,
+ 165, 9, 70, 227, 190, 247, 249, 210, 215, 10, 241, 223, 158, 253, 89,
+ 91, 183, 151, 194, 52, 240, 183, 84, 227, 167, 75, 170, 102, 197, 53,
+ 201, 80, 87, 221, 245, 135, 103, 197, 56, 98, 250, 99, 238, 44, 99,
+ 175, 182, 93, 13, 151, 126, 251, 73, 221, 240, 116, 120, 243, 53, 67,
+ 21, 166, 232, 238, 195, 141, 187, 103, 86, 51, 212, 10, 216, 170, 158,
+ 123, 157, 203, 104, 50, 136, 152, 174, 169, 206, 25, 98, 215, 220, 53,
+ 240, 71, 9, 63, 227, 105, 207, 45, 189, 160, 172, 224, 163, 43, 89,
+ 39, 238, 237, 53, 84, 250, 214, 139, 191, 204, 169, 183, 182, 27, 76,
+ 76, 95, 20, 219, 160, 238, 188, 112, 131, 161, 67, 216, 123, 252, 189,
+ 95, 14, 236, 234, 57, 132, 152, 122, 53, 40, 173, 217, 186, 231, 47,
+ 67, 129, 152, 72, 62, 160, 82, 139, 207, 174, 118, 6, 29, 63, 219,
+ 65, 115, 209, 235, 99, 195, 247, 191, 38, 243, 103, 251, 94, 57, 215,
+ 188, 139, 194, 164, 245, 111, 165, 249, 167, 243, 44, 245, 63, 239, 69,
+ 242, 127, 13, 234, 18, 124, 95, 77, 76, 241, 254, 158, 198, 65, 39,
+ 215, 170, 251, 93, 94, 174, 142, 244, 218, 217, 38, 97, 56, 49, 141,
+ 187, 178, 216, 208, 185, 73, 81, 62, 173, 104, 49, 254, 175, 156, 175,
+ 155, 252, 51, 26, 198, 111, 203, 111, 89, 131, 122, 127, 198, 171, 166,
+ 151, 226, 199, 95, 240, 141, 24, 29, 67, 76, 103, 134, 22, 208, 156,
+ 57, 52, 149, 111, 177, 216, 135, 175, 173, 25, 217, 219, 212, 138, 152,
+ 116, 223, 133, 240, 37, 55, 110, 230, 91, 13, 232, 205, 235, 185, 101,
+ 81, 199, 1, 47, 179, 96, 117, 227, 209, 131, 151, 213, 159, 156, 248,
+ 71, 61, 191, 225, 229, 218, 199, 18, 136, 233, 235, 29, 61, 141, 83,
+ 127, 190, 175, 222, 186, 172, 58, 191, 225, 69, 159, 234, 79, 97, 125,
+ 24, 150, 119, 52, 250, 110, 218, 125, 96, 85, 223, 65, 252, 242, 23,
+ 237, 31, 47, 2, 91, 124, 247, 115, 63, 227, 205, 150, 17, 134, 67,
+ 195, 159, 168, 67, 174, 15, 248, 173, 24, 224, 45, 57, 86, 210, 56,
+ 38, 100, 16, 159, 102, 122, 21, 124, 179, 243, 201, 33, 132, 40, 76,
+ 133, 115, 139, 241, 219, 58, 84, 54, 28, 120, 178, 156, 127, 244, 98,
+ 225, 171, 7, 64, 27, 116, 244, 104, 214, 77, 159, 62, 134, 196, 164,
+ 0, 222, 227, 228, 38, 226, 147, 76, 76, 169, 93, 27, 241, 165, 135,
+ 29, 82, 151, 58, 59, 147, 127, 247, 229, 156, 82, 19, 192, 30, 36,
+ 214, 249, 52, 235, 121, 250, 65, 53, 246, 173, 242, 181, 237, 222, 181,
+ 97, 93, 214, 105, 241, 53, 191, 224, 231, 139, 134, 18, 47, 218, 243,
+ 199, 239, 87, 202, 232, 9, 253, 184, 54, 56, 198, 48, 216, 56, 67,
+ 240, 71, 37, 189, 35, 142, 222, 31, 67, 76, 105, 223, 4, 25, 98,
+ 75, 149, 53, 220, 30, 58, 67, 125, 84, 83, 46, 247, 208, 39, 196,
+ 244, 153, 88, 86, 199, 103, 24, 191, 161, 228, 222, 194, 13, 160, 141,
+ 89, 97, 51, 14, 236, 228, 19, 179, 208, 71, 29, 242, 212, 151, 138,
+ 131, 245, 187, 88, 57, 208, 48, 161, 77, 143, 3, 177, 153, 69, 248,
+ 197, 47, 61, 42, 150, 5, 61, 173, 85, 225, 67, 67, 165, 86, 213,
+ 12, 131, 170, 39, 241, 127, 148, 53, 229, 122, 65, 217, 203, 27, 95,
+ 25, 50, 79, 206, 54, 140, 159, 90, 146, 255, 161, 232, 185, 203, 219,
+ 97, 157, 55, 241, 87, 26, 191, 155, 58, 255, 192, 200, 9, 185, 234,
+ 65, 164, 155, 223, 226, 247, 136, 169, 118, 165, 127, 12, 7, 251, 111,
+ 53, 204, 45, 26, 198, 183, 63, 231, 113, 112, 242, 80, 98, 242, 233,
+ 252, 139, 193, 247, 66, 57, 195, 170, 228, 100, 62, 226, 207, 31, 61,
+ 50, 160, 221, 171, 233, 91, 13, 13, 11, 21, 86, 183, 225, 130, 248,
+ 211, 207, 118, 6, 158, 31, 75, 76, 47, 238, 4, 26, 7, 175, 52,
+ 24, 180, 101, 62, 82, 119, 202, 30, 191, 143, 68, 19, 211, 189, 43,
+ 77, 140, 223, 116, 59, 103, 80, 15, 215, 102, 100, 28, 152, 241, 9,
+ 142, 115, 135, 139, 75, 248, 230, 93, 11, 24, 111, 220, 110, 180, 195,
+ 227, 215, 158, 51, 176, 236, 179, 211, 227, 140, 125, 219, 181, 49, 116,
+ 44, 52, 59, 120, 224, 141, 130, 248, 179, 18, 166, 247, 215, 95, 52,
+ 244, 217, 227, 109, 108, 190, 97, 94, 102, 199, 71, 201, 122, 44, 235,
+ 152, 194, 25, 126, 30, 114, 215, 48, 117, 220, 141, 204, 150, 117, 244,
+ 179, 144, 182, 114, 218, 2, 245, 156, 178, 71, 12, 31, 23, 44, 190,
+ 163, 210, 237, 146, 211, 132, 212, 141, 19, 149, 52, 97, 137, 5, 141,
+ 31, 94, 237, 177, 163, 127, 80, 143, 15, 17, 175, 74, 183, 94, 154,
+ 98, 191, 45, 54, 180, 237, 213, 110, 199, 165, 241, 37, 126, 64, 188,
+ 117, 105, 81, 154, 207, 78, 125, 169, 206, 92, 89, 126, 71, 145, 164,
+ 138, 205, 17, 239, 69, 143, 103, 134, 109, 193, 74, 254, 213, 185, 144,
+ 224, 114, 37, 46, 77, 65, 188, 247, 154, 109, 52, 180, 57, 18, 205,
+ 175, 107, 250, 85, 208, 149, 29, 61, 49, 155, 210, 212, 195, 207, 71,
+ 179, 123, 209, 90, 126, 96, 173, 207, 50, 181, 161, 35, 199, 32, 173,
+ 178, 85, 51, 254, 230, 153, 43, 252, 135, 127, 108, 205, 200, 245, 50,
+ 164, 96, 217, 148, 39, 181, 13, 47, 134, 27, 249, 79, 7, 13, 11,
+ 78, 59, 252, 19, 190, 118, 206, 244, 104, 239, 74, 99, 90, 137, 213,
+ 89, 239, 206, 141, 107, 60, 79, 223, 234, 33, 226, 233, 47, 77, 53,
+ 246, 110, 48, 154, 31, 82, 184, 119, 227, 46, 155, 46, 234, 176, 236,
+ 185, 117, 76, 179, 132, 49, 253, 12, 116, 8, 198, 190, 177, 121, 236,
+ 13, 56, 246, 245, 63, 36, 166, 162, 48, 71, 101, 97, 142, 86, 39,
+ 39, 27, 112, 142, 162, 166, 42, 44, 115, 249, 81, 209, 48, 3, 206,
+ 229, 244, 229, 230, 57, 63, 14, 115, 30, 55, 33, 55, 11, 231, 124,
+ 4, 216, 201, 87, 160, 27, 25, 160, 27, 147, 166, 150, 52, 160, 110,
+ 116, 158, 5, 122, 0, 58, 84, 1, 116, 40, 166, 122, 146, 1, 117,
+ 232, 41, 216, 251, 37, 160, 107, 9, 160, 107, 195, 51, 139, 24, 80,
+ 215, 238, 64, 153, 30, 116, 50, 29, 116, 178, 206, 104, 165, 1, 117,
+ 114, 41, 180, 187, 6, 116, 119, 40, 232, 110, 3, 159, 97, 6, 212,
+ 221, 115, 83, 173, 58, 158, 59, 116, 70, 22, 234, 184, 122, 20, 49,
+ 221, 128, 181, 48, 8, 214, 66, 93, 160, 197, 181, 80, 124, 62, 196,
+ 67, 176, 102, 82, 97, 205, 84, 126, 209, 222, 128, 107, 230, 235, 21,
+ 196, 148, 12, 107, 235, 21, 172, 173, 106, 211, 75, 25, 42, 193, 218,
+ 186, 4, 54, 118, 30, 172, 193, 242, 176, 6, 203, 156, 157, 105, 192,
+ 53, 56, 7, 218, 104, 12, 107, 245, 26, 172, 213, 241, 73, 1, 6,
+ 92, 171, 15, 231, 18, 147, 39, 172, 233, 205, 176, 166, 15, 62, 89,
+ 110, 192, 53, 93, 84, 111, 182, 7, 215, 193, 30, 100, 13, 127, 146,
+ 133, 246, 224, 239, 153, 196, 100, 4, 187, 225, 13, 118, 99, 89, 223,
+ 65, 6, 180, 27, 35, 1, 111, 19, 216, 151, 25, 96, 95, 54, 46,
+ 171, 110, 64, 251, 226, 53, 211, 108, 135, 142, 131, 29, 154, 123, 226,
+ 159, 44, 180, 67, 45, 192, 7, 244, 7, 123, 85, 10, 236, 85, 235,
+ 1, 189, 13, 104, 175, 154, 131, 204, 103, 193, 174, 157, 5, 187, 166,
+ 89, 236, 99, 64, 187, 198, 237, 39, 166, 26, 96, 255, 6, 155, 237,
+ 159, 1, 237, 223, 199, 128, 55, 30, 236, 164, 214, 108, 39, 13, 104,
+ 39, 189, 83, 205, 246, 116, 8, 216, 211, 222, 151, 151, 103, 161, 61,
+ 77, 93, 76, 4, 187, 251, 28, 236, 174, 231, 251, 145, 6, 180, 187,
+ 197, 15, 154, 237, 243, 5, 176, 207, 215, 126, 77, 54, 160, 125, 62,
+ 158, 174, 176, 216, 241, 82, 49, 145, 6, 180, 227, 85, 183, 17, 211,
+ 106, 176, 247, 157, 192, 222, 119, 15, 123, 207, 128, 246, 254, 235, 149,
+ 196, 84, 24, 252, 194, 41, 240, 11, 213, 190, 245, 50, 160, 95, 216,
+ 189, 202, 236, 63, 226, 192, 127, 180, 60, 74, 12, 232, 63, 190, 2,
+ 63, 72, 253, 76, 213, 128, 173, 89, 232, 103, 78, 173, 54, 251, 163,
+ 30, 224, 143, 178, 127, 251, 41, 11, 253, 209, 187, 203, 205, 126, 43,
+ 13, 252, 86, 191, 38, 25, 89, 232, 183, 110, 46, 33, 166, 28, 240,
+ 111, 7, 193, 191, 249, 92, 43, 100, 64, 255, 118, 113, 163, 194, 180,
+ 7, 252, 224, 83, 240, 131, 33, 27, 42, 24, 208, 15, 22, 27, 108,
+ 245, 151, 51, 15, 84, 203, 66, 127, 217, 42, 73, 97, 241, 181, 254,
+ 89, 126, 89, 232, 107, 231, 37, 152, 125, 242, 111, 224, 147, 83, 74,
+ 29, 204, 66, 159, 124, 29, 244, 175, 163, 232, 187, 235, 229, 128, 110,
+ 130, 239, 46, 10, 62, 175, 63, 248, 248, 190, 224, 227, 171, 165, 77,
+ 48, 160, 143, 31, 219, 83, 97, 250, 9, 98, 129, 9, 16, 11, 108,
+ 78, 175, 108, 192, 88, 96, 210, 72, 107, 204, 80, 119, 91, 104, 22,
+ 198, 12, 185, 96, 255, 126, 132, 120, 227, 25, 196, 27, 167, 202, 142,
+ 51, 96, 188, 145, 94, 26, 214, 165, 24, 151, 76, 254, 152, 55, 96,
+ 92, 178, 234, 164, 194, 212, 28, 226, 151, 27, 16, 191, 252, 83, 51,
+ 202, 128, 241, 203, 179, 219, 196, 116, 92, 140, 115, 22, 111, 244, 53,
+ 96, 156, 179, 12, 214, 106, 178, 24, 15, 29, 27, 85, 193, 128, 241,
+ 80, 18, 230, 148, 65, 220, 180, 12, 226, 166, 11, 115, 66, 13, 24,
+ 55, 237, 195, 188, 73, 136, 175, 84, 220, 201, 176, 129, 35, 219, 24,
+ 48, 190, 170, 14, 54, 187, 27, 196, 97, 89, 16, 135, 109, 90, 220,
+ 209, 128, 113, 216, 237, 36, 98, 218, 14, 241, 90, 3, 136, 215, 154,
+ 31, 24, 110, 192, 120, 109, 44, 172, 213, 30, 16, 215, 213, 129, 184,
+ 238, 208, 222, 51, 6, 140, 235, 170, 194, 26, 68, 90, 35, 208, 122,
+ 221, 61, 106, 192, 248, 47, 4, 226, 176, 239, 33, 78, 92, 15, 113,
+ 226, 87, 119, 102, 26, 48, 78, 12, 4, 126, 143, 161, 93, 13, 180,
+ 187, 89, 127, 194, 128, 241, 228, 57, 88, 91, 17, 162, 124, 109, 186,
+ 100, 26, 48, 238, 44, 1, 122, 159, 8, 253, 248, 30, 250, 81, 160,
+ 235, 7, 6, 140, 79, 91, 206, 38, 166, 163, 208, 223, 58, 208, 223,
+ 42, 209, 179, 13, 24, 199, 14, 239, 66, 44, 227, 18, 51, 99, 189,
+ 1, 227, 221, 229, 191, 192, 152, 66, 92, 252, 5, 196, 197, 51, 122,
+ 47, 51, 96, 92, 252, 241, 14, 133, 169, 1, 196, 207, 205, 32, 126,
+ 238, 219, 115, 147, 1, 227, 231, 50, 208, 143, 21, 16, 103, 63, 132,
+ 56, 187, 18, 240, 195, 56, 187, 23, 172, 233, 230, 16, 143, 231, 64,
+ 60, 94, 40, 117, 187, 1, 227, 241, 186, 211, 20, 166, 45, 16, 183,
+ 143, 131, 184, 253, 239, 243, 41, 6, 140, 219, 15, 3, 94, 37, 49,
+ 190, 63, 210, 188, 189, 1, 227, 251, 6, 48, 6, 116, 31, 128, 101,
+ 184, 15, 168, 86, 76, 97, 186, 5, 251, 133, 138, 48, 151, 223, 220,
+ 77, 49, 224, 126, 33, 178, 32, 248, 115, 152, 95, 44, 107, 84, 127,
+ 143, 1, 247, 21, 77, 155, 42, 76, 9, 176, 255, 208, 193, 254, 99,
+ 131, 223, 42, 3, 238, 63, 234, 67, 187, 85, 96, 159, 50, 11, 246,
+ 41, 69, 61, 198, 24, 112, 159, 226, 15, 250, 87, 1, 246, 51, 221,
+ 96, 63, 179, 162, 239, 104, 3, 238, 103, 174, 130, 44, 90, 216, 247,
+ 84, 128, 125, 79, 101, 232, 7, 238, 123, 214, 189, 132, 181, 15, 251,
+ 163, 146, 176, 63, 170, 183, 102, 129, 1, 247, 71, 101, 64, 62, 29,
+ 236, 163, 80, 215, 82, 119, 100, 24, 112, 31, 181, 229, 23, 235, 62,
+ 175, 251, 194, 69, 7, 112, 191, 213, 191, 142, 194, 178, 47, 139, 209,
+ 44, 203, 194, 125, 217, 192, 201, 214, 253, 91, 242, 87, 51, 179, 112,
+ 255, 246, 39, 179, 191, 124, 144, 89, 55, 11, 247, 121, 99, 31, 88,
+ 247, 131, 179, 77, 53, 178, 112, 63, 88, 191, 132, 66, 216, 55, 30,
+ 135, 125, 99, 82, 212, 145, 44, 220, 55, 126, 232, 97, 221, 231, 221,
+ 29, 27, 100, 192, 253, 101, 213, 90, 196, 164, 18, 247, 161, 131, 150,
+ 86, 54, 224, 62, 244, 196, 175, 10, 203, 126, 117, 222, 164, 31, 178,
+ 112, 191, 58, 156, 179, 182, 59, 127, 100, 93, 3, 238, 107, 135, 63,
+ 36, 150, 253, 239, 135, 128, 39, 236, 127, 167, 90, 247, 201, 157, 99,
+ 239, 101, 225, 62, 121, 56, 216, 216, 219, 98, 63, 138, 245, 111, 104,
+ 192, 253, 180, 10, 240, 112, 223, 221, 14, 246, 221, 93, 1, 15, 247,
+ 221, 49, 5, 192, 207, 192, 254, 252, 16, 236, 207, 235, 131, 175, 192,
+ 253, 121, 69, 189, 121, 92, 58, 195, 184, 36, 87, 29, 96, 192, 125,
+ 124, 58, 232, 105, 71, 216, 239, 239, 132, 253, 62, 250, 35, 220, 239,
+ 15, 211, 155, 115, 56, 87, 21, 194, 119, 150, 245, 244, 242, 23, 207,
+ 5, 114, 131, 99, 189, 44, 239, 93, 99, 224, 4, 6, 14, 96, 224,
+ 220, 32, 6, 159, 129, 19, 24, 56, 128, 129, 115, 3, 25, 124, 6,
+ 78, 96, 224, 0, 6, 206, 13, 96, 240, 25, 56, 129, 129, 3, 24,
+ 56, 167, 145, 21, 78, 99, 96, 29, 3, 171, 24, 56, 199, 159, 193,
+ 103, 96, 29, 3, 171, 24, 56, 167, 33, 131, 207, 192, 58, 6, 86,
+ 49, 112, 78, 3, 6, 159, 129, 117, 12, 172, 98, 224, 156, 250, 12,
+ 62, 3, 235, 24, 88, 197, 192, 57, 245, 24, 124, 6, 214, 49, 176,
+ 138, 129, 115, 234, 50, 248, 12, 172, 99, 96, 21, 3, 231, 212, 97,
+ 240, 25, 88, 199, 192, 42, 6, 206, 169, 205, 224, 51, 176, 142, 129,
+ 85, 12, 156, 83, 139, 193, 103, 96, 29, 3, 171, 24, 56, 167, 38,
+ 131, 207, 192, 58, 6, 86, 49, 112, 78, 13, 6, 159, 129, 117, 12,
+ 172, 4, 152, 30, 226, 25, 171, 91, 225, 4, 6, 14, 168, 206, 232,
+ 100, 53, 70, 39, 25, 88, 87, 205, 138, 175, 100, 224, 108, 63, 43,
+ 78, 42, 3, 231, 164, 48, 178, 49, 176, 142, 129, 85, 12, 156, 61,
+ 197, 202, 51, 117, 138, 181, 92, 195, 148, 231, 78, 182, 194, 233, 147,
+ 25, 158, 76, 185, 146, 129, 179, 223, 103, 100, 99, 96, 45, 3, 43,
+ 25, 56, 251, 61, 6, 159, 129, 181, 12, 172, 100, 96, 227, 36, 102,
+ 60, 25, 88, 197, 192, 217, 19, 173, 176, 158, 129, 3, 24, 56, 119,
+ 2, 51, 86, 19, 172, 229, 90, 6, 38, 12, 108, 28, 111, 197, 215,
+ 51, 176, 134, 129, 115, 199, 89, 241, 211, 24, 88, 203, 192, 202, 113,
+ 76, 223, 199, 50, 125, 103, 96, 45, 3, 147, 177, 204, 248, 39, 91,
+ 97, 29, 3, 43, 25, 56, 59, 137, 225, 201, 192, 90, 6, 86, 50,
+ 112, 118, 34, 131, 207, 192, 90, 6, 86, 50, 176, 113, 12, 51, 254,
+ 12, 28, 48, 134, 209, 195, 4, 70, 175, 24, 88, 195, 192, 57, 163,
+ 153, 241, 103, 96, 29, 3, 171, 24, 56, 39, 158, 193, 103, 96, 109,
+ 60, 51, 95, 12, 108, 28, 197, 204, 23, 3, 107, 24, 56, 119, 36,
+ 51, 95, 12, 172, 101, 96, 229, 72, 102, 172, 70, 48, 99, 197, 192,
+ 90, 6, 86, 50, 112, 246, 112, 6, 159, 129, 181, 12, 172, 100, 224,
+ 236, 56, 6, 159, 129, 181, 12, 172, 100, 224, 236, 88, 6, 159, 129,
+ 181, 12, 172, 100, 224, 236, 97, 12, 62, 3, 107, 25, 88, 201, 192,
+ 217, 67, 25, 124, 6, 214, 50, 176, 146, 129, 179, 99, 24, 124, 6,
+ 214, 50, 176, 146, 129, 179, 135, 48, 248, 12, 172, 101, 96, 37, 3,
+ 103, 15, 102, 240, 25, 88, 203, 192, 74, 6, 206, 30, 196, 224, 51,
+ 176, 150, 129, 149, 12, 156, 29, 205, 224, 51, 176, 150, 129, 149, 12,
+ 156, 173, 99, 116, 76, 199, 232, 57, 83, 158, 83, 156, 209, 91, 6,
+ 214, 49, 176, 138, 129, 115, 138, 49, 248, 12, 172, 99, 96, 101, 49,
+ 70, 207, 139, 50, 235, 145, 129, 3, 138, 50, 122, 238, 195, 248, 23,
+ 6, 166, 239, 176, 198, 24, 173, 161, 248, 124, 167, 144, 248, 220, 139,
+ 254, 206, 133, 143, 24, 183, 185, 170, 79, 144, 169, 15, 144, 169, 199,
+ 152, 207, 101, 251, 50, 245, 9, 76, 125, 17, 177, 158, 254, 78, 134,
+ 143, 24, 47, 186, 170, 199, 24, 210, 85, 125, 58, 83, 95, 84, 172,
+ 167, 191, 131, 225, 35, 198, 154, 174, 234, 3, 100, 234, 49, 38, 117,
+ 85, 159, 30, 224, 90, 190, 132, 0, 153, 241, 151, 169, 199, 24, 215,
+ 85, 251, 105, 76, 125, 25, 177, 158, 254, 14, 132, 143, 24, 11, 187,
+ 170, 87, 49, 245, 165, 196, 122, 250, 59, 22, 62, 98, 204, 236, 170,
+ 62, 141, 169, 47, 65, 159, 203, 86, 97, 218, 151, 169, 87, 249, 187,
+ 150, 15, 99, 112, 151, 237, 203, 212, 235, 26, 202, 180, 47, 83, 143,
+ 49, 189, 171, 250, 52, 153, 122, 29, 83, 95, 156, 202, 167, 99, 218,
+ 151, 169, 199, 61, 130, 203, 254, 203, 212, 235, 234, 203, 244, 95, 166,
+ 30, 247, 28, 46, 251, 95, 207, 181, 252, 58, 153, 122, 149, 76, 61,
+ 238, 97, 92, 213, 167, 201, 212, 235, 234, 202, 244, 95, 166, 30, 247,
+ 68, 46, 251, 95, 71, 102, 252, 101, 234, 85, 117, 100, 244, 191, 182,
+ 235, 250, 52, 166, 94, 33, 214, 211, 223, 177, 242, 17, 247, 98, 180,
+ 158, 163, 242, 251, 51, 237, 203, 212, 227, 158, 205, 85, 125, 154, 76,
+ 189, 174, 150, 107, 249, 84, 50, 245, 184, 7, 116, 85, 159, 86, 83,
+ 166, 125, 153, 122, 149, 12, 127, 220, 83, 186, 108, 95, 166, 94, 231,
+ 162, 222, 87, 220, 143, 54, 20, 235, 60, 169, 255, 40, 243, 88, 33,
+ 254, 214, 46, 79, 127, 83, 204, 87, 220, 175, 58, 195, 45, 32, 226,
+ 210, 223, 255, 242, 21, 247, 179, 20, 183, 32, 237, 247, 96, 138, 171,
+ 183, 224, 250, 136, 251, 93, 42, 35, 139, 107, 241, 129, 213, 92, 215,
+ 167, 51, 245, 246, 252, 125, 197, 189, 50, 149, 197, 131, 250, 48, 232,
+ 151, 248, 155, 10, 60, 253, 221, 51, 95, 113, 47, 237, 206, 120, 248,
+ 136, 123, 109, 218, 46, 139, 75, 235, 83, 253, 164, 229, 242, 17, 247,
+ 228, 174, 234, 211, 82, 100, 230, 86, 166, 94, 149, 226, 122, 238, 113,
+ 143, 239, 108, 92, 196, 56, 209, 134, 87, 234, 20, 215, 188, 52, 83,
+ 220, 155, 111, 95, 241, 220, 192, 29, 61, 242, 17, 207, 21, 92, 206,
+ 237, 100, 247, 117, 82, 57, 217, 149, 140, 182, 237, 226, 89, 5, 109,
+ 215, 139, 218, 189, 186, 204, 120, 200, 212, 107, 101, 234, 149, 50, 245,
+ 120, 246, 225, 178, 125, 153, 122, 173, 76, 189, 146, 169, 103, 231, 222,
+ 178, 214, 39, 217, 143, 43, 145, 180, 11, 9, 147, 220, 183, 33, 170,
+ 60, 224, 226, 89, 141, 59, 250, 233, 43, 158, 229, 184, 139, 27, 48,
+ 209, 125, 61, 192, 179, 32, 87, 122, 159, 54, 193, 253, 254, 104, 39,
+ 184, 175, 171, 100, 130, 251, 246, 19, 207, 159, 92, 217, 71, 189, 76,
+ 189, 102, 188, 235, 53, 134, 103, 87, 238, 218, 207, 180, 113, 121, 24,
+ 15, 6, 151, 109, 87, 164, 83, 179, 182, 84, 57, 206, 181, 173, 196,
+ 243, 50, 151, 182, 120, 172, 107, 91, 169, 29, 235, 122, 158, 201, 88,
+ 247, 245, 11, 207, 226, 220, 29, 3, 93, 30, 112, 149, 201, 238, 173,
+ 73, 31, 241, 172, 79, 106, 125, 251, 136, 231, 127, 180, 222, 155, 246,
+ 215, 143, 25, 15, 153, 122, 165, 76, 61, 158, 29, 186, 170, 79, 149,
+ 169, 215, 202, 212, 43, 93, 212, 251, 138, 103, 145, 238, 172, 113, 95,
+ 241, 172, 210, 93, 127, 20, 48, 198, 245, 90, 193, 243, 77, 119, 215,
+ 120, 106, 130, 251, 62, 83, 147, 224, 190, 175, 198, 243, 83, 151, 49,
+ 163, 76, 189, 78, 166, 94, 53, 90, 38, 174, 137, 151, 137, 107, 226,
+ 165, 215, 170, 175, 120, 110, 235, 238, 154, 32, 241, 238, 217, 38, 31,
+ 241, 220, 215, 149, 92, 250, 81, 50, 118, 210, 69, 189, 175, 120, 102,
+ 236, 238, 124, 166, 141, 116, 95, 79, 180, 35, 221, 143, 73, 149, 35,
+ 93, 207, 29, 158, 83, 187, 170, 79, 149, 169, 215, 202, 212, 43, 153,
+ 122, 154, 39, 79, 127, 87, 217, 71, 60, 247, 118, 85, 159, 58, 92,
+ 166, 125, 153, 122, 165, 12, 127, 60, 71, 119, 217, 190, 76, 189, 86,
+ 166, 94, 201, 212, 151, 165, 58, 48, 133, 105, 63, 214, 117, 125, 42,
+ 83, 95, 154, 234, 179, 7, 211, 190, 76, 189, 146, 169, 47, 73, 117,
+ 165, 0, 211, 254, 48, 215, 245, 169, 50, 245, 90, 166, 94, 73, 245,
+ 218, 139, 105, 95, 166, 30, 159, 27, 184, 170, 79, 149, 169, 215, 202,
+ 212, 43, 135, 202, 244, 63, 70, 166, 255, 50, 245, 218, 24, 153, 241,
+ 151, 169, 199, 231, 26, 46, 251, 47, 83, 175, 29, 226, 90, 62, 165,
+ 76, 61, 62, 39, 113, 217, 127, 153, 122, 237, 96, 153, 254, 203, 212,
+ 227, 115, 23, 151, 250, 63, 72, 166, 125, 153, 122, 229, 32, 153, 246,
+ 163, 93, 215, 167, 70, 187, 150, 79, 43, 83, 175, 100, 234, 139, 209,
+ 125, 87, 33, 166, 125, 157, 181, 190, 48, 165, 47, 198, 236, 99, 116,
+ 86, 91, 207, 214, 251, 80, 91, 83, 132, 241, 71, 12, 47, 103, 245,
+ 248, 124, 201, 149, 44, 105, 50, 245, 58, 153, 122, 149, 76, 61, 62,
+ 175, 114, 37, 95, 154, 76, 189, 206, 69, 189, 175, 248, 172, 203, 157,
+ 177, 242, 21, 159, 133, 185, 139, 155, 80, 212, 253, 57, 8, 40, 42,
+ 61, 159, 62, 226, 243, 53, 87, 245, 233, 46, 234, 119, 195, 160, 226,
+ 119, 186, 234, 89, 190, 171, 229, 41, 252, 138, 172, 146, 252, 202, 97,
+ 4, 99, 254, 29, 174, 231, 156, 167, 240, 203, 72, 248, 219, 162, 89,
+ 28, 254, 154, 40, 190, 37, 172, 6, 217, 196, 121, 1, 71, 140, 141,
+ 253, 72, 48, 87, 72, 120, 243, 24, 174, 153, 222, 0, 23, 17, 198,
+ 83, 69, 198, 113, 69, 128, 74, 208, 91, 146, 200, 121, 11, 111, 45,
+ 195, 223, 86, 106, 6, 112, 97, 241, 183, 170, 18, 184, 194, 164, 16,
+ 224, 40, 137, 63, 201, 5, 254, 222, 194, 155, 205, 148, 164, 63, 135,
+ 191, 93, 138, 111, 60, 43, 65, 126, 226, 10, 0, 84, 20, 164, 168,
+ 76, 118, 112, 120, 18, 94, 12, 100, 42, 79, 238, 3, 255, 194, 194,
+ 249, 67, 73, 50, 4, 96, 47, 33, 46, 82, 145, 30, 28, 254, 174,
+ 87, 17, 225, 76, 59, 25, 224, 34, 66, 121, 77, 18, 192, 149, 18,
+ 222, 187, 87, 26, 254, 109, 229, 240, 253, 125, 126, 112, 223, 128, 188,
+ 199, 149, 22, 222, 217, 87, 6, 248, 108, 225, 240, 173, 126, 213, 224,
+ 222, 151, 60, 224, 240, 109, 127, 213, 133, 119, 172, 157, 231, 202, 8,
+ 239, 243, 195, 223, 252, 186, 203, 85, 20, 222, 200, 135, 191, 195, 53,
+ 158, 43, 43, 252, 242, 22, 254, 206, 215, 11, 14, 223, 223, 87, 75,
+ 248, 13, 175, 95, 184, 202, 194, 187, 255, 106, 0, 230, 90, 174, 10,
+ 64, 181, 133, 223, 240, 122, 197, 213, 36, 117, 0, 174, 5, 178, 61,
+ 224, 202, 9, 191, 250, 133, 227, 208, 147, 195, 95, 12, 43, 41, 244,
+ 101, 60, 135, 191, 58, 22, 32, 142, 97, 9, 225, 215, 182, 202, 65,
+ 43, 127, 115, 37, 197, 119, 231, 149, 34, 99, 128, 182, 17, 17, 206,
+ 60, 96, 108, 125, 1, 246, 23, 224, 166, 128, 163, 18, 206, 226, 85,
+ 192, 179, 36, 208, 169, 4, 158, 9, 0, 227, 155, 247, 8, 148, 140,
+ 225, 240, 55, 205, 252, 133, 49, 233, 198, 225, 59, 215, 240, 55, 189,
+ 170, 144, 94, 192, 7, 127, 229, 171, 60, 200, 115, 3, 198, 161, 33,
+ 140, 77, 5, 248, 247, 152, 195, 183, 178, 225, 27, 2, 43, 2, 126,
+ 25, 24, 131, 250, 112, 87, 10, 100, 171, 0, 159, 245, 161, 180, 60,
+ 201, 132, 49, 169, 47, 188, 81, 176, 60, 249, 13, 198, 164, 146, 240,
+ 214, 193, 82, 32, 115, 37, 224, 92, 23, 238, 74, 145, 37, 28, 190,
+ 139, 176, 46, 180, 90, 5, 230, 40, 152, 132, 136, 239, 16, 28, 207,
+ 5, 9, 111, 216, 107, 33, 232, 94, 19, 248, 108, 46, 200, 63, 22,
+ 224, 230, 194, 251, 4, 91, 129, 108, 65, 226, 187, 5, 75, 193, 92,
+ 7, 9, 191, 17, 102, 150, 63, 158, 132, 139, 239, 4, 28, 15, 112,
+ 160, 240, 222, 64, 13, 73, 2, 56, 148, 140, 22, 96, 44, 15, 19,
+ 222, 9, 168, 129, 177, 10, 21, 126, 105, 204, 60, 230, 248, 59, 98,
+ 136, 83, 13, 198, 39, 8, 228, 9, 22, 248, 196, 0, 76, 223, 15,
+ 24, 196, 53, 5, 74, 243, 59, 248, 198, 1, 220, 65, 104, 183, 52,
+ 41, 5, 112, 71, 241, 93, 126, 221, 56, 124, 43, 97, 71, 17, 14,
+ 35, 157, 68, 56, 24, 96, 181, 248, 238, 191, 193, 28, 190, 209, 80,
+ 45, 242, 236, 96, 121, 39, 224, 16, 78, 77, 162, 44, 56, 67, 8,
+ 132, 244, 66, 223, 199, 3, 172, 17, 222, 105, 168, 130, 190, 224, 219,
+ 22, 155, 8, 115, 215, 148, 195, 55, 41, 6, 9, 176, 134, 11, 1,
+ 57, 155, 8, 56, 201, 0, 55, 17, 198, 83, 5, 125, 137, 35, 157,
+ 5, 57, 107, 0, 159, 102, 0, 55, 23, 198, 42, 136, 171, 10, 154,
+ 135, 111, 53, 68, 61, 172, 13, 122, 24, 33, 252, 198, 217, 5, 40,
+ 143, 36, 194, 111, 70, 195, 56, 215, 33, 221, 197, 247, 33, 6, 115,
+ 248, 75, 123, 189, 73, 47, 128, 167, 192, 122, 44, 78, 122, 194, 93,
+ 121, 192, 239, 5, 159, 125, 200, 59, 130, 77, 232, 1, 245, 239, 144,
+ 190, 0, 31, 16, 172, 72, 47, 210, 3, 52, 189, 15, 192, 61, 0,
+ 191, 56, 104, 194, 26, 174, 53, 72, 211, 65, 208, 195, 158, 0, 199,
+ 137, 99, 24, 13, 112, 7, 210, 79, 104, 171, 52, 140, 73, 39, 17,
+ 14, 226, 240, 77, 138, 253, 196, 241, 124, 135, 12, 32, 253, 5, 254,
+ 205, 184, 54, 228, 93, 104, 23, 203, 203, 1, 237, 187, 226, 123, 24,
+ 99, 160, 188, 15, 233, 38, 192, 17, 0, 119, 35, 109, 5, 24, 127,
+ 148, 62, 138, 12, 20, 224, 182, 0, 247, 23, 222, 207, 168, 129, 126,
+ 13, 134, 145, 29, 40, 244, 183, 49, 192, 3, 137, 78, 128, 135, 114,
+ 131, 0, 86, 11, 112, 51, 128, 117, 34, 206, 24, 46, 10, 104, 7,
+ 8, 124, 146, 1, 30, 96, 145, 243, 93, 128, 204, 229, 99, 1, 110,
+ 45, 150, 107, 184, 190, 132, 23, 223, 59, 89, 19, 224, 254, 226, 187,
+ 41, 85, 92, 31, 144, 121, 128, 48, 110, 58, 78, 11, 50, 247, 196,
+ 92, 8, 104, 75, 11, 50, 155, 251, 213, 18, 240, 181, 66, 57, 234,
+ 103, 95, 224, 162, 21, 251, 165, 6, 105, 204, 239, 151, 84, 114, 93,
+ 97, 182, 218, 139, 58, 223, 21, 86, 84, 59, 97, 108, 91, 113, 248,
+ 118, 207, 118, 162, 62, 84, 1, 168, 174, 176, 94, 148, 92, 93, 210,
+ 149, 116, 17, 236, 225, 80, 174, 37, 204, 111, 23, 145, 182, 46, 64,
+ 221, 133, 242, 198, 48, 239, 117, 5, 184, 36, 233, 202, 5, 138, 239,
+ 226, 172, 1, 115, 52, 8, 224, 64, 129, 103, 36, 232, 149, 249, 221,
+ 151, 42, 82, 3, 224, 54, 100, 184, 0, 183, 225, 240, 183, 240, 70,
+ 137, 246, 167, 13, 64, 230, 242, 106, 220, 40, 225, 55, 242, 204, 118,
+ 108, 20, 64, 35, 69, 24, 127, 55, 111, 132, 5, 30, 33, 150, 39,
+ 114, 145, 36, 86, 44, 31, 15, 240, 8, 177, 47, 1, 220, 48, 40,
+ 143, 20, 230, 46, 16, 224, 72, 225, 93, 156, 26, 88, 59, 195, 0,
+ 138, 16, 231, 113, 24, 64, 67, 133, 242, 161, 92, 4, 244, 36, 90,
+ 228, 31, 1, 208, 80, 145, 127, 52, 148, 183, 20, 199, 39, 26, 160,
+ 24, 81, 231, 99, 0, 214, 8, 112, 45, 128, 129, 179, 0, 15, 129,
+ 177, 162, 239, 229, 28, 7, 176, 86, 156, 83, 45, 215, 69, 120, 51,
+ 167, 89, 31, 186, 0, 164, 21, 203, 187, 65, 185, 121, 94, 26, 115,
+ 248, 118, 207, 182, 226, 188, 159, 34, 39, 201, 9, 114, 28, 96, 3,
+ 119, 154, 156, 2, 232, 24, 192, 47, 185, 227, 228, 27, 114, 84, 128,
+ 47, 114, 39, 200, 17, 184, 59, 14, 99, 222, 157, 251, 6, 224, 67,
+ 130, 111, 29, 202, 29, 38, 7, 5, 184, 52, 248, 214, 195, 196, 40,
+ 252, 216, 38, 218, 132, 131, 0, 239, 23, 125, 235, 17, 98, 16, 224,
+ 72, 50, 12, 224, 253, 2, 62, 218, 180, 67, 0, 27, 201, 97, 193,
+ 183, 158, 32, 89, 128, 117, 4, 240, 215, 114, 39, 201, 1, 184, 59,
+ 1, 243, 158, 193, 29, 3, 9, 12, 112, 87, 142, 92, 6, 217, 142,
+ 1, 116, 0, 116, 230, 31, 224, 255, 141, 216, 110, 32, 192, 71, 225,
+ 14, 219, 237, 202, 25, 64, 130, 253, 130, 206, 140, 1, 248, 168, 32,
+ 79, 117, 208, 231, 61, 100, 55, 249, 154, 108, 2, 252, 129, 92, 38,
+ 124, 126, 77, 50, 192, 203, 221, 227, 118, 147, 93, 228, 43, 184, 243,
+ 5, 249, 51, 224, 243, 43, 178, 29, 116, 236, 5, 183, 29, 160, 141,
+ 100, 27, 200, 179, 151, 219, 69, 118, 2, 252, 21, 192, 73, 220, 54,
+ 128, 190, 36, 91, 1, 254, 147, 219, 73, 210, 1, 222, 8, 240, 3,
+ 46, 157, 108, 33, 235, 225, 78, 73, 118, 113, 91, 225, 115, 61, 217,
+ 0, 50, 247, 231, 182, 144, 205, 228, 11, 184, 83, 146, 39, 220, 6,
+ 248, 252, 130, 172, 3, 217, 94, 112, 59, 64, 134, 76, 97, 28, 122,
+ 114, 251, 200, 94, 178, 67, 232, 203, 120, 128, 87, 145, 189, 226, 24,
+ 238, 131, 210, 213, 112, 95, 151, 60, 228, 246, 194, 231, 106, 225, 57,
+ 116, 50, 208, 102, 10, 48, 234, 76, 38, 249, 84, 132, 7, 3, 206,
+ 30, 224, 106, 246, 173, 123, 1, 50, 243, 76, 0, 120, 53, 96, 161,
+ 77, 78, 6, 248, 83, 192, 194, 49, 233, 6, 99, 242, 41, 249, 12,
+ 198, 165, 10, 89, 15, 124, 50, 0, 254, 20, 230, 55, 17, 198, 97,
+ 59, 73, 131, 59, 244, 173, 187, 225, 51, 13, 198, 168, 34, 89, 7,
+ 227, 144, 70, 62, 135, 177, 64, 31, 186, 29, 198, 230, 115, 184, 47,
+ 69, 190, 135, 49, 217, 74, 214, 192, 29, 250, 220, 157, 240, 185, 6,
+ 198, 165, 60, 200, 156, 14, 208, 90, 24, 151, 242, 224, 91, 183, 194,
+ 120, 172, 133, 251, 42, 96, 111, 87, 144, 229, 100, 145, 184, 198, 87,
+ 146, 197, 96, 255, 151, 128, 156, 6, 110, 25, 64, 139, 133, 49, 25,
+ 11, 240, 82, 193, 47, 128, 61, 0, 156, 165, 100, 153, 208, 247, 64,
+ 128, 151, 192, 157, 89, 254, 120, 242, 9, 249, 216, 226, 91, 63, 22,
+ 236, 0, 250, 208, 120, 240, 154, 11, 5, 120, 28, 192, 11, 1, 203,
+ 92, 190, 16, 56, 46, 21, 199, 103, 33, 224, 52, 23, 99, 188, 149,
+ 100, 133, 40, 79, 19, 128, 23, 9, 50, 40, 201, 32, 110, 41, 153,
+ 46, 240, 193, 121, 95, 10, 237, 206, 16, 236, 79, 27, 128, 103, 144,
+ 233, 162, 253, 95, 8, 208, 39, 34, 252, 9, 192, 211, 4, 120, 40,
+ 192, 211, 72, 170, 0, 55, 5, 56, 85, 148, 115, 16, 55, 3, 202,
+ 205, 180, 129, 92, 42, 192, 83, 69, 156, 33, 224, 89, 23, 136, 54,
+ 97, 8, 64, 243, 69, 120, 5, 244, 124, 185, 48, 119, 131, 1, 94,
+ 41, 140, 67, 57, 176, 153, 139, 0, 90, 44, 218, 255, 69, 128, 177,
+ 204, 226, 91, 151, 128, 71, 197, 49, 76, 226, 150, 64, 15, 59, 139,
+ 250, 191, 153, 124, 72, 230, 130, 246, 161, 30, 126, 1, 208, 60, 208,
+ 67, 37, 217, 9, 229, 179, 160, 6, 105, 187, 115, 235, 160, 244, 125,
+ 81, 254, 83, 100, 34, 153, 0, 118, 65, 73, 126, 135, 245, 56, 129,
+ 76, 18, 214, 221, 78, 110, 34, 25, 71, 198, 195, 61, 218, 132, 247,
+ 200, 88, 184, 155, 8, 240, 21, 88, 155, 239, 1, 116, 10, 44, 252,
+ 231, 0, 31, 0, 252, 247, 32, 18, 235, 193, 125, 0, 99, 181, 68,
+ 208, 195, 158, 0, 47, 1, 239, 138, 99, 216, 24, 224, 100, 97, 60,
+ 209, 167, 204, 0, 120, 154, 56, 62, 211, 0, 158, 42, 142, 231, 56,
+ 224, 159, 68, 18, 1, 62, 203, 205, 129, 86, 199, 136, 190, 242, 3,
+ 50, 71, 132, 155, 64, 249, 100, 168, 65, 184, 36, 192, 179, 225, 14,
+ 225, 238, 220, 2, 146, 32, 242, 41, 7, 240, 84, 224, 99, 182, 189,
+ 131, 161, 220, 60, 206, 209, 0, 235, 72, 130, 0, 7, 129, 31, 73,
+ 21, 225, 97, 0, 39, 136, 62, 55, 129, 155, 10, 237, 39, 9, 124,
+ 198, 0, 156, 12, 119, 102, 57, 199, 0, 148, 44, 250, 214, 49, 0,
+ 125, 32, 250, 190, 177, 48, 115, 11, 68, 223, 58, 22, 160, 36, 209,
+ 198, 142, 135, 145, 74, 4, 169, 209, 183, 166, 192, 232, 140, 23, 246,
+ 26, 195, 0, 30, 47, 202, 92, 26, 240, 39, 145, 20, 209, 38, 140,
+ 5, 104, 190, 216, 175, 84, 144, 63, 65, 244, 221, 83, 200, 76, 152,
+ 49, 179, 206, 79, 1, 104, 173, 48, 182, 101, 193, 206, 204, 2, 75,
+ 99, 214, 135, 45, 80, 58, 75, 88, 47, 26, 110, 45, 209, 147, 41,
+ 130, 61, 12, 230, 62, 2, 248, 125, 145, 118, 45, 64, 122, 161, 60,
+ 26, 230, 253, 125, 145, 79, 15, 240, 173, 31, 11, 122, 91, 13, 230,
+ 104, 16, 172, 168, 84, 129, 167, 18, 244, 106, 142, 208, 71, 216, 161,
+ 0, 60, 28, 238, 16, 198, 49, 31, 5, 163, 110, 182, 63, 115, 160,
+ 220, 236, 103, 85, 224, 79, 103, 138, 229, 73, 0, 143, 132, 59, 179,
+ 189, 154, 9, 126, 115, 150, 88, 62, 19, 202, 71, 136, 227, 252, 33,
+ 64, 177, 98, 92, 253, 33, 96, 152, 203, 117, 224, 55, 63, 20, 202,
+ 53, 2, 60, 87, 208, 85, 179, 159, 157, 71, 230, 138, 243, 56, 12,
+ 60, 232, 60, 161, 60, 136, 155, 7, 254, 244, 125, 145, 255, 60, 40,
+ 143, 22, 249, 71, 147, 143, 196, 242, 49, 0, 199, 192, 29, 194, 221,
+ 192, 159, 206, 23, 225, 234, 0, 15, 17, 215, 93, 0, 140, 85, 138,
+ 48, 62, 184, 246, 63, 130, 210, 20, 209, 135, 234, 97, 182, 166, 136,
+ 250, 160, 135, 210, 201, 98, 249, 100, 232, 161, 185, 60, 26, 224, 217,
+ 66, 127, 113, 222, 113, 47, 171, 237, 99, 126, 47, 73, 3, 113, 47,
+ 219, 35, 219, 135, 191, 83, 234, 138, 250, 246, 170, 130, 188, 166, 250,
+ 56, 245, 47, 125, 139, 243, 7, 114, 38, 170, 219, 205, 244, 227, 171,
+ 103, 123, 58, 188, 87, 165, 111, 141, 196, 109, 154, 119, 97, 126, 188,
+ 197, 28, 214, 28, 243, 123, 71, 188, 19, 158, 170, 189, 62, 251, 65,
+ 189, 111, 252, 63, 234, 85, 234, 36, 11, 63, 202, 223, 158, 207, 181,
+ 99, 135, 131, 51, 134, 58, 242, 161, 116, 148, 207, 31, 190, 207, 213,
+ 23, 103, 122, 168, 87, 87, 40, 200, 215, 126, 252, 56, 220, 158, 79,
+ 142, 49, 49, 252, 187, 254, 142, 124, 104, 63, 40, 63, 74, 127, 209,
+ 163, 8, 95, 246, 234, 125, 7, 62, 195, 66, 199, 108, 217, 209, 217,
+ 145, 15, 165, 235, 244, 179, 39, 223, 163, 194, 14, 11, 189, 212, 123,
+ 103, 198, 183, 121, 190, 190, 80, 168, 35, 31, 21, 255, 68, 189, 169,
+ 100, 11, 11, 159, 39, 253, 30, 170, 15, 180, 189, 46, 201, 103, 243,
+ 157, 42, 189, 219, 246, 147, 230, 67, 233, 11, 55, 253, 75, 221, 125,
+ 237, 213, 48, 41, 62, 157, 210, 59, 235, 250, 86, 116, 228, 67, 233,
+ 169, 60, 114, 124, 118, 252, 101, 232, 221, 113, 157, 35, 31, 58, 30,
+ 148, 15, 29, 47, 41, 62, 77, 187, 133, 111, 91, 244, 141, 60, 31,
+ 250, 41, 197, 103, 94, 193, 96, 92, 18, 14, 124, 40, 29, 29, 39,
+ 218, 47, 90, 110, 207, 39, 154, 43, 172, 63, 99, 146, 214, 31, 42,
+ 23, 237, 23, 213, 39, 123, 62, 107, 35, 158, 236, 248, 106, 171, 35,
+ 31, 186, 142, 236, 245, 81, 106, 93, 24, 234, 248, 29, 209, 47, 113,
+ 228, 99, 191, 174, 168, 60, 116, 125, 216, 243, 121, 118, 106, 109, 100,
+ 191, 207, 165, 215, 169, 253, 186, 167, 252, 237, 249, 212, 186, 248, 77,
+ 248, 186, 165, 242, 250, 35, 55, 239, 134, 203, 71, 186, 53, 233, 43,
+ 205, 199, 190, 63, 82, 124, 106, 221, 156, 218, 119, 72, 47, 249, 117,
+ 42, 183, 190, 98, 31, 174, 236, 51, 108, 157, 52, 31, 74, 47, 39,
+ 207, 114, 175, 172, 193, 129, 233, 142, 124, 218, 107, 34, 248, 150, 229,
+ 127, 84, 55, 105, 216, 145, 95, 218, 224, 123, 245, 228, 175, 135, 243,
+ 225, 245, 139, 242, 23, 39, 246, 225, 167, 124, 228, 227, 192, 199, 207,
+ 39, 174, 227, 38, 39, 246, 240, 210, 135, 157, 249, 162, 241, 103, 212,
+ 61, 43, 36, 241, 155, 15, 22, 229, 41, 31, 202, 215, 65, 15, 189,
+ 163, 63, 82, 55, 119, 178, 190, 196, 118, 41, 253, 254, 103, 49, 124,
+ 220, 253, 178, 252, 173, 167, 61, 249, 42, 145, 37, 28, 228, 121, 126,
+ 233, 3, 239, 27, 19, 29, 249, 80, 57, 198, 70, 143, 225, 91, 175,
+ 168, 108, 225, 67, 249, 218, 243, 25, 210, 97, 230, 169, 63, 223, 113,
+ 228, 67, 233, 127, 184, 210, 134, 55, 190, 104, 202, 155, 72, 8, 31,
+ 183, 174, 129, 133, 159, 61, 159, 193, 189, 87, 152, 222, 27, 224, 200,
+ 135, 202, 111, 161, 19, 249, 92, 248, 179, 60, 191, 58, 171, 162, 3,
+ 159, 49, 223, 222, 202, 78, 27, 233, 200, 135, 202, 177, 174, 91, 8,
+ 159, 54, 163, 37, 63, 250, 165, 138, 255, 126, 65, 11, 11, 63, 123,
+ 62, 123, 123, 174, 121, 126, 203, 137, 31, 180, 180, 43, 210, 81, 62,
+ 59, 203, 253, 173, 62, 118, 59, 192, 129, 79, 210, 249, 211, 57, 139,
+ 147, 29, 249, 80, 124, 74, 127, 169, 109, 69, 94, 169, 142, 228, 203,
+ 254, 252, 143, 186, 236, 242, 222, 14, 124, 170, 63, 24, 86, 182, 231,
+ 100, 71, 62, 180, 63, 170, 209, 225, 124, 207, 236, 70, 22, 62, 150,
+ 254, 217, 253, 121, 61, 106, 216, 238, 119, 39, 246, 135, 182, 75, 233,
+ 199, 76, 109, 206, 119, 154, 208, 9, 214, 68, 57, 184, 146, 29, 248,
+ 188, 91, 254, 120, 205, 21, 227, 85, 142, 254, 75, 148, 227, 78, 147,
+ 62, 124, 239, 123, 181, 44, 124, 40, 95, 123, 62, 131, 78, 240, 39,
+ 223, 119, 178, 46, 154, 79, 142, 224, 55, 246, 220, 174, 166, 235, 131,
+ 174, 7, 169, 117, 218, 174, 238, 209, 249, 5, 234, 59, 242, 89, 80,
+ 220, 159, 223, 119, 108, 166, 154, 242, 27, 214, 176, 33, 191, 179, 250,
+ 30, 73, 62, 205, 158, 255, 211, 186, 240, 8, 105, 62, 148, 126, 74,
+ 219, 250, 124, 177, 98, 41, 146, 124, 38, 110, 57, 167, 59, 94, 82,
+ 154, 15, 165, 167, 114, 209, 79, 123, 62, 141, 94, 249, 232, 235, 58,
+ 241, 131, 84, 14, 74, 39, 39, 79, 244, 239, 217, 173, 186, 44, 145,
+ 30, 103, 251, 241, 150, 126, 239, 158, 183, 83, 191, 76, 233, 40, 31,
+ 185, 249, 138, 244, 187, 181, 104, 192, 33, 233, 126, 81, 122, 106, 103,
+ 165, 248, 4, 85, 174, 62, 232, 112, 39, 249, 241, 145, 147, 167, 105,
+ 209, 242, 81, 109, 98, 228, 229, 161, 252, 164, 248, 248, 63, 141, 236,
+ 52, 97, 185, 52, 31, 123, 191, 33, 197, 231, 167, 162, 197, 6, 55,
+ 116, 225, 119, 236, 237, 189, 148, 191, 248, 231, 110, 118, 143, 178, 107,
+ 164, 231, 203, 222, 127, 81, 251, 111, 207, 231, 232, 131, 239, 23, 213,
+ 219, 39, 237, 47, 236, 253, 14, 181, 255, 246, 124, 206, 135, 146, 75,
+ 223, 47, 150, 246, 95, 246, 246, 94, 202, 239, 108, 223, 165, 87, 205,
+ 91, 41, 237, 47, 236, 237, 180, 148, 223, 249, 35, 115, 194, 159, 191,
+ 46, 151, 246, 95, 246, 126, 199, 226, 207, 236, 254, 166, 183, 62, 90,
+ 249, 155, 101, 210, 126, 199, 222, 95, 80, 187, 237, 160, 207, 173, 22,
+ 148, 46, 182, 88, 218, 239, 216, 251, 13, 41, 255, 245, 106, 111, 47,
+ 18, 190, 72, 218, 239, 216, 219, 123, 41, 127, 145, 120, 166, 119, 163,
+ 161, 139, 164, 253, 142, 189, 255, 162, 246, 223, 158, 79, 133, 71, 135,
+ 234, 100, 79, 112, 228, 3, 35, 13, 250, 159, 3, 235, 32, 22, 62,
+ 113, 61, 12, 128, 207, 162, 146, 239, 123, 29, 91, 177, 65, 175, 9,
+ 95, 40, 157, 240, 73, 1, 124, 21, 208, 143, 129, 79, 13, 196, 133,
+ 189, 145, 30, 118, 106, 209, 240, 217, 206, 97, 93, 108, 40, 126, 237,
+ 159, 160, 169, 97, 78, 248, 180, 2, 252, 37, 106, 74, 103, 229, 227,
+ 92, 158, 33, 63, 44, 127, 183, 245, 78, 79, 7, 62, 29, 123, 84,
+ 10, 127, 244, 176, 52, 95, 120, 196, 199, 225, 159, 172, 56, 160, 206,
+ 76, 46, 164, 62, 84, 247, 160, 228, 122, 47, 243, 121, 96, 161, 30,
+ 61, 29, 199, 167, 199, 186, 225, 234, 114, 227, 11, 240, 148, 159, 28,
+ 159, 31, 42, 154, 78, 165, 142, 145, 230, 67, 233, 107, 77, 13, 84,
+ 95, 11, 146, 182, 63, 87, 43, 182, 93, 20, 196, 59, 155, 47, 21,
+ 62, 14, 9, 251, 182, 88, 184, 250, 206, 229, 146, 225, 159, 254, 241,
+ 121, 120, 210, 59, 211, 37, 227, 240, 135, 155, 126, 184, 118, 173, 191,
+ 52, 31, 216, 209, 169, 89, 126, 82, 124, 148, 235, 79, 108, 45, 82,
+ 223, 91, 146, 207, 71, 239, 235, 195, 72, 95, 250, 219, 147, 177, 146,
+ 253, 42, 189, 84, 23, 217, 177, 66, 9, 73, 62, 180, 63, 86, 126,
+ 206, 249, 76, 79, 171, 81, 119, 89, 7, 199, 126, 81, 58, 58, 206,
+ 116, 254, 165, 248, 124, 233, 83, 37, 238, 215, 182, 210, 124, 172, 244,
+ 174, 251, 165, 188, 244, 219, 68, 252, 21, 51, 233, 117, 65, 215, 23,
+ 93, 111, 206, 249, 124, 91, 228, 85, 133, 137, 211, 43, 185, 224, 67,
+ 215, 5, 229, 231, 156, 79, 195, 154, 35, 124, 26, 205, 114, 228, 67,
+ 199, 133, 246, 175, 97, 31, 15, 245, 233, 47, 102, 74, 251, 193, 18,
+ 239, 212, 27, 53, 158, 72, 242, 169, 188, 178, 159, 186, 243, 177, 109,
+ 178, 250, 156, 214, 122, 122, 67, 117, 180, 52, 31, 42, 7, 229, 39,
+ 197, 167, 125, 249, 23, 126, 198, 9, 210, 243, 69, 245, 71, 174, 95,
+ 253, 111, 92, 125, 118, 241, 125, 71, 62, 148, 126, 151, 190, 135, 122,
+ 111, 110, 140, 236, 248, 132, 127, 215, 185, 70, 210, 24, 105, 62, 67,
+ 186, 232, 212, 77, 179, 238, 88, 248, 73, 241, 41, 126, 229, 253, 125,
+ 159, 196, 72, 243, 161, 235, 147, 242, 147, 148, 167, 232, 173, 50, 209,
+ 78, 246, 41, 116, 92, 105, 127, 228, 228, 185, 227, 251, 176, 89, 191,
+ 4, 71, 62, 180, 253, 122, 95, 111, 83, 207, 106, 63, 74, 150, 79,
+ 205, 63, 190, 76, 111, 50, 200, 145, 143, 241, 159, 250, 252, 174, 226,
+ 59, 212, 3, 162, 138, 241, 37, 247, 13, 81, 95, 56, 95, 134, 159,
+ 113, 63, 82, 218, 174, 86, 48, 126, 98, 10, 147, 230, 19, 21, 89,
+ 157, 31, 223, 234, 140, 133, 159, 20, 159, 11, 85, 230, 45, 15, 110,
+ 227, 200, 103, 211, 80, 141, 122, 254, 174, 40, 254, 231, 207, 138, 169,
+ 23, 118, 234, 101, 177, 247, 82, 124, 244, 229, 91, 108, 14, 122, 87,
+ 154, 15, 165, 167, 118, 95, 138, 79, 71, 223, 97, 39, 215, 140, 113,
+ 102, 159, 233, 250, 166, 235, 157, 250, 69, 231, 124, 22, 93, 234, 20,
+ 221, 105, 167, 210, 5, 31, 74, 239, 218, 191, 119, 184, 60, 126, 84,
+ 202, 9, 95, 7, 62, 19, 115, 167, 171, 79, 148, 188, 162, 14, 191,
+ 223, 82, 221, 165, 231, 69, 217, 245, 94, 190, 251, 146, 222, 113, 245,
+ 28, 251, 69, 233, 40, 31, 57, 251, 188, 185, 89, 193, 196, 143, 148,
+ 206, 198, 199, 188, 47, 166, 251, 219, 153, 199, 199, 241, 5, 55, 244,
+ 230, 23, 116, 236, 196, 191, 8, 25, 239, 192, 231, 80, 171, 10, 21,
+ 171, 196, 57, 198, 9, 148, 158, 238, 151, 55, 44, 25, 203, 215, 185,
+ 85, 223, 194, 207, 158, 79, 118, 129, 17, 39, 149, 201, 210, 242, 208,
+ 246, 9, 241, 131, 75, 39, 57, 206, 234, 142, 119, 98, 202, 148, 116,
+ 148, 135, 202, 241, 227, 216, 222, 124, 183, 168, 210, 22, 121, 36, 245,
+ 240, 89, 209, 243, 35, 156, 216, 67, 122, 254, 72, 207, 71, 135, 204,
+ 47, 196, 7, 53, 84, 242, 147, 7, 120, 240, 233, 67, 111, 59, 196,
+ 99, 167, 130, 126, 44, 208, 101, 172, 244, 249, 42, 229, 71, 233, 41,
+ 63, 135, 115, 63, 255, 95, 61, 127, 156, 227, 200, 199, 158, 110, 242,
+ 180, 95, 213, 59, 127, 121, 166, 126, 248, 213, 35, 117, 178, 49, 219,
+ 65, 158, 23, 133, 195, 218, 247, 143, 117, 228, 179, 242, 69, 97, 126,
+ 203, 221, 99, 22, 57, 40, 125, 197, 80, 194, 47, 85, 108, 118, 224,
+ 115, 172, 232, 176, 175, 11, 12, 148, 63, 167, 165, 252, 40, 127, 123,
+ 62, 158, 145, 233, 109, 51, 182, 72, 243, 177, 151, 75, 234, 252, 121,
+ 107, 196, 193, 150, 77, 122, 59, 242, 41, 189, 110, 158, 186, 142, 223,
+ 113, 203, 186, 146, 243, 131, 15, 130, 87, 52, 29, 49, 76, 154, 15,
+ 93, 175, 114, 235, 180, 87, 212, 66, 62, 179, 139, 52, 31, 42, 199,
+ 149, 247, 151, 169, 183, 109, 218, 40, 201, 231, 89, 224, 79, 229, 255,
+ 76, 148, 246, 59, 212, 79, 200, 241, 89, 20, 20, 82, 97, 177, 19,
+ 62, 148, 158, 250, 29, 57, 62, 79, 131, 119, 222, 75, 73, 114, 228,
+ 67, 245, 165, 231, 195, 108, 117, 243, 71, 155, 212, 31, 55, 123, 160,
+ 94, 90, 101, 172, 164, 254, 92, 170, 88, 213, 216, 195, 201, 121, 84,
+ 161, 225, 155, 213, 29, 234, 122, 242, 252, 150, 189, 234, 106, 253, 127,
+ 87, 83, 125, 150, 146, 231, 96, 189, 97, 165, 10, 143, 151, 30, 103,
+ 202, 135, 242, 149, 226, 19, 242, 131, 127, 139, 1, 113, 210, 242, 80,
+ 57, 166, 86, 188, 161, 254, 102, 173, 175, 36, 159, 98, 47, 202, 191,
+ 184, 148, 34, 205, 135, 210, 167, 84, 248, 90, 189, 108, 118, 61, 73,
+ 62, 251, 94, 76, 48, 221, 117, 194, 135, 250, 97, 58, 95, 179, 207,
+ 156, 85, 15, 169, 95, 64, 58, 254, 201, 57, 114, 107, 247, 68, 105,
+ 62, 116, 158, 40, 63, 41, 62, 115, 210, 190, 206, 60, 95, 219, 201,
+ 254, 93, 140, 47, 40, 63, 57, 121, 58, 254, 240, 124, 217, 59, 225,
+ 210, 124, 40, 253, 131, 15, 207, 169, 55, 123, 254, 44, 25, 143, 109,
+ 184, 112, 113, 101, 201, 72, 71, 62, 163, 38, 246, 83, 251, 165, 175,
+ 13, 167, 124, 228, 226, 58, 239, 61, 151, 183, 245, 104, 39, 205, 135,
+ 202, 33, 215, 175, 197, 187, 110, 110, 50, 105, 28, 249, 208, 113, 165,
+ 227, 76, 215, 135, 20, 159, 202, 7, 185, 251, 163, 227, 165, 249, 80,
+ 122, 185, 117, 186, 124, 95, 229, 202, 117, 157, 216, 121, 186, 30, 40,
+ 189, 156, 60, 65, 23, 123, 134, 244, 26, 46, 205, 135, 174, 51, 57,
+ 121, 12, 23, 70, 104, 150, 56, 57, 15, 167, 246, 129, 234, 15, 141,
+ 55, 165, 248, 156, 34, 19, 31, 38, 166, 72, 243, 161, 227, 44, 23,
+ 175, 22, 244, 39, 215, 207, 57, 177, 99, 116, 157, 211, 254, 209, 241,
+ 145, 242, 167, 215, 125, 111, 55, 42, 224, 36, 110, 73, 158, 83, 146,
+ 247, 60, 250, 167, 197, 126, 81, 255, 37, 37, 207, 250, 197, 217, 71,
+ 251, 213, 147, 230, 67, 237, 134, 156, 61, 28, 246, 151, 209, 71, 61,
+ 69, 122, 124, 44, 114, 201, 200, 51, 56, 199, 103, 224, 218, 46, 210,
+ 124, 232, 60, 81, 126, 82, 124, 174, 63, 217, 152, 115, 246, 61, 233,
+ 253, 14, 93, 87, 114, 246, 103, 209, 189, 207, 175, 15, 119, 194, 103,
+ 121, 102, 17, 254, 244, 132, 38, 150, 184, 240, 137, 255, 53, 245, 198,
+ 181, 93, 36, 237, 170, 70, 245, 91, 185, 105, 19, 165, 249, 208, 243,
+ 190, 30, 63, 87, 230, 91, 248, 197, 75, 242, 233, 19, 244, 193, 31,
+ 151, 147, 164, 159, 55, 209, 184, 85, 46, 94, 213, 212, 249, 99, 194,
+ 130, 34, 222, 46, 248, 152, 233, 169, 92, 82, 124, 146, 15, 196, 250,
+ 23, 94, 237, 228, 60, 92, 164, 163, 253, 251, 113, 74, 13, 190, 212,
+ 39, 210, 254, 107, 76, 147, 57, 69, 50, 156, 244, 107, 82, 183, 32,
+ 254, 135, 49, 196, 18, 63, 203, 241, 249, 218, 235, 250, 133, 220, 9,
+ 210, 242, 80, 122, 202, 79, 138, 207, 35, 245, 55, 10, 221, 104, 34,
+ 25, 207, 91, 248, 201, 240, 201, 254, 113, 235, 203, 211, 19, 157, 237,
+ 47, 204, 231, 116, 84, 31, 229, 206, 235, 188, 106, 221, 158, 181, 249,
+ 47, 79, 73, 127, 97, 245, 55, 102, 190, 146, 231, 108, 133, 239, 207,
+ 46, 88, 95, 41, 185, 31, 164, 118, 85, 46, 110, 25, 244, 195, 186,
+ 33, 225, 45, 137, 36, 31, 43, 253, 60, 144, 199, 91, 146, 207, 111,
+ 223, 110, 26, 88, 188, 141, 82, 50, 110, 177, 198, 43, 51, 128, 79,
+ 35, 73, 62, 247, 182, 213, 237, 210, 151, 151, 142, 127, 172, 244, 174,
+ 229, 185, 184, 99, 98, 151, 153, 173, 156, 237, 187, 205, 244, 84, 30,
+ 185, 245, 222, 243, 86, 244, 232, 33, 33, 68, 146, 143, 149, 254, 16,
+ 220, 15, 146, 228, 243, 211, 189, 238, 201, 53, 131, 156, 228, 129, 88,
+ 232, 233, 58, 47, 3, 215, 68, 73, 62, 235, 107, 235, 135, 159, 15,
+ 113, 197, 135, 210, 187, 150, 231, 23, 191, 207, 199, 84, 11, 112, 242,
+ 28, 214, 178, 79, 238, 202, 19, 253, 44, 89, 121, 170, 247, 188, 218,
+ 175, 126, 5, 87, 124, 40, 189, 107, 59, 182, 58, 156, 211, 189, 104,
+ 225, 100, 156, 245, 83, 1, 127, 152, 69, 30, 43, 95, 231, 124, 38,
+ 189, 31, 89, 100, 92, 69, 105, 62, 148, 158, 158, 35, 72, 241, 81,
+ 77, 62, 93, 244, 101, 89, 105, 62, 148, 94, 238, 28, 96, 140, 86,
+ 251, 169, 103, 41, 105, 62, 148, 190, 152, 49, 133, 255, 176, 167, 116,
+ 60, 223, 161, 247, 210, 175, 7, 213, 113, 228, 67, 233, 169, 253, 138,
+ 237, 253, 46, 191, 194, 197, 185, 86, 213, 187, 59, 83, 31, 133, 74,
+ 243, 161, 244, 114, 242, 68, 189, 106, 53, 179, 78, 13, 71, 62, 148,
+ 158, 202, 67, 237, 190, 228, 121, 230, 181, 202, 11, 87, 134, 73, 243,
+ 161, 244, 207, 63, 104, 198, 103, 166, 253, 45, 233, 223, 151, 101, 37,
+ 44, 14, 115, 50, 239, 148, 142, 242, 145, 139, 15, 219, 121, 15, 158,
+ 254, 155, 11, 62, 148, 158, 158, 111, 74, 230, 21, 212, 169, 183, 114,
+ 67, 43, 23, 126, 80, 244, 95, 114, 241, 207, 142, 163, 202, 191, 234,
+ 141, 145, 230, 67, 233, 229, 250, 197, 31, 62, 248, 251, 139, 81, 142,
+ 124, 168, 28, 212, 191, 203, 237, 79, 163, 79, 126, 235, 59, 125, 140,
+ 52, 31, 74, 47, 215, 175, 109, 198, 46, 197, 218, 59, 217, 167, 80,
+ 122, 42, 143, 156, 125, 158, 114, 178, 74, 133, 214, 99, 164, 249, 80,
+ 122, 185, 253, 242, 224, 27, 147, 159, 255, 250, 190, 252, 121, 157, 125,
+ 62, 163, 179, 60, 97, 227, 27, 200, 63, 196, 60, 225, 168, 229, 210,
+ 121, 194, 246, 121, 131, 82, 124, 48, 79, 184, 209, 218, 252, 231, 121,
+ 98, 158, 112, 199, 109, 210, 121, 131, 246, 121, 172, 174, 242, 132, 159,
+ 28, 145, 207, 239, 149, 227, 131, 121, 194, 123, 214, 73, 243, 161, 249,
+ 175, 114, 249, 144, 152, 39, 188, 254, 134, 116, 126, 166, 125, 30, 173,
+ 171, 60, 225, 29, 253, 164, 243, 123, 237, 243, 52, 93, 229, 9, 143,
+ 12, 249, 159, 207, 19, 182, 207, 127, 166, 227, 230, 44, 79, 56, 152,
+ 228, 63, 207, 28, 243, 132, 123, 105, 229, 207, 177, 237, 243, 241, 157,
+ 230, 9, 199, 73, 231, 9, 219, 231, 205, 75, 233, 51, 230, 9, 127,
+ 241, 6, 242, 249, 49, 79, 216, 217, 121, 184, 125, 126, 175, 220, 124,
+ 97, 158, 240, 169, 47, 164, 249, 216, 247, 203, 85, 158, 240, 170, 141,
+ 242, 249, 189, 114, 242, 96, 158, 240, 242, 126, 210, 124, 168, 60, 114,
+ 235, 11, 243, 132, 191, 237, 146, 255, 124, 45, 204, 19, 238, 177, 60,
+ 255, 249, 90, 152, 39, 124, 232, 88, 254, 243, 172, 48, 79, 184, 210,
+ 172, 252, 231, 125, 97, 158, 112, 201, 245, 249, 207, 179, 194, 60, 225,
+ 153, 107, 242, 159, 247, 133, 121, 194, 186, 133, 249, 207, 215, 194, 60,
+ 97, 223, 207, 243, 159, 175, 133, 121, 194, 35, 230, 230, 63, 95, 11,
+ 243, 132, 191, 158, 150, 255, 124, 45, 204, 19, 46, 31, 39, 127, 110,
+ 35, 151, 223, 139, 121, 194, 67, 231, 120, 75, 230, 9, 219, 231, 27,
+ 211, 243, 10, 103, 121, 194, 51, 150, 75, 231, 175, 210, 117, 33, 151,
+ 191, 138, 121, 194, 207, 207, 201, 231, 247, 202, 229, 121, 98, 158, 240,
+ 227, 69, 242, 249, 189, 114, 249, 198, 152, 39, 220, 252, 158, 124, 222,
+ 178, 125, 158, 175, 179, 60, 225, 139, 38, 233, 188, 83, 251, 124, 99,
+ 87, 121, 194, 219, 226, 228, 243, 177, 229, 248, 200, 229, 9, 187, 155,
+ 79, 219, 218, 239, 214, 162, 181, 225, 249, 207, 167, 197, 60, 225, 240,
+ 140, 252, 231, 247, 98, 158, 240, 222, 21, 249, 207, 55, 198, 60, 225,
+ 57, 67, 243, 159, 255, 140, 121, 194, 63, 116, 201, 255, 247, 83, 48,
+ 79, 248, 206, 128, 252, 127, 63, 5, 243, 132, 47, 68, 230, 255, 123,
+ 37, 152, 39, 236, 63, 60, 255, 223, 115, 193, 60, 225, 228, 33, 249,
+ 255, 94, 9, 230, 9, 251, 13, 205, 255, 247, 92, 48, 79, 56, 116,
+ 88, 254, 191, 159, 130, 121, 194, 127, 15, 207, 255, 247, 83, 48, 79,
+ 248, 240, 136, 252, 127, 63, 5, 243, 132, 87, 140, 200, 255, 247, 83,
+ 48, 79, 56, 96, 182, 171, 60, 97, 154, 63, 228, 58, 255, 16, 243,
+ 132, 231, 244, 245, 118, 35, 143, 145, 230, 247, 154, 243, 134, 157, 229,
+ 9, 159, 157, 226, 42, 79, 216, 54, 207, 216, 85, 158, 240, 190, 246,
+ 210, 121, 194, 238, 230, 139, 98, 158, 240, 166, 175, 228, 243, 123, 229,
+ 242, 199, 48, 79, 56, 97, 190, 52, 31, 154, 183, 33, 151, 111, 140,
+ 121, 194, 103, 141, 68, 54, 159, 86, 238, 121, 1, 230, 9, 87, 89,
+ 43, 159, 111, 44, 247, 188, 0, 243, 132, 31, 157, 83, 186, 200, 55,
+ 54, 231, 209, 202, 229, 247, 98, 158, 240, 142, 155, 133, 100, 243, 141,
+ 229, 242, 159, 49, 79, 56, 118, 135, 124, 126, 175, 220, 56, 99, 158,
+ 176, 223, 110, 105, 62, 180, 95, 114, 250, 131, 121, 194, 251, 77, 69,
+ 92, 172, 11, 251, 124, 124, 233, 60, 225, 217, 239, 87, 114, 35, 223,
+ 216, 245, 186, 192, 60, 225, 239, 38, 86, 146, 205, 203, 149, 155, 47,
+ 204, 19, 94, 56, 71, 58, 191, 215, 221, 188, 38, 204, 19, 62, 244,
+ 169, 124, 190, 177, 92, 94, 46, 230, 9, 107, 102, 75, 207, 23, 165,
+ 151, 211, 31, 204, 19, 174, 59, 93, 58, 47, 215, 221, 124, 90, 204,
+ 19, 254, 104, 190, 124, 190, 177, 92, 30, 8, 230, 9, 199, 175, 144,
+ 207, 55, 150, 91, 239, 152, 39, 252, 217, 52, 249, 124, 45, 185, 113,
+ 198, 60, 225, 47, 22, 72, 63, 55, 183, 207, 219, 114, 149, 39, 124,
+ 106, 181, 116, 126, 175, 125, 254, 142, 171, 60, 97, 238, 176, 124, 190,
+ 177, 220, 57, 54, 230, 9, 159, 217, 35, 159, 223, 75, 243, 133, 93,
+ 229, 9, 159, 253, 92, 154, 143, 253, 247, 75, 92, 229, 9, 191, 59,
+ 159, 184, 145, 223, 235, 122, 189, 99, 158, 112, 102, 123, 111, 23, 124,
+ 168, 127, 119, 157, 111, 140, 121, 194, 83, 155, 74, 231, 9, 219, 231,
+ 249, 186, 202, 19, 94, 122, 94, 58, 79, 152, 218, 83, 57, 62, 152,
+ 39, 156, 244, 151, 124, 94, 46, 125, 158, 70, 247, 187, 206, 242, 132,
+ 175, 45, 145, 206, 19, 182, 127, 30, 39, 181, 95, 198, 60, 225, 220,
+ 185, 210, 242, 208, 231, 148, 114, 207, 25, 49, 79, 248, 143, 123, 210,
+ 121, 194, 246, 207, 229, 92, 229, 9, 47, 158, 45, 253, 220, 193, 62,
+ 63, 87, 234, 253, 36, 167, 130, 46, 21, 216, 246, 161, 244, 249, 170,
+ 125, 158, 177, 212, 121, 38, 230, 9, 215, 25, 47, 157, 39, 76, 243,
+ 152, 104, 30, 145, 84, 190, 49, 230, 9, 59, 123, 127, 2, 205, 199,
+ 165, 121, 64, 22, 126, 18, 249, 207, 152, 39, 252, 60, 45, 255, 249,
+ 189, 152, 39, 28, 213, 53, 255, 249, 198, 152, 39, 124, 234, 75, 249,
+ 188, 92, 185, 252, 94, 204, 19, 94, 188, 76, 62, 223, 152, 174, 91,
+ 87, 121, 194, 157, 210, 165, 249, 208, 188, 58, 57, 255, 142, 121, 194,
+ 37, 63, 146, 246, 59, 148, 143, 156, 63, 93, 24, 20, 82, 97, 196,
+ 71, 210, 121, 194, 148, 143, 156, 223, 193, 60, 97, 253, 60, 233, 60,
+ 97, 251, 124, 61, 154, 103, 231, 44, 79, 120, 211, 34, 249, 188, 92,
+ 154, 175, 231, 42, 79, 248, 241, 28, 233, 113, 182, 207, 59, 118, 149,
+ 39, 188, 118, 137, 124, 126, 175, 92, 158, 30, 230, 9, 215, 214, 19,
+ 217, 124, 27, 185, 231, 185, 152, 39, 92, 90, 47, 157, 223, 235, 110,
+ 126, 29, 230, 9, 183, 155, 37, 159, 111, 76, 231, 203, 85, 158, 112,
+ 253, 31, 229, 243, 123, 229, 226, 13, 204, 19, 222, 112, 72, 154, 143,
+ 187, 121, 185, 152, 39, 252, 231, 62, 34, 155, 175, 37, 199, 7, 243,
+ 132, 55, 237, 146, 207, 55, 150, 203, 91, 198, 60, 97, 206, 32, 159,
+ 223, 43, 55, 206, 152, 39, 252, 241, 199, 210, 124, 220, 205, 239, 197,
+ 60, 225, 139, 75, 165, 243, 123, 221, 205, 55, 198, 60, 225, 175, 22,
+ 203, 231, 27, 211, 245, 230, 42, 79, 120, 248, 114, 249, 188, 83, 57,
+ 253, 193, 60, 225, 249, 122, 249, 124, 99, 185, 113, 198, 60, 225, 6,
+ 243, 164, 243, 132, 237, 191, 247, 64, 251, 235, 44, 79, 248, 249, 92,
+ 23, 121, 194, 162, 223, 146, 179, 27, 152, 39, 252, 197, 121, 249, 124,
+ 99, 57, 187, 129, 121, 194, 135, 166, 74, 143, 15, 149, 71, 46, 15,
+ 4, 243, 132, 7, 164, 203, 231, 27, 203, 237, 11, 48, 79, 56, 104,
+ 134, 252, 247, 34, 229, 214, 41, 230, 9, 47, 153, 33, 157, 223, 235,
+ 152, 175, 39, 157, 39, 60, 101, 150, 52, 31, 154, 31, 44, 151, 151,
+ 139, 121, 194, 181, 230, 17, 217, 252, 94, 107, 252, 42, 157, 39, 60,
+ 230, 161, 82, 246, 253, 54, 114, 253, 194, 60, 225, 199, 131, 228, 243,
+ 114, 173, 121, 213, 210, 121, 194, 81, 243, 228, 243, 163, 228, 226, 103,
+ 204, 19, 86, 206, 118, 33, 143, 155, 249, 198, 152, 39, 156, 150, 74,
+ 100, 191, 247, 39, 55, 95, 152, 39, 220, 120, 150, 116, 158, 176, 187,
+ 223, 23, 198, 60, 225, 238, 74, 233, 60, 97, 251, 188, 99, 87, 121,
+ 194, 207, 206, 121, 203, 230, 247, 202, 217, 85, 204, 19, 62, 156, 37,
+ 157, 39, 76, 243, 113, 229, 242, 141, 49, 79, 248, 254, 30, 111, 217,
+ 252, 94, 185, 124, 45, 204, 19, 94, 111, 116, 149, 39, 76, 243, 131,
+ 93, 231, 27, 99, 158, 240, 123, 251, 189, 101, 243, 123, 229, 228, 193,
+ 60, 225, 85, 223, 72, 231, 9, 211, 124, 92, 185, 124, 54, 204, 19,
+ 190, 114, 198, 157, 252, 94, 215, 235, 20, 243, 132, 235, 127, 227, 138,
+ 15, 205, 15, 118, 157, 223, 139, 121, 194, 191, 124, 235, 78, 126, 47,
+ 205, 23, 150, 206, 19, 62, 127, 211, 21, 31, 247, 242, 159, 49, 79,
+ 216, 243, 168, 124, 126, 175, 156, 60, 152, 39, 252, 225, 13, 249, 252,
+ 94, 185, 115, 0, 204, 19, 246, 184, 45, 159, 223, 43, 151, 111, 140,
+ 121, 194, 47, 238, 74, 243, 161, 249, 184, 114, 249, 198, 152, 39, 252,
+ 233, 69, 249, 252, 94, 57, 187, 138, 121, 194, 69, 142, 72, 243, 161,
+ 242, 200, 229, 27, 99, 158, 240, 143, 87, 228, 243, 123, 229, 228, 193,
+ 60, 225, 152, 195, 210, 124, 236, 243, 124, 93, 229, 9, 31, 185, 33,
+ 159, 223, 43, 199, 7, 243, 132, 43, 184, 224, 99, 255, 254, 3, 87,
+ 121, 194, 239, 236, 151, 207, 239, 149, 243, 95, 152, 39, 124, 97, 190,
+ 52, 31, 119, 191, 111, 133, 121, 194, 158, 159, 200, 231, 247, 202, 249,
+ 119, 204, 19, 158, 60, 95, 154, 143, 253, 247, 210, 92, 229, 9, 239,
+ 250, 88, 62, 191, 87, 78, 30, 204, 19, 222, 55, 95, 154, 143, 187,
+ 223, 7, 193, 60, 97, 63, 39, 207, 29, 162, 90, 19, 225, 157, 247,
+ 198, 34, 177, 94, 65, 204, 239, 179, 37, 52, 166, 126, 0, 113, 146,
+ 70, 196, 197, 251, 7, 4, 4, 18, 155, 63, 78, 68, 79, 253, 251,
+ 177, 130, 72, 252, 233, 129, 111, 174, 151, 153, 87, 78, 193, 88, 47,
+ 125, 225, 88, 175, 236, 66, 86, 222, 246, 127, 133, 197, 223, 35, 68,
+ 198, 186, 159, 35, 249, 182, 169, 179, 96, 215, 168, 111, 92, 173, 214,
+ 49, 77, 235, 122, 119, 249, 243, 243, 167, 104, 88, 252, 42, 196, 147,
+ 40, 152, 95, 149, 195, 119, 38, 123, 138, 237, 138, 50, 146, 28, 143,
+ 88, 47, 44, 63, 142, 229, 208, 126, 35, 177, 157, 246, 245, 251, 26,
+ 215, 60, 173, 204, 39, 152, 106, 240, 243, 110, 156, 125, 165, 152, 172,
+ 48, 117, 128, 178, 117, 80, 54, 220, 84, 195, 128, 101, 175, 166, 41,
+ 76, 103, 43, 198, 26, 159, 7, 119, 228, 245, 141, 202, 91, 240, 176,
+ 236, 5, 148, 77, 106, 84, 222, 130, 215, 237, 204, 24, 227, 233, 123,
+ 215, 212, 254, 223, 22, 183, 148, 105, 161, 236, 36, 148, 53, 254, 182,
+ 184, 133, 246, 196, 193, 95, 255, 31, 123, 95, 1, 87, 213, 182, 173,
+ 191, 232, 110, 65, 58, 164, 148, 6, 233, 70, 148, 84, 80, 164, 67,
+ 233, 238, 6, 165, 149, 80, 26, 165, 20, 65, 5, 233, 110, 16, 73,
+ 105, 164, 59, 5, 105, 9, 165, 164, 255, 123, 123, 166, 247, 112, 125,
+ 231, 220, 115, 239, 123, 239, 190, 247, 126, 255, 115, 182, 191, 15, 215,
+ 94, 107, 206, 49, 190, 49, 230, 152, 177, 214, 158, 115, 46, 201, 171,
+ 122, 66, 117, 125, 223, 109, 57, 245, 129, 32, 196, 83, 215, 71, 121,
+ 117, 50, 176, 115, 67, 103, 206, 57, 195, 206, 73, 195, 206, 13, 132,
+ 123, 215, 253, 56, 247, 1, 150, 247, 10, 236, 92, 239, 153, 115, 112,
+ 219, 220, 225, 239, 200, 130, 249, 149, 3, 216, 22, 9, 59, 254, 225,
+ 149, 155, 103, 142, 241, 207, 28, 247, 160, 255, 122, 28, 121, 230, 248,
+ 230, 153, 227, 127, 245, 243, 183, 247, 129, 97, 252, 193, 251, 8, 255,
+ 224, 58, 254, 31, 92, 135, 115, 255, 135, 239, 99, 252, 131, 235, 55,
+ 255, 193, 117, 6, 248, 251, 167, 96, 49, 203, 242, 183, 119, 99, 34,
+ 126, 127, 239, 37, 124, 239, 115, 248, 155, 164, 16, 192, 49, 42, 132,
+ 1, 161, 67, 104, 16, 45, 116, 250, 221, 238, 17, 16, 227, 108, 127,
+ 203, 183, 9, 27, 223, 62, 130, 181, 89, 241, 176, 255, 3, 197, 167,
+ 198, 138, 197, 60, 23, 213, 126, 183, 13, 11, 131, 197, 199, 225, 125,
+ 244, 31, 239, 168, 253, 117, 206, 242, 223, 242, 253, 34, 231, 87, 185,
+ 191, 47, 7, 37, 224, 63, 202, 249, 241, 222, 197, 255, 120, 12, 228,
+ 192, 142, 206, 2, 130, 190, 193, 226, 11, 9, 241, 111, 114, 16, 64,
+ 155, 33, 5, 179, 31, 230, 132, 20, 20, 115, 52, 186, 51, 117, 236,
+ 108, 28, 220, 144, 178, 181, 115, 178, 55, 49, 130, 12, 156, 77, 28,
+ 45, 12, 172, 207, 180, 25, 103, 142, 124, 37, 126, 197, 223, 181, 26,
+ 191, 115, 30, 250, 157, 116, 127, 255, 57, 253, 155, 255, 127, 121, 247,
+ 215, 175, 121, 127, 149, 251, 115, 124, 211, 162, 252, 126, 155, 244, 159,
+ 173, 7, 55, 129, 92, 50, 96, 45, 194, 217, 183, 95, 34, 194, 234,
+ 216, 143, 55, 145, 254, 174, 221, 190, 18, 191, 141, 95, 108, 249, 81,
+ 14, 112, 223, 211, 157, 241, 109, 202, 25, 91, 110, 72, 57, 26, 24,
+ 26, 90, 56, 67, 223, 75, 227, 215, 54, 28, 241, 255, 104, 57, 232,
+ 35, 253, 123, 202, 1, 46, 247, 223, 85, 14, 170, 176, 62, 52, 3,
+ 200, 162, 254, 187, 24, 255, 245, 163, 122, 77, 213, 196, 253, 55, 206,
+ 255, 90, 14, 190, 176, 250, 156, 34, 249, 123, 186, 126, 125, 215, 247,
+ 127, 228, 9, 183, 231, 87, 63, 35, 254, 75, 254, 145, 191, 1, 139,
+ 81, 132, 95, 234, 54, 41, 224, 254, 247, 237, 5, 60, 141, 147, 185,
+ 129, 177, 157, 27, 135, 179, 153, 193, 79, 253, 255, 247, 15, 39, 167,
+ 179, 137, 187, 179, 139, 163, 137, 19, 231, 153, 132, 240, 80, 251, 126,
+ 82, 247, 183, 115, 255, 207, 126, 244, 215, 143, 255, 105, 199, 32, 252,
+ 221, 49, 194, 223, 149, 211, 12, 244, 203, 88, 226, 28, 56, 38, 1,
+ 233, 217, 36, 255, 94, 198, 77, 58, 165, 239, 233, 224, 231, 225, 199,
+ 191, 202, 253, 149, 134, 36, 236, 31, 45, 58, 124, 114, 237, 191, 25,
+ 8, 255, 69, 64, 255, 199, 129, 240, 191, 140, 255, 43, 54, 35, 254,
+ 15, 227, 127, 195, 23, 255, 200, 94, 164, 223, 0, 242, 127, 19, 126,
+ 75, 246, 63, 242, 199, 255, 132, 221, 191, 101, 39, 202, 25, 160, 254,
+ 55, 227, 172, 236, 223, 242, 203, 191, 195, 15, 255, 200, 110, 228, 223,
+ 176, 21, 13, 0, 29, 0, 227, 55, 128, 249, 7, 248, 173, 60, 63,
+ 228, 253, 144, 255, 179, 79, 144, 255, 13, 126, 248, 61, 219, 145, 207,
+ 216, 140, 246, 147, 157, 112, 254, 88, 48, 96, 3, 224, 156, 1, 238,
+ 191, 136, 179, 121, 127, 200, 195, 250, 201, 71, 232, 103, 252, 113, 214,
+ 15, 255, 85, 31, 252, 108, 251, 217, 50, 63, 107, 247, 89, 123, 127,
+ 216, 136, 7, 159, 24, 11, 3, 1, 12, 132, 0, 68, 0, 231, 254,
+ 73, 252, 72, 255, 35, 63, 1, 144, 137, 119, 198, 55, 103, 253, 113,
+ 214, 15, 63, 199, 194, 127, 198, 7, 63, 219, 126, 182, 204, 127, 148,
+ 55, 22, 224, 241, 195, 94, 66, 192, 157, 24, 6, 18, 24, 206, 195,
+ 64, 10, 159, 20, 7, 159, 136, 15, 64, 241, 79, 226, 71, 122, 50,
+ 32, 227, 60, 144, 73, 12, 116, 16, 158, 241, 7, 14, 224, 242, 35,
+ 30, 126, 43, 22, 254, 21, 251, 255, 200, 118, 76, 224, 123, 60, 80,
+ 46, 68, 128, 27, 41, 224, 76, 9, 3, 53, 252, 97, 48, 252, 65,
+ 55, 124, 17, 38, 12, 23, 224, 15, 243, 1, 24, 254, 0, 63, 210,
+ 93, 0, 121, 105, 129, 44, 106, 32, 155, 28, 232, 34, 1, 186, 9,
+ 0, 23, 236, 51, 177, 240, 95, 241, 193, 207, 245, 253, 172, 237, 63,
+ 202, 28, 255, 140, 221, 100, 128, 23, 13, 224, 12, 183, 129, 9, 134,
+ 139, 48, 176, 192, 192, 10, 3, 27, 124, 114, 54, 0, 199, 31, 224,
+ 71, 58, 54, 144, 151, 5, 200, 98, 2, 178, 47, 0, 93, 148, 64,
+ 247, 15, 63, 224, 159, 137, 133, 179, 62, 248, 185, 61, 248, 87, 203,
+ 254, 172, 237, 184, 192, 223, 231, 64, 25, 252, 176, 27, 94, 94, 204,
+ 128, 43, 156, 59, 23, 124, 114, 6, 12, 188, 240, 69, 94, 240, 5,
+ 126, 48, 8, 194, 32, 4, 159, 204, 244, 7, 16, 2, 105, 5, 64,
+ 94, 94, 32, 139, 11, 200, 102, 1, 186, 232, 207, 248, 129, 20, 112,
+ 34, 0, 28, 207, 250, 224, 95, 137, 129, 223, 179, 29, 19, 248, 150,
+ 0, 212, 65, 184, 223, 169, 64, 89, 48, 129, 114, 226, 4, 92, 225,
+ 220, 69, 224, 147, 61, 225, 63, 160, 195, 112, 5, 134, 171, 240, 197,
+ 119, 48, 200, 192, 32, 11, 32, 247, 19, 126, 156, 151, 1, 105, 175,
+ 130, 188, 146, 64, 150, 8, 144, 205, 11, 116, 177, 2, 221, 23, 0,
+ 23, 50, 192, 141, 0, 112, 197, 252, 7, 62, 248, 103, 202, 30, 5,
+ 180, 169, 24, 160, 110, 225, 3, 31, 147, 129, 186, 8, 247, 255, 37,
+ 16, 179, 188, 160, 220, 224, 60, 165, 129, 29, 138, 48, 40, 193, 112,
+ 19, 6, 21, 24, 84, 225, 63, 120, 194, 39, 31, 254, 1, 212, 64,
+ 90, 21, 144, 87, 9, 200, 146, 5, 178, 197, 129, 46, 94, 160, 251,
+ 18, 224, 66, 13, 184, 157, 3, 92, 177, 1, 119, 180, 159, 234, 193,
+ 239, 197, 192, 63, 138, 123, 60, 80, 199, 72, 129, 175, 127, 216, 206,
+ 5, 226, 84, 12, 112, 147, 135, 65, 25, 240, 215, 132, 47, 56, 128,
+ 225, 46, 252, 135, 13, 248, 143, 0, 240, 133, 75, 48, 152, 192, 96,
+ 250, 59, 48, 1, 105, 140, 64, 158, 187, 64, 134, 38, 144, 169, 12,
+ 116, 72, 3, 157, 2, 128, 195, 15, 31, 80, 1, 142, 68, 128, 51,
+ 214, 191, 16, 3, 191, 85, 246, 103, 227, 158, 4, 212, 181, 11, 103,
+ 108, 135, 199, 163, 4, 40, 27, 37, 80, 118, 58, 128, 59, 220, 30,
+ 75, 24, 108, 96, 176, 135, 47, 106, 131, 79, 4, 129, 47, 38, 131,
+ 193, 245, 119, 224, 2, 210, 56, 130, 60, 54, 64, 134, 41, 144, 169,
+ 3, 116, 40, 1, 157, 18, 128, 195, 15, 31, 92, 0, 28, 73, 126,
+ 170, 7, 191, 21, 3, 127, 20, 251, 63, 151, 61, 25, 104, 111, 152,
+ 64, 220, 9, 0, 253, 240, 186, 123, 11, 6, 45, 192, 209, 28, 6,
+ 91, 96, 135, 7, 12, 94, 240, 9, 219, 48, 248, 195, 240, 0, 134,
+ 135, 48, 4, 194, 16, 244, 19, 2, 193, 181, 7, 32, 173, 47, 200,
+ 235, 1, 100, 217, 2, 217, 6, 64, 215, 45, 160, 91, 2, 112, 225,
+ 0, 220, 104, 0, 215, 159, 99, 224, 31, 213, 129, 179, 246, 255, 136,
+ 253, 179, 245, 254, 71, 217, 211, 131, 118, 135, 23, 196, 159, 44, 224,
+ 161, 13, 226, 214, 26, 112, 189, 15, 108, 128, 219, 21, 10, 67, 4,
+ 12, 209, 240, 137, 82, 240, 201, 136, 48, 196, 194, 16, 247, 19, 98,
+ 193, 181, 39, 32, 109, 4, 200, 27, 4, 100, 221, 7, 178, 173, 129,
+ 46, 109, 160, 91, 22, 112, 225, 5, 220, 232, 207, 196, 192, 217, 118,
+ 224, 71, 29, 248, 61, 251, 127, 174, 251, 24, 32, 126, 8, 65, 157,
+ 162, 1, 253, 14, 39, 104, 127, 164, 65, 28, 106, 1, 62, 240, 242,
+ 113, 7, 229, 22, 12, 248, 195, 237, 73, 132, 225, 5, 12, 47, 225,
+ 27, 73, 192, 144, 6, 159, 104, 1, 144, 14, 240, 227, 123, 26, 72,
+ 243, 18, 228, 73, 4, 50, 34, 128, 76, 95, 160, 195, 22, 232, 212,
+ 2, 28, 164, 1, 39, 78, 192, 145, 6, 112, 38, 4, 54, 96, 252,
+ 65, 27, 240, 123, 117, 31, 23, 180, 167, 228, 160, 110, 177, 0, 63,
+ 139, 131, 118, 72, 13, 196, 163, 53, 224, 229, 15, 202, 12, 94, 134,
+ 207, 97, 120, 5, 95, 108, 7, 67, 14, 124, 18, 60, 252, 135, 89,
+ 24, 138, 97, 40, 129, 255, 248, 252, 19, 74, 192, 181, 66, 144, 54,
+ 7, 228, 125, 5, 100, 61, 1, 178, 253, 129, 46, 107, 160, 91, 13,
+ 112, 17, 7, 220, 88, 0, 87, 114, 192, 29, 247, 159, 104, 3, 126,
+ 203, 254, 31, 117, 159, 24, 196, 19, 3, 24, 127, 8, 2, 127, 43,
+ 131, 246, 200, 28, 196, 165, 47, 224, 7, 143, 227, 100, 80, 174, 121,
+ 192, 174, 74, 24, 222, 194, 39, 154, 194, 80, 7, 95, 152, 2, 208,
+ 8, 240, 227, 123, 29, 72, 243, 22, 228, 41, 1, 50, 210, 129, 204,
+ 88, 160, 195, 23, 232, 52, 7, 28, 148, 1, 39, 65, 192, 145, 1,
+ 112, 38, 62, 211, 6, 252, 43, 246, 163, 255, 84, 247, 169, 65, 219,
+ 194, 5, 198, 33, 178, 160, 63, 50, 0, 177, 120, 31, 196, 231, 19,
+ 192, 51, 19, 190, 88, 28, 216, 0, 183, 167, 9, 134, 86, 24, 218,
+ 97, 232, 132, 161, 11, 134, 15, 240, 133, 143, 0, 31, 192, 185, 78,
+ 144, 166, 21, 228, 169, 5, 50, 138, 128, 204, 100, 160, 35, 24, 232,
+ 180, 5, 28, 84, 1, 39, 17, 192, 145, 9, 112, 62, 219, 6, 160,
+ 255, 147, 246, 163, 158, 177, 159, 0, 220, 123, 209, 128, 49, 56, 15,
+ 136, 51, 69, 208, 39, 155, 130, 114, 240, 7, 117, 244, 57, 40, 43,
+ 56, 223, 106, 80, 182, 109, 192, 190, 62, 248, 66, 124, 248, 228, 49,
+ 24, 70, 224, 139, 12, 126, 194, 8, 184, 54, 8, 210, 126, 0, 121,
+ 27, 129, 172, 34, 32, 251, 57, 208, 229, 15, 116, 155, 2, 46, 138,
+ 128, 27, 15, 224, 74, 3, 184, 19, 156, 177, 31, 245, 15, 236, 255,
+ 189, 182, 143, 246, 76, 221, 151, 4, 109, 142, 46, 232, 155, 61, 64,
+ 27, 253, 20, 212, 213, 60, 80, 102, 112, 222, 29, 48, 244, 194, 23,
+ 224, 193, 48, 6, 195, 36, 12, 211, 240, 133, 206, 240, 205, 202, 126,
+ 194, 71, 112, 109, 18, 164, 29, 2, 121, 59, 128, 172, 74, 32, 251,
+ 21, 208, 21, 4, 116, 91, 2, 46, 74, 128, 219, 143, 54, 128, 246,
+ 31, 180, 129, 103, 237, 71, 248, 3, 251, 201, 192, 125, 40, 43, 184,
+ 31, 185, 2, 198, 165, 119, 193, 248, 196, 11, 212, 201, 68, 208, 94,
+ 149, 128, 184, 109, 3, 252, 71, 128, 77, 112, 251, 62, 193, 39, 51,
+ 194, 176, 4, 195, 242, 79, 88, 2, 215, 62, 129, 180, 147, 32, 111,
+ 47, 144, 85, 11, 100, 103, 0, 93, 161, 64, 183, 13, 224, 114, 19,
+ 112, 227, 7, 92, 233, 0, 247, 127, 100, 63, 194, 31, 216, 79, 116,
+ 166, 237, 103, 3, 227, 140, 171, 96, 108, 110, 0, 198, 104, 190, 32,
+ 30, 95, 128, 54, 187, 18, 212, 221, 15, 160, 12, 225, 118, 204, 193,
+ 176, 8, 159, 144, 5, 195, 103, 24, 214, 97, 216, 248, 9, 235, 224,
+ 218, 10, 72, 59, 7, 242, 14, 1, 89, 77, 64, 118, 14, 208, 21,
+ 1, 116, 219, 3, 46, 42, 128, 155, 0, 224, 250, 163, 15, 32, 250,
+ 79, 218, 143, 123, 198, 126, 250, 51, 109, 255, 53, 208, 222, 24, 129,
+ 113, 170, 63, 24, 175, 188, 4, 253, 214, 91, 208, 126, 245, 129, 56,
+ 254, 8, 236, 89, 5, 54, 126, 129, 225, 43, 124, 49, 215, 79, 248,
+ 10, 174, 173, 131, 180, 139, 32, 239, 24, 144, 213, 10, 100, 231, 3,
+ 93, 209, 64, 183, 35, 224, 162, 10, 184, 253, 232, 3, 232, 207, 216,
+ 143, 251, 159, 180, 255, 28, 120, 30, 245, 195, 126, 33, 112, 127, 170,
+ 6, 198, 31, 206, 96, 188, 250, 4, 140, 91, 10, 65, 156, 182, 131,
+ 118, 108, 18, 196, 243, 10, 176, 11, 110, 227, 54, 124, 226, 52, 12,
+ 187, 48, 236, 1, 236, 130, 115, 219, 32, 205, 58, 200, 243, 9, 200,
+ 24, 4, 50, 107, 129, 142, 215, 64, 231, 3, 192, 193, 24, 112, 146,
+ 1, 28, 127, 216, 79, 113, 102, 12, 240, 175, 216, 143, 249, 147, 253,
+ 12, 96, 124, 45, 12, 250, 25, 117, 112, 175, 230, 2, 198, 236, 79,
+ 193, 216, 173, 24, 244, 225, 157, 160, 45, 159, 6, 117, 250, 51, 40,
+ 219, 109, 96, 235, 55, 248, 98, 181, 159, 240, 13, 92, 219, 6, 105,
+ 63, 131, 188, 211, 64, 86, 39, 144, 93, 12, 116, 61, 5, 186, 93,
+ 0, 23, 117, 192, 77, 24, 112, 101, 248, 201, 126, 204, 255, 102, 251,
+ 77, 193, 61, 91, 32, 24, 151, 188, 1, 237, 83, 3, 232, 203, 71,
+ 64, 252, 46, 157, 41, 251, 157, 51, 182, 31, 192, 55, 68, 3, 56,
+ 56, 227, 131, 157, 51, 49, 176, 4, 100, 140, 0, 153, 13, 64, 199,
+ 27, 160, 51, 16, 112, 48, 253, 31, 180, 95, 238, 39, 251, 131, 192,
+ 253, 203, 27, 48, 142, 109, 0, 237, 213, 40, 232, 215, 150, 65, 251,
+ 182, 5, 202, 247, 172, 237, 71, 0, 103, 125, 176, 11, 210, 110, 128,
+ 188, 179, 64, 214, 7, 32, 187, 20, 232, 138, 3, 186, 207, 218, 47,
+ 247, 191, 104, 127, 58, 224, 214, 8, 198, 116, 191, 101, 255, 30, 176,
+ 241, 172, 237, 103, 125, 176, 15, 210, 252, 150, 253, 221, 64, 118, 41,
+ 208, 245, 151, 253, 255, 183, 236, 255, 179, 196, 255, 159, 189, 253, 251,
+ 51, 244, 127, 127, 246, 241, 207, 95, 227, 223, 191, 238, 127, 254, 44,
+ 247, 191, 127, 246, 231, 31, 127, 61, 255, 250, 235, 249, 231, 95, 207,
+ 191, 255, 250, 253, 227, 207, 254, 251, 215, 159, 253, 247, 207, 63, 243,
+ 239, 223, 127, 246, 249, 15, 127, 205, 127, 249, 107, 254, 211, 159, 125,
+ 254, 219, 95, 243, 31, 255, 154, 255, 250, 215, 252, 231, 191, 230, 191,
+ 255, 181, 254, 225, 175, 245, 47, 127, 173, 127, 250, 107, 253, 219, 95,
+ 235, 31, 255, 90, 255, 250, 215, 250, 231, 255, 207, 215, 191, 255, 109,
+ 135, 8, 21, 181, 107, 234, 242, 183, 229, 149, 149, 216, 53, 101, 228,
+ 175, 95, 227, 248, 117, 111, 134, 153, 95, 247, 102, 56, 187, 15, 203,
+ 47, 123, 51, 252, 178, 191, 199, 101, 14, 75, 123, 179, 223, 216, 195,
+ 192, 81, 88, 247, 174, 189, 139, 161, 181, 133, 147, 185, 137, 35, 187,
+ 189, 163, 137, 181, 157, 129, 177, 137, 163, 46, 216, 177, 65, 247, 183,
+ 115, 255, 207, 126, 184, 16, 190, 253, 151, 246, 102, 248, 113, 110, 115,
+ 243, 215, 189, 25, 224, 199, 63, 246, 102, 24, 188, 241, 247, 50, 82,
+ 114, 127, 217, 155, 97, 228, 198, 47, 199, 63, 100, 156, 142, 156, 206,
+ 64, 248, 10, 50, 242, 50, 16, 2, 34, 2, 36, 7, 251, 7, 157,
+ 174, 17, 190, 185, 105, 110, 231, 108, 231, 100, 110, 103, 79, 123, 153,
+ 131, 11, 18, 188, 34, 127, 3, 105, 237, 151, 205, 148, 224, 41, 190,
+ 211, 0, 255, 195, 175, 33, 227, 124, 191, 6, 223, 238, 196, 253, 123,
+ 218, 173, 239, 223, 209, 127, 104, 255, 158, 6, 243, 7, 113, 248, 55,
+ 102, 124, 176, 245, 213, 15, 67, 16, 191, 231, 219, 249, 126, 44, 7,
+ 113, 154, 154, 194, 174, 88, 195, 254, 162, 130, 92, 191, 156, 121, 153,
+ 144, 248, 183, 51, 191, 108, 221, 165, 13, 251, 251, 227, 12, 223, 247,
+ 191, 236, 191, 158, 249, 46, 243, 219, 47, 155, 123, 65, 240, 200, 251,
+ 141, 15, 210, 210, 247, 125, 91, 254, 219, 175, 125, 183, 249, 199, 134,
+ 39, 72, 223, 191, 253, 82, 226, 164, 191, 87, 206, 223, 211, 160, 3,
+ 47, 127, 247, 20, 162, 228, 47, 0, 215, 206, 253, 205, 203, 132, 223,
+ 191, 99, 127, 79, 250, 9, 20, 165, 253, 47, 64, 184, 9, 65, 49,
+ 240, 243, 173, 48, 77, 8, 191, 89, 190, 235, 16, 174, 148, 177, 157,
+ 161, 9, 100, 12, 127, 191, 29, 194, 233, 56, 244, 0, 194, 70, 71,
+ 71, 199, 64, 199, 198, 192, 192, 38, 192, 194, 196, 34, 32, 198, 195,
+ 198, 198, 35, 38, 37, 34, 34, 38, 34, 34, 37, 192, 254, 254, 1,
+ 255, 253, 246, 7, 1, 7, 11, 11, 7, 23, 7, 31, 23, 23, 255,
+ 28, 46, 46, 238, 57, 248, 31, 220, 115, 191, 100, 33, 248, 103, 4,
+ 156, 214, 65, 4, 232, 48, 3, 236, 145, 16, 46, 64, 136, 4, 8,
+ 72, 4, 8, 167, 147, 48, 99, 209, 78, 155, 16, 36, 96, 44, 81,
+ 16, 190, 127, 128, 175, 144, 96, 230, 32, 163, 160, 162, 161, 99, 96,
+ 98, 33, 252, 124, 17, 1, 66, 68, 250, 113, 17, 31, 66, 64, 70,
+ 64, 66, 68, 70, 68, 65, 67, 69, 71, 65, 194, 190, 12, 187, 72,
+ 128, 132, 76, 71, 200, 141, 34, 117, 203, 128, 232, 130, 131, 31, 15,
+ 234, 185, 168, 151, 133, 87, 232, 25, 136, 85, 234, 13, 47, 243, 58,
+ 250, 247, 74, 163, 49, 70, 223, 222, 252, 248, 197, 200, 137, 143, 228,
+ 85, 81, 0, 211, 213, 24, 85, 227, 107, 13, 175, 157, 249, 207, 247,
+ 169, 205, 154, 124, 45, 126, 208, 216, 239, 50, 183, 37, 195, 252, 36,
+ 245, 97, 201, 211, 166, 129, 79, 219, 105, 165, 239, 7, 231, 119, 212,
+ 77, 93, 3, 99, 223, 148, 53, 15, 45, 236, 10, 200, 106, 152, 185,
+ 5, 197, 165, 151, 183, 12, 47, 238, 17, 64, 136, 136, 48, 182, 200,
+ 223, 57, 161, 161, 162, 240, 125, 167, 64, 199, 77, 136, 12, 99, 224,
+ 112, 129, 8, 133, 199, 47, 234, 28, 156, 65, 189, 74, 239, 230, 101,
+ 6, 195, 143, 142, 254, 209, 210, 183, 137, 141, 156, 120, 191, 48, 162,
+ 194, 9, 160, 49, 241, 53, 244, 193, 72, 188, 62, 111, 124, 77, 141,
+ 223, 217, 100, 246, 111, 20, 126, 159, 1, 243, 175, 20, 78, 199, 32,
+ 108, 164, 239, 58, 9, 32, 9, 168, 100, 237, 101, 106, 28, 6, 30,
+ 249, 234, 132, 237, 30, 47, 222, 167, 204, 119, 67, 26, 183, 177, 74,
+ 142, 134, 49, 14, 152, 180, 123, 118, 215, 220, 202, 147, 87, 236, 110,
+ 149, 32, 42, 62, 214, 70, 62, 124, 131, 91, 219, 190, 123, 232, 90,
+ 57, 181, 203, 166, 84, 58, 80, 230, 39, 63, 132, 86, 46, 207, 248,
+ 70, 172, 234, 176, 252, 158, 202, 237, 26, 181, 48, 78, 179, 117, 63,
+ 17, 55, 251, 229, 205, 201, 245, 177, 201, 252, 177, 144, 219, 150, 70,
+ 146, 180, 94, 180, 139, 21, 136, 66, 132, 226, 49, 53, 47, 198, 249,
+ 15, 125, 118, 204, 46, 133, 12, 234, 177, 27, 69, 84, 166, 223, 232,
+ 74, 66, 248, 216, 145, 186, 156, 128, 93, 154, 231, 58, 59, 139, 246,
+ 192, 31, 125, 12, 109, 135, 255, 152, 230, 88, 99, 57, 77, 96, 233,
+ 101, 106, 153, 73, 103, 142, 237, 148, 60, 141, 226, 50, 234, 97, 205,
+ 187, 161, 92, 81, 87, 212, 230, 17, 174, 30, 99, 251, 251, 135, 238,
+ 180, 70, 1, 219, 111, 164, 168, 251, 204, 154, 14, 239, 190, 246, 137,
+ 57, 169, 237, 90, 26, 188, 101, 124, 30, 215, 135, 147, 195, 80, 225,
+ 54, 43, 142, 62, 101, 27, 151, 81, 83, 67, 20, 59, 244, 98, 70,
+ 142, 168, 59, 250, 201, 61, 185, 125, 220, 155, 83, 195, 49, 107, 9,
+ 168, 202, 54, 216, 202, 125, 199, 27, 43, 169, 105, 143, 183, 119, 227,
+ 113, 241, 233, 55, 110, 10, 84, 248, 127, 92, 64, 118, 35, 72, 223,
+ 245, 106, 119, 30, 66, 15, 138, 120, 73, 173, 187, 181, 118, 185, 252,
+ 225, 121, 245, 186, 161, 53, 238, 151, 104, 241, 18, 251, 52, 31, 228,
+ 21, 4, 86, 153, 140, 154, 245, 79, 33, 230, 39, 167, 144, 37, 142,
+ 133, 133, 112, 56, 70, 112, 12, 243, 180, 196, 53, 244, 161, 6, 42,
+ 19, 253, 117, 15, 14, 119, 102, 127, 153, 110, 187, 253, 96, 229, 34,
+ 4, 134, 53, 130, 42, 249, 254, 218, 16, 121, 121, 235, 182, 204, 46,
+ 60, 100, 235, 40, 238, 47, 227, 184, 189, 102, 38, 165, 41, 144, 59,
+ 178, 136, 125, 184, 143, 187, 143, 217, 177, 183, 63, 251, 13, 196, 87,
+ 7, 143, 117, 153, 52, 133, 98, 50, 167, 211, 123, 167, 143, 34, 142,
+ 252, 3, 165, 35, 10, 99, 82, 144, 43, 132, 141, 151, 215, 198, 203,
+ 247, 188, 99, 183, 85, 97, 189, 101, 79, 177, 215, 67, 255, 197, 98,
+ 123, 232, 60, 73, 149, 228, 209, 204, 41, 228, 32, 82, 219, 103, 183,
+ 163, 179, 226, 211, 204, 66, 69, 65, 92, 246, 201, 216, 69, 183, 44,
+ 72, 128, 146, 170, 186, 102, 236, 75, 245, 158, 106, 213, 235, 145, 177,
+ 61, 30, 82, 175, 222, 116, 180, 164, 220, 221, 53, 23, 159, 1, 169,
+ 21, 134, 57, 103, 107, 165, 216, 254, 194, 81, 250, 129, 50, 4, 252,
+ 233, 180, 109, 159, 165, 212, 44, 19, 42, 129, 124, 149, 67, 7, 86,
+ 98, 157, 91, 123, 114, 1, 18, 53, 107, 234, 158, 84, 110, 132, 82,
+ 162, 130, 136, 188, 65, 164, 7, 194, 201, 105, 213, 199, 62, 125, 170,
+ 75, 236, 182, 244, 137, 155, 200, 98, 69, 104, 59, 46, 78, 186, 85,
+ 226, 81, 146, 54, 187, 149, 185, 236, 6, 238, 180, 34, 122, 232, 243,
+ 121, 167, 144, 236, 41, 244, 154, 16, 181, 79, 138, 92, 120, 36, 62,
+ 86, 67, 211, 105, 98, 49, 238, 186, 45, 20, 238, 21, 122, 192, 126,
+ 192, 190, 123, 111, 48, 101, 45, 12, 74, 26, 195, 224, 64, 58, 73,
+ 158, 10, 238, 227, 191, 238, 209, 73, 19, 71, 163, 56, 150, 61, 241,
+ 181, 87, 226, 249, 44, 122, 4, 193, 41, 164, 58, 237, 58, 16, 25,
+ 119, 15, 171, 204, 222, 3, 169, 117, 89, 34, 105, 191, 213, 206, 9,
+ 169, 172, 130, 170, 137, 232, 56, 118, 217, 76, 162, 186, 250, 208, 210,
+ 89, 117, 152, 123, 44, 26, 215, 175, 166, 78, 196, 167, 18, 235, 82,
+ 253, 203, 151, 235, 177, 168, 9, 145, 130, 71, 117, 87, 20, 20, 86,
+ 73, 251, 60, 208, 182, 94, 55, 42, 31, 36, 181, 42, 241, 227, 223,
+ 93, 243, 224, 234, 251, 152, 238, 254, 201, 238, 120, 254, 250, 132, 158,
+ 211, 39, 255, 41, 52, 218, 138, 15, 171, 252, 197, 203, 247, 180, 55,
+ 62, 251, 140, 63, 186, 176, 27, 64, 94, 133, 193, 70, 27, 57, 140,
+ 136, 219, 181, 238, 84, 43, 226, 58, 189, 115, 76, 126, 219, 176, 175,
+ 69, 163, 220, 181, 79, 151, 177, 25, 239, 235, 30, 94, 151, 35, 1,
+ 237, 24, 169, 88, 81, 157, 246, 71, 232, 186, 207, 179, 109, 177, 83,
+ 168, 227, 152, 249, 136, 5, 165, 146, 130, 5, 71, 36, 109, 221, 137,
+ 124, 193, 95, 239, 109, 28, 137, 180, 87, 178, 178, 235, 241, 114, 238,
+ 189, 220, 114, 39, 170, 150, 18, 91, 124, 233, 230, 112, 11, 135, 221,
+ 147, 167, 131, 39, 86, 62, 157, 242, 215, 117, 247, 30, 151, 157, 135,
+ 12, 113, 238, 201, 108, 184, 245, 21, 126, 144, 80, 62, 72, 126, 125,
+ 10, 101, 43, 205, 46, 150, 214, 81, 173, 249, 106, 95, 149, 233, 167,
+ 121, 237, 179, 83, 59, 124, 130, 79, 172, 185, 56, 209, 60, 178, 136,
+ 184, 200, 95, 251, 74, 91, 172, 65, 177, 86, 188, 251, 246, 128, 119,
+ 75, 33, 113, 25, 218, 144, 149, 147, 107, 77, 24, 215, 210, 199, 186,
+ 67, 189, 242, 173, 119, 113, 199, 188, 240, 224, 232, 21, 217, 76, 72,
+ 72, 86, 227, 180, 160, 75, 181, 139, 105, 181, 152, 62, 78, 78, 45,
+ 60, 104, 190, 213, 185, 58, 204, 69, 80, 84, 52, 214, 92, 147, 40,
+ 64, 60, 48, 43, 96, 81, 182, 139, 35, 237, 149, 40, 133, 202, 119,
+ 210, 55, 83, 200, 227, 211, 30, 55, 106, 148, 218, 225, 71, 159, 32,
+ 62, 48, 154, 116, 126, 142, 58, 101, 221, 80, 210, 122, 168, 79, 250,
+ 46, 68, 67, 131, 184, 49, 165, 199, 143, 218, 35, 25, 144, 137, 139,
+ 20, 142, 86, 69, 35, 33, 181, 126, 224, 179, 186, 242, 245, 88, 168,
+ 171, 112, 35, 51, 53, 230, 117, 34, 179, 116, 235, 226, 178, 237, 158,
+ 144, 139, 222, 69, 10, 243, 204, 197, 201, 210, 112, 139, 113, 242, 250,
+ 233, 42, 113, 239, 141, 21, 159, 248, 215, 69, 233, 213, 197, 186, 113,
+ 54, 236, 123, 114, 144, 185, 49, 65, 149, 143, 219, 210, 155, 194, 92,
+ 225, 36, 109, 190, 11, 188, 180, 73, 249, 195, 7, 185, 42, 153, 47,
+ 67, 113, 160, 32, 126, 125, 171, 99, 195, 41, 159, 232, 87, 125, 179,
+ 13, 75, 227, 111, 151, 152, 76, 197, 67, 104, 100, 167, 183, 137, 98,
+ 47, 91, 213, 217, 54, 190, 196, 151, 15, 119, 121, 49, 221, 46, 213,
+ 89, 100, 205, 64, 133, 206, 190, 187, 114, 61, 98, 37, 249, 85, 202,
+ 42, 100, 84, 86, 33, 133, 28, 196, 75, 99, 97, 30, 103, 251, 0,
+ 177, 97, 175, 162, 141, 182, 59, 163, 121, 215, 185, 35, 185, 241, 121,
+ 215, 212, 238, 41, 52, 172, 162, 98, 89, 67, 225, 182, 238, 206, 16,
+ 162, 239, 75, 155, 108, 165, 87, 129, 51, 88, 211, 170, 97, 216, 51,
+ 187, 138, 206, 39, 98, 142, 236, 79, 110, 144, 178, 102, 103, 122, 232,
+ 118, 140, 247, 45, 91, 162, 62, 107, 119, 125, 202, 184, 49, 60, 21,
+ 7, 15, 165, 218, 90, 124, 195, 233, 197, 70, 175, 79, 126, 38, 207,
+ 225, 234, 212, 161, 64, 205, 251, 158, 143, 235, 241, 20, 58, 20, 74,
+ 11, 199, 204, 62, 249, 223, 24, 82, 73, 52, 76, 226, 231, 243, 236,
+ 93, 103, 123, 113, 201, 5, 21, 75, 246, 248, 198, 189, 62, 164, 155,
+ 238, 122, 71, 108, 39, 111, 90, 90, 187, 168, 108, 14, 109, 16, 199,
+ 32, 244, 232, 173, 125, 217, 77, 250, 112, 112, 103, 241, 20, 90, 25,
+ 152, 29, 46, 124, 229, 98, 85, 123, 245, 27, 67, 19, 205, 61, 202,
+ 13, 215, 233, 111, 234, 94, 152, 181, 155, 4, 101, 229, 158, 126, 129,
+ 164, 51, 179, 140, 69, 8, 104, 203, 181, 86, 62, 30, 176, 16, 59,
+ 133, 122, 45, 46, 153, 173, 187, 164, 174, 30, 208, 178, 187, 163, 109,
+ 37, 111, 24, 115, 55, 142, 86, 159, 228, 111, 13, 232, 242, 96, 117,
+ 176, 237, 161, 34, 101, 235, 228, 205, 50, 126, 168, 57, 12, 28, 90,
+ 247, 73, 63, 86, 86, 24, 216, 16, 241, 162, 88, 137, 30, 191, 138,
+ 129, 22, 98, 99, 227, 242, 44, 185, 122, 191, 236, 224, 222, 216, 198,
+ 196, 118, 191, 141, 121, 94, 121, 28, 213, 26, 77, 26, 253, 68, 11,
+ 62, 37, 219, 30, 47, 119, 233, 161, 222, 209, 198, 1, 191, 119, 204,
+ 49, 139, 130, 207, 105, 223, 84, 221, 155, 238, 162, 105, 28, 219, 77,
+ 74, 163, 200, 141, 15, 115, 251, 119, 97, 45, 204, 170, 85, 231, 193,
+ 99, 37, 60, 221, 119, 175, 183, 239, 184, 241, 126, 161, 93, 169, 81,
+ 76, 21, 47, 24, 86, 149, 134, 5, 189, 46, 213, 20, 243, 41, 196,
+ 173, 203, 60, 252, 33, 202, 198, 67, 194, 214, 220, 181, 13, 123, 226,
+ 158, 197, 231, 136, 207, 180, 215, 242, 66, 94, 91, 188, 203, 228, 27,
+ 77, 216, 64, 246, 14, 229, 238, 23, 43, 61, 80, 44, 93, 42, 137,
+ 253, 216, 41, 91, 133, 228, 71, 77, 131, 242, 225, 88, 166, 249, 213,
+ 243, 243, 107, 140, 249, 165, 201, 215, 35, 186, 184, 69, 124, 86, 72,
+ 78, 216, 79, 18, 138, 242, 149, 237, 82, 181, 77, 189, 159, 224, 84,
+ 29, 211, 76, 157, 180, 28, 107, 35, 16, 242, 235, 73, 59, 145, 15,
+ 21, 44, 25, 249, 17, 161, 45, 123, 91, 18, 39, 92, 119, 114, 33,
+ 156, 114, 67, 186, 96, 54, 121, 10, 41, 30, 251, 120, 63, 94, 247,
+ 86, 12, 54, 46, 109, 112, 173, 168, 163, 77, 216, 93, 90, 155, 150,
+ 34, 171, 24, 18, 126, 133, 187, 96, 238, 108, 59, 20, 239, 182, 126,
+ 204, 185, 115, 10, 213, 61, 58, 239, 122, 103, 104, 221, 126, 2, 194,
+ 231, 157, 164, 244, 118, 219, 113, 165, 195, 178, 46, 234, 182, 170, 183,
+ 182, 25, 19, 53, 232, 234, 61, 212, 92, 56, 176, 53, 59, 162, 134,
+ 57, 253, 20, 26, 10, 138, 210, 209, 36, 239, 69, 105, 198, 186, 203,
+ 67, 201, 164, 187, 86, 93, 46, 112, 80, 155, 124, 32, 113, 67, 196,
+ 104, 144, 3, 23, 135, 155, 205, 159, 191, 202, 108, 252, 228, 252, 150,
+ 207, 179, 209, 195, 228, 221, 175, 42, 236, 229, 218, 253, 37, 159, 7,
+ 172, 45, 6, 168, 100, 114, 92, 135, 42, 223, 250, 8, 28, 72, 28,
+ 211, 209, 57, 61, 95, 40, 26, 18, 241, 56, 144, 122, 173, 1, 9,
+ 120, 113, 190, 90, 93, 118, 235, 59, 62, 168, 149, 221, 95, 185, 94,
+ 84, 30, 214, 229, 63, 195, 116, 213, 38, 160, 48, 125, 124, 91, 123,
+ 237, 101, 172, 214, 126, 8, 215, 160, 113, 220, 219, 176, 7, 197, 110,
+ 134, 67, 17, 139, 15, 146, 222, 37, 167, 159, 66, 183, 78, 33, 242,
+ 232, 216, 199, 218, 125, 55, 244, 35, 186, 227, 120, 45, 56, 112, 220,
+ 106, 15, 166, 186, 55, 147, 95, 159, 232, 16, 33, 178, 32, 12, 137,
+ 13, 225, 165, 213, 204, 242, 29, 136, 220, 45, 204, 27, 95, 94, 223,
+ 61, 156, 254, 108, 118, 92, 53, 91, 21, 63, 44, 98, 206, 30, 156,
+ 175, 55, 102, 121, 220, 121, 180, 104, 99, 127, 10, 213, 231, 202, 239,
+ 150, 190, 233, 26, 119, 195, 31, 162, 16, 144, 114, 246, 121, 48, 89,
+ 189, 92, 108, 183, 116, 124, 146, 165, 96, 100, 229, 106, 173, 239, 221,
+ 120, 187, 156, 183, 147, 171, 90, 198, 70, 226, 53, 251, 218, 254, 41,
+ 180, 51, 208, 197, 65, 162, 165, 123, 222, 119, 161, 166, 183, 90, 210,
+ 135, 87, 194, 174, 247, 68, 57, 243, 132, 232, 100, 156, 145, 221, 105,
+ 252, 182, 110, 95, 189, 89, 5, 137, 124, 156, 69, 57, 172, 83, 252,
+ 124, 10, 181, 106, 104, 177, 31, 83, 133, 79, 172, 145, 143, 26, 233,
+ 164, 146, 6, 201, 82, 212, 200, 141, 151, 31, 91, 195, 194, 171, 127,
+ 100, 201, 205, 182, 170, 89, 180, 74, 115, 115, 223, 126, 156, 252, 158,
+ 68, 209, 198, 246, 179, 154, 21, 31, 45, 110, 150, 174, 204, 157, 210,
+ 24, 147, 176, 49, 82, 231, 61, 188, 151, 184, 110, 229, 91, 79, 243,
+ 18, 252, 110, 176, 151, 211, 150, 230, 246, 148, 15, 92, 166, 149, 119,
+ 74, 52, 21, 15, 159, 215, 16, 201, 222, 30, 214, 94, 201, 114, 191,
+ 87, 111, 142, 199, 197, 16, 124, 180, 113, 228, 47, 239, 80, 69, 214,
+ 217, 96, 149, 229, 98, 99, 101, 137, 140, 49, 64, 253, 177, 118, 159,
+ 170, 67, 246, 220, 99, 30, 118, 225, 195, 15, 11, 232, 95, 15, 112,
+ 143, 167, 15, 166, 143, 200, 107, 237, 228, 77, 182, 53, 108, 40, 52,
+ 59, 172, 46, 212, 185, 160, 154, 140, 157, 66, 3, 62, 183, 110, 165,
+ 187, 144, 81, 232, 210, 27, 196, 227, 155, 45, 219, 156, 104, 148, 47,
+ 165, 166, 219, 145, 132, 56, 56, 165, 70, 234, 98, 156, 66, 153, 159,
+ 169, 182, 245, 214, 213, 239, 76, 166, 148, 33, 32, 135, 223, 219, 61,
+ 154, 126, 189, 221, 215, 124, 143, 66, 53, 12, 57, 201, 103, 99, 140,
+ 101, 148, 51, 218, 53, 73, 116, 59, 210, 104, 98, 216, 199, 130, 129,
+ 151, 135, 157, 196, 206, 2, 95, 191, 244, 1, 141, 197, 16, 127, 181,
+ 244, 209, 226, 193, 33, 97, 122, 191, 129, 123, 16, 95, 105, 96, 97,
+ 98, 163, 175, 57, 146, 146, 120, 236, 41, 116, 96, 142, 199, 48, 116,
+ 200, 22, 7, 41, 173, 165, 198, 135, 141, 151, 196, 9, 189, 123, 238,
+ 99, 64, 144, 75, 215, 197, 23, 72, 174, 147, 55, 211, 99, 76, 85,
+ 77, 222, 61, 105, 59, 116, 10, 5, 192, 186, 212, 187, 199, 54, 140,
+ 97, 36, 182, 105, 105, 213, 87, 239, 213, 164, 188, 64, 82, 108, 116,
+ 222, 114, 157, 156, 150, 62, 133, 68, 187, 201, 186, 207, 227, 57, 80,
+ 40, 29, 60, 31, 138, 90, 195, 73, 58, 89, 40, 222, 190, 171, 120,
+ 112, 18, 7, 11, 25, 34, 189, 216, 106, 74, 146, 183, 158, 79, 149,
+ 242, 130, 108, 81, 222, 45, 248, 208, 193, 170, 250, 100, 232, 41, 84,
+ 54, 40, 149, 112, 35, 97, 33, 210, 181, 50, 232, 70, 42, 62, 147,
+ 128, 167, 247, 198, 188, 196, 190, 207, 166, 207, 50, 97, 146, 130, 21,
+ 103, 230, 76, 144, 198, 114, 20, 158, 175, 238, 48, 162, 143, 252, 6,
+ 238, 100, 77, 190, 145, 171, 247, 41, 180, 229, 170, 25, 227, 166, 101,
+ 128, 29, 116, 40, 233, 164, 148, 234, 199, 236, 140, 122, 76, 99, 163,
+ 60, 173, 147, 99, 118, 32, 177, 104, 181, 163, 229, 91, 118, 195, 108,
+ 192, 230, 129, 63, 185, 36, 82, 33, 77, 170, 196, 243, 197, 147, 160,
+ 163, 11, 133, 106, 34, 119, 87, 130, 20, 223, 8, 188, 208, 92, 62,
+ 128, 245, 152, 50, 45, 158, 161, 242, 242, 150, 57, 93, 6, 185, 113,
+ 92, 138, 206, 17, 246, 8, 85, 27, 28, 147, 213, 163, 39, 181, 31,
+ 164, 47, 190, 183, 181, 231, 50, 116, 255, 244, 237, 20, 202, 63, 65,
+ 219, 238, 253, 208, 34, 250, 168, 213, 234, 206, 50, 210, 77, 201, 192,
+ 56, 174, 117, 187, 245, 195, 155, 28, 78, 202, 101, 116, 101, 74, 207,
+ 195, 196, 195, 55, 14, 23, 79, 178, 229, 241, 78, 7, 134, 15, 54,
+ 146, 188, 169, 81, 42, 70, 166, 229, 159, 158, 47, 227, 141, 183, 74,
+ 110, 249, 234, 154, 207, 146, 158, 113, 160, 39, 139, 185, 254, 124, 245,
+ 171, 157, 147, 206, 110, 226, 87, 136, 110, 175, 162, 178, 108, 88, 154,
+ 149, 243, 24, 181, 133, 187, 212, 246, 152, 99, 103, 53, 89, 43, 115,
+ 231, 242, 177, 202, 113, 138, 80, 46, 178, 171, 223, 164, 193, 246, 187,
+ 176, 62, 171, 110, 129, 185, 94, 61, 38, 170, 119, 187, 33, 246, 71,
+ 195, 85, 33, 19, 99, 94, 225, 71, 77, 209, 151, 134, 151, 188, 164,
+ 230, 206, 127, 222, 21, 236, 64, 70, 250, 16, 224, 214, 119, 146, 149,
+ 153, 248, 245, 115, 121, 252, 94, 16, 190, 182, 179, 149, 223, 152, 0,
+ 222, 74, 37, 121, 206, 219, 235, 194, 228, 99, 202, 149, 169, 165, 169,
+ 123, 139, 135, 56, 147, 88, 226, 157, 126, 198, 99, 138, 51, 113, 82,
+ 228, 82, 200, 101, 184, 126, 167, 80, 219, 41, 84, 78, 120, 187, 58,
+ 34, 185, 44, 29, 33, 19, 165, 190, 186, 28, 137, 38, 41, 199, 231,
+ 69, 80, 84, 116, 139, 252, 118, 27, 114, 96, 84, 193, 186, 8, 172,
+ 200, 229, 203, 247, 124, 118, 46, 180, 189, 218, 100, 141, 119, 162, 28,
+ 138, 97, 63, 184, 34, 233, 68, 51, 238, 86, 123, 10, 169, 179, 230,
+ 216, 39, 117, 35, 221, 46, 107, 24, 141, 202, 91, 40, 204, 67, 218,
+ 47, 47, 62, 98, 222, 21, 83, 222, 182, 80, 196, 31, 122, 172, 169,
+ 73, 121, 151, 211, 201, 77, 232, 147, 47, 239, 88, 99, 233, 244, 200,
+ 41, 244, 64, 166, 133, 118, 244, 166, 7, 95, 101, 24, 110, 65, 36,
+ 210, 227, 80, 193, 160, 242, 173, 68, 88, 8, 70, 40, 247, 221, 114,
+ 200, 236, 30, 115, 113, 74, 148, 118, 147, 90, 16, 179, 235, 60, 133,
+ 66, 143, 166, 183, 93, 152, 45, 240, 42, 103, 135, 130, 212, 59, 16,
+ 76, 2, 38, 228, 35, 94, 157, 66, 202, 99, 29, 20, 135, 225, 167,
+ 208, 96, 230, 13, 221, 225, 245, 55, 245, 154, 40, 41, 124, 41, 132,
+ 51, 107, 74, 161, 139, 91, 122, 135, 135, 167, 208, 11, 221, 225, 27,
+ 217, 151, 38, 21, 157, 169, 124, 35, 240, 61, 204, 135, 151, 125, 250,
+ 245, 140, 148, 199, 196, 174, 44, 245, 145, 233, 39, 77, 45, 4, 118,
+ 212, 152, 14, 173, 77, 117, 175, 158, 66, 45, 172, 238, 73, 28, 111,
+ 222, 146, 148, 190, 156, 79, 169, 240, 163, 253, 118, 111, 206, 117, 152,
+ 225, 141, 251, 182, 181, 49, 63, 21, 237, 121, 196, 105, 135, 128, 236,
+ 242, 136, 201, 177, 60, 46, 82, 215, 17, 216, 64, 145, 204, 58, 154,
+ 114, 33, 226, 245, 209, 27, 137, 99, 47, 1, 43, 105, 99, 73, 156,
+ 128, 10, 115, 101, 143, 147, 14, 2, 214, 220, 29, 222, 203, 241, 241,
+ 76, 114, 230, 199, 61, 74, 139, 214, 150, 10, 58, 253, 56, 176, 254,
+ 127, 29, 143, 106, 206, 224, 104, 216, 139, 198, 242, 165, 187, 137, 126,
+ 69, 100, 195, 50, 135, 121, 255, 132, 215, 59, 9, 69, 187, 175, 181,
+ 219, 175, 106, 237, 119, 3, 163, 234, 2, 223, 174, 248, 184, 139, 236,
+ 213, 230, 20, 175, 91, 68, 227, 85, 233, 191, 152, 149, 99, 95, 247,
+ 201, 173, 97, 148, 56, 29, 172, 222, 137, 203, 176, 245, 242, 165, 162,
+ 68, 10, 122, 239, 228, 226, 18, 102, 105, 93, 37, 73, 183, 78, 217,
+ 241, 46, 58, 108, 52, 110, 17, 93, 159, 195, 30, 95, 213, 193, 83,
+ 253, 38, 83, 67, 253, 214, 165, 75, 213, 234, 138, 101, 43, 75, 225,
+ 178, 161, 135, 94, 181, 85, 201, 107, 36, 18, 99, 245, 25, 99, 253,
+ 8, 175, 175, 232, 44, 239, 29, 237, 62, 249, 80, 95, 50, 44, 34,
+ 231, 198, 37, 200, 178, 168, 216, 236, 68, 87, 22, 92, 184, 78, 33,
+ 32, 24, 216, 186, 39, 226, 218, 95, 189, 148, 154, 250, 68, 195, 74,
+ 43, 219, 117, 181, 216, 233, 27, 90, 236, 144, 150, 132, 172, 83, 57,
+ 43, 233, 120, 2, 182, 7, 14, 34, 18, 100, 77, 226, 47, 53, 182,
+ 49, 53, 53, 89, 187, 51, 111, 144, 143, 191, 23, 80, 110, 29, 23,
+ 86, 87, 38, 91, 46, 139, 230, 69, 65, 182, 125, 10, 61, 155, 218,
+ 209, 224, 222, 61, 80, 114, 51, 234, 64, 135, 117, 211, 1, 159, 187,
+ 194, 229, 217, 198, 99, 251, 245, 41, 18, 53, 119, 35, 135, 9, 112,
+ 251, 176, 220, 74, 211, 199, 54, 236, 96, 189, 207, 18, 59, 230, 235,
+ 11, 163, 30, 180, 99, 107, 121, 140, 41, 176, 234, 179, 235, 163, 230,
+ 64, 99, 85, 56, 202, 195, 80, 118, 221, 109, 177, 222, 85, 12, 191,
+ 102, 45, 201, 172, 100, 137, 137, 31, 214, 40, 166, 6, 30, 147, 126,
+ 124, 32, 88, 33, 105, 225, 70, 128, 76, 210, 245, 116, 185, 250, 20,
+ 82, 59, 72, 190, 97, 222, 47, 137, 204, 215, 40, 9, 37, 4, 251,
+ 138, 74, 136, 44, 49, 109, 55, 249, 127, 132, 120, 121, 37, 135, 95,
+ 152, 45, 173, 203, 154, 35, 138, 4, 147, 71, 208, 81, 69, 43, 34,
+ 232, 120, 199, 89, 48, 44, 11, 215, 31, 125, 146, 42, 55, 35, 15,
+ 191, 119, 52, 127, 49, 170, 202, 37, 88, 98, 250, 85, 168, 98, 96,
+ 63, 82, 145, 156, 229, 148, 246, 34, 153, 197, 248, 26, 237, 46, 46,
+ 218, 100, 75, 245, 193, 99, 241, 61, 245, 185, 242, 165, 53, 124, 179,
+ 238, 73, 118, 183, 131, 83, 104, 169, 52, 205, 157, 178, 62, 82, 42,
+ 82, 144, 167, 48, 191, 242, 96, 195, 34, 236, 13, 31, 37, 6, 99,
+ 110, 196, 212, 131, 104, 216, 64, 119, 244, 251, 243, 142, 95, 158, 234,
+ 160, 125, 127, 250, 4, 187, 217, 255, 63, 252, 28, 227, 251, 246, 180,
+ 127, 255, 28, 3, 255, 180, 9, 138, 128, 32, 68, 164, 95, 159, 83,
+ 192, 159, 99, 32, 35, 32, 162, 64, 168, 104, 103, 31, 95, 128, 135,
+ 24, 136, 72, 248, 191, 60, 56, 64, 65, 64, 65, 65, 67, 66, 68,
+ 194, 128, 157, 35, 64, 34, 132, 232, 184, 47, 240, 32, 75, 93, 81,
+ 49, 36, 186, 101, 224, 72, 127, 25, 197, 193, 95, 250, 54, 170, 95,
+ 116, 81, 159, 145, 211, 185, 194, 87, 13, 81, 179, 155, 188, 170, 47,
+ 235, 191, 4, 196, 188, 46, 110, 100, 32, 128, 137, 69, 132, 41, 61,
+ 35, 152, 0, 145, 142, 91, 138, 16, 201, 239, 239, 159, 11, 152, 159,
+ 56, 116, 178, 68, 55, 69, 22, 150, 233, 138, 239, 120, 62, 142, 234,
+ 77, 136, 191, 200, 50, 83, 25, 145, 242, 233, 176, 35, 251, 92, 254,
+ 147, 204, 38, 72, 237, 105, 224, 166, 160, 147, 85, 158, 9, 138, 62,
+ 126, 186, 127, 82, 243, 225, 72, 238, 130, 30, 74, 22, 95, 114, 28,
+ 234, 52, 33, 238, 5, 213, 192, 237, 252, 167, 165, 174, 250, 121, 86,
+ 5, 15, 173, 245, 155, 219, 103, 194, 118, 79, 76, 131, 228, 133, 140,
+ 125, 145, 155, 30, 61, 176, 191, 92, 184, 47, 70, 94, 238, 230, 138,
+ 77, 94, 39, 199, 202, 129, 48, 77, 235, 115, 121, 125, 137, 189, 198,
+ 245, 37, 137, 36, 68, 158, 240, 161, 199, 51, 203, 116, 208, 169, 16,
+ 113, 56, 46, 132, 15, 141, 81, 110, 75, 255, 75, 156, 202, 182, 57,
+ 241, 200, 188, 126, 6, 143, 14, 23, 131, 41, 94, 2, 55, 57, 107,
+ 102, 201, 16, 198, 39, 19, 204, 207, 12, 157, 206, 95, 247, 245, 156,
+ 81, 88, 50, 199, 231, 93, 30, 12, 155, 232, 47, 48, 204, 116, 188,
+ 83, 247, 168, 42, 17, 159, 242, 173, 155, 140, 229, 167, 107, 71, 110,
+ 149, 232, 210, 173, 26, 214, 216, 215, 34, 72, 122, 34, 248, 148, 85,
+ 52, 117, 35, 92, 184, 42, 11, 43, 186, 20, 133, 212, 15, 123, 252,
+ 248, 205, 235, 181, 22, 41, 67, 214, 253, 28, 135, 90, 226, 18, 121,
+ 50, 36, 210, 10, 205, 175, 135, 46, 218, 209, 221, 145, 254, 253, 193,
+ 19, 72, 18, 23, 242, 121, 142, 236, 86, 7, 223, 188, 55, 98, 193,
+ 143, 51, 81, 87, 11, 245, 82, 243, 106, 233, 157, 215, 96, 229, 110,
+ 66, 69, 18, 122, 206, 223, 194, 230, 140, 80, 31, 225, 240, 245, 126,
+ 148, 149, 36, 38, 3, 42, 233, 246, 101, 14, 221, 3, 199, 196, 71,
+ 101, 159, 27, 208, 52, 153, 233, 152, 184, 13, 214, 122, 14, 21, 238,
+ 126, 243, 165, 224, 199, 198, 93, 16, 204, 13, 73, 103, 149, 42, 42,
+ 140, 189, 169, 38, 158, 67, 209, 117, 88, 177, 36, 156, 118, 83, 65,
+ 102, 252, 83, 97, 93, 4, 205, 84, 111, 124, 166, 12, 65, 3, 134,
+ 218, 244, 147, 3, 23, 237, 198, 251, 15, 114, 202, 104, 239, 155, 233,
+ 43, 236, 15, 115, 10, 240, 135, 6, 25, 206, 52, 132, 39, 213, 126,
+ 182, 65, 115, 253, 200, 205, 195, 255, 194, 226, 128, 234, 14, 226, 246,
+ 122, 227, 138, 123, 64, 230, 77, 196, 207, 23, 4, 198, 155, 238, 185,
+ 208, 123, 48, 219, 11, 149, 137, 80, 161, 93, 149, 12, 23, 241, 49,
+ 63, 133, 72, 170, 77, 22, 40, 16, 6, 4, 201, 132, 227, 144, 51,
+ 177, 91, 130, 77, 169, 185, 87, 244, 28, 232, 98, 242, 93, 71, 226,
+ 55, 105, 244, 208, 12, 95, 238, 249, 189, 141, 198, 157, 46, 191, 73,
+ 67, 120, 191, 79, 224, 240, 234, 146, 101, 93, 222, 162, 31, 11, 94,
+ 255, 161, 151, 144, 85, 34, 170, 100, 60, 115, 40, 13, 141, 202, 18,
+ 251, 87, 23, 133, 142, 168, 224, 241, 198, 6, 175, 177, 57, 251, 86,
+ 9, 68, 125, 164, 83, 104, 98, 140, 162, 66, 239, 195, 39, 202, 80,
+ 170, 111, 87, 223, 100, 107, 249, 68, 208, 175, 4, 204, 177, 126, 76,
+ 185, 88, 166, 134, 48, 29, 114, 64, 144, 125, 63, 136, 253, 164, 184,
+ 60, 120, 119, 89, 255, 20, 162, 122, 132, 49, 66, 132, 108, 43, 176,
+ 121, 60, 105, 95, 130, 159, 250, 220, 105, 25, 205, 215, 96, 128, 66,
+ 178, 205, 108, 78, 72, 30, 214, 250, 120, 189, 88, 83, 208, 172, 127,
+ 44, 51, 227, 179, 186, 214, 215, 62, 146, 199, 216, 116, 221, 111, 91,
+ 56, 198, 90, 145, 155, 136, 114, 69, 212, 59, 148, 23, 151, 132, 217,
+ 157, 75, 102, 90, 254, 128, 63, 35, 13, 91, 64, 126, 83, 162, 92,
+ 49, 223, 126, 142, 120, 149, 128, 205, 251, 245, 231, 65, 113, 19, 18,
+ 100, 54, 166, 41, 250, 7, 45, 223, 116, 36, 205, 88, 222, 156, 183,
+ 181, 53, 216, 22, 214, 158, 197, 49, 137, 96, 189, 20, 24, 22, 65,
+ 245, 165, 23, 39, 128, 67, 99, 218, 101, 186, 101, 119, 73, 209, 177,
+ 192, 132, 2, 197, 168, 197, 87, 140, 209, 25, 42, 188, 66, 194, 150,
+ 26, 22, 65, 128, 253, 46, 255, 109, 149, 220, 112, 88, 83, 84, 169,
+ 239, 214, 241, 237, 253, 71, 244, 177, 131, 253, 53, 239, 109, 235, 134,
+ 114, 136, 80, 105, 136, 148, 86, 197, 243, 77, 159, 186, 33, 140, 188,
+ 192, 150, 108, 119, 231, 109, 228, 44, 231, 84, 207, 56, 237, 177, 253,
+ 4, 69, 167, 133, 211, 34, 80, 11, 57, 40, 79, 14, 226, 88, 223,
+ 144, 28, 21, 204, 215, 193, 57, 133, 198, 133, 133, 238, 157, 39, 67,
+ 194, 25, 141, 244, 149, 130, 117, 148, 52, 28, 254, 170, 153, 100, 25,
+ 180, 33, 99, 110, 68, 251, 181, 247, 164, 46, 214, 146, 151, 35, 125,
+ 217, 66, 154, 145, 162, 28, 244, 90, 99, 159, 114, 115, 233, 91, 169,
+ 127, 52, 208, 174, 26, 204, 144, 186, 79, 193, 126, 103, 35, 146, 38,
+ 76, 14, 59, 231, 125, 76, 58, 227, 244, 51, 47, 195, 61, 175, 207,
+ 77, 97, 65, 116, 148, 142, 72, 126, 61, 122, 34, 229, 105, 41, 220,
+ 163, 129, 12, 212, 228, 238, 110, 132, 9, 108, 223, 190, 6, 32, 83,
+ 211, 112, 86, 223, 177, 159, 194, 96, 29, 48, 101, 94, 93, 30, 191,
+ 126, 123, 34, 15, 19, 195, 23, 131, 71, 169, 101, 100, 12, 79, 38,
+ 206, 68, 239, 77, 227, 133, 98, 108, 108, 216, 32, 139, 200, 71, 252,
+ 192, 120, 108, 45, 198, 208, 131, 64, 145, 152, 144, 204, 203, 168, 191,
+ 35, 135, 99, 168, 215, 136, 91, 62, 28, 89, 126, 36, 166, 67, 231,
+ 32, 70, 219, 43, 109, 176, 237, 133, 172, 22, 42, 207, 8, 205, 199,
+ 130, 109, 115, 62, 2, 148, 224, 58, 15, 200, 216, 144, 223, 222, 243,
+ 157, 178, 227, 193, 182, 247, 36, 235, 124, 206, 245, 250, 144, 153, 195,
+ 245, 220, 88, 109, 76, 242, 247, 215, 98, 241, 55, 77, 40, 213, 189,
+ 196, 39, 5, 212, 100, 150, 175, 249, 106, 185, 109, 70, 222, 175, 175,
+ 241, 68, 84, 79, 121, 195, 246, 0, 197, 90, 191, 222, 37, 236, 137,
+ 205, 167, 222, 107, 23, 19, 72, 235, 203, 216, 11, 68, 186, 99, 70,
+ 179, 122, 117, 12, 131, 175, 100, 170, 220, 212, 26, 140, 220, 17, 220,
+ 177, 120, 148, 197, 81, 175, 180, 34, 144, 147, 212, 93, 45, 101, 156,
+ 115, 63, 186, 113, 53, 150, 146, 246, 91, 254, 137, 54, 7, 66, 202,
+ 151, 118, 181, 160, 1, 119, 75, 150, 167, 134, 117, 235, 45, 65, 227,
+ 217, 95, 51, 66, 38, 77, 130, 15, 188, 187, 144, 115, 26, 30, 138,
+ 50, 71, 4, 102, 245, 81, 208, 114, 51, 212, 225, 95, 16, 27, 43,
+ 10, 167, 37, 85, 95, 137, 24, 253, 152, 161, 47, 164, 116, 59, 120,
+ 178, 226, 147, 132, 89, 185, 20, 178, 237, 185, 28, 8, 27, 143, 230,
+ 115, 143, 150, 191, 177, 13, 2, 194, 196, 6, 25, 158, 237, 35, 53,
+ 41, 173, 185, 74, 245, 100, 164, 143, 41, 194, 88, 228, 5, 231, 35,
+ 121, 177, 83, 159, 72, 20, 79, 166, 44, 49, 38, 10, 61, 173, 104,
+ 233, 147, 104, 201, 174, 42, 230, 33, 93, 70, 251, 204, 232, 53, 70,
+ 193, 146, 28, 249, 73, 35, 145, 76, 0, 209, 44, 255, 250, 109, 182,
+ 135, 133, 180, 97, 17, 21, 158, 129, 190, 120, 58, 209, 105, 50, 179,
+ 134, 174, 115, 43, 97, 82, 35, 151, 46, 16, 189, 185, 222, 202, 188,
+ 252, 70, 19, 91, 117, 83, 13, 95, 242, 11, 218, 45, 203, 160, 235,
+ 250, 4, 133, 225, 151, 143, 19, 161, 139, 237, 152, 33, 209, 138, 50,
+ 253, 148, 74, 15, 154, 235, 39, 171, 136, 217, 85, 50, 140, 16, 239,
+ 75, 172, 247, 35, 27, 197, 12, 73, 225, 43, 248, 10, 68, 40, 85,
+ 146, 151, 171, 172, 182, 175, 8, 140, 251, 126, 153, 75, 65, 184, 93,
+ 23, 194, 118, 161, 76, 20, 243, 75, 221, 106, 136, 96, 54, 10, 146,
+ 237, 149, 251, 120, 41, 43, 214, 79, 145, 195, 111, 166, 122, 119, 239,
+ 65, 131, 55, 30, 152, 60, 54, 190, 74, 19, 90, 215, 74, 67, 32,
+ 140, 251, 244, 161, 40, 157, 107, 4, 82, 227, 97, 162, 114, 69, 110,
+ 124, 138, 164, 12, 242, 252, 219, 162, 195, 227, 182, 55, 78, 72, 100,
+ 179, 82, 151, 160, 117, 188, 115, 118, 213, 89, 92, 92, 228, 5, 88,
+ 77, 168, 70, 80, 254, 215, 103, 147, 89, 76, 5, 31, 30, 222, 49,
+ 144, 226, 113, 139, 22, 93, 205, 162, 84, 195, 16, 221, 229, 37, 212,
+ 208, 151, 218, 61, 40, 81, 88, 69, 175, 101, 168, 183, 86, 115, 91,
+ 62, 174, 122, 169, 174, 113, 81, 142, 175, 109, 228, 139, 122, 120, 218,
+ 238, 10, 70, 53, 129, 142, 166, 76, 187, 168, 251, 220, 194, 241, 124,
+ 159, 6, 67, 110, 104, 240, 80, 6, 148, 193, 32, 117, 123, 97, 97,
+ 43, 239, 89, 105, 119, 51, 142, 251, 39, 210, 197, 40, 81, 239, 218,
+ 154, 180, 216, 242, 172, 55, 106, 197, 132, 80, 161, 106, 228, 213, 8,
+ 69, 203, 136, 211, 94, 135, 231, 143, 73, 85, 59, 190, 132, 13, 211,
+ 227, 176, 49, 14, 234, 244, 103, 56, 40, 190, 84, 115, 242, 207, 176,
+ 108, 219, 225, 239, 214, 26, 92, 207, 100, 119, 204, 38, 126, 199, 99,
+ 37, 146, 7, 185, 112, 30, 84, 221, 153, 29, 28, 232, 208, 247, 247,
+ 39, 83, 88, 87, 93, 207, 61, 89, 240, 187, 179, 179, 169, 110, 184,
+ 40, 54, 124, 105, 194, 83, 163, 49, 170, 116, 81, 143, 109, 253, 158,
+ 111, 6, 189, 56, 151, 0, 154, 182, 216, 134, 83, 12, 165, 58, 3,
+ 212, 95, 54, 227, 233, 147, 144, 238, 35, 249, 217, 91, 150, 164, 96,
+ 238, 157, 31, 223, 73, 92, 137, 10, 229, 11, 211, 105, 27, 250, 9,
+ 239, 184, 137, 155, 184, 211, 6, 199, 137, 187, 199, 221, 46, 215, 176,
+ 137, 71, 16, 62, 10, 107, 84, 106, 223, 75, 108, 203, 35, 247, 78,
+ 196, 99, 28, 31, 217, 242, 139, 186, 128, 150, 110, 151, 87, 90, 109,
+ 54, 129, 106, 193, 194, 88, 115, 189, 118, 225, 6, 231, 180, 43, 142,
+ 110, 21, 2, 141, 221, 144, 179, 82, 151, 188, 121, 248, 77, 143, 215,
+ 143, 10, 182, 188, 186, 208, 82, 215, 60, 18, 196, 185, 159, 68, 68,
+ 201, 207, 74, 82, 145, 59, 149, 16, 63, 201, 13, 17, 244, 71, 194,
+ 197, 191, 95, 40, 252, 225, 179, 165, 137, 169, 161, 135, 36, 151, 106,
+ 171, 138, 236, 185, 45, 131, 92, 220, 225, 18, 78, 251, 98, 102, 21,
+ 22, 194, 152, 194, 48, 164, 210, 60, 201, 23, 120, 207, 71, 209, 236,
+ 222, 86, 217, 166, 220, 146, 211, 247, 80, 246, 155, 73, 111, 145, 122,
+ 227, 119, 103, 180, 85, 100, 168, 211, 204, 80, 168, 72, 152, 79, 110,
+ 250, 162, 254, 120, 200, 77, 60, 156, 218, 132, 20, 86, 169, 200, 171,
+ 69, 33, 104, 117, 121, 41, 217, 97, 225, 125, 66, 58, 39, 159, 93,
+ 234, 184, 240, 229, 16, 82, 49, 68, 209, 135, 209, 158, 15, 6, 211,
+ 218, 202, 14, 28, 39, 226, 234, 26, 209, 114, 217, 193, 154, 233, 199,
+ 150, 162, 250, 193, 114, 201, 37, 84, 186, 74, 90, 56, 3, 126, 34,
+ 215, 195, 73, 87, 30, 186, 10, 38, 212, 181, 39, 132, 189, 109, 75,
+ 73, 123, 136, 186, 242, 118, 38, 128, 222, 79, 220, 70, 161, 246, 34,
+ 54, 170, 241, 2, 205, 224, 218, 64, 251, 90, 3, 207, 83, 162, 143,
+ 75, 131, 108, 172, 193, 152, 114, 120, 37, 14, 205, 232, 54, 40, 131,
+ 88, 118, 164, 177, 200, 248, 184, 77, 56, 55, 24, 102, 120, 46, 240,
+ 204, 139, 202, 29, 226, 230, 240, 71, 166, 39, 8, 64, 238, 173, 171,
+ 122, 210, 134, 8, 250, 50, 141, 14, 21, 9, 203, 131, 132, 150, 29,
+ 22, 129, 148, 226, 141, 43, 61, 214, 237, 14, 33, 152, 180, 21, 99,
+ 98, 99, 171, 222, 38, 80, 222, 39, 169, 2, 47, 141, 17, 23, 53,
+ 83, 18, 90, 10, 84, 180, 53, 180, 241, 12, 186, 39, 92, 80, 8,
+ 81, 163, 95, 210, 77, 179, 183, 248, 58, 236, 193, 91, 8, 131, 25,
+ 167, 80, 36, 217, 0, 177, 49, 195, 90, 161, 47, 90, 237, 213, 72,
+ 36, 91, 15, 165, 14, 10, 63, 49, 109, 204, 113, 179, 217, 135, 88,
+ 197, 151, 48, 167, 165, 151, 123, 212, 194, 25, 234, 110, 78, 100, 25,
+ 249, 13, 187, 65, 98, 239, 73, 250, 30, 42, 20, 250, 73, 188, 243,
+ 18, 95, 211, 146, 62, 215, 84, 84, 160, 190, 72, 17, 245, 110, 159,
+ 195, 23, 179, 94, 146, 26, 41, 215, 45, 210, 75, 155, 104, 208, 172,
+ 117, 84, 68, 155, 231, 168, 8, 34, 104, 17, 171, 17, 230, 179, 206,
+ 33, 31, 154, 141, 46, 24, 15, 212, 250, 50, 72, 45, 125, 195, 230,
+ 5, 84, 37, 63, 78, 45, 104, 178, 162, 57, 72, 130, 103, 140, 242,
+ 208, 196, 235, 19, 46, 235, 137, 141, 218, 228, 173, 74, 223, 248, 168,
+ 221, 12, 88, 231, 197, 113, 187, 186, 236, 189, 225, 199, 91, 17, 109,
+ 154, 234, 163, 146, 43, 249, 156, 119, 30, 171, 213, 210, 145, 176, 199,
+ 191, 52, 111, 16, 122, 18, 117, 10, 185, 106, 251, 15, 167, 208, 51,
+ 250, 93, 192, 86, 190, 254, 205, 252, 60, 211, 197, 138, 19, 166, 69,
+ 66, 217, 39, 24, 250, 95, 50, 145, 63, 45, 25, 99, 72, 80, 16,
+ 149, 73, 110, 209, 111, 175, 136, 68, 225, 88, 32, 177, 53, 51, 202,
+ 14, 96, 108, 14, 210, 156, 246, 137, 249, 177, 97, 107, 157, 92, 29,
+ 85, 97, 52, 121, 237, 57, 37, 70, 142, 53, 122, 43, 125, 142, 163,
+ 201, 175, 236, 214, 64, 53, 177, 233, 182, 69, 246, 202, 45, 147, 102,
+ 226, 219, 174, 46, 161, 15, 168, 241, 212, 139, 14, 163, 145, 184, 53,
+ 155, 234, 253, 42, 88, 9, 202, 166, 52, 123, 204, 42, 243, 14, 253,
+ 235, 91, 29, 146, 51, 134, 115, 142, 133, 159, 174, 221, 187, 62, 110,
+ 68, 190, 229, 243, 134, 243, 232, 197, 222, 5, 134, 18, 18, 250, 37,
+ 81, 190, 210, 131, 97, 119, 145, 59, 195, 196, 7, 146, 228, 120, 66,
+ 199, 178, 7, 143, 245, 38, 142, 92, 4, 228, 195, 184, 143, 197, 166,
+ 166, 114, 212, 246, 146, 34, 194, 199, 218, 136, 197, 202, 142, 194, 42,
+ 103, 37, 76, 75, 37, 174, 95, 205, 155, 247, 71, 101, 240, 147, 208,
+ 187, 222, 92, 99, 229, 83, 253, 146, 138, 212, 158, 64, 148, 63, 204,
+ 212, 245, 73, 196, 51, 158, 26, 17, 212, 57, 90, 199, 164, 210, 202,
+ 113, 242, 169, 183, 88, 70, 162, 24, 155, 199, 85, 242, 34, 134, 73,
+ 235, 8, 47, 29, 177, 101, 31, 149, 107, 116, 176, 213, 198, 142, 229,
+ 148, 84, 99, 14, 17, 107, 248, 170, 171, 122, 83, 10, 42, 172, 154,
+ 149, 174, 53, 100, 5, 84, 208, 26, 237, 122, 57, 71, 152, 214, 151,
+ 51, 73, 111, 93, 117, 239, 214, 220, 181, 186, 147, 134, 108, 88, 71,
+ 76, 107, 66, 179, 115, 59, 101, 35, 24, 59, 193, 36, 50, 52, 94,
+ 22, 105, 101, 128, 128, 162, 144, 81, 46, 54, 226, 208, 89, 159, 7,
+ 17, 143, 215, 203, 80, 242, 171, 185, 146, 76, 59, 6, 118, 181, 175,
+ 187, 191, 40, 47, 146, 33, 150, 147, 3, 87, 106, 56, 50, 193, 252,
+ 158, 101, 150, 60, 2, 26, 191, 254, 145, 233, 5, 201, 175, 252, 185,
+ 58, 10, 21, 20, 24, 95, 102, 211, 7, 83, 218, 98, 175, 96, 16,
+ 87, 88, 80, 211, 134, 77, 248, 220, 147, 148, 231, 80, 203, 162, 83,
+ 229, 228, 189, 26, 152, 84, 177, 244, 180, 184, 125, 190, 36, 220, 100,
+ 142, 208, 179, 4, 115, 96, 140, 13, 57, 8, 165, 137, 72, 180, 113,
+ 224, 246, 64, 149, 193, 10, 30, 105, 188, 49, 50, 219, 126, 80, 4,
+ 127, 64, 152, 254, 167, 22, 207, 189, 168, 109, 241, 194, 180, 108, 83,
+ 132, 161, 117, 71, 60, 22, 63, 4, 191, 237, 205, 126, 244, 206, 243,
+ 115, 56, 16, 122, 235, 230, 248, 35, 174, 30, 82, 10, 170, 172, 229,
+ 155, 185, 37, 72, 132, 174, 97, 40, 177, 45, 188, 168, 87, 228, 167,
+ 201, 208, 236, 113, 5, 155, 179, 216, 159, 135, 102, 249, 214, 200, 182,
+ 183, 124, 51, 147, 42, 107, 194, 68, 98, 101, 110, 118, 160, 13, 107,
+ 193, 117, 110, 233, 28, 195, 156, 84, 91, 157, 176, 251, 202, 234, 88,
+ 49, 97, 140, 247, 165, 208, 214, 6, 201, 231, 50, 3, 7, 155, 33,
+ 93, 197, 85, 23, 147, 236, 76, 217, 91, 133, 119, 44, 24, 141, 137,
+ 99, 96, 13, 242, 235, 185, 160, 214, 202, 10, 23, 226, 135, 183, 139,
+ 155, 102, 231, 250, 55, 134, 213, 244, 77, 116, 53, 99, 253, 153, 7,
+ 100, 163, 62, 248, 5, 186, 180, 183, 30, 221, 98, 66, 195, 31, 175,
+ 183, 171, 201, 98, 40, 246, 23, 180, 46, 184, 175, 92, 45, 173, 169,
+ 112, 206, 180, 87, 52, 231, 250, 83, 90, 39, 122, 239, 221, 108, 45,
+ 20, 61, 61, 163, 103, 252, 155, 17, 60, 51, 29, 43, 61, 248, 53,
+ 129, 109, 106, 116, 117, 15, 13, 118, 144, 79, 176, 114, 86, 95, 53,
+ 188, 44, 207, 12, 184, 78, 53, 132, 59, 34, 248, 117, 137, 170, 255,
+ 243, 123, 181, 16, 110, 20, 247, 130, 29, 38, 216, 157, 103, 230, 61,
+ 154, 147, 139, 36, 242, 197, 136, 10, 15, 219, 37, 79, 161, 195, 243,
+ 170, 152, 217, 172, 111, 26, 2, 162, 140, 94, 20, 191, 67, 53, 10,
+ 159, 212, 102, 31, 186, 189, 31, 133, 63, 82, 212, 66, 212, 159, 104,
+ 33, 109, 19, 158, 214, 87, 100, 99, 217, 48, 187, 248, 116, 192, 65,
+ 196, 184, 35, 143, 170, 199, 44, 47, 122, 139, 181, 24, 215, 196, 240,
+ 157, 12, 149, 85, 232, 10, 58, 199, 173, 46, 59, 196, 52, 243, 130,
+ 152, 106, 229, 121, 113, 137, 125, 203, 230, 161, 55, 181, 209, 24, 151,
+ 80, 234, 136, 162, 35, 148, 198, 8, 39, 93, 30, 220, 65, 37, 214,
+ 252, 38, 141, 168, 16, 78, 154, 204, 207, 121, 10, 153, 134, 61, 245,
+ 83, 251, 74, 139, 90, 55, 171, 249, 241, 20, 42, 61, 62, 120, 53,
+ 148, 229, 70, 28, 41, 141, 92, 108, 17, 245, 110, 20, 101, 60, 238,
+ 169, 11, 71, 198, 251, 108, 221, 248, 135, 77, 78, 78, 56, 233, 36,
+ 205, 46, 14, 38, 38, 248, 229, 244, 136, 76, 234, 18, 247, 205, 197,
+ 118, 197, 170, 40, 174, 242, 95, 189, 239, 143, 59, 106, 95, 205, 184,
+ 56, 223, 227, 115, 218, 207, 23, 11, 213, 146, 103, 88, 78, 180, 87,
+ 190, 80, 63, 209, 241, 32, 98, 28, 50, 243, 48, 12, 116, 129, 50,
+ 244, 26, 10, 66, 141, 118, 87, 13, 123, 110, 112, 72, 114, 45, 158,
+ 191, 69, 168, 137, 177, 143, 54, 25, 102, 56, 122, 45, 182, 74, 126,
+ 159, 103, 156, 203, 51, 104, 82, 24, 173, 54, 61, 3, 77, 68, 161,
+ 121, 75, 184, 251, 228, 213, 186, 184, 247, 220, 44, 37, 66, 196, 241,
+ 216, 182, 243, 144, 8, 94, 95, 29, 149, 3, 77, 9, 149, 7, 69,
+ 190, 14, 103, 81, 63, 118, 105, 52, 2, 181, 248, 244, 228, 64, 249,
+ 195, 33, 211, 10, 25, 151, 134, 0, 136, 228, 128, 108, 11, 199, 124,
+ 38, 27, 247, 252, 37, 202, 198, 21, 217, 91, 228, 50, 137, 147, 171,
+ 234, 90, 193, 17, 163, 107, 253, 219, 23, 191, 13, 81, 16, 20, 163,
+ 206, 102, 239, 122, 239, 86, 86, 59, 247, 190, 154, 243, 39, 38, 108,
+ 82, 154, 11, 166, 38, 55, 96, 41, 173, 14, 44, 244, 33, 187, 77,
+ 114, 141, 80, 233, 176, 40, 99, 235, 205, 147, 53, 218, 230, 249, 219,
+ 28, 212, 23, 189, 187, 204, 119, 231, 179, 139, 242, 159, 248, 35, 145,
+ 137, 146, 215, 250, 28, 218, 229, 21, 54, 239, 105, 151, 60, 236, 52,
+ 148, 108, 51, 173, 64, 69, 216, 98, 42, 185, 36, 90, 41, 115, 113,
+ 162, 120, 91, 184, 107, 173, 88, 199, 91, 52, 13, 50, 108, 250, 70,
+ 182, 210, 162, 52, 36, 153, 43, 205, 27, 27, 169, 81, 223, 189, 95,
+ 34, 205, 168, 68, 91, 212, 157, 37, 232, 47, 234, 204, 35, 239, 173,
+ 143, 241, 241, 80, 54, 96, 133, 56, 56, 193, 136, 246, 74, 249, 64,
+ 183, 226, 165, 237, 149, 43, 153, 172, 17, 215, 159, 27, 187, 183, 200,
+ 248, 170, 191, 208, 52, 143, 97, 73, 15, 84, 17, 187, 147, 214, 131,
+ 80, 204, 36, 130, 42, 135, 115, 1, 3, 169, 227, 213, 24, 75, 1,
+ 75, 204, 133, 226, 39, 1, 85, 145, 232, 65, 122, 246, 152, 142, 174,
+ 104, 36, 43, 55, 153, 248, 67, 87, 133, 81, 89, 105, 99, 25, 164,
+ 158, 199, 173, 240, 83, 214, 214, 188, 62, 215, 22, 114, 129, 86, 62,
+ 156, 118, 73, 149, 5, 18, 136, 62, 255, 204, 150, 190, 81, 131, 227,
+ 154, 63, 189, 47, 210, 26, 57, 102, 129, 171, 28, 45, 255, 189, 2,
+ 200, 221, 130, 112, 182, 12, 191, 153, 220, 254, 86, 133, 95, 147, 221,
+ 66, 255, 100, 61, 166, 223, 183, 115, 200, 47, 195, 34, 166, 250, 88,
+ 77, 36, 185, 140, 89, 136, 83, 195, 185, 188, 162, 62, 245, 112, 186,
+ 217, 15, 169, 32, 162, 27, 206, 71, 227, 93, 54, 188, 191, 226, 44,
+ 28, 118, 145, 180, 152, 192, 36, 155, 229, 147, 123, 183, 242, 94, 141,
+ 176, 17, 57, 153, 97, 111, 112, 235, 99, 60, 95, 156, 206, 220, 60,
+ 170, 26, 189, 62, 253, 118, 105, 91, 228, 237, 130, 25, 45, 177, 137,
+ 170, 139, 156, 250, 153, 100, 108, 183, 52, 53, 77, 155, 174, 11, 60,
+ 153, 91, 72, 219, 38, 113, 187, 90, 74, 171, 47, 183, 159, 18, 26,
+ 53, 70, 102, 125, 109, 59, 155, 63, 249, 219, 57, 55, 232, 41, 99,
+ 182, 244, 151, 75, 83, 82, 171, 186, 111, 167, 107, 211, 40, 74, 89,
+ 167, 216, 203, 184, 175, 182, 108, 238, 34, 37, 148, 127, 155, 54, 74,
+ 52, 15, 177, 178, 193, 206, 53, 216, 231, 200, 52, 201, 202, 118, 64,
+ 21, 74, 184, 127, 84, 149, 203, 16, 104, 236, 159, 206, 199, 27, 195,
+ 205, 32, 73, 226, 53, 137, 46, 210, 31, 160, 235, 95, 106, 42, 65,
+ 119, 163, 217, 169, 189, 173, 92, 218, 99, 91, 173, 242, 121, 126, 107,
+ 90, 60, 183, 142, 194, 183, 141, 182, 112, 49, 205, 138, 30, 166, 201,
+ 193, 134, 221, 207, 89, 243, 247, 31, 84, 239, 179, 137, 71, 122, 102,
+ 237, 89, 148, 85, 205, 80, 63, 115, 160, 83, 183, 102, 160, 74, 30,
+ 15, 18, 23, 214, 169, 53, 113, 195, 252, 188, 51, 26, 142, 21, 184,
+ 159, 127, 183, 165, 113, 139, 237, 235, 210, 163, 80, 181, 176, 193, 2,
+ 87, 229, 48, 199, 145, 185, 133, 172, 250, 163, 247, 47, 148, 239, 60,
+ 98, 180, 226, 72, 229, 25, 80, 48, 125, 169, 95, 119, 216, 245, 201,
+ 6, 99, 120, 174, 208, 33, 23, 71, 61, 163, 136, 21, 194, 151, 189,
+ 149, 89, 227, 61, 201, 245, 52, 215, 63, 155, 133, 225, 85, 219, 43,
+ 253, 76, 21, 250, 57, 155, 34, 61, 167, 161, 55, 143, 90, 108, 21,
+ 80, 236, 173, 162, 133, 40, 62, 228, 47, 52, 82, 169, 210, 233, 220,
+ 185, 200, 87, 46, 60, 162, 51, 199, 230, 22, 208, 25, 90, 113, 224,
+ 220, 197, 46, 230, 139, 162, 38, 39, 56, 223, 167, 41, 27, 23, 200,
+ 207, 234, 89, 34, 146, 243, 94, 198, 229, 227, 151, 231, 143, 33, 116,
+ 188, 67, 47, 60, 225, 82, 129, 97, 101, 219, 214, 91, 143, 10, 217,
+ 234, 108, 25, 195, 181, 134, 166, 108, 109, 174, 221, 60, 234, 144, 27,
+ 187, 114, 17, 185, 77, 72, 244, 107, 238, 139, 36, 234, 134, 105, 210,
+ 59, 106, 237, 16, 251, 59, 102, 167, 128, 75, 66, 59, 230, 110, 163,
+ 99, 140, 23, 58, 82, 170, 231, 140, 18, 38, 54, 30, 149, 177, 182,
+ 79, 76, 77, 170, 181, 29, 93, 19, 109, 109, 97, 186, 40, 192, 247,
+ 34, 176, 163, 195, 176, 44, 248, 116, 192, 246, 107, 159, 129, 131, 44,
+ 97, 131, 4, 123, 253, 248, 158, 103, 9, 71, 115, 68, 226, 230, 103,
+ 238, 144, 54, 122, 191, 221, 165, 201, 186, 194, 15, 250, 248, 119, 227,
+ 229, 70, 139, 68, 59, 76, 239, 36, 9, 29, 152, 32, 96, 113, 249,
+ 163, 206, 132, 33, 222, 29, 208, 72, 20, 145, 67, 86, 200, 73, 250,
+ 102, 213, 172, 74, 182, 175, 28, 191, 165, 124, 82, 105, 213, 227, 163,
+ 185, 199, 98, 130, 16, 233, 157, 124, 235, 189, 206, 157, 123, 197, 209,
+ 237, 197, 101, 197, 165, 206, 251, 205, 85, 222, 56, 87, 174, 206, 151,
+ 224, 162, 93, 119, 205, 185, 130, 142, 242, 238, 17, 218, 77, 234, 124,
+ 71, 115, 146, 25, 90, 220, 40, 28, 137, 27, 21, 230, 147, 1, 125,
+ 183, 162, 27, 219, 165, 104, 195, 89, 204, 172, 189, 170, 154, 243, 158,
+ 37, 172, 117, 60, 150, 192, 113, 189, 137, 112, 251, 221, 221, 107, 135,
+ 99, 195, 153, 3, 60, 113, 242, 150, 101, 173, 33, 66, 2, 155, 122,
+ 165, 49, 183, 33, 110, 67, 134, 72, 221, 112, 130, 85, 117, 242, 113,
+ 133, 190, 169, 177, 102, 119, 3, 99, 86, 63, 22, 73, 205, 35, 133,
+ 228, 67, 190, 62, 193, 59, 31, 110, 118, 197, 248, 162, 179, 150, 63,
+ 120, 149, 60, 230, 67, 192, 59, 61, 103, 168, 152, 129, 5, 105, 187,
+ 19, 212, 210, 81, 111, 184, 198, 172, 105, 176, 93, 161, 140, 207, 81,
+ 154, 88, 17, 118, 223, 223, 158, 231, 175, 9, 182, 154, 124, 157, 88,
+ 112, 95, 110, 211, 68, 56, 227, 50, 111, 10, 74, 218, 94, 43, 250,
+ 11, 49, 75, 209, 49, 58, 21, 218, 47, 244, 246, 120, 143, 146, 5,
+ 166, 6, 17, 51, 232, 109, 252, 230, 185, 43, 94, 164, 217, 217, 134,
+ 88, 168, 11, 81, 171, 32, 76, 55, 200, 248, 135, 74, 224, 199, 179,
+ 169, 26, 7, 26, 71, 45, 246, 124, 154, 109, 205, 21, 226, 178, 92,
+ 212, 151, 18, 121, 147, 175, 195, 122, 201, 245, 118, 36, 173, 16, 141,
+ 244, 92, 134, 62, 210, 219, 8, 106, 125, 65, 163, 153, 185, 201, 148,
+ 10, 111, 131, 2, 204, 150, 200, 8, 68, 225, 0, 203, 143, 49, 180,
+ 19, 88, 84, 15, 60, 34, 250, 21, 67, 139, 98, 136, 66, 235, 190,
+ 220, 221, 90, 77, 108, 66, 35, 56, 140, 22, 12, 56, 33, 233, 149,
+ 89, 143, 127, 216, 250, 249, 74, 228, 242, 71, 52, 91, 61, 230, 103,
+ 195, 150, 121, 82, 57, 20, 222, 3, 244, 108, 46, 119, 230, 42, 11,
+ 173, 253, 4, 55, 51, 35, 6, 142, 205, 210, 175, 84, 13, 200, 23,
+ 54, 187, 20, 226, 87, 127, 54, 162, 28, 12, 74, 191, 122, 151, 177,
+ 16, 73, 221, 140, 80, 149, 87, 154, 141, 234, 221, 53, 49, 109, 219,
+ 216, 151, 142, 4, 40, 2, 134, 181, 183, 223, 55, 23, 215, 229, 166,
+ 249, 250, 143, 82, 216, 143, 20, 80, 82, 209, 119, 101, 100, 45, 32,
+ 161, 234, 119, 217, 11, 17, 94, 144, 156, 215, 165, 24, 78, 233, 173,
+ 21, 125, 140, 218, 166, 231, 225, 59, 17, 48, 111, 220, 19, 206, 33,
+ 89, 128, 104, 68, 23, 49, 218, 130, 115, 187, 116, 253, 86, 8, 62,
+ 153, 239, 133, 226, 18, 223, 119, 234, 118, 234, 218, 132, 110, 193, 77,
+ 15, 162, 232, 133, 115, 146, 2, 60, 122, 147, 159, 73, 217, 126, 68,
+ 186, 168, 130, 96, 37, 165, 210, 116, 229, 169, 168, 196, 61, 249, 124,
+ 43, 86, 149, 28, 205, 167, 49, 54, 250, 238, 144, 242, 71, 159, 56,
+ 217, 117, 142, 55, 237, 239, 31, 27, 167, 102, 124, 107, 77, 110, 138,
+ 169, 230, 124, 234, 194, 91, 167, 86, 148, 186, 196, 48, 82, 12, 205,
+ 207, 107, 174, 180, 92, 99, 159, 98, 87, 215, 222, 205, 126, 194, 255,
+ 16, 181, 40, 157, 193, 222, 195, 218, 142, 131, 204, 114, 111, 143, 78,
+ 147, 241, 179, 4, 250, 137, 56, 115, 60, 49, 153, 134, 35, 206, 51,
+ 146, 65, 59, 206, 167, 225, 239, 217, 174, 222, 143, 9, 191, 113, 23,
+ 85, 246, 196, 86, 56, 223, 222, 246, 20, 138, 222, 83, 233, 97, 201,
+ 209, 186, 138, 47, 143, 235, 67, 88, 188, 178, 203, 225, 155, 109, 41,
+ 92, 108, 18, 219, 170, 119, 91, 255, 99, 104, 251, 129, 150, 78, 111,
+ 166, 225, 198, 189, 182, 155, 219, 91, 116, 29, 174, 183, 187, 2, 28,
+ 119, 238, 149, 8, 115, 34, 238, 92, 81, 188, 132, 18, 69, 26, 22,
+ 239, 112, 215, 142, 255, 205, 187, 133, 212, 146, 121, 157, 139, 182, 42,
+ 29, 5, 26, 104, 17, 225, 194, 23, 130, 217, 203, 43, 73, 88, 9,
+ 137, 125, 48, 218, 8, 168, 238, 226, 36, 126, 102, 55, 82, 83, 235,
+ 204, 224, 120, 230, 207, 51, 179, 195, 255, 80, 234, 155, 181, 115, 169,
+ 214, 59, 197, 120, 193, 59, 72, 247, 179, 75, 221, 189, 119, 19, 57,
+ 72, 90, 11, 156, 10, 219, 143, 76, 100, 198, 179, 153, 247, 238, 87,
+ 157, 11, 123, 162, 110, 163, 99, 149, 28, 60, 242, 230, 9, 42, 151,
+ 209, 64, 216, 73, 76, 213, 210, 211, 167, 69, 41, 37, 116, 87, 202,
+ 104, 66, 22, 13, 165, 218, 122, 78, 161, 178, 197, 219, 54, 25, 88,
+ 53, 93, 209, 218, 51, 104, 146, 164, 23, 191, 242, 202, 94, 46, 207,
+ 117, 150, 54, 18, 83, 46, 195, 70, 232, 234, 19, 138, 242, 180, 22,
+ 255, 212, 162, 234, 115, 58, 216, 231, 217, 129, 108, 208, 79, 72, 219,
+ 10, 133, 63, 237, 127, 242, 154, 217, 242, 74, 8, 173, 181, 168, 190,
+ 5, 57, 212, 122, 1, 189, 169, 137, 8, 69, 57, 221, 135, 163, 36,
+ 152, 184, 103, 232, 226, 164, 167, 212, 193, 102, 211, 146, 40, 205, 142,
+ 180, 208, 122, 162, 161, 166, 49, 237, 218, 161, 247, 110, 177, 132, 178,
+ 187, 197, 5, 163, 147, 196, 158, 147, 172, 7, 235, 225, 84, 220, 12,
+ 212, 116, 111, 39, 92, 98, 70, 198, 100, 35, 194, 11, 171, 243, 187,
+ 27, 123, 158, 17, 167, 100, 76, 6, 5, 111, 138, 105, 51, 27, 238,
+ 60, 86, 181, 167, 13, 37, 65, 198, 231, 75, 44, 39, 168, 228, 114,
+ 23, 248, 12, 107, 37, 138, 187, 90, 15, 155, 182, 162, 102, 240, 30,
+ 133, 153, 169, 239, 229, 190, 209, 149, 97, 37, 109, 251, 54, 198, 127,
+ 188, 102, 125, 18, 95, 217, 83, 50, 98, 118, 190, 141, 222, 214, 81,
+ 216, 123, 189, 8, 169, 219, 166, 19, 87, 231, 186, 151, 248, 242, 80,
+ 242, 50, 191, 63, 227, 107, 250, 89, 241, 23, 40, 94, 99, 203, 148,
+ 118, 54, 28, 195, 115, 188, 242, 81, 1, 138, 129, 162, 237, 83, 130,
+ 229, 175, 149, 85, 218, 251, 58, 87, 100, 70, 9, 240, 189, 218, 82,
+ 24, 200, 199, 52, 41, 144, 102, 163, 5, 2, 142, 186, 39, 251, 47,
+ 170, 90, 63, 70, 224, 159, 144, 163, 49, 186, 231, 162, 69, 25, 50,
+ 37, 52, 42, 121, 185, 196, 111, 185, 111, 104, 15, 177, 40, 134, 249,
+ 18, 20, 177, 89, 180, 148, 113, 165, 66, 147, 1, 226, 153, 43, 148,
+ 40, 239, 200, 226, 9, 29, 41, 224, 22, 109, 156, 144, 8, 78, 239,
+ 79, 249, 20, 120, 125, 56, 178, 160, 222, 241, 80, 148, 98, 50, 131,
+ 222, 239, 114, 71, 57, 181, 201, 161, 247, 122, 112, 47, 244, 34, 163,
+ 181, 121, 86, 54, 24, 105, 48, 229, 252, 62, 110, 15, 229, 135, 57,
+ 11, 233, 193, 227, 73, 228, 200, 209, 194, 142, 200, 186, 54, 119, 36,
+ 42, 207, 243, 142, 185, 150, 177, 6, 92, 146, 46, 168, 232, 226, 36,
+ 204, 153, 124, 236, 9, 164, 35, 146, 60, 220, 33, 90, 88, 197, 244,
+ 202, 229, 210, 5, 87, 82, 100, 47, 182, 111, 98, 217, 162, 111, 11,
+ 164, 149, 16, 23, 84, 106, 25, 36, 228, 91, 223, 167, 190, 207, 167,
+ 125, 207, 53, 247, 6, 95, 4, 73, 81, 77, 219, 205, 55, 142, 74,
+ 182, 182, 119, 146, 240, 63, 177, 225, 52, 20, 189, 47, 228, 102, 21,
+ 223, 144, 182, 122, 186, 100, 216, 109, 177, 168, 114, 173, 61, 213, 215,
+ 44, 142, 205, 75, 24, 225, 50, 241, 205, 157, 130, 124, 68, 196, 128,
+ 249, 168, 163, 107, 39, 58, 230, 36, 47, 121, 31, 148, 6, 170, 86,
+ 154, 152, 48, 74, 118, 116, 197, 37, 240, 54, 62, 228, 176, 84, 99,
+ 106, 128, 18, 184, 13, 253, 234, 60, 180, 134, 21, 75, 195, 98, 52,
+ 149, 110, 210, 233, 110, 54, 81, 123, 98, 10, 124, 225, 165, 116, 47,
+ 115, 160, 147, 42, 8, 12, 137, 167, 185, 192, 115, 232, 229, 89, 202,
+ 210, 144, 142, 143, 206, 129, 36, 211, 127, 82, 148, 21, 70, 84, 202,
+ 119, 87, 139, 157, 61, 146, 5, 175, 252, 129, 240, 65, 205, 193, 163,
+ 246, 246, 97, 157, 162, 26, 135, 0, 254, 25, 136, 174, 143, 162, 35,
+ 54, 32, 113, 8, 123, 51, 128, 63, 168, 83, 74, 253, 118, 219, 99,
+ 129, 103, 186, 88, 217, 159, 175, 48, 202, 122, 112, 163, 181, 190, 136,
+ 61, 133, 148, 37, 77, 50, 46, 243, 73, 102, 16, 102, 235, 58, 35,
+ 116, 142, 106, 44, 121, 191, 45, 165, 128, 20, 23, 244, 26, 170, 95,
+ 173, 147, 134, 235, 102, 142, 127, 243, 214, 59, 231, 166, 234, 61, 83,
+ 64, 167, 80, 12, 161, 211, 207, 25, 50, 51, 187, 36, 119, 246, 61,
+ 224, 187, 146, 152, 75, 171, 218, 213, 104, 174, 78, 201, 134, 43, 203,
+ 167, 179, 180, 187, 48, 20, 99, 170, 160, 233, 167, 215, 209, 111, 216,
+ 236, 67, 220, 182, 210, 18, 163, 55, 201, 103, 39, 95, 58, 68, 50,
+ 192, 66, 167, 124, 49, 42, 90, 86, 121, 214, 156, 101, 101, 66, 251,
+ 13, 131, 105, 83, 38, 62, 165, 199, 240, 248, 66, 111, 95, 181, 84,
+ 46, 18, 106, 97, 61, 27, 182, 239, 210, 85, 15, 199, 158, 39, 5,
+ 250, 57, 157, 41, 28, 172, 180, 95, 21, 214, 226, 98, 59, 15, 28,
+ 123, 158, 9, 172, 139, 220, 227, 214, 71, 124, 94, 200, 160, 239, 218,
+ 117, 167, 150, 67, 251, 194, 158, 154, 88, 23, 67, 5, 109, 32, 91,
+ 119, 116, 1, 22, 77, 224, 253, 220, 52, 242, 133, 162, 52, 231, 210,
+ 36, 111, 117, 19, 141, 167, 151, 136, 194, 174, 119, 12, 198, 38, 29,
+ 75, 159, 136, 237, 12, 237, 82, 102, 186, 198, 52, 205, 222, 47, 247,
+ 154, 84, 73, 204, 185, 89, 175, 238, 232, 192, 202, 29, 255, 181, 198,
+ 90, 121, 244, 85, 112, 182, 84, 214, 19, 207, 135, 82, 168, 8, 202,
+ 172, 234, 11, 58, 236, 53, 218, 36, 56, 183, 220, 52, 248, 143, 34,
+ 194, 228, 244, 165, 3, 58, 185, 197, 101, 6, 230, 173, 94, 178, 5,
+ 54, 124, 66, 197, 170, 48, 94, 182, 46, 90, 248, 80, 115, 173, 84,
+ 51, 212, 155, 196, 138, 76, 147, 86, 157, 16, 147, 32, 154, 229, 128,
+ 179, 165, 59, 43, 226, 116, 168, 111, 237, 99, 222, 2, 225, 198, 59,
+ 89, 175, 39, 13, 15, 189, 44, 198, 89, 199, 43, 240, 165, 113, 154,
+ 199, 35, 138, 39, 83, 171, 61, 207, 105, 83, 169, 62, 26, 79, 240,
+ 10, 250, 64, 161, 115, 238, 21, 57, 6, 166, 3, 125, 93, 91, 212,
+ 162, 30, 90, 183, 68, 182, 149, 21, 70, 73, 125, 155, 123, 192, 12,
+ 127, 51, 223, 124, 181, 142, 3, 131, 87, 97, 254, 189, 99, 217, 209,
+ 69, 233, 161, 14, 90, 236, 193, 186, 89, 101, 180, 225, 110, 54, 212,
+ 103, 163, 247, 153, 181, 10, 107, 108, 41, 48, 204, 27, 141, 80, 25,
+ 148, 30, 143, 105, 106, 245, 123, 163, 5, 245, 47, 231, 212, 155, 243,
+ 173, 106, 108, 107, 223, 136, 165, 13, 45, 226, 234, 157, 229, 99, 176,
+ 178, 220, 153, 77, 179, 237, 224, 146, 242, 151, 48, 103, 14, 79, 58,
+ 166, 99, 140, 55, 105, 102, 62, 169, 196, 209, 202, 228, 243, 78, 174,
+ 43, 22, 64, 13, 22, 12, 232, 145, 201, 63, 48, 225, 43, 142, 41,
+ 64, 20, 140, 41, 207, 214, 113, 178, 124, 200, 210, 153, 86, 145, 209,
+ 209, 224, 197, 86, 197, 135, 18, 77, 48, 81, 140, 129, 237, 157, 98,
+ 63, 72, 93, 138, 171, 86, 22, 182, 234, 3, 201, 140, 28, 15, 13,
+ 74, 53, 17, 133, 220, 188, 94, 63, 251, 134, 73, 185, 252, 42, 113,
+ 82, 154, 182, 169, 44, 77, 1, 181, 63, 159, 110, 67, 19, 183, 175,
+ 135, 242, 163, 128, 50, 182, 42, 173, 60, 220, 121, 42, 121, 156, 15,
+ 146, 60, 82, 104, 91, 68, 227, 47, 71, 39, 207, 21, 154, 72, 107,
+ 162, 183, 18, 160, 60, 9, 173, 242, 170, 66, 195, 121, 26, 219, 36,
+ 164, 87, 167, 34, 208, 148, 188, 101, 113, 175, 157, 133, 203, 40, 80,
+ 70, 50, 36, 64, 34, 225, 100, 234, 193, 12, 164, 93, 218, 166, 27,
+ 28, 34, 4, 241, 180, 208, 216, 6, 25, 105, 107, 190, 130, 82, 8,
+ 139, 76, 34, 51, 201, 238, 219, 44, 247, 112, 13, 141, 213, 71, 110,
+ 161, 33, 93, 16, 242, 101, 173, 223, 97, 183, 189, 82, 63, 200, 194,
+ 84, 17, 217, 59, 136, 108, 161, 28, 165, 240, 58, 229, 189, 174, 76,
+ 63, 102, 199, 167, 241, 225, 151, 186, 221, 44, 26, 44, 106, 218, 247,
+ 77, 223, 214, 220, 201, 26, 151, 188, 103, 107, 8, 229, 181, 145, 208,
+ 235, 215, 201, 25, 208, 196, 132, 31, 29, 164, 9, 140, 72, 115, 218,
+ 175, 176, 154, 16, 15, 116, 10, 92, 145, 21, 115, 91, 59, 97, 199,
+ 60, 188, 80, 125, 43, 195, 24, 211, 81, 23, 185, 81, 73, 66, 248,
+ 158, 14, 59, 21, 58, 127, 126, 155, 28, 123, 48, 138, 28, 237, 91,
+ 39, 214, 75, 187, 75, 36, 235, 90, 132, 65, 109, 137, 249, 15, 227,
+ 158, 120, 8, 107, 208, 173, 204, 15, 96, 177, 179, 141, 122, 51, 94,
+ 231, 249, 54, 19, 218, 164, 220, 238, 23, 20, 163, 190, 110, 165, 219,
+ 145, 21, 132, 137, 206, 230, 94, 77, 157, 197, 38, 223, 194, 216, 27,
+ 165, 157, 181, 150, 127, 31, 149, 78, 145, 242, 17, 250, 178, 184, 245,
+ 253, 68, 148, 123, 102, 110, 200, 177, 40, 152, 245, 250, 70, 220, 171,
+ 11, 219, 219, 239, 18, 24, 171, 171, 60, 26, 130, 66, 217, 242, 217,
+ 59, 61, 86, 138, 248, 212, 63, 175, 222, 215, 12, 197, 49, 119, 213,
+ 58, 226, 23, 109, 221, 199, 174, 197, 217, 174, 105, 179, 100, 29, 239,
+ 213, 194, 138, 84, 131, 94, 83, 63, 118, 90, 232, 144, 48, 245, 123,
+ 234, 82, 148, 182, 174, 248, 40, 135, 35, 211, 64, 223, 152, 152, 244,
+ 190, 227, 139, 183, 46, 74, 196, 172, 235, 196, 214, 142, 241, 77, 3,
+ 41, 141, 121, 167, 208, 199, 150, 155, 79, 43, 115, 180, 27, 144, 176,
+ 63, 103, 150, 75, 111, 23, 149, 193, 42, 190, 58, 223, 240, 45, 83,
+ 77, 171, 41, 196, 194, 120, 151, 96, 183, 187, 59, 220, 61, 36, 217,
+ 196, 35, 57, 49, 186, 1, 200, 184, 146, 82, 71, 206, 135, 53, 218,
+ 122, 230, 235, 171, 76, 227, 114, 124, 35, 152, 98, 151, 250, 102, 124,
+ 206, 111, 164, 39, 223, 118, 179, 25, 29, 252, 50, 210, 51, 18, 170,
+ 214, 214, 42, 191, 156, 247, 153, 187, 101, 228, 128, 145, 95, 204, 194,
+ 207, 176, 128, 238, 70, 163, 231, 104, 5, 251, 139, 161, 30, 71, 199,
+ 26, 15, 238, 210, 119, 60, 24, 244, 86, 208, 87, 155, 165, 97, 214,
+ 160, 26, 234, 244, 5, 76, 45, 99, 162, 120, 138, 251, 214, 233, 253,
+ 25, 215, 10, 145, 178, 234, 50, 210, 185, 175, 69, 135, 74, 132, 80,
+ 233, 142, 173, 79, 245, 77, 102, 21, 51, 145, 32, 94, 123, 250, 66,
+ 131, 122, 187, 71, 173, 175, 58, 11, 235, 70, 147, 122, 158, 85, 188,
+ 63, 207, 74, 102, 182, 152, 38, 255, 195, 113, 2, 109, 102, 219, 59,
+ 36, 229, 239, 159, 4, 68, 115, 109, 125, 114, 188, 99, 195, 181, 83,
+ 224, 193, 247, 88, 10, 5, 187, 206, 240, 173, 250, 76, 199, 226, 13,
+ 149, 236, 108, 43, 84, 151, 252, 214, 9, 127, 65, 237, 183, 60, 221,
+ 3, 137, 23, 47, 182, 148, 91, 37, 132, 61, 10, 30, 69, 116, 165,
+ 247, 54, 187, 171, 174, 48, 38, 168, 157, 91, 53, 140, 141, 37, 169,
+ 63, 129, 89, 16, 106, 115, 120, 128, 149, 111, 95, 211, 112, 68, 156,
+ 169, 189, 80, 104, 212, 45, 16, 209, 104, 249, 124, 80, 124, 239, 11,
+ 175, 209, 88, 145, 127, 61, 164, 23, 129, 200, 252, 126, 201, 228, 20,
+ 66, 13, 62, 29, 30, 90, 83, 123, 167, 238, 56, 139, 31, 153, 118,
+ 125, 145, 82, 67, 103, 16, 149, 248, 99, 147, 111, 197, 73, 183, 82,
+ 193, 61, 43, 173, 123, 177, 87, 42, 80, 167, 208, 4, 8, 36, 24,
+ 60, 28, 135, 90, 44, 44, 172, 181, 145, 231, 40, 221, 231, 102, 69,
+ 199, 176, 239, 14, 47, 53, 100, 159, 123, 199, 210, 238, 230, 175, 202,
+ 123, 162, 52, 85, 115, 191, 99, 231, 206, 68, 110, 167, 43, 178, 151,
+ 196, 114, 126, 254, 201, 155, 240, 185, 4, 71, 63, 250, 53, 209, 107,
+ 137, 155, 18, 3, 62, 111, 180, 16, 103, 5, 76, 18, 118, 174, 63,
+ 175, 117, 187, 230, 161, 64, 156, 99, 255, 14, 233, 206, 226, 129, 209,
+ 246, 190, 255, 76, 82, 91, 212, 123, 163, 150, 59, 138, 219, 219, 205,
+ 155, 232, 199, 85, 123, 201, 41, 227, 155, 175, 62, 189, 38, 153, 64,
+ 154, 91, 27, 208, 233, 119, 170, 101, 245, 205, 33, 35, 134, 228, 142,
+ 223, 9, 175, 88, 93, 165, 231, 159, 148, 52, 170, 165, 121, 125, 178,
+ 30, 111, 23, 60, 144, 117, 29, 219, 141, 185, 222, 139, 97, 149, 165,
+ 131, 83, 233, 35, 126, 45, 225, 121, 86, 212, 54, 177, 139, 35, 62,
+ 151, 213, 98, 123, 11, 30, 199, 155, 48, 189, 199, 78, 9, 198, 77,
+ 98, 47, 207, 116, 33, 217, 67, 167, 178, 194, 150, 243, 111, 239, 154,
+ 155, 255, 246, 225, 233, 135, 134, 172, 226, 16, 181, 152, 150, 39, 14,
+ 109, 46, 183, 93, 22, 38, 116, 245, 253, 25, 248, 55, 73, 189, 77,
+ 173, 6, 18, 242, 252, 181, 6, 198, 242, 34, 252, 44, 164, 137, 138,
+ 247, 179, 124, 106, 178, 232, 197, 66, 98, 104, 194, 219, 88, 152, 219,
+ 40, 167, 105, 38, 220, 135, 89, 180, 45, 219, 103, 106, 131, 5, 48,
+ 61, 30, 119, 62, 46, 49, 24, 215, 204, 233, 204, 162, 172, 55, 60,
+ 210, 154, 101, 16, 136, 187, 118, 61, 185, 225, 19, 186, 159, 164, 189,
+ 210, 78, 183, 98, 94, 92, 249, 34, 9, 93, 169, 67, 6, 122, 97,
+ 172, 227, 19, 158, 114, 206, 76, 151, 151, 119, 237, 140, 52, 40, 21,
+ 252, 66, 194, 90, 231, 190, 192, 136, 77, 163, 155, 33, 4, 95, 212,
+ 82, 56, 148, 251, 250, 176, 23, 125, 84, 249, 35, 135, 137, 158, 214,
+ 167, 176, 58, 131, 38, 225, 252, 252, 43, 172, 97, 149, 151, 206, 51,
+ 49, 81, 51, 140, 4, 133, 221, 245, 172, 17, 49, 20, 78, 142, 236,
+ 110, 24, 101, 125, 249, 149, 224, 157, 124, 234, 40, 171, 153, 14, 167,
+ 222, 107, 138, 43, 155, 42, 2, 138, 53, 149, 230, 217, 154, 68, 108,
+ 86, 46, 166, 35, 3, 169, 73, 61, 39, 38, 90, 62, 31, 51, 243,
+ 26, 30, 158, 220, 108, 46, 85, 19, 10, 140, 126, 240, 13, 79, 93,
+ 184, 56, 237, 209, 163, 143, 82, 250, 47, 91, 115, 164, 166, 195, 222,
+ 250, 112, 187, 88, 58, 126, 27, 122, 221, 109, 136, 113, 205, 155, 228,
+ 146, 104, 247, 220, 43, 225, 186, 88, 246, 148, 151, 184, 16, 123, 112,
+ 216, 51, 159, 228, 227, 247, 171, 131, 250, 67, 163, 220, 251, 10, 131,
+ 216, 232, 171, 183, 155, 138, 125, 46, 83, 169, 62, 100, 136, 98, 43,
+ 109, 127, 77, 20, 126, 245, 196, 196, 227, 20, 10, 184, 38, 91, 248,
+ 176, 245, 235, 45, 241, 20, 202, 235, 94, 201, 241, 241, 251, 195, 82,
+ 82, 142, 55, 87, 38, 239, 18, 51, 20, 46, 4, 229, 40, 58, 30,
+ 14, 223, 98, 204, 201, 98, 11, 176, 22, 38, 158, 188, 131, 58, 80,
+ 109, 211, 155, 135, 16, 157, 193, 60, 103, 127, 249, 133, 160, 70, 223,
+ 202, 163, 81, 86, 230, 103, 106, 159, 215, 247, 69, 116, 46, 223, 204,
+ 109, 226, 36, 189, 41, 100, 123, 237, 164, 179, 132, 144, 69, 223, 151,
+ 232, 203, 48, 46, 214, 1, 197, 41, 148, 126, 88, 102, 153, 140, 140,
+ 231, 223, 76, 139, 235, 65, 217, 161, 67, 20, 253, 177, 191, 205, 52,
+ 81, 70, 3, 175, 53, 107, 136, 11, 65, 158, 86, 48, 244, 157, 42,
+ 222, 98, 79, 206, 171, 14, 114, 86, 35, 195, 98, 212, 43, 114, 209,
+ 175, 196, 21, 158, 223, 115, 38, 230, 77, 201, 37, 77, 185, 151, 194,
+ 58, 100, 200, 77, 211, 164, 172, 193, 17, 194, 106, 114, 67, 39, 250,
+ 68, 85, 20, 67, 150, 202, 58, 166, 43, 107, 239, 154, 131, 187, 117,
+ 182, 215, 170, 42, 181, 103, 57, 139, 152, 152, 112, 110, 192, 124, 26,
+ 245, 107, 98, 55, 20, 105, 94, 91, 154, 254, 119, 108, 149, 158, 37,
+ 168, 175, 10, 50, 218, 211, 217, 35, 154, 91, 66, 238, 190, 230, 76,
+ 167, 226, 120, 85, 238, 44, 83, 114, 223, 178, 110, 119, 72, 48, 97,
+ 126, 49, 171, 113, 48, 179, 41, 209, 222, 212, 178, 78, 61, 175, 57,
+ 210, 129, 53, 238, 98, 178, 122, 134, 136, 213, 13, 95, 65, 29, 110,
+ 185, 50, 8, 10, 232, 53, 209, 242, 40, 65, 107, 186, 175, 24, 250,
+ 144, 223, 233, 170, 35, 193, 210, 142, 250, 88, 22, 27, 82, 60, 157,
+ 180, 241, 140, 115, 118, 116, 225, 23, 132, 83, 200, 115, 37, 22, 77,
+ 86, 37, 195, 154, 175, 78, 31, 242, 15, 123, 231, 106, 180, 28, 38,
+ 234, 59, 118, 89, 210, 152, 224, 75, 145, 12, 27, 26, 63, 155, 176,
+ 203, 149, 56, 93, 255, 161, 181, 83, 136, 64, 189, 25, 207, 84, 68,
+ 255, 62, 255, 41, 116, 251, 42, 217, 144, 146, 135, 65, 100, 65, 219,
+ 164, 190, 139, 170, 178, 202, 106, 117, 170, 63, 25, 241, 203, 15, 10,
+ 215, 9, 58, 6, 117, 60, 189, 170, 104, 92, 60, 136, 23, 165, 212,
+ 23, 243, 103, 197, 161, 237, 26, 239, 41, 156, 12, 137, 211, 30, 183,
+ 147, 43, 165, 105, 88, 248, 251, 190, 170, 31, 234, 149, 207, 237, 90,
+ 153, 198, 147, 156, 191, 77, 134, 79, 211, 132, 254, 241, 129, 135, 203,
+ 162, 90, 239, 186, 186, 236, 62, 91, 235, 142, 17, 11, 154, 138, 225,
+ 228, 157, 46, 79, 137, 126, 61, 235, 160, 168, 80, 35, 45, 122, 195,
+ 90, 117, 106, 221, 146, 219, 147, 239, 61, 84, 155, 72, 163, 186, 230,
+ 144, 198, 243, 217, 15, 90, 204, 239, 101, 189, 72, 55, 66, 151, 151,
+ 106, 70, 160, 153, 29, 206, 226, 167, 228, 210, 75, 189, 18, 131, 228,
+ 34, 220, 182, 177, 250, 204, 49, 195, 191, 50, 236, 93, 238, 178, 207,
+ 84, 47, 141, 160, 88, 242, 251, 137, 88, 68, 196, 132, 147, 46, 207,
+ 238, 190, 81, 242, 146, 203, 200, 77, 120, 197, 157, 99, 29, 199, 138,
+ 37, 174, 235, 108, 133, 68, 40, 173, 167, 208, 240, 41, 52, 103, 67,
+ 180, 61, 189, 47, 66, 143, 126, 179, 142, 136, 222, 208, 211, 199, 237,
+ 218, 61, 204, 118, 158, 64, 35, 132, 56, 66, 193, 175, 223, 202, 138,
+ 114, 42, 199, 102, 80, 57, 208, 67, 168, 216, 240, 79, 76, 239, 118,
+ 170, 125, 93, 193, 115, 48, 145, 75, 219, 247, 195, 204, 43, 12, 209,
+ 96, 238, 88, 190, 171, 158, 105, 118, 10, 241, 174, 21, 104, 16, 170,
+ 11, 197, 80, 95, 127, 146, 207, 201, 179, 20, 134, 105, 227, 248, 158,
+ 224, 125, 104, 168, 189, 214, 10, 54, 115, 182, 6, 239, 128, 165, 218,
+ 114, 29, 97, 120, 83, 189, 161, 71, 182, 23, 106, 126, 96, 123, 167,
+ 108, 59, 196, 81, 56, 255, 117, 84, 235, 107, 89, 18, 49, 191, 150,
+ 62, 59, 110, 0, 29, 132, 248, 46, 183, 195, 251, 194, 18, 211, 35,
+ 43, 70, 87, 58, 199, 192, 40, 46, 201, 113, 164, 116, 124, 132, 40,
+ 84, 193, 248, 248, 135, 226, 172, 153, 175, 207, 149, 65, 92, 133, 24,
+ 148, 87, 93, 150, 230, 175, 228, 233, 112, 65, 31, 203, 137, 197, 180,
+ 49, 31, 233, 144, 92, 144, 190, 72, 250, 84, 212, 123, 146, 115, 66,
+ 85, 147, 255, 72, 224, 118, 227, 179, 46, 97, 225, 128, 34, 57, 204,
+ 171, 136, 242, 177, 104, 131, 123, 206, 88, 35, 185, 55, 18, 4, 179,
+ 81, 88, 139, 229, 69, 223, 58, 99, 185, 225, 95, 112, 100, 180, 226,
+ 140, 192, 72, 86, 241, 33, 146, 51, 84, 184, 248, 234, 234, 144, 71,
+ 248, 126, 253, 81, 153, 198, 124, 175, 237, 122, 206, 53, 118, 207, 4,
+ 217, 201, 148, 231, 174, 243, 45, 52, 76, 213, 21, 237, 179, 100, 87,
+ 142, 82, 80, 75, 229, 94, 40, 47, 244, 87, 157, 48, 61, 194, 33,
+ 65, 24, 187, 245, 164, 88, 179, 47, 231, 106, 164, 228, 81, 89, 50,
+ 83, 188, 42, 223, 108, 23, 79, 138, 137, 31, 3, 29, 59, 233, 144,
+ 68, 220, 187, 172, 221, 243, 158, 239, 13, 52, 241, 181, 84, 63, 135,
+ 166, 74, 123, 22, 22, 58, 171, 153, 222, 153, 122, 43, 169, 42, 152,
+ 216, 217, 54, 215, 213, 53, 63, 223, 195, 234, 197, 106, 50, 100, 92,
+ 148, 35, 93, 234, 129, 142, 137, 183, 208, 75, 153, 119, 244, 118, 105,
+ 76, 236, 209, 165, 88, 42, 219, 151, 146, 34, 232, 162, 181, 211, 141,
+ 138, 119, 134, 132, 42, 179, 232, 162, 155, 19, 207, 213, 233, 214, 47,
+ 40, 162, 61, 205, 233, 29, 189, 86, 42, 118, 173, 125, 216, 50, 171,
+ 83, 137, 132, 51, 240, 206, 84, 13, 154, 163, 113, 153, 186, 183, 74,
+ 105, 145, 95, 19, 47, 225, 251, 27, 158, 185, 76, 57, 55, 213, 165,
+ 234, 102, 138, 16, 212, 95, 84, 125, 222, 62, 164, 208, 200, 61, 167,
+ 233, 45, 43, 67, 172, 33, 80, 212, 84, 127, 194, 119, 77, 89, 123,
+ 191, 164, 214, 138, 143, 101, 228, 51, 153, 138, 183, 126, 42, 229, 170,
+ 249, 183, 4, 85, 92, 51, 61, 36, 226, 114, 235, 227, 202, 54, 44,
+ 114, 178, 119, 23, 132, 31, 68, 11, 17, 122, 196, 168, 190, 170, 247,
+ 15, 52, 189, 197, 26, 63, 166, 209, 80, 158, 79, 67, 127, 10, 17,
+ 93, 83, 79, 81, 229, 46, 120, 112, 205, 224, 218, 75, 105, 126, 6,
+ 147, 112, 246, 5, 181, 190, 21, 237, 129, 188, 140, 72, 77, 62, 236,
+ 168, 214, 215, 91, 88, 59, 70, 39, 67, 254, 187, 85, 106, 19, 163,
+ 58, 99, 217, 225, 252, 35, 164, 115, 149, 162, 230, 118, 60, 31, 179,
+ 249, 158, 84, 40, 222, 108, 43, 12, 201, 136, 126, 169, 144, 175, 231,
+ 190, 125, 20, 154, 40, 97, 111, 201, 55, 52, 217, 128, 197, 186, 54,
+ 78, 110, 251, 208, 144, 50, 248, 72, 53, 162, 99, 161, 103, 32, 77,
+ 222, 70, 141, 56, 151, 133, 140, 152, 0, 225, 136, 45, 159, 173, 246,
+ 88, 76, 21, 51, 171, 111, 30, 71, 190, 45, 181, 220, 214, 152, 50,
+ 206, 46, 202, 102, 60, 155, 234, 110, 209, 90, 148, 141, 47, 215, 117,
+ 73, 25, 11, 13, 2, 230, 36, 229, 169, 22, 233, 55, 175, 210, 228,
+ 49, 155, 83, 62, 52, 188, 186, 82, 193, 156, 144, 165, 172, 81, 84,
+ 115, 121, 188, 243, 19, 251, 62, 41, 147, 34, 90, 38, 243, 203, 7,
+ 46, 150, 44, 147, 117, 62, 15, 229, 167, 231, 44, 74, 242, 3, 188,
+ 55, 54, 183, 187, 109, 137, 205, 59, 178, 159, 217, 87, 19, 197, 161,
+ 222, 192, 46, 145, 126, 29, 212, 105, 248, 74, 242, 144, 140, 198, 142,
+ 101, 101, 230, 162, 101, 195, 156, 38, 86, 135, 184, 250, 56, 7, 57,
+ 173, 0, 187, 147, 129, 43, 67, 14, 98, 10, 198, 220, 80, 64, 122,
+ 186, 226, 68, 41, 170, 67, 181, 232, 67, 22, 104, 130, 224, 155, 43,
+ 187, 197, 209, 13, 97, 143, 71, 81, 8, 177, 87, 16, 13, 41, 214,
+ 118, 203, 162, 214, 91, 37, 43, 146, 67, 7, 234, 20, 93, 144, 154,
+ 177, 56, 89, 7, 166, 110, 160, 157, 246, 62, 91, 194, 125, 223, 151,
+ 89, 35, 199, 209, 216, 169, 252, 205, 165, 250, 64, 142, 115, 28, 187,
+ 55, 234, 9, 73, 121, 35, 19, 115, 199, 158, 115, 197, 43, 54, 87,
+ 85, 218, 81, 83, 123, 1, 86, 202, 28, 10, 157, 154, 34, 3, 133,
+ 224, 102, 254, 9, 251, 164, 111, 75, 89, 130, 236, 183, 76, 67, 159,
+ 133, 220, 93, 223, 78, 50, 157, 148, 231, 153, 199, 240, 235, 14, 9,
+ 17, 227, 66, 203, 214, 94, 120, 170, 16, 95, 25, 61, 113, 53, 41,
+ 34, 91, 107, 111, 234, 33, 250, 4, 233, 18, 37, 197, 116, 74, 103,
+ 37, 65, 223, 219, 56, 254, 27, 47, 220, 103, 153, 55, 79, 161, 9,
+ 61, 86, 61, 222, 97, 125, 89, 232, 107, 59, 179, 60, 173, 93, 152,
+ 191, 231, 222, 80, 173, 229, 160, 118, 243, 155, 160, 143, 6, 201, 132,
+ 252, 29, 27, 28, 143, 15, 130, 12, 217, 155, 209, 120, 66, 125, 177,
+ 10, 91, 250, 215, 123, 140, 221, 144, 179, 251, 66, 241, 154, 87, 12,
+ 66, 38, 184, 69, 179, 166, 212, 7, 89, 161, 35, 155, 78, 204, 79,
+ 87, 227, 45, 226, 155, 14, 93, 251, 101, 203, 205, 154, 199, 81, 173,
+ 12, 183, 36, 233, 25, 169, 68, 11, 247, 179, 83, 88, 125, 21, 42,
+ 87, 200, 222, 49, 155, 222, 149, 27, 207, 117, 198, 115, 93, 73, 103,
+ 224, 97, 120, 76, 28, 12, 37, 143, 175, 217, 134, 89, 176, 75, 77,
+ 16, 171, 4, 163, 183, 197, 61, 42, 248, 58, 183, 60, 164, 97, 57,
+ 207, 195, 241, 117, 61, 165, 131, 170, 61, 169, 224, 46, 39, 71, 89,
+ 181, 1, 218, 147, 173, 10, 52, 155, 224, 112, 33, 243, 192, 168, 243,
+ 105, 21, 87, 241, 69, 241, 50, 93, 216, 209, 229, 102, 47, 232, 236,
+ 222, 115, 49, 161, 176, 118, 157, 77, 253, 146, 252, 218, 220, 181, 77,
+ 69, 218, 40, 138, 96, 151, 168, 101, 207, 25, 161, 236, 99, 48, 243,
+ 146, 3, 15, 170, 226, 50, 245, 26, 187, 75, 165, 122, 29, 126, 106,
+ 163, 252, 71, 234, 160, 237, 149, 225, 88, 108, 4, 63, 17, 2, 49,
+ 134, 253, 97, 27, 230, 201, 17, 85, 129, 214, 208, 79, 161, 182, 1,
+ 213, 108, 50, 46, 56, 231, 8, 108, 172, 151, 178, 141, 40, 177, 115,
+ 162, 88, 35, 23, 114, 187, 191, 241, 226, 237, 243, 14, 12, 22, 115,
+ 19, 147, 24, 231, 36, 167, 110, 177, 71, 173, 12, 246, 156, 111, 83,
+ 200, 40, 188, 157, 0, 51, 16, 45, 205, 40, 225, 46, 149, 146, 90,
+ 101, 11, 23, 171, 59, 237, 151, 219, 225, 223, 90, 158, 110, 83, 210,
+ 11, 79, 174, 126, 107, 53, 37, 25, 72, 150, 225, 214, 203, 146, 136,
+ 123, 53, 37, 18, 25, 158, 38, 73, 38, 197, 226, 234, 25, 241, 200,
+ 225, 72, 233, 249, 78, 253, 88, 54, 113, 130, 28, 46, 98, 155, 158,
+ 175, 197, 92, 138, 217, 68, 134, 105, 199, 156, 118, 242, 156, 90, 82,
+ 236, 117, 194, 23, 105, 135, 99, 8, 123, 116, 89, 149, 31, 39, 181,
+ 135, 111, 66, 180, 175, 57, 21, 135, 174, 123, 219, 165, 223, 232, 243,
+ 175, 155, 199, 229, 151, 109, 38, 46, 163, 245, 201, 166, 246, 98, 157,
+ 204, 36, 25, 117, 49, 167, 113, 193, 245, 141, 138, 98, 142, 254, 82,
+ 206, 113, 185, 59, 131, 106, 235, 146, 231, 70, 218, 96, 31, 202, 103,
+ 1, 50, 68, 113, 180, 100, 225, 181, 15, 29, 41, 220, 143, 70, 57,
+ 49, 89, 88, 48, 115, 141, 253, 194, 162, 250, 230, 122, 54, 171, 40,
+ 124, 90, 24, 89, 50, 237, 71, 10, 244, 42, 173, 71, 79, 212, 118,
+ 215, 94, 239, 105, 112, 144, 96, 169, 226, 47, 50, 109, 106, 52, 99,
+ 30, 249, 172, 112, 20, 219, 85, 98, 77, 241, 92, 233, 34, 225, 28,
+ 163, 15, 42, 125, 91, 133, 131, 59, 93, 241, 106, 125, 148, 104, 150,
+ 141, 68, 220, 242, 201, 186, 52, 94, 148, 77, 254, 186, 229, 128, 216,
+ 149, 175, 170, 132, 157, 184, 38, 50, 235, 242, 171, 215, 61, 75, 112,
+ 39, 52, 149, 219, 110, 60, 126, 106, 73, 29, 109, 12, 189, 189, 19,
+ 211, 146, 45, 195, 91, 45, 100, 25, 156, 89, 110, 207, 28, 157, 190,
+ 252, 190, 166, 108, 137, 162, 116, 112, 9, 59, 235, 115, 250, 22, 109,
+ 179, 100, 184, 218, 225, 129, 246, 138, 244, 235, 98, 254, 121, 131, 209,
+ 33, 166, 152, 142, 176, 231, 66, 171, 59, 43, 173, 131, 148, 15, 163,
+ 89, 237, 51, 77, 12, 37, 111, 159, 66, 3, 135, 30, 59, 6, 146,
+ 247, 237, 158, 222, 123, 170, 144, 56, 65, 230, 121, 172, 119, 71, 15,
+ 229, 158, 122, 177, 137, 137, 190, 101, 108, 26, 19, 142, 126, 139, 234,
+ 78, 222, 139, 226, 114, 138, 39, 183, 30, 83, 14, 83, 5, 31, 196,
+ 111, 113, 248, 141, 23, 229, 208, 9, 205, 246, 222, 101, 107, 247, 90,
+ 227, 147, 84, 91, 155, 145, 145, 147, 151, 31, 145, 253, 186, 125, 77,
+ 237, 50, 203, 72, 125, 107, 177, 29, 143, 91, 243, 251, 164, 59, 125,
+ 67, 16, 177, 248, 245, 61, 134, 53, 90, 15, 159, 175, 61, 195, 12,
+ 170, 40, 154, 134, 250, 248, 23, 240, 82, 191, 124, 26, 24, 126, 244,
+ 88, 170, 149, 176, 79, 35, 92, 200, 147, 23, 177, 48, 219, 107, 34,
+ 24, 147, 219, 93, 100, 3, 59, 55, 237, 112, 101, 62, 34, 129, 250,
+ 60, 163, 72, 20, 77, 92, 220, 241, 164, 176, 101, 99, 113, 38, 13,
+ 165, 146, 212, 253, 226, 126, 195, 227, 83, 136, 223, 119, 166, 244, 190,
+ 131, 214, 34, 253, 83, 95, 100, 150, 209, 198, 107, 62, 167, 125, 59,
+ 98, 73, 28, 235, 100, 6, 61, 77, 132, 2, 118, 26, 235, 203, 239,
+ 22, 43, 179, 75, 110, 236, 146, 87, 115, 189, 122, 213, 116, 213, 167,
+ 255, 142, 206, 65, 196, 14, 147, 222, 192, 90, 133, 214, 41, 84, 229,
+ 124, 238, 248, 238, 65, 252, 240, 69, 10, 124, 239, 196, 150, 187, 43,
+ 136, 147, 74, 220, 226, 104, 142, 232, 7, 86, 93, 174, 73, 249, 171,
+ 62, 131, 62, 89, 229, 70, 7, 102, 151, 47, 178, 105, 62, 87, 189,
+ 200, 253, 172, 124, 119, 149, 116, 114, 202, 85, 172, 127, 168, 211, 91,
+ 155, 242, 117, 38, 15, 207, 237, 199, 230, 111, 197, 139, 15, 52, 238,
+ 83, 245, 22, 126, 59, 234, 160, 214, 218, 60, 204, 205, 87, 125, 200,
+ 158, 33, 73, 136, 182, 22, 48, 151, 159, 232, 29, 113, 80, 177, 94,
+ 237, 121, 239, 81, 29, 238, 219, 88, 206, 33, 239, 170, 221, 83, 40,
+ 205, 45, 109, 144, 220, 248, 170, 180, 141, 56, 78, 138, 231, 88, 36,
+ 54, 61, 126, 181, 251, 215, 100, 149, 85, 164, 234, 92, 99, 226, 17,
+ 127, 19, 228, 175, 21, 201, 205, 45, 147, 185, 213, 118, 190, 72, 216,
+ 229, 211, 187, 47, 16, 93, 194, 166, 182, 198, 228, 5, 47, 113, 199,
+ 33, 197, 189, 242, 98, 127, 133, 248, 255, 152, 251, 238, 176, 40, 146,
+ 231, 239, 37, 232, 154, 80, 84, 84, 48, 174, 1, 19, 138, 128, 98,
+ 32, 237, 204, 168, 96, 150, 83, 48, 7, 64, 5, 5, 84, 196, 128,
+ 9, 88, 64, 49, 11, 102, 209, 83, 49, 220, 137, 152, 0, 81, 81,
+ 1, 215, 156, 191, 162, 39, 138, 98, 88, 3, 6, 76, 152, 21, 65,
+ 223, 238, 221, 233, 158, 94, 220, 157, 89, 126, 187, 127, 188, 247, 60,
+ 60, 214, 51, 215, 93, 53, 85, 83, 159, 234, 234, 234, 176, 113, 35,
+ 67, 19, 70, 165, 218, 205, 142, 29, 51, 197, 219, 37, 175, 243, 145,
+ 159, 206, 117, 18, 223, 158, 30, 80, 100, 57, 119, 195, 187, 215, 255,
+ 203, 161, 172, 39, 55, 95, 21, 189, 103, 146, 181, 229, 116, 235, 224,
+ 135, 91, 2, 191, 126, 45, 233, 89, 245, 162, 185, 137, 200, 201, 225,
+ 238, 144, 26, 131, 142, 44, 189, 111, 107, 148, 119, 201, 216, 178, 87,
+ 199, 196, 225, 115, 99, 199, 31, 233, 179, 34, 113, 246, 119, 143, 135,
+ 57, 235, 139, 47, 250, 118, 61, 126, 254, 194, 196, 230, 59, 30, 133,
+ 22, 30, 29, 181, 125, 244, 198, 143, 149, 90, 53, 61, 155, 122, 193,
+ 190, 126, 179, 216, 2, 81, 181, 143, 103, 87, 181, 152, 178, 170, 164,
+ 243, 207, 123, 99, 51, 82, 141, 211, 182, 7, 230, 173, 27, 239, 58,
+ 204, 126, 73, 233, 181, 254, 71, 110, 31, 113, 244, 237, 221, 181, 123,
+ 69, 241, 223, 115, 215, 93, 157, 241, 106, 222, 152, 127, 246, 7, 15,
+ 178, 171, 243, 171, 166, 131, 217, 178, 231, 73, 11, 63, 29, 28, 179,
+ 244, 221, 189, 83, 227, 118, 25, 175, 111, 183, 160, 66, 134, 85, 201,
+ 128, 3, 127, 167, 219, 126, 60, 79, 221, 217, 153, 94, 241, 174, 40,
+ 62, 241, 75, 199, 14, 31, 31, 53, 252, 52, 186, 167, 197, 215, 47,
+ 247, 191, 110, 62, 183, 68, 210, 252, 68, 45, 75, 247, 177, 77, 14,
+ 127, 186, 21, 102, 118, 207, 161, 228, 192, 141, 139, 238, 61, 103, 13,
+ 47, 248, 222, 42, 255, 89, 78, 199, 177, 33, 237, 251, 92, 91, 252,
+ 168, 121, 219, 109, 177, 215, 210, 236, 175, 70, 134, 13, 237, 153, 212,
+ 226, 201, 104, 233, 18, 183, 224, 106, 51, 182, 57, 77, 180, 152, 254,
+ 245, 164, 245, 127, 87, 235, 90, 198, 250, 68, 141, 171, 242, 213, 170,
+ 96, 253, 191, 233, 71, 110, 251, 31, 168, 231, 22, 116, 179, 111, 219,
+ 38, 143, 191, 85, 254, 246, 185, 94, 106, 112, 187, 138, 19, 36, 11,
+ 219, 103, 63, 62, 58, 98, 236, 251, 185, 159, 179, 18, 70, 36, 95,
+ 9, 170, 56, 136, 154, 254, 172, 249, 138, 33, 231, 55, 190, 51, 22,
+ 251, 55, 24, 113, 177, 210, 160, 251, 7, 188, 158, 2, 135, 27, 176,
+ 62, 173, 112, 89, 199, 134, 9, 251, 6, 157, 55, 50, 218, 88, 227,
+ 202, 10, 227, 176, 176, 195, 137, 105, 59, 175, 29, 201, 77, 144, 90,
+ 53, 60, 246, 211, 251, 112, 220, 111, 145, 107, 131, 12, 159, 110, 222,
+ 15, 221, 159, 45, 156, 88, 146, 59, 249, 248, 225, 136, 95, 183, 140,
+ 250, 116, 107, 86, 121, 208, 253, 129, 197, 67, 130, 44, 190, 73, 242,
+ 220, 123, 76, 49, 202, 143, 75, 121, 233, 186, 219, 247, 254, 250, 103,
+ 251, 237, 51, 101, 231, 250, 61, 245, 17, 31, 152, 249, 207, 192, 185,
+ 14, 97, 19, 108, 247, 153, 45, 221, 213, 123, 230, 39, 144, 43, 22,
+ 188, 190, 254, 43, 126, 244, 222, 144, 246, 50, 241, 215, 157, 91, 151,
+ 135, 31, 127, 248, 79, 221, 228, 235, 23, 189, 178, 69, 39, 118, 27,
+ 53, 79, 254, 247, 99, 199, 46, 67, 162, 115, 91, 77, 113, 107, 209,
+ 54, 244, 88, 239, 61, 23, 237, 107, 255, 22, 93, 233, 82, 103, 198,
+ 207, 226, 137, 109, 119, 30, 13, 54, 105, 91, 225, 249, 189, 136, 46,
+ 174, 21, 66, 63, 118, 56, 234, 217, 126, 104, 207, 161, 162, 208, 164,
+ 116, 179, 95, 185, 19, 166, 78, 89, 254, 210, 234, 181, 227, 17, 185,
+ 81, 252, 253, 58, 226, 205, 142, 78, 85, 75, 230, 216, 5, 180, 147,
+ 248, 78, 52, 31, 226, 33, 174, 159, 252, 32, 48, 197, 163, 185, 53,
+ 211, 62, 41, 170, 69, 13, 167, 35, 7, 19, 90, 247, 154, 48, 249,
+ 242, 237, 6, 33, 30, 75, 239, 254, 106, 63, 212, 255, 192, 17, 73,
+ 146, 115, 74, 69, 170, 249, 164, 15, 55, 234, 140, 12, 158, 177, 111,
+ 167, 127, 152, 168, 203, 210, 109, 93, 204, 198, 220, 14, 54, 86, 88,
+ 69, 85, 205, 156, 250, 229, 74, 164, 237, 62, 115, 167, 153, 235, 124,
+ 2, 166, 26, 187, 102, 175, 168, 154, 145, 150, 50, 242, 185, 233, 39,
+ 209, 89, 143, 154, 63, 102, 213, 240, 151, 213, 152, 236, 107, 69, 15,
+ 202, 253, 104, 101, 53, 65, 122, 213, 251, 115, 225, 210, 49, 233, 51,
+ 18, 218, 54, 59, 246, 120, 85, 97, 247, 183, 159, 3, 246, 30, 111,
+ 223, 243, 129, 200, 104, 243, 182, 90, 190, 81, 86, 93, 76, 214, 143,
+ 48, 59, 176, 108, 244, 178, 9, 11, 170, 255, 21, 20, 93, 213, 207,
+ 105, 78, 150, 219, 232, 58, 191, 255, 251, 186, 237, 192, 223, 206, 99,
+ 198, 190, 185, 179, 160, 212, 239, 200, 187, 133, 23, 23, 172, 78, 79,
+ 105, 240, 97, 90, 238, 193, 153, 165, 238, 167, 38, 254, 37, 95, 115,
+ 176, 222, 253, 23, 67, 67, 218, 123, 189, 202, 123, 43, 61, 62, 46,
+ 119, 199, 133, 255, 253, 22, 245, 46, 157, 250, 101, 108, 206, 188, 205,
+ 83, 74, 157, 158, 230, 63, 240, 115, 28, 98, 41, 94, 91, 250, 86,
+ 114, 245, 127, 231, 54, 174, 247, 119, 232, 253, 164, 247, 157, 163, 165,
+ 131, 139, 251, 28, 248, 177, 249, 216, 219, 110, 173, 102, 153, 156, 185,
+ 176, 155, 41, 237, 82, 220, 252, 240, 181, 177, 153, 25, 25, 13, 54,
+ 201, 47, 252, 188, 151, 48, 182, 239, 247, 26, 159, 79, 6, 205, 12,
+ 95, 115, 95, 145, 60, 252, 180, 251, 249, 1, 143, 30, 223, 57, 244,
+ 198, 121, 209, 190, 143, 43, 171, 116, 235, 186, 216, 109, 194, 183, 73,
+ 179, 222, 122, 205, 247, 30, 180, 176, 237, 190, 184, 21, 205, 101, 206,
+ 29, 155, 12, 57, 124, 98, 202, 197, 228, 54, 109, 45, 19, 86, 201,
+ 229, 185, 125, 38, 79, 238, 92, 115, 228, 129, 23, 139, 31, 55, 46,
+ 248, 22, 100, 147, 81, 119, 229, 179, 117, 70, 55, 98, 140, 79, 14,
+ 251, 228, 113, 176, 81, 224, 230, 191, 108, 22, 110, 237, 255, 107, 87,
+ 163, 113, 97, 245, 110, 79, 54, 206, 153, 118, 101, 75, 212, 226, 22,
+ 126, 251, 199, 30, 165, 26, 15, 253, 126, 191, 90, 218, 166, 143, 146,
+ 233, 230, 161, 151, 238, 92, 190, 178, 123, 111, 231, 170, 54, 201, 41,
+ 213, 29, 106, 93, 221, 213, 205, 56, 194, 166, 203, 149, 53, 195, 95,
+ 79, 27, 26, 252, 163, 206, 146, 118, 87, 187, 84, 180, 31, 60, 178,
+ 195, 158, 116, 47, 219, 142, 65, 255, 60, 48, 126, 49, 186, 239, 181,
+ 163, 91, 15, 37, 222, 170, 247, 63, 171, 166, 67, 234, 214, 105, 97,
+ 118, 168, 153, 91, 197, 177, 238, 137, 142, 63, 115, 7, 181, 15, 121,
+ 28, 124, 41, 202, 230, 237, 249, 57, 119, 122, 47, 191, 20, 208, 240,
+ 201, 121, 102, 152, 108, 215, 30, 151, 131, 191, 190, 238, 155, 119, 46,
+ 112, 197, 194, 117, 49, 157, 198, 215, 117, 168, 226, 97, 47, 77, 240,
+ 222, 248, 210, 114, 100, 207, 37, 115, 143, 154, 22, 100, 36, 216, 12,
+ 31, 124, 241, 214, 139, 119, 245, 235, 52, 207, 184, 240, 91, 244, 229,
+ 118, 114, 114, 179, 27, 99, 74, 71, 215, 107, 219, 106, 224, 163, 254,
+ 195, 45, 86, 223, 57, 244, 98, 76, 11, 73, 179, 126, 86, 62, 237,
+ 198, 158, 184, 113, 224, 192, 229, 148, 186, 93, 172, 197, 69, 65, 147,
+ 206, 173, 93, 99, 243, 177, 85, 66, 104, 142, 247, 144, 228, 81, 7,
+ 76, 21, 153, 133, 137, 230, 103, 246, 76, 25, 253, 35, 43, 47, 112,
+ 253, 224, 251, 213, 115, 134, 231, 255, 19, 102, 118, 105, 112, 147, 197,
+ 219, 66, 186, 188, 176, 61, 56, 105, 95, 244, 209, 74, 145, 107, 26,
+ 100, 138, 46, 77, 99, 150, 103, 143, 238, 62, 180, 191, 119, 179, 79,
+ 237, 101, 91, 110, 93, 169, 59, 113, 204, 192, 209, 163, 50, 239, 85,
+ 183, 185, 191, 59, 96, 68, 45, 247, 144, 210, 172, 213, 14, 214, 3,
+ 250, 123, 231, 23, 207, 152, 59, 198, 42, 122, 253, 149, 140, 67, 85,
+ 46, 159, 186, 63, 61, 45, 255, 104, 65, 224, 250, 252, 209, 113, 25,
+ 87, 163, 29, 188, 31, 122, 46, 15, 30, 21, 185, 113, 229, 241, 245,
+ 255, 182, 47, 169, 215, 44, 165, 170, 109, 43, 255, 154, 63, 42, 214,
+ 120, 49, 225, 85, 78, 216, 180, 251, 237, 111, 119, 158, 228, 179, 125,
+ 84, 71, 55, 83, 217, 151, 143, 37, 254, 78, 171, 54, 108, 235, 227,
+ 216, 55, 108, 242, 196, 197, 97, 145, 171, 79, 53, 172, 244, 50, 240,
+ 195, 235, 253, 159, 223, 30, 92, 87, 55, 224, 127, 135, 23, 90, 153,
+ 84, 219, 245, 121, 239, 145, 187, 145, 97, 116, 226, 16, 102, 135, 241,
+ 85, 163, 17, 185, 10, 139, 143, 201, 247, 183, 72, 27, 143, 168, 209,
+ 173, 120, 93, 255, 248, 148, 214, 109, 75, 158, 119, 165, 62, 207, 219,
+ 48, 252, 82, 241, 244, 172, 141, 79, 227, 167, 52, 207, 119, 153, 89,
+ 24, 231, 151, 99, 124, 251, 203, 237, 85, 178, 37, 207, 127, 5, 252,
+ 156, 101, 155, 36, 237, 191, 99, 245, 237, 213, 67, 171, 13, 91, 119,
+ 223, 120, 224, 122, 151, 77, 149, 74, 27, 28, 177, 56, 158, 109, 223,
+ 182, 202, 182, 54, 91, 214, 109, 27, 249, 57, 122, 210, 210, 211, 107,
+ 198, 62, 150, 249, 181, 152, 90, 122, 254, 102, 233, 22, 139, 110, 126,
+ 219, 22, 47, 232, 190, 112, 157, 255, 149, 153, 19, 221, 182, 184, 246,
+ 57, 208, 115, 216, 162, 102, 86, 244, 167, 211, 103, 247, 228, 116, 31,
+ 178, 50, 90, 30, 229, 77, 109, 75, 138, 52, 118, 201, 11, 218, 145,
+ 217, 127, 218, 194, 171, 227, 23, 219, 121, 236, 169, 244, 241, 229, 75,
+ 155, 216, 42, 227, 147, 63, 136, 253, 7, 57, 121, 108, 104, 95, 101,
+ 85, 248, 192, 69, 173, 173, 199, 117, 116, 158, 253, 52, 209, 225, 86,
+ 90, 119, 247, 1, 70, 62, 93, 187, 236, 217, 251, 185, 208, 115, 129,
+ 104, 251, 67, 202, 37, 172, 241, 132, 152, 189, 161, 149, 37, 117, 242,
+ 122, 21, 13, 185, 181, 58, 130, 170, 120, 185, 197, 165, 70, 45, 222,
+ 39, 110, 166, 170, 13, 167, 68, 173, 29, 170, 63, 139, 236, 192, 28,
+ 173, 213, 194, 188, 206, 242, 97, 149, 86, 91, 172, 140, 59, 177, 126,
+ 201, 125, 219, 225, 141, 107, 102, 151, 182, 152, 243, 121, 111, 255, 33,
+ 243, 3, 141, 90, 86, 137, 75, 246, 200, 207, 221, 209, 250, 113, 132,
+ 139, 105, 155, 238, 11, 142, 46, 90, 250, 169, 120, 100, 159, 209, 179,
+ 215, 123, 219, 12, 167, 60, 99, 107, 215, 206, 238, 220, 107, 138, 251,
+ 199, 73, 178, 134, 35, 205, 143, 236, 105, 177, 82, 180, 101, 123, 124,
+ 193, 63, 251, 255, 25, 182, 126, 202, 228, 11, 23, 226, 163, 229, 95,
+ 134, 92, 119, 27, 219, 50, 230, 247, 173, 175, 219, 246, 219, 206, 254,
+ 223, 135, 131, 29, 31, 52, 203, 157, 85, 210, 224, 245, 151, 59, 59,
+ 75, 71, 60, 184, 19, 126, 248, 249, 111, 145, 215, 161, 249, 27, 226,
+ 86, 70, 31, 169, 243, 207, 169, 238, 103, 223, 39, 189, 109, 219, 215,
+ 121, 219, 170, 229, 49, 103, 195, 91, 93, 217, 213, 32, 195, 246, 245,
+ 154, 41, 247, 35, 3, 254, 155, 108, 183, 229, 229, 142, 130, 6, 62,
+ 23, 37, 77, 18, 65, 16, 237, 103, 59, 251, 76, 208, 241, 192, 182,
+ 219, 135, 197, 92, 30, 215, 193, 124, 126, 189, 169, 67, 118, 100, 191,
+ 169, 31, 117, 197, 106, 244, 11, 191, 157, 63, 34, 231, 13, 111, 116,
+ 125, 238, 251, 137, 85, 90, 53, 237, 250, 97, 144, 120, 91, 220, 24,
+ 89, 214, 197, 241, 181, 76, 236, 55, 86, 243, 89, 215, 188, 253, 197,
+ 79, 19, 23, 189, 127, 151, 191, 225, 169, 29, 125, 217, 61, 199, 181,
+ 190, 247, 148, 186, 125, 109, 234, 24, 37, 156, 253, 32, 250, 49, 108,
+ 94, 250, 137, 208, 91, 198, 244, 197, 55, 13, 102, 250, 117, 243, 217,
+ 214, 193, 118, 113, 157, 228, 33, 223, 63, 88, 217, 173, 58, 107, 245,
+ 60, 112, 100, 196, 22, 139, 129, 127, 167, 157, 90, 241, 81, 222, 169,
+ 90, 192, 143, 67, 133, 57, 201, 199, 46, 119, 106, 178, 188, 197, 187,
+ 7, 212, 214, 49, 169, 37, 174, 131, 78, 91, 90, 246, 110, 241, 180,
+ 249, 235, 167, 131, 221, 143, 103, 74, 114, 253, 146, 143, 22, 221, 221,
+ 21, 113, 239, 228, 137, 29, 141, 127, 139, 226, 79, 109, 186, 119, 254,
+ 227, 222, 16, 179, 244, 104, 179, 224, 189, 47, 115, 63, 117, 248, 116,
+ 196, 101, 249, 213, 246, 251, 231, 244, 29, 112, 249, 213, 63, 63, 67,
+ 141, 215, 61, 252, 183, 77, 106, 173, 115, 243, 235, 30, 249, 90, 152,
+ 59, 63, 45, 112, 97, 157, 180, 184, 120, 179, 162, 142, 5, 191, 70,
+ 78, 220, 189, 178, 221, 43, 191, 132, 125, 183, 188, 229, 119, 131, 63,
+ 217, 186, 125, 206, 61, 179, 121, 232, 147, 75, 163, 247, 245, 246, 241,
+ 179, 170, 119, 249, 68, 232, 152, 227, 77, 2, 47, 88, 239, 155, 236,
+ 121, 41, 216, 253, 99, 188, 253, 245, 119, 217, 123, 7, 197, 173, 60,
+ 184, 188, 66, 194, 4, 239, 71, 23, 54, 221, 123, 211, 120, 86, 142,
+ 125, 248, 250, 97, 179, 28, 211, 30, 141, 88, 24, 208, 98, 128, 248,
+ 223, 83, 5, 71, 7, 223, 246, 218, 238, 125, 161, 232, 85, 53, 201,
+ 206, 152, 23, 79, 47, 23, 15, 62, 209, 118, 221, 106, 155, 206, 255,
+ 172, 31, 95, 115, 104, 195, 215, 83, 159, 59, 68, 218, 94, 107, 188,
+ 54, 121, 153, 205, 158, 181, 78, 195, 229, 151, 172, 22, 63, 155, 250,
+ 205, 38, 167, 234, 151, 166, 15, 141, 179, 206, 213, 28, 84, 107, 122,
+ 101, 135, 3, 115, 179, 221, 11, 190, 175, 190, 86, 255, 196, 94, 175,
+ 13, 171, 107, 53, 90, 167, 184, 188, 42, 230, 193, 234, 31, 235, 103,
+ 6, 157, 58, 112, 239, 189, 71, 80, 221, 10, 97, 29, 98, 236, 62,
+ 58, 157, 220, 220, 200, 107, 71, 254, 192, 199, 201, 139, 246, 83, 105,
+ 98, 35, 135, 117, 78, 31, 127, 100, 57, 85, 122, 215, 225, 248, 222,
+ 45, 151, 54, 245, 170, 179, 176, 69, 68, 171, 58, 125, 135, 94, 190,
+ 183, 201, 220, 188, 225, 241, 172, 245, 173, 199, 213, 170, 176, 241, 244,
+ 209, 161, 31, 106, 223, 77, 30, 125, 247, 240, 155, 65, 79, 170, 120,
+ 117, 139, 15, 97, 230, 142, 57, 57, 164, 227, 243, 255, 26, 29, 174,
+ 178, 167, 123, 5, 207, 244, 189, 1, 29, 219, 62, 253, 190, 45, 59,
+ 123, 178, 233, 127, 116, 64, 223, 177, 25, 118, 187, 86, 133, 173, 29,
+ 88, 144, 59, 53, 33, 228, 198, 229, 241, 39, 86, 143, 108, 55, 218,
+ 163, 70, 114, 243, 131, 191, 230, 30, 157, 236, 94, 79, 210, 172, 209,
+ 173, 146, 139, 255, 210, 102, 199, 135, 239, 44, 233, 217, 215, 173, 91,
+ 167, 90, 195, 231, 159, 142, 236, 18, 55, 36, 250, 146, 151, 121, 238,
+ 186, 253, 81, 139, 93, 6, 137, 251, 206, 77, 155, 60, 189, 253, 198,
+ 36, 179, 101, 109, 90, 186, 214, 190, 182, 209, 173, 160, 224, 198, 29,
+ 201, 41, 102, 245, 217, 241, 187, 79, 237, 12, 255, 236, 88, 189, 119,
+ 235, 156, 38, 115, 63, 54, 244, 72, 104, 114, 111, 83, 243, 117, 61,
+ 3, 105, 177, 165, 217, 242, 232, 26, 73, 43, 134, 59, 207, 118, 24,
+ 127, 168, 93, 219, 245, 49, 141, 27, 206, 60, 189, 227, 212, 94, 23,
+ 35, 217, 252, 136, 103, 47, 247, 212, 176, 178, 146, 139, 254, 59, 54,
+ 168, 147, 73, 133, 85, 167, 92, 186, 216, 205, 106, 55, 223, 171, 112,
+ 90, 149, 140, 216, 142, 181, 106, 68, 137, 47, 223, 179, 105, 218, 34,
+ 189, 242, 19, 143, 197, 77, 188, 115, 135, 55, 181, 172, 16, 63, 59,
+ 74, 225, 118, 77, 84, 53, 181, 202, 85, 227, 36, 59, 170, 232, 227,
+ 251, 237, 35, 71, 7, 223, 47, 217, 55, 64, 18, 45, 241, 216, 221,
+ 243, 104, 203, 75, 157, 91, 249, 248, 25, 69, 101, 204, 140, 115, 91,
+ 223, 222, 119, 204, 58, 219, 185, 3, 99, 106, 244, 45, 30, 75, 217,
+ 228, 14, 14, 162, 140, 77, 58, 182, 171, 24, 63, 173, 160, 241, 212,
+ 89, 49, 126, 171, 36, 167, 175, 214, 245, 169, 108, 180, 190, 249, 162,
+ 253, 51, 70, 222, 95, 184, 255, 91, 188, 239, 248, 41, 39, 222, 53,
+ 120, 255, 178, 222, 40, 175, 35, 133, 149, 39, 30, 108, 126, 185, 193,
+ 219, 105, 133, 55, 198, 254, 206, 253, 60, 118, 239, 35, 199, 88, 241,
+ 152, 160, 236, 147, 45, 236, 6, 154, 77, 10, 123, 112, 113, 174, 223,
+ 204, 23, 63, 55, 251, 121, 196, 202, 44, 194, 250, 108, 72, 109, 181,
+ 190, 235, 236, 222, 31, 238, 12, 127, 180, 39, 189, 174, 131, 69, 204,
+ 231, 86, 19, 243, 135, 127, 61, 54, 180, 69, 99, 105, 137, 251, 158,
+ 97, 29, 140, 3, 94, 214, 48, 74, 188, 147, 86, 116, 121, 87, 237,
+ 246, 214, 217, 121, 138, 157, 15, 118, 122, 251, 157, 180, 49, 91, 121,
+ 245, 151, 185, 211, 156, 25, 11, 219, 50, 189, 243, 35, 154, 244, 111,
+ 212, 110, 130, 67, 181, 240, 78, 213, 106, 175, 104, 119, 160, 187, 185,
+ 209, 86, 231, 129, 223, 15, 95, 15, 221, 150, 48, 44, 157, 146, 52,
+ 54, 165, 166, 140, 22, 221, 235, 107, 85, 219, 100, 220, 30, 234, 109,
+ 224, 166, 171, 62, 93, 154, 12, 62, 211, 225, 88, 226, 102, 231, 5,
+ 210, 6, 206, 181, 188, 38, 43, 170, 20, 127, 255, 242, 239, 230, 61,
+ 107, 47, 154, 230, 13, 31, 96, 99, 229, 95, 233, 183, 168, 241, 177,
+ 121, 118, 163, 41, 209, 66, 227, 243, 127, 101, 108, 27, 241, 115, 70,
+ 233, 131, 45, 222, 169, 241, 146, 51, 93, 199, 212, 60, 243, 108, 251,
+ 6, 48, 231, 239, 111, 225, 180, 239, 218, 107, 115, 119, 73, 179, 53,
+ 169, 115, 26, 94, 124, 91, 56, 182, 229, 30, 191, 124, 255, 220, 187,
+ 157, 15, 189, 153, 37, 138, 115, 184, 251, 124, 234, 201, 253, 13, 156,
+ 103, 92, 109, 26, 178, 32, 209, 221, 207, 164, 183, 116, 131, 159, 123,
+ 162, 215, 23, 187, 160, 97, 206, 205, 198, 249, 14, 107, 75, 187, 196,
+ 13, 255, 58, 113, 225, 203, 118, 11, 214, 167, 167, 101, 250, 120, 152,
+ 207, 111, 19, 57, 101, 99, 73, 157, 65, 215, 198, 181, 221, 240, 172,
+ 235, 187, 253, 37, 125, 142, 57, 13, 222, 208, 221, 209, 113, 102, 140,
+ 212, 97, 187, 169, 149, 81, 226, 219, 152, 185, 91, 102, 84, 61, 56,
+ 97, 136, 183, 243, 173, 243, 46, 244, 224, 199, 27, 18, 210, 189, 223,
+ 207, 11, 26, 213, 189, 118, 247, 51, 237, 19, 221, 77, 35, 171, 198,
+ 181, 157, 248, 122, 194, 138, 124, 209, 248, 164, 2, 199, 85, 107, 123,
+ 55, 184, 93, 124, 37, 226, 115, 251, 97, 102, 183, 155, 210, 79, 191,
+ 5, 231, 158, 24, 243, 121, 205, 98, 123, 249, 18, 197, 192, 165, 169,
+ 159, 95, 118, 206, 205, 185, 247, 168, 85, 175, 194, 65, 149, 106, 86,
+ 173, 235, 251, 60, 188, 246, 209, 253, 147, 219, 38, 245, 79, 16, 53,
+ 148, 53, 221, 16, 17, 246, 109, 223, 36, 39, 219, 81, 255, 4, 220,
+ 238, 109, 101, 245, 120, 233, 207, 6, 35, 92, 179, 122, 60, 28, 49,
+ 183, 71, 166, 101, 197, 57, 199, 102, 212, 202, 74, 24, 185, 160, 243,
+ 236, 232, 54, 23, 141, 36, 115, 166, 130, 201, 218, 146, 252, 156, 218,
+ 199, 183, 156, 31, 23, 226, 179, 196, 183, 235, 212, 18, 233, 128, 165,
+ 201, 183, 71, 182, 184, 88, 181, 107, 241, 134, 51, 131, 199, 48, 23,
+ 199, 4, 62, 173, 211, 106, 182, 120, 115, 147, 172, 245, 209, 15, 178,
+ 122, 29, 88, 120, 172, 95, 130, 180, 119, 222, 193, 7, 55, 246, 254,
+ 117, 234, 219, 79, 143, 59, 37, 199, 87, 222, 153, 87, 117, 103, 159,
+ 173, 94, 110, 85, 92, 219, 59, 217, 81, 189, 71, 47, 168, 85, 239,
+ 165, 81, 225, 224, 196, 117, 37, 251, 150, 210, 247, 168, 154, 198, 179,
+ 147, 110, 57, 108, 79, 200, 127, 251, 216, 230, 235, 188, 195, 51, 38,
+ 121, 139, 100, 153, 226, 91, 77, 102, 237, 53, 53, 137, 55, 218, 85,
+ 91, 124, 33, 247, 219, 200, 30, 33, 67, 134, 95, 218, 125, 230, 205,
+ 253, 208, 79, 65, 123, 67, 186, 156, 141, 238, 44, 142, 125, 248, 182,
+ 175, 232, 174, 168, 185, 155, 141, 91, 243, 255, 29, 95, 190, 57, 174,
+ 209, 206, 5, 207, 58, 153, 182, 106, 92, 177, 75, 193, 182, 26, 83,
+ 246, 124, 172, 208, 162, 145, 236, 94, 196, 162, 7, 7, 2, 186, 214,
+ 204, 61, 19, 87, 177, 201, 243, 156, 3, 162, 61, 205, 255, 238, 20,
+ 222, 35, 174, 244, 184, 104, 89, 208, 200, 1, 35, 163, 35, 171, 85,
+ 118, 185, 112, 161, 145, 89, 98, 236, 170, 248, 109, 182, 255, 181, 218,
+ 251, 109, 102, 192, 233, 208, 53, 171, 223, 28, 168, 248, 52, 111, 70,
+ 171, 87, 237, 122, 87, 105, 92, 101, 203, 69, 183, 6, 115, 59, 121,
+ 30, 144, 58, 250, 180, 124, 150, 178, 126, 203, 242, 240, 112, 39, 179,
+ 37, 77, 159, 5, 84, 28, 238, 215, 125, 234, 161, 26, 199, 143, 111,
+ 78, 46, 25, 187, 106, 179, 213, 18, 111, 187, 86, 177, 125, 143, 63,
+ 63, 222, 232, 224, 228, 153, 54, 169, 223, 199, 175, 184, 109, 237, 63,
+ 103, 78, 230, 138, 196, 223, 183, 123, 125, 251, 39, 222, 120, 198, 162,
+ 105, 51, 94, 245, 60, 249, 246, 233, 153, 1, 222, 247, 230, 39, 91,
+ 173, 188, 64, 111, 27, 191, 126, 213, 78, 79, 153, 209, 126, 139, 210,
+ 206, 219, 106, 255, 251, 186, 212, 105, 113, 78, 243, 225, 166, 238, 43,
+ 138, 162, 91, 245, 255, 45, 58, 149, 60, 103, 246, 203, 152, 195, 81,
+ 95, 234, 87, 219, 108, 190, 39, 230, 140, 251, 155, 27, 125, 171, 54,
+ 236, 115, 91, 90, 82, 251, 221, 171, 43, 243, 140, 127, 158, 63, 56,
+ 112, 252, 186, 148, 85, 45, 170, 155, 138, 172, 2, 54, 111, 206, 79,
+ 12, 61, 254, 122, 251, 222, 229, 249, 171, 123, 59, 216, 15, 41, 76,
+ 218, 189, 173, 195, 216, 157, 253, 118, 120, 135, 251, 109, 42, 168, 187,
+ 234, 163, 104, 127, 231, 161, 46, 251, 50, 82, 94, 229, 83, 111, 222,
+ 36, 61, 252, 178, 254, 135, 104, 208, 225, 235, 181, 31, 87, 63, 237,
+ 120, 39, 204, 113, 214, 187, 169, 187, 50, 102, 54, 159, 184, 186, 119,
+ 212, 132, 158, 78, 169, 159, 134, 238, 216, 184, 175, 78, 235, 5, 135,
+ 189, 147, 214, 109, 148, 157, 11, 245, 184, 18, 49, 244, 249, 179, 156,
+ 55, 153, 131, 189, 253, 78, 125, 152, 210, 98, 74, 183, 184, 254, 133,
+ 57, 143, 194, 220, 223, 110, 9, 189, 84, 127, 252, 184, 227, 111, 206,
+ 135, 126, 159, 188, 109, 202, 250, 253, 61, 115, 166, 53, 219, 151, 96,
+ 213, 36, 52, 118, 130, 231, 188, 78, 38, 135, 247, 49, 117, 38, 44,
+ 235, 148, 54, 35, 230, 233, 199, 32, 233, 137, 44, 19, 187, 9, 230,
+ 30, 3, 138, 254, 123, 126, 123, 255, 178, 213, 107, 42, 184, 181, 140,
+ 18, 79, 171, 85, 81, 58, 111, 88, 228, 30, 155, 214, 173, 44, 215,
+ 52, 152, 34, 94, 25, 85, 117, 234, 233, 161, 73, 3, 155, 212, 114,
+ 219, 118, 98, 231, 215, 13, 117, 69, 33, 83, 58, 126, 249, 250, 170,
+ 106, 157, 191, 55, 154, 123, 172, 220, 248, 246, 175, 180, 123, 179, 154,
+ 47, 250, 175, 199, 92, 219, 27, 9, 183, 38, 220, 220, 57, 75, 225,
+ 246, 52, 40, 236, 208, 198, 161, 247, 199, 75, 63, 199, 221, 205, 61,
+ 40, 189, 107, 83, 84, 209, 168, 246, 79, 143, 31, 135, 95, 254, 116,
+ 188, 75, 215, 170, 148, 215, 228, 232, 202, 168, 95, 247, 188, 122, 13,
+ 203, 95, 27, 46, 110, 180, 114, 199, 202, 160, 225, 209, 103, 223, 75,
+ 39, 126, 10, 127, 59, 34, 57, 151, 121, 122, 110, 150, 241, 236, 235,
+ 119, 134, 86, 189, 102, 250, 209, 228, 148, 135, 201, 249, 78, 53, 71,
+ 79, 222, 112, 105, 204, 147, 0, 203, 39, 174, 221, 123, 90, 119, 108,
+ 177, 98, 137, 243, 84, 251, 244, 137, 129, 138, 106, 219, 86, 14, 62,
+ 186, 225, 221, 203, 21, 166, 239, 237, 83, 236, 75, 11, 124, 19, 143,
+ 184, 28, 107, 231, 60, 245, 228, 178, 121, 51, 43, 12, 75, 252, 149,
+ 211, 106, 101, 190, 111, 82, 240, 141, 202, 53, 207, 70, 207, 175, 212,
+ 196, 253, 75, 80, 76, 235, 106, 212, 170, 243, 173, 130, 7, 196, 108,
+ 167, 42, 57, 228, 159, 93, 18, 243, 56, 251, 120, 211, 0, 217, 147,
+ 95, 55, 187, 82, 185, 111, 98, 154, 250, 44, 190, 55, 59, 60, 50,
+ 43, 217, 184, 223, 58, 243, 113, 83, 15, 209, 180, 164, 32, 125, 142,
+ 172, 184, 209, 177, 153, 87, 171, 191, 148, 88, 42, 102, 173, 122, 155,
+ 187, 195, 248, 131, 169, 213, 16, 103, 143, 135, 119, 134, 153, 26, 27,
+ 129, 121, 99, 222, 163, 130, 201, 162, 132, 126, 11, 159, 84, 252, 57,
+ 173, 249, 213, 234, 171, 51, 158, 236, 172, 155, 223, 116, 89, 109, 241,
+ 171, 5, 197, 233, 143, 197, 97, 14, 205, 103, 53, 153, 186, 127, 198,
+ 134, 233, 99, 168, 189, 159, 134, 12, 24, 176, 55, 125, 229, 193, 53,
+ 223, 166, 229, 180, 9, 218, 208, 102, 141, 113, 85, 115, 135, 188, 235,
+ 155, 142, 124, 252, 100, 187, 224, 250, 240, 249, 183, 226, 187, 54, 45,
+ 242, 253, 181, 171, 120, 230, 237, 175, 63, 36, 109, 174, 37, 172, 246,
+ 122, 119, 110, 192, 181, 163, 9, 245, 250, 230, 141, 56, 215, 196, 170,
+ 253, 247, 69, 205, 82, 170, 117, 232, 91, 244, 241, 229, 193, 223, 119,
+ 69, 34, 81, 119, 90, 36, 10, 6, 255, 122, 22, 77, 20, 215, 99,
+ 47, 8, 147, 39, 114, 119, 232, 137, 148, 109, 186, 251, 78, 158, 16,
+ 234, 171, 253, 190, 57, 68, 73, 0, 183, 16, 70, 36, 146, 73, 69,
+ 162, 68, 64, 87, 3, 180, 72, 202, 119, 103, 29, 146, 15, 101, 214,
+ 35, 56, 193, 247, 41, 43, 223, 214, 206, 206, 94, 219, 125, 119, 34,
+ 145, 131, 232, 218, 213, 171, 174, 34, 209, 69, 86, 166, 68, 39, 249,
+ 253, 64, 171, 116, 240, 111, 78, 206, 68, 113, 147, 63, 120, 162, 54,
+ 253, 124, 39, 135, 252, 249, 220, 20, 223, 49, 134, 46, 176, 131, 122,
+ 163, 63, 248, 31, 69, 169, 236, 16, 194, 108, 74, 176, 114, 83, 251,
+ 255, 198, 38, 34, 246, 61, 193, 59, 118, 98, 109, 70, 81, 255, 215,
+ 123, 2, 123, 123, 2, 155, 65, 137, 192, 142, 230, 232, 59, 250, 76,
+ 18, 171, 183, 161, 199, 205, 152, 52, 117, 138, 173, 239, 140, 96, 223,
+ 233, 156, 53, 177, 205, 129, 13, 60, 101, 234, 223, 30, 254, 71, 119,
+ 87, 253, 11, 239, 5, 244, 100, 219, 181, 97, 251, 121, 70, 113, 237,
+ 115, 82, 254, 236, 251, 39, 175, 250, 74, 203, 25, 107, 176, 181, 247,
+ 188, 62, 29, 176, 140, 40, 78, 70, 14, 120, 39, 40, 83, 121, 31,
+ 226, 42, 93, 100, 52, 208, 42, 35, 188, 210, 207, 20, 36, 3, 242,
+ 197, 122, 64, 25, 172, 46, 118, 33, 147, 116, 144, 209, 80, 171, 140,
+ 101, 107, 218, 186, 98, 61, 8, 25, 34, 86, 166, 210, 83, 236, 116,
+ 145, 97, 165, 85, 134, 245, 133, 72, 41, 148, 81, 196, 218, 221, 154,
+ 245, 199, 226, 132, 101, 167, 160, 29, 145, 63, 34, 58, 212, 113, 9,
+ 205, 61, 47, 139, 99, 37, 119, 99, 69, 171, 250, 76, 159, 201, 29,
+ 83, 88, 175, 103, 80, 251, 138, 223, 189, 153, 5, 204, 41, 222, 190,
+ 197, 98, 63, 230, 159, 156, 56, 59, 213, 211, 96, 70, 218, 254, 111,
+ 37, 93, 249, 243, 92, 198, 58, 227, 128, 29, 95, 223, 159, 11, 99,
+ 25, 215, 238, 13, 216, 54, 43, 49, 221, 38, 127, 61, 241, 92, 115,
+ 95, 100, 3, 232, 23, 164, 13, 224, 119, 70, 54, 64, 52, 180, 1,
+ 247, 92, 187, 13, 182, 135, 60, 180, 71, 54, 64, 237, 161, 13, 150,
+ 111, 156, 154, 42, 100, 3, 231, 190, 14, 105, 200, 6, 203, 183, 210,
+ 105, 200, 6, 11, 55, 15, 75, 19, 178, 129, 111, 184, 60, 21, 217,
+ 0, 209, 208, 6, 220, 115, 1, 27, 0, 191, 69, 54, 248, 12, 108,
+ 0, 253, 16, 217, 0, 209, 109, 59, 45, 161, 185, 231, 154, 249, 209,
+ 45, 234, 51, 158, 54, 245, 178, 145, 13, 80, 123, 57, 176, 1, 149,
+ 179, 131, 183, 111, 35, 96, 131, 59, 253, 66, 221, 144, 13, 186, 198,
+ 199, 40, 233, 206, 192, 6, 242, 246, 107, 220, 248, 250, 126, 6, 54,
+ 200, 189, 98, 236, 134, 108, 128, 232, 70, 192, 6, 220, 115, 126, 27,
+ 64, 92, 145, 126, 0, 113, 130, 108, 128, 232, 64, 224, 7, 220, 115,
+ 205, 252, 174, 0, 63, 152, 249, 119, 140, 20, 217, 0, 181, 175, 10,
+ 108, 80, 218, 59, 130, 183, 239, 103, 96, 131, 150, 38, 179, 165, 200,
+ 6, 33, 1, 97, 74, 186, 26, 176, 193, 163, 240, 89, 82, 33, 63,
+ 176, 127, 17, 46, 69, 54, 64, 116, 107, 96, 3, 238, 185, 230, 190,
+ 104, 12, 128, 113, 31, 141, 1, 33, 230, 147, 196, 20, 49, 158, 255,
+ 49, 6, 56, 168, 143, 1, 20, 232, 235, 249, 215, 36, 193, 49, 0,
+ 182, 67, 113, 77, 46, 225, 218, 43, 60, 39, 233, 56, 6, 24, 105,
+ 140, 107, 16, 239, 72, 6, 228, 139, 100, 80, 128, 166, 216, 241, 44,
+ 68, 39, 25, 13, 180, 202, 128, 120, 194, 122, 16, 50, 160, 222, 72,
+ 23, 159, 154, 186, 142, 1, 154, 101, 64, 127, 197, 99, 192, 95, 147,
+ 212, 198, 0, 138, 149, 81, 100, 174, 235, 24, 160, 89, 6, 244, 7,
+ 40, 195, 133, 181, 187, 53, 219, 198, 236, 221, 223, 114, 46, 110, 202,
+ 164, 136, 94, 232, 150, 73, 241, 197, 83, 35, 35, 35, 99, 196, 47,
+ 164, 12, 63, 46, 6, 201, 164, 136, 134, 252, 248, 98, 19, 201, 15,
+ 218, 147, 228, 199, 225, 89, 38, 69, 52, 228, 199, 135, 115, 146, 31,
+ 180, 29, 201, 143, 195, 134, 76, 138, 104, 200, 143, 15, 51, 144, 31,
+ 194, 12, 196, 9, 194, 140, 39, 24, 79, 201, 220, 233, 15, 204, 116,
+ 84, 199, 76, 136, 17, 240, 27, 90, 24, 51, 176, 29, 242, 131, 34,
+ 17, 215, 222, 147, 214, 15, 51, 163, 173, 162, 112, 222, 4, 249, 182,
+ 193, 23, 253, 78, 18, 67, 153, 74, 92, 82, 250, 97, 166, 94, 117,
+ 9, 198, 76, 8, 33, 3, 234, 141, 116, 9, 161, 244, 195, 140, 44,
+ 102, 56, 206, 155, 32, 95, 18, 51, 33, 72, 134, 104, 162, 94, 152,
+ 89, 180, 51, 18, 99, 6, 218, 221, 90, 99, 206, 47, 147, 66, 155,
+ 114, 57, 189, 182, 251, 182, 213, 125, 18, 218, 88, 27, 63, 104, 191,
+ 242, 242, 11, 225, 225, 7, 109, 85, 110, 126, 162, 137, 90, 249, 65,
+ 187, 232, 202, 15, 97, 6, 226, 4, 97, 38, 241, 32, 240, 53, 115,
+ 30, 204, 116, 82, 199, 76, 74, 252, 68, 177, 36, 90, 24, 51, 176,
+ 29, 242, 3, 187, 120, 238, 219, 167, 68, 25, 110, 156, 177, 35, 100,
+ 36, 130, 119, 74, 97, 229, 80, 81, 134, 27, 103, 32, 95, 36, 3,
+ 234, 141, 116, 201, 145, 25, 110, 156, 145, 68, 171, 99, 38, 145, 181,
+ 175, 143, 204, 112, 227, 12, 180, 59, 242, 161, 68, 170, 131, 198, 113,
+ 38, 62, 109, 63, 165, 75, 222, 238, 194, 218, 152, 228, 167, 105, 156,
+ 129, 252, 116, 201, 129, 93, 88, 123, 90, 227, 216, 212, 65, 227, 56,
+ 35, 79, 221, 79, 233, 146, 79, 186, 176, 182, 35, 223, 79, 211, 56,
+ 35, 3, 239, 167, 107, 110, 6, 113, 130, 48, 227, 179, 23, 228, 90,
+ 41, 60, 185, 153, 99, 153, 234, 10, 232, 155, 184, 95, 24, 51, 176,
+ 29, 246, 231, 3, 92, 123, 187, 253, 250, 97, 134, 156, 159, 67, 190,
+ 216, 159, 1, 13, 101, 42, 109, 187, 79, 63, 204, 144, 243, 115, 9,
+ 33, 3, 234, 141, 116, 241, 220, 167, 31, 102, 200, 249, 57, 228, 75,
+ 98, 70, 194, 202, 80, 236, 213, 15, 51, 104, 126, 238, 194, 218, 29,
+ 249, 144, 204, 71, 44, 191, 55, 112, 139, 99, 217, 249, 121, 191, 196,
+ 13, 84, 255, 140, 204, 195, 186, 196, 113, 104, 99, 146, 223, 160, 27,
+ 255, 164, 151, 157, 235, 66, 126, 133, 55, 207, 118, 210, 133, 159, 39,
+ 193, 175, 245, 40, 177, 220, 110, 227, 195, 19, 101, 231, 141, 137, 25,
+ 27, 168, 87, 83, 174, 186, 234, 52, 14, 238, 37, 198, 45, 240, 126,
+ 85, 183, 70, 253, 49, 7, 155, 191, 125, 3, 101, 179, 125, 158, 78,
+ 185, 25, 196, 9, 198, 204, 78, 224, 7, 7, 121, 198, 153, 206, 234,
+ 152, 81, 36, 79, 18, 251, 236, 17, 198, 12, 108, 135, 252, 192, 39,
+ 153, 104, 159, 164, 43, 102, 42, 104, 244, 3, 82, 134, 15, 33, 67,
+ 1, 222, 73, 193, 202, 73, 252, 87, 87, 204, 8, 203, 128, 124, 177,
+ 30, 128, 70, 186, 80, 255, 232, 138, 25, 29, 244, 216, 163, 142, 25,
+ 5, 107, 95, 197, 78, 93, 49, 163, 77, 134, 76, 137, 153, 118, 70,
+ 42, 187, 91, 43, 91, 130, 248, 223, 166, 157, 156, 108, 131, 40, 42,
+ 37, 134, 226, 203, 85, 96, 220, 149, 15, 44, 161, 126, 244, 125, 114,
+ 136, 141, 128, 116, 82, 172, 106, 92, 146, 228, 249, 210, 22, 199, 159,
+ 117, 228, 235, 91, 84, 59, 142, 94, 21, 176, 137, 197, 106, 18, 174,
+ 159, 213, 126, 121, 142, 110, 237, 124, 236, 48, 95, 223, 183, 245, 10,
+ 233, 161, 116, 245, 163, 108, 165, 152, 249, 175, 203, 173, 35, 202, 90,
+ 113, 73, 37, 230, 81, 227, 204, 35, 124, 125, 75, 77, 106, 48, 92,
+ 173, 206, 2, 211, 33, 47, 172, 24, 161, 26, 30, 178, 31, 244, 41,
+ 67, 217, 207, 161, 250, 41, 7, 100, 191, 93, 57, 170, 113, 24, 218,
+ 143, 57, 97, 126, 72, 200, 126, 182, 23, 118, 164, 35, 251, 161, 216,
+ 4, 237, 103, 221, 254, 84, 39, 33, 251, 45, 217, 106, 209, 25, 217,
+ 47, 124, 215, 3, 71, 100, 191, 196, 105, 103, 29, 133, 236, 199, 213,
+ 249, 44, 48, 13, 237, 39, 84, 255, 67, 246, 131, 120, 65, 246, 75,
+ 109, 173, 217, 126, 13, 116, 176, 223, 245, 126, 37, 212, 214, 174, 191,
+ 93, 145, 253, 130, 76, 77, 148, 121, 135, 223, 93, 95, 58, 38, 184,
+ 34, 111, 14, 50, 205, 34, 142, 182, 90, 116, 244, 4, 178, 31, 138,
+ 197, 217, 111, 207, 209, 227, 34, 46, 241, 214, 225, 238, 88, 22, 210,
+ 73, 61, 76, 164, 200, 126, 181, 59, 94, 86, 202, 154, 45, 170, 204,
+ 28, 51, 57, 194, 43, 215, 198, 180, 6, 195, 213, 8, 45, 48, 125,
+ 236, 185, 21, 35, 84, 59, 68, 246, 131, 177, 64, 221, 255, 100, 82,
+ 245, 53, 18, 228, 127, 50, 222, 188, 41, 11, 248, 223, 239, 109, 40,
+ 183, 178, 163, 71, 23, 168, 232, 182, 192, 255, 78, 180, 229, 175, 195,
+ 253, 6, 254, 103, 180, 14, 141, 61, 73, 184, 230, 55, 28, 248, 95,
+ 254, 145, 121, 188, 125, 75, 128, 255, 57, 116, 27, 143, 237, 87, 104,
+ 23, 164, 164, 221, 128, 255, 109, 138, 153, 204, 47, 23, 248, 31, 87,
+ 95, 180, 192, 116, 0, 240, 63, 161, 186, 35, 30, 243, 118, 114, 99,
+ 158, 124, 43, 136, 227, 123, 121, 198, 188, 174, 101, 198, 188, 29, 160,
+ 253, 118, 29, 198, 188, 29, 196, 88, 177, 131, 107, 95, 148, 104, 184,
+ 185, 149, 15, 33, 67, 1, 222, 73, 193, 202, 145, 37, 26, 110, 110,
+ 5, 249, 98, 61, 0, 141, 116, 73, 217, 102, 184, 185, 149, 207, 246,
+ 50, 99, 30, 107, 95, 106, 155, 225, 230, 86, 208, 238, 250, 206, 173,
+ 200, 60, 76, 150, 168, 255, 220, 138, 228, 7, 237, 169, 239, 220, 138,
+ 228, 71, 109, 211, 127, 110, 69, 230, 137, 16, 39, 8, 51, 178, 141,
+ 192, 15, 118, 242, 96, 166, 91, 153, 186, 55, 232, 43, 255, 91, 135,
+ 186, 247, 86, 162, 246, 181, 133, 107, 159, 179, 89, 87, 204, 152, 104,
+ 158, 147, 52, 201, 227, 234, 222, 91, 136, 186, 55, 160, 161, 76, 165,
+ 207, 109, 210, 21, 51, 154, 101, 36, 126, 95, 152, 134, 245, 32, 100,
+ 64, 189, 145, 46, 69, 9, 186, 98, 70, 179, 140, 103, 230, 71, 48,
+ 102, 32, 95, 181, 186, 55, 178, 87, 130, 174, 152, 209, 44, 99, 65,
+ 143, 169, 74, 204, 164, 179, 118, 183, 86, 182, 20, 137, 126, 44, 110,
+ 42, 133, 118, 196, 115, 23, 150, 182, 82, 236, 38, 158, 107, 142, 187,
+ 207, 155, 228, 73, 35, 22, 62, 70, 109, 168, 183, 214, 79, 149, 180,
+ 199, 210, 113, 212, 175, 30, 175, 121, 251, 142, 109, 113, 128, 226, 248,
+ 43, 48, 237, 176, 208, 140, 230, 147, 139, 176, 144, 206, 126, 91, 82,
+ 15, 248, 173, 144, 30, 136, 134, 122, 112, 207, 181, 235, 97, 118, 117,
+ 25, 106, 67, 217, 255, 111, 121, 26, 210, 163, 228, 246, 170, 52, 33,
+ 61, 56, 254, 10, 76, 67, 61, 248, 228, 146, 122, 64, 255, 65, 122,
+ 248, 44, 105, 42, 133, 254, 128, 244, 64, 244, 139, 71, 187, 137, 231,
+ 154, 223, 229, 73, 163, 60, 233, 145, 159, 89, 168, 13, 181, 100, 196,
+ 73, 37, 189, 120, 201, 56, 106, 151, 253, 121, 222, 190, 78, 64, 15,
+ 142, 191, 2, 211, 109, 128, 30, 124, 114, 73, 61, 68, 132, 30, 149,
+ 129, 30, 208, 231, 144, 30, 136, 174, 5, 190, 7, 247, 92, 243, 187,
+ 108, 0, 223, 99, 211, 81, 156, 47, 80, 47, 66, 85, 116, 91, 240,
+ 61, 222, 54, 8, 230, 237, 59, 2, 232, 193, 241, 87, 96, 218, 30,
+ 232, 193, 39, 151, 140, 137, 48, 14, 162, 152, 72, 173, 5, 56, 223,
+ 170, 61, 38, 218, 219, 149, 217, 87, 3, 250, 202, 214, 11, 199, 68,
+ 216, 14, 225, 92, 182, 129, 107, 111, 190, 94, 191, 60, 194, 190, 162,
+ 145, 61, 146, 1, 249, 226, 88, 2, 101, 108, 100, 231, 206, 235, 244,
+ 203, 35, 18, 190, 108, 195, 49, 81, 68, 200, 128, 122, 35, 93, 236,
+ 214, 233, 151, 71, 72, 253, 238, 226, 152, 8, 249, 146, 49, 81, 196,
+ 202, 144, 175, 213, 47, 143, 56, 121, 33, 0, 231, 17, 208, 238, 218,
+ 234, 252, 208, 166, 229, 93, 55, 128, 54, 214, 198, 15, 218, 175, 188,
+ 252, 236, 120, 248, 65, 91, 149, 151, 31, 180, 157, 54, 126, 208, 46,
+ 229, 93, 215, 128, 56, 193, 235, 26, 191, 129, 31, 108, 228, 193, 76,
+ 153, 61, 84, 242, 53, 96, 188, 94, 45, 140, 25, 216, 14, 143, 241,
+ 107, 136, 60, 98, 149, 225, 114, 111, 138, 144, 33, 7, 239, 36, 103,
+ 229, 248, 172, 50, 92, 238, 13, 249, 98, 61, 0, 141, 116, 41, 138,
+ 55, 92, 238, 77, 173, 86, 199, 140, 156, 181, 175, 44, 222, 112, 185,
+ 55, 180, 187, 33, 215, 53, 124, 86, 25, 118, 93, 3, 218, 211, 144,
+ 235, 26, 178, 120, 3, 175, 107, 252, 38, 106, 180, 63, 129, 31, 172,
+ 229, 193, 76, 153, 61, 39, 18, 208, 55, 177, 84, 135, 117, 141, 223,
+ 196, 122, 192, 47, 98, 93, 163, 84, 63, 204, 248, 165, 189, 229, 214,
+ 53, 126, 17, 235, 26, 128, 134, 50, 149, 182, 45, 209, 15, 51, 65,
+ 195, 214, 96, 204, 72, 8, 25, 80, 111, 164, 139, 103, 137, 126, 152,
+ 185, 226, 122, 145, 91, 215, 40, 45, 179, 174, 193, 202, 80, 252, 212,
+ 15, 51, 162, 243, 17, 220, 186, 70, 169, 246, 184, 11, 109, 90, 238,
+ 56, 94, 162, 157, 31, 180, 95, 121, 249, 121, 242, 240, 131, 182, 42,
+ 247, 250, 254, 79, 237, 252, 160, 93, 202, 59, 206, 64, 156, 32, 204,
+ 20, 125, 0, 126, 240, 91, 3, 102, 198, 249, 134, 134, 204, 156, 110,
+ 27, 60, 193, 95, 189, 198, 83, 12, 230, 183, 63, 116, 168, 241, 20,
+ 19, 181, 145, 98, 34, 55, 251, 166, 43, 102, 42, 107, 244, 131, 111,
+ 79, 114, 92, 112, 109, 132, 144, 161, 0, 239, 164, 96, 229, 200, 63,
+ 235, 138, 25, 205, 50, 22, 220, 153, 142, 101, 64, 190, 88, 15, 64,
+ 35, 93, 66, 62, 234, 138, 25, 205, 50, 228, 189, 27, 102, 99, 61,
+ 126, 148, 169, 241, 176, 246, 205, 121, 171, 43, 102, 52, 203, 232, 245,
+ 116, 190, 18, 51, 13, 141, 85, 118, 183, 86, 182, 84, 237, 79, 132,
+ 118, 68, 126, 131, 104, 143, 244, 181, 52, 247, 92, 115, 220, 253, 60,
+ 160, 27, 83, 191, 205, 57, 182, 77, 63, 6, 181, 55, 206, 26, 200,
+ 12, 113, 254, 143, 183, 239, 47, 198, 139, 185, 121, 253, 62, 219, 102,
+ 24, 99, 237, 247, 144, 237, 59, 146, 153, 253, 249, 145, 64, 95, 31,
+ 102, 173, 248, 49, 219, 102, 60, 243, 174, 201, 45, 85, 223, 8, 127,
+ 38, 98, 225, 21, 254, 190, 81, 147, 152, 43, 235, 15, 177, 109, 130,
+ 153, 112, 201, 191, 108, 223, 41, 76, 135, 228, 141, 188, 125, 127, 71,
+ 77, 99, 130, 150, 174, 96, 219, 204, 96, 204, 219, 203, 216, 190, 179,
+ 152, 128, 109, 19, 4, 228, 206, 97, 110, 212, 114, 100, 219, 204, 103,
+ 34, 206, 180, 84, 210, 70, 17, 50, 230, 81, 139, 42, 2, 125, 99,
+ 152, 129, 81, 205, 216, 54, 177, 204, 167, 253, 214, 172, 220, 197, 204,
+ 134, 123, 173, 5, 250, 46, 99, 14, 37, 181, 97, 219, 172, 196, 116,
+ 198, 167, 120, 226, 185, 246, 113, 26, 250, 11, 196, 16, 233, 47, 16,
+ 19, 120, 30, 202, 210, 208, 95, 184, 231, 218, 253, 229, 234, 127, 67,
+ 176, 191, 160, 246, 208, 95, 106, 252, 51, 135, 183, 111, 41, 240, 151,
+ 232, 90, 139, 176, 191, 36, 117, 93, 142, 253, 229, 127, 99, 86, 9,
+ 250, 203, 171, 53, 27, 177, 191, 52, 250, 185, 14, 251, 75, 161, 116,
+ 173, 160, 191, 100, 95, 88, 138, 253, 229, 80, 238, 2, 236, 47, 3,
+ 47, 132, 11, 244, 157, 198, 84, 233, 22, 130, 253, 197, 114, 232, 56,
+ 236, 47, 45, 103, 14, 17, 244, 23, 233, 14, 26, 251, 203, 241, 182,
+ 78, 216, 95, 82, 156, 109, 4, 253, 229, 179, 79, 7, 236, 47, 131,
+ 69, 182, 216, 95, 210, 182, 181, 19, 244, 151, 111, 152, 255, 74, 76,
+ 67, 127, 249, 38, 32, 23, 249, 11, 140, 135, 164, 191, 192, 248, 134,
+ 252, 5, 209, 157, 128, 191, 112, 207, 53, 243, 59, 9, 252, 229, 138,
+ 159, 17, 222, 3, 142, 218, 155, 1, 127, 105, 177, 183, 41, 111, 223,
+ 239, 192, 95, 102, 56, 58, 102, 35, 127, 57, 145, 226, 170, 164, 127,
+ 103, 142, 100, 222, 217, 184, 243, 246, 173, 220, 221, 135, 145, 191, 252,
+ 43, 27, 249, 139, 127, 137, 135, 146, 182, 6, 254, 226, 55, 134, 230,
+ 237, 107, 20, 61, 137, 185, 84, 161, 117, 54, 242, 23, 139, 150, 150,
+ 42, 26, 248, 203, 112, 247, 74, 188, 125, 197, 209, 211, 152, 227, 117,
+ 222, 101, 33, 127, 153, 58, 247, 170, 146, 54, 5, 254, 146, 240, 48,
+ 57, 139, 175, 111, 30, 240, 151, 181, 127, 5, 100, 33, 127, 57, 115,
+ 154, 86, 210, 69, 225, 50, 102, 212, 208, 183, 153, 124, 125, 127, 2,
+ 127, 113, 238, 101, 149, 133, 252, 229, 80, 96, 173, 44, 228, 47, 157,
+ 86, 84, 205, 18, 242, 151, 122, 38, 239, 50, 145, 191, 32, 26, 250,
+ 11, 247, 156, 223, 95, 224, 216, 70, 250, 11, 28, 171, 144, 191, 32,
+ 26, 198, 23, 238, 185, 102, 126, 159, 128, 191, 172, 50, 139, 192, 251,
+ 229, 81, 123, 19, 224, 47, 137, 187, 249, 251, 194, 248, 18, 145, 131,
+ 214, 227, 134, 49, 227, 166, 170, 104, 24, 95, 122, 85, 231, 95, 167,
+ 131, 241, 229, 81, 248, 92, 41, 242, 151, 192, 34, 21, 109, 2, 252,
+ 229, 130, 139, 64, 95, 16, 95, 190, 134, 206, 199, 251, 244, 59, 213,
+ 82, 205, 117, 140, 128, 191, 132, 166, 134, 75, 133, 226, 139, 43, 141,
+ 244, 157, 193, 72, 146, 35, 216, 190, 179, 24, 147, 218, 145, 82, 161,
+ 248, 146, 184, 16, 181, 153, 207, 252, 62, 16, 41, 197, 227, 145, 192,
+ 122, 40, 140, 47, 109, 255, 135, 250, 198, 50, 230, 215, 85, 52, 244,
+ 151, 175, 215, 133, 228, 46, 99, 92, 30, 68, 226, 179, 5, 136, 134,
+ 254, 194, 61, 231, 159, 231, 193, 60, 21, 229, 172, 241, 133, 32, 15,
+ 251, 201, 155, 179, 42, 15, 153, 225, 61, 188, 160, 111, 206, 27, 29,
+ 246, 73, 127, 32, 246, 73, 23, 113, 237, 125, 222, 232, 55, 207, 131,
+ 99, 46, 222, 39, 93, 68, 236, 251, 7, 24, 128, 50, 149, 152, 125,
+ 173, 223, 60, 15, 198, 105, 188, 239, 255, 45, 39, 3, 234, 141, 116,
+ 145, 189, 214, 111, 158, 7, 177, 141, 207, 176, 189, 81, 207, 89, 61,
+ 217, 92, 213, 252, 181, 126, 243, 60, 232, 15, 184, 150, 241, 70, 125,
+ 175, 61, 151, 187, 200, 164, 136, 126, 194, 100, 82, 124, 57, 141, 218,
+ 222, 253, 215, 234, 252, 184, 177, 13, 228, 192, 44, 13, 249, 241, 141,
+ 121, 106, 235, 156, 101, 248, 113, 177, 79, 38, 69, 52, 228, 199, 23,
+ 19, 73, 126, 230, 101, 248, 113, 216, 144, 73, 17, 13, 249, 241, 97,
+ 134, 156, 231, 65, 156, 224, 179, 5, 207, 129, 31, 124, 16, 194, 140,
+ 3, 254, 30, 230, 160, 111, 252, 75, 97, 204, 192, 118, 200, 15, 226,
+ 95, 113, 237, 37, 47, 13, 135, 25, 200, 23, 201, 48, 7, 52, 148,
+ 169, 92, 103, 127, 97, 56, 204, 152, 19, 50, 160, 222, 72, 23, 234,
+ 133, 225, 48, 3, 249, 146, 152, 49, 103, 101, 228, 60, 55, 28, 102,
+ 160, 221, 113, 173, 192, 116, 126, 182, 38, 204, 136, 194, 26, 235, 140,
+ 25, 104, 99, 146, 159, 38, 204, 64, 126, 186, 98, 134, 42, 195, 79,
+ 19, 102, 32, 63, 93, 49, 3, 109, 71, 242, 211, 132, 25, 200, 79,
+ 87, 204, 64, 156, 32, 204, 152, 63, 1, 126, 80, 40, 132, 153, 142,
+ 220, 25, 219, 130, 73, 98, 207, 103, 194, 152, 129, 237, 240, 24, 80,
+ 64, 156, 97, 123, 106, 56, 204, 120, 18, 50, 114, 192, 59, 229, 176,
+ 114, 66, 158, 26, 14, 51, 144, 47, 214, 3, 208, 88, 151, 167, 134,
+ 195, 140, 231, 51, 117, 204, 228, 176, 246, 141, 127, 98, 56, 204, 64,
+ 187, 235, 139, 25, 178, 198, 29, 242, 84, 127, 204, 144, 252, 68, 79,
+ 245, 199, 12, 201, 15, 218, 78, 95, 204, 144, 185, 25, 196, 9, 174,
+ 193, 63, 0, 126, 240, 92, 8, 51, 157, 240, 247, 136, 127, 60, 73,
+ 156, 248, 72, 24, 51, 176, 29, 30, 3, 30, 19, 53, 248, 71, 250,
+ 97, 134, 172, 39, 154, 19, 50, 226, 21, 0, 251, 172, 28, 249, 67,
+ 253, 48, 67, 214, 19, 33, 95, 92, 131, 7, 239, 142, 116, 241, 124,
+ 168, 31, 102, 200, 122, 34, 228, 75, 98, 6, 202, 84, 198, 151, 7,
+ 250, 97, 6, 213, 19, 93, 88, 187, 227, 179, 0, 167, 171, 159, 220,
+ 248, 34, 243, 143, 122, 34, 165, 216, 45, 173, 242, 228, 150, 78, 227,
+ 2, 180, 49, 226, 231, 35, 175, 126, 242, 65, 163, 15, 206, 101, 235,
+ 77, 230, 128, 223, 13, 105, 172, 78, 252, 60, 9, 126, 242, 206, 53,
+ 78, 166, 54, 116, 254, 163, 30, 161, 120, 189, 91, 26, 223, 164, 110,
+ 182, 78, 53, 248, 7, 4, 191, 83, 213, 79, 54, 158, 59, 239, 143,
+ 249, 170, 29, 220, 151, 97, 163, 219, 158, 49, 136, 19, 132, 25, 197,
+ 61, 64, 63, 17, 194, 140, 35, 87, 31, 190, 15, 230, 63, 249, 58,
+ 212, 224, 239, 19, 181, 235, 251, 92, 251, 214, 148, 167, 142, 152, 169,
+ 165, 209, 15, 58, 186, 72, 156, 112, 237, 154, 144, 161, 0, 239, 164,
+ 96, 229, 180, 46, 234, 171, 35, 102, 52, 203, 56, 229, 242, 245, 56,
+ 214, 35, 159, 208, 3, 208, 72, 151, 214, 241, 131, 116, 196, 140, 102,
+ 25, 207, 95, 62, 116, 198, 122, 228, 151, 169, 193, 179, 246, 109, 77,
+ 245, 211, 17, 51, 154, 101, 140, 250, 165, 26, 103, 186, 154, 170, 236,
+ 110, 173, 108, 41, 18, 69, 180, 105, 39, 135, 118, 68, 62, 132, 232,
+ 110, 41, 49, 20, 247, 92, 115, 220, 13, 28, 88, 66, 221, 173, 214,
+ 10, 239, 237, 182, 237, 227, 164, 164, 187, 79, 243, 167, 175, 247, 31,
+ 200, 187, 79, 250, 205, 146, 205, 52, 135, 213, 36, 92, 239, 55, 141,
+ 72, 166, 249, 176, 170, 172, 151, 68, 237, 167, 155, 95, 42, 102, 219,
+ 164, 208, 41, 79, 191, 41, 105, 113, 68, 26, 221, 237, 215, 103, 23,
+ 254, 26, 217, 97, 122, 162, 59, 90, 91, 200, 160, 223, 88, 30, 97,
+ 235, 147, 199, 233, 126, 175, 55, 243, 246, 45, 142, 202, 162, 205, 62,
+ 141, 99, 219, 200, 233, 95, 238, 110, 74, 250, 87, 248, 105, 58, 112,
+ 179, 165, 192, 59, 159, 163, 19, 186, 84, 98, 219, 92, 164, 93, 102,
+ 154, 176, 114, 47, 211, 167, 39, 148, 58, 243, 215, 254, 175, 209, 255,
+ 171, 86, 153, 237, 155, 67, 203, 220, 234, 179, 182, 186, 73, 247, 14,
+ 225, 31, 187, 197, 209, 185, 180, 111, 52, 197, 182, 201, 163, 47, 84,
+ 154, 175, 164, 171, 71, 220, 163, 151, 93, 220, 44, 176, 230, 240, 128,
+ 62, 251, 24, 173, 147, 40, 104, 179, 1, 166, 174, 42, 125, 159, 208,
+ 13, 108, 234, 243, 126, 223, 111, 81, 5, 180, 223, 227, 78, 108, 155,
+ 151, 244, 149, 10, 61, 149, 244, 207, 240, 66, 250, 65, 27, 111, 87,
+ 126, 59, 191, 165, 27, 87, 25, 199, 182, 41, 162, 229, 19, 3, 85,
+ 116, 196, 71, 122, 224, 133, 105, 174, 252, 53, 158, 47, 244, 222, 239,
+ 51, 217, 54, 223, 233, 27, 86, 51, 92, 85, 245, 176, 98, 250, 155,
+ 83, 168, 43, 255, 55, 42, 165, 71, 248, 142, 71, 109, 152, 143, 139,
+ 84, 239, 96, 36, 53, 98, 150, 30, 240, 227, 237, 43, 58, 101, 204,
+ 92, 104, 141, 222, 205, 148, 233, 246, 45, 72, 73, 87, 144, 86, 96,
+ 18, 206, 249, 243, 246, 253, 45, 175, 200, 48, 174, 3, 216, 54, 149,
+ 24, 231, 3, 82, 21, 45, 173, 204, 56, 55, 177, 231, 215, 87, 94,
+ 133, 217, 145, 208, 132, 109, 83, 141, 217, 209, 183, 142, 146, 254, 29,
+ 94, 157, 201, 61, 40, 18, 176, 85, 77, 134, 91, 103, 179, 192, 116,
+ 198, 167, 186, 140, 208, 250, 27, 142, 37, 32, 190, 162, 88, 50, 15,
+ 196, 18, 24, 47, 81, 44, 65, 52, 60, 231, 192, 61, 215, 204, 111,
+ 17, 136, 37, 5, 171, 37, 89, 40, 150, 44, 200, 87, 213, 132, 103,
+ 130, 88, 18, 179, 176, 22, 111, 29, 184, 20, 196, 18, 110, 156, 78,
+ 194, 107, 65, 70, 32, 150, 240, 141, 211, 42, 27, 236, 167, 15, 78,
+ 138, 195, 177, 100, 141, 245, 90, 22, 151, 105, 116, 216, 99, 254, 53,
+ 57, 99, 16, 75, 70, 108, 221, 129, 99, 73, 163, 135, 241, 74, 186,
+ 10, 136, 37, 53, 157, 35, 120, 251, 126, 1, 177, 36, 229, 59, 122,
+ 103, 57, 109, 26, 36, 119, 86, 189, 243, 105, 90, 242, 112, 37, 111,
+ 60, 48, 137, 62, 71, 43, 198, 63, 117, 70, 177, 196, 43, 181, 169,
+ 82, 86, 101, 16, 75, 154, 164, 254, 37, 16, 255, 174, 209, 211, 70,
+ 39, 224, 88, 146, 185, 41, 155, 181, 213, 77, 186, 81, 222, 83, 222,
+ 190, 159, 162, 114, 233, 236, 122, 53, 92, 81, 44, 89, 185, 161, 30,
+ 27, 15, 238, 209, 109, 235, 73, 4, 124, 237, 1, 45, 94, 83, 215,
+ 21, 197, 146, 228, 11, 42, 218, 56, 226, 9, 221, 191, 164, 46, 63,
+ 62, 64, 44, 169, 224, 89, 31, 199, 18, 119, 214, 223, 77, 34, 10,
+ 233, 101, 79, 90, 8, 96, 250, 45, 109, 92, 161, 35, 142, 37, 67,
+ 171, 117, 98, 251, 126, 164, 247, 213, 118, 20, 144, 251, 133, 78, 29,
+ 106, 131, 99, 73, 82, 159, 22, 236, 59, 23, 211, 155, 93, 27, 9,
+ 198, 18, 145, 71, 77, 28, 75, 188, 3, 171, 170, 250, 130, 88, 242,
+ 239, 138, 10, 188, 125, 171, 128, 88, 98, 126, 161, 42, 142, 37, 190,
+ 193, 111, 148, 223, 165, 22, 136, 37, 121, 238, 167, 120, 191, 209, 75,
+ 16, 75, 222, 236, 184, 225, 140, 98, 201, 137, 109, 3, 148, 244, 47,
+ 183, 202, 76, 242, 246, 236, 12, 222, 119, 6, 177, 100, 141, 236, 167,
+ 51, 138, 37, 77, 150, 54, 114, 65, 177, 68, 212, 104, 180, 139, 80,
+ 44, 225, 214, 96, 45, 48, 13, 99, 137, 208, 218, 44, 142, 37, 32,
+ 143, 66, 177, 228, 75, 171, 118, 114, 152, 23, 161, 88, 130, 232, 217,
+ 7, 99, 40, 238, 185, 102, 126, 123, 61, 74, 168, 167, 139, 209, 90,
+ 153, 29, 253, 120, 244, 56, 37, 61, 106, 170, 63, 125, 169, 229, 2,
+ 222, 117, 176, 62, 177, 155, 105, 46, 71, 79, 194, 235, 132, 217, 32,
+ 150, 240, 229, 232, 74, 61, 22, 238, 167, 195, 61, 235, 100, 163, 88,
+ 50, 112, 84, 129, 50, 110, 117, 137, 73, 163, 207, 183, 221, 198, 27,
+ 195, 146, 34, 14, 211, 45, 169, 9, 56, 150, 220, 91, 31, 160, 252,
+ 254, 203, 231, 30, 167, 71, 25, 95, 230, 245, 151, 170, 178, 44, 250,
+ 91, 190, 137, 27, 138, 37, 139, 43, 152, 43, 233, 53, 32, 47, 137,
+ 108, 222, 144, 119, 63, 92, 11, 16, 75, 78, 191, 169, 227, 134, 98,
+ 137, 115, 70, 53, 37, 61, 31, 196, 18, 191, 40, 19, 254, 125, 230,
+ 32, 150, 52, 114, 188, 231, 138, 98, 137, 34, 240, 136, 146, 158, 0,
+ 98, 201, 177, 13, 171, 249, 207, 201, 197, 228, 210, 86, 117, 135, 224,
+ 88, 242, 248, 199, 89, 165, 238, 9, 145, 247, 232, 17, 85, 87, 156,
+ 224, 235, 107, 25, 253, 128, 14, 25, 224, 147, 133, 98, 73, 231, 159,
+ 199, 149, 244, 106, 144, 151, 172, 120, 98, 204, 251, 141, 254, 149, 21,
+ 208, 141, 188, 28, 178, 81, 44, 25, 253, 122, 128, 146, 126, 54, 191,
+ 144, 14, 241, 15, 226, 237, 27, 12, 98, 201, 67, 183, 168, 108, 20,
+ 75, 134, 236, 90, 162, 164, 183, 135, 127, 164, 55, 87, 92, 205, 219,
+ 119, 61, 136, 37, 109, 159, 111, 202, 70, 177, 228, 116, 151, 45, 74,
+ 250, 83, 120, 49, 253, 102, 241, 54, 222, 190, 37, 32, 150, 88, 120,
+ 110, 70, 109, 152, 202, 225, 9, 217, 40, 47, 17, 37, 111, 200, 230,
+ 199, 180, 49, 99, 210, 110, 93, 54, 138, 37, 69, 215, 214, 40, 105,
+ 83, 16, 75, 238, 79, 229, 127, 231, 122, 167, 42, 50, 197, 118, 107,
+ 178, 81, 44, 249, 217, 60, 78, 73, 119, 0, 121, 137, 85, 221, 101,
+ 252, 235, 216, 167, 170, 48, 51, 174, 200, 178, 81, 44, 25, 247, 51,
+ 84, 73, 127, 0, 177, 196, 241, 172, 119, 182, 80, 44, 225, 214, 231,
+ 45, 48, 125, 2, 196, 18, 161, 117, 123, 110, 142, 211, 15, 199, 146,
+ 37, 32, 47, 129, 243, 31, 20, 75, 16, 237, 10, 242, 18, 238, 185,
+ 102, 126, 59, 64, 94, 210, 242, 197, 28, 124, 254, 210, 172, 149, 138,
+ 166, 65, 94, 226, 226, 61, 155, 183, 239, 71, 144, 151, 112, 243, 243,
+ 36, 188, 134, 108, 2, 98, 9, 223, 252, 92, 53, 246, 236, 167, 223,
+ 159, 70, 109, 82, 232, 99, 78, 17, 82, 148, 151, 196, 164, 241, 159,
+ 251, 44, 141, 58, 76, 239, 216, 133, 244, 202, 160, 247, 207, 87, 209,
+ 98, 144, 151, 100, 120, 241, 235, 11, 231, 56, 77, 175, 33, 185, 114,
+ 250, 235, 20, 150, 6, 121, 201, 85, 115, 161, 119, 62, 71, 103, 122,
+ 160, 54, 23, 233, 39, 203, 195, 89, 125, 47, 211, 149, 111, 10, 173,
+ 39, 95, 163, 227, 99, 145, 94, 57, 244, 165, 231, 104, 61, 249, 38,
+ 109, 228, 33, 180, 174, 155, 75, 175, 57, 134, 218, 228, 209, 190, 25,
+ 42, 218, 20, 204, 113, 58, 28, 229, 239, 43, 6, 177, 36, 42, 10,
+ 181, 81, 208, 127, 109, 83, 201, 53, 7, 121, 137, 85, 22, 255, 59,
+ 139, 162, 11, 232, 204, 157, 232, 251, 190, 164, 143, 119, 81, 173, 189,
+ 255, 6, 115, 156, 140, 43, 252, 190, 241, 3, 196, 146, 101, 230, 97,
+ 82, 20, 75, 196, 79, 102, 74, 85, 243, 163, 143, 244, 226, 67, 51,
+ 164, 252, 185, 227, 23, 122, 116, 143, 233, 82, 20, 75, 94, 190, 15,
+ 101, 109, 85, 76, 207, 216, 28, 42, 96, 171, 82, 186, 213, 8, 212,
+ 87, 196, 20, 236, 86, 209, 48, 150, 236, 252, 50, 157, 255, 251, 130,
+ 88, 18, 217, 103, 6, 62, 19, 188, 110, 217, 12, 182, 111, 5, 102,
+ 239, 85, 254, 119, 54, 2, 177, 196, 247, 17, 106, 83, 137, 217, 22,
+ 169, 210, 215, 20, 196, 18, 69, 19, 254, 59, 1, 225, 28, 39, 126,
+ 59, 178, 85, 53, 230, 47, 153, 202, 182, 191, 64, 44, 185, 238, 58,
+ 87, 42, 20, 75, 184, 189, 27, 22, 152, 62, 6, 98, 137, 208, 158,
+ 14, 84, 35, 83, 214, 197, 80, 173, 244, 246, 36, 177, 207, 3, 161,
+ 26, 89, 23, 92, 127, 241, 1, 125, 21, 121, 194, 53, 50, 216, 14,
+ 215, 175, 238, 114, 237, 67, 242, 12, 183, 22, 3, 249, 226, 250, 21,
+ 160, 161, 76, 21, 100, 12, 183, 22, 227, 67, 200, 128, 122, 35, 93,
+ 226, 239, 24, 110, 45, 6, 242, 37, 107, 100, 62, 172, 12, 201, 29,
+ 195, 173, 197, 64, 187, 27, 114, 253, 82, 148, 103, 216, 245, 75, 104,
+ 79, 67, 174, 95, 74, 238, 24, 118, 253, 18, 226, 4, 175, 197, 220,
+ 4, 126, 112, 79, 8, 51, 93, 185, 189, 250, 160, 111, 226, 45, 29,
+ 206, 67, 220, 38, 214, 48, 114, 137, 181, 152, 91, 134, 195, 12, 228,
+ 139, 207, 67, 0, 26, 202, 84, 142, 140, 255, 25, 14, 51, 18, 66,
+ 6, 212, 27, 233, 226, 249, 159, 225, 48, 3, 249, 170, 157, 135, 96,
+ 101, 40, 110, 26, 14, 51, 208, 238, 134, 92, 191, 132, 54, 54, 228,
+ 250, 165, 231, 127, 134, 93, 191, 132, 182, 51, 228, 250, 37, 196, 9,
+ 94, 139, 185, 6, 252, 224, 182, 16, 102, 186, 113, 235, 4, 55, 64,
+ 60, 207, 209, 97, 45, 230, 6, 49, 6, 220, 224, 218, 167, 92, 215,
+ 15, 51, 205, 158, 85, 227, 206, 17, 16, 50, 20, 224, 157, 20, 172,
+ 28, 234, 186, 126, 152, 249, 57, 32, 60, 11, 235, 145, 67, 232, 1,
+ 104, 164, 75, 206, 255, 244, 195, 204, 218, 199, 5, 220, 157, 23, 57,
+ 101, 214, 98, 88, 251, 250, 252, 79, 63, 204, 4, 206, 242, 229, 238,
+ 19, 188, 174, 253, 76, 13, 180, 41, 162, 181, 201, 249, 99, 95, 11,
+ 15, 63, 104, 191, 242, 242, 131, 246, 212, 198, 15, 218, 170, 188, 252,
+ 124, 120, 248, 65, 187, 232, 202, 15, 231, 102, 215, 136, 220, 236, 18,
+ 240, 131, 155, 2, 152, 177, 183, 227, 242, 6, 208, 87, 113, 69, 135,
+ 220, 236, 26, 225, 207, 87, 137, 220, 236, 138, 1, 115, 179, 171, 132,
+ 63, 3, 26, 202, 84, 54, 186, 98, 192, 220, 140, 144, 1, 245, 70,
+ 186, 196, 95, 54, 96, 110, 118, 165, 76, 110, 198, 202, 144, 92, 54,
+ 96, 110, 118, 197, 176, 227, 140, 232, 138, 97, 199, 25, 104, 79, 67,
+ 142, 51, 146, 203, 134, 29, 103, 32, 78, 112, 110, 118, 14, 248, 193,
+ 53, 33, 204, 112, 123, 152, 37, 160, 111, 226, 5, 29, 114, 179, 75,
+ 68, 78, 115, 145, 200, 205, 46, 24, 48, 55, 187, 72, 228, 102, 128,
+ 134, 50, 149, 185, 217, 121, 3, 230, 102, 132, 12, 168, 55, 210, 197,
+ 243, 188, 1, 115, 179, 11, 101, 114, 51, 86, 134, 226, 156, 1, 115,
+ 179, 11, 134, 157, 207, 64, 27, 27, 114, 62, 227, 121, 222, 176, 243,
+ 25, 104, 59, 67, 206, 103, 32, 78, 240, 89, 213, 163, 192, 15, 46,
+ 105, 199, 76, 232, 164, 0, 209, 12, 50, 111, 56, 11, 226, 249, 153,
+ 73, 98, 127, 255, 150, 114, 127, 255, 102, 204, 137, 248, 5, 217, 157,
+ 123, 198, 75, 255, 200, 205, 206, 18, 99, 192, 89, 226, 78, 4, 185,
+ 38, 63, 128, 99, 100, 17, 221, 115, 232, 211, 172, 150, 243, 166, 56,
+ 171, 48, 83, 69, 163, 31, 164, 140, 59, 142, 125, 205, 135, 144, 161,
+ 0, 239, 164, 96, 229, 196, 103, 105, 151, 177, 125, 118, 167, 236, 236,
+ 226, 66, 103, 21, 102, 52, 203, 184, 107, 245, 15, 55, 6, 156, 33,
+ 244, 0, 52, 214, 229, 132, 118, 25, 199, 99, 26, 158, 220, 22, 33,
+ 118, 83, 97, 70, 179, 140, 191, 159, 53, 224, 114, 204, 51, 101, 114,
+ 179, 51, 236, 190, 210, 12, 237, 50, 234, 45, 235, 37, 125, 103, 19,
+ 43, 85, 97, 70, 179, 140, 25, 5, 170, 189, 101, 195, 140, 85, 118,
+ 183, 86, 182, 84, 157, 13, 130, 118, 68, 252, 16, 13, 207, 6, 113,
+ 207, 69, 162, 53, 162, 230, 162, 221, 162, 22, 162, 84, 240, 135, 239,
+ 114, 28, 208, 141, 113, 112, 221, 194, 182, 233, 199, 160, 246, 166, 89,
+ 3, 25, 187, 174, 114, 222, 49, 224, 55, 227, 197, 220, 105, 115, 147,
+ 109, 51, 140, 121, 57, 44, 91, 73, 91, 101, 141, 100, 230, 45, 74,
+ 230, 237, 107, 220, 221, 135, 233, 99, 126, 136, 109, 51, 158, 89, 53,
+ 49, 93, 73, 87, 44, 157, 200, 252, 232, 120, 132, 183, 111, 123, 211,
+ 169, 76, 223, 160, 189, 108, 155, 25, 76, 97, 229, 68, 37, 93, 224,
+ 54, 147, 57, 106, 191, 133, 183, 111, 177, 124, 22, 211, 163, 194, 70,
+ 182, 205, 108, 230, 199, 134, 117, 42, 90, 58, 135, 57, 214, 118, 13,
+ 191, 190, 242, 185, 204, 193, 51, 171, 216, 54, 243, 25, 187, 247, 241,
+ 153, 170, 186, 183, 140, 113, 220, 178, 130, 191, 111, 84, 12, 115, 160,
+ 46, 234, 27, 203, 220, 159, 181, 56, 83, 85, 159, 92, 196, 124, 106,
+ 185, 64, 64, 238, 98, 230, 68, 220, 84, 182, 205, 82, 198, 44, 200,
+ 143, 237, 187, 140, 25, 235, 238, 45, 208, 119, 57, 227, 230, 219, 19,
+ 159, 67, 67, 244, 253, 57, 113, 196, 115, 237, 99, 60, 244, 53, 136,
+ 63, 210, 215, 32, 158, 144, 175, 33, 26, 250, 26, 247, 28, 250, 90,
+ 83, 214, 215, 90, 98, 126, 239, 128, 175, 141, 176, 90, 133, 125, 13,
+ 181, 135, 190, 246, 209, 106, 143, 160, 175, 73, 173, 210, 177, 175, 73,
+ 126, 108, 193, 190, 22, 154, 183, 72, 208, 215, 114, 125, 226, 176, 175,
+ 237, 90, 185, 90, 73, 139, 129, 175, 109, 186, 186, 94, 208, 215, 134,
+ 164, 175, 198, 190, 102, 50, 51, 30, 251, 154, 99, 65, 156, 160, 175,
+ 13, 154, 18, 135, 125, 237, 139, 91, 28, 246, 181, 132, 26, 113, 130,
+ 190, 70, 21, 175, 196, 190, 182, 172, 69, 28, 246, 181, 195, 215, 248,
+ 251, 194, 115, 104, 67, 71, 174, 197, 190, 86, 177, 247, 42, 236, 107,
+ 15, 78, 198, 9, 250, 218, 138, 244, 37, 216, 215, 230, 251, 199, 98,
+ 95, 11, 178, 140, 17, 244, 181, 37, 142, 225, 216, 215, 16, 13, 125,
+ 141, 123, 206, 239, 107, 48, 14, 147, 190, 6, 227, 42, 242, 53, 68,
+ 187, 3, 95, 227, 158, 67, 95, 171, 9, 124, 205, 10, 248, 90, 35,
+ 204, 175, 0, 248, 218, 189, 31, 245, 241, 25, 89, 212, 190, 2, 240,
+ 181, 248, 218, 252, 235, 116, 166, 221, 189, 152, 121, 63, 26, 225, 51,
+ 178, 77, 71, 171, 126, 111, 9, 250, 218, 90, 185, 57, 111, 95, 19,
+ 224, 107, 223, 60, 43, 225, 51, 178, 118, 115, 69, 217, 200, 215, 54,
+ 86, 122, 195, 187, 206, 110, 11, 124, 173, 192, 228, 10, 62, 231, 26,
+ 36, 75, 201, 66, 190, 246, 248, 209, 158, 44, 33, 95, 235, 119, 107,
+ 123, 22, 242, 181, 37, 39, 55, 101, 33, 95, 123, 153, 188, 134, 183,
+ 239, 79, 224, 107, 233, 253, 22, 225, 51, 178, 225, 221, 99, 149, 116,
+ 5, 224, 107, 73, 141, 163, 179, 132, 124, 173, 114, 149, 227, 248, 140,
+ 108, 154, 245, 126, 37, 93, 5, 248, 218, 208, 67, 255, 242, 247, 5,
+ 190, 246, 176, 150, 44, 11, 249, 90, 223, 51, 67, 178, 84, 251, 65,
+ 150, 49, 238, 190, 237, 179, 4, 125, 205, 242, 5, 231, 107, 44, 253,
+ 0, 250, 26, 126, 206, 239, 107, 112, 60, 38, 125, 13, 142, 175, 200,
+ 215, 16, 13, 227, 26, 247, 28, 250, 218, 76, 224, 107, 179, 128, 175,
+ 133, 169, 197, 181, 89, 21, 230, 227, 243, 181, 168, 61, 140, 107, 84,
+ 45, 129, 181, 69, 16, 215, 146, 163, 195, 241, 249, 218, 251, 53, 85,
+ 116, 125, 224, 107, 213, 182, 243, 175, 1, 193, 184, 22, 24, 26, 142,
+ 207, 215, 46, 121, 164, 162, 127, 151, 76, 100, 172, 167, 241, 175, 195,
+ 218, 192, 49, 52, 133, 59, 35, 235, 251, 69, 69, 67, 95, 251, 183,
+ 162, 192, 58, 44, 240, 181, 27, 141, 80, 155, 217, 204, 206, 14, 44,
+ 13, 124, 109, 6, 29, 41, 21, 138, 107, 123, 70, 113, 231, 107, 15,
+ 143, 65, 103, 100, 101, 204, 115, 255, 72, 193, 243, 181, 175, 158, 70,
+ 224, 243, 181, 207, 140, 216, 179, 185, 192, 215, 30, 155, 11, 201, 93,
+ 204, 140, 11, 65, 109, 150, 50, 167, 214, 163, 190, 203, 152, 38, 89,
+ 66, 125, 151, 51, 94, 119, 185, 179, 185, 136, 134, 113, 141, 123, 206,
+ 63, 175, 133, 121, 57, 202, 209, 83, 14, 129, 188, 243, 28, 111, 142,
+ 174, 126, 54, 23, 244, 45, 58, 44, 156, 163, 195, 118, 248, 108, 238,
+ 17, 142, 191, 236, 176, 174, 57, 186, 230, 185, 26, 204, 19, 240, 217,
+ 220, 35, 196, 111, 24, 1, 26, 202, 84, 174, 73, 31, 214, 53, 71,
+ 215, 44, 3, 142, 15, 88, 15, 66, 6, 212, 27, 233, 146, 152, 174,
+ 107, 142, 174, 69, 6, 136, 11, 88, 143, 195, 101, 126, 195, 136, 149,
+ 97, 151, 174, 107, 142, 174, 89, 6, 244, 7, 124, 246, 245, 176, 250,
+ 89, 85, 46, 223, 146, 73, 17, 253, 163, 123, 38, 197, 151, 135, 169,
+ 157, 125, 45, 195, 143, 27, 83, 101, 82, 68, 67, 126, 124, 99, 173,
+ 218, 221, 129, 233, 101, 248, 225, 184, 9, 248, 177, 180, 146, 31, 79,
+ 60, 85, 187, 59, 176, 12, 63, 14, 27, 50, 41, 162, 33, 63, 62,
+ 204, 144, 243, 90, 136, 19, 124, 207, 182, 93, 160, 184, 232, 168, 16,
+ 102, 184, 179, 185, 118, 160, 111, 74, 170, 48, 102, 96, 59, 228, 7,
+ 41, 105, 28, 127, 42, 213, 112, 152, 129, 124, 241, 239, 36, 1, 26,
+ 202, 84, 206, 157, 83, 12, 135, 25, 59, 66, 6, 212, 27, 233, 226,
+ 147, 98, 56, 204, 64, 190, 36, 102, 236, 88, 25, 148, 125, 160, 193,
+ 48, 3, 237, 142, 107, 35, 191, 229, 110, 154, 48, 35, 10, 123, 40,
+ 213, 21, 51, 208, 198, 36, 63, 77, 152, 129, 252, 116, 197, 140, 15,
+ 201, 239, 23, 224, 167, 1, 51, 242, 89, 15, 165, 186, 98, 6, 218,
+ 142, 124, 63, 77, 152, 129, 239, 167, 43, 102, 32, 78, 112, 253, 212,
+ 37, 80, 156, 114, 72, 8, 51, 220, 217, 92, 10, 244, 77, 116, 11,
+ 20, 196, 12, 108, 135, 235, 142, 82, 238, 219, 219, 185, 5, 26, 12,
+ 51, 144, 47, 174, 159, 2, 26, 202, 84, 218, 214, 53, 208, 96, 152,
+ 145, 16, 50, 160, 222, 72, 23, 79, 30, 25, 229, 197, 12, 228, 171,
+ 86, 63, 101, 101, 40, 92, 12, 135, 25, 104, 119, 125, 49, 163, 182,
+ 182, 237, 26, 168, 55, 102, 212, 214, 182, 73, 126, 255, 71, 204, 168,
+ 173, 109, 187, 232, 143, 25, 181, 181, 109, 23, 14, 51, 146, 174, 129,
+ 98, 185, 93, 160, 0, 102, 184, 179, 185, 10, 231, 64, 177, 143, 147,
+ 48, 102, 96, 59, 92, 119, 116, 230, 248, 23, 117, 211, 15, 51, 106,
+ 245, 83, 66, 134, 2, 188, 147, 130, 149, 35, 235, 166, 31, 102, 212,
+ 234, 167, 78, 132, 30, 128, 70, 186, 152, 119, 211, 15, 51, 106, 245,
+ 83, 39, 117, 204, 64, 153, 202, 252, 175, 171, 126, 152, 65, 245, 83,
+ 23, 214, 238, 248, 142, 85, 121, 245, 147, 179, 254, 125, 243, 71, 253,
+ 20, 158, 165, 245, 30, 146, 162, 181, 126, 170, 118, 207, 9, 193, 79,
+ 113, 162, 250, 201, 13, 253, 236, 179, 202, 214, 200, 226, 31, 237, 150,
+ 182, 9, 136, 208, 90, 35, 83, 203, 245, 8, 126, 146, 46, 53, 78,
+ 42, 6, 121, 254, 81, 7, 41, 122, 189, 91, 218, 122, 98, 77, 173,
+ 117, 16, 181, 92, 175, 43, 193, 239, 116, 245, 147, 141, 183, 207, 253,
+ 99, 174, 11, 207, 230, 46, 28, 30, 174, 117, 174, 75, 142, 51, 16,
+ 39, 120, 109, 219, 17, 248, 129, 139, 16, 102, 184, 179, 185, 137, 93,
+ 2, 197, 146, 206, 194, 152, 129, 237, 240, 24, 208, 133, 227, 223, 58,
+ 113, 128, 142, 152, 209, 124, 222, 244, 183, 243, 66, 124, 54, 87, 66,
+ 200, 72, 4, 239, 148, 200, 202, 105, 29, 50, 80, 71, 204, 104, 150,
+ 177, 161, 168, 176, 27, 214, 163, 51, 161, 7, 160, 145, 46, 173, 115,
+ 70, 235, 136, 25, 205, 50, 162, 198, 191, 194, 103, 115, 37, 157, 213,
+ 49, 3, 101, 194, 127, 147, 126, 14, 208, 17, 51, 154, 101, 244, 35,
+ 207, 230, 2, 187, 163, 125, 235, 129, 109, 218, 201, 161, 29, 17, 63,
+ 68, 119, 74, 137, 161, 184, 231, 224, 255, 84, 3, 253, 128, 127, 59,
+ 19, 117, 224, 102, 3, 75, 168, 169, 109, 70, 225, 243, 116, 45, 215,
+ 132, 42, 105, 239, 105, 254, 180, 120, 209, 66, 92, 247, 25, 12, 240,
+ 17, 0, 254, 230, 137, 36, 92, 173, 106, 201, 102, 154, 195, 106, 18,
+ 94, 223, 128, 231, 233, 248, 176, 42, 98, 207, 211, 5, 53, 69, 117,
+ 230, 20, 218, 102, 122, 34, 91, 83, 77, 163, 11, 207, 110, 16, 168,
+ 169, 30, 166, 87, 180, 66, 117, 209, 12, 154, 154, 19, 195, 202, 61,
+ 78, 23, 174, 155, 39, 208, 55, 139, 78, 79, 69, 99, 165, 156, 238,
+ 190, 46, 140, 149, 123, 154, 190, 57, 123, 154, 192, 186, 193, 57, 250,
+ 99, 189, 137, 108, 155, 139, 116, 161, 253, 48, 182, 239, 101, 58, 191,
+ 111, 47, 1, 185, 215, 232, 169, 118, 150, 108, 155, 28, 122, 120, 108,
+ 11, 213, 26, 75, 196, 77, 122, 248, 125, 59, 129, 190, 185, 244, 240,
+ 108, 20, 171, 242, 104, 171, 76, 118, 109, 36, 226, 30, 253, 205, 50,
+ 73, 224, 157, 31, 208, 135, 211, 142, 177, 109, 20, 244, 148, 227, 215,
+ 84, 117, 254, 136, 39, 116, 207, 211, 143, 121, 251, 138, 163, 11, 232,
+ 186, 235, 191, 179, 109, 94, 210, 245, 236, 170, 43, 253, 161, 114, 68,
+ 33, 189, 177, 142, 132, 183, 38, 248, 46, 234, 45, 237, 188, 212, 131,
+ 109, 83, 68, 79, 179, 31, 164, 164, 75, 194, 63, 210, 30, 121, 163,
+ 4, 234, 152, 95, 232, 9, 145, 131, 217, 54, 223, 233, 110, 212, 0,
+ 246, 174, 191, 98, 186, 154, 81, 111, 254, 51, 158, 81, 165, 180, 123,
+ 39, 23, 212, 134, 153, 254, 165, 91, 150, 170, 182, 100, 196, 108, 63,
+ 210, 133, 183, 175, 209, 41, 99, 166, 141, 87, 119, 182, 141, 41, 147,
+ 191, 206, 89, 85, 123, 149, 86, 96, 2, 238, 116, 20, 168, 219, 86,
+ 100, 46, 78, 170, 205, 182, 169, 196, 60, 247, 170, 162, 164, 127, 187,
+ 85, 102, 236, 41, 35, 129, 250, 105, 21, 102, 143, 83, 37, 182, 77,
+ 53, 166, 117, 134, 169, 146, 54, 137, 168, 206, 244, 244, 255, 41, 240,
+ 125, 107, 50, 220, 186, 162, 5, 166, 225, 121, 58, 114, 189, 81, 100,
+ 212, 66, 84, 29, 252, 53, 54, 106, 241, 231, 25, 24, 16, 95, 81,
+ 44, 105, 213, 186, 157, 28, 198, 75, 20, 75, 16, 253, 241, 96, 12,
+ 197, 61, 215, 28, 75, 118, 245, 41, 161, 238, 157, 104, 129, 207, 211,
+ 85, 17, 181, 87, 210, 57, 161, 254, 180, 155, 184, 115, 54, 23, 75,
+ 44, 65, 44, 177, 4, 177, 164, 30, 238, 219, 116, 233, 102, 154, 27,
+ 167, 147, 240, 250, 213, 143, 240, 100, 154, 111, 156, 22, 41, 207, 61,
+ 237, 167, 47, 247, 240, 192, 177, 228, 91, 211, 186, 44, 62, 210, 232,
+ 247, 191, 46, 241, 158, 17, 251, 9, 207, 192, 12, 148, 156, 64, 177,
+ 36, 211, 207, 77, 117, 254, 24, 196, 146, 131, 78, 209, 78, 66, 177,
+ 100, 244, 145, 67, 78, 40, 150, 180, 126, 248, 203, 9, 197, 146, 207,
+ 198, 214, 206, 66, 177, 36, 181, 133, 11, 62, 155, 187, 244, 104, 176,
+ 179, 234, 155, 95, 166, 123, 252, 195, 127, 174, 183, 66, 244, 53, 218,
+ 163, 205, 38, 103, 20, 75, 172, 188, 127, 43, 233, 106, 32, 150, 92,
+ 163, 29, 4, 238, 38, 200, 165, 7, 191, 62, 132, 207, 249, 87, 141,
+ 221, 166, 164, 187, 129, 88, 210, 170, 201, 50, 222, 190, 133, 32, 150,
+ 140, 58, 127, 238, 24, 138, 37, 158, 221, 140, 149, 118, 126, 21, 254,
+ 132, 62, 231, 28, 193, 235, 167, 95, 163, 10, 104, 251, 210, 36, 28,
+ 75, 102, 39, 92, 85, 210, 165, 225, 133, 116, 113, 167, 34, 222, 190,
+ 223, 64, 44, 89, 183, 185, 26, 142, 37, 70, 209, 22, 42, 108, 129,
+ 88, 210, 127, 98, 67, 193, 88, 242, 81, 84, 31, 199, 146, 15, 149,
+ 234, 227, 88, 82, 100, 94, 159, 31, 151, 32, 150, 48, 243, 234, 225,
+ 88, 146, 118, 78, 117, 214, 220, 4, 196, 146, 86, 230, 252, 114, 225,
+ 217, 92, 197, 30, 59, 28, 75, 38, 246, 80, 181, 111, 8, 98, 201,
+ 146, 251, 98, 222, 190, 143, 65, 44, 185, 187, 98, 64, 38, 138, 37,
+ 15, 125, 45, 50, 85, 107, 49, 149, 153, 71, 97, 233, 252, 254, 12,
+ 98, 201, 8, 71, 52, 6, 86, 99, 218, 57, 170, 214, 24, 225, 25,
+ 152, 153, 147, 210, 4, 198, 153, 154, 12, 183, 110, 108, 129, 105, 24,
+ 75, 200, 245, 100, 222, 88, 2, 242, 40, 20, 75, 106, 128, 88, 2,
+ 243, 34, 20, 75, 16, 13, 207, 230, 114, 207, 53, 199, 146, 215, 30,
+ 37, 84, 77, 103, 55, 28, 75, 46, 231, 251, 42, 233, 246, 83, 253,
+ 233, 131, 62, 11, 136, 88, 82, 15, 196, 18, 11, 37, 15, 212, 215,
+ 35, 118, 51, 205, 229, 232, 73, 120, 125, 242, 36, 200, 75, 248, 114,
+ 116, 216, 119, 83, 244, 126, 218, 230, 191, 247, 89, 40, 150, 12, 126,
+ 41, 87, 210, 211, 64, 44, 185, 243, 106, 21, 239, 119, 243, 5, 177,
+ 228, 197, 139, 202, 89, 40, 150, 204, 127, 211, 67, 105, 179, 160, 240,
+ 227, 116, 251, 6, 141, 120, 177, 245, 0, 196, 146, 249, 177, 119, 241,
+ 157, 33, 189, 76, 108, 149, 103, 94, 95, 132, 159, 166, 29, 92, 167,
+ 242, 158, 145, 93, 2, 98, 9, 179, 229, 31, 87, 20, 75, 170, 139,
+ 142, 42, 233, 39, 225, 151, 233, 11, 99, 46, 242, 246, 157, 11, 98,
+ 73, 160, 199, 77, 124, 54, 183, 161, 60, 67, 73, 175, 142, 188, 73,
+ 223, 108, 190, 141, 183, 175, 83, 76, 46, 253, 189, 208, 6, 159, 205,
+ 109, 96, 45, 81, 190, 255, 29, 16, 75, 94, 45, 203, 224, 245, 181,
+ 69, 178, 7, 244, 86, 159, 191, 241, 217, 220, 58, 23, 238, 40, 233,
+ 55, 243, 159, 208, 225, 179, 43, 243, 174, 235, 230, 131, 188, 36, 217,
+ 200, 10, 159, 205, 173, 51, 85, 117, 135, 242, 79, 144, 151, 132, 126,
+ 248, 139, 183, 239, 151, 200, 183, 244, 237, 238, 11, 241, 217, 220, 54,
+ 39, 84, 103, 85, 175, 204, 255, 72, 63, 108, 177, 137, 183, 239, 49,
+ 16, 75, 94, 223, 77, 192, 103, 115, 135, 214, 85, 157, 181, 253, 21,
+ 94, 76, 111, 27, 244, 55, 255, 90, 116, 116, 41, 189, 214, 29, 183,
+ 97, 168, 223, 42, 89, 21, 65, 44, 121, 118, 52, 129, 255, 92, 175,
+ 220, 152, 185, 186, 149, 59, 155, 187, 251, 173, 234, 172, 173, 49, 136,
+ 37, 177, 46, 252, 103, 115, 45, 78, 85, 100, 82, 155, 114, 103, 115,
+ 63, 184, 169, 244, 109, 39, 173, 204, 4, 140, 228, 63, 155, 91, 253,
+ 84, 21, 166, 214, 142, 40, 124, 54, 247, 235, 137, 25, 74, 186, 24,
+ 196, 146, 237, 201, 67, 5, 207, 230, 114, 251, 2, 44, 48, 125, 28,
+ 196, 18, 114, 191, 128, 200, 200, 10, 196, 18, 43, 16, 75, 172, 254,
+ 136, 37, 112, 190, 132, 98, 73, 36, 152, 227, 244, 35, 206, 230, 34,
+ 218, 9, 204, 113, 250, 17, 103, 115, 85, 177, 36, 12, 196, 18, 110,
+ 77, 120, 38, 152, 227, 84, 242, 158, 133, 207, 230, 86, 157, 161, 58,
+ 83, 216, 27, 204, 113, 6, 68, 112, 231, 17, 7, 139, 102, 136, 224,
+ 142, 188, 121, 162, 233, 184, 239, 123, 120, 54, 23, 207, 207, 147, 240,
+ 250, 51, 60, 155, 203, 55, 63, 23, 177, 247, 15, 181, 234, 27, 129,
+ 207, 230, 58, 95, 99, 105, 16, 75, 6, 12, 140, 20, 60, 155, 219,
+ 241, 127, 220, 217, 220, 235, 31, 209, 221, 199, 199, 233, 195, 85, 101,
+ 2, 231, 107, 179, 104, 235, 55, 145, 248, 108, 110, 215, 44, 180, 174,
+ 123, 154, 238, 187, 82, 104, 93, 247, 28, 125, 207, 42, 18, 159, 205,
+ 61, 248, 9, 157, 175, 189, 76, 47, 184, 38, 240, 59, 178, 96, 142,
+ 227, 145, 205, 157, 205, 157, 251, 62, 130, 181, 213, 77, 122, 191, 68,
+ 72, 223, 92, 250, 84, 17, 119, 54, 247, 98, 1, 119, 54, 247, 250,
+ 61, 254, 190, 70, 209, 15, 232, 252, 134, 220, 217, 220, 49, 243, 35,
+ 216, 115, 204, 79, 232, 71, 249, 252, 107, 254, 181, 65, 44, 249, 215,
+ 45, 28, 159, 205, 237, 192, 254, 222, 109, 125, 16, 75, 254, 110, 207,
+ 127, 102, 244, 49, 200, 75, 102, 47, 155, 133, 207, 230, 158, 106, 175,
+ 242, 171, 183, 32, 47, 177, 206, 153, 46, 112, 174, 247, 11, 93, 119,
+ 23, 119, 54, 183, 235, 180, 233, 248, 108, 238, 8, 55, 129, 243, 181,
+ 32, 47, 177, 252, 139, 59, 155, 59, 113, 33, 119, 54, 55, 227, 152,
+ 240, 217, 220, 65, 125, 185, 179, 185, 94, 155, 185, 179, 185, 67, 94,
+ 11, 159, 205, 109, 90, 97, 38, 62, 155, 107, 177, 69, 69, 155, 128,
+ 88, 82, 217, 113, 150, 84, 104, 142, 179, 32, 142, 59, 155, 107, 28,
+ 48, 155, 61, 3, 93, 157, 249, 89, 71, 248, 108, 46, 183, 239, 195,
+ 2, 211, 48, 47, 33, 247, 131, 136, 140, 102, 129, 88, 50, 11, 196,
+ 146, 89, 127, 238, 101, 119, 228, 106, 100, 158, 17, 129, 98, 73, 87,
+ 161, 26, 25, 119, 54, 87, 2, 250, 38, 118, 20, 174, 145, 193, 118,
+ 184, 126, 213, 137, 88, 139, 233, 104, 192, 181, 152, 78, 68, 253, 10,
+ 208, 80, 166, 50, 186, 68, 26, 112, 45, 134, 144, 1, 245, 70, 186,
+ 80, 145, 6, 92, 139, 233, 88, 102, 45, 134, 149, 145, 19, 97, 192,
+ 181, 152, 142, 129, 6, 93, 191, 132, 54, 54, 228, 250, 37, 21, 25,
+ 104, 208, 245, 75, 104, 59, 67, 174, 95, 66, 156, 224, 187, 133, 231,
+ 2, 63, 112, 20, 194, 12, 119, 54, 55, 39, 60, 80, 236, 57, 95,
+ 24, 51, 176, 29, 190, 147, 55, 156, 227, 175, 152, 103, 56, 204, 120,
+ 18, 50, 114, 192, 59, 229, 176, 114, 66, 230, 25, 14, 51, 144, 47,
+ 214, 3, 208, 88, 151, 121, 134, 195, 140, 231, 124, 117, 204, 64, 153,
+ 202, 181, 140, 185, 134, 195, 12, 180, 187, 33, 215, 47, 67, 230, 25,
+ 118, 253, 82, 52, 207, 176, 235, 151, 208, 118, 134, 92, 191, 132, 56,
+ 65, 152, 201, 153, 9, 252, 32, 66, 8, 51, 220, 217, 220, 248, 57,
+ 160, 239, 108, 97, 204, 192, 118, 248, 110, 225, 57, 28, 255, 196, 48,
+ 253, 48, 227, 89, 235, 43, 119, 183, 48, 33, 35, 30, 188, 83, 60,
+ 43, 199, 46, 76, 63, 204, 132, 121, 158, 193, 247, 164, 66, 190, 88,
+ 15, 64, 35, 93, 228, 179, 244, 195, 140, 229, 198, 57, 248, 247, 253,
+ 204, 103, 171, 99, 6, 202, 84, 234, 58, 75, 63, 204, 68, 79, 228,
+ 48, 3, 237, 174, 237, 172, 42, 180, 41, 199, 91, 243, 127, 127, 236,
+ 221, 226, 225, 7, 237, 87, 94, 126, 208, 158, 218, 248, 65, 91, 149,
+ 151, 159, 39, 15, 63, 104, 23, 93, 249, 33, 204, 64, 156, 224, 223,
+ 74, 153, 6, 232, 185, 2, 152, 33, 206, 230, 122, 130, 190, 57, 211,
+ 133, 49, 3, 219, 225, 49, 96, 6, 199, 223, 103, 186, 225, 198, 25,
+ 200, 23, 143, 1, 128, 134, 50, 149, 51, 131, 80, 195, 141, 51, 158,
+ 132, 12, 168, 55, 210, 69, 22, 106, 184, 113, 6, 242, 85, 251, 173,
+ 20, 86, 134, 121, 168, 225, 198, 25, 104, 119, 67, 142, 51, 208, 198,
+ 134, 28, 103, 100, 161, 134, 29, 103, 204, 67, 13, 59, 206, 40, 113,
+ 130, 246, 56, 4, 3, 63, 152, 41, 132, 25, 110, 15, 179, 57, 232,
+ 43, 153, 42, 140, 25, 216, 14, 143, 1, 33, 28, 255, 148, 41, 134,
+ 195, 12, 228, 139, 231, 26, 224, 157, 160, 76, 229, 92, 99, 138, 225,
+ 48, 3, 249, 226, 57, 19, 160, 145, 46, 57, 147, 13, 135, 25, 201,
+ 212, 50, 107, 254, 83, 85, 188, 125, 38, 27, 14, 51, 208, 238, 134,
+ 156, 207, 80, 83, 12, 59, 159, 129, 246, 52, 228, 124, 198, 103, 178,
+ 97, 231, 51, 16, 39, 24, 51, 19, 128, 31, 76, 211, 132, 153, 80,
+ 223, 41, 147, 102, 78, 86, 110, 250, 39, 190, 135, 15, 232, 171, 8,
+ 12, 20, 190, 3, 34, 152, 216, 247, 21, 196, 181, 151, 79, 10, 212,
+ 241, 60, 187, 169, 70, 63, 24, 113, 230, 73, 10, 222, 247, 21, 68,
+ 236, 251, 2, 52, 148, 169, 244, 185, 137, 129, 58, 158, 103, 215, 44,
+ 227, 88, 250, 90, 123, 172, 7, 33, 3, 234, 141, 116, 145, 5, 4,
+ 234, 120, 158, 93, 179, 12, 215, 253, 215, 113, 110, 6, 249, 170, 221,
+ 1, 193, 202, 240, 241, 15, 212, 241, 60, 187, 102, 25, 182, 7, 84,
+ 191, 189, 92, 196, 218, 221, 90, 217, 82, 117, 174, 8, 218, 17, 249,
+ 16, 162, 67, 29, 151, 208, 220, 115, 205, 113, 87, 209, 170, 62, 35,
+ 251, 22, 197, 254, 182, 114, 63, 6, 181, 175, 248, 221, 155, 9, 110,
+ 145, 196, 219, 183, 88, 236, 199, 188, 92, 94, 133, 253, 61, 244, 96,
+ 166, 176, 175, 175, 146, 174, 252, 121, 46, 211, 249, 112, 42, 239, 239,
+ 164, 255, 92, 24, 203, 28, 95, 60, 211, 70, 245, 116, 37, 166, 219,
+ 228, 175, 39, 158, 107, 31, 123, 138, 88, 191, 32, 109, 0, 191, 51,
+ 178, 1, 162, 161, 13, 184, 231, 218, 109, 208, 100, 102, 91, 7, 100,
+ 3, 212, 30, 218, 192, 117, 209, 40, 123, 33, 27, 204, 60, 124, 56,
+ 5, 217, 32, 54, 171, 118, 42, 178, 193, 145, 154, 147, 82, 133, 108,
+ 112, 194, 164, 233, 62, 100, 3, 68, 67, 27, 112, 207, 249, 109, 0,
+ 253, 22, 217, 224, 59, 176, 1, 244, 67, 100, 3, 68, 223, 234, 180,
+ 132, 230, 158, 107, 230, 39, 105, 89, 159, 73, 173, 49, 197, 13, 217,
+ 0, 181, 247, 1, 54, 184, 94, 146, 192, 219, 119, 45, 176, 193, 186,
+ 51, 165, 153, 200, 6, 63, 7, 171, 246, 181, 124, 253, 52, 151, 249,
+ 154, 185, 131, 119, 109, 241, 43, 176, 129, 255, 29, 159, 12, 100, 3,
+ 68, 183, 4, 54, 224, 158, 243, 219, 0, 226, 138, 244, 3, 136, 19,
+ 100, 3, 68, 67, 63, 224, 158, 107, 247, 131, 2, 92, 87, 239, 199,
+ 160, 246, 74, 63, 200, 227, 239, 11, 253, 32, 44, 44, 18, 255, 150,
+ 228, 213, 125, 42, 26, 250, 193, 149, 18, 254, 220, 7, 250, 1, 55,
+ 175, 88, 137, 105, 232, 7, 34, 129, 223, 131, 196, 99, 192, 4, 98,
+ 175, 164, 47, 136, 107, 193, 188, 99, 128, 131, 218, 24, 0, 250, 42,
+ 198, 233, 48, 6, 76, 32, 98, 231, 120, 174, 125, 200, 184, 64, 189,
+ 238, 52, 137, 153, 180, 192, 14, 199, 206, 241, 196, 24, 0, 104, 40,
+ 83, 217, 104, 92, 160, 94, 119, 154, 76, 72, 110, 159, 138, 245, 32,
+ 100, 64, 189, 145, 46, 241, 126, 129, 122, 221, 105, 114, 126, 113, 40,
+ 119, 63, 215, 184, 50, 99, 0, 43, 67, 226, 23, 168, 215, 157, 38,
+ 38, 43, 136, 123, 128, 198, 105, 159, 175, 66, 155, 150, 119, 254, 43,
+ 226, 225, 7, 237, 87, 94, 126, 208, 158, 218, 248, 65, 91, 149, 151,
+ 159, 132, 135, 31, 180, 75, 121, 231, 231, 16, 39, 120, 237, 100, 52,
+ 240, 131, 9, 188, 152, 233, 72, 98, 70, 2, 250, 74, 198, 10, 99,
+ 6, 182, 195, 243, 0, 31, 98, 237, 196, 71, 63, 204, 92, 75, 119,
+ 193, 254, 12, 249, 98, 25, 224, 157, 160, 76, 229, 124, 102, 140, 126,
+ 152, 89, 30, 249, 13, 231, 77, 144, 47, 158, 107, 0, 26, 233, 66,
+ 141, 209, 15, 51, 169, 55, 219, 225, 251, 230, 36, 99, 203, 204, 53,
+ 88, 251, 230, 140, 214, 15, 51, 207, 6, 19, 191, 151, 229, 163, 221,
+ 135, 160, 77, 203, 235, 147, 208, 198, 218, 248, 65, 251, 149, 151, 31,
+ 197, 195, 15, 218, 170, 188, 252, 160, 237, 180, 241, 131, 118, 41, 47,
+ 102, 32, 78, 240, 218, 201, 112, 224, 7, 190, 188, 152, 233, 68, 98,
+ 38, 103, 84, 160, 216, 115, 164, 48, 102, 96, 59, 92, 111, 26, 69,
+ 172, 157, 140, 208, 15, 51, 48, 175, 196, 245, 38, 66, 70, 14, 120,
+ 167, 28, 86, 78, 200, 8, 253, 48, 3, 243, 54, 172, 199, 72, 66,
+ 15, 64, 99, 93, 70, 232, 135, 25, 152, 23, 97, 61, 70, 150, 89,
+ 59, 97, 237, 27, 63, 92, 63, 204, 64, 159, 192, 107, 39, 35, 136,
+ 115, 44, 84, 7, 57, 151, 159, 203, 164, 136, 142, 79, 219, 79, 233,
+ 146, 183, 187, 176, 54, 38, 249, 113, 185, 174, 76, 138, 104, 200, 79,
+ 151, 28, 216, 133, 181, 39, 254, 205, 58, 186, 131, 156, 203, 27, 101,
+ 82, 68, 123, 2, 126, 186, 228, 147, 46, 172, 237, 200, 247, 227, 240,
+ 1, 255, 85, 209, 240, 253, 116, 205, 205, 32, 78, 240, 218, 137, 23,
+ 240, 131, 209, 188, 152, 113, 36, 49, 19, 63, 12, 244, 29, 42, 140,
+ 25, 216, 14, 175, 57, 12, 35, 214, 78, 134, 232, 135, 25, 114, 126,
+ 110, 78, 200, 136, 7, 239, 20, 207, 202, 177, 27, 162, 31, 102, 200,
+ 249, 57, 228, 139, 245, 0, 52, 210, 69, 238, 173, 31, 102, 200, 249,
+ 185, 249, 208, 50, 107, 39, 172, 125, 61, 189, 245, 195, 12, 154, 159,
+ 187, 176, 118, 199, 191, 203, 232, 35, 150, 135, 228, 118, 119, 44, 59,
+ 63, 239, 151, 184, 129, 90, 245, 35, 232, 176, 78, 107, 39, 101, 248,
+ 205, 152, 242, 219, 177, 236, 92, 23, 242, 75, 219, 106, 121, 68, 167,
+ 181, 19, 111, 98, 92, 248, 75, 44, 247, 218, 218, 205, 173, 236, 188,
+ 209, 243, 214, 6, 234, 95, 219, 20, 103, 157, 214, 78, 8, 126, 41,
+ 99, 197, 242, 42, 107, 162, 254, 152, 131, 237, 218, 190, 129, 10, 250,
+ 107, 142, 78, 53, 45, 136, 19, 124, 223, 156, 39, 160, 135, 243, 98,
+ 166, 51, 137, 25, 79, 208, 55, 103, 144, 48, 102, 96, 59, 60, 6,
+ 12, 38, 230, 51, 127, 233, 138, 153, 10, 90, 98, 39, 49, 150, 13,
+ 38, 198, 0, 64, 67, 153, 74, 127, 110, 172, 43, 102, 132, 101, 120,
+ 18, 50, 160, 222, 72, 23, 159, 70, 186, 98, 70, 7, 61, 6, 149,
+ 89, 59, 65, 246, 106, 168, 43, 102, 42, 240, 142, 51, 237, 140, 84,
+ 118, 183, 86, 182, 4, 152, 108, 211, 78, 174, 94, 87, 86, 253, 7,
+ 127, 75, 141, 47, 87, 129, 113, 87, 62, 176, 132, 138, 166, 87, 28,
+ 98, 51, 109, 26, 253, 127, 73, 158, 47, 13, 158, 119, 228, 235, 91,
+ 84, 59, 142, 254, 210, 137, 98, 177, 149, 132, 235, 103, 181, 95, 158,
+ 163, 199, 109, 11, 56, 204, 215, 247, 109, 189, 66, 122, 229, 194, 84,
+ 22, 127, 166, 204, 133, 201, 11, 148, 180, 73, 73, 37, 38, 253, 74,
+ 224, 17, 190, 190, 165, 38, 53, 24, 174, 86, 103, 129, 233, 144, 23,
+ 86, 140, 80, 13, 15, 217, 15, 250, 148, 161, 236, 215, 183, 81, 183,
+ 116, 77, 246, 3, 207, 59, 9, 217, 239, 253, 209, 98, 108, 63, 20,
+ 155, 160, 253, 46, 93, 174, 115, 68, 200, 126, 178, 69, 254, 71, 145,
+ 253, 190, 188, 183, 57, 138, 236, 215, 112, 162, 229, 81, 33, 251, 113,
+ 117, 62, 11, 76, 67, 251, 9, 213, 255, 144, 253, 32, 94, 144, 253,
+ 86, 104, 177, 223, 52, 29, 236, 183, 215, 179, 132, 26, 231, 114, 43,
+ 179, 172, 253, 154, 222, 243, 165, 31, 186, 243, 255, 182, 231, 133, 58,
+ 113, 180, 243, 221, 46, 110, 200, 126, 40, 22, 119, 252, 124, 142, 158,
+ 117, 224, 51, 239, 249, 153, 234, 245, 11, 233, 3, 123, 173, 78, 34,
+ 251, 117, 152, 116, 87, 185, 31, 249, 65, 133, 202, 204, 49, 251, 19,
+ 188, 251, 154, 39, 152, 214, 96, 184, 26, 161, 5, 166, 239, 23, 88,
+ 49, 66, 181, 67, 100, 63, 24, 11, 212, 253, 239, 207, 188, 73, 229,
+ 127, 252, 121, 19, 244, 191, 71, 183, 35, 165, 156, 253, 84, 237, 219,
+ 2, 255, 139, 183, 224, 239, 91, 217, 34, 142, 174, 184, 36, 10, 239,
+ 107, 70, 99, 207, 56, 224, 127, 179, 38, 205, 225, 223, 7, 106, 89,
+ 72, 23, 126, 24, 139, 247, 144, 54, 58, 31, 160, 164, 251, 1, 255,
+ 27, 226, 23, 200, 255, 91, 56, 192, 126, 92, 125, 209, 2, 211, 19,
+ 128, 255, 9, 213, 29, 241, 253, 77, 158, 220, 152, 71, 89, 130, 56,
+ 238, 197, 59, 230, 117, 37, 199, 188, 16, 208, 87, 86, 95, 120, 204,
+ 131, 237, 80, 28, 151, 53, 224, 218, 155, 215, 55, 220, 220, 10, 242,
+ 197, 99, 5, 160, 161, 76, 101, 46, 106, 101, 184, 185, 149, 136, 144,
+ 1, 245, 70, 186, 216, 89, 25, 110, 110, 5, 249, 146, 99, 158, 136,
+ 149, 33, 183, 52, 220, 220, 10, 218, 93, 223, 185, 149, 218, 25, 124,
+ 43, 253, 231, 86, 106, 121, 167, 149, 254, 115, 43, 181, 188, 211, 82,
+ 255, 185, 21, 153, 39, 66, 156, 32, 204, 136, 106, 5, 138, 139, 60,
+ 121, 49, 211, 141, 196, 140, 188, 94, 160, 152, 170, 43, 140, 25, 216,
+ 14, 249, 1, 85, 143, 107, 239, 89, 71, 87, 204, 152, 104, 244, 3,
+ 247, 71, 219, 241, 188, 135, 34, 100, 200, 193, 59, 201, 89, 57, 62,
+ 22, 186, 98, 70, 179, 140, 156, 254, 94, 105, 88, 143, 186, 132, 30,
+ 128, 70, 186, 132, 212, 214, 21, 51, 154, 101, 248, 72, 215, 226, 123,
+ 53, 168, 186, 234, 152, 145, 179, 246, 149, 213, 210, 21, 51, 154, 101,
+ 28, 174, 52, 83, 137, 153, 116, 214, 238, 214, 202, 150, 34, 209, 143,
+ 197, 77, 165, 208, 142, 200, 135, 16, 221, 243, 214, 110, 226, 185, 230,
+ 184, 155, 209, 40, 79, 106, 92, 247, 52, 106, 67, 189, 217, 115, 65,
+ 73, 59, 166, 140, 163, 190, 46, 123, 106, 207, 231, 127, 143, 90, 29,
+ 160, 56, 254, 10, 76, 59, 44, 52, 163, 133, 228, 34, 61, 224, 183,
+ 37, 245, 128, 223, 10, 233, 129, 104, 168, 7, 247, 92, 187, 30, 57,
+ 43, 34, 80, 27, 170, 223, 251, 232, 52, 164, 135, 91, 215, 117, 105,
+ 66, 122, 112, 252, 21, 152, 134, 122, 8, 201, 69, 122, 64, 255, 65,
+ 122, 44, 91, 217, 84, 10, 253, 1, 233, 129, 232, 43, 55, 119, 19,
+ 207, 181, 140, 191, 198, 121, 210, 133, 39, 83, 81, 27, 234, 68, 254,
+ 17, 37, 157, 249, 207, 56, 202, 104, 112, 78, 54, 159, 30, 121, 214,
+ 7, 40, 142, 191, 2, 211, 135, 22, 152, 209, 66, 114, 145, 30, 208,
+ 71, 145, 30, 219, 150, 52, 149, 66, 159, 67, 122, 32, 250, 76, 222,
+ 110, 226, 185, 102, 126, 222, 13, 242, 164, 147, 75, 167, 162, 54, 212,
+ 127, 141, 84, 244, 143, 3, 227, 40, 31, 121, 32, 111, 92, 219, 1,
+ 190, 7, 199, 95, 129, 233, 230, 224, 123, 8, 201, 69, 49, 17, 198,
+ 65, 124, 63, 87, 127, 128, 115, 75, 190, 152, 104, 111, 71, 198, 68,
+ 89, 205, 64, 113, 226, 64, 225, 152, 8, 219, 97, 156, 215, 36, 214,
+ 53, 6, 234, 151, 71, 60, 186, 102, 138, 99, 162, 136, 144, 33, 51,
+ 7, 99, 60, 43, 71, 62, 64, 191, 60, 194, 216, 246, 0, 94, 59,
+ 129, 124, 241, 218, 9, 124, 119, 86, 134, 231, 0, 253, 242, 136, 13,
+ 212, 39, 188, 22, 8, 249, 146, 49, 17, 202, 84, 126, 221, 254, 250,
+ 229, 17, 22, 118, 92, 189, 9, 218, 93, 91, 157, 31, 218, 180, 188,
+ 235, 6, 208, 198, 218, 248, 65, 251, 149, 151, 159, 39, 15, 63, 104,
+ 171, 242, 242, 131, 182, 211, 198, 15, 218, 165, 188, 235, 26, 16, 39,
+ 248, 126, 174, 222, 224, 187, 212, 226, 197, 140, 218, 30, 42, 69, 191,
+ 64, 177, 79, 95, 97, 204, 192, 118, 120, 109, 187, 31, 113, 63, 87,
+ 31, 195, 229, 222, 62, 132, 12, 5, 120, 39, 5, 43, 71, 214, 199,
+ 112, 185, 55, 228, 139, 245, 0, 52, 210, 197, 188, 143, 225, 114, 111,
+ 159, 190, 101, 238, 231, 98, 237, 155, 216, 219, 112, 185, 55, 180, 187,
+ 33, 215, 53, 100, 125, 12, 187, 174, 97, 222, 199, 176, 235, 26, 208,
+ 118, 134, 92, 215, 128, 56, 193, 251, 14, 123, 0, 63, 232, 207, 139,
+ 25, 181, 61, 39, 137, 189, 2, 197, 18, 15, 97, 204, 192, 118, 120,
+ 221, 185, 23, 177, 87, 215, 93, 63, 204, 236, 147, 89, 226, 49, 64,
+ 66, 200, 72, 4, 239, 148, 200, 202, 161, 220, 245, 195, 76, 161, 201,
+ 69, 110, 253, 220, 131, 208, 3, 208, 72, 151, 156, 158, 250, 97, 38,
+ 41, 185, 42, 183, 126, 238, 81, 102, 253, 156, 181, 175, 79, 79, 253,
+ 48, 179, 98, 115, 56, 183, 87, 215, 93, 123, 220, 133, 54, 45, 247,
+ 122, 55, 15, 63, 104, 191, 114, 175, 119, 247, 212, 206, 15, 218, 170,
+ 188, 252, 124, 120, 248, 65, 187, 148, 119, 156, 129, 56, 65, 152, 145,
+ 81, 192, 15, 122, 107, 192, 204, 4, 223, 80, 248, 195, 83, 51, 216,
+ 205, 186, 120, 15, 17, 232, 171, 96, 116, 216, 167, 213, 131, 24, 3,
+ 186, 19, 227, 12, 173, 223, 124, 245, 171, 127, 50, 183, 199, 181, 59,
+ 49, 6, 0, 26, 202, 84, 49, 208, 111, 190, 218, 212, 249, 45, 206,
+ 155, 124, 8, 25, 80, 111, 164, 139, 93, 13, 253, 230, 171, 143, 186,
+ 155, 74, 177, 30, 76, 153, 125, 90, 172, 12, 170, 186, 126, 243, 85,
+ 239, 38, 195, 240, 124, 21, 218, 29, 205, 43, 224, 254, 68, 104, 71,
+ 228, 55, 136, 30, 244, 247, 2, 154, 123, 174, 57, 238, 62, 76, 53,
+ 99, 102, 20, 61, 96, 219, 244, 99, 80, 251, 186, 111, 198, 51, 75,
+ 46, 173, 227, 237, 251, 125, 73, 20, 51, 117, 127, 33, 91, 123, 94,
+ 137, 233, 132, 211, 127, 19, 207, 249, 231, 71, 34, 66, 143, 111, 64,
+ 15, 248, 173, 144, 30, 136, 222, 4, 244, 224, 158, 107, 230, 183, 52,
+ 205, 140, 169, 61, 122, 1, 254, 221, 12, 212, 254, 9, 208, 99, 203,
+ 174, 16, 222, 190, 166, 75, 163, 152, 230, 14, 238, 110, 72, 15, 68,
+ 199, 3, 61, 184, 231, 252, 122, 64, 255, 65, 122, 124, 0, 122, 64,
+ 127, 192, 185, 50, 75, 215, 219, 178, 128, 230, 158, 107, 230, 151, 126,
+ 200, 140, 249, 247, 131, 20, 239, 23, 69, 237, 169, 119, 227, 153, 231,
+ 103, 242, 120, 223, 165, 30, 208, 195, 105, 177, 35, 254, 30, 136, 142,
+ 2, 122, 112, 207, 249, 245, 128, 62, 138, 235, 7, 64, 15, 232, 115,
+ 72, 15, 68, 143, 1, 223, 131, 123, 174, 153, 223, 79, 224, 87, 87,
+ 77, 123, 97, 61, 80, 251, 110, 224, 123, 4, 196, 143, 225, 223, 247,
+ 10, 252, 170, 75, 229, 121, 120, 239, 42, 162, 55, 0, 61, 184, 231,
+ 252, 121, 4, 140, 131, 184, 134, 87, 5, 224, 188, 7, 127, 76, 116,
+ 32, 235, 75, 102, 96, 126, 91, 77, 135, 26, 158, 25, 81, 251, 50,
+ 227, 218, 231, 84, 213, 47, 143, 200, 74, 94, 134, 199, 95, 138, 144,
+ 33, 7, 239, 36, 103, 229, 248, 84, 213, 47, 143, 24, 172, 136, 199,
+ 245, 53, 200, 23, 235, 1, 104, 164, 75, 81, 21, 253, 242, 136, 152,
+ 167, 117, 113, 76, 164, 170, 149, 169, 225, 177, 246, 149, 85, 209, 47,
+ 143, 216, 188, 191, 19, 206, 35, 160, 221, 181, 141, 171, 208, 166, 229,
+ 30, 167, 121, 248, 65, 251, 149, 151, 31, 180, 167, 214, 189, 181, 192,
+ 86, 229, 229, 39, 227, 225, 7, 237, 82, 222, 60, 2, 226, 4, 255,
+ 110, 65, 133, 64, 49, 196, 16, 31, 102, 58, 146, 245, 135, 202, 160,
+ 109, 37, 29, 106, 60, 149, 9, 63, 168, 204, 181, 143, 23, 235, 135,
+ 25, 89, 225, 255, 48, 102, 68, 132, 12, 25, 120, 39, 25, 43, 71,
+ 34, 214, 15, 51, 155, 54, 137, 79, 98, 61, 42, 17, 122, 64, 189,
+ 89, 25, 41, 21, 245, 195, 204, 3, 207, 35, 156, 30, 149, 202, 212,
+ 120, 88, 251, 82, 21, 245, 195, 76, 252, 137, 86, 24, 51, 208, 238,
+ 218, 124, 8, 218, 180, 188, 62, 41, 225, 225, 7, 237, 87, 94, 126,
+ 208, 158, 218, 248, 65, 91, 149, 123, 110, 192, 195, 15, 218, 165, 188,
+ 152, 129, 56, 193, 185, 183, 17, 248, 46, 85, 248, 49, 211, 137, 144,
+ 77, 129, 190, 114, 19, 97, 204, 192, 118, 120, 12, 48, 37, 214, 138,
+ 76, 244, 195, 204, 191, 189, 250, 98, 95, 131, 124, 241, 24, 0, 104,
+ 40, 83, 89, 35, 49, 214, 15, 51, 37, 155, 190, 227, 252, 158, 34,
+ 100, 64, 189, 145, 46, 33, 198, 250, 97, 166, 198, 254, 255, 112, 126,
+ 15, 249, 146, 152, 161, 144, 189, 140, 245, 195, 76, 147, 248, 48, 140,
+ 25, 104, 119, 109, 62, 4, 109, 170, 139, 15, 145, 53, 20, 104, 99,
+ 109, 252, 160, 253, 202, 203, 47, 132, 135, 31, 180, 85, 121, 249, 137,
+ 120, 248, 65, 187, 232, 202, 15, 231, 102, 70, 68, 141, 167, 29, 240,
+ 131, 10, 252, 152, 113, 36, 101, 131, 190, 146, 14, 194, 152, 129, 237,
+ 240, 24, 32, 34, 106, 60, 182, 250, 97, 134, 156, 175, 66, 190, 184,
+ 198, 3, 223, 201, 136, 141, 207, 182, 250, 97, 134, 156, 175, 66, 190,
+ 184, 198, 3, 104, 164, 75, 78, 123, 253, 48, 67, 206, 87, 37, 29,
+ 202, 212, 120, 88, 251, 250, 180, 215, 15, 51, 104, 190, 234, 194, 218,
+ 29, 249, 80, 142, 175, 88, 222, 114, 235, 138, 63, 230, 171, 223, 35,
+ 79, 82, 59, 102, 228, 185, 234, 20, 199, 9, 126, 149, 198, 137, 229,
+ 3, 91, 159, 251, 99, 222, 24, 15, 248, 85, 221, 87, 55, 91, 167,
+ 26, 79, 123, 142, 159, 221, 26, 177, 60, 226, 86, 190, 91, 217, 249,
+ 219, 217, 169, 39, 169, 61, 63, 90, 73, 117, 202, 29, 9, 126, 150,
+ 19, 196, 242, 255, 242, 199, 252, 49, 143, 122, 22, 113, 146, 138, 24,
+ 214, 95, 183, 243, 216, 237, 8, 204, 88, 3, 63, 48, 226, 199, 76,
+ 103, 178, 254, 0, 250, 42, 218, 234, 80, 227, 105, 71, 212, 70, 108,
+ 136, 243, 216, 109, 244, 59, 143, 173, 182, 94, 97, 67, 212, 120, 0,
+ 13, 101, 42, 125, 174, 181, 126, 231, 177, 213, 244, 32, 100, 64, 189,
+ 145, 46, 178, 86, 250, 157, 199, 86, 211, 163, 109, 153, 26, 15, 43,
+ 195, 167, 165, 126, 231, 177, 209, 90, 66, 17, 107, 119, 116, 6, 53,
+ 78, 203, 222, 193, 1, 58, 236, 29, 172, 232, 89, 66, 45, 202, 247,
+ 255, 99, 239, 224, 140, 60, 95, 250, 224, 3, 127, 222, 186, 192, 249,
+ 218, 113, 116, 141, 84, 132, 213, 36, 92, 79, 26, 84, 114, 157, 54,
+ 9, 203, 227, 173, 15, 173, 168, 37, 98, 184, 250, 147, 5, 166, 79,
+ 109, 177, 97, 132, 234, 82, 248, 60, 118, 107, 206, 6, 43, 181, 216,
+ 96, 164, 14, 54, 240, 0, 54, 72, 76, 77, 116, 41, 107, 131, 51,
+ 192, 6, 75, 210, 19, 121, 239, 37, 217, 10, 108, 176, 157, 57, 135,
+ 239, 91, 71, 241, 165, 43, 176, 65, 250, 254, 186, 188, 251, 0, 150,
+ 1, 27, 112, 181, 43, 11, 76, 67, 27, 8, 213, 180, 240, 121, 236,
+ 86, 156, 13, 70, 107, 177, 193, 248, 52, 97, 27, 56, 140, 40, 161,
+ 236, 141, 15, 101, 149, 181, 193, 141, 103, 190, 244, 114, 230, 16, 239,
+ 247, 216, 104, 22, 71, 159, 255, 144, 143, 247, 144, 162, 152, 232, 246,
+ 253, 58, 189, 252, 103, 43, 222, 154, 140, 4, 216, 128, 171, 123, 89,
+ 96, 58, 19, 216, 64, 168, 30, 134, 207, 99, 183, 228, 108, 176, 66,
+ 203, 62, 208, 80, 29, 246, 129, 30, 2, 126, 48, 220, 39, 230, 143,
+ 125, 160, 189, 238, 250, 210, 117, 164, 252, 123, 57, 71, 3, 63, 8,
+ 184, 51, 6, 239, 3, 69, 113, 188, 26, 240, 131, 162, 161, 253, 121,
+ 251, 198, 2, 27, 112, 53, 51, 11, 76, 67, 63, 16, 170, 165, 225,
+ 49, 192, 154, 56, 143, 221, 20, 196, 181, 118, 252, 99, 64, 87, 50,
+ 62, 129, 190, 138, 230, 58, 140, 1, 214, 68, 236, 108, 65, 156, 95,
+ 104, 174, 95, 222, 4, 235, 193, 56, 118, 182, 32, 198, 0, 64, 67,
+ 153, 202, 70, 205, 245, 203, 155, 96, 173, 22, 235, 65, 200, 128, 122,
+ 35, 93, 226, 155, 233, 151, 55, 193, 58, 42, 214, 163, 121, 153, 49,
+ 128, 149, 33, 105, 166, 95, 222, 4, 107, 156, 56, 151, 111, 206, 229,
+ 17, 241, 62, 187, 229, 92, 93, 93, 38, 69, 180, 220, 162, 34, 205,
+ 87, 111, 87, 59, 143, 77, 240, 147, 249, 238, 150, 115, 245, 109, 153,
+ 20, 209, 150, 128, 31, 95, 221, 91, 237, 60, 118, 51, 142, 31, 53,
+ 110, 183, 156, 171, 51, 203, 164, 136, 126, 89, 171, 34, 205, 87, 127,
+ 86, 171, 31, 16, 252, 82, 128, 190, 92, 189, 87, 38, 69, 116, 18,
+ 120, 63, 190, 58, 176, 218, 121, 236, 166, 68, 77, 43, 7, 248, 129,
+ 53, 63, 102, 186, 17, 223, 67, 2, 250, 74, 62, 232, 112, 30, 187,
+ 41, 49, 15, 144, 16, 251, 150, 100, 122, 238, 91, 90, 83, 11, 207,
+ 53, 32, 95, 44, 3, 240, 133, 50, 149, 243, 153, 34, 253, 48, 179,
+ 181, 225, 99, 78, 134, 140, 152, 107, 0, 189, 145, 46, 84, 145, 126,
+ 152, 241, 120, 189, 158, 187, 251, 233, 67, 153, 185, 6, 107, 35, 234,
+ 134, 126, 152, 153, 229, 74, 236, 91, 146, 241, 236, 91, 2, 54, 45,
+ 239, 252, 23, 218, 88, 27, 63, 104, 191, 242, 242, 163, 120, 248, 65,
+ 91, 149, 155, 223, 13, 237, 252, 160, 93, 202, 59, 63, 135, 56, 65,
+ 152, 9, 145, 4, 137, 19, 155, 242, 98, 70, 185, 217, 15, 215, 91,
+ 64, 95, 74, 161, 67, 77, 43, 135, 168, 55, 61, 38, 206, 99, 167,
+ 234, 135, 153, 108, 199, 5, 220, 218, 201, 99, 162, 222, 4, 222, 9,
+ 202, 84, 142, 101, 169, 250, 97, 230, 212, 241, 177, 120, 12, 128, 124,
+ 177, 30, 80, 6, 210, 37, 85, 207, 113, 102, 103, 33, 167, 135, 162,
+ 204, 218, 9, 107, 223, 248, 20, 253, 48, 51, 33, 117, 56, 119, 30,
+ 59, 85, 187, 15, 65, 155, 150, 183, 206, 26, 194, 195, 15, 218, 175,
+ 188, 252, 68, 60, 252, 160, 173, 202, 203, 15, 218, 78, 235, 189, 36,
+ 192, 46, 229, 173, 3, 67, 156, 224, 123, 57, 69, 65, 98, 121, 14,
+ 63, 102, 200, 61, 24, 137, 118, 160, 175, 81, 144, 240, 190, 37, 208,
+ 14, 255, 86, 178, 57, 215, 222, 211, 55, 72, 175, 61, 24, 100, 110,
+ 6, 249, 226, 223, 124, 6, 52, 148, 169, 204, 109, 124, 130, 244, 218,
+ 131, 65, 230, 102, 118, 132, 12, 168, 55, 210, 69, 70, 7, 233, 181,
+ 7, 131, 204, 205, 32, 95, 181, 223, 124, 102, 101, 196, 83, 65, 122,
+ 237, 193, 64, 185, 89, 58, 107, 119, 188, 230, 223, 35, 214, 77, 83,
+ 110, 86, 117, 207, 117, 169, 208, 94, 8, 207, 239, 245, 168, 115, 174,
+ 173, 88, 31, 166, 168, 21, 107, 157, 148, 244, 209, 235, 155, 169, 6,
+ 99, 103, 240, 230, 97, 45, 219, 63, 163, 56, 254, 230, 56, 15, 28,
+ 20, 212, 145, 214, 117, 15, 6, 252, 182, 72, 15, 151, 150, 177, 110,
+ 154, 114, 194, 46, 7, 175, 75, 133, 246, 66, 28, 104, 96, 73, 37,
+ 44, 104, 138, 245, 184, 62, 182, 161, 146, 110, 148, 179, 153, 170, 243,
+ 169, 26, 175, 30, 73, 29, 158, 81, 28, 127, 115, 156, 127, 46, 11,
+ 238, 72, 235, 186, 7, 3, 250, 15, 210, 99, 238, 224, 88, 55, 77,
+ 185, 104, 215, 127, 175, 75, 133, 246, 66, 108, 127, 81, 143, 154, 119,
+ 195, 14, 235, 113, 184, 66, 47, 37, 29, 7, 190, 135, 113, 98, 44,
+ 175, 30, 63, 108, 158, 81, 28, 127, 115, 156, 247, 158, 12, 236, 72,
+ 235, 186, 7, 3, 250, 40, 210, 163, 158, 117, 172, 155, 166, 28, 56,
+ 44, 245, 186, 84, 104, 47, 132, 125, 35, 75, 202, 51, 18, 253, 78,
+ 5, 69, 197, 175, 85, 253, 222, 69, 51, 240, 61, 34, 111, 133, 240,
+ 230, 207, 167, 192, 247, 224, 248, 155, 227, 124, 123, 61, 248, 30, 186,
+ 238, 193, 128, 113, 16, 197, 196, 20, 81, 176, 24, 198, 72, 190, 152,
+ 72, 238, 193, 144, 229, 4, 137, 139, 140, 131, 133, 215, 147, 115, 136,
+ 152, 168, 224, 248, 203, 52, 244, 45, 87, 157, 63, 221, 7, 231, 197,
+ 144, 47, 142, 137, 128, 134, 50, 149, 86, 209, 73, 134, 246, 60, 98,
+ 233, 254, 48, 44, 195, 142, 144, 1, 245, 70, 186, 36, 26, 5, 235,
+ 149, 71, 28, 9, 251, 136, 215, 18, 32, 95, 181, 152, 200, 202, 176,
+ 211, 73, 134, 246, 60, 226, 248, 16, 110, 47, 39, 180, 187, 182, 113,
+ 21, 218, 180, 188, 227, 180, 57, 15, 63, 104, 191, 242, 242, 131, 246,
+ 212, 198, 15, 218, 170, 188, 252, 236, 120, 248, 65, 187, 148, 55, 143,
+ 128, 56, 193, 231, 108, 250, 4, 139, 33, 134, 52, 98, 38, 116, 82,
+ 192, 68, 118, 51, 39, 254, 158, 160, 111, 226, 0, 97, 204, 192, 118,
+ 220, 249, 20, 174, 125, 74, 255, 96, 189, 242, 8, 133, 127, 50, 113,
+ 62, 133, 147, 33, 1, 52, 148, 169, 204, 93, 251, 5, 235, 149, 71,
+ 4, 56, 191, 197, 152, 145, 16, 50, 160, 222, 72, 151, 156, 190, 193,
+ 122, 229, 17, 15, 137, 181, 49, 200, 87, 237, 183, 87, 88, 25, 138,
+ 62, 193, 122, 229, 17, 94, 196, 94, 78, 104, 119, 114, 47, 39, 180,
+ 35, 242, 27, 68, 123, 254, 189, 128, 230, 158, 107, 142, 187, 247, 82,
+ 205, 152, 93, 209, 203, 216, 54, 253, 24, 212, 190, 214, 155, 241, 76,
+ 251, 211, 71, 120, 251, 194, 189, 156, 159, 198, 162, 122, 244, 74, 76,
+ 195, 189, 156, 220, 115, 254, 113, 11, 126, 91, 82, 15, 248, 173, 144,
+ 30, 136, 246, 2, 122, 112, 207, 53, 243, 83, 0, 61, 250, 159, 173,
+ 131, 239, 13, 69, 237, 173, 128, 30, 251, 7, 222, 18, 220, 147, 122,
+ 112, 80, 63, 87, 164, 7, 162, 161, 30, 220, 115, 126, 61, 160, 255,
+ 32, 61, 190, 0, 61, 30, 18, 123, 57, 17, 125, 22, 232, 241, 80,
+ 160, 118, 253, 46, 205, 140, 105, 117, 219, 30, 239, 129, 68, 237, 135,
+ 190, 29, 207, 56, 154, 63, 227, 205, 105, 170, 44, 141, 98, 190, 92,
+ 172, 128, 247, 164, 34, 122, 25, 208, 131, 123, 206, 175, 7, 244, 81,
+ 242, 123, 120, 17, 123, 57, 17, 61, 22, 232, 225, 37, 80, 127, 46,
+ 1, 223, 99, 78, 170, 7, 214, 3, 181, 119, 2, 223, 227, 68, 170,
+ 240, 94, 206, 7, 89, 220, 94, 78, 68, 195, 189, 156, 220, 115, 254,
+ 60, 2, 198, 65, 124, 142, 202, 29, 140, 141, 162, 96, 254, 152, 232,
+ 64, 156, 241, 233, 29, 44, 246, 233, 37, 28, 19, 97, 59, 92, 147,
+ 238, 205, 181, 47, 242, 208, 47, 143, 232, 221, 105, 30, 254, 173, 115,
+ 31, 66, 134, 2, 188, 147, 130, 149, 35, 243, 208, 47, 143, 120, 92,
+ 181, 29, 222, 203, 9, 249, 98, 61, 0, 141, 116, 49, 247, 208, 47,
+ 143, 88, 166, 216, 197, 213, 214, 123, 169, 199, 68, 5, 107, 223, 68,
+ 119, 253, 242, 136, 245, 49, 83, 184, 115, 84, 30, 218, 199, 85, 104,
+ 211, 242, 142, 211, 50, 30, 126, 208, 126, 229, 206, 75, 120, 248, 65,
+ 91, 149, 59, 47, 113, 215, 206, 15, 218, 165, 188, 121, 4, 196, 9,
+ 222, 47, 64, 3, 63, 232, 35, 128, 153, 142, 68, 61, 162, 103, 176,
+ 88, 210, 67, 24, 51, 176, 29, 30, 227, 123, 18, 121, 68, 119, 253,
+ 48, 115, 183, 105, 12, 246, 103, 9, 33, 35, 17, 188, 83, 34, 43,
+ 135, 234, 174, 31, 102, 206, 116, 120, 135, 253, 25, 242, 197, 122, 0,
+ 26, 233, 146, 195, 232, 135, 25, 199, 119, 151, 185, 115, 84, 61, 212,
+ 49, 147, 200, 218, 215, 135, 209, 15, 51, 89, 199, 164, 220, 30, 155,
+ 238, 218, 125, 8, 218, 180, 188, 62, 73, 241, 240, 131, 246, 43, 47,
+ 63, 104, 79, 109, 252, 160, 173, 202, 203, 207, 135, 135, 31, 180, 75,
+ 121, 49, 3, 113, 130, 115, 111, 87, 224, 7, 238, 2, 152, 233, 68,
+ 172, 253, 129, 190, 137, 82, 97, 204, 192, 118, 120, 12, 160, 184, 246,
+ 118, 82, 253, 48, 19, 186, 182, 18, 55, 6, 80, 196, 24, 0, 104,
+ 40, 83, 153, 123, 187, 233, 135, 153, 243, 117, 55, 114, 231, 168, 8,
+ 25, 80, 111, 164, 139, 167, 155, 126, 152, 73, 108, 31, 200, 205, 33,
+ 164, 234, 152, 241, 97, 101, 40, 92, 245, 195, 140, 223, 26, 226, 238,
+ 94, 169, 118, 31, 130, 54, 45, 239, 90, 12, 180, 177, 214, 251, 169,
+ 129, 253, 202, 203, 207, 147, 135, 31, 180, 85, 121, 249, 65, 219, 105,
+ 227, 7, 237, 82, 222, 181, 34, 136, 19, 156, 155, 117, 3, 126, 64,
+ 11, 96, 198, 145, 200, 27, 92, 128, 111, 58, 235, 144, 155, 185, 16,
+ 254, 236, 66, 228, 102, 78, 250, 97, 134, 156, 175, 250, 16, 50, 20,
+ 224, 157, 20, 172, 28, 153, 147, 126, 152, 33, 231, 171, 144, 47, 214,
+ 3, 208, 72, 23, 115, 39, 253, 48, 67, 206, 87, 125, 156, 203, 228,
+ 102, 172, 125, 19, 187, 233, 135, 25, 47, 98, 47, 39, 180, 59, 185,
+ 151, 211, 98, 235, 138, 63, 230, 171, 112, 47, 103, 236, 140, 188, 44,
+ 157, 114, 51, 130, 31, 220, 203, 185, 164, 245, 185, 63, 230, 141, 112,
+ 47, 103, 215, 125, 117, 117, 218, 147, 96, 78, 240, 131, 123, 57, 195,
+ 137, 189, 156, 15, 137, 189, 156, 73, 58, 238, 229, 132, 182, 35, 247,
+ 114, 222, 36, 246, 114, 122, 17, 123, 57, 195, 117, 220, 203, 9, 113,
+ 130, 49, 227, 0, 252, 192, 85, 0, 51, 157, 137, 188, 161, 43, 24,
+ 151, 186, 232, 144, 155, 117, 37, 114, 154, 174, 68, 251, 206, 193, 6,
+ 219, 203, 41, 33, 100, 36, 130, 119, 74, 100, 229, 40, 58, 5, 27,
+ 108, 47, 39, 228, 139, 245, 0, 52, 210, 69, 222, 49, 216, 96, 123,
+ 57, 37, 93, 202, 228, 102, 172, 125, 19, 29, 130, 13, 182, 151, 19,
+ 218, 221, 80, 123, 57, 39, 229, 251, 255, 177, 143, 17, 238, 229, 92,
+ 245, 192, 159, 119, 31, 35, 220, 203, 89, 154, 178, 2, 239, 99, 68,
+ 88, 133, 123, 57, 95, 204, 202, 227, 173, 241, 192, 189, 156, 92, 253,
+ 201, 2, 211, 112, 255, 154, 80, 93, 10, 217, 0, 250, 133, 161, 246,
+ 114, 94, 79, 77, 252, 99, 63, 43, 220, 203, 153, 145, 158, 200, 187,
+ 198, 2, 247, 114, 222, 103, 206, 225, 253, 172, 40, 190, 192, 189, 156,
+ 138, 253, 117, 121, 235, 42, 112, 47, 39, 87, 187, 178, 192, 52, 180,
+ 129, 80, 77, 11, 239, 233, 237, 24, 108, 176, 189, 156, 29, 180, 236,
+ 229, 92, 166, 195, 94, 206, 115, 196, 94, 206, 135, 196, 94, 206, 101,
+ 58, 236, 229, 124, 72, 236, 229, 124, 72, 236, 229, 124, 168, 227, 94,
+ 78, 136, 171, 255, 31, 246, 114, 250, 19, 123, 57, 189, 136, 189, 156,
+ 239, 116, 216, 203, 233, 69, 236, 229, 244, 34, 246, 114, 122, 233, 184,
+ 151, 19, 198, 125, 124, 127, 251, 104, 16, 215, 186, 9, 140, 1, 93,
+ 137, 248, 100, 15, 98, 237, 88, 29, 198, 0, 123, 34, 118, 218, 19,
+ 115, 13, 59, 253, 242, 38, 88, 15, 198, 177, 147, 144, 145, 8, 248,
+ 38, 178, 114, 236, 198, 234, 151, 55, 193, 90, 45, 183, 239, 129, 144,
+ 1, 248, 34, 93, 228, 99, 244, 203, 155, 96, 29, 149, 251, 45, 146,
+ 50, 99, 0, 107, 35, 207, 49, 250, 229, 77, 176, 198, 137, 231, 26,
+ 118, 193, 196, 125, 235, 187, 229, 92, 93, 93, 38, 69, 244, 69, 139,
+ 138, 52, 95, 189, 93, 109, 237, 105, 108, 176, 218, 222, 80, 174, 190,
+ 45, 147, 34, 26, 238, 13, 229, 171, 123, 171, 221, 207, 53, 134, 227,
+ 103, 238, 183, 91, 206, 213, 153, 101, 82, 68, 167, 212, 174, 72, 243,
+ 213, 159, 213, 238, 231, 34, 248, 193, 189, 156, 92, 189, 87, 38, 69,
+ 52, 220, 203, 201, 87, 7, 86, 187, 191, 125, 52, 135, 153, 248, 225,
+ 192, 15, 28, 4, 48, 211, 141, 184, 91, 28, 244, 205, 25, 41, 140,
+ 25, 216, 14, 223, 123, 62, 138, 107, 239, 51, 82, 63, 204, 148, 100,
+ 54, 200, 226, 126, 139, 36, 152, 248, 45, 146, 96, 49, 148, 169, 156,
+ 207, 140, 208, 15, 51, 197, 15, 189, 178, 185, 223, 34, 33, 244, 0,
+ 239, 142, 116, 145, 141, 208, 15, 51, 84, 158, 59, 167, 199, 72, 117,
+ 204, 120, 178, 50, 204, 71, 232, 135, 153, 171, 47, 231, 112, 191, 125,
+ 59, 82, 251, 124, 21, 218, 180, 188, 243, 95, 104, 99, 109, 252, 160,
+ 253, 202, 203, 79, 198, 195, 15, 218, 170, 188, 252, 204, 121, 248, 65,
+ 187, 148, 119, 126, 14, 113, 130, 127, 143, 202, 27, 248, 193, 104, 126,
+ 204, 192, 205, 156, 248, 183, 111, 65, 223, 248, 161, 194, 152, 129, 237,
+ 240, 111, 120, 12, 227, 218, 75, 134, 234, 135, 153, 230, 138, 219, 89,
+ 220, 111, 145, 4, 19, 191, 69, 2, 116, 26, 174, 226, 157, 50, 68,
+ 63, 204, 156, 43, 110, 146, 197, 253, 22, 9, 161, 7, 120, 119, 164,
+ 11, 53, 68, 63, 204, 212, 59, 158, 229, 198, 253, 22, 137, 58, 102,
+ 204, 89, 25, 57, 222, 250, 97, 102, 67, 149, 96, 140, 25, 104, 119,
+ 109, 62, 4, 109, 90, 222, 58, 43, 180, 177, 54, 126, 208, 126, 229,
+ 174, 43, 243, 240, 131, 182, 42, 119, 93, 217, 91, 59, 63, 104, 151,
+ 242, 214, 129, 33, 78, 240, 190, 165, 8, 224, 7, 195, 5, 48, 67,
+ 236, 193, 200, 241, 2, 241, 124, 176, 48, 102, 96, 59, 60, 6, 120,
+ 17, 227, 204, 32, 253, 246, 96, 144, 185, 153, 39, 33, 35, 7, 188,
+ 83, 14, 43, 39, 228, 47, 253, 246, 96, 144, 185, 25, 228, 203, 253,
+ 22, 9, 208, 157, 149, 33, 243, 212, 111, 15, 6, 153, 155, 121, 14,
+ 86, 199, 76, 14, 107, 95, 187, 72, 253, 246, 96, 160, 220, 44, 157,
+ 181, 59, 90, 43, 111, 238, 24, 235, 166, 41, 55, 171, 149, 121, 93,
+ 42, 180, 23, 226, 98, 85, 75, 74, 116, 106, 4, 59, 142, 80, 84,
+ 230, 165, 137, 74, 250, 197, 245, 205, 84, 175, 128, 37, 188, 103, 145,
+ 131, 109, 159, 81, 28, 127, 115, 156, 7, 126, 8, 234, 72, 235, 186,
+ 7, 3, 126, 91, 164, 199, 246, 14, 177, 110, 154, 114, 66, 199, 172,
+ 235, 82, 161, 189, 16, 29, 106, 89, 82, 135, 110, 254, 204, 68, 122,
+ 84, 114, 106, 167, 148, 95, 12, 244, 248, 17, 190, 153, 55, 63, 85,
+ 0, 61, 56, 254, 230, 56, 255, 108, 27, 220, 145, 214, 117, 15, 6,
+ 244, 31, 164, 71, 146, 67, 172, 155, 166, 92, 116, 45, 248, 30, 66,
+ 123, 33, 246, 86, 183, 164, 106, 143, 246, 195, 123, 57, 127, 14, 155,
+ 170, 164, 223, 3, 61, 30, 55, 90, 198, 155, 199, 38, 2, 61, 56,
+ 254, 230, 56, 239, 173, 10, 244, 208, 117, 15, 6, 244, 81, 164, 135,
+ 168, 101, 172, 155, 166, 28, 184, 231, 201, 235, 82, 161, 189, 16, 254,
+ 141, 44, 169, 102, 191, 67, 241, 94, 206, 150, 231, 166, 41, 233, 198,
+ 57, 155, 169, 201, 245, 166, 240, 230, 207, 251, 59, 60, 163, 56, 254,
+ 230, 56, 223, 94, 1, 244, 208, 117, 15, 6, 140, 131, 248, 76, 200,
+ 92, 128, 115, 111, 129, 152, 72, 236, 193, 176, 3, 125, 83, 230, 235,
+ 176, 47, 45, 130, 195, 121, 74, 56, 215, 158, 154, 175, 95, 30, 177,
+ 33, 203, 18, 231, 197, 144, 47, 222, 203, 9, 104, 40, 83, 25, 83,
+ 230, 233, 151, 71, 188, 173, 181, 19, 199, 93, 59, 66, 6, 212, 27,
+ 233, 226, 51, 79, 191, 60, 98, 113, 238, 75, 44, 3, 242, 85, 219,
+ 203, 201, 202, 40, 154, 171, 95, 30, 225, 182, 125, 46, 206, 35, 160,
+ 221, 181, 142, 171, 192, 166, 229, 30, 167, 231, 105, 231, 7, 237, 87,
+ 238, 245, 95, 30, 126, 208, 86, 229, 229, 7, 109, 167, 141, 31, 180,
+ 75, 121, 243, 8, 136, 19, 140, 153, 233, 192, 15, 34, 52, 96, 198,
+ 127, 194, 228, 153, 196, 205, 156, 72, 118, 209, 156, 96, 113, 200, 236,
+ 96, 177, 191, 127, 75, 185, 191, 127, 51, 230, 68, 252, 130, 236, 206,
+ 61, 227, 165, 101, 49, 3, 219, 33, 63, 8, 153, 195, 241, 247, 12,
+ 211, 228, 7, 240, 221, 45, 152, 221, 173, 26, 102, 190, 19, 253, 112,
+ 229, 171, 243, 127, 165, 151, 225, 49, 62, 132, 144, 81, 4, 222, 169,
+ 136, 149, 99, 55, 75, 187, 12, 143, 234, 21, 50, 31, 205, 173, 237,
+ 198, 87, 231, 95, 253, 239, 18, 44, 3, 242, 197, 122, 0, 26, 233,
+ 98, 62, 83, 187, 140, 47, 61, 46, 103, 30, 107, 83, 81, 202, 87,
+ 231, 191, 120, 115, 50, 206, 35, 66, 102, 171, 99, 6, 202, 84, 254,
+ 59, 157, 71, 198, 73, 47, 233, 248, 16, 153, 148, 175, 206, 223, 255,
+ 74, 24, 174, 243, 67, 187, 147, 191, 27, 14, 237, 136, 248, 33, 90,
+ 121, 47, 39, 126, 46, 18, 173, 17, 181, 17, 237, 22, 217, 136, 246,
+ 138, 218, 225, 184, 251, 32, 213, 140, 9, 111, 126, 130, 187, 151, 147,
+ 109, 111, 246, 121, 4, 211, 123, 113, 36, 239, 24, 250, 181, 234, 100,
+ 38, 236, 107, 7, 182, 205, 124, 38, 231, 157, 137, 146, 54, 41, 137,
+ 102, 206, 183, 190, 198, 91, 31, 47, 53, 89, 194, 200, 54, 206, 195,
+ 119, 72, 34, 58, 228, 197, 26, 226, 57, 127, 125, 23, 250, 5, 105,
+ 3, 248, 157, 145, 13, 16, 61, 24, 216, 128, 123, 174, 217, 6, 143,
+ 224, 126, 214, 12, 57, 182, 1, 106, 95, 29, 216, 64, 252, 112, 182,
+ 160, 13, 58, 15, 107, 140, 109, 224, 61, 249, 63, 23, 100, 131, 237,
+ 212, 10, 65, 27, 68, 244, 219, 234, 140, 108, 128, 232, 105, 192, 6,
+ 220, 115, 126, 27, 64, 191, 69, 54, 248, 14, 108, 0, 253, 16, 217,
+ 0, 209, 211, 129, 13, 184, 231, 208, 6, 118, 192, 6, 221, 128, 13,
+ 156, 48, 191, 246, 105, 102, 140, 171, 243, 30, 188, 23, 22, 181, 239,
+ 1, 108, 32, 218, 235, 205, 155, 131, 124, 6, 54, 24, 48, 214, 196,
+ 13, 217, 224, 242, 195, 93, 74, 123, 252, 254, 25, 205, 120, 187, 121,
+ 184, 10, 217, 192, 204, 99, 141, 19, 178, 1, 162, 161, 13, 184, 231,
+ 252, 54, 128, 184, 34, 253, 0, 226, 4, 217, 0, 209, 127, 1, 27,
+ 112, 207, 161, 13, 194, 128, 13, 102, 2, 27, 204, 192, 252, 242, 129,
+ 31, 228, 62, 8, 197, 251, 79, 81, 251, 170, 192, 6, 213, 139, 103,
+ 243, 230, 47, 95, 128, 13, 58, 204, 68, 251, 240, 231, 51, 61, 62,
+ 169, 206, 195, 66, 63, 40, 253, 16, 41, 21, 178, 193, 236, 111, 145,
+ 120, 239, 42, 162, 33, 22, 184, 231, 252, 121, 19, 140, 251, 248, 252,
+ 249, 20, 16, 215, 230, 10, 141, 1, 14, 92, 124, 10, 5, 237, 167,
+ 233, 48, 6, 132, 18, 177, 51, 148, 136, 101, 211, 116, 29, 3, 180,
+ 220, 169, 8, 240, 142, 99, 39, 33, 163, 8, 240, 45, 98, 229, 196,
+ 135, 232, 58, 6, 104, 150, 1, 241, 132, 245, 152, 70, 232, 1, 104,
+ 164, 75, 202, 84, 93, 199, 0, 205, 50, 160, 191, 98, 61, 166, 149,
+ 25, 3, 88, 27, 81, 83, 117, 29, 3, 52, 203, 128, 254, 128, 207,
+ 170, 78, 227, 242, 8, 179, 119, 127, 203, 185, 184, 41, 147, 34, 250,
+ 16, 149, 73, 241, 197, 83, 181, 179, 170, 33, 234, 252, 184, 24, 36,
+ 147, 34, 58, 13, 240, 227, 139, 77, 106, 245, 156, 169, 234, 252, 56,
+ 60, 203, 164, 136, 134, 252, 248, 112, 174, 86, 207, 41, 195, 143, 195,
+ 134, 76, 138, 104, 168, 47, 31, 102, 212, 238, 84, 156, 194, 97, 70,
+ 22, 8, 252, 96, 186, 16, 102, 58, 114, 231, 207, 65, 95, 121, 176,
+ 48, 102, 96, 59, 124, 54, 124, 50, 145, 55, 5, 27, 14, 51, 144,
+ 47, 62, 27, 14, 104, 40, 83, 185, 63, 34, 200, 112, 152, 161, 8,
+ 25, 80, 111, 164, 75, 72, 144, 225, 48, 3, 249, 170, 221, 169, 136,
+ 236, 21, 100, 56, 204, 64, 187, 35, 31, 146, 139, 78, 158, 212, 132,
+ 25, 201, 187, 249, 58, 99, 6, 218, 152, 228, 167, 9, 51, 144, 159,
+ 174, 152, 9, 41, 195, 79, 19, 102, 40, 192, 79, 87, 204, 136, 202,
+ 240, 211, 132, 25, 17, 224, 167, 43, 102, 32, 78, 240, 239, 60, 250,
+ 3, 63, 152, 34, 132, 153, 78, 220, 247, 0, 125, 101, 19, 133, 49,
+ 3, 219, 225, 59, 21, 39, 113, 252, 205, 39, 26, 14, 51, 144, 47,
+ 246, 53, 40, 35, 144, 221, 139, 19, 96, 56, 204, 136, 8, 25, 80,
+ 111, 164, 139, 93, 128, 225, 48, 3, 249, 170, 253, 206, 35, 43, 67,
+ 238, 111, 56, 204, 64, 187, 235, 139, 25, 114, 237, 9, 218, 88, 95,
+ 204, 144, 252, 236, 2, 244, 199, 12, 201, 15, 218, 78, 95, 204, 144,
+ 185, 25, 196, 9, 190, 35, 222, 15, 248, 65, 160, 16, 102, 28, 185,
+ 59, 56, 38, 128, 120, 62, 94, 24, 51, 176, 29, 30, 3, 38, 112,
+ 252, 115, 198, 233, 135, 25, 114, 126, 78, 17, 50, 228, 224, 157, 228,
+ 172, 28, 159, 113, 250, 97, 134, 156, 159, 67, 190, 88, 15, 64, 35,
+ 93, 138, 252, 244, 195, 12, 57, 63, 167, 198, 171, 99, 6, 202, 84,
+ 114, 243, 211, 15, 51, 104, 126, 238, 194, 218, 29, 255, 94, 209, 88,
+ 177, 124, 212, 215, 230, 127, 204, 207, 115, 228, 215, 165, 73, 71, 214,
+ 107, 157, 155, 170, 213, 160, 8, 126, 121, 99, 196, 242, 129, 30, 213,
+ 255, 152, 235, 74, 78, 93, 151, 118, 251, 172, 27, 63, 104, 79, 188,
+ 183, 118, 128, 88, 158, 22, 93, 226, 90, 118, 222, 40, 187, 112, 93,
+ 186, 188, 118, 180, 214, 121, 163, 218, 222, 90, 130, 31, 5, 222, 207,
+ 57, 42, 242, 143, 57, 152, 2, 188, 95, 24, 53, 75, 235, 28, 76,
+ 237, 142, 120, 63, 98, 15, 70, 77, 224, 7, 254, 66, 152, 233, 204,
+ 157, 233, 247, 13, 22, 123, 54, 18, 198, 12, 108, 135, 253, 192, 151,
+ 227, 31, 111, 165, 43, 102, 106, 104, 244, 131, 149, 177, 18, 28, 159,
+ 69, 132, 12, 153, 15, 192, 62, 43, 39, 167, 142, 174, 152, 209, 44,
+ 163, 105, 159, 100, 110, 12, 240, 33, 214, 198, 128, 222, 72, 23, 243,
+ 90, 186, 98, 70, 179, 140, 134, 146, 71, 120, 44, 131, 124, 213, 238,
+ 136, 247, 97, 177, 223, 78, 87, 204, 104, 150, 17, 248, 75, 53, 206,
+ 44, 48, 81, 217, 221, 90, 217, 82, 245, 27, 220, 208, 142, 136, 31,
+ 162, 123, 165, 196, 80, 220, 115, 240, 127, 170, 137, 68, 173, 69, 45,
+ 69, 206, 224, 15, 197, 221, 103, 3, 75, 168, 154, 45, 27, 226, 125,
+ 155, 237, 219, 183, 81, 182, 31, 150, 231, 75, 167, 244, 179, 199, 99,
+ 212, 96, 145, 181, 40, 0, 244, 155, 71, 244, 253, 89, 59, 142, 94,
+ 48, 216, 129, 187, 135, 148, 197, 170, 105, 201, 62, 250, 150, 251, 58,
+ 222, 58, 82, 169, 201, 33, 218, 249, 202, 14, 182, 77, 6, 221, 100,
+ 208, 126, 182, 30, 150, 73, 27, 221, 61, 138, 251, 166, 128, 62, 233,
+ 162, 246, 162, 12, 240, 135, 207, 190, 154, 156, 161, 205, 162, 206, 178,
+ 109, 46, 210, 131, 91, 252, 79, 73, 27, 69, 92, 166, 63, 127, 185,
+ 137, 251, 102, 129, 62, 167, 68, 182, 162, 115, 224, 15, 245, 253, 21,
+ 117, 141, 190, 58, 0, 221, 145, 154, 67, 239, 217, 125, 95, 73, 27,
+ 71, 220, 164, 23, 138, 30, 243, 214, 95, 126, 71, 229, 210, 39, 115,
+ 10, 216, 54, 121, 244, 251, 137, 133, 108, 223, 123, 116, 83, 163, 247,
+ 184, 239, 101, 81, 7, 209, 255, 192, 95, 14, 248, 195, 250, 70, 61,
+ 160, 235, 0, 44, 168, 90, 40, 104, 227, 89, 95, 149, 180, 121, 196,
+ 19, 250, 201, 235, 79, 184, 239, 77, 16, 55, 110, 129, 126, 183, 137,
+ 190, 38, 209, 5, 116, 114, 255, 103, 108, 155, 151, 244, 167, 181, 119,
+ 85, 182, 138, 40, 164, 37, 247, 255, 135, 251, 230, 129, 62, 247, 128,
+ 174, 247, 9, 125, 139, 163, 222, 210, 75, 219, 160, 122, 93, 17, 93,
+ 241, 247, 97, 37, 93, 26, 254, 145, 254, 231, 214, 94, 220, 247, 17,
+ 176, 213, 99, 240, 247, 148, 248, 70, 197, 81, 95, 232, 216, 103, 137,
+ 108, 155, 239, 116, 241, 240, 4, 182, 111, 49, 189, 228, 250, 42, 220,
+ 183, 0, 244, 121, 1, 254, 94, 129, 111, 140, 250, 254, 136, 42, 165,
+ 15, 245, 194, 181, 68, 102, 217, 213, 88, 21, 45, 53, 98, 2, 61,
+ 23, 224, 190, 111, 64, 159, 119, 224, 175, 136, 232, 251, 91, 110, 204,
+ 220, 190, 182, 136, 109, 99, 202, 220, 14, 88, 204, 126, 223, 138, 204,
+ 237, 205, 92, 125, 242, 35, 232, 243, 25, 252, 125, 39, 250, 254, 138,
+ 170, 204, 84, 183, 64, 109, 170, 49, 237, 130, 150, 176, 223, 168, 58,
+ 211, 231, 52, 215, 183, 20, 246, 49, 178, 17, 85, 48, 34, 251, 214,
+ 100, 184, 26, 176, 5, 166, 51, 62, 213, 101, 200, 218, 112, 21, 208,
+ 167, 58, 248, 171, 69, 244, 69, 184, 132, 177, 10, 225, 18, 238, 41,
+ 135, 177, 7, 225, 18, 209, 238, 0, 151, 220, 115, 205, 184, 84, 0,
+ 92, 238, 23, 87, 192, 184, 244, 15, 59, 164, 108, 63, 28, 224, 50,
+ 248, 57, 63, 46, 107, 90, 196, 209, 59, 119, 55, 196, 184, 68, 99,
+ 94, 21, 128, 203, 106, 11, 248, 113, 249, 11, 224, 242, 249, 200, 61,
+ 24, 151, 155, 163, 50, 48, 46, 7, 239, 190, 160, 1, 151, 132, 175,
+ 1, 92, 86, 140, 191, 135, 113, 105, 122, 237, 165, 138, 6, 184, 156,
+ 255, 250, 61, 129, 75, 91, 128, 203, 14, 0, 151, 36, 62, 174, 209,
+ 183, 107, 124, 199, 184, 28, 94, 90, 202, 126, 243, 155, 116, 208, 23,
+ 35, 222, 154, 170, 81, 116, 46, 61, 98, 141, 169, 27, 194, 229, 233,
+ 87, 98, 37, 109, 10, 112, 105, 79, 85, 117, 227, 112, 105, 7, 112,
+ 105, 7, 112, 105, 79, 248, 248, 3, 186, 210, 236, 218, 110, 8, 151,
+ 191, 247, 212, 84, 210, 205, 33, 46, 243, 107, 184, 113, 184, 180, 7,
+ 184, 180, 7, 184, 228, 250, 26, 3, 92, 230, 47, 68, 181, 220, 151,
+ 116, 71, 107, 213, 251, 255, 12, 47, 164, 79, 185, 189, 34, 112, 105,
+ 7, 112, 217, 1, 224, 146, 211, 183, 0, 224, 114, 158, 243, 45, 140,
+ 75, 207, 190, 215, 84, 247, 173, 3, 92, 46, 30, 121, 158, 192, 165,
+ 45, 192, 165, 45, 192, 165, 45, 97, 171, 47, 116, 103, 219, 203, 24,
+ 151, 157, 141, 174, 178, 62, 94, 76, 59, 222, 186, 70, 224, 210, 22,
+ 224, 210, 22, 224, 146, 236, 91, 74, 111, 250, 245, 31, 198, 229, 158,
+ 41, 42, 218, 24, 224, 50, 227, 225, 77, 2, 151, 182, 0, 151, 182,
+ 0, 151, 92, 95, 209, 41, 99, 198, 102, 197, 85, 140, 203, 71, 54,
+ 23, 216, 56, 84, 145, 233, 52, 41, 147, 192, 165, 45, 192, 165, 45,
+ 192, 37, 17, 179, 1, 46, 99, 20, 123, 48, 46, 59, 157, 221, 166,
+ 170, 123, 135, 87, 103, 138, 119, 175, 35, 112, 9, 124, 209, 168, 29,
+ 192, 101, 59, 53, 92, 114, 235, 18, 22, 152, 134, 184, 36, 215, 43,
+ 248, 112, 9, 199, 119, 132, 203, 165, 0, 151, 112, 188, 70, 184, 68,
+ 244, 82, 128, 75, 238, 185, 102, 92, 54, 255, 171, 132, 170, 215, 245,
+ 50, 198, 229, 95, 45, 95, 43, 219, 223, 190, 231, 75, 47, 121, 215,
+ 196, 149, 195, 101, 11, 22, 151, 109, 112, 223, 39, 117, 226, 232, 85,
+ 247, 141, 240, 30, 127, 148, 59, 206, 5, 184, 52, 63, 26, 197, 187,
+ 230, 80, 223, 244, 16, 221, 244, 244, 90, 55, 132, 75, 171, 129, 59,
+ 149, 116, 5, 128, 203, 224, 251, 169, 110, 28, 46, 93, 1, 46, 41,
+ 128, 75, 6, 247, 189, 15, 112, 121, 211, 237, 172, 27, 194, 165, 115,
+ 227, 155, 74, 250, 109, 248, 101, 122, 169, 217, 93, 55, 14, 151, 61,
+ 1, 46, 61, 0, 46, 123, 115, 249, 1, 192, 101, 106, 245, 199, 110,
+ 8, 151, 119, 255, 123, 174, 164, 63, 134, 223, 164, 183, 110, 252, 127,
+ 180, 93, 7, 124, 84, 197, 243, 191, 132, 64, 32, 8, 4, 136, 244,
+ 18, 58, 136, 98, 128, 159, 10, 36, 228, 238, 61, 154, 74, 11, 130,
+ 34, 61, 180, 208, 67, 232, 45, 229, 146, 208, 107, 64, 20, 148, 22,
+ 21, 165, 9, 134, 38, 144, 220, 133, 208, 164, 67, 168, 210, 57, 122,
+ 145, 18, 122, 11, 240, 159, 121, 239, 109, 185, 112, 217, 119, 126, 242,
+ 254, 124, 62, 249, 56, 159, 231, 238, 204, 219, 185, 249, 206, 236, 206,
+ 238, 188, 189, 35, 196, 101, 105, 192, 229, 183, 7, 31, 80, 92, 30,
+ 186, 249, 76, 161, 75, 3, 46, 247, 121, 189, 225, 112, 217, 28, 112,
+ 217, 18, 112, 217, 138, 246, 221, 5, 184, 76, 168, 154, 135, 220, 143,
+ 45, 85, 88, 165, 214, 49, 196, 199, 92, 150, 238, 215, 202, 101, 102,
+ 184, 12, 1, 92, 134, 0, 46, 91, 211, 190, 53, 1, 151, 141, 234,
+ 63, 160, 184, 204, 29, 173, 126, 215, 227, 15, 192, 229, 252, 29, 255,
+ 4, 51, 92, 182, 0, 92, 126, 9, 184, 252, 156, 221, 177, 110, 189,
+ 43, 21, 106, 188, 43, 152, 224, 178, 241, 208, 52, 133, 182, 3, 46,
+ 135, 254, 154, 18, 204, 112, 217, 4, 112, 217, 24, 112, 217, 136, 225,
+ 35, 238, 137, 212, 33, 104, 123, 48, 193, 101, 239, 3, 42, 159, 2,
+ 128, 203, 241, 157, 247, 6, 51, 92, 54, 1, 92, 54, 1, 92, 54,
+ 101, 191, 17, 224, 178, 233, 230, 35, 193, 52, 94, 102, 166, 43, 116,
+ 77, 192, 229, 54, 75, 122, 48, 195, 101, 51, 192, 101, 51, 192, 101,
+ 51, 218, 183, 24, 224, 242, 233, 235, 191, 131, 9, 46, 125, 235, 170,
+ 239, 92, 18, 112, 185, 111, 193, 186, 96, 134, 203, 38, 128, 203, 198,
+ 128, 75, 102, 27, 187, 1, 151, 233, 161, 139, 130, 9, 46, 127, 25,
+ 48, 91, 161, 247, 2, 46, 167, 143, 158, 16, 204, 112, 105, 6, 92,
+ 54, 4, 92, 6, 178, 239, 186, 0, 46, 217, 94, 153, 31, 165, 237,
+ 128, 75, 126, 15, 205, 199, 163, 62, 224, 178, 62, 224, 178, 254, 59,
+ 184, 196, 57, 49, 63, 143, 197, 57, 46, 193, 37, 161, 45, 128, 75,
+ 246, 156, 224, 114, 20, 224, 114, 20, 229, 183, 19, 226, 101, 155, 8,
+ 43, 173, 59, 105, 168, 181, 175, 15, 241, 242, 84, 105, 214, 183, 45,
+ 244, 233, 3, 127, 227, 184, 190, 149, 32, 94, 14, 92, 16, 77, 235,
+ 78, 200, 26, 172, 4, 224, 114, 72, 248, 72, 225, 62, 88, 65, 192,
+ 101, 222, 46, 195, 204, 4, 151, 221, 102, 170, 223, 112, 43, 10, 184,
+ 252, 117, 235, 32, 51, 195, 229, 48, 192, 229, 80, 192, 229, 16, 118,
+ 199, 161, 215, 14, 41, 224, 167, 126, 102, 130, 203, 83, 1, 97, 234,
+ 62, 24, 196, 203, 234, 145, 189, 204, 12, 151, 17, 128, 203, 193, 128,
+ 203, 112, 46, 110, 29, 148, 126, 49, 247, 48, 19, 92, 46, 248, 41,
+ 84, 165, 33, 94, 206, 123, 34, 254, 254, 75, 65, 192, 101, 158, 176,
+ 46, 102, 130, 203, 50, 195, 58, 153, 213, 185, 232, 25, 169, 180, 181,
+ 131, 153, 225, 114, 16, 224, 114, 0, 224, 114, 0, 231, 15, 206, 75,
+ 15, 210, 218, 81, 92, 90, 215, 124, 173, 208, 11, 33, 94, 154, 23,
+ 126, 195, 225, 178, 31, 224, 178, 63, 224, 178, 63, 237, 123, 55, 246,
+ 154, 52, 127, 21, 145, 123, 83, 10, 234, 208, 221, 172, 218, 218, 109,
+ 105, 88, 158, 222, 102, 134, 203, 129, 128, 203, 65, 128, 203, 193, 180,
+ 239, 50, 136, 151, 177, 3, 136, 174, 50, 164, 33, 182, 254, 10, 253,
+ 47, 224, 178, 90, 129, 129, 102, 134, 203, 8, 192, 101, 4, 224, 114,
+ 136, 83, 188, 188, 185, 186, 191, 153, 224, 114, 203, 19, 149, 143, 23,
+ 224, 114, 74, 195, 126, 102, 134, 203, 8, 192, 101, 4, 224, 50, 130,
+ 179, 241, 215, 210, 132, 222, 125, 72, 27, 57, 102, 158, 74, 231, 3,
+ 92, 142, 221, 75, 159, 3, 46, 7, 3, 46, 7, 3, 46, 217, 59,
+ 123, 0, 46, 123, 60, 35, 252, 189, 228, 167, 29, 6, 152, 201, 60,
+ 182, 98, 121, 118, 62, 236, 33, 200, 123, 12, 239, 251, 156, 123, 231,
+ 199, 128, 203, 224, 252, 100, 127, 245, 61, 185, 146, 143, 250, 205, 192,
+ 23, 128, 203, 23, 121, 153, 77, 190, 6, 187, 242, 240, 24, 6, 184,
+ 28, 206, 141, 183, 176, 204, 246, 111, 253, 40, 189, 5, 112, 201, 239,
+ 235, 250, 120, 140, 0, 92, 142, 0, 92, 142, 120, 247, 140, 122, 97,
+ 174, 30, 182, 6, 172, 91, 123, 232, 229, 20, 234, 177, 243, 211, 208,
+ 55, 180, 166, 126, 78, 1, 219, 209, 179, 221, 190, 92, 13, 249, 7,
+ 198, 229, 174, 145, 47, 187, 63, 5, 198, 84, 88, 203, 95, 125, 96,
+ 92, 238, 26, 249, 178, 251, 83, 6, 122, 147, 177, 248, 126, 96, 92,
+ 238, 58, 180, 102, 150, 26, 242, 154, 90, 14, 190, 134, 113, 185, 107,
+ 212, 187, 145, 251, 61, 214, 15, 140, 221, 239, 241, 253, 192, 216, 253,
+ 30, 212, 157, 145, 251, 61, 136, 19, 250, 125, 159, 202, 96, 7, 133,
+ 245, 48, 83, 159, 213, 182, 85, 31, 232, 237, 95, 77, 31, 51, 216,
+ 142, 214, 15, 86, 231, 190, 239, 83, 213, 56, 204, 248, 115, 50, 18,
+ 225, 157, 18, 53, 57, 150, 170, 198, 97, 6, 249, 210, 113, 0, 77,
+ 198, 146, 94, 197, 56, 204, 248, 87, 203, 82, 63, 88, 77, 203, 195,
+ 85, 49, 14, 51, 168, 119, 35, 247, 123, 44, 85, 141, 221, 239, 65,
+ 125, 26, 185, 223, 19, 90, 197, 216, 253, 30, 196, 9, 189, 63, 197,
+ 31, 236, 160, 134, 14, 102, 106, 7, 112, 119, 123, 12, 244, 118, 84,
+ 212, 199, 12, 182, 99, 247, 142, 48, 254, 17, 21, 141, 195, 12, 242,
+ 165, 49, 0, 104, 148, 169, 52, 170, 104, 28, 102, 66, 57, 25, 56,
+ 110, 50, 150, 132, 10, 198, 97, 6, 249, 58, 125, 223, 71, 147, 225,
+ 95, 193, 56, 204, 160, 222, 141, 140, 51, 166, 138, 198, 198, 25, 212,
+ 167, 145, 113, 198, 191, 130, 177, 113, 6, 113, 66, 207, 48, 135, 12,
+ 242, 118, 84, 214, 195, 12, 59, 195, 156, 224, 24, 232, 29, 146, 161,
+ 143, 25, 108, 71, 237, 57, 129, 251, 237, 143, 24, 135, 25, 228, 75,
+ 107, 161, 224, 157, 80, 166, 242, 142, 233, 198, 97, 6, 249, 210, 253,
+ 30, 160, 201, 88, 2, 252, 251, 27, 134, 153, 144, 140, 44, 181, 80,
+ 25, 154, 140, 128, 1, 198, 157, 95, 59, 98, 108, 156, 65, 29, 27,
+ 122, 174, 192, 191, 191, 161, 113, 6, 117, 103, 100, 156, 65, 156, 208,
+ 250, 193, 208, 65, 222, 136, 33, 49, 102, 216, 153, 79, 135, 47, 244,
+ 173, 61, 72, 23, 51, 216, 142, 98, 6, 104, 194, 63, 49, 96, 144,
+ 113, 152, 225, 100, 36, 192, 59, 57, 52, 57, 1, 2, 25, 255, 21,
+ 51, 200, 151, 214, 245, 2, 77, 198, 146, 216, 125, 144, 97, 152, 241,
+ 229, 100, 152, 52, 153, 202, 56, 68, 50, 254, 35, 102, 80, 239, 70,
+ 198, 153, 128, 44, 252, 114, 26, 103, 80, 159, 70, 198, 153, 128, 44,
+ 252, 114, 26, 103, 16, 39, 52, 206, 56, 6, 121, 35, 134, 178, 193,
+ 12, 86, 152, 105, 60, 180, 12, 28, 244, 245, 175, 224, 10, 51, 30,
+ 78, 152, 193, 118, 116, 29, 80, 145, 241, 15, 77, 207, 222, 14, 138,
+ 172, 241, 72, 253, 37, 181, 68, 144, 168, 86, 230, 80, 241, 105, 236,
+ 123, 40, 21, 153, 140, 68, 120, 39, 148, 169, 52, 250, 51, 123, 25,
+ 173, 242, 122, 167, 174, 184, 149, 55, 72, 84, 43, 243, 221, 39, 83,
+ 217, 119, 17, 43, 112, 227, 0, 154, 140, 197, 177, 58, 123, 25, 123,
+ 90, 28, 176, 45, 73, 206, 45, 172, 149, 185, 115, 129, 157, 197, 241,
+ 175, 224, 140, 25, 148, 169, 156, 201, 249, 35, 123, 25, 151, 190, 250,
+ 218, 252, 112, 136, 184, 86, 102, 253, 94, 86, 43, 131, 122, 231, 235,
+ 3, 80, 143, 132, 31, 161, 177, 86, 134, 61, 199, 188, 104, 5, 211,
+ 50, 83, 121, 211, 42, 248, 227, 107, 101, 186, 70, 38, 211, 239, 158,
+ 147, 246, 88, 43, 243, 120, 112, 140, 93, 175, 78, 100, 239, 159, 1,
+ 118, 82, 31, 240, 126, 241, 220, 118, 82, 31, 96, 46, 144, 110, 211,
+ 171, 15, 40, 63, 32, 214, 70, 234, 3, 8, 141, 245, 1, 236, 185,
+ 184, 70, 2, 237, 130, 215, 1, 254, 206, 68, 7, 132, 198, 90, 25,
+ 246, 220, 181, 14, 176, 86, 102, 119, 237, 109, 84, 7, 164, 61, 214,
+ 202, 76, 206, 51, 86, 87, 7, 63, 252, 94, 158, 234, 160, 230, 135,
+ 39, 109, 68, 7, 1, 197, 18, 116, 117, 240, 219, 163, 21, 41, 68,
+ 7, 132, 198, 58, 17, 246, 92, 172, 3, 180, 91, 190, 86, 6, 237,
+ 144, 232, 128, 208, 88, 43, 195, 158, 163, 14, 106, 129, 14, 62, 5,
+ 29, 124, 230, 84, 43, 19, 211, 132, 213, 202, 144, 246, 88, 43, 83,
+ 113, 163, 126, 173, 76, 151, 30, 172, 86, 230, 207, 243, 172, 86, 38,
+ 178, 142, 126, 173, 204, 237, 174, 9, 180, 86, 134, 208, 168, 3, 246,
+ 92, 172, 3, 196, 21, 111, 7, 136, 19, 162, 3, 66, 99, 173, 12,
+ 123, 142, 58, 24, 12, 58, 24, 4, 58, 24, 228, 84, 43, 147, 121,
+ 150, 213, 202, 144, 246, 88, 43, 19, 255, 92, 191, 86, 102, 247, 48,
+ 86, 43, 83, 234, 33, 171, 149, 201, 204, 208, 175, 149, 185, 241, 148,
+ 213, 202, 16, 26, 177, 192, 158, 235, 204, 155, 28, 44, 6, 88, 151,
+ 15, 242, 78, 10, 21, 198, 0, 167, 122, 73, 11, 232, 47, 109, 165,
+ 126, 12, 192, 118, 244, 172, 228, 42, 198, 63, 100, 165, 187, 49, 192,
+ 245, 92, 0, 241, 78, 207, 74, 174, 98, 50, 44, 64, 91, 52, 159,
+ 233, 88, 225, 110, 12, 112, 45, 3, 241, 68, 199, 193, 201, 192, 113,
+ 147, 177, 68, 172, 112, 55, 6, 184, 150, 129, 246, 74, 199, 177, 210,
+ 57, 6, 88, 136, 190, 86, 184, 27, 3, 92, 203, 64, 123, 160, 231,
+ 254, 87, 14, 114, 170, 29, 97, 126, 211, 106, 38, 52, 214, 142, 136,
+ 252, 169, 211, 185, 255, 21, 206, 252, 152, 15, 178, 154, 9, 141, 181,
+ 45, 34, 223, 228, 116, 238, 63, 11, 63, 134, 103, 171, 153, 208, 200,
+ 79, 132, 115, 167, 252, 65, 22, 126, 12, 27, 86, 51, 161, 113, 188,
+ 34, 204, 56, 157, 251, 95, 206, 48, 99, 89, 10, 243, 38, 135, 30,
+ 102, 216, 90, 195, 4, 125, 173, 191, 235, 99, 6, 219, 209, 179, 146,
+ 203, 24, 127, 223, 223, 141, 195, 12, 242, 165, 182, 134, 50, 150, 107,
+ 235, 128, 223, 140, 195, 140, 137, 147, 129, 227, 38, 99, 9, 248, 205,
+ 56, 204, 32, 95, 167, 115, 255, 154, 140, 180, 165, 198, 97, 6, 245,
+ 206, 207, 189, 93, 97, 6, 231, 222, 238, 98, 6, 117, 204, 243, 115,
+ 133, 25, 92, 107, 184, 139, 153, 128, 44, 252, 92, 97, 6, 215, 26,
+ 238, 98, 6, 117, 199, 243, 115, 133, 25, 28, 175, 187, 152, 65, 156,
+ 208, 60, 240, 86, 176, 131, 229, 122, 152, 97, 245, 101, 105, 191, 130,
+ 63, 255, 69, 31, 51, 216, 142, 198, 128, 95, 25, 255, 244, 159, 141,
+ 195, 140, 133, 147, 145, 6, 239, 148, 166, 201, 9, 253, 217, 56, 204,
+ 32, 95, 58, 14, 160, 201, 88, 50, 18, 141, 195, 140, 229, 23, 103,
+ 204, 160, 76, 133, 91, 162, 113, 152, 65, 189, 231, 20, 51, 78, 123,
+ 19, 63, 231, 28, 51, 60, 63, 212, 103, 78, 49, 195, 243, 179, 38,
+ 230, 28, 51, 252, 220, 12, 113, 66, 239, 70, 72, 1, 59, 88, 170,
+ 135, 25, 86, 95, 230, 15, 125, 19, 237, 250, 152, 193, 118, 116, 237,
+ 156, 202, 248, 7, 216, 115, 134, 25, 126, 125, 142, 124, 233, 218, 25,
+ 104, 148, 169, 216, 156, 45, 103, 152, 225, 215, 231, 254, 156, 12, 28,
+ 55, 25, 75, 136, 45, 103, 152, 225, 215, 231, 200, 215, 233, 94, 50,
+ 77, 134, 35, 37, 103, 152, 33, 235, 243, 32, 77, 239, 196, 134, 38,
+ 119, 243, 78, 219, 62, 188, 194, 59, 235, 115, 172, 149, 105, 184, 243,
+ 135, 108, 215, 166, 78, 126, 220, 198, 248, 125, 11, 252, 62, 242, 40,
+ 243, 206, 90, 55, 3, 248, 117, 176, 184, 199, 47, 132, 227, 103, 105,
+ 237, 157, 22, 254, 236, 117, 195, 172, 235, 70, 203, 238, 195, 102, 255,
+ 188, 113, 217, 174, 27, 157, 230, 142, 41, 140, 95, 72, 87, 239, 180,
+ 203, 221, 99, 222, 89, 131, 165, 111, 59, 108, 62, 210, 120, 100, 182,
+ 107, 48, 62, 206, 32, 78, 40, 102, 214, 130, 29, 108, 213, 195, 12,
+ 171, 47, 115, 36, 15, 242, 14, 221, 162, 143, 25, 108, 71, 243, 192,
+ 201, 92, 30, 120, 163, 187, 152, 113, 93, 255, 241, 119, 80, 179, 100,
+ 154, 7, 230, 100, 56, 224, 157, 28, 154, 28, 199, 90, 119, 49, 227,
+ 90, 198, 163, 238, 54, 42, 3, 249, 210, 113, 0, 77, 198, 146, 246,
+ 183, 187, 152, 113, 45, 35, 239, 252, 43, 108, 79, 115, 139, 51, 102,
+ 80, 166, 66, 236, 112, 23, 51, 174, 101, 124, 205, 213, 202, 160, 222,
+ 249, 51, 134, 168, 71, 194, 143, 208, 88, 43, 195, 158, 147, 51, 134,
+ 149, 77, 129, 240, 199, 215, 202, 172, 182, 149, 160, 223, 121, 95, 115,
+ 89, 109, 143, 181, 50, 47, 182, 212, 182, 57, 159, 201, 175, 108, 26,
+ 103, 170, 196, 214, 226, 69, 103, 73, 213, 143, 126, 76, 191, 243, 78,
+ 176, 154, 59, 243, 15, 169, 103, 187, 239, 133, 121, 36, 172, 149, 169,
+ 223, 151, 124, 139, 105, 179, 244, 195, 185, 53, 118, 114, 38, 255, 73,
+ 72, 178, 157, 157, 49, 44, 103, 218, 0, 127, 155, 77, 101, 157, 106,
+ 101, 50, 143, 236, 177, 147, 51, 134, 126, 187, 142, 217, 213, 51, 104,
+ 251, 164, 69, 193, 167, 237, 236, 140, 97, 89, 211, 54, 83, 25, 211,
+ 46, 248, 227, 107, 101, 166, 246, 184, 104, 39, 103, 12, 115, 127, 117,
+ 213, 78, 206, 228, 199, 72, 183, 132, 249, 43, 172, 149, 169, 240, 215,
+ 61, 59, 57, 99, 184, 250, 224, 35, 187, 122, 70, 253, 140, 20, 120,
+ 237, 185, 157, 157, 49, 44, 109, 58, 4, 127, 233, 240, 199, 206, 138,
+ 159, 151, 58, 174, 246, 72, 37, 103, 12, 151, 109, 52, 41, 116, 161,
+ 232, 203, 146, 99, 220, 91, 59, 59, 99, 88, 218, 116, 28, 254, 78,
+ 114, 125, 189, 226, 174, 73, 181, 223, 102, 216, 201, 25, 195, 202, 91,
+ 174, 171, 122, 142, 190, 45, 61, 24, 122, 206, 206, 206, 24, 150, 54,
+ 157, 129, 177, 158, 227, 198, 107, 138, 187, 43, 141, 26, 113, 200, 78,
+ 206, 24, 250, 23, 221, 161, 141, 247, 161, 180, 43, 105, 147, 157, 157,
+ 49, 44, 99, 186, 4, 250, 186, 194, 233, 249, 69, 236, 19, 105, 189,
+ 99, 185, 157, 156, 49, 60, 127, 101, 177, 93, 173, 5, 120, 41, 125,
+ 118, 99, 174, 157, 157, 49, 44, 103, 186, 1, 127, 183, 184, 223, 247,
+ 73, 236, 107, 41, 127, 171, 41, 164, 141, 124, 161, 206, 4, 133, 126,
+ 27, 236, 33, 239, 46, 30, 107, 103, 103, 12, 203, 155, 238, 193, 95,
+ 6, 215, 23, 107, 101, 206, 245, 140, 183, 147, 51, 134, 251, 28, 241,
+ 154, 158, 243, 200, 191, 159, 25, 111, 103, 103, 12, 203, 155, 30, 195,
+ 223, 115, 174, 47, 214, 202, 124, 92, 101, 146, 157, 156, 49, 236, 222,
+ 114, 178, 54, 222, 130, 242, 119, 35, 232, 251, 152, 94, 99, 31, 143,
+ 242, 166, 220, 30, 229, 157, 206, 228, 179, 28, 176, 31, 165, 241, 76,
+ 62, 159, 27, 246, 129, 62, 5, 225, 175, 8, 215, 151, 224, 18, 125,
+ 21, 95, 43, 131, 190, 135, 224, 146, 208, 205, 0, 151, 236, 185, 107,
+ 92, 94, 6, 92, 46, 190, 146, 151, 226, 50, 79, 17, 187, 210, 190,
+ 61, 224, 50, 111, 141, 122, 66, 92, 230, 242, 155, 37, 53, 235, 254,
+ 1, 197, 37, 137, 121, 222, 128, 203, 122, 233, 115, 133, 184, 196, 90,
+ 153, 74, 35, 151, 82, 92, 38, 167, 39, 81, 92, 182, 173, 105, 23,
+ 226, 242, 21, 224, 50, 96, 197, 1, 138, 203, 138, 205, 78, 81, 92,
+ 22, 47, 118, 65, 136, 75, 172, 149, 249, 96, 243, 85, 138, 203, 181,
+ 241, 183, 40, 46, 63, 105, 125, 79, 136, 75, 172, 149, 241, 254, 224,
+ 33, 197, 229, 228, 143, 158, 107, 248, 56, 35, 149, 168, 253, 70, 136,
+ 75, 172, 149, 169, 153, 199, 155, 226, 114, 246, 184, 220, 10, 93, 22,
+ 112, 121, 43, 35, 87, 42, 195, 101, 41, 192, 101, 41, 192, 101, 41,
+ 167, 90, 153, 221, 205, 31, 80, 92, 118, 254, 253, 138, 66, 103, 70,
+ 221, 150, 94, 153, 78, 10, 113, 121, 59, 246, 174, 148, 252, 114, 59,
+ 197, 229, 254, 7, 41, 234, 125, 54, 81, 15, 165, 218, 183, 54, 112,
+ 184, 44, 251, 14, 46, 241, 236, 239, 212, 94, 127, 81, 92, 166, 123,
+ 108, 210, 240, 241, 82, 42, 182, 100, 19, 135, 203, 178, 128, 203, 178,
+ 128, 203, 178, 156, 141, 191, 150, 102, 21, 182, 81, 92, 134, 15, 85,
+ 229, 98, 173, 76, 203, 99, 201, 28, 46, 203, 2, 46, 203, 2, 46,
+ 203, 58, 213, 202, 36, 236, 221, 72, 113, 25, 90, 108, 29, 197, 101,
+ 230, 159, 43, 57, 92, 150, 5, 92, 150, 3, 92, 150, 227, 222, 57,
+ 159, 188, 172, 227, 18, 138, 203, 42, 199, 231, 83, 92, 46, 111, 57,
+ 135, 195, 37, 244, 241, 40, 247, 14, 46, 217, 190, 132, 31, 165, 17,
+ 151, 252, 126, 133, 8, 151, 24, 223, 9, 46, 167, 0, 46, 49, 94,
+ 19, 92, 18, 26, 107, 101, 216, 115, 196, 101, 21, 192, 101, 21, 192,
+ 101, 21, 202, 175, 114, 155, 76, 203, 121, 243, 1, 90, 43, 243, 79,
+ 244, 85, 165, 253, 137, 51, 221, 165, 132, 207, 249, 90, 153, 138, 128,
+ 203, 42, 128, 203, 106, 180, 239, 137, 247, 103, 73, 31, 205, 243, 164,
+ 181, 50, 100, 238, 56, 10, 112, 153, 184, 42, 86, 184, 231, 80, 214,
+ 107, 189, 180, 104, 0, 171, 149, 105, 115, 243, 23, 133, 206, 11, 184,
+ 28, 218, 155, 175, 149, 105, 0, 184, 12, 2, 92, 6, 211, 190, 167,
+ 1, 151, 126, 119, 118, 208, 90, 153, 181, 41, 106, 77, 198, 157, 168,
+ 125, 82, 145, 95, 79, 113, 181, 50, 18, 224, 178, 17, 224, 178, 137,
+ 83, 173, 204, 184, 241, 14, 90, 43, 115, 225, 83, 181, 86, 230, 81,
+ 212, 81, 233, 202, 205, 127, 133, 123, 29, 101, 1, 151, 183, 61, 88,
+ 173, 204, 197, 210, 106, 173, 76, 25, 192, 101, 183, 79, 95, 115, 181,
+ 50, 205, 0, 151, 95, 0, 46, 191, 164, 125, 83, 0, 151, 211, 55,
+ 229, 166, 103, 242, 147, 6, 168, 181, 50, 93, 98, 46, 75, 114, 121,
+ 190, 86, 166, 5, 224, 178, 57, 224, 178, 57, 237, 91, 3, 112, 249,
+ 83, 249, 135, 180, 86, 102, 191, 183, 250, 206, 155, 1, 151, 115, 50,
+ 78, 115, 181, 50, 159, 3, 46, 155, 2, 46, 27, 211, 190, 151, 172,
+ 119, 37, 105, 206, 30, 90, 43, 19, 24, 177, 67, 171, 179, 121, 40,
+ 213, 106, 147, 202, 213, 202, 200, 128, 75, 9, 112, 105, 225, 206, 213,
+ 63, 145, 66, 95, 176, 90, 153, 47, 122, 176, 90, 153, 122, 251, 119,
+ 115, 181, 50, 18, 224, 82, 2, 92, 202, 220, 217, 248, 215, 82, 174,
+ 101, 135, 104, 173, 204, 253, 250, 7, 21, 186, 22, 224, 114, 245, 129,
+ 253, 92, 173, 76, 35, 192, 165, 12, 184, 100, 125, 125, 1, 151, 159,
+ 214, 218, 78, 107, 101, 30, 199, 171, 53, 61, 62, 128, 203, 239, 107,
+ 173, 225, 106, 101, 36, 192, 165, 5, 112, 201, 108, 227, 32, 224, 114,
+ 215, 177, 159, 104, 173, 76, 133, 181, 179, 20, 250, 72, 84, 65, 185,
+ 110, 194, 120, 174, 86, 38, 16, 112, 89, 31, 112, 89, 143, 155, 31,
+ 20, 150, 217, 94, 153, 31, 165, 177, 86, 134, 223, 67, 243, 241, 248,
+ 20, 112, 249, 41, 224, 242, 211, 119, 112, 137, 115, 98, 126, 30, 251,
+ 53, 87, 43, 243, 53, 87, 43, 243, 245, 59, 181, 50, 17, 240, 70,
+ 17, 78, 181, 50, 23, 135, 176, 90, 153, 175, 180, 246, 245, 32, 94,
+ 94, 47, 193, 215, 202, 68, 0, 46, 35, 0, 151, 172, 111, 5, 136,
+ 151, 249, 35, 89, 173, 12, 89, 131, 21, 7, 92, 30, 28, 58, 82,
+ 184, 15, 134, 181, 50, 3, 70, 178, 90, 153, 65, 235, 88, 173, 76,
+ 151, 123, 124, 173, 204, 64, 192, 229, 0, 192, 37, 171, 59, 201, 229,
+ 181, 67, 170, 114, 136, 213, 202, 180, 30, 198, 106, 101, 46, 237, 226,
+ 107, 101, 250, 1, 46, 251, 2, 46, 251, 56, 213, 202, 108, 152, 199,
+ 106, 101, 124, 94, 135, 154, 73, 188, 236, 217, 163, 155, 48, 215, 82,
+ 8, 112, 185, 227, 18, 171, 149, 185, 244, 136, 213, 202, 220, 200, 221,
+ 145, 171, 149, 9, 3, 92, 246, 6, 92, 246, 102, 53, 188, 128, 203,
+ 99, 109, 191, 166, 184, 236, 92, 65, 173, 143, 153, 6, 241, 210, 251,
+ 62, 95, 43, 211, 19, 112, 217, 19, 112, 217, 139, 246, 125, 24, 123,
+ 77, 234, 62, 159, 213, 202, 180, 46, 174, 214, 202, 28, 1, 92, 222,
+ 252, 190, 23, 87, 43, 19, 6, 184, 236, 3, 184, 236, 75, 251, 174,
+ 133, 120, 57, 125, 87, 95, 90, 43, 243, 97, 45, 181, 246, 229, 38,
+ 224, 114, 206, 15, 3, 184, 90, 153, 126, 128, 203, 126, 128, 75, 86,
+ 163, 243, 10, 112, 233, 253, 39, 171, 149, 217, 33, 247, 167, 181, 50,
+ 214, 147, 124, 173, 76, 127, 192, 101, 63, 192, 101, 63, 167, 120, 121,
+ 173, 127, 95, 90, 43, 211, 120, 103, 95, 90, 43, 243, 91, 217, 126,
+ 92, 173, 76, 63, 192, 101, 63, 192, 101, 63, 167, 120, 57, 243, 139,
+ 1, 180, 86, 230, 220, 124, 181, 166, 231, 109, 84, 30, 121, 212, 103,
+ 131, 185, 90, 153, 254, 128, 203, 254, 128, 75, 102, 27, 79, 1, 151,
+ 211, 231, 177, 90, 153, 171, 221, 212, 90, 153, 87, 128, 203, 218, 213,
+ 249, 90, 153, 129, 128, 203, 129, 128, 203, 65, 78, 241, 146, 237, 223,
+ 250, 81, 26, 107, 101, 248, 125, 93, 31, 232, 83, 16, 254, 138, 112,
+ 125, 105, 78, 97, 45, 151, 187, 158, 5, 235, 228, 20, 189, 156, 194,
+ 103, 108, 189, 155, 4, 109, 183, 187, 145, 83, 72, 226, 214, 226, 73,
+ 140, 127, 194, 54, 227, 114, 215, 161, 156, 12, 43, 188, 147, 67, 147,
+ 227, 191, 205, 184, 220, 53, 242, 165, 235, 125, 160, 201, 88, 146, 210,
+ 140, 203, 93, 155, 182, 59, 231, 20, 80, 166, 226, 27, 211, 140, 203,
+ 93, 163, 222, 141, 220, 239, 241, 223, 102, 236, 126, 15, 234, 211, 200,
+ 253, 30, 75, 154, 177, 251, 61, 136, 19, 154, 135, 155, 6, 118, 176,
+ 86, 15, 51, 172, 190, 204, 31, 250, 38, 206, 112, 35, 119, 61, 139,
+ 203, 249, 206, 228, 114, 215, 51, 140, 195, 12, 242, 165, 185, 107, 160,
+ 81, 166, 146, 35, 155, 110, 28, 102, 252, 57, 25, 56, 110, 50, 150,
+ 144, 233, 198, 97, 6, 249, 58, 229, 174, 53, 25, 142, 105, 198, 97,
+ 6, 245, 110, 228, 126, 15, 234, 216, 200, 253, 158, 144, 233, 198, 238,
+ 247, 160, 238, 140, 220, 239, 65, 156, 208, 154, 204, 73, 96, 7, 179,
+ 244, 48, 195, 234, 203, 28, 83, 1, 99, 83, 220, 136, 51, 83, 185,
+ 56, 51, 149, 241, 207, 152, 108, 96, 156, 225, 100, 56, 224, 157, 28,
+ 154, 28, 235, 100, 227, 48, 131, 124, 233, 56, 128, 38, 99, 241, 157,
+ 108, 28, 102, 66, 167, 100, 201, 93, 79, 209, 206, 71, 76, 50, 14,
+ 51, 168, 119, 35, 227, 140, 117, 178, 177, 113, 198, 119, 178, 177, 113,
+ 6, 117, 103, 100, 156, 65, 156, 208, 154, 204, 56, 176, 131, 105, 58,
+ 152, 225, 234, 203, 18, 39, 130, 63, 159, 160, 143, 25, 108, 71, 99,
+ 192, 68, 198, 63, 105, 188, 113, 152, 241, 231, 100, 36, 194, 59, 37,
+ 106, 114, 44, 227, 141, 195, 12, 242, 165, 227, 0, 154, 140, 37, 61,
+ 222, 56, 204, 248, 79, 200, 114, 134, 121, 130, 118, 62, 34, 222, 56,
+ 204, 160, 222, 141, 140, 51, 150, 241, 198, 198, 25, 212, 167, 145, 113,
+ 38, 52, 222, 216, 56, 131, 56, 33, 152, 9, 240, 7, 59, 152, 164,
+ 135, 25, 118, 230, 51, 20, 250, 58, 172, 250, 152, 193, 118, 52, 6,
+ 196, 50, 254, 17, 86, 227, 48, 131, 124, 105, 12, 0, 26, 101, 42,
+ 243, 191, 196, 1, 134, 97, 38, 148, 147, 129, 227, 38, 99, 9, 240,
+ 31, 104, 24, 102, 144, 175, 83, 77, 166, 38, 35, 201, 223, 56, 204,
+ 160, 222, 141, 140, 51, 168, 99, 67, 207, 175, 249, 15, 52, 52, 206,
+ 160, 238, 140, 140, 51, 136, 19, 186, 158, 169, 28, 238, 237, 136, 115,
+ 129, 153, 190, 35, 6, 245, 30, 58, 98, 88, 173, 129, 189, 77, 195,
+ 121, 31, 248, 113, 184, 183, 127, 173, 112, 253, 218, 127, 104, 71, 253,
+ 51, 208, 244, 252, 90, 205, 240, 108, 237, 160, 88, 197, 49, 54, 143,
+ 37, 203, 27, 168, 152, 201, 231, 210, 14, 106, 118, 169, 193, 226, 12,
+ 39, 35, 17, 222, 41, 81, 147, 99, 173, 145, 189, 140, 69, 99, 110,
+ 216, 74, 12, 159, 159, 172, 98, 198, 181, 140, 95, 254, 153, 195, 214,
+ 76, 181, 184, 113, 0, 77, 198, 18, 80, 45, 123, 25, 11, 23, 22,
+ 218, 186, 219, 119, 191, 77, 197, 140, 107, 25, 135, 151, 109, 100, 231,
+ 125, 56, 25, 38, 77, 166, 50, 71, 171, 156, 189, 140, 55, 199, 218,
+ 154, 175, 79, 34, 152, 113, 45, 227, 199, 251, 209, 10, 102, 202, 120,
+ 170, 122, 175, 162, 180, 84, 235, 3, 80, 143, 132, 31, 161, 155, 109,
+ 152, 43, 177, 231, 38, 211, 34, 83, 101, 211, 50, 83, 21, 211, 10,
+ 110, 159, 228, 81, 171, 250, 242, 157, 61, 205, 108, 164, 62, 128, 180,
+ 207, 101, 111, 45, 47, 110, 86, 73, 24, 163, 222, 200, 237, 228, 143,
+ 251, 23, 214, 218, 124, 43, 47, 216, 252, 70, 193, 147, 167, 189, 147,
+ 124, 114, 225, 25, 97, 60, 122, 45, 135, 202, 163, 82, 227, 180, 54,
+ 189, 228, 53, 254, 179, 212, 190, 209, 97, 114, 245, 30, 243, 132, 125,
+ 223, 196, 246, 147, 171, 174, 189, 170, 181, 25, 40, 127, 120, 197, 219,
+ 166, 230, 84, 195, 229, 157, 131, 202, 138, 223, 57, 118, 136, 188, 165,
+ 36, 217, 151, 29, 46, 223, 89, 209, 88, 235, 59, 82, 46, 219, 160,
+ 141, 78, 223, 49, 114, 163, 159, 191, 177, 145, 122, 8, 203, 69, 149,
+ 246, 140, 182, 202, 13, 58, 181, 215, 233, 27, 47, 103, 206, 104, 162,
+ 181, 153, 40, 199, 167, 52, 212, 250, 78, 150, 125, 110, 125, 162, 211,
+ 119, 154, 124, 114, 211, 135, 180, 174, 136, 208, 155, 31, 37, 112, 207,
+ 179, 143, 211, 104, 47, 136, 33, 222, 94, 16, 19, 196, 94, 8, 221,
+ 20, 236, 133, 61, 71, 123, 169, 2, 246, 82, 25, 236, 133, 237, 119,
+ 63, 0, 123, 169, 55, 182, 53, 181, 23, 210, 30, 237, 101, 234, 200,
+ 5, 186, 246, 210, 192, 103, 19, 181, 151, 139, 197, 213, 253, 57, 180,
+ 151, 137, 85, 46, 217, 244, 236, 197, 179, 92, 110, 59, 177, 151, 23,
+ 149, 189, 236, 196, 94, 30, 69, 231, 210, 57, 15, 210, 79, 182, 4,
+ 220, 178, 17, 123, 73, 40, 245, 143, 166, 251, 112, 217, 225, 181, 75,
+ 215, 94, 142, 62, 249, 131, 218, 75, 253, 207, 23, 83, 123, 89, 250,
+ 211, 44, 93, 123, 105, 177, 207, 74, 237, 101, 211, 144, 209, 90, 95,
+ 171, 252, 162, 102, 152, 174, 189, 228, 13, 137, 164, 246, 146, 80, 49,
+ 142, 218, 75, 153, 178, 19, 117, 237, 229, 193, 103, 51, 168, 189, 16,
+ 26, 237, 133, 61, 23, 219, 11, 250, 67, 222, 94, 208, 191, 17, 123,
+ 33, 244, 195, 245, 115, 37, 246, 28, 237, 165, 20, 216, 75, 57, 176,
+ 23, 182, 175, 91, 0, 236, 165, 225, 229, 130, 169, 196, 94, 72, 251,
+ 218, 96, 47, 77, 79, 36, 10, 127, 183, 247, 26, 181, 147, 63, 170,
+ 217, 192, 78, 236, 229, 120, 201, 117, 202, 187, 191, 181, 117, 146, 219,
+ 87, 243, 16, 214, 134, 239, 7, 123, 217, 119, 220, 210, 144, 216, 75,
+ 241, 151, 181, 20, 186, 5, 216, 203, 39, 69, 42, 9, 235, 183, 242,
+ 197, 245, 147, 107, 248, 5, 5, 18, 123, 217, 212, 113, 161, 34, 55,
+ 15, 216, 75, 249, 114, 213, 133, 239, 92, 53, 110, 136, 188, 164, 29,
+ 57, 251, 50, 92, 158, 88, 82, 221, 171, 47, 3, 246, 98, 186, 122,
+ 95, 216, 119, 30, 216, 75, 219, 147, 213, 82, 137, 189, 212, 111, 80,
+ 95, 161, 247, 69, 89, 229, 118, 47, 58, 165, 138, 250, 62, 1, 123,
+ 169, 176, 131, 220, 87, 61, 81, 142, 90, 165, 182, 71, 123, 217, 250,
+ 93, 143, 84, 49, 62, 166, 201, 175, 242, 69, 164, 18, 123, 33, 52,
+ 218, 11, 123, 46, 182, 23, 140, 109, 188, 189, 96, 172, 34, 246, 66,
+ 104, 140, 71, 236, 57, 218, 203, 72, 176, 151, 81, 96, 47, 236, 123,
+ 120, 143, 193, 94, 58, 85, 142, 166, 245, 106, 164, 189, 39, 216, 139,
+ 185, 132, 78, 205, 25, 248, 151, 165, 118, 210, 230, 91, 185, 214, 153,
+ 24, 51, 241, 47, 155, 117, 214, 31, 111, 192, 94, 246, 47, 32, 109,
+ 122, 201, 125, 126, 214, 250, 130, 189, 84, 254, 77, 167, 47, 248, 151,
+ 243, 247, 72, 155, 129, 242, 39, 103, 73, 223, 112, 121, 198, 110, 113,
+ 95, 19, 216, 203, 207, 179, 73, 155, 225, 242, 63, 23, 181, 26, 59,
+ 176, 151, 247, 106, 69, 139, 199, 11, 246, 242, 180, 123, 36, 173, 207,
+ 155, 180, 69, 187, 187, 19, 252, 203, 202, 190, 99, 205, 122, 254, 37,
+ 173, 15, 105, 51, 81, 14, 121, 61, 198, 76, 236, 229, 210, 156, 49,
+ 102, 61, 255, 242, 89, 250, 104, 90, 219, 71, 104, 180, 23, 246, 92,
+ 39, 159, 8, 246, 66, 247, 173, 204, 225, 222, 1, 254, 194, 57, 171,
+ 83, 109, 159, 163, 82, 184, 119, 104, 69, 253, 57, 43, 182, 99, 223,
+ 197, 97, 115, 175, 140, 10, 238, 206, 89, 93, 175, 93, 48, 230, 178,
+ 239, 226, 132, 115, 223, 197, 129, 185, 183, 38, 199, 90, 193, 221, 57,
+ 171, 107, 25, 232, 167, 217, 119, 113, 184, 113, 0, 77, 198, 226, 91,
+ 193, 221, 57, 171, 107, 25, 136, 109, 58, 142, 138, 206, 115, 86, 148,
+ 169, 204, 93, 253, 221, 157, 179, 186, 150, 129, 246, 64, 243, 137, 21,
+ 194, 157, 106, 221, 216, 220, 197, 106, 38, 244, 101, 217, 102, 17, 205,
+ 105, 156, 242, 137, 89, 248, 177, 216, 102, 53, 19, 26, 249, 137, 98,
+ 158, 83, 62, 49, 11, 63, 230, 251, 172, 102, 66, 35, 63, 145, 79,
+ 116, 202, 39, 250, 59, 243, 99, 216, 176, 154, 9, 141, 252, 68, 152,
+ 113, 218, 183, 50, 51, 204, 164, 7, 130, 29, 112, 235, 9, 215, 152,
+ 97, 181, 125, 254, 208, 55, 177, 161, 62, 102, 176, 29, 93, 131, 5,
+ 51, 254, 1, 254, 198, 97, 6, 249, 210, 53, 24, 208, 40, 83, 145,
+ 209, 208, 56, 204, 248, 115, 50, 112, 220, 100, 44, 105, 65, 198, 97,
+ 6, 249, 58, 237, 91, 105, 50, 66, 130, 140, 195, 76, 0, 103, 67,
+ 38, 175, 200, 84, 87, 152, 49, 141, 42, 231, 54, 102, 80, 199, 60,
+ 63, 87, 152, 65, 126, 238, 98, 6, 245, 73, 249, 121, 70, 166, 186,
+ 194, 12, 242, 115, 23, 51, 33, 65, 206, 239, 231, 10, 51, 200, 207,
+ 93, 204, 32, 78, 232, 253, 36, 159, 129, 29, 152, 245, 48, 195, 106,
+ 251, 66, 160, 111, 122, 125, 125, 204, 96, 59, 250, 45, 169, 6, 140,
+ 127, 104, 125, 227, 48, 131, 124, 233, 183, 164, 128, 70, 153, 74, 44,
+ 171, 103, 28, 102, 66, 56, 25, 56, 110, 50, 22, 107, 61, 227, 48,
+ 131, 124, 121, 204, 132, 104, 50, 124, 235, 25, 135, 25, 212, 123, 78,
+ 49, 195, 231, 184, 81, 199, 57, 197, 12, 207, 207, 90, 47, 231, 152,
+ 225, 249, 249, 214, 203, 57, 102, 248, 185, 25, 226, 132, 96, 38, 164,
+ 46, 216, 65, 160, 30, 102, 88, 109, 159, 47, 244, 77, 248, 68, 31,
+ 51, 216, 142, 126, 75, 234, 83, 198, 223, 255, 147, 156, 97, 134, 207,
+ 39, 34, 95, 250, 45, 41, 160, 81, 166, 146, 187, 254, 95, 206, 48,
+ 195, 231, 19, 125, 57, 25, 56, 110, 50, 22, 203, 255, 114, 134, 25,
+ 62, 159, 136, 124, 121, 204, 248, 106, 50, 210, 235, 230, 12, 51, 36,
+ 159, 24, 164, 233, 157, 216, 80, 232, 246, 130, 91, 43, 109, 29, 253,
+ 78, 62, 209, 226, 88, 102, 254, 59, 178, 100, 182, 249, 68, 167, 28,
+ 247, 255, 156, 249, 237, 154, 243, 213, 59, 249, 38, 228, 247, 121, 181,
+ 5, 217, 230, 155, 156, 206, 0, 113, 252, 28, 53, 11, 109, 173, 177,
+ 173, 96, 106, 214, 124, 68, 250, 237, 101, 230, 184, 203, 137, 217, 230,
+ 35, 156, 238, 158, 175, 203, 189, 223, 182, 130, 91, 227, 11, 190, 187,
+ 94, 245, 135, 247, 91, 84, 38, 38, 219, 245, 42, 31, 103, 16, 39,
+ 116, 110, 22, 0, 118, 240, 153, 30, 102, 88, 109, 95, 122, 29, 240,
+ 231, 181, 245, 49, 131, 237, 104, 12, 168, 195, 248, 87, 79, 111, 227,
+ 38, 102, 138, 186, 180, 3, 252, 255, 52, 6, 112, 50, 210, 225, 157,
+ 210, 53, 57, 213, 3, 58, 187, 137, 25, 215, 50, 240, 255, 211, 113,
+ 212, 230, 198, 1, 52, 25, 75, 223, 142, 239, 229, 114, 15, 51, 174,
+ 101, 224, 255, 167, 227, 168, 237, 140, 25, 148, 169, 140, 35, 173, 165,
+ 155, 152, 113, 45, 99, 231, 191, 234, 190, 213, 112, 47, 85, 239, 85,
+ 148, 150, 234, 153, 104, 212, 35, 225, 71, 104, 60, 19, 205, 158, 187,
+ 190, 215, 99, 107, 235, 76, 203, 247, 85, 167, 164, 144, 51, 209, 43,
+ 158, 169, 185, 243, 224, 33, 97, 210, 136, 15, 74, 101, 169, 33, 170,
+ 98, 138, 226, 242, 247, 119, 167, 44, 144, 24, 86, 151, 211, 124, 191,
+ 87, 244, 74, 73, 132, 85, 147, 82, 235, 182, 90, 242, 88, 190, 86,
+ 147, 155, 36, 141, 251, 106, 122, 138, 154, 159, 92, 39, 201, 47, 91,
+ 166, 136, 115, 70, 27, 165, 207, 150, 142, 79, 33, 231, 169, 71, 108,
+ 249, 86, 203, 223, 39, 75, 97, 31, 84, 23, 231, 254, 99, 237, 210,
+ 249, 106, 223, 213, 83, 159, 166, 73, 3, 150, 188, 215, 64, 149, 187,
+ 93, 58, 52, 48, 190, 129, 56, 247, 176, 75, 90, 31, 126, 96, 11,
+ 57, 139, 125, 98, 183, 99, 139, 42, 119, 159, 244, 212, 255, 201, 22,
+ 113, 223, 131, 210, 185, 233, 73, 245, 201, 89, 236, 251, 55, 91, 52,
+ 80, 251, 30, 149, 54, 239, 74, 212, 145, 123, 66, 42, 220, 35, 87,
+ 32, 57, 139, 189, 227, 246, 43, 173, 239, 25, 169, 103, 225, 7, 58,
+ 125, 207, 75, 219, 242, 183, 104, 64, 206, 98, 87, 11, 91, 83, 95,
+ 237, 123, 89, 58, 240, 225, 221, 205, 98, 61, 95, 147, 22, 87, 251,
+ 117, 11, 57, 139, 221, 170, 176, 90, 247, 233, 25, 125, 91, 26, 208,
+ 108, 113, 178, 88, 238, 93, 233, 248, 223, 249, 83, 200, 89, 236, 139,
+ 129, 149, 181, 223, 247, 161, 116, 51, 41, 72, 103, 143, 229, 137, 212,
+ 97, 76, 227, 20, 114, 22, 187, 219, 244, 38, 218, 239, 251, 82, 234,
+ 189, 164, 169, 78, 223, 215, 82, 249, 163, 117, 73, 27, 249, 238, 214,
+ 122, 170, 92, 179, 135, 108, 91, 221, 80, 108, 87, 105, 158, 242, 94,
+ 223, 182, 90, 27, 47, 249, 229, 228, 112, 173, 111, 110, 249, 7, 211,
+ 4, 157, 190, 121, 228, 34, 219, 22, 106, 109, 242, 202, 253, 191, 93,
+ 175, 245, 205, 39, 239, 188, 191, 87, 167, 175, 143, 44, 21, 184, 171,
+ 181, 121, 79, 126, 147, 223, 83, 205, 213, 155, 11, 200, 29, 103, 23,
+ 176, 137, 251, 22, 148, 43, 39, 19, 156, 250, 202, 45, 211, 253, 181,
+ 190, 133, 229, 17, 215, 171, 234, 244, 45, 34, 179, 61, 58, 63, 74,
+ 159, 27, 243, 190, 204, 239, 221, 249, 120, 84, 49, 21, 132, 191, 34,
+ 30, 85, 156, 230, 127, 138, 31, 2, 223, 76, 252, 16, 214, 50, 162,
+ 175, 37, 126, 136, 208, 193, 224, 135, 216, 115, 215, 126, 104, 19, 248,
+ 161, 73, 211, 6, 211, 154, 169, 164, 120, 117, 62, 219, 16, 252, 80,
+ 193, 70, 191, 113, 126, 168, 178, 82, 203, 24, 197, 237, 11, 161, 31,
+ 98, 49, 126, 57, 221, 71, 66, 63, 36, 138, 241, 196, 15, 37, 29,
+ 75, 177, 17, 63, 228, 255, 249, 46, 27, 241, 67, 227, 109, 135, 108,
+ 122, 126, 232, 147, 149, 187, 109, 196, 15, 21, 59, 170, 237, 41, 129,
+ 31, 122, 241, 226, 136, 206, 62, 137, 93, 250, 170, 231, 85, 27, 241,
+ 67, 23, 199, 223, 176, 17, 63, 52, 224, 247, 219, 54, 61, 63, 36,
+ 247, 38, 123, 86, 123, 164, 31, 219, 95, 212, 250, 238, 147, 30, 124,
+ 113, 222, 166, 231, 135, 230, 103, 92, 176, 17, 63, 52, 235, 249, 57,
+ 27, 241, 67, 19, 77, 103, 109, 122, 126, 232, 230, 193, 99, 54, 226,
+ 135, 110, 141, 59, 102, 35, 126, 232, 118, 141, 99, 54, 61, 63, 244,
+ 100, 196, 105, 27, 241, 67, 77, 125, 206, 106, 239, 124, 89, 154, 183,
+ 248, 156, 78, 223, 107, 210, 23, 59, 201, 187, 221, 148, 218, 154, 200,
+ 59, 223, 150, 186, 4, 233, 245, 189, 43, 213, 142, 39, 58, 201, 144,
+ 98, 147, 72, 223, 135, 210, 145, 243, 122, 227, 125, 34, 237, 137, 63,
+ 101, 35, 126, 168, 200, 193, 147, 54, 226, 135, 58, 23, 59, 97, 211,
+ 243, 67, 11, 70, 81, 157, 200, 37, 226, 143, 218, 136, 31, 250, 126,
+ 166, 216, 54, 176, 38, 100, 93, 200, 113, 27, 241, 67, 129, 245, 14,
+ 218, 136, 31, 218, 90, 254, 111, 155, 158, 31, 202, 252, 125, 157, 141,
+ 248, 161, 194, 214, 165, 54, 226, 135, 170, 118, 248, 65, 252, 206, 224,
+ 135, 154, 140, 140, 177, 17, 63, 180, 171, 239, 112, 234, 135, 90, 117,
+ 234, 167, 235, 135, 98, 170, 140, 165, 126, 104, 173, 35, 150, 250, 161,
+ 95, 215, 76, 212, 245, 67, 108, 239, 215, 143, 210, 232, 135, 248, 61,
+ 97, 31, 143, 202, 224, 135, 42, 131, 31, 170, 252, 142, 31, 194, 249,
+ 27, 241, 67, 117, 192, 15, 225, 124, 140, 248, 33, 66, 251, 130, 31,
+ 98, 207, 93, 215, 84, 159, 106, 153, 105, 217, 59, 238, 137, 157, 248,
+ 33, 219, 179, 252, 202, 92, 255, 252, 224, 48, 105, 250, 238, 114, 169,
+ 204, 15, 149, 1, 63, 84, 10, 252, 80, 73, 218, 247, 231, 137, 11,
+ 36, 182, 54, 88, 78, 247, 39, 87, 131, 31, 18, 173, 13, 176, 239,
+ 124, 240, 67, 81, 117, 138, 216, 137, 31, 122, 254, 170, 182, 66, 23,
+ 138, 91, 39, 189, 120, 212, 70, 184, 119, 55, 125, 242, 70, 105, 81,
+ 129, 221, 180, 30, 59, 104, 137, 250, 158, 159, 140, 79, 150, 170, 222,
+ 234, 40, 92, 199, 175, 29, 101, 151, 118, 46, 93, 147, 74, 252, 80,
+ 224, 201, 93, 10, 93, 115, 244, 118, 201, 49, 236, 156, 176, 111, 25,
+ 240, 67, 167, 111, 253, 147, 74, 252, 80, 100, 137, 11, 10, 221, 10,
+ 252, 208, 31, 77, 174, 10, 251, 182, 138, 59, 40, 221, 124, 118, 55,
+ 149, 248, 161, 164, 230, 207, 20, 186, 60, 248, 161, 41, 33, 166, 173,
+ 194, 189, 89, 240, 67, 59, 46, 228, 219, 74, 252, 208, 226, 203, 42,
+ 125, 23, 252, 208, 152, 235, 249, 132, 125, 143, 96, 109, 90, 11, 194,
+ 223, 33, 249, 44, 83, 229, 174, 143, 186, 44, 125, 244, 215, 61, 225,
+ 59, 223, 1, 63, 148, 239, 244, 245, 84, 226, 135, 174, 238, 184, 168,
+ 208, 143, 162, 110, 75, 101, 254, 60, 37, 236, 187, 11, 252, 208, 164,
+ 190, 135, 83, 137, 31, 170, 26, 176, 79, 161, 79, 68, 61, 148, 22,
+ 60, 223, 41, 236, 123, 23, 252, 208, 119, 189, 183, 165, 18, 63, 244,
+ 96, 108, 170, 66, 123, 131, 31, 234, 146, 144, 34, 236, 219, 44, 238,
+ 181, 84, 107, 86, 50, 105, 35, 119, 201, 220, 160, 254, 70, 224, 135,
+ 230, 244, 249, 83, 216, 183, 15, 248, 161, 237, 127, 47, 77, 37, 126,
+ 40, 224, 192, 124, 133, 238, 15, 126, 104, 251, 222, 233, 194, 190, 23,
+ 192, 15, 61, 249, 136, 228, 144, 242, 202, 251, 39, 169, 251, 195, 169,
+ 193, 249, 228, 207, 110, 215, 19, 246, 93, 8, 126, 104, 66, 177, 146,
+ 169, 196, 15, 149, 159, 158, 71, 161, 255, 10, 46, 32, 47, 42, 126,
+ 83, 136, 133, 116, 240, 67, 229, 158, 239, 179, 19, 63, 180, 183, 101,
+ 170, 66, 63, 8, 46, 44, 63, 249, 109, 173, 176, 239, 107, 240, 67,
+ 236, 76, 129, 31, 165, 207, 131, 31, 226, 207, 26, 248, 120, 148, 3,
+ 63, 84, 14, 252, 80, 185, 119, 231, 67, 176, 198, 227, 231, 67, 184,
+ 102, 35, 126, 136, 208, 184, 46, 99, 207, 93, 223, 235, 102, 135, 249,
+ 208, 79, 199, 163, 104, 173, 234, 244, 25, 42, 45, 193, 124, 40, 195,
+ 28, 197, 213, 170, 142, 4, 63, 52, 18, 252, 208, 72, 182, 31, 15,
+ 243, 33, 150, 83, 88, 78, 247, 189, 61, 193, 15, 137, 114, 10, 106,
+ 220, 90, 45, 253, 189, 135, 180, 73, 146, 198, 172, 81, 233, 50, 48,
+ 31, 170, 57, 87, 188, 159, 108, 141, 219, 40, 125, 95, 192, 74, 235,
+ 92, 79, 29, 83, 247, 135, 207, 195, 124, 200, 54, 85, 188, 175, 107,
+ 129, 249, 80, 205, 149, 164, 222, 49, 77, 138, 243, 80, 235, 32, 199,
+ 68, 109, 151, 54, 119, 236, 43, 236, 155, 1, 126, 232, 100, 173, 190,
+ 180, 70, 182, 244, 76, 181, 70, 246, 125, 240, 67, 157, 239, 246, 18,
+ 246, 173, 0, 126, 168, 235, 10, 86, 35, 59, 176, 128, 90, 35, 91,
+ 28, 252, 144, 121, 72, 23, 97, 223, 21, 224, 135, 252, 127, 106, 79,
+ 107, 100, 135, 207, 83, 233, 175, 193, 15, 237, 153, 219, 94, 216, 247,
+ 58, 248, 33, 207, 65, 93, 104, 141, 236, 154, 199, 106, 61, 238, 69,
+ 240, 67, 101, 35, 123, 8, 251, 62, 2, 63, 212, 46, 162, 23, 173,
+ 145, 141, 170, 22, 166, 213, 125, 222, 150, 126, 188, 208, 71, 216, 247,
+ 1, 248, 161, 31, 31, 176, 251, 228, 194, 139, 171, 181, 167, 248, 77,
+ 137, 250, 13, 7, 10, 251, 98, 141, 236, 145, 251, 3, 105, 141, 108,
+ 224, 164, 65, 102, 50, 31, 90, 90, 46, 92, 216, 55, 47, 248, 161,
+ 136, 206, 180, 141, 60, 161, 251, 96, 90, 35, 187, 52, 44, 66, 216,
+ 55, 55, 248, 161, 13, 195, 135, 210, 26, 217, 4, 179, 90, 231, 234,
+ 5, 126, 104, 140, 207, 72, 97, 223, 103, 224, 135, 138, 158, 34, 185,
+ 103, 88, 151, 117, 85, 207, 29, 188, 0, 63, 180, 230, 234, 56, 241,
+ 120, 193, 15, 205, 44, 18, 69, 235, 107, 187, 167, 170, 244, 91, 240,
+ 67, 1, 253, 197, 231, 35, 112, 62, 244, 123, 18, 105, 227, 43, 231,
+ 58, 173, 210, 56, 31, 10, 245, 136, 49, 235, 205, 135, 216, 89, 21,
+ 63, 74, 227, 124, 136, 63, 195, 226, 227, 49, 10, 252, 208, 40, 240,
+ 67, 163, 222, 201, 163, 99, 30, 144, 158, 203, 45, 19, 238, 29, 82,
+ 87, 47, 39, 200, 106, 115, 67, 160, 111, 98, 57, 55, 246, 158, 2,
+ 184, 125, 206, 242, 220, 126, 109, 57, 3, 247, 107, 203, 115, 251, 181,
+ 64, 163, 76, 197, 67, 148, 53, 112, 191, 150, 147, 129, 227, 38, 99,
+ 9, 41, 107, 224, 126, 109, 185, 44, 251, 181, 154, 12, 71, 25, 3,
+ 247, 107, 203, 25, 187, 95, 139, 58, 54, 114, 191, 54, 164, 172, 177,
+ 251, 181, 168, 59, 35, 247, 107, 17, 39, 180, 206, 176, 68, 184, 119,
+ 122, 128, 30, 102, 88, 109, 174, 163, 116, 184, 119, 104, 41, 55, 206,
+ 5, 149, 230, 206, 211, 148, 230, 206, 5, 149, 52, 240, 92, 16, 39,
+ 195, 1, 239, 228, 208, 228, 88, 75, 26, 120, 46, 168, 20, 55, 14,
+ 160, 201, 88, 124, 75, 26, 120, 46, 168, 84, 150, 115, 65, 165, 180,
+ 115, 65, 37, 12, 60, 23, 84, 210, 216, 253, 90, 107, 73, 99, 247,
+ 107, 125, 75, 26, 187, 95, 139, 186, 51, 114, 191, 22, 113, 66, 235,
+ 12, 139, 130, 29, 148, 209, 195, 12, 119, 247, 99, 241, 112, 111, 255,
+ 98, 110, 212, 127, 20, 231, 98, 64, 113, 198, 63, 233, 253, 156, 97,
+ 166, 88, 209, 143, 26, 210, 24, 192, 201, 72, 132, 119, 74, 212, 228,
+ 88, 222, 207, 25, 102, 254, 57, 81, 139, 125, 239, 181, 24, 55, 14,
+ 160, 201, 88, 210, 253, 114, 134, 153, 162, 195, 186, 178, 113, 20, 203,
+ 82, 255, 81, 76, 229, 29, 234, 151, 51, 204, 28, 168, 206, 213, 25,
+ 190, 207, 217, 80, 22, 126, 168, 83, 198, 219, 245, 191, 119, 246, 87,
+ 5, 252, 80, 127, 255, 149, 31, 234, 51, 59, 126, 168, 171, 255, 202,
+ 47, 84, 192, 15, 245, 226, 46, 63, 90, 103, 88, 148, 97, 38, 32,
+ 6, 236, 160, 132, 14, 102, 248, 187, 31, 161, 175, 163, 176, 62, 102,
+ 176, 29, 141, 1, 69, 24, 255, 136, 194, 198, 197, 25, 228, 75, 99,
+ 0, 208, 40, 83, 105, 84, 216, 184, 56, 19, 202, 201, 192, 113, 147,
+ 177, 36, 248, 26, 23, 103, 144, 175, 83, 157, 161, 38, 35, 41, 198,
+ 184, 56, 131, 122, 55, 50, 206, 152, 10, 27, 27, 103, 80, 159, 70,
+ 198, 25, 212, 157, 145, 113, 6, 113, 66, 48, 147, 49, 22, 236, 160,
+ 168, 30, 102, 216, 153, 237, 164, 232, 112, 239, 128, 40, 125, 204, 96,
+ 59, 98, 7, 1, 209, 140, 127, 90, 164, 113, 152, 9, 224, 100, 36,
+ 193, 59, 37, 105, 114, 66, 34, 141, 195, 12, 242, 165, 227, 0, 154,
+ 140, 197, 49, 206, 56, 204, 4, 68, 57, 99, 6, 101, 42, 254, 101,
+ 156, 113, 152, 65, 189, 27, 185, 158, 9, 137, 52, 118, 61, 131, 250,
+ 52, 114, 61, 19, 49, 206, 216, 245, 12, 226, 132, 222, 97, 52, 4,
+ 236, 32, 70, 128, 153, 161, 253, 76, 125, 135, 179, 223, 35, 2, 250,
+ 102, 140, 214, 199, 12, 182, 35, 118, 144, 49, 134, 241, 79, 28, 153,
+ 189, 29, 116, 191, 227, 101, 75, 159, 82, 52, 72, 84, 155, 235, 8,
+ 241, 160, 119, 63, 34, 95, 34, 35, 2, 104, 148, 169, 96, 102, 120,
+ 246, 50, 230, 60, 219, 106, 251, 241, 236, 252, 32, 81, 109, 238, 44,
+ 207, 82, 20, 51, 17, 156, 12, 28, 55, 29, 203, 208, 236, 101, 60,
+ 223, 113, 38, 53, 237, 227, 163, 65, 162, 218, 220, 198, 246, 191, 232,
+ 252, 15, 249, 242, 152, 137, 208, 100, 164, 15, 202, 94, 198, 213, 94,
+ 125, 204, 193, 30, 177, 194, 218, 220, 95, 158, 176, 218, 92, 212, 59,
+ 95, 11, 133, 122, 36, 252, 8, 141, 181, 80, 236, 57, 230, 129, 171,
+ 154, 150, 193, 223, 10, 110, 63, 30, 107, 161, 230, 253, 91, 88, 107,
+ 211, 66, 38, 237, 177, 22, 106, 212, 235, 87, 194, 250, 55, 172, 181,
+ 188, 21, 113, 77, 107, 243, 173, 28, 121, 236, 159, 64, 181, 111, 39,
+ 185, 208, 167, 251, 116, 250, 134, 202, 247, 46, 164, 104, 109, 122, 201,
+ 77, 63, 248, 83, 161, 115, 101, 246, 149, 195, 234, 139, 239, 100, 125,
+ 157, 107, 176, 124, 166, 246, 100, 173, 205, 112, 185, 254, 180, 33, 129,
+ 106, 206, 109, 132, 92, 234, 68, 191, 64, 113, 206, 109, 164, 124, 36,
+ 79, 31, 173, 205, 104, 185, 119, 175, 111, 180, 190, 99, 228, 23, 219,
+ 154, 232, 244, 29, 43, 135, 238, 247, 211, 218, 68, 202, 203, 27, 21,
+ 81, 199, 27, 109, 149, 119, 87, 206, 43, 30, 111, 108, 188, 220, 40,
+ 101, 137, 214, 102, 162, 124, 239, 223, 149, 90, 223, 201, 242, 143, 101,
+ 254, 210, 233, 59, 77, 94, 108, 137, 215, 218, 204, 164, 52, 214, 66,
+ 177, 231, 217, 199, 105, 180, 23, 196, 16, 111, 47, 136, 9, 98, 47,
+ 132, 70, 123, 97, 207, 201, 57, 10, 231, 243, 92, 104, 47, 173, 31,
+ 150, 165, 181, 185, 164, 61, 218, 139, 103, 253, 146, 186, 181, 185, 47,
+ 90, 20, 163, 181, 185, 95, 127, 252, 62, 173, 205, 93, 91, 216, 207,
+ 166, 103, 47, 227, 182, 23, 181, 17, 123, 177, 135, 22, 181, 17, 123,
+ 25, 112, 161, 136, 77, 207, 94, 38, 31, 44, 76, 235, 107, 223, 236,
+ 40, 98, 35, 246, 178, 192, 163, 168, 77, 207, 94, 6, 28, 34, 239,
+ 54, 90, 110, 28, 95, 212, 70, 236, 165, 108, 189, 34, 54, 61, 123,
+ 233, 183, 175, 0, 173, 205, 141, 126, 146, 143, 214, 114, 255, 214, 232,
+ 73, 138, 158, 189, 100, 164, 39, 165, 16, 123, 241, 54, 111, 73, 33,
+ 246, 82, 110, 245, 182, 20, 61, 123, 41, 86, 185, 36, 173, 205, 37,
+ 52, 218, 11, 123, 46, 182, 23, 244, 135, 188, 189, 160, 127, 35, 246,
+ 66, 232, 79, 192, 94, 216, 115, 180, 151, 178, 239, 236, 119, 239, 4,
+ 123, 233, 82, 117, 18, 189, 35, 146, 180, 127, 15, 236, 229, 180, 148,
+ 38, 220, 167, 51, 53, 106, 39, 159, 142, 188, 72, 107, 115, 175, 212,
+ 80, 247, 235, 189, 192, 94, 98, 7, 228, 22, 206, 79, 61, 26, 133,
+ 202, 231, 7, 21, 73, 37, 246, 178, 113, 134, 186, 87, 158, 15, 236,
+ 229, 139, 205, 181, 132, 125, 243, 120, 13, 150, 251, 133, 53, 74, 37,
+ 246, 210, 120, 76, 251, 84, 117, 31, 98, 132, 236, 27, 221, 89, 216,
+ 215, 107, 219, 72, 57, 176, 114, 207, 84, 98, 47, 15, 246, 246, 211,
+ 250, 142, 145, 15, 15, 22, 207, 169, 159, 130, 189, 164, 118, 141, 161,
+ 181, 185, 121, 151, 71, 42, 116, 27, 176, 151, 106, 7, 134, 136, 247,
+ 247, 193, 94, 198, 7, 123, 209, 218, 220, 15, 60, 212, 239, 149, 183,
+ 3, 123, 57, 180, 195, 67, 172, 171, 184, 105, 242, 254, 120, 86, 155,
+ 75, 232, 149, 96, 47, 236, 185, 216, 94, 48, 182, 57, 213, 254, 63,
+ 97, 103, 157, 9, 141, 254, 133, 61, 71, 123, 25, 245, 206, 190, 36,
+ 126, 43, 226, 139, 132, 24, 90, 155, 75, 218, 99, 237, 255, 134, 147,
+ 209, 102, 61, 255, 210, 127, 84, 52, 173, 205, 157, 93, 153, 244, 237,
+ 36, 111, 62, 18, 165, 91, 155, 107, 233, 21, 69, 107, 115, 77, 215,
+ 213, 61, 77, 47, 176, 151, 149, 13, 35, 197, 125, 193, 191, 236, 108,
+ 49, 142, 214, 215, 78, 148, 198, 154, 137, 127, 249, 235, 205, 24, 179,
+ 158, 127, 121, 188, 144, 180, 25, 45, 123, 53, 24, 99, 38, 254, 197,
+ 239, 31, 241, 154, 233, 13, 216, 75, 116, 230, 40, 90, 155, 219, 168,
+ 232, 104, 237, 91, 182, 86, 249, 235, 240, 209, 58, 123, 124, 241, 114,
+ 252, 158, 40, 90, 155, 27, 127, 37, 74, 235, 59, 89, 142, 127, 19,
+ 165, 91, 155, 91, 233, 24, 171, 205, 37, 52, 250, 23, 246, 92, 188,
+ 206, 195, 121, 42, 173, 153, 234, 15, 243, 176, 177, 194, 57, 171, 83,
+ 109, 174, 9, 250, 166, 15, 212, 159, 179, 98, 59, 250, 189, 215, 8,
+ 174, 102, 106, 160, 187, 115, 86, 215, 107, 23, 140, 185, 244, 123, 175,
+ 17, 220, 57, 115, 156, 223, 13, 209, 106, 166, 6, 184, 59, 103, 205,
+ 38, 103, 9, 126, 154, 238, 191, 13, 226, 206, 203, 195, 187, 147, 177,
+ 88, 7, 184, 59, 103, 117, 45, 3, 177, 77, 207, 203, 15, 204, 82,
+ 51, 165, 205, 85, 125, 7, 184, 59, 103, 117, 45, 3, 237, 129, 230,
+ 215, 6, 58, 215, 170, 178, 185, 139, 213, 76, 104, 172, 85, 21, 205,
+ 105, 248, 117, 20, 234, 152, 231, 199, 98, 155, 213, 76, 104, 228, 39,
+ 138, 121, 78, 181, 190, 89, 248, 49, 223, 103, 53, 19, 26, 249, 137,
+ 124, 162, 83, 173, 111, 22, 126, 12, 27, 86, 51, 161, 145, 159, 8,
+ 51, 252, 58, 15, 113, 66, 107, 166, 194, 192, 14, 134, 232, 97, 134,
+ 213, 230, 250, 66, 223, 132, 190, 110, 212, 76, 245, 231, 106, 141, 250,
+ 113, 53, 83, 125, 141, 195, 12, 242, 165, 53, 83, 64, 163, 76, 37,
+ 183, 208, 199, 56, 204, 248, 114, 50, 112, 220, 100, 44, 150, 62, 198,
+ 97, 6, 249, 58, 213, 76, 105, 50, 210, 195, 140, 195, 12, 234, 157,
+ 207, 21, 184, 194, 12, 230, 10, 220, 197, 12, 234, 152, 231, 231, 10,
+ 51, 200, 207, 93, 204, 88, 120, 126, 111, 198, 165, 186, 194, 140, 101,
+ 68, 57, 183, 49, 131, 186, 227, 223, 207, 21, 102, 240, 253, 220, 197,
+ 12, 226, 132, 96, 198, 183, 7, 216, 65, 127, 61, 204, 176, 218, 220,
+ 244, 222, 225, 222, 33, 189, 220, 168, 153, 234, 205, 197, 128, 222, 140,
+ 191, 163, 167, 113, 152, 9, 225, 100, 164, 195, 59, 165, 107, 114, 34,
+ 122, 26, 135, 25, 228, 75, 199, 1, 52, 29, 75, 79, 227, 48, 19,
+ 210, 43, 75, 205, 84, 47, 45, 207, 223, 195, 56, 204, 160, 222, 115,
+ 138, 25, 62, 199, 29, 209, 51, 231, 152, 113, 202, 233, 247, 204, 57,
+ 102, 156, 114, 250, 61, 114, 142, 25, 126, 110, 134, 56, 161, 103, 138,
+ 186, 128, 29, 132, 233, 97, 134, 213, 230, 38, 116, 15, 247, 78, 236,
+ 166, 143, 25, 108, 71, 99, 64, 119, 238, 76, 81, 183, 156, 97, 134,
+ 207, 39, 250, 114, 50, 18, 66, 1, 251, 154, 156, 180, 174, 57, 195,
+ 12, 159, 79, 68, 190, 116, 63, 25, 222, 157, 140, 37, 164, 107, 206,
+ 48, 195, 231, 19, 145, 47, 143, 25, 148, 169, 140, 181, 75, 206, 48,
+ 67, 242, 137, 65, 154, 222, 169, 13, 109, 43, 184, 53, 108, 97, 222,
+ 119, 242, 137, 88, 171, 154, 250, 215, 219, 192, 236, 242, 137, 78, 103,
+ 138, 186, 114, 181, 180, 105, 5, 183, 254, 89, 98, 89, 74, 214, 124,
+ 147, 47, 240, 251, 95, 169, 234, 217, 230, 155, 156, 114, 250, 28, 63,
+ 203, 129, 130, 91, 131, 194, 174, 188, 147, 143, 176, 92, 90, 102, 254,
+ 227, 208, 234, 108, 243, 17, 78, 57, 253, 46, 206, 227, 237, 60, 238,
+ 221, 245, 42, 142, 183, 88, 193, 152, 108, 215, 171, 78, 103, 138, 186,
+ 112, 231, 35, 58, 2, 221, 67, 15, 51, 220, 189, 155, 157, 195, 189,
+ 67, 59, 185, 113, 166, 168, 51, 183, 15, 219, 153, 139, 51, 167, 91,
+ 184, 137, 25, 215, 245, 166, 121, 255, 215, 184, 62, 221, 135, 229, 100,
+ 56, 224, 157, 28, 154, 156, 18, 99, 90, 187, 137, 25, 215, 50, 42,
+ 124, 153, 196, 190, 247, 218, 137, 27, 7, 208, 100, 44, 37, 190, 8,
+ 113, 19, 51, 174, 101, 148, 77, 219, 199, 246, 147, 59, 101, 57, 83,
+ 212, 73, 149, 145, 55, 95, 27, 55, 49, 227, 90, 198, 5, 174, 54,
+ 23, 245, 206, 215, 230, 162, 30, 9, 63, 66, 227, 25, 112, 246, 60,
+ 251, 218, 220, 232, 113, 73, 26, 174, 2, 164, 66, 219, 47, 42, 180,
+ 60, 36, 76, 154, 190, 46, 31, 205, 223, 183, 133, 62, 125, 224, 47,
+ 138, 235, 251, 124, 202, 2, 137, 97, 117, 57, 205, 247, 227, 25, 112,
+ 17, 86, 77, 218, 25, 240, 25, 242, 125, 173, 77, 146, 180, 97, 210,
+ 99, 45, 39, 189, 78, 58, 123, 224, 133, 56, 23, 30, 187, 81, 154,
+ 188, 179, 136, 38, 119, 179, 84, 241, 185, 143, 66, 231, 138, 78, 150,
+ 54, 215, 204, 21, 36, 206, 31, 216, 165, 192, 190, 27, 52, 254, 105,
+ 82, 193, 51, 9, 106, 14, 62, 122, 187, 116, 124, 94, 71, 161, 92,
+ 83, 220, 46, 105, 247, 247, 205, 181, 54, 123, 164, 223, 154, 28, 111,
+ 160, 202, 221, 39, 5, 63, 243, 169, 47, 234, 155, 25, 123, 80, 242,
+ 120, 48, 80, 243, 67, 233, 210, 183, 179, 22, 168, 116, 244, 81, 233,
+ 245, 111, 105, 58, 57, 213, 19, 210, 208, 32, 226, 195, 78, 73, 255,
+ 244, 94, 171, 229, 99, 207, 72, 65, 179, 82, 116, 234, 152, 207, 75,
+ 77, 182, 29, 214, 218, 56, 164, 143, 22, 188, 76, 81, 223, 249, 178,
+ 180, 48, 89, 156, 67, 206, 140, 189, 38, 149, 105, 218, 138, 214, 196,
+ 217, 71, 132, 168, 121, 111, 172, 137, 251, 237, 43, 221, 154, 184, 159,
+ 254, 87, 150, 214, 196, 101, 78, 240, 209, 106, 241, 30, 74, 199, 215,
+ 220, 215, 173, 205, 45, 219, 242, 28, 173, 205, 237, 125, 249, 184, 86,
+ 215, 251, 82, 90, 51, 234, 160, 110, 109, 110, 197, 149, 23, 104, 109,
+ 110, 194, 202, 19, 180, 54, 247, 245, 202, 3, 186, 181, 185, 131, 226,
+ 214, 210, 218, 220, 123, 45, 102, 209, 218, 220, 180, 90, 29, 117, 107,
+ 115, 223, 92, 74, 214, 234, 79, 243, 202, 235, 122, 236, 221, 164, 246,
+ 205, 39, 95, 253, 97, 67, 3, 113, 95, 31, 249, 250, 202, 214, 154,
+ 93, 189, 39, 151, 95, 55, 67, 219, 23, 42, 32, 167, 205, 92, 175,
+ 179, 47, 84, 80, 94, 52, 230, 140, 214, 198, 87, 110, 242, 213, 29,
+ 173, 111, 97, 249, 214, 7, 111, 116, 250, 22, 145, 217, 30, 157, 31,
+ 165, 241, 12, 56, 191, 119, 231, 227, 81, 213, 84, 16, 254, 138, 120,
+ 84, 125, 167, 22, 5, 125, 51, 241, 67, 211, 193, 15, 161, 175, 37,
+ 126, 136, 208, 102, 240, 67, 236, 185, 107, 63, 180, 17, 252, 208, 159,
+ 109, 231, 211, 123, 70, 199, 141, 155, 169, 208, 173, 193, 15, 237, 73,
+ 142, 231, 252, 80, 53, 240, 67, 213, 192, 15, 177, 251, 12, 95, 128,
+ 31, 98, 49, 126, 57, 221, 71, 242, 0, 63, 36, 138, 241, 196, 15,
+ 45, 178, 215, 167, 181, 185, 7, 110, 5, 218, 136, 31, 122, 249, 126,
+ 176, 110, 109, 238, 165, 243, 53, 104, 109, 238, 245, 253, 31, 219, 136,
+ 31, 186, 191, 69, 252, 205, 219, 92, 113, 118, 105, 87, 70, 51, 90,
+ 155, 59, 249, 155, 161, 218, 55, 56, 183, 75, 17, 93, 103, 10, 251,
+ 62, 141, 221, 37, 245, 248, 114, 55, 173, 205, 61, 220, 228, 8, 173,
+ 205, 45, 41, 157, 213, 173, 205, 253, 170, 251, 86, 90, 155, 235, 215,
+ 101, 3, 173, 205, 61, 245, 237, 10, 155, 56, 87, 127, 66, 74, 120,
+ 243, 43, 173, 205, 125, 82, 102, 182, 246, 206, 103, 164, 38, 35, 35,
+ 197, 251, 96, 224, 135, 138, 174, 169, 78, 107, 115, 119, 238, 124, 168,
+ 252, 94, 111, 163, 46, 75, 121, 107, 205, 77, 209, 243, 67, 3, 138,
+ 94, 79, 38, 126, 232, 169, 41, 81, 253, 166, 0, 248, 33, 191, 34,
+ 71, 27, 136, 229, 222, 149, 174, 109, 148, 2, 137, 31, 42, 83, 187,
+ 67, 32, 241, 67, 95, 252, 17, 17, 168, 231, 135, 174, 79, 168, 31,
+ 72, 252, 208, 166, 247, 106, 4, 18, 63, 52, 245, 187, 18, 129, 122,
+ 126, 232, 204, 69, 178, 95, 107, 146, 219, 12, 240, 12, 36, 126, 104,
+ 246, 221, 139, 13, 244, 252, 80, 226, 134, 245, 13, 136, 31, 234, 177,
+ 245, 117, 125, 226, 135, 102, 183, 59, 182, 69, 207, 15, 21, 251, 188,
+ 34, 253, 70, 192, 197, 9, 221, 233, 55, 2, 118, 119, 79, 208, 253,
+ 70, 192, 179, 15, 22, 211, 111, 4, 60, 63, 189, 49, 133, 248, 161,
+ 204, 201, 7, 83, 244, 252, 208, 190, 67, 79, 83, 136, 31, 170, 177,
+ 40, 55, 173, 205, 253, 247, 104, 33, 221, 218, 92, 182, 247, 235, 71,
+ 105, 244, 67, 252, 158, 176, 232, 27, 1, 56, 127, 35, 126, 168, 50,
+ 248, 33, 156, 143, 17, 63, 68, 232, 194, 224, 135, 216, 115, 215, 181,
+ 185, 105, 45, 51, 45, 63, 127, 243, 146, 214, 230, 174, 120, 163, 214,
+ 230, 22, 3, 63, 180, 237, 227, 50, 194, 218, 220, 197, 224, 135, 216,
+ 218, 96, 57, 221, 159, 244, 3, 63, 36, 90, 27, 96, 223, 123, 224,
+ 135, 110, 252, 246, 3, 173, 205, 141, 45, 49, 67, 221, 111, 4, 63,
+ 212, 102, 90, 188, 112, 175, 178, 101, 220, 70, 233, 211, 162, 83, 104,
+ 109, 238, 130, 179, 125, 20, 218, 10, 126, 232, 195, 248, 134, 194, 190,
+ 131, 97, 62, 228, 63, 99, 20, 245, 67, 151, 231, 239, 84, 126, 195,
+ 212, 168, 237, 82, 88, 254, 230, 58, 54, 190, 75, 106, 80, 167, 2,
+ 253, 86, 201, 240, 193, 241, 74, 223, 254, 224, 135, 94, 62, 54, 9,
+ 127, 243, 21, 241, 7, 165, 144, 133, 85, 169, 31, 58, 253, 67, 1,
+ 229, 61, 95, 91, 143, 74, 63, 72, 67, 133, 239, 252, 19, 248, 161,
+ 157, 253, 30, 208, 123, 150, 111, 204, 174, 164, 252, 46, 255, 195, 154,
+ 184, 200, 86, 194, 188, 197, 142, 184, 243, 210, 245, 95, 172, 236, 254,
+ 243, 195, 243, 20, 250, 36, 248, 161, 231, 30, 226, 90, 85, 71, 228,
+ 53, 201, 199, 124, 146, 214, 230, 22, 41, 171, 214, 34, 207, 143, 186,
+ 45, 237, 185, 117, 77, 216, 55, 22, 252, 80, 163, 58, 71, 104, 109,
+ 174, 215, 133, 125, 90, 77, 240, 67, 105, 255, 52, 113, 109, 238, 85,
+ 240, 67, 35, 62, 98, 181, 185, 105, 77, 213, 218, 220, 220, 224, 135,
+ 170, 134, 234, 215, 230, 166, 218, 89, 109, 238, 207, 245, 55, 42, 116,
+ 8, 248, 161, 216, 245, 226, 241, 246, 223, 230, 41, 215, 121, 194, 106,
+ 115, 59, 159, 82, 107, 115, 7, 130, 31, 10, 93, 47, 174, 205, 61,
+ 9, 126, 168, 116, 195, 193, 180, 54, 247, 247, 196, 182, 234, 55, 151,
+ 131, 243, 201, 62, 5, 197, 181, 185, 75, 192, 15, 109, 241, 103, 181,
+ 185, 247, 207, 169, 181, 185, 91, 130, 11, 200, 195, 155, 220, 18, 218,
+ 198, 17, 240, 67, 131, 106, 30, 160, 181, 185, 193, 83, 183, 210, 218,
+ 220, 248, 127, 215, 233, 214, 230, 178, 51, 5, 126, 148, 198, 218, 92,
+ 254, 172, 129, 168, 54, 23, 215, 120, 124, 109, 238, 5, 174, 54, 247,
+ 2, 87, 155, 123, 193, 141, 218, 220, 113, 251, 88, 109, 110, 105, 173,
+ 54, 23, 215, 101, 133, 191, 20, 215, 230, 226, 186, 140, 229, 20, 150,
+ 211, 125, 111, 92, 151, 137, 114, 10, 100, 62, 148, 191, 41, 171, 205,
+ 173, 212, 149, 124, 235, 121, 157, 20, 56, 82, 167, 166, 16, 230, 67,
+ 165, 70, 199, 208, 218, 220, 61, 9, 164, 111, 178, 52, 114, 133, 222,
+ 55, 166, 237, 146, 227, 102, 12, 173, 205, 205, 245, 44, 198, 76, 214,
+ 101, 223, 121, 90, 205, 122, 126, 40, 230, 86, 12, 173, 205, 53, 221,
+ 38, 114, 247, 73, 177, 183, 197, 114, 61, 226, 14, 74, 155, 203, 88,
+ 105, 109, 110, 29, 173, 46, 185, 0, 204, 135, 30, 124, 35, 238, 91,
+ 28, 252, 208, 246, 46, 209, 180, 54, 183, 244, 42, 117, 175, 30, 253,
+ 144, 244, 92, 252, 125, 234, 80, 240, 67, 53, 27, 142, 166, 181, 185,
+ 94, 99, 212, 122, 211, 16, 88, 151, 29, 95, 47, 174, 85, 173, 13,
+ 243, 161, 241, 213, 250, 210, 218, 220, 26, 191, 132, 105, 245, 181, 183,
+ 165, 54, 101, 123, 11, 251, 222, 0, 63, 244, 237, 50, 86, 155, 91,
+ 61, 159, 90, 155, 251, 16, 252, 208, 229, 254, 226, 218, 220, 23, 224,
+ 135, 174, 21, 30, 68, 107, 115, 103, 46, 103, 181, 185, 159, 154, 245,
+ 107, 115, 71, 246, 99, 181, 185, 201, 3, 88, 109, 110, 190, 112, 253,
+ 218, 220, 21, 227, 89, 109, 174, 169, 45, 171, 205, 237, 89, 65, 92,
+ 155, 251, 20, 252, 144, 215, 19, 86, 155, 187, 99, 52, 171, 205, 13,
+ 207, 212, 175, 205, 253, 181, 52, 171, 205, 181, 238, 96, 181, 185, 29,
+ 7, 232, 215, 230, 102, 174, 103, 181, 185, 167, 207, 177, 218, 220, 191,
+ 114, 235, 215, 230, 178, 179, 42, 126, 148, 86, 190, 85, 242, 196, 189,
+ 218, 92, 37, 15, 72, 114, 195, 223, 132, 123, 135, 118, 209, 203, 9,
+ 178, 218, 220, 80, 232, 235, 248, 214, 141, 250, 143, 142, 92, 190, 174,
+ 3, 87, 255, 241, 173, 113, 123, 79, 200, 151, 230, 235, 128, 70, 153,
+ 234, 17, 27, 227, 246, 158, 66, 57, 25, 56, 110, 50, 150, 132, 246,
+ 198, 237, 61, 33, 95, 167, 250, 15, 77, 134, 127, 123, 227, 246, 158,
+ 80, 239, 70, 238, 215, 154, 190, 53, 118, 191, 22, 245, 105, 228, 126,
+ 173, 127, 123, 99, 247, 107, 17, 39, 116, 239, 233, 43, 176, 131, 142,
+ 122, 152, 225, 238, 205, 133, 190, 137, 237, 220, 248, 254, 248, 55, 220,
+ 158, 205, 215, 220, 222, 83, 59, 227, 48, 131, 124, 105, 13, 32, 208,
+ 40, 83, 137, 170, 109, 141, 195, 140, 63, 39, 3, 199, 77, 198, 18,
+ 210, 214, 56, 204, 32, 95, 167, 122, 118, 77, 134, 227, 43, 227, 48,
+ 131, 122, 55, 114, 191, 22, 117, 108, 228, 126, 109, 72, 91, 99, 247,
+ 107, 81, 119, 70, 238, 215, 34, 78, 232, 222, 83, 75, 176, 131, 111,
+ 244, 48, 195, 221, 155, 219, 6, 252, 121, 136, 27, 123, 79, 109, 184,
+ 24, 208, 134, 171, 205, 109, 157, 51, 204, 236, 245, 119, 176, 24, 192,
+ 201, 112, 192, 59, 57, 52, 57, 150, 214, 57, 195, 204, 238, 233, 185,
+ 217, 189, 185, 33, 220, 56, 128, 38, 99, 73, 111, 149, 51, 204, 220,
+ 169, 187, 147, 238, 215, 134, 134, 100, 217, 123, 10, 209, 106, 115, 91,
+ 229, 12, 51, 187, 182, 176, 253, 90, 212, 123, 118, 181, 170, 168, 83,
+ 198, 219, 245, 191, 119, 206, 241, 8, 248, 161, 254, 254, 43, 63, 212,
+ 103, 118, 252, 80, 87, 255, 149, 95, 168, 128, 31, 234, 197, 93, 126,
+ 116, 110, 214, 146, 155, 155, 125, 1, 118, 240, 149, 14, 102, 248, 218,
+ 92, 232, 235, 104, 238, 198, 220, 172, 37, 103, 207, 45, 184, 185, 89,
+ 115, 3, 231, 102, 45, 56, 123, 6, 26, 101, 42, 141, 154, 27, 56,
+ 55, 227, 100, 224, 184, 201, 88, 18, 190, 52, 112, 110, 214, 60, 203,
+ 220, 76, 147, 225, 255, 165, 129, 115, 179, 230, 198, 198, 25, 83, 115,
+ 99, 227, 12, 234, 211, 200, 56, 227, 255, 165, 177, 113, 6, 113, 66,
+ 231, 102, 77, 192, 14, 90, 234, 97, 134, 157, 217, 246, 135, 190, 137,
+ 205, 220, 152, 155, 125, 193, 205, 105, 62, 231, 230, 102, 205, 12, 156,
+ 155, 125, 206, 205, 205, 128, 70, 153, 202, 220, 172, 169, 129, 115, 51,
+ 78, 6, 142, 155, 140, 37, 164, 169, 129, 115, 179, 102, 89, 230, 102,
+ 154, 12, 71, 19, 3, 231, 102, 205, 140, 93, 207, 160, 142, 141, 92,
+ 207, 132, 52, 53, 118, 61, 131, 186, 51, 114, 61, 131, 56, 161, 152,
+ 153, 49, 216, 59, 241, 11, 23, 152, 25, 56, 98, 80, 143, 238, 67,
+ 149, 26, 7, 19, 63, 111, 104, 12, 254, 188, 81, 184, 247, 213, 252,
+ 83, 210, 62, 183, 135, 200, 163, 90, 108, 181, 215, 222, 216, 215, 242,
+ 206, 220, 172, 49, 23, 3, 26, 51, 254, 22, 57, 123, 59, 56, 246,
+ 176, 248, 134, 103, 245, 122, 212, 85, 49, 227, 229, 210, 14, 156, 98,
+ 25, 39, 195, 1, 239, 228, 208, 228, 248, 75, 217, 203, 152, 218, 62,
+ 120, 195, 234, 9, 211, 234, 170, 152, 209, 151, 129, 124, 233, 56, 128,
+ 166, 99, 153, 53, 56, 91, 25, 215, 66, 170, 165, 30, 26, 26, 23,
+ 172, 98, 198, 141, 113, 52, 202, 50, 55, 107, 164, 97, 102, 70, 246,
+ 50, 46, 189, 26, 101, 254, 41, 146, 212, 179, 103, 39, 195, 170, 96,
+ 38, 67, 211, 123, 21, 165, 165, 90, 11, 229, 204, 79, 253, 55, 244,
+ 147, 41, 18, 223, 123, 137, 169, 162, 105, 61, 252, 165, 194, 31, 221,
+ 235, 168, 86, 74, 62, 252, 193, 146, 36, 181, 69, 11, 153, 180, 205,
+ 243, 252, 107, 249, 218, 202, 232, 143, 69, 62, 251, 165, 119, 15, 185,
+ 248, 191, 113, 1, 234, 211, 129, 242, 219, 106, 39, 21, 58, 223, 227,
+ 177, 242, 31, 177, 53, 106, 11, 115, 110, 19, 38, 202, 29, 187, 207,
+ 213, 218, 204, 164, 116, 141, 179, 63, 112, 207, 179, 143, 61, 25, 154,
+ 93, 24, 165, 131, 230, 253, 61, 255, 116, 165, 131, 34, 43, 211, 63,
+ 210, 211, 193, 241, 41, 39, 107, 17, 29, 204, 30, 253, 241, 199, 68,
+ 7, 185, 175, 76, 253, 88, 79, 7, 33, 213, 30, 125, 76, 116, 64,
+ 104, 212, 1, 123, 46, 214, 1, 218, 173, 158, 14, 90, 191, 163, 131,
+ 194, 154, 14, 106, 82, 126, 209, 160, 3, 203, 234, 111, 26, 102, 213,
+ 65, 41, 208, 193, 65, 123, 77, 225, 220, 34, 79, 222, 30, 114, 190,
+ 239, 2, 236, 68, 7, 139, 6, 36, 40, 116, 41, 208, 193, 196, 37,
+ 87, 197, 123, 49, 160, 131, 169, 21, 62, 167, 117, 129, 132, 70, 29,
+ 176, 231, 98, 29, 32, 174, 156, 117, 96, 229, 230, 234, 42, 173, 218,
+ 1, 211, 201, 18, 147, 3, 116, 112, 17, 116, 112, 209, 201, 14, 250,
+ 86, 177, 154, 153, 14, 84, 26, 237, 32, 223, 3, 113, 46, 23, 237,
+ 96, 44, 229, 63, 80, 62, 221, 89, 109, 239, 3, 58, 88, 27, 38,
+ 206, 33, 163, 29, 124, 228, 59, 142, 214, 186, 17, 26, 117, 192, 158,
+ 235, 172, 207, 65, 7, 244, 123, 115, 83, 6, 123, 135, 54, 17, 197,
+ 128, 58, 206, 49, 96, 58, 180, 159, 54, 88, 63, 6, 64, 59, 234,
+ 59, 167, 51, 95, 150, 49, 117, 176, 155, 49, 192, 245, 92, 0, 241,
+ 78, 125, 39, 39, 195, 1, 239, 228, 208, 228, 88, 5, 50, 156, 99,
+ 128, 107, 25, 136, 39, 58, 142, 105, 220, 56, 128, 38, 99, 241, 157,
+ 234, 110, 12, 112, 45, 3, 237, 149, 142, 131, 147, 97, 210, 100, 226,
+ 127, 19, 167, 184, 27, 3, 92, 203, 64, 123, 160, 181, 105, 83, 7,
+ 59, 213, 126, 49, 191, 105, 53, 19, 122, 66, 176, 205, 34, 242, 167,
+ 78, 181, 105, 89, 248, 49, 31, 100, 53, 19, 26, 249, 137, 124, 147,
+ 83, 109, 90, 22, 126, 12, 207, 86, 51, 161, 199, 3, 63, 17, 206,
+ 157, 238, 161, 156, 226, 204, 143, 97, 195, 106, 38, 52, 190, 159, 8,
+ 51, 252, 188, 9, 113, 66, 115, 90, 227, 193, 14, 184, 248, 252, 46,
+ 102, 234, 58, 97, 38, 113, 242, 96, 111, 255, 73, 250, 152, 193, 118,
+ 116, 29, 48, 153, 241, 79, 154, 104, 28, 102, 252, 57, 25, 137, 240,
+ 78, 137, 154, 28, 203, 68, 227, 48, 131, 124, 233, 56, 128, 38, 99,
+ 73, 159, 96, 28, 102, 252, 39, 57, 99, 6, 101, 42, 235, 244, 9,
+ 198, 97, 6, 245, 78, 108, 40, 209, 242, 177, 75, 204, 36, 172, 91,
+ 237, 54, 102, 44, 89, 248, 185, 194, 12, 242, 115, 23, 51, 168, 79,
+ 122, 159, 23, 240, 115, 133, 25, 228, 231, 46, 102, 66, 39, 56, 191,
+ 159, 43, 204, 32, 63, 119, 49, 131, 56, 161, 57, 45, 43, 216, 193,
+ 20, 17, 102, 254, 231, 132, 153, 80, 232, 235, 136, 211, 199, 12, 182,
+ 163, 49, 32, 158, 241, 143, 136, 51, 14, 51, 200, 151, 198, 0, 160,
+ 81, 166, 210, 40, 206, 56, 204, 132, 114, 50, 112, 220, 100, 44, 9,
+ 177, 198, 97, 6, 249, 58, 229, 180, 52, 25, 254, 177, 198, 97, 6,
+ 245, 158, 83, 204, 56, 229, 180, 226, 114, 142, 25, 167, 156, 86, 108,
+ 206, 49, 227, 148, 211, 138, 205, 57, 102, 156, 114, 90, 86, 134, 153,
+ 144, 63, 192, 14, 198, 139, 48, 243, 137, 115, 156, 249, 19, 48, 182,
+ 198, 141, 56, 243, 39, 231, 159, 255, 100, 252, 3, 172, 57, 195, 140,
+ 83, 222, 140, 147, 145, 8, 239, 148, 168, 201, 73, 90, 157, 51, 204,
+ 56, 141, 99, 13, 55, 14, 160, 201, 88, 44, 171, 115, 134, 25, 167,
+ 113, 172, 201, 18, 103, 214, 104, 177, 236, 143, 156, 97, 134, 172, 207,
+ 131, 52, 189, 19, 27, 178, 134, 122, 167, 189, 4, 61, 103, 93, 151,
+ 89, 146, 42, 89, 94, 214, 187, 188, 46, 187, 181, 169, 83, 77, 245,
+ 106, 103, 126, 107, 64, 167, 174, 248, 173, 153, 144, 127, 189, 59, 252,
+ 44, 28, 191, 209, 109, 188, 211, 170, 159, 78, 125, 103, 191, 100, 244,
+ 230, 74, 150, 230, 207, 130, 27, 102, 183, 110, 116, 138, 91, 127, 56,
+ 191, 31, 234, 42, 235, 26, 172, 47, 188, 95, 239, 248, 152, 108, 215,
+ 96, 78, 53, 213, 127, 112, 152, 249, 5, 108, 205, 42, 194, 204, 167,
+ 78, 152, 73, 95, 53, 216, 59, 100, 165, 62, 102, 176, 29, 173, 69,
+ 94, 197, 197, 153, 229, 238, 98, 198, 91, 215, 214, 66, 56, 25, 233,
+ 240, 78, 233, 154, 156, 132, 223, 221, 197, 140, 190, 12, 228, 75, 199,
+ 1, 52, 25, 75, 210, 82, 119, 49, 227, 198, 56, 86, 58, 99, 6,
+ 101, 42, 255, 253, 197, 93, 204, 120, 11, 49, 179, 212, 67, 213, 123,
+ 21, 165, 165, 90, 235, 230, 42, 151, 129, 103, 42, 249, 222, 165, 193,
+ 30, 235, 194, 95, 51, 46, 159, 147, 214, 58, 211, 82, 207, 190, 43,
+ 137, 156, 169, 108, 250, 222, 0, 37, 46, 249, 159, 234, 46, 237, 107,
+ 88, 176, 14, 233, 219, 13, 250, 12, 131, 191, 73, 92, 223, 140, 162,
+ 179, 164, 101, 13, 8, 86, 151, 211, 188, 73, 222, 145, 27, 224, 121,
+ 246, 88, 85, 207, 99, 238, 144, 74, 62, 41, 190, 129, 156, 49, 148,
+ 90, 250, 109, 80, 243, 7, 167, 165, 185, 161, 133, 55, 144, 190, 251,
+ 160, 207, 113, 248, 59, 199, 245, 125, 233, 125, 93, 234, 151, 92, 103,
+ 61, 57, 175, 183, 238, 253, 117, 107, 145, 202, 61, 246, 153, 84, 169,
+ 86, 42, 125, 231, 107, 208, 231, 46, 252, 61, 230, 250, 190, 145, 77,
+ 114, 7, 107, 96, 93, 114, 110, 238, 78, 13, 139, 66, 231, 202, 204,
+ 43, 119, 236, 222, 180, 46, 233, 251, 10, 251, 120, 84, 52, 229, 243,
+ 168, 200, 125, 183, 172, 144, 204, 180, 233, 71, 233, 136, 27, 37, 101,
+ 94, 207, 69, 161, 79, 105, 248, 171, 204, 245, 37, 191, 27, 218, 178,
+ 81, 191, 219, 129, 27, 219, 214, 146, 223, 237, 242, 15, 105, 31, 147,
+ 223, 109, 249, 203, 211, 181, 245, 126, 183, 95, 38, 78, 115, 249, 187,
+ 253, 50, 49, 123, 159, 72, 127, 183, 142, 193, 244, 119, 107, 95, 179,
+ 30, 253, 221, 42, 214, 175, 171, 251, 187, 249, 207, 109, 72, 127, 183,
+ 79, 174, 22, 78, 34, 191, 219, 185, 218, 62, 117, 245, 126, 55, 159,
+ 200, 246, 244, 119, 43, 187, 170, 61, 253, 221, 46, 221, 106, 255, 255,
+ 254, 187, 161, 127, 32, 191, 219, 160, 234, 174, 127, 183, 204, 63, 245,
+ 127, 183, 184, 230, 153, 150, 61, 27, 223, 79, 37, 191, 91, 72, 188,
+ 250, 29, 180, 35, 167, 187, 75, 187, 192, 207, 80, 174, 239, 177, 63,
+ 122, 142, 251, 253, 89, 82, 200, 201, 84, 123, 214, 223, 173, 208, 168,
+ 13, 210, 176, 199, 217, 199, 30, 236, 187, 125, 242, 14, 233, 151, 50,
+ 165, 131, 201, 239, 214, 246, 235, 102, 10, 221, 233, 217, 105, 201, 55,
+ 169, 127, 48, 251, 221, 204, 240, 187, 53, 131, 223, 173, 37, 237, 91,
+ 49, 239, 117, 41, 215, 248, 184, 96, 242, 187, 101, 212, 142, 80, 232,
+ 79, 199, 61, 147, 126, 153, 25, 26, 204, 126, 183, 175, 224, 119, 107,
+ 5, 191, 91, 11, 218, 247, 10, 252, 110, 77, 203, 149, 9, 38, 191,
+ 91, 155, 127, 238, 43, 239, 249, 231, 171, 188, 114, 120, 135, 89, 13,
+ 217, 239, 102, 134, 223, 173, 30, 252, 110, 31, 179, 251, 148, 178, 249,
+ 221, 198, 252, 135, 223, 13, 125, 46, 249, 221, 102, 41, 120, 123, 55,
+ 214, 170, 120, 99, 191, 99, 105, 136, 177, 117, 225, 175, 25, 151, 239,
+ 220, 2, 120, 43, 112, 44, 146, 158, 61, 247, 185, 173, 210, 149, 1,
+ 111, 222, 30, 236, 236, 121, 55, 211, 121, 192, 219, 121, 192, 219, 121,
+ 39, 188, 45, 160, 49, 126, 57, 205, 173, 22, 0, 188, 137, 98, 60,
+ 246, 125, 6, 120, 179, 206, 141, 164, 103, 177, 191, 46, 165, 206, 163,
+ 115, 3, 222, 14, 254, 203, 190, 101, 182, 15, 228, 29, 135, 95, 237,
+ 156, 233, 44, 203, 149, 2, 222, 162, 94, 141, 162, 231, 154, 103, 159,
+ 85, 247, 200, 10, 1, 222, 126, 142, 103, 125, 175, 153, 78, 195, 239,
+ 118, 6, 126, 183, 51, 12, 171, 240, 187, 253, 86, 52, 138, 158, 47,
+ 206, 223, 80, 203, 203, 2, 222, 102, 239, 101, 239, 252, 10, 199, 233,
+ 113, 1, 126, 55, 246, 206, 153, 202, 239, 102, 53, 179, 223, 77, 165,
+ 135, 40, 191, 27, 211, 115, 81, 232, 83, 26, 254, 42, 115, 125, 233,
+ 156, 230, 23, 46, 223, 180, 8, 226, 244, 31, 162, 57, 77, 61, 231,
+ 57, 205, 207, 208, 62, 209, 141, 57, 205, 207, 220, 92, 224, 103, 46,
+ 223, 180, 196, 184, 181, 115, 8, 39, 35, 29, 222, 41, 93, 147, 99,
+ 89, 98, 220, 218, 25, 249, 210, 113, 0, 77, 198, 146, 190, 216, 184,
+ 181, 115, 72, 98, 150, 57, 77, 162, 150, 111, 90, 108, 96, 190, 105,
+ 137, 193, 249, 166, 37, 6, 231, 155, 22, 27, 156, 111, 90, 108, 112,
+ 190, 105, 17, 151, 111, 250, 17, 236, 224, 23, 17, 102, 234, 59, 231,
+ 155, 160, 175, 99, 129, 27, 249, 166, 69, 92, 158, 102, 33, 183, 14,
+ 88, 96, 96, 190, 105, 33, 151, 111, 2, 26, 101, 42, 141, 22, 24,
+ 152, 111, 226, 100, 224, 184, 201, 88, 18, 126, 50, 48, 223, 180, 32,
+ 75, 190, 73, 147, 225, 255, 147, 129, 249, 166, 5, 6, 231, 155, 22,
+ 24, 156, 111, 250, 201, 224, 124, 211, 79, 6, 231, 155, 126, 100, 152,
+ 9, 253, 30, 236, 96, 145, 0, 51, 181, 3, 156, 48, 227, 15, 125,
+ 19, 231, 233, 99, 6, 219, 209, 92, 208, 124, 46, 223, 52, 47, 103,
+ 152, 57, 219, 173, 100, 29, 154, 11, 154, 207, 229, 130, 128, 70, 153,
+ 202, 25, 170, 31, 114, 134, 153, 201, 223, 140, 11, 160, 227, 224, 100,
+ 224, 184, 201, 88, 66, 126, 200, 25, 102, 30, 157, 63, 196, 206, 80,
+ 205, 115, 198, 140, 191, 38, 195, 241, 125, 206, 48, 51, 231, 195, 254,
+ 44, 223, 52, 111, 112, 182, 103, 87, 81, 167, 255, 245, 44, 44, 234,
+ 56, 59, 126, 168, 191, 255, 202, 47, 68, 192, 15, 117, 245, 95, 249,
+ 161, 238, 178, 227, 135, 122, 249, 175, 103, 117, 17, 39, 116, 255, 124,
+ 54, 216, 193, 143, 34, 204, 100, 57, 67, 53, 23, 252, 249, 119, 110,
+ 236, 159, 207, 229, 98, 192, 92, 110, 255, 124, 142, 129, 251, 231, 156,
+ 12, 7, 188, 147, 67, 147, 99, 157, 99, 224, 254, 249, 119, 220, 56,
+ 128, 38, 99, 241, 157, 99, 224, 254, 249, 119, 89, 246, 207, 191, 211,
+ 246, 207, 103, 27, 184, 127, 62, 199, 216, 56, 99, 157, 99, 108, 156,
+ 241, 157, 99, 108, 156, 65, 221, 25, 25, 103, 16, 39, 4, 51, 233,
+ 153, 96, 7, 223, 139, 48, 227, 124, 230, 36, 49, 1, 48, 246, 198,
+ 141, 125, 141, 4, 206, 63, 191, 229, 226, 76, 130, 113, 152, 65, 190,
+ 52, 206, 0, 157, 168, 241, 14, 120, 99, 28, 102, 252, 57, 25, 56,
+ 110, 50, 150, 180, 215, 198, 97, 6, 249, 58, 197, 25, 77, 70, 200,
+ 107, 227, 48, 131, 122, 55, 114, 61, 131, 58, 54, 114, 61, 131, 250,
+ 52, 114, 61, 19, 242, 218, 216, 245, 12, 226, 132, 126, 43, 246, 1,
+ 204, 105, 102, 187, 192, 204, 160, 222, 195, 187, 247, 236, 62, 52, 98,
+ 196, 48, 211, 192, 222, 97, 236, 123, 217, 208, 55, 253, 229, 96, 239,
+ 176, 176, 48, 115, 88, 88, 30, 203, 154, 102, 151, 236, 159, 95, 250,
+ 233, 221, 187, 116, 51, 185, 245, 249, 43, 198, 223, 250, 60, 123, 59,
+ 152, 112, 102, 146, 253, 113, 225, 47, 27, 138, 238, 209, 249, 169, 204,
+ 109, 250, 221, 75, 228, 75, 215, 231, 64, 163, 76, 5, 51, 79, 179,
+ 151, 177, 183, 247, 123, 182, 85, 61, 31, 11, 239, 209, 185, 121, 98,
+ 62, 149, 17, 194, 201, 192, 113, 147, 177, 56, 30, 101, 47, 227, 243,
+ 97, 37, 182, 126, 187, 196, 203, 44, 186, 71, 167, 242, 161, 85, 236,
+ 155, 228, 47, 157, 49, 19, 162, 201, 72, 120, 144, 189, 140, 82, 126,
+ 157, 204, 147, 14, 91, 133, 247, 232, 36, 189, 141, 160, 247, 232, 160,
+ 222, 249, 123, 11, 80, 143, 132, 31, 161, 27, 111, 152, 43, 177, 231,
+ 174, 115, 165, 255, 182, 170, 47, 223, 170, 116, 147, 222, 163, 67, 218,
+ 123, 217, 91, 203, 83, 99, 111, 11, 191, 135, 231, 221, 168, 157, 156,
+ 80, 207, 91, 203, 77, 126, 43, 155, 11, 238, 83, 218, 23, 179, 119,
+ 146, 155, 172, 152, 32, 236, 123, 71, 14, 149, 187, 228, 253, 137, 222,
+ 139, 210, 106, 240, 32, 133, 174, 26, 29, 38, 87, 111, 47, 254, 118,
+ 214, 213, 216, 126, 242, 145, 25, 191, 4, 145, 115, 145, 53, 186, 223,
+ 85, 232, 7, 81, 225, 178, 189, 120, 153, 134, 194, 115, 145, 177, 67,
+ 228, 33, 94, 126, 90, 155, 225, 114, 231, 153, 197, 20, 218, 35, 122,
+ 164, 220, 184, 68, 73, 97, 223, 55, 177, 99, 228, 252, 65, 37, 180,
+ 54, 145, 114, 175, 194, 106, 95, 188, 23, 165, 184, 173, 176, 78, 223,
+ 120, 185, 250, 180, 92, 90, 155, 137, 114, 212, 239, 38, 77, 238, 100,
+ 121, 105, 252, 43, 157, 239, 14, 78, 147, 67, 234, 121, 53, 164, 103,
+ 122, 53, 26, 239, 45, 96, 207, 179, 143, 211, 104, 47, 136, 33, 222,
+ 94, 16, 19, 196, 94, 8, 253, 1, 216, 11, 123, 238, 218, 94, 150,
+ 130, 189, 148, 108, 204, 206, 244, 146, 246, 69, 192, 94, 172, 189, 26,
+ 9, 199, 113, 87, 110, 39, 143, 250, 59, 130, 222, 163, 179, 241, 151,
+ 85, 42, 13, 246, 82, 237, 210, 5, 225, 111, 94, 160, 81, 168, 60,
+ 122, 243, 110, 106, 47, 141, 38, 170, 223, 16, 44, 10, 246, 114, 188,
+ 236, 10, 225, 247, 165, 238, 128, 189, 132, 109, 79, 160, 246, 146, 59,
+ 237, 128, 66, 63, 3, 123, 137, 232, 34, 214, 95, 38, 216, 203, 210,
+ 145, 175, 131, 136, 189, 52, 145, 94, 104, 223, 169, 28, 41, 223, 202,
+ 255, 36, 72, 207, 94, 6, 109, 62, 19, 68, 236, 229, 121, 165, 131,
+ 65, 234, 111, 110, 149, 139, 188, 90, 27, 164, 103, 47, 207, 58, 206,
+ 10, 34, 246, 242, 116, 198, 116, 77, 238, 100, 249, 73, 218, 20, 93,
+ 123, 233, 208, 61, 41, 136, 216, 11, 161, 209, 94, 216, 115, 177, 189,
+ 160, 63, 36, 246, 242, 20, 236, 5, 253, 27, 177, 23, 66, 183, 254,
+ 115, 174, 196, 158, 187, 182, 151, 118, 82, 125, 249, 178, 119, 222, 173,
+ 196, 94, 72, 123, 219, 214, 214, 178, 215, 182, 121, 194, 57, 102, 181,
+ 198, 237, 228, 184, 106, 31, 167, 18, 123, 57, 59, 106, 129, 178, 167,
+ 147, 23, 236, 165, 220, 240, 197, 194, 113, 52, 50, 135, 202, 215, 35,
+ 66, 130, 137, 189, 60, 171, 242, 133, 66, 15, 141, 13, 147, 35, 155,
+ 53, 14, 22, 245, 45, 26, 215, 79, 78, 255, 170, 127, 67, 98, 47,
+ 143, 182, 91, 21, 91, 27, 7, 246, 210, 52, 98, 163, 240, 236, 249,
+ 11, 176, 151, 191, 31, 125, 64, 239, 224, 73, 63, 170, 214, 239, 44,
+ 142, 26, 41, 215, 105, 187, 64, 56, 222, 17, 49, 99, 228, 227, 215,
+ 211, 233, 61, 58, 169, 239, 95, 84, 232, 208, 40, 171, 188, 178, 245,
+ 43, 97, 223, 253, 96, 47, 133, 139, 31, 165, 247, 232, 120, 14, 82,
+ 191, 17, 245, 44, 106, 178, 188, 110, 199, 118, 97, 223, 215, 96, 47,
+ 157, 87, 236, 160, 231, 229, 9, 189, 5, 236, 133, 61, 23, 219, 11,
+ 198, 54, 222, 191, 96, 172, 34, 246, 66, 232, 2, 224, 95, 216, 243,
+ 108, 236, 5, 252, 203, 194, 164, 94, 244, 188, 60, 105, 95, 17, 252,
+ 203, 141, 17, 195, 132, 107, 136, 83, 224, 95, 252, 102, 70, 209, 123,
+ 116, 70, 251, 107, 223, 1, 2, 123, 9, 235, 32, 254, 14, 208, 51,
+ 136, 71, 39, 38, 143, 165, 247, 232, 252, 252, 84, 165, 125, 208, 191,
+ 152, 197, 107, 151, 167, 224, 95, 106, 159, 138, 161, 231, 244, 175, 237,
+ 86, 233, 247, 163, 195, 229, 249, 155, 196, 103, 252, 63, 140, 27, 34,
+ 207, 49, 69, 209, 59, 120, 124, 38, 168, 123, 79, 181, 193, 191, 156,
+ 203, 59, 92, 216, 119, 21, 248, 151, 19, 91, 251, 210, 123, 116, 62,
+ 175, 172, 126, 203, 231, 14, 216, 139, 207, 189, 80, 241, 120, 193, 94,
+ 174, 127, 221, 143, 222, 163, 99, 127, 170, 229, 55, 192, 191, 204, 152,
+ 55, 80, 247, 30, 157, 158, 157, 7, 210, 218, 2, 66, 163, 127, 97,
+ 207, 197, 235, 60, 156, 167, 210, 125, 171, 43, 48, 15, 203, 20, 206,
+ 89, 157, 238, 209, 73, 200, 128, 181, 206, 61, 253, 57, 43, 182, 163,
+ 235, 163, 251, 140, 191, 239, 157, 236, 231, 97, 101, 194, 174, 219, 251,
+ 87, 92, 162, 205, 89, 125, 92, 206, 195, 70, 221, 236, 72, 235, 37,
+ 145, 47, 93, 231, 1, 141, 50, 21, 110, 183, 178, 151, 113, 164, 198,
+ 14, 219, 249, 182, 185, 181, 57, 171, 107, 25, 119, 30, 70, 179, 154,
+ 76, 78, 6, 142, 155, 140, 37, 227, 122, 246, 50, 26, 46, 121, 158,
+ 250, 252, 211, 66, 218, 156, 213, 181, 140, 67, 121, 87, 179, 117, 222,
+ 189, 44, 235, 60, 77, 70, 232, 213, 236, 101, 124, 17, 217, 217, 252,
+ 73, 53, 50, 103, 117, 45, 163, 229, 37, 117, 206, 250, 173, 167, 170,
+ 247, 42, 74, 75, 213, 71, 160, 30, 9, 63, 66, 55, 5, 31, 193,
+ 158, 187, 246, 17, 15, 193, 71, 212, 26, 58, 135, 222, 229, 71, 218,
+ 227, 93, 91, 145, 101, 90, 136, 191, 23, 9, 62, 226, 117, 211, 175,
+ 82, 136, 143, 104, 118, 234, 134, 66, 207, 7, 31, 49, 33, 164, 174,
+ 176, 239, 16, 152, 131, 172, 9, 78, 166, 115, 144, 106, 107, 213, 111,
+ 122, 158, 43, 217, 79, 46, 249, 105, 9, 225, 60, 34, 58, 223, 96,
+ 249, 155, 55, 63, 208, 187, 31, 115, 159, 235, 167, 126, 43, 49, 112,
+ 132, 220, 56, 126, 147, 112, 254, 210, 59, 109, 164, 188, 254, 228, 66,
+ 173, 205, 104, 121, 164, 237, 119, 133, 190, 16, 60, 70, 238, 185, 48,
+ 73, 216, 247, 69, 218, 88, 185, 227, 123, 151, 82, 136, 143, 88, 18,
+ 121, 88, 251, 134, 179, 85, 126, 17, 60, 37, 69, 28, 23, 226, 229,
+ 146, 77, 170, 211, 57, 136, 169, 127, 73, 117, 14, 98, 158, 36, 15,
+ 206, 44, 44, 140, 191, 111, 211, 38, 203, 249, 239, 221, 214, 190, 67,
+ 58, 85, 254, 242, 135, 154, 218, 247, 64, 167, 201, 15, 219, 92, 215,
+ 249, 30, 232, 116, 185, 195, 179, 33, 244, 30, 64, 66, 159, 27, 51,
+ 139, 123, 158, 125, 60, 66, 91, 67, 252, 241, 182, 134, 120, 34, 182,
+ 70, 104, 92, 31, 177, 231, 174, 109, 237, 14, 216, 90, 239, 173, 54,
+ 106, 107, 164, 61, 174, 143, 102, 68, 132, 137, 191, 129, 13, 182, 86,
+ 38, 113, 52, 181, 181, 60, 221, 230, 40, 116, 2, 216, 90, 253, 33,
+ 203, 133, 58, 24, 0, 182, 38, 255, 251, 34, 133, 216, 218, 230, 146,
+ 223, 43, 250, 158, 14, 182, 118, 230, 94, 71, 161, 173, 13, 6, 91,
+ 91, 85, 176, 1, 157, 179, 94, 217, 84, 87, 225, 147, 6, 182, 22,
+ 168, 243, 29, 107, 180, 181, 223, 87, 63, 165, 182, 182, 97, 134, 122,
+ 239, 37, 218, 218, 212, 13, 181, 133, 227, 125, 14, 182, 214, 43, 45,
+ 148, 222, 27, 249, 143, 173, 55, 189, 55, 242, 227, 53, 99, 108, 122,
+ 243, 221, 158, 61, 167, 179, 123, 35, 15, 253, 160, 217, 203, 36, 185,
+ 99, 174, 133, 41, 122, 182, 54, 232, 48, 185, 159, 115, 170, 252, 253,
+ 46, 139, 141, 216, 90, 74, 74, 127, 155, 158, 173, 245, 45, 60, 159,
+ 218, 26, 161, 209, 214, 216, 115, 177, 173, 161, 31, 230, 109, 13, 253,
+ 42, 177, 53, 66, 127, 6, 182, 198, 158, 187, 182, 181, 221, 96, 107,
+ 109, 98, 182, 164, 18, 91, 35, 237, 243, 227, 29, 130, 83, 87, 166,
+ 138, 215, 71, 237, 228, 129, 167, 151, 210, 185, 114, 249, 197, 139, 82,
+ 137, 173, 45, 237, 254, 131, 176, 111, 39, 176, 181, 133, 62, 211, 232,
+ 157, 147, 99, 91, 171, 237, 159, 23, 239, 39, 167, 172, 250, 77, 216,
+ 183, 58, 216, 218, 155, 58, 243, 232, 124, 247, 7, 191, 57, 10, 125,
+ 28, 108, 237, 238, 161, 4, 97, 223, 126, 96, 107, 117, 75, 37, 208,
+ 59, 39, 107, 254, 79, 165, 255, 5, 91, 123, 191, 149, 184, 111, 221,
+ 109, 99, 229, 204, 148, 185, 116, 174, 188, 249, 196, 76, 133, 126, 5,
+ 182, 86, 175, 91, 184, 176, 239, 75, 107, 188, 60, 111, 144, 143, 157,
+ 216, 218, 141, 165, 234, 119, 110, 75, 91, 38, 201, 182, 22, 237, 133,
+ 243, 251, 122, 219, 38, 203, 55, 254, 45, 155, 74, 108, 173, 119, 195,
+ 46, 10, 237, 13, 182, 182, 185, 229, 76, 161, 92, 159, 109, 211, 229,
+ 127, 159, 237, 164, 243, 108, 66, 223, 0, 91, 99, 207, 197, 182, 134,
+ 241, 152, 183, 53, 140, 175, 196, 214, 8, 221, 4, 108, 141, 61, 119,
+ 109, 107, 247, 192, 214, 2, 54, 132, 211, 121, 54, 105, 143, 49, 116,
+ 75, 200, 16, 221, 251, 42, 87, 44, 25, 78, 231, 217, 87, 103, 170,
+ 243, 242, 197, 96, 107, 143, 162, 134, 10, 251, 14, 199, 24, 90, 51,
+ 156, 206, 179, 151, 254, 161, 242, 49, 131, 95, 155, 54, 93, 124, 127,
+ 99, 119, 176, 181, 34, 139, 70, 210, 185, 114, 163, 78, 35, 20, 122,
+ 39, 216, 218, 151, 249, 71, 8, 251, 134, 129, 173, 181, 152, 50, 130,
+ 222, 87, 89, 103, 137, 74, 163, 95, 203, 191, 81, 220, 247, 37, 248,
+ 181, 220, 237, 70, 208, 121, 118, 129, 67, 42, 237, 13, 182, 86, 243,
+ 175, 81, 186, 243, 236, 57, 19, 99, 232, 60, 187, 202, 95, 42, 237,
+ 13, 126, 237, 254, 65, 241, 218, 160, 32, 216, 218, 209, 41, 68, 39,
+ 83, 101, 243, 125, 245, 44, 90, 49, 176, 181, 166, 237, 196, 223, 174,
+ 244, 4, 91, 235, 86, 143, 205, 209, 9, 125, 22, 108, 141, 61, 23,
+ 207, 209, 113, 94, 78, 230, 232, 1, 23, 129, 126, 160, 55, 71, 103,
+ 247, 246, 133, 66, 95, 199, 37, 253, 57, 58, 182, 163, 123, 139, 151,
+ 185, 115, 50, 151, 220, 205, 43, 103, 179, 79, 82, 207, 171, 33, 221,
+ 91, 188, 204, 237, 45, 2, 141, 50, 149, 70, 151, 220, 205, 43, 187,
+ 150, 129, 185, 20, 58, 14, 78, 6, 142, 155, 140, 37, 193, 225, 110,
+ 94, 217, 181, 12, 92, 127, 211, 113, 92, 202, 114, 78, 70, 147, 145,
+ 116, 209, 221, 188, 178, 107, 25, 184, 102, 163, 231, 100, 46, 101, 169,
+ 215, 165, 249, 69, 171, 153, 208, 120, 247, 163, 40, 239, 232, 244, 29,
+ 200, 44, 252, 88, 254, 201, 106, 38, 52, 242, 19, 229, 165, 156, 190,
+ 3, 233, 112, 230, 199, 242, 19, 86, 51, 161, 145, 159, 40, 111, 225,
+ 84, 3, 115, 209, 153, 31, 91, 191, 90, 205, 132, 70, 126, 162, 117,
+ 45, 191, 23, 163, 224, 68, 227, 151, 113, 6, 236, 224, 138, 30, 102,
+ 216, 189, 125, 73, 23, 6, 123, 7, 156, 215, 199, 12, 182, 35, 118,
+ 16, 112, 129, 241, 79, 59, 231, 238, 186, 54, 27, 123, 134, 185, 53,
+ 145, 17, 192, 201, 72, 130, 119, 74, 210, 228, 132, 156, 115, 119, 93,
+ 235, 90, 6, 206, 169, 232, 56, 206, 115, 227, 0, 154, 140, 197, 113,
+ 214, 221, 117, 173, 107, 25, 24, 75, 233, 56, 206, 59, 99, 6, 101,
+ 42, 254, 229, 172, 187, 235, 90, 215, 50, 208, 135, 210, 253, 193, 115,
+ 89, 108, 156, 174, 81, 192, 198, 53, 250, 69, 35, 176, 113, 193, 218,
+ 197, 105, 127, 48, 11, 63, 54, 15, 181, 154, 9, 141, 252, 68, 243,
+ 83, 167, 115, 45, 103, 157, 249, 177, 185, 134, 213, 76, 104, 228, 39,
+ 154, 131, 240, 252, 34, 178, 240, 99, 241, 196, 106, 38, 52, 242, 19,
+ 197, 25, 30, 51, 136, 19, 130, 153, 164, 147, 96, 7, 23, 245, 48,
+ 195, 238, 237, 139, 128, 190, 25, 167, 244, 49, 131, 237, 136, 29, 100,
+ 156, 230, 246, 47, 79, 25, 23, 103, 144, 47, 145, 17, 1, 52, 202,
+ 84, 242, 77, 167, 140, 139, 51, 17, 156, 12, 28, 55, 25, 75, 226,
+ 63, 198, 197, 25, 228, 203, 99, 38, 66, 147, 17, 240, 143, 113, 113,
+ 6, 245, 206, 127, 175, 202, 85, 156, 193, 239, 85, 185, 27, 103, 124,
+ 179, 240, 115, 21, 103, 144, 159, 187, 113, 6, 245, 73, 249, 229, 137,
+ 76, 117, 21, 103, 252, 129, 159, 187, 113, 38, 224, 31, 231, 247, 115,
+ 21, 103, 240, 253, 220, 141, 51, 136, 19, 130, 153, 136, 163, 96, 7,
+ 103, 244, 48, 195, 238, 237, 11, 128, 190, 73, 199, 245, 49, 131, 237,
+ 104, 12, 56, 193, 248, 91, 142, 27, 23, 103, 144, 47, 141, 1, 64,
+ 163, 76, 108, 147, 126, 204, 184, 56, 19, 192, 201, 192, 113, 147, 177,
+ 132, 30, 51, 46, 206, 32, 95, 30, 51, 1, 154, 140, 140, 163, 198,
+ 197, 25, 212, 59, 181, 161, 183, 105, 193, 174, 226, 140, 105, 212, 5,
+ 179, 187, 113, 6, 117, 204, 243, 115, 21, 103, 144, 159, 187, 113, 38,
+ 148, 231, 119, 40, 45, 216, 85, 156, 177, 134, 93, 48, 187, 27, 103,
+ 80, 119, 148, 223, 203, 180, 96, 87, 113, 198, 50, 226, 130, 217, 221,
+ 56, 131, 56, 161, 123, 14, 7, 193, 14, 78, 234, 97, 230, 83, 250,
+ 123, 100, 28, 1, 127, 158, 174, 143, 25, 108, 71, 99, 192, 17, 174,
+ 86, 230, 176, 113, 113, 38, 130, 147, 145, 1, 239, 148, 161, 201, 177,
+ 28, 54, 46, 206, 32, 95, 58, 14, 160, 201, 88, 210, 15, 25, 23,
+ 103, 34, 210, 157, 49, 131, 50, 21, 92, 30, 50, 46, 206, 160, 222,
+ 115, 26, 103, 248, 243, 142, 150, 195, 57, 143, 51, 60, 63, 212, 103,
+ 78, 227, 12, 207, 47, 244, 80, 206, 227, 140, 83, 14, 224, 32, 87,
+ 43, 179, 23, 236, 224, 168, 30, 102, 184, 187, 32, 160, 175, 99, 191,
+ 27, 57, 128, 131, 220, 218, 249, 0, 151, 3, 216, 111, 92, 156, 65,
+ 190, 52, 7, 0, 52, 202, 84, 26, 237, 55, 46, 206, 132, 114, 50,
+ 112, 220, 100, 44, 9, 251, 140, 139, 51, 200, 215, 41, 7, 160, 201,
+ 240, 223, 103, 92, 156, 65, 189, 231, 52, 206, 240, 54, 105, 218, 159,
+ 243, 56, 195, 243, 67, 125, 230, 52, 206, 240, 252, 252, 247, 229, 60,
+ 206, 240, 152, 65, 156, 208, 90, 153, 93, 96, 7, 7, 245, 48, 195,
+ 221, 5, 1, 125, 19, 119, 235, 99, 6, 219, 209, 61, 225, 61, 220,
+ 25, 230, 221, 57, 139, 51, 252, 121, 76, 228, 75, 247, 182, 129, 70,
+ 153, 74, 158, 225, 239, 156, 197, 25, 254, 60, 166, 63, 39, 3, 199,
+ 77, 198, 18, 242, 119, 206, 226, 12, 127, 30, 19, 249, 58, 237, 109,
+ 107, 50, 28, 187, 114, 22, 103, 200, 121, 204, 32, 77, 239, 244, 158,
+ 239, 139, 5, 183, 162, 158, 179, 158, 199, 244, 191, 178, 204, 92, 185,
+ 244, 158, 108, 207, 215, 57, 157, 57, 254, 155, 227, 183, 183, 224, 86,
+ 212, 105, 214, 243, 122, 25, 142, 101, 230, 78, 19, 39, 186, 197, 47,
+ 132, 227, 151, 56, 162, 252, 86, 212, 97, 214, 243, 92, 105, 211, 86,
+ 152, 151, 127, 60, 59, 213, 29, 126, 168, 59, 138, 153, 214, 133, 182,
+ 166, 219, 122, 189, 115, 222, 39, 228, 222, 50, 243, 200, 97, 195, 204,
+ 34, 126, 180, 86, 102, 23, 87, 43, 179, 13, 236, 96, 175, 30, 102,
+ 184, 187, 32, 118, 130, 63, 223, 161, 143, 25, 108, 71, 99, 192, 78,
+ 174, 86, 102, 123, 206, 226, 12, 127, 30, 36, 148, 147, 225, 128, 119,
+ 114, 104, 114, 172, 219, 115, 22, 103, 248, 243, 32, 200, 151, 142, 3,
+ 104, 50, 22, 223, 237, 57, 139, 51, 252, 121, 144, 208, 29, 89, 106,
+ 101, 118, 104, 121, 134, 109, 57, 139, 51, 228, 60, 72, 144, 166, 119,
+ 250, 125, 159, 212, 130, 91, 215, 108, 59, 242, 206, 121, 16, 199, 197,
+ 101, 230, 168, 189, 117, 108, 238, 216, 164, 149, 227, 103, 217, 86, 112,
+ 107, 207, 197, 97, 239, 236, 249, 251, 3, 102, 218, 220, 140, 117, 139,
+ 159, 47, 199, 47, 241, 203, 66, 91, 23, 95, 158, 241, 206, 190, 174,
+ 227, 238, 50, 243, 210, 70, 235, 221, 194, 12, 234, 142, 242, 59, 83,
+ 112, 107, 80, 167, 145, 239, 236, 221, 37, 93, 94, 102, 190, 189, 103,
+ 176, 91, 152, 65, 156, 80, 204, 164, 130, 29, 236, 210, 193, 12, 119,
+ 23, 68, 98, 26, 96, 44, 85, 31, 51, 216, 142, 250, 231, 173, 140,
+ 255, 158, 201, 159, 187, 25, 103, 138, 184, 180, 131, 136, 30, 149, 183,
+ 80, 25, 91, 185, 56, 3, 52, 202, 84, 226, 196, 223, 69, 114, 185,
+ 23, 103, 92, 203, 8, 121, 156, 212, 128, 198, 25, 78, 6, 142, 155,
+ 140, 229, 243, 205, 205, 221, 140, 51, 174, 101, 212, 158, 158, 196, 206,
+ 130, 165, 102, 137, 51, 68, 198, 169, 236, 199, 225, 28, 103, 92, 203,
+ 216, 156, 17, 163, 96, 166, 158, 151, 170, 247, 42, 74, 75, 147, 105,
+ 118, 141, 15, 211, 80, 143, 132, 31, 161, 241, 59, 29, 236, 185, 106,
+ 59, 13, 76, 37, 157, 246, 127, 119, 180, 206, 180, 200, 95, 84, 165,
+ 119, 102, 159, 27, 49, 77, 161, 111, 71, 132, 73, 127, 61, 223, 35,
+ 60, 3, 158, 103, 202, 2, 137, 197, 183, 229, 180, 198, 160, 78, 244,
+ 74, 73, 20, 223, 148, 125, 201, 184, 213, 82, 242, 163, 10, 90, 155,
+ 36, 105, 127, 254, 79, 26, 168, 231, 145, 214, 73, 93, 218, 230, 23,
+ 158, 197, 41, 31, 183, 81, 10, 89, 58, 155, 222, 153, 93, 225, 167,
+ 59, 54, 245, 156, 101, 178, 180, 97, 127, 37, 187, 168, 239, 79, 177,
+ 118, 105, 79, 106, 172, 214, 38, 77, 218, 125, 96, 188, 93, 61, 103,
+ 185, 93, 66, 123, 21, 245, 61, 17, 187, 75, 90, 178, 184, 190, 214,
+ 102, 143, 180, 54, 185, 162, 93, 61, 103, 185, 79, 242, 57, 157, 95,
+ 216, 215, 39, 238, 160, 212, 254, 223, 146, 90, 155, 116, 233, 155, 47,
+ 189, 213, 179, 6, 209, 71, 165, 216, 144, 91, 194, 241, 158, 141, 61,
+ 33, 5, 214, 251, 134, 222, 153, 61, 165, 126, 144, 66, 231, 143, 62,
+ 35, 221, 14, 172, 40, 236, 251, 52, 246, 188, 212, 182, 219, 50, 122,
+ 103, 246, 217, 37, 59, 20, 250, 85, 212, 101, 105, 211, 197, 139, 194,
+ 190, 120, 103, 182, 229, 147, 123, 90, 155, 155, 210, 135, 141, 30, 105,
+ 231, 120, 110, 75, 69, 218, 60, 23, 246, 53, 197, 221, 149, 174, 36,
+ 60, 210, 218, 100, 72, 251, 54, 95, 87, 207, 75, 69, 63, 148, 22,
+ 56, 78, 235, 200, 125, 34, 157, 136, 252, 75, 107, 243, 92, 58, 125,
+ 86, 187, 83, 60, 250, 165, 148, 209, 96, 145, 176, 175, 71, 220, 107,
+ 201, 81, 105, 41, 105, 35, 55, 79, 248, 78, 61, 19, 104, 246, 144,
+ 39, 100, 198, 137, 229, 166, 121, 202, 213, 126, 39, 119, 69, 123, 201,
+ 27, 43, 189, 167, 142, 215, 156, 91, 222, 34, 191, 74, 17, 218, 243,
+ 182, 60, 114, 173, 182, 221, 180, 190, 121, 229, 82, 109, 2, 20, 186,
+ 144, 57, 159, 60, 172, 133, 135, 80, 238, 243, 52, 31, 185, 111, 224,
+ 34, 237, 76, 224, 123, 242, 255, 164, 42, 10, 46, 30, 71, 21, 148,
+ 205, 150, 21, 66, 28, 189, 142, 45, 44, 179, 218, 30, 63, 74, 111,
+ 121, 84, 76, 214, 171, 249, 33, 190, 4, 253, 43, 239, 75, 208, 95,
+ 210, 220, 136, 70, 163, 47, 97, 207, 93, 251, 146, 237, 224, 75, 122,
+ 6, 29, 14, 36, 190, 164, 72, 211, 26, 138, 252, 154, 67, 194, 164,
+ 208, 204, 8, 225, 187, 252, 5, 190, 132, 205, 109, 151, 211, 250, 147,
+ 66, 224, 75, 68, 115, 91, 69, 127, 177, 171, 165, 71, 55, 223, 6,
+ 18, 95, 242, 253, 93, 245, 46, 143, 87, 81, 235, 164, 152, 31, 163,
+ 235, 139, 109, 109, 163, 84, 179, 177, 103, 10, 241, 37, 81, 237, 99,
+ 85, 26, 124, 201, 204, 233, 219, 82, 196, 186, 183, 75, 87, 190, 243,
+ 161, 247, 94, 159, 140, 204, 175, 217, 248, 118, 9, 227, 146, 168, 175,
+ 87, 220, 46, 233, 246, 194, 11, 41, 196, 151, 68, 122, 70, 164, 168,
+ 231, 204, 247, 73, 95, 150, 202, 159, 44, 150, 123, 80, 250, 227, 220,
+ 161, 64, 226, 75, 58, 158, 254, 80, 209, 207, 155, 168, 163, 82, 106,
+ 163, 161, 58, 186, 58, 33, 213, 172, 65, 106, 166, 78, 73, 111, 146,
+ 215, 107, 125, 207, 72, 83, 91, 236, 18, 246, 125, 3, 190, 164, 106,
+ 229, 191, 131, 136, 47, 217, 123, 126, 183, 86, 199, 114, 89, 26, 48,
+ 111, 175, 78, 223, 107, 210, 225, 26, 187, 131, 136, 47, 41, 56, 123,
+ 103, 16, 241, 37, 45, 159, 111, 211, 233, 123, 87, 106, 184, 52, 37,
+ 136, 248, 18, 239, 85, 91, 52, 185, 15, 165, 163, 107, 55, 233, 244,
+ 125, 34, 213, 140, 39, 109, 158, 75, 91, 126, 222, 162, 201, 125, 41,
+ 53, 75, 75, 17, 246, 125, 27, 251, 90, 122, 85, 147, 198, 49, 185,
+ 234, 7, 105, 218, 185, 87, 15, 185, 73, 245, 205, 98, 185, 224, 75,
+ 236, 210, 119, 65, 196, 151, 36, 183, 85, 227, 170, 9, 124, 201, 142,
+ 222, 241, 98, 185, 105, 121, 228, 79, 190, 39, 117, 74, 121, 229, 225,
+ 251, 102, 171, 227, 5, 95, 178, 254, 237, 28, 157, 190, 62, 242, 140,
+ 244, 25, 65, 196, 151, 60, 49, 205, 212, 198, 91, 80, 222, 217, 125,
+ 166, 142, 174, 10, 203, 172, 238, 203, 143, 210, 155, 193, 151, 232, 213,
+ 131, 17, 95, 130, 243, 40, 226, 75, 58, 124, 240, 97, 26, 206, 139,
+ 136, 47, 33, 244, 124, 240, 37, 236, 57, 241, 37, 197, 157, 248, 133,
+ 180, 205, 180, 132, 22, 61, 108, 39, 190, 164, 166, 199, 103, 202, 220,
+ 186, 183, 28, 38, 93, 216, 62, 81, 120, 126, 178, 173, 215, 2, 137,
+ 173, 107, 151, 211, 218, 36, 219, 252, 149, 146, 104, 93, 139, 125, 63,
+ 30, 187, 90, 234, 153, 158, 102, 39, 190, 228, 200, 212, 122, 10, 206,
+ 154, 14, 95, 39, 249, 62, 254, 187, 161, 168, 239, 150, 241, 27, 165,
+ 15, 255, 173, 25, 76, 124, 73, 174, 80, 171, 66, 143, 141, 73, 150,
+ 234, 21, 89, 21, 44, 234, 59, 37, 220, 46, 21, 169, 243, 58, 152,
+ 248, 146, 54, 191, 120, 40, 115, 255, 146, 147, 182, 75, 56, 247, 20,
+ 245, 237, 99, 221, 37, 253, 240, 227, 223, 193, 196, 151, 196, 253, 182,
+ 76, 161, 3, 199, 237, 147, 102, 220, 152, 44, 148, 59, 16, 230, 37,
+ 125, 147, 58, 208, 239, 220, 245, 31, 93, 81, 161, 127, 6, 95, 178,
+ 40, 250, 164, 112, 188, 115, 198, 158, 144, 130, 71, 215, 165, 190, 228,
+ 158, 79, 128, 226, 183, 226, 98, 206, 72, 141, 146, 155, 9, 253, 223,
+ 45, 235, 121, 41, 170, 81, 239, 134, 196, 151, 204, 190, 241, 155, 122,
+ 166, 40, 242, 178, 228, 99, 58, 45, 148, 219, 27, 124, 73, 191, 93,
+ 175, 27, 18, 95, 82, 98, 80, 62, 229, 157, 183, 70, 221, 150, 206,
+ 60, 42, 42, 28, 239, 93, 240, 37, 35, 110, 151, 164, 223, 230, 187,
+ 100, 47, 174, 208, 18, 248, 146, 42, 179, 223, 23, 246, 237, 23, 247,
+ 68, 234, 218, 210, 39, 152, 248, 146, 78, 166, 103, 202, 59, 76, 6,
+ 95, 178, 163, 163, 248, 157, 243, 195, 188, 228, 147, 7, 137, 164, 141,
+ 252, 145, 105, 136, 66, 191, 13, 246, 144, 79, 149, 241, 23, 246, 45,
+ 182, 205, 83, 190, 122, 118, 10, 245, 37, 205, 62, 154, 172, 196, 138,
+ 218, 224, 75, 110, 148, 56, 36, 212, 243, 40, 152, 151, 244, 249, 169,
+ 149, 157, 248, 146, 66, 125, 127, 81, 232, 209, 224, 75, 58, 254, 121,
+ 94, 56, 103, 221, 12, 190, 164, 213, 130, 242, 169, 196, 151, 220, 146,
+ 205, 10, 221, 17, 230, 37, 95, 12, 139, 22, 226, 232, 37, 248, 18,
+ 86, 19, 232, 71, 233, 83, 224, 75, 244, 106, 5, 169, 47, 57, 197,
+ 230, 37, 243, 97, 94, 130, 235, 31, 226, 75, 8, 253, 57, 248, 18,
+ 246, 156, 248, 146, 30, 78, 252, 94, 192, 188, 100, 224, 176, 24, 250,
+ 45, 194, 77, 199, 212, 58, 174, 147, 131, 195, 164, 9, 23, 70, 9,
+ 177, 53, 121, 194, 2, 137, 229, 180, 150, 211, 186, 181, 107, 48, 47,
+ 17, 229, 180, 20, 95, 108, 93, 45, 221, 234, 74, 238, 103, 73, 146,
+ 106, 191, 85, 223, 161, 51, 172, 113, 112, 173, 39, 234, 187, 41, 126,
+ 163, 84, 167, 51, 233, 187, 89, 250, 123, 163, 250, 158, 165, 173, 201,
+ 146, 127, 238, 33, 194, 190, 225, 209, 118, 41, 166, 90, 23, 51, 241,
+ 37, 209, 101, 59, 43, 116, 9, 235, 118, 9, 215, 153, 162, 190, 135,
+ 192, 151, 140, 218, 49, 192, 76, 124, 73, 158, 63, 84, 89, 103, 35,
+ 247, 73, 249, 103, 137, 117, 53, 11, 230, 37, 91, 166, 142, 165, 223,
+ 94, 188, 255, 163, 250, 29, 198, 51, 224, 75, 150, 47, 143, 22, 246,
+ 189, 15, 243, 146, 207, 19, 201, 111, 116, 74, 186, 242, 175, 86, 179,
+ 7, 107, 156, 212, 210, 98, 93, 189, 133, 121, 201, 5, 250, 251, 58,
+ 164, 207, 61, 99, 180, 59, 229, 47, 75, 235, 18, 196, 114, 95, 131,
+ 47, 9, 56, 65, 206, 214, 222, 148, 110, 71, 71, 105, 114, 111, 75,
+ 191, 85, 143, 50, 235, 205, 75, 126, 191, 29, 73, 191, 23, 89, 89,
+ 251, 174, 101, 46, 240, 37, 191, 20, 143, 210, 121, 231, 39, 210, 237,
+ 249, 164, 205, 115, 105, 180, 103, 180, 153, 204, 75, 242, 12, 212, 123,
+ 231, 215, 82, 80, 121, 106, 243, 114, 234, 16, 141, 134, 121, 137, 101,
+ 103, 140, 88, 46, 204, 75, 90, 190, 136, 161, 223, 169, 156, 245, 72,
+ 211, 21, 248, 146, 35, 119, 197, 125, 113, 141, 51, 246, 40, 105, 147,
+ 87, 14, 171, 164, 210, 121, 192, 151, 180, 26, 46, 126, 231, 60, 219,
+ 124, 228, 230, 121, 200, 120, 223, 147, 191, 24, 162, 98, 176, 8, 204,
+ 75, 202, 55, 27, 109, 22, 175, 233, 10, 203, 172, 94, 212, 143, 210,
+ 56, 47, 209, 171, 35, 165, 57, 178, 84, 110, 255, 50, 101, 176, 183,
+ 255, 54, 189, 28, 25, 171, 51, 76, 180, 67, 123, 155, 27, 57, 50,
+ 59, 151, 191, 178, 51, 254, 155, 63, 127, 47, 151, 123, 121, 101, 215,
+ 121, 159, 14, 49, 5, 105, 142, 204, 159, 147, 145, 8, 239, 148, 168,
+ 201, 241, 111, 153, 189, 12, 231, 188, 178, 107, 25, 5, 191, 89, 155,
+ 76, 199, 97, 227, 198, 1, 52, 25, 75, 117, 255, 174, 110, 230, 149,
+ 93, 203, 24, 112, 103, 61, 171, 101, 180, 101, 249, 78, 190, 77, 219,
+ 35, 173, 220, 213, 205, 188, 178, 107, 25, 21, 184, 28, 25, 234, 157,
+ 196, 15, 19, 196, 15, 212, 35, 221, 191, 212, 232, 10, 16, 63, 216,
+ 115, 213, 118, 170, 155, 74, 57, 251, 226, 150, 153, 150, 27, 101, 143,
+ 208, 185, 232, 175, 245, 206, 42, 244, 117, 88, 215, 222, 148, 174, 11,
+ 99, 232, 123, 83, 23, 72, 44, 159, 189, 156, 214, 52, 190, 137, 90,
+ 41, 137, 242, 217, 42, 206, 87, 75, 190, 82, 21, 27, 137, 31, 62,
+ 55, 203, 105, 249, 151, 117, 146, 247, 172, 18, 226, 122, 38, 88, 215,
+ 190, 191, 176, 60, 205, 145, 45, 106, 90, 67, 235, 155, 44, 85, 123,
+ 80, 71, 167, 6, 203, 46, 229, 58, 255, 5, 93, 215, 230, 233, 161,
+ 230, 158, 252, 96, 93, 27, 118, 163, 135, 176, 111, 47, 88, 215, 142,
+ 77, 251, 205, 70, 226, 135, 61, 92, 125, 207, 125, 176, 174, 45, 189,
+ 227, 159, 6, 194, 119, 182, 30, 148, 230, 95, 168, 219, 144, 196, 143,
+ 3, 27, 26, 41, 116, 203, 232, 163, 210, 228, 137, 109, 133, 231, 50,
+ 190, 131, 248, 49, 242, 248, 18, 58, 23, 173, 125, 102, 136, 66, 63,
+ 133, 117, 237, 171, 146, 149, 133, 103, 48, 238, 67, 252, 184, 179, 118,
+ 11, 93, 215, 62, 120, 255, 176, 66, 103, 70, 93, 150, 164, 49, 87,
+ 117, 190, 177, 112, 77, 42, 222, 246, 31, 186, 174, 189, 63, 254, 44,
+ 93, 215, 254, 253, 215, 69, 157, 190, 119, 37, 71, 220, 3, 186, 174,
+ 221, 62, 254, 126, 16, 201, 145, 253, 58, 241, 174, 176, 175, 39, 204,
+ 69, 131, 71, 159, 167, 235, 218, 181, 53, 212, 117, 106, 30, 136, 31,
+ 151, 206, 172, 19, 246, 197, 248, 209, 181, 251, 100, 186, 174, 173, 210,
+ 163, 83, 16, 137, 31, 39, 61, 170, 138, 223, 25, 226, 135, 207, 149,
+ 196, 64, 18, 63, 82, 95, 239, 10, 84, 235, 88, 114, 203, 94, 37,
+ 255, 21, 222, 59, 252, 2, 214, 181, 79, 204, 108, 93, 187, 247, 214,
+ 92, 133, 206, 13, 241, 99, 238, 119, 63, 234, 212, 145, 250, 200, 71,
+ 46, 53, 164, 235, 218, 213, 155, 212, 124, 207, 91, 152, 139, 134, 22,
+ 24, 94, 95, 172, 231, 194, 50, 171, 37, 246, 163, 52, 230, 200, 244,
+ 106, 140, 137, 47, 65, 255, 74, 124, 9, 126, 135, 30, 253, 37, 241,
+ 37, 132, 54, 131, 47, 97, 207, 179, 241, 37, 48, 23, 141, 29, 58,
+ 208, 70, 124, 137, 247, 233, 169, 10, 109, 1, 95, 114, 182, 219, 207,
+ 226, 92, 238, 148, 5, 18, 219, 203, 90, 78, 107, 86, 61, 97, 46,
+ 42, 218, 203, 82, 253, 193, 106, 233, 198, 192, 41, 212, 151, 28, 177,
+ 206, 85, 232, 220, 224, 75, 14, 206, 93, 34, 196, 116, 190, 184, 141,
+ 210, 237, 192, 253, 212, 151, 252, 30, 184, 70, 251, 70, 79, 178, 20,
+ 88, 127, 182, 176, 239, 57, 240, 37, 3, 109, 177, 13, 136, 47, 105,
+ 82, 33, 116, 139, 186, 222, 218, 46, 93, 217, 191, 37, 89, 212, 55,
+ 45, 118, 151, 84, 245, 135, 189, 212, 151, 36, 237, 113, 104, 121, 239,
+ 125, 82, 243, 23, 207, 132, 114, 243, 194, 186, 246, 203, 37, 100, 92,
+ 233, 82, 187, 222, 95, 105, 227, 61, 42, 173, 41, 186, 95, 88, 71,
+ 122, 5, 124, 137, 231, 189, 55, 129, 196, 151, 60, 127, 113, 66, 161,
+ 63, 133, 185, 232, 55, 94, 171, 133, 54, 126, 1, 124, 201, 163, 126,
+ 29, 104, 190, 189, 123, 147, 197, 10, 125, 19, 124, 73, 211, 35, 135,
+ 133, 239, 252, 12, 124, 201, 200, 181, 103, 104, 190, 125, 228, 246, 243,
+ 52, 223, 30, 126, 204, 97, 211, 243, 37, 103, 222, 238, 163, 249, 246,
+ 57, 237, 118, 218, 72, 142, 172, 229, 10, 187, 78, 223, 39, 82, 235,
+ 219, 54, 154, 111, 223, 16, 186, 197, 70, 230, 162, 37, 254, 217, 40,
+ 236, 107, 130, 117, 109, 141, 101, 235, 105, 190, 253, 222, 235, 101, 54,
+ 146, 35, 251, 173, 221, 66, 155, 158, 47, 41, 244, 225, 24, 154, 111,
+ 127, 61, 180, 175, 141, 228, 200, 76, 201, 237, 117, 234, 117, 243, 200,
+ 189, 34, 251, 210, 124, 251, 139, 203, 253, 109, 36, 71, 54, 243, 139,
+ 65, 54, 61, 95, 114, 250, 127, 4, 131, 239, 201, 5, 222, 14, 178,
+ 145, 28, 217, 136, 239, 134, 216, 244, 124, 9, 171, 21, 247, 163, 52,
+ 206, 69, 245, 106, 200, 137, 47, 193, 121, 20, 241, 37, 54, 240, 37,
+ 56, 47, 34, 190, 132, 208, 85, 193, 151, 176, 231, 196, 151, 148, 112,
+ 226, 55, 31, 124, 137, 87, 239, 43, 116, 94, 178, 254, 171, 42, 202,
+ 186, 250, 71, 88, 215, 126, 177, 161, 139, 112, 141, 189, 10, 214, 181,
+ 108, 31, 123, 57, 173, 73, 190, 0, 190, 68, 180, 143, 141, 125, 11,
+ 196, 175, 150, 182, 21, 77, 75, 37, 190, 164, 215, 147, 131, 10, 253,
+ 101, 204, 58, 169, 228, 213, 179, 194, 179, 86, 119, 193, 151, 180, 14,
+ 242, 216, 74, 124, 201, 216, 133, 143, 149, 246, 111, 103, 37, 75, 143,
+ 190, 185, 46, 236, 187, 111, 188, 93, 186, 209, 99, 113, 42, 241, 37,
+ 59, 54, 116, 87, 232, 74, 224, 75, 154, 213, 203, 35, 236, 59, 126,
+ 194, 46, 41, 169, 201, 77, 234, 75, 166, 191, 63, 69, 153, 79, 44,
+ 137, 218, 39, 173, 253, 177, 170, 240, 59, 64, 107, 6, 28, 148, 130,
+ 207, 255, 70, 115, 100, 99, 218, 109, 86, 232, 123, 99, 143, 74, 183,
+ 223, 223, 39, 236, 59, 215, 122, 66, 58, 112, 116, 105, 48, 241, 37,
+ 230, 66, 243, 21, 122, 18, 204, 75, 186, 124, 61, 77, 216, 55, 32,
+ 254, 188, 36, 143, 142, 15, 38, 190, 100, 223, 228, 126, 10, 93, 53,
+ 230, 178, 52, 44, 119, 11, 97, 223, 55, 209, 215, 164, 99, 126, 36,
+ 87, 117, 83, 74, 90, 252, 82, 25, 239, 202, 168, 219, 82, 250, 39,
+ 151, 132, 115, 169, 137, 224, 75, 78, 7, 189, 79, 115, 100, 7, 51,
+ 84, 186, 11, 248, 146, 45, 75, 139, 9, 229, 214, 135, 121, 73, 159,
+ 106, 158, 52, 71, 118, 111, 215, 117, 69, 86, 67, 240, 37, 243, 62,
+ 219, 43, 148, 27, 12, 190, 164, 102, 202, 18, 154, 35, 123, 47, 100,
+ 168, 66, 251, 131, 47, 25, 94, 170, 138, 176, 239, 123, 219, 60, 229,
+ 110, 7, 194, 104, 142, 108, 253, 237, 135, 138, 143, 47, 7, 190, 164,
+ 230, 163, 59, 66, 76, 143, 134, 117, 237, 151, 109, 218, 211, 28, 89,
+ 245, 124, 191, 43, 244, 56, 240, 37, 150, 31, 28, 194, 58, 240, 95,
+ 113, 239, 238, 64, 5, 154, 35, 43, 218, 215, 162, 214, 159, 71, 22,
+ 148, 231, 15, 143, 18, 218, 228, 85, 240, 37, 236, 91, 0, 126, 148,
+ 62, 14, 190, 68, 239, 27, 1, 196, 151, 224, 122, 137, 248, 146, 185,
+ 224, 75, 42, 112, 57, 50, 66, 227, 222, 93, 133, 44, 57, 178, 234,
+ 166, 8, 39, 126, 123, 192, 151, 248, 53, 137, 162, 57, 50, 191, 178,
+ 234, 250, 252, 85, 68, 152, 84, 115, 187, 120, 125, 94, 19, 230, 37,
+ 236, 12, 203, 114, 90, 115, 94, 19, 124, 137, 232, 12, 11, 246, 149,
+ 227, 86, 75, 147, 251, 15, 162, 57, 178, 85, 33, 234, 247, 135, 66,
+ 96, 94, 82, 226, 211, 62, 194, 115, 150, 79, 96, 141, 211, 170, 94,
+ 87, 154, 35, 203, 157, 174, 126, 235, 104, 149, 53, 89, 26, 217, 191,
+ 167, 176, 111, 51, 171, 93, 122, 94, 104, 56, 205, 145, 13, 91, 163,
+ 214, 84, 111, 139, 220, 46, 201, 77, 197, 245, 216, 111, 97, 94, 82,
+ 249, 172, 149, 230, 200, 134, 182, 81, 219, 215, 141, 217, 39, 141, 250,
+ 55, 82, 216, 119, 43, 172, 113, 254, 55, 38, 130, 230, 200, 34, 98,
+ 212, 26, 248, 199, 81, 71, 165, 13, 19, 197, 231, 74, 207, 193, 188,
+ 228, 219, 126, 67, 105, 142, 172, 88, 127, 245, 253, 111, 131, 47, 249,
+ 173, 255, 72, 157, 119, 62, 47, 205, 90, 56, 138, 230, 200, 78, 149,
+ 27, 163, 229, 170, 46, 75, 21, 127, 30, 43, 236, 123, 3, 230, 37,
+ 51, 90, 176, 28, 217, 196, 43, 42, 253, 6, 124, 201, 232, 177, 226,
+ 251, 167, 51, 193, 151, 124, 86, 44, 138, 230, 200, 26, 21, 100, 57,
+ 178, 214, 121, 162, 116, 222, 249, 137, 148, 118, 144, 229, 200, 242, 52,
+ 136, 214, 114, 115, 47, 165, 22, 191, 139, 229, 226, 26, 39, 53, 128,
+ 229, 200, 38, 141, 97, 57, 178, 144, 237, 58, 191, 47, 204, 75, 174,
+ 189, 97, 57, 178, 190, 79, 89, 142, 236, 223, 187, 49, 58, 245, 246,
+ 121, 228, 126, 123, 89, 142, 236, 247, 98, 44, 71, 118, 177, 167, 248,
+ 157, 115, 111, 243, 145, 7, 222, 138, 164, 57, 178, 223, 251, 168, 24,
+ 204, 7, 243, 18, 175, 94, 163, 117, 116, 85, 88, 102, 223, 122, 240,
+ 163, 52, 206, 75, 244, 190, 1, 65, 207, 43, 167, 112, 223, 92, 222,
+ 52, 216, 27, 115, 102, 226, 28, 25, 171, 191, 244, 135, 190, 137, 91,
+ 220, 56, 175, 156, 194, 229, 175, 146, 185, 243, 202, 105, 198, 213, 197,
+ 32, 95, 154, 191, 2, 26, 101, 42, 50, 182, 24, 87, 23, 227, 207,
+ 201, 192, 113, 147, 177, 164, 109, 54, 174, 46, 6, 249, 58, 157, 35,
+ 211, 100, 132, 108, 54, 174, 46, 6, 245, 110, 100, 253, 37, 234, 216,
+ 200, 250, 75, 212, 167, 145, 245, 151, 33, 155, 141, 173, 191, 68, 156,
+ 16, 204, 36, 172, 7, 59, 72, 209, 195, 12, 171, 191, 12, 129, 190,
+ 233, 27, 221, 248, 230, 242, 38, 238, 91, 197, 127, 49, 254, 161, 27,
+ 141, 171, 139, 65, 190, 244, 155, 203, 64, 163, 76, 197, 99, 111, 48,
+ 174, 46, 38, 132, 147, 129, 227, 38, 99, 177, 110, 48, 174, 46, 6,
+ 249, 58, 125, 115, 89, 147, 225, 187, 193, 184, 186, 24, 212, 187, 145,
+ 245, 151, 168, 99, 35, 235, 47, 173, 27, 140, 173, 191, 244, 221, 96,
+ 108, 253, 37, 226, 132, 126, 79, 198, 18, 238, 157, 190, 73, 15, 51,
+ 172, 254, 210, 23, 250, 38, 172, 213, 199, 12, 182, 35, 118, 144, 176,
+ 142, 241, 247, 95, 107, 92, 156, 65, 190, 68, 134, 47, 208, 40, 83,
+ 153, 197, 38, 25, 23, 103, 124, 57, 25, 56, 110, 50, 22, 75, 146,
+ 113, 113, 6, 249, 242, 152, 241, 213, 100, 36, 193, 111, 99, 84, 156,
+ 65, 189, 27, 89, 127, 137, 58, 54, 178, 254, 210, 146, 100, 108, 253,
+ 37, 234, 206, 200, 250, 75, 196, 9, 253, 182, 127, 227, 71, 158, 9,
+ 235, 245, 48, 195, 213, 95, 102, 132, 123, 103, 124, 245, 200, 83, 183,
+ 254, 18, 218, 209, 26, 252, 144, 55, 158, 244, 23, 135, 190, 70, 197,
+ 25, 228, 75, 109, 173, 199, 35, 79, 148, 169, 216, 156, 64, 198, 127,
+ 141, 51, 200, 151, 214, 69, 3, 95, 50, 150, 196, 54, 217, 203, 248,
+ 175, 113, 6, 249, 242, 152, 65, 153, 202, 254, 101, 227, 236, 101, 252,
+ 215, 56, 131, 122, 55, 178, 254, 210, 55, 11, 191, 156, 214, 95, 162,
+ 62, 141, 172, 191, 68, 221, 25, 89, 127, 137, 56, 161, 223, 147, 233,
+ 11, 118, 192, 249, 51, 215, 152, 97, 245, 151, 9, 141, 160, 175, 172,
+ 143, 25, 108, 71, 99, 64, 35, 246, 219, 39, 74, 217, 219, 129, 59,
+ 113, 102, 210, 194, 8, 59, 141, 1, 156, 140, 4, 120, 167, 4, 77,
+ 142, 111, 255, 236, 101, 184, 19, 103, 22, 116, 98, 53, 43, 200, 151,
+ 142, 3, 104, 50, 150, 196, 126, 217, 203, 112, 39, 206, 216, 46, 60,
+ 11, 166, 227, 144, 157, 49, 131, 50, 149, 117, 153, 64, 134, 59, 113,
+ 166, 249, 160, 110, 20, 51, 168, 247, 236, 238, 238, 66, 157, 50, 222,
+ 174, 255, 189, 51, 247, 233, 159, 61, 63, 212, 223, 127, 229, 135, 250,
+ 204, 142, 31, 234, 234, 191, 242, 11, 16, 240, 67, 189, 184, 203, 143,
+ 126, 79, 166, 47, 195, 76, 68, 47, 160, 57, 127, 230, 26, 51, 172,
+ 254, 50, 0, 250, 38, 133, 233, 99, 6, 219, 209, 239, 176, 244, 97,
+ 252, 45, 97, 57, 139, 51, 163, 63, 107, 79, 231, 102, 200, 151, 198,
+ 50, 160, 81, 166, 146, 113, 235, 157, 179, 56, 147, 158, 60, 138, 206,
+ 205, 2, 56, 25, 56, 110, 50, 150, 208, 222, 57, 139, 51, 127, 124,
+ 249, 47, 197, 12, 242, 117, 250, 158, 140, 38, 35, 163, 87, 206, 226,
+ 76, 207, 251, 61, 216, 247, 100, 194, 178, 183, 33, 212, 233, 127, 181,
+ 73, 212, 113, 118, 252, 80, 127, 255, 149, 95, 168, 128, 31, 234, 234,
+ 191, 242, 67, 221, 101, 199, 15, 245, 242, 95, 49, 163, 224, 132, 172,
+ 107, 35, 193, 14, 250, 234, 96, 166, 14, 171, 191, 204, 232, 249, 200,
+ 51, 49, 90, 31, 51, 216, 142, 230, 155, 98, 24, 127, 107, 207, 156,
+ 197, 25, 167, 188, 89, 12, 147, 225, 15, 116, 134, 198, 59, 32, 58,
+ 103, 113, 198, 41, 111, 198, 201, 192, 113, 147, 177, 164, 69, 229, 44,
+ 206, 56, 229, 205, 162, 157, 49, 227, 175, 201, 8, 137, 202, 89, 156,
+ 113, 250, 110, 89, 79, 206, 134, 12, 88, 207, 160, 142, 141, 92, 207,
+ 160, 62, 141, 92, 207, 132, 68, 57, 191, 95, 78, 215, 51, 136, 19,
+ 154, 55, 27, 253, 200, 51, 162, 151, 30, 102, 216, 121, 204, 16, 232,
+ 155, 62, 86, 31, 51, 216, 142, 230, 155, 198, 49, 254, 161, 99, 141,
+ 91, 207, 32, 95, 154, 55, 3, 26, 101, 42, 184, 30, 99, 220, 122,
+ 38, 132, 147, 129, 227, 38, 99, 177, 142, 49, 110, 61, 131, 124, 157,
+ 242, 102, 154, 12, 223, 49, 198, 173, 103, 80, 239, 70, 174, 103, 80,
+ 199, 70, 174, 103, 172, 99, 140, 93, 207, 248, 142, 49, 118, 61, 131,
+ 56, 33, 152, 9, 25, 14, 118, 16, 169, 135, 25, 246, 29, 102, 95,
+ 232, 155, 48, 82, 31, 51, 216, 142, 174, 53, 70, 49, 254, 254, 35,
+ 141, 139, 51, 200, 151, 174, 53, 128, 70, 153, 74, 190, 105, 132, 113,
+ 113, 198, 151, 147, 129, 227, 38, 99, 177, 140, 48, 46, 206, 32, 95,
+ 167, 188, 153, 38, 35, 125, 184, 113, 113, 6, 245, 110, 228, 254, 12,
+ 234, 216, 200, 253, 25, 203, 136, 156, 199, 25, 167, 185, 227, 240, 156,
+ 199, 25, 126, 110, 134, 56, 161, 152, 233, 2, 118, 48, 90, 15, 51,
+ 236, 59, 204, 233, 195, 30, 121, 250, 119, 211, 199, 12, 182, 163, 49,
+ 96, 24, 227, 239, 24, 106, 92, 156, 9, 225, 100, 36, 194, 59, 165,
+ 107, 114, 146, 186, 26, 23, 103, 144, 47, 157, 255, 1, 77, 198, 98,
+ 233, 106, 92, 156, 241, 239, 230, 140, 25, 148, 169, 232, 186, 139, 113,
+ 113, 6, 245, 110, 228, 254, 12, 234, 216, 200, 253, 25, 75, 215, 156,
+ 199, 25, 39, 204, 116, 201, 121, 156, 113, 194, 76, 23, 134, 25, 107,
+ 42, 216, 193, 240, 108, 48, 51, 188, 251, 208, 97, 89, 238, 145, 77,
+ 239, 12, 237, 59, 185, 129, 153, 206, 28, 102, 58, 51, 254, 1, 29,
+ 179, 183, 131, 216, 214, 211, 236, 7, 10, 52, 212, 48, 227, 229, 58,
+ 7, 208, 39, 15, 187, 227, 149, 147, 145, 14, 239, 148, 174, 201, 241,
+ 237, 32, 144, 177, 176, 76, 234, 189, 220, 165, 131, 85, 204, 184, 150,
+ 113, 115, 116, 5, 54, 255, 235, 196, 141, 3, 104, 50, 150, 140, 246,
+ 217, 203, 24, 155, 249, 40, 245, 232, 192, 175, 181, 187, 151, 93, 203,
+ 8, 253, 242, 61, 154, 255, 11, 233, 228, 140, 25, 148, 169, 16, 91,
+ 179, 151, 209, 236, 239, 174, 230, 253, 251, 8, 102, 92, 203, 168, 126,
+ 92, 173, 149, 201, 208, 244, 94, 69, 105, 169, 222, 39, 130, 122, 164,
+ 57, 0, 141, 14, 89, 56, 94, 98, 207, 93, 159, 37, 57, 181, 182,
+ 128, 92, 108, 72, 43, 237, 188, 119, 11, 153, 180, 247, 121, 220, 81,
+ 158, 148, 80, 73, 184, 118, 121, 154, 127, 144, 188, 251, 205, 4, 122,
+ 79, 102, 171, 17, 234, 221, 142, 185, 50, 227, 228, 182, 59, 215, 136,
+ 107, 26, 114, 77, 145, 55, 92, 76, 165, 119, 93, 18, 58, 226, 198,
+ 119, 220, 243, 236, 231, 107, 25, 154, 93, 240, 58, 192, 223, 153, 232,
+ 128, 208, 168, 3, 246, 60, 123, 29, 172, 152, 18, 78, 239, 138, 34,
+ 237, 81, 7, 30, 47, 11, 218, 244, 116, 176, 237, 230, 28, 122, 79,
+ 215, 160, 204, 70, 41, 68, 7, 27, 118, 120, 166, 232, 233, 224, 250,
+ 248, 127, 147, 137, 14, 8, 141, 58, 96, 207, 197, 58, 64, 187, 229,
+ 117, 128, 118, 72, 116, 64, 232, 54, 160, 3, 246, 60, 155, 111, 214,
+ 128, 14, 46, 151, 252, 202, 78, 116, 64, 218, 231, 7, 29, 244, 45,
+ 34, 62, 187, 255, 4, 116, 112, 114, 219, 80, 122, 127, 212, 161, 98,
+ 37, 109, 68, 7, 79, 23, 39, 235, 234, 96, 226, 252, 69, 41, 68,
+ 7, 132, 70, 29, 176, 231, 98, 29, 32, 174, 120, 29, 32, 78, 136,
+ 14, 8, 141, 118, 192, 158, 103, 111, 7, 7, 183, 198, 208, 187, 117,
+ 72, 251, 124, 160, 131, 252, 167, 197, 231, 200, 208, 14, 254, 188, 19,
+ 67, 239, 154, 249, 94, 59, 191, 137, 58, 168, 245, 72, 220, 23, 117,
+ 208, 129, 158, 83, 155, 73, 105, 212, 65, 7, 157, 243, 107, 36, 6,
+ 160, 223, 167, 49, 96, 19, 248, 181, 46, 194, 24, 224, 116, 47, 163,
+ 9, 250, 90, 109, 24, 3, 170, 166, 133, 133, 85, 148, 55, 148, 158,
+ 187, 181, 195, 166, 222, 22, 169, 145, 135, 83, 12, 192, 118, 196, 175,
+ 89, 237, 220, 250, 60, 37, 123, 191, 182, 96, 84, 160, 189, 66, 169,
+ 239, 133, 49, 224, 92, 196, 253, 20, 34, 3, 249, 82, 223, 137, 50,
+ 82, 181, 57, 77, 114, 246, 50, 194, 62, 44, 159, 218, 98, 252, 246,
+ 134, 162, 24, 208, 170, 194, 192, 64, 58, 14, 78, 6, 142, 155, 140,
+ 197, 127, 75, 246, 50, 28, 233, 143, 82, 27, 253, 220, 77, 24, 3,
+ 222, 126, 146, 143, 198, 0, 228, 235, 180, 223, 72, 244, 181, 57, 123,
+ 25, 219, 7, 132, 154, 167, 108, 21, 199, 0, 180, 67, 98, 247, 168,
+ 119, 222, 238, 81, 143, 132, 31, 161, 209, 238, 217, 115, 147, 233, 59,
+ 83, 77, 211, 50, 211, 135, 166, 85, 240, 71, 108, 232, 52, 216, 253,
+ 149, 219, 201, 245, 137, 221, 147, 246, 232, 255, 50, 206, 188, 175, 235,
+ 255, 254, 90, 97, 165, 216, 239, 208, 243, 39, 138, 253, 191, 167, 172,
+ 178, 233, 217, 253, 208, 111, 237, 244, 14, 55, 66, 163, 221, 179, 231,
+ 98, 236, 163, 93, 240, 58, 192, 223, 153, 232, 128, 208, 168, 3, 246,
+ 28, 117, 240, 225, 59, 58, 64, 236, 183, 237, 227, 77, 239, 83, 39,
+ 237, 81, 7, 223, 166, 87, 12, 212, 211, 193, 235, 179, 151, 146, 137,
+ 14, 110, 207, 108, 67, 99, 64, 201, 215, 147, 117, 253, 223, 45, 207,
+ 89, 212, 255, 17, 26, 117, 192, 158, 139, 117, 128, 118, 203, 235, 0,
+ 237, 144, 232, 128, 208, 24, 3, 216, 115, 212, 193, 71, 160, 131, 154,
+ 160, 131, 154, 78, 49, 224, 196, 208, 214, 52, 6, 144, 246, 24, 3,
+ 62, 220, 152, 161, 27, 3, 186, 79, 235, 69, 237, 96, 124, 61, 31,
+ 106, 7, 11, 60, 23, 234, 234, 224, 74, 116, 36, 213, 1, 161, 81,
+ 7, 236, 185, 78, 12, 216, 236, 172, 3, 230, 175, 173, 102, 66, 163,
+ 29, 240, 126, 252, 59, 83, 99, 208, 65, 99, 208, 65, 99, 39, 59,
+ 8, 220, 205, 98, 0, 105, 143, 49, 160, 205, 121, 253, 24, 144, 114,
+ 143, 197, 128, 181, 15, 88, 12, 88, 233, 70, 12, 232, 193, 197, 128,
+ 30, 92, 12, 232, 225, 110, 12, 216, 196, 98, 128, 101, 61, 248, 181,
+ 84, 189, 24, 192, 242, 77, 38, 232, 107, 221, 168, 191, 14, 192, 118,
+ 212, 119, 254, 197, 248, 251, 110, 116, 119, 29, 224, 122, 61, 136, 115,
+ 62, 234, 59, 255, 226, 124, 39, 202, 216, 164, 237, 109, 111, 112, 119,
+ 29, 224, 90, 6, 206, 169, 232, 56, 56, 25, 56, 110, 50, 150, 128,
+ 13, 238, 174, 3, 92, 203, 192, 57, 11, 29, 199, 198, 44, 49, 64,
+ 147, 145, 182, 222, 221, 117, 64, 54, 121, 134, 187, 49, 116, 237, 140,
+ 122, 231, 239, 244, 97, 115, 103, 171, 153, 208, 235, 44, 54, 139, 104,
+ 78, 237, 180, 223, 189, 193, 153, 31, 155, 135, 90, 205, 132, 94, 15,
+ 252, 68, 243, 83, 167, 253, 238, 44, 252, 216, 156, 206, 106, 38, 52,
+ 242, 19, 205, 245, 156, 206, 23, 175, 119, 230, 199, 230, 71, 86, 51,
+ 161, 145, 159, 104, 222, 196, 175, 157, 17, 39, 4, 51, 105, 127, 131,
+ 29, 108, 210, 195, 12, 203, 55, 165, 173, 123, 228, 105, 89, 171, 63,
+ 111, 194, 118, 196, 14, 44, 235, 24, 255, 244, 36, 119, 231, 77, 174,
+ 237, 0, 99, 36, 145, 97, 225, 100, 164, 193, 59, 165, 105, 114, 66,
+ 147, 220, 157, 55, 185, 150, 129, 49, 136, 142, 99, 45, 55, 14, 160,
+ 201, 88, 146, 118, 187, 59, 111, 114, 45, 3, 125, 60, 29, 199, 90,
+ 103, 204, 160, 76, 101, 254, 183, 219, 221, 121, 147, 107, 25, 61, 56,
+ 204, 160, 222, 121, 27, 98, 115, 13, 171, 153, 208, 104, 67, 162, 57,
+ 136, 211, 126, 119, 22, 126, 44, 110, 91, 205, 132, 70, 126, 162, 120,
+ 238, 148, 191, 218, 237, 204, 143, 197, 64, 171, 153, 208, 200, 79, 20,
+ 27, 157, 242, 87, 89, 248, 245, 224, 48, 211, 131, 195, 76, 15, 55,
+ 49, 131, 56, 161, 107, 141, 237, 96, 7, 235, 245, 48, 195, 234, 78,
+ 44, 208, 55, 109, 167, 126, 156, 193, 118, 212, 158, 119, 49, 254, 33,
+ 59, 141, 139, 51, 200, 151, 218, 51, 208, 40, 83, 201, 3, 239, 48,
+ 46, 206, 88, 56, 25, 56, 110, 50, 150, 136, 29, 198, 197, 25, 228,
+ 203, 99, 198, 66, 244, 181, 195, 184, 56, 131, 122, 39, 54, 148, 102,
+ 218, 186, 213, 85, 156, 49, 221, 139, 116, 59, 206, 160, 142, 121, 126,
+ 174, 226, 12, 242, 115, 55, 206, 68, 100, 225, 231, 42, 206, 32, 63,
+ 119, 227, 140, 41, 11, 63, 87, 113, 6, 249, 185, 27, 103, 16, 39,
+ 236, 14, 35, 176, 131, 191, 245, 48, 195, 234, 78, 76, 208, 215, 154,
+ 230, 198, 250, 124, 59, 55, 167, 217, 198, 248, 39, 29, 54, 46, 206,
+ 32, 95, 106, 107, 40, 99, 187, 230, 159, 15, 27, 23, 103, 76, 156,
+ 12, 28, 55, 25, 75, 250, 33, 227, 226, 12, 242, 117, 154, 155, 105,
+ 50, 66, 15, 25, 23, 103, 80, 239, 188, 13, 185, 138, 51, 104, 67,
+ 238, 198, 25, 75, 22, 126, 174, 226, 12, 242, 115, 55, 206, 160, 62,
+ 121, 126, 174, 226, 12, 242, 115, 55, 206, 132, 102, 225, 231, 42, 206,
+ 32, 63, 119, 227, 12, 226, 132, 221, 97, 4, 118, 176, 93, 15, 51,
+ 159, 114, 119, 24, 61, 242, 116, 236, 119, 227, 12, 253, 65, 102, 7,
+ 142, 3, 140, 127, 196, 126, 227, 226, 12, 242, 101, 119, 24, 61, 242,
+ 68, 153, 74, 163, 253, 198, 197, 153, 80, 78, 6, 142, 155, 140, 37,
+ 97, 159, 113, 113, 6, 249, 58, 223, 97, 164, 229, 205, 246, 25, 23,
+ 103, 80, 239, 57, 141, 51, 38, 167, 59, 140, 114, 30, 103, 76, 78,
+ 119, 24, 229, 60, 206, 152, 156, 238, 48, 202, 121, 156, 49, 57, 221,
+ 97, 196, 48, 19, 122, 14, 236, 224, 160, 30, 102, 62, 227, 238, 48,
+ 122, 228, 153, 120, 65, 63, 206, 96, 59, 186, 183, 125, 145, 219, 11,
+ 188, 96, 92, 156, 65, 190, 116, 111, 27, 104, 148, 169, 172, 7, 206,
+ 27, 23, 103, 252, 57, 25, 56, 110, 50, 150, 144, 243, 198, 197, 25,
+ 228, 235, 116, 182, 81, 147, 225, 56, 103, 92, 156, 65, 189, 231, 52,
+ 206, 56, 157, 69, 60, 159, 243, 56, 227, 116, 22, 241, 124, 206, 227,
+ 12, 207, 15, 117, 151, 211, 56, 195, 99, 6, 113, 66, 239, 99, 57,
+ 5, 118, 176, 87, 15, 51, 172, 238, 196, 113, 22, 252, 249, 25, 253,
+ 56, 131, 237, 104, 12, 56, 203, 248, 103, 156, 206, 89, 156, 225, 247,
+ 207, 67, 57, 25, 14, 120, 39, 135, 38, 199, 122, 58, 103, 113, 134,
+ 223, 63, 71, 190, 116, 28, 64, 147, 177, 248, 158, 206, 89, 156, 225,
+ 247, 207, 67, 207, 56, 99, 6, 101, 42, 249, 191, 83, 57, 139, 51,
+ 100, 255, 60, 72, 211, 59, 189, 211, 167, 155, 119, 218, 232, 3, 207,
+ 222, 217, 63, 79, 74, 59, 108, 158, 248, 251, 232, 192, 236, 246, 12,
+ 157, 106, 120, 57, 126, 37, 186, 122, 167, 205, 47, 253, 107, 80, 214,
+ 189, 104, 199, 246, 195, 230, 209, 241, 110, 222, 97, 196, 241, 75, 107,
+ 225, 157, 86, 108, 72, 155, 134, 89, 247, 117, 67, 79, 30, 54, 23,
+ 110, 255, 149, 221, 29, 126, 168, 59, 194, 47, 52, 212, 59, 13, 117,
+ 149, 117, 143, 212, 10, 227, 109, 50, 54, 198, 189, 59, 140, 78, 113,
+ 235, 153, 99, 96, 7, 231, 244, 48, 195, 234, 78, 18, 255, 1, 127,
+ 126, 82, 63, 206, 96, 59, 26, 3, 254, 225, 214, 51, 39, 114, 22,
+ 103, 248, 253, 70, 127, 78, 70, 34, 188, 83, 162, 38, 199, 114, 34,
+ 103, 113, 134, 223, 111, 68, 190, 116, 28, 64, 147, 177, 164, 31, 207,
+ 89, 156, 225, 247, 27, 253, 79, 102, 57, 167, 117, 82, 91, 207, 28,
+ 207, 89, 156, 33, 251, 141, 65, 154, 222, 137, 13, 205, 7, 204, 92,
+ 26, 243, 216, 150, 117, 191, 49, 13, 108, 104, 229, 184, 207, 178, 221,
+ 111, 116, 90, 207, 112, 252, 38, 3, 191, 6, 107, 199, 217, 222, 217,
+ 187, 219, 118, 216, 28, 212, 229, 97, 182, 123, 119, 78, 235, 153, 227,
+ 140, 223, 104, 192, 76, 205, 125, 223, 52, 204, 186, 15, 150, 4, 152,
+ 233, 180, 169, 117, 182, 251, 96, 78, 235, 153, 227, 206, 152, 65, 93,
+ 101, 221, 83, 66, 204, 252, 58, 62, 251, 61, 37, 167, 245, 204, 49,
+ 110, 61, 115, 9, 236, 224, 148, 14, 102, 184, 123, 191, 66, 161, 175,
+ 227, 136, 27, 235, 153, 99, 92, 12, 56, 202, 213, 55, 222, 113, 55,
+ 206, 20, 116, 105, 7, 43, 228, 125, 244, 155, 198, 200, 151, 198, 0,
+ 160, 81, 166, 50, 183, 185, 229, 110, 156, 113, 45, 35, 180, 79, 50,
+ 91, 207, 112, 50, 112, 220, 100, 44, 137, 215, 220, 141, 51, 217, 200,
+ 184, 91, 143, 197, 178, 35, 89, 214, 51, 154, 12, 255, 203, 238, 198,
+ 25, 215, 50, 182, 189, 82, 49, 243, 121, 46, 85, 239, 85, 148, 150,
+ 38, 83, 116, 141, 15, 211, 80, 143, 132, 31, 161, 27, 36, 197, 91,
+ 216, 115, 215, 223, 33, 29, 220, 58, 211, 210, 191, 95, 121, 205, 158,
+ 3, 164, 197, 129, 181, 20, 250, 127, 167, 186, 75, 248, 219, 137, 206,
+ 181, 188, 231, 55, 75, 98, 241, 109, 57, 61, 19, 150, 63, 243, 15,
+ 73, 20, 223, 176, 111, 102, 174, 245, 210, 189, 184, 181, 244, 190, 157,
+ 193, 203, 212, 187, 172, 60, 50, 109, 210, 143, 77, 19, 132, 231, 170,
+ 94, 229, 218, 33, 133, 140, 220, 77, 191, 225, 103, 93, 175, 221, 71,
+ 149, 121, 64, 106, 241, 188, 144, 240, 60, 210, 203, 92, 199, 164, 246,
+ 123, 63, 208, 218, 156, 146, 138, 127, 25, 164, 210, 209, 103, 164, 65,
+ 62, 77, 132, 125, 95, 199, 158, 151, 102, 31, 108, 169, 181, 113, 72,
+ 158, 141, 212, 24, 137, 223, 151, 31, 178, 249, 27, 97, 223, 92, 113,
+ 215, 164, 239, 31, 182, 213, 218, 220, 148, 202, 111, 234, 162, 208, 190,
+ 209, 183, 165, 135, 227, 250, 8, 251, 150, 143, 187, 43, 33, 150, 180,
+ 153, 157, 100, 181, 68, 42, 244, 252, 232, 135, 82, 159, 51, 221, 133,
+ 125, 15, 199, 62, 145, 26, 77, 190, 64, 191, 233, 233, 223, 82, 189,
+ 155, 106, 75, 212, 75, 233, 235, 53, 167, 55, 139, 250, 218, 98, 95,
+ 75, 79, 99, 190, 161, 223, 7, 222, 95, 98, 170, 66, 191, 10, 246,
+ 144, 207, 223, 93, 46, 190, 143, 42, 205, 83, 30, 177, 176, 15, 253,
+ 14, 223, 155, 15, 219, 169, 116, 116, 30, 121, 112, 171, 143, 116, 238,
+ 159, 201, 39, 159, 121, 213, 136, 126, 227, 247, 217, 167, 13, 232, 221,
+ 53, 126, 67, 3, 116, 239, 174, 97, 103, 19, 253, 40, 141, 223, 191,
+ 210, 59, 179, 72, 176, 133, 254, 134, 96, 11, 239, 193, 66, 255, 65,
+ 231, 72, 26, 45, 1, 182, 216, 115, 215, 216, 218, 6, 216, 202, 95,
+ 109, 90, 10, 193, 86, 82, 155, 207, 21, 58, 24, 176, 245, 217, 202,
+ 199, 194, 187, 157, 26, 2, 182, 216, 92, 111, 57, 61, 107, 88, 11,
+ 176, 37, 154, 235, 97, 223, 2, 94, 235, 165, 60, 39, 124, 236, 4,
+ 91, 219, 171, 202, 10, 157, 15, 176, 21, 62, 102, 140, 208, 94, 254,
+ 5, 108, 45, 155, 246, 43, 189, 219, 110, 198, 89, 155, 66, 63, 126,
+ 117, 64, 58, 248, 193, 73, 97, 95, 47, 175, 99, 210, 218, 186, 119,
+ 40, 182, 22, 188, 246, 80, 206, 45, 215, 3, 108, 229, 205, 240, 22,
+ 126, 199, 208, 39, 254, 188, 132, 190, 156, 96, 171, 240, 60, 31, 133,
+ 246, 138, 187, 44, 229, 63, 147, 33, 148, 219, 127, 252, 53, 233, 88,
+ 68, 56, 197, 214, 149, 184, 210, 138, 126, 126, 6, 108, 85, 92, 90,
+ 65, 232, 195, 74, 143, 187, 43, 69, 22, 205, 71, 191, 113, 217, 223,
+ 175, 136, 66, 127, 111, 125, 40, 221, 133, 184, 34, 234, 123, 9, 176,
+ 213, 120, 246, 210, 134, 4, 91, 123, 199, 215, 87, 104, 63, 192, 214,
+ 197, 233, 213, 133, 182, 246, 32, 230, 181, 36, 207, 43, 64, 198, 37,
+ 247, 75, 104, 163, 208, 179, 1, 91, 185, 23, 77, 21, 142, 247, 14,
+ 96, 171, 89, 46, 114, 119, 161, 151, 252, 123, 165, 177, 10, 93, 8,
+ 176, 53, 178, 107, 127, 29, 31, 150, 79, 126, 83, 169, 134, 157, 96,
+ 107, 206, 7, 185, 21, 58, 51, 170, 160, 92, 184, 231, 118, 155, 30,
+ 182, 216, 153, 87, 63, 74, 227, 247, 179, 245, 206, 194, 210, 184, 117,
+ 141, 97, 107, 22, 98, 11, 226, 38, 197, 150, 70, 43, 216, 162, 207,
+ 9, 182, 222, 189, 175, 242, 104, 183, 149, 244, 251, 217, 197, 103, 77,
+ 87, 232, 98, 167, 187, 75, 9, 227, 186, 8, 223, 165, 111, 177, 89,
+ 18, 91, 247, 44, 167, 103, 88, 195, 94, 255, 33, 137, 214, 61, 216,
+ 119, 50, 96, 235, 11, 223, 227, 20, 91, 255, 171, 80, 68, 177, 83,
+ 11, 96, 107, 154, 165, 129, 208, 198, 127, 6, 108, 181, 92, 62, 36,
+ 149, 96, 171, 121, 216, 116, 133, 62, 6, 216, 250, 242, 233, 18, 97,
+ 223, 23, 128, 173, 118, 215, 215, 166, 18, 108, 149, 239, 189, 71, 161,
+ 243, 198, 156, 145, 186, 175, 58, 38, 236, 107, 25, 127, 94, 194, 57,
+ 12, 193, 214, 221, 63, 174, 42, 116, 163, 217, 151, 37, 251, 169, 227,
+ 194, 190, 227, 18, 174, 73, 109, 27, 206, 77, 37, 216, 178, 125, 92,
+ 95, 161, 235, 143, 191, 45, 13, 238, 61, 93, 168, 171, 69, 157, 239,
+ 74, 127, 125, 82, 142, 98, 171, 118, 68, 3, 133, 94, 51, 225, 161,
+ 116, 4, 230, 83, 162, 190, 243, 162, 158, 72, 201, 103, 250, 80, 108,
+ 45, 238, 222, 89, 241, 157, 211, 70, 191, 148, 74, 255, 28, 35, 148,
+ 251, 89, 212, 107, 169, 72, 255, 71, 20, 91, 17, 113, 249, 149, 119,
+ 158, 0, 216, 42, 91, 173, 108, 170, 30, 182, 70, 143, 32, 223, 16,
+ 246, 146, 171, 52, 120, 165, 240, 241, 2, 108, 205, 61, 243, 143, 80,
+ 238, 77, 192, 86, 205, 87, 75, 41, 182, 34, 214, 170, 247, 136, 222,
+ 5, 108, 125, 123, 172, 157, 176, 111, 38, 96, 139, 157, 165, 246, 163,
+ 116, 50, 96, 75, 239, 140, 53, 141, 91, 151, 25, 182, 240, 219, 244,
+ 56, 95, 36, 216, 34, 52, 126, 3, 150, 61, 119, 253, 13, 216, 52,
+ 192, 86, 194, 124, 118, 79, 210, 230, 100, 149, 174, 8, 113, 203, 113,
+ 78, 124, 214, 249, 113, 209, 89, 18, 203, 1, 44, 167, 103, 163, 243,
+ 66, 220, 18, 229, 0, 148, 24, 0, 216, 170, 190, 147, 221, 117, 20,
+ 81, 68, 253, 230, 103, 41, 192, 214, 31, 161, 227, 132, 125, 11, 121,
+ 237, 144, 198, 121, 140, 166, 223, 98, 45, 127, 95, 253, 38, 106, 69,
+ 152, 19, 254, 118, 78, 124, 79, 82, 115, 192, 86, 157, 242, 225, 244,
+ 123, 170, 69, 188, 251, 41, 180, 4, 113, 235, 199, 177, 97, 194, 190,
+ 29, 226, 206, 75, 56, 119, 39, 216, 218, 237, 173, 126, 55, 192, 110,
+ 189, 44, 181, 110, 217, 91, 216, 183, 119, 204, 53, 105, 40, 189, 75,
+ 233, 166, 180, 161, 135, 58, 198, 47, 163, 110, 75, 87, 3, 196, 186,
+ 218, 20, 123, 87, 42, 91, 123, 52, 253, 158, 234, 147, 153, 42, 221,
+ 8, 230, 132, 7, 238, 136, 191, 211, 187, 21, 226, 86, 169, 147, 209,
+ 244, 123, 170, 159, 255, 21, 163, 125, 199, 245, 165, 244, 113, 115, 241,
+ 29, 75, 15, 97, 78, 120, 195, 70, 191, 215, 42, 95, 14, 82, 105,
+ 188, 191, 204, 97, 139, 212, 189, 115, 104, 83, 72, 20, 253, 158, 106,
+ 112, 66, 148, 118, 215, 81, 30, 185, 69, 161, 104, 179, 222, 156, 240,
+ 219, 127, 163, 233, 55, 81, 189, 191, 32, 247, 66, 21, 148, 55, 254,
+ 30, 99, 214, 139, 91, 236, 140, 190, 31, 165, 113, 78, 168, 119, 118,
+ 159, 238, 127, 92, 226, 114, 185, 177, 176, 110, 60, 166, 183, 198, 102,
+ 231, 224, 67, 97, 61, 152, 56, 75, 63, 47, 21, 202, 173, 27, 29,
+ 233, 92, 205, 237, 116, 119, 243, 82, 174, 215, 141, 63, 70, 236, 164,
+ 247, 94, 35, 95, 186, 198, 6, 26, 101, 42, 235, 223, 201, 238, 230,
+ 165, 92, 203, 168, 210, 38, 141, 202, 8, 229, 100, 224, 184, 201, 88,
+ 252, 39, 184, 155, 151, 114, 45, 35, 207, 125, 137, 237, 227, 204, 202,
+ 178, 198, 214, 100, 36, 198, 186, 155, 151, 114, 45, 163, 49, 183, 198,
+ 70, 189, 19, 127, 26, 9, 254, 20, 245, 72, 248, 17, 26, 215, 216,
+ 236, 57, 241, 167, 31, 154, 2, 185, 51, 224, 3, 193, 159, 14, 247,
+ 47, 75, 191, 207, 255, 127, 228, 125, 119, 116, 20, 85, 244, 255, 38,
+ 244, 30, 32, 116, 132, 208, 73, 1, 150, 42, 66, 96, 119, 134, 162,
+ 244, 80, 20, 172, 132, 14, 210, 130, 244, 146, 176, 9, 32, 82, 132,
+ 40, 8, 34, 136, 1, 21, 34, 2, 198, 0, 138, 144, 132, 13, 77,
+ 164, 70, 138, 70, 138, 44, 189, 72, 9, 33, 129, 16, 8, 252, 238,
+ 157, 153, 87, 38, 108, 102, 246, 251, 203, 251, 227, 123, 206, 55, 231,
+ 236, 225, 158, 225, 221, 123, 231, 221, 185, 159, 119, 95, 187, 239, 149,
+ 232, 30, 164, 208, 45, 161, 61, 197, 239, 71, 120, 251, 90, 2, 45,
+ 35, 224, 55, 147, 219, 59, 93, 10, 198, 1, 108, 62, 44, 150, 238,
+ 185, 47, 9, 237, 169, 209, 124, 24, 242, 90, 160, 61, 13, 47, 122,
+ 172, 45, 105, 79, 227, 214, 191, 163, 222, 179, 2, 237, 105, 74, 232,
+ 70, 218, 63, 141, 3, 158, 237, 240, 219, 105, 105, 196, 48, 3, 125,
+ 149, 132, 116, 114, 39, 205, 33, 169, 126, 72, 101, 37, 22, 23, 132,
+ 246, 52, 103, 195, 171, 180, 79, 157, 8, 60, 201, 240, 59, 192, 241,
+ 230, 192, 24, 123, 114, 249, 129, 237, 72, 123, 122, 227, 89, 68, 59,
+ 50, 198, 62, 60, 109, 62, 229, 61, 12, 60, 199, 45, 141, 45, 41,
+ 240, 227, 239, 169, 70, 127, 38, 237, 169, 245, 194, 114, 133, 46, 14,
+ 99, 108, 91, 204, 114, 202, 123, 18, 120, 78, 195, 239, 47, 142, 55,
+ 59, 242, 154, 180, 225, 206, 92, 122, 31, 100, 161, 59, 170, 94, 188,
+ 55, 35, 229, 249, 68, 202, 155, 10, 60, 103, 225, 119, 158, 123, 231,
+ 202, 48, 198, 190, 208, 115, 70, 59, 210, 158, 222, 122, 109, 176, 66,
+ 55, 135, 246, 180, 70, 237, 174, 148, 247, 34, 240, 93, 2, 190, 43,
+ 28, 47, 158, 79, 237, 10, 46, 65, 251, 42, 133, 171, 169, 247, 231,
+ 166, 65, 123, 122, 110, 214, 8, 106, 231, 107, 192, 115, 3, 126, 183,
+ 184, 111, 116, 24, 218, 211, 137, 67, 206, 145, 113, 184, 92, 51, 76,
+ 205, 243, 194, 246, 180, 79, 246, 30, 250, 125, 239, 0, 207, 61, 248,
+ 165, 113, 188, 79, 161, 61, 205, 217, 96, 163, 119, 240, 84, 236, 59,
+ 175, 173, 218, 38, 22, 150, 223, 232, 157, 66, 231, 95, 210, 129, 39,
+ 3, 126, 89, 28, 47, 182, 167, 117, 35, 106, 183, 33, 237, 233, 142,
+ 35, 167, 119, 145, 246, 212, 119, 116, 56, 213, 155, 131, 60, 94, 65,
+ 150, 66, 94, 65, 186, 246, 148, 229, 126, 248, 82, 26, 219, 83, 62,
+ 39, 164, 56, 240, 148, 134, 95, 57, 142, 151, 142, 3, 62, 209, 143,
+ 177, 177, 253, 32, 216, 34, 52, 142, 3, 216, 115, 247, 216, 194, 49,
+ 246, 249, 83, 75, 232, 93, 211, 227, 78, 118, 84, 232, 70, 128, 173,
+ 202, 217, 236, 158, 169, 190, 192, 51, 2, 126, 51, 57, 222, 50, 128,
+ 45, 54, 55, 28, 75, 115, 57, 42, 0, 182, 140, 230, 134, 149, 111,
+ 94, 96, 155, 244, 236, 55, 114, 127, 242, 78, 233, 159, 71, 218, 253,
+ 80, 128, 173, 147, 171, 202, 183, 99, 216, 106, 4, 216, 106, 164, 195,
+ 86, 58, 96, 107, 244, 170, 246, 237, 8, 182, 250, 78, 121, 179, 157,
+ 186, 159, 255, 168, 84, 180, 239, 24, 67, 108, 213, 130, 190, 74, 175,
+ 117, 163, 40, 182, 90, 215, 93, 168, 249, 233, 89, 169, 214, 137, 229,
+ 134, 216, 122, 7, 250, 42, 216, 142, 19, 108, 189, 253, 243, 143, 10,
+ 61, 22, 250, 42, 247, 247, 27, 99, 235, 222, 156, 107, 210, 235, 147,
+ 239, 208, 251, 173, 146, 34, 235, 42, 118, 251, 15, 176, 213, 177, 89,
+ 151, 68, 134, 173, 70, 128, 173, 32, 192, 22, 107, 195, 134, 133, 223,
+ 149, 18, 55, 91, 146, 8, 182, 182, 62, 45, 163, 208, 27, 194, 211,
+ 165, 17, 65, 53, 147, 24, 182, 252, 1, 91, 254, 128, 173, 134, 28,
+ 62, 50, 165, 183, 26, 164, 39, 18, 108, 109, 219, 118, 82, 161, 255,
+ 4, 108, 21, 237, 180, 45, 145, 97, 203, 31, 176, 21, 0, 216, 10,
+ 160, 188, 223, 1, 182, 14, 223, 161, 99, 20, 185, 74, 85, 117, 238,
+ 227, 54, 96, 235, 139, 65, 3, 18, 25, 182, 2, 0, 91, 129, 128,
+ 173, 64, 221, 157, 52, 47, 122, 189, 71, 199, 216, 183, 19, 187, 39,
+ 170, 237, 80, 97, 121, 196, 170, 70, 137, 12, 91, 129, 128, 173, 64,
+ 192, 86, 32, 215, 14, 21, 147, 187, 119, 56, 79, 239, 149, 153, 61,
+ 70, 189, 123, 254, 41, 140, 3, 238, 55, 98, 121, 79, 57, 200, 227,
+ 6, 91, 44, 167, 200, 151, 210, 56, 198, 230, 115, 141, 140, 176, 133,
+ 113, 150, 96, 107, 9, 96, 11, 227, 38, 193, 22, 161, 17, 91, 236,
+ 57, 98, 203, 255, 37, 108, 237, 7, 108, 149, 61, 203, 198, 216, 107,
+ 55, 168, 119, 84, 85, 133, 49, 118, 217, 107, 253, 18, 140, 176, 53,
+ 1, 198, 216, 108, 157, 36, 150, 230, 8, 141, 134, 49, 182, 209, 58,
+ 9, 242, 206, 131, 184, 181, 114, 255, 41, 58, 198, 62, 89, 83, 29,
+ 99, 183, 1, 108, 189, 63, 132, 141, 177, 227, 224, 187, 109, 135, 239,
+ 190, 147, 243, 151, 207, 1, 91, 247, 158, 179, 49, 246, 128, 46, 234,
+ 24, 251, 56, 140, 177, 143, 71, 179, 49, 118, 162, 165, 62, 96, 171,
+ 62, 96, 171, 30, 229, 173, 94, 232, 148, 212, 169, 111, 28, 29, 99,
+ 55, 206, 58, 168, 208, 1, 48, 198, 158, 210, 231, 100, 18, 195, 86,
+ 93, 192, 86, 29, 192, 86, 109, 202, 59, 26, 198, 216, 216, 135, 33,
+ 216, 10, 125, 113, 69, 161, 7, 125, 126, 89, 90, 187, 134, 141, 207,
+ 79, 90, 106, 1, 182, 106, 1, 182, 24, 239, 8, 24, 99, 63, 29,
+ 20, 77, 199, 216, 203, 6, 55, 81, 232, 213, 115, 110, 75, 155, 167,
+ 142, 226, 176, 85, 15, 176, 213, 80, 135, 173, 75, 239, 222, 149, 238,
+ 183, 12, 162, 99, 108, 215, 244, 206, 10, 29, 53, 63, 93, 146, 161,
+ 63, 197, 176, 101, 5, 108, 53, 5, 108, 53, 165, 188, 205, 97, 140,
+ 109, 153, 57, 129, 198, 45, 223, 231, 95, 41, 109, 247, 197, 169, 217,
+ 210, 168, 107, 11, 18, 245, 113, 43, 72, 135, 173, 117, 179, 114, 164,
+ 230, 109, 188, 73, 189, 228, 173, 77, 43, 40, 244, 100, 192, 214, 168,
+ 172, 6, 73, 12, 91, 254, 128, 45, 127, 192, 86, 67, 221, 24, 123,
+ 86, 168, 15, 29, 99, 187, 182, 169, 227, 109, 196, 86, 221, 95, 175,
+ 115, 216, 242, 7, 108, 249, 3, 182, 252, 185, 57, 183, 98, 114, 213,
+ 233, 63, 210, 49, 118, 194, 13, 117, 174, 236, 58, 96, 107, 85, 60,
+ 27, 99, 231, 224, 187, 122, 5, 0, 182, 152, 173, 158, 2, 182, 88,
+ 174, 154, 47, 165, 119, 3, 182, 248, 28, 182, 226, 192, 83, 26, 126,
+ 229, 56, 94, 26, 183, 34, 245, 99, 236, 142, 220, 24, 187, 35, 55,
+ 198, 238, 248, 210, 24, 187, 35, 96, 171, 163, 110, 140, 253, 211, 106,
+ 54, 198, 238, 145, 192, 198, 216, 255, 113, 99, 236, 190, 192, 51, 2,
+ 126, 51, 57, 94, 28, 99, 179, 53, 195, 88, 154, 123, 134, 99, 108,
+ 163, 53, 67, 228, 45, 6, 216, 90, 149, 202, 198, 216, 139, 36, 117,
+ 12, 86, 9, 176, 53, 113, 19, 27, 99, 199, 1, 207, 118, 248, 237,
+ 180, 116, 96, 119, 87, 195, 24, 251, 240, 52, 54, 198, 14, 140, 157,
+ 172, 208, 53, 33, 110, 77, 250, 251, 35, 27, 195, 86, 7, 192, 86,
+ 7, 192, 86, 7, 238, 46, 246, 83, 82, 191, 109, 227, 233, 24, 123,
+ 197, 118, 245, 126, 151, 142, 216, 39, 108, 49, 210, 198, 176, 37, 3,
+ 182, 100, 192, 150, 76, 121, 37, 136, 91, 216, 119, 39, 216, 106, 48,
+ 81, 189, 211, 101, 17, 196, 173, 135, 225, 108, 124, 126, 210, 34, 1,
+ 182, 36, 192, 150, 68, 121, 163, 97, 140, 61, 35, 112, 26, 29, 99,
+ 191, 177, 77, 173, 227, 24, 24, 99, 159, 105, 197, 108, 149, 10, 239,
+ 122, 22, 126, 231, 57, 91, 197, 195, 24, 123, 99, 97, 54, 198, 126,
+ 175, 190, 74, 183, 130, 62, 161, 79, 103, 54, 198, 190, 8, 124, 151,
+ 224, 119, 133, 171, 239, 17, 136, 91, 103, 226, 216, 157, 37, 227, 180,
+ 251, 135, 159, 66, 220, 122, 56, 158, 233, 189, 6, 250, 110, 192, 239,
+ 22, 167, 247, 17, 196, 173, 126, 85, 217, 24, 123, 255, 31, 179, 232,
+ 157, 37, 173, 166, 179, 49, 246, 29, 224, 185, 7, 191, 52, 142, 23,
+ 199, 216, 127, 212, 97, 99, 236, 94, 19, 217, 24, 251, 157, 114, 108,
+ 140, 157, 14, 60, 25, 240, 203, 226, 120, 177, 79, 88, 33, 135, 141,
+ 177, 223, 255, 128, 141, 177, 191, 223, 195, 222, 57, 7, 121, 188, 58,
+ 2, 182, 58, 234, 226, 22, 203, 129, 244, 165, 52, 246, 9, 249, 220,
+ 200, 226, 192, 83, 26, 126, 229, 56, 94, 186, 247, 35, 146, 141, 177,
+ 45, 107, 96, 204, 124, 201, 108, 140, 205, 242, 63, 98, 28, 15, 189,
+ 237, 107, 205, 215, 177, 177, 28, 205, 205, 248, 134, 203, 153, 250, 90,
+ 220, 190, 92, 148, 75, 115, 51, 224, 157, 80, 167, 50, 70, 253, 90,
+ 220, 190, 92, 148, 75, 235, 1, 52, 169, 75, 218, 26, 113, 251, 114,
+ 237, 107, 115, 229, 76, 173, 213, 246, 125, 173, 17, 183, 47, 23, 237,
+ 46, 50, 255, 35, 244, 107, 177, 249, 31, 104, 79, 145, 249, 31, 142,
+ 53, 98, 243, 63, 16, 39, 52, 207, 112, 229, 67, 111, 191, 72, 51,
+ 204, 176, 252, 15, 199, 106, 40, 251, 149, 249, 188, 20, 150, 163, 126,
+ 176, 154, 201, 143, 94, 37, 110, 95, 174, 133, 211, 225, 128, 119, 114,
+ 104, 122, 252, 86, 137, 219, 151, 139, 114, 105, 61, 128, 38, 117, 137,
+ 251, 82, 220, 190, 92, 203, 87, 122, 204, 160, 78, 165, 79, 240, 165,
+ 184, 125, 185, 104, 119, 145, 249, 31, 126, 171, 196, 230, 127, 160, 61,
+ 69, 230, 127, 216, 191, 20, 155, 255, 129, 56, 161, 121, 134, 203, 224,
+ 187, 172, 49, 195, 12, 203, 255, 176, 3, 175, 243, 11, 15, 242, 12,
+ 87, 114, 49, 96, 5, 151, 103, 248, 133, 192, 60, 195, 21, 92, 12,
+ 0, 26, 117, 42, 61, 164, 229, 2, 243, 12, 57, 29, 88, 111, 82,
+ 151, 176, 229, 2, 243, 12, 191, 200, 149, 103, 72, 236, 181, 92, 96,
+ 158, 225, 23, 98, 243, 63, 208, 198, 34, 243, 63, 194, 150, 139, 205,
+ 255, 176, 44, 23, 155, 255, 129, 56, 161, 231, 39, 110, 5, 63, 88,
+ 105, 134, 25, 150, 255, 97, 1, 94, 199, 103, 30, 228, 25, 46, 227,
+ 98, 192, 231, 220, 25, 16, 159, 9, 204, 51, 252, 156, 243, 53, 212,
+ 177, 76, 139, 1, 63, 9, 204, 51, 228, 116, 96, 189, 73, 93, 236,
+ 63, 9, 204, 51, 252, 44, 87, 158, 161, 166, 35, 101, 171, 184, 56,
+ 131, 118, 23, 153, 255, 129, 54, 22, 153, 255, 97, 255, 73, 108, 254,
+ 7, 218, 78, 100, 254, 7, 226, 132, 222, 213, 179, 9, 252, 96, 153,
+ 25, 102, 88, 254, 71, 202, 150, 135, 222, 33, 155, 61, 56, 63, 113,
+ 11, 119, 238, 224, 22, 238, 204, 209, 31, 197, 197, 153, 16, 78, 71,
+ 10, 188, 83, 138, 166, 39, 236, 71, 113, 113, 6, 229, 210, 122, 0,
+ 77, 235, 242, 163, 184, 56, 19, 178, 57, 215, 249, 137, 155, 181, 92,
+ 198, 77, 226, 226, 12, 218, 93, 228, 120, 38, 236, 71, 177, 227, 25,
+ 203, 143, 98, 199, 51, 104, 59, 145, 227, 25, 196, 9, 189, 67, 225,
+ 123, 240, 131, 173, 102, 152, 97, 249, 31, 209, 63, 0, 111, 172, 121,
+ 156, 193, 114, 244, 220, 233, 31, 184, 189, 236, 27, 197, 197, 25, 31,
+ 78, 71, 52, 188, 83, 180, 166, 199, 186, 81, 92, 156, 65, 185, 180,
+ 30, 64, 147, 186, 56, 55, 136, 139, 51, 62, 177, 185, 238, 234, 137,
+ 213, 114, 25, 55, 136, 139, 51, 104, 119, 145, 227, 25, 235, 70, 177,
+ 227, 25, 180, 167, 200, 241, 76, 200, 6, 177, 227, 25, 196, 9, 189,
+ 71, 241, 5, 208, 155, 76, 48, 195, 221, 59, 18, 2, 188, 41, 223,
+ 122, 112, 135, 194, 247, 92, 12, 248, 142, 59, 163, 241, 91, 113, 113,
+ 6, 229, 210, 24, 0, 52, 234, 84, 230, 180, 214, 139, 139, 51, 33,
+ 156, 14, 172, 55, 169, 139, 99, 189, 184, 56, 131, 114, 117, 119, 40,
+ 104, 58, 226, 94, 136, 139, 51, 104, 119, 145, 227, 25, 180, 177, 200,
+ 241, 140, 99, 189, 216, 241, 12, 218, 78, 228, 120, 70, 193, 137, 38,
+ 47, 45, 27, 252, 224, 123, 51, 204, 176, 253, 92, 113, 207, 31, 122,
+ 91, 115, 204, 227, 12, 150, 163, 119, 79, 61, 103, 242, 157, 207, 196,
+ 197, 25, 43, 167, 35, 14, 222, 41, 78, 211, 19, 242, 76, 92, 156,
+ 65, 185, 180, 30, 64, 147, 186, 184, 158, 138, 139, 51, 214, 28, 61,
+ 102, 80, 167, 210, 199, 124, 42, 46, 206, 160, 221, 69, 142, 103, 66,
+ 158, 137, 29, 207, 160, 61, 69, 142, 103, 194, 158, 138, 29, 207, 32,
+ 78, 232, 61, 138, 143, 192, 15, 94, 152, 97, 134, 157, 3, 25, 6,
+ 188, 105, 89, 230, 113, 6, 203, 209, 59, 59, 159, 112, 247, 91, 101,
+ 137, 139, 51, 40, 151, 232, 8, 3, 26, 117, 42, 243, 12, 89, 226,
+ 226, 76, 24, 167, 3, 235, 77, 234, 18, 243, 88, 92, 156, 65, 185,
+ 60, 102, 194, 52, 29, 214, 199, 226, 226, 12, 218, 93, 228, 120, 198,
+ 39, 75, 236, 120, 6, 237, 41, 114, 60, 99, 125, 44, 118, 60, 131,
+ 56, 161, 247, 40, 166, 131, 31, 100, 155, 97, 134, 157, 3, 105, 5,
+ 222, 184, 12, 243, 56, 131, 229, 104, 12, 200, 228, 238, 81, 204, 16,
+ 23, 103, 80, 46, 141, 1, 64, 163, 78, 101, 12, 253, 80, 92, 156,
+ 177, 114, 58, 176, 222, 164, 46, 161, 15, 197, 197, 25, 148, 171, 187,
+ 71, 81, 211, 145, 150, 46, 46, 206, 160, 221, 69, 142, 103, 208, 198,
+ 34, 199, 51, 161, 15, 197, 142, 103, 208, 118, 34, 199, 51, 136, 19,
+ 122, 222, 112, 161, 12, 239, 184, 71, 110, 48, 19, 54, 108, 204, 148,
+ 81, 234, 121, 243, 22, 238, 123, 164, 61, 120, 232, 237, 87, 58, 3,
+ 48, 83, 88, 26, 62, 188, 134, 188, 102, 73, 216, 158, 10, 217, 85,
+ 236, 47, 221, 163, 248, 128, 139, 1, 15, 184, 243, 185, 74, 101, 228,
+ 233, 7, 72, 29, 59, 122, 84, 195, 140, 183, 197, 219, 226, 254, 143,
+ 198, 0, 94, 71, 127, 192, 190, 166, 199, 89, 210, 19, 29, 213, 60,
+ 211, 209, 159, 219, 107, 95, 38, 195, 155, 212, 197, 199, 35, 29, 213,
+ 61, 210, 129, 114, 233, 57, 19, 168, 67, 187, 211, 36, 180, 132, 145,
+ 14, 135, 237, 216, 209, 197, 26, 102, 242, 210, 225, 176, 209, 115, 38,
+ 56, 29, 49, 240, 253, 80, 167, 82, 162, 152, 59, 29, 86, 9, 117,
+ 76, 156, 239, 179, 167, 83, 237, 162, 90, 123, 88, 196, 45, 46, 117,
+ 245, 40, 205, 213, 3, 104, 63, 77, 71, 76, 145, 188, 117, 188, 223,
+ 196, 127, 79, 15, 239, 251, 208, 190, 120, 83, 29, 5, 12, 116, 248,
+ 113, 58, 44, 154, 78, 229, 155, 23, 202, 91, 71, 219, 125, 243, 183,
+ 213, 89, 176, 164, 153, 212, 161, 128, 105, 61, 166, 105, 62, 90, 79,
+ 177, 170, 122, 38, 185, 222, 246, 218, 152, 115, 205, 92, 73, 103, 233,
+ 60, 238, 165, 96, 37, 186, 83, 122, 246, 245, 133, 114, 30, 46, 161,
+ 235, 99, 78, 211, 124, 249, 127, 203, 187, 248, 252, 47, 122, 23, 196,
+ 134, 254, 93, 28, 220, 125, 178, 14, 27, 123, 23, 135, 205, 252, 93,
+ 28, 54, 246, 46, 42, 173, 190, 139, 195, 102, 246, 46, 223, 121, 169,
+ 24, 170, 167, 120, 86, 222, 118, 25, 217, 99, 149, 206, 46, 195, 44,
+ 175, 88, 28, 150, 38, 150, 37, 150, 214, 44, 7, 117, 127, 39, 249,
+ 243, 246, 101, 219, 230, 182, 139, 151, 173, 135, 252, 202, 208, 155, 191,
+ 25, 189, 139, 87, 114, 79, 121, 236, 137, 47, 180, 62, 93, 136, 92,
+ 240, 217, 120, 37, 182, 20, 182, 245, 150, 111, 45, 56, 108, 56, 158,
+ 41, 146, 220, 71, 110, 148, 213, 76, 139, 149, 253, 228, 55, 254, 94,
+ 160, 208, 245, 18, 251, 203, 206, 105, 52, 135, 218, 45, 111, 147, 14,
+ 239, 201, 101, 10, 70, 104, 101, 66, 229, 133, 41, 106, 62, 251, 91,
+ 109, 135, 203, 94, 247, 203, 26, 222, 223, 120, 113, 255, 88, 185, 145,
+ 125, 132, 86, 102, 146, 60, 54, 92, 221, 163, 123, 190, 141, 67, 254,
+ 178, 229, 97, 67, 222, 156, 253, 243, 229, 194, 157, 125, 246, 168, 79,
+ 151, 80, 250, 173, 65, 95, 112, 207, 141, 191, 27, 182, 75, 228, 187,
+ 133, 142, 157, 97, 75, 88, 152, 216, 58, 247, 119, 11, 253, 98, 129,
+ 109, 84, 246, 122, 118, 198, 7, 124, 51, 252, 69, 194, 175, 128, 218,
+ 82, 121, 47, 216, 215, 73, 238, 59, 183, 122, 187, 220, 223, 173, 27,
+ 124, 183, 222, 99, 179, 13, 109, 239, 13, 223, 45, 248, 80, 209, 68,
+ 242, 221, 66, 166, 118, 85, 232, 204, 246, 189, 229, 30, 229, 62, 54,
+ 180, 125, 182, 179, 143, 156, 146, 180, 41, 145, 124, 183, 211, 87, 15,
+ 41, 244, 195, 132, 254, 242, 221, 31, 140, 109, 127, 69, 126, 79, 78,
+ 187, 244, 122, 18, 249, 110, 77, 166, 169, 123, 186, 143, 180, 25, 46,
+ 59, 7, 173, 54, 228, 253, 2, 190, 219, 216, 173, 251, 233, 119, 59,
+ 95, 234, 162, 66, 255, 2, 223, 109, 208, 149, 98, 134, 182, 127, 4,
+ 223, 109, 230, 4, 127, 250, 221, 8, 221, 31, 190, 27, 123, 110, 252,
+ 221, 176, 173, 55, 195, 219, 168, 92, 120, 27, 170, 125, 183, 37, 240,
+ 163, 57, 193, 128, 183, 148, 204, 38, 187, 220, 225, 109, 195, 254, 146,
+ 175, 25, 189, 203, 11, 103, 79, 121, 226, 224, 166, 109, 200, 119, 187,
+ 80, 185, 123, 27, 149, 183, 183, 252, 250, 137, 225, 109, 140, 121, 251,
+ 200, 53, 83, 3, 218, 144, 239, 54, 229, 86, 21, 133, 246, 6, 188,
+ 221, 111, 115, 220, 80, 239, 115, 248, 110, 227, 223, 248, 250, 53, 242,
+ 221, 86, 6, 141, 87, 232, 130, 128, 183, 140, 226, 87, 90, 27, 241,
+ 62, 131, 239, 86, 184, 190, 119, 107, 242, 221, 42, 117, 252, 202, 170,
+ 242, 58, 228, 87, 235, 70, 237, 52, 230, 157, 47, 191, 17, 176, 178,
+ 41, 249, 110, 132, 238, 1, 223, 141, 61, 55, 158, 223, 192, 190, 38,
+ 157, 19, 244, 130, 126, 78, 186, 81, 191, 179, 153, 174, 223, 233, 44,
+ 152, 225, 237, 44, 96, 222, 239, 196, 114, 116, 207, 78, 65, 214, 39,
+ 8, 41, 224, 105, 63, 199, 253, 248, 3, 219, 20, 186, 103, 135, 211,
+ 129, 239, 228, 212, 244, 184, 188, 61, 237, 231, 120, 185, 237, 231, 160,
+ 255, 211, 122, 20, 208, 247, 115, 72, 93, 194, 188, 61, 237, 231, 184,
+ 175, 7, 126, 43, 58, 191, 86, 32, 67, 119, 190, 60, 107, 55, 29,
+ 54, 66, 175, 178, 37, 216, 141, 218, 83, 221, 217, 224, 222, 122, 121,
+ 12, 207, 14, 27, 161, 151, 133, 236, 182, 27, 225, 92, 183, 54, 155,
+ 75, 30, 243, 51, 135, 141, 208, 171, 225, 253, 140, 252, 143, 31, 247,
+ 160, 207, 209, 61, 54, 17, 25, 222, 118, 174, 207, 248, 178, 255, 53,
+ 215, 249, 95, 24, 250, 171, 197, 220, 255, 176, 28, 157, 151, 178, 48,
+ 249, 113, 179, 197, 249, 31, 202, 165, 227, 30, 160, 81, 167, 226, 35,
+ 179, 197, 249, 95, 152, 69, 239, 127, 164, 46, 41, 17, 226, 252, 15,
+ 109, 194, 159, 211, 230, 206, 255, 66, 43, 172, 240, 216, 255, 236, 156,
+ 60, 251, 160, 34, 110, 253, 47, 12, 228, 121, 234, 127, 88, 87, 34,
+ 207, 1, 239, 231, 206, 255, 82, 124, 87, 120, 236, 127, 232, 115, 116,
+ 255, 253, 204, 12, 239, 52, 47, 35, 255, 107, 161, 243, 191, 148, 240,
+ 12, 239, 148, 89, 230, 254, 135, 229, 232, 26, 95, 56, 147, 31, 58,
+ 75, 156, 255, 133, 112, 58, 240, 157, 82, 52, 61, 105, 51, 197, 249,
+ 31, 202, 213, 173, 241, 105, 58, 28, 51, 197, 249, 31, 218, 36, 191,
+ 254, 167, 91, 227, 155, 153, 127, 255, 211, 173, 241, 205, 204, 191, 255,
+ 241, 241, 23, 125, 142, 198, 223, 137, 25, 222, 33, 17, 70, 254, 215,
+ 82, 231, 127, 142, 25, 25, 222, 142, 169, 230, 254, 135, 229, 232, 119,
+ 155, 193, 228, 251, 76, 245, 116, 222, 199, 203, 116, 190, 196, 194, 233,
+ 112, 76, 135, 247, 210, 244, 196, 76, 241, 116, 222, 199, 92, 7, 202,
+ 165, 245, 0, 154, 212, 197, 58, 197, 211, 121, 31, 15, 234, 193, 233,
+ 112, 76, 131, 122, 76, 215, 230, 50, 38, 123, 58, 239, 227, 101, 58,
+ 239, 131, 114, 105, 61, 128, 182, 104, 58, 66, 38, 231, 175, 61, 208,
+ 213, 131, 211, 129, 62, 130, 58, 149, 254, 208, 164, 252, 181, 7, 186,
+ 239, 49, 85, 223, 30, 88, 52, 29, 97, 147, 242, 215, 30, 16, 29,
+ 193, 154, 143, 242, 120, 115, 55, 174, 24, 234, 216, 99, 55, 154, 223,
+ 208, 173, 157, 76, 17, 43, 207, 42, 88, 30, 250, 153, 94, 222, 203,
+ 115, 40, 170, 60, 135, 205, 19, 121, 33, 188, 188, 111, 11, 58, 167,
+ 125, 80, 114, 79, 238, 247, 75, 123, 88, 207, 62, 115, 201, 103, 237,
+ 243, 154, 7, 209, 245, 39, 39, 113, 237, 243, 255, 231, 248, 92, 215,
+ 159, 156, 164, 175, 111, 244, 161, 79, 155, 229, 150, 103, 143, 171, 99,
+ 143, 62, 84, 42, 62, 175, 113, 163, 174, 63, 57, 145, 139, 231, 149,
+ 192, 15, 103, 26, 181, 167, 173, 244, 253, 73, 224, 13, 11, 243, 160,
+ 63, 57, 145, 235, 79, 126, 196, 249, 122, 77, 79, 219, 211, 130, 166,
+ 237, 16, 202, 165, 253, 73, 160, 81, 167, 130, 223, 87, 60, 109, 79,
+ 205, 117, 132, 113, 58, 210, 38, 64, 223, 71, 171, 139, 179, 186, 167,
+ 237, 169, 7, 245, 152, 192, 213, 3, 232, 48, 77, 71, 76, 53, 79,
+ 219, 211, 130, 166, 237, 105, 24, 167, 35, 13, 190, 31, 234, 84, 252,
+ 166, 170, 167, 237, 105, 33, 183, 237, 16, 150, 161, 245, 8, 227, 234,
+ 1, 116, 152, 166, 195, 85, 217, 211, 246, 180, 144, 219, 246, 20, 203,
+ 208, 122, 132, 229, 234, 223, 135, 105, 253, 171, 74, 158, 182, 167, 238,
+ 235, 129, 255, 79, 239, 246, 172, 153, 65, 239, 246, 196, 92, 110, 119,
+ 237, 21, 230, 114, 231, 110, 175, 154, 88, 2, 94, 58, 47, 77, 255,
+ 46, 234, 159, 95, 234, 32, 211, 185, 230, 180, 242, 75, 185, 50, 177,
+ 148, 30, 247, 236, 132, 41, 111, 116, 57, 11, 55, 31, 237, 75, 233,
+ 189, 95, 7, 202, 102, 188, 196, 6, 136, 161, 255, 235, 54, 64, 140,
+ 255, 95, 183, 1, 182, 65, 122, 27, 188, 28, 107, 85, 27, 232, 99,
+ 109, 19, 139, 175, 215, 203, 54, 112, 216, 152, 13, 84, 90, 181, 129,
+ 241, 90, 135, 106, 3, 118, 174, 1, 161, 85, 27, 24, 243, 170, 54,
+ 112, 216, 152, 13, 84, 90, 181, 129, 49, 47, 218, 32, 200, 75, 109,
+ 35, 235, 41, 45, 7, 188, 249, 217, 91, 118, 108, 243, 72, 61, 8,
+ 125, 37, 125, 144, 196, 158, 147, 179, 29, 94, 177, 116, 128, 31, 145,
+ 183, 115, 244, 82, 169, 219, 116, 210, 183, 96, 223, 114, 118, 210, 118,
+ 201, 246, 99, 222, 125, 11, 197, 126, 61, 246, 73, 115, 27, 47, 212,
+ 222, 55, 69, 58, 219, 104, 155, 66, 103, 31, 248, 87, 106, 114, 249,
+ 50, 173, 199, 90, 75, 31, 203, 102, 203, 251, 150, 68, 203, 40, 202,
+ 59, 184, 229, 3, 41, 115, 70, 97, 226, 131, 242, 230, 86, 215, 148,
+ 242, 203, 23, 22, 150, 51, 75, 239, 165, 188, 127, 90, 38, 89, 46,
+ 1, 95, 154, 37, 148, 157, 117, 240, 71, 41, 185, 204, 7, 229, 119,
+ 17, 251, 17, 186, 240, 91, 213, 184, 231, 216, 160, 54, 177, 148, 134,
+ 95, 13, 175, 38, 47, 217, 15, 219, 127, 98, 191, 110, 255, 221, 178,
+ 99, 123, 78, 236, 71, 232, 42, 155, 103, 72, 236, 57, 218, 175, 153,
+ 114, 110, 114, 111, 248, 145, 245, 138, 209, 167, 54, 74, 172, 47, 197,
+ 236, 247, 214, 170, 88, 201, 108, 173, 99, 109, 145, 157, 82, 135, 83,
+ 123, 146, 136, 253, 98, 254, 78, 80, 232, 70, 79, 92, 210, 181, 93,
+ 187, 232, 186, 193, 231, 150, 58, 96, 191, 58, 150, 61, 240, 35, 188,
+ 222, 33, 233, 82, 249, 213, 123, 216, 185, 161, 45, 39, 43, 107, 38,
+ 213, 27, 148, 147, 49, 118, 17, 222, 147, 150, 32, 229, 44, 149, 98,
+ 94, 237, 41, 239, 251, 203, 202, 203, 246, 97, 51, 127, 35, 246, 35,
+ 116, 147, 65, 213, 184, 231, 22, 75, 41, 206, 126, 132, 151, 216, 15,
+ 99, 27, 177, 95, 107, 176, 31, 198, 42, 98, 63, 66, 35, 142, 216,
+ 115, 180, 95, 45, 176, 95, 19, 240, 191, 38, 58, 28, 157, 250, 143,
+ 244, 29, 153, 253, 138, 78, 217, 14, 207, 243, 238, 59, 34, 111, 214,
+ 130, 125, 210, 180, 232, 162, 219, 136, 253, 138, 252, 108, 85, 232, 226,
+ 25, 255, 74, 85, 82, 67, 183, 49, 255, 107, 2, 246, 107, 2, 254,
+ 199, 120, 31, 151, 120, 32, 253, 178, 126, 30, 41, 35, 143, 174, 56,
+ 120, 155, 58, 127, 95, 88, 254, 98, 191, 109, 27, 243, 191, 38, 96,
+ 191, 38, 150, 251, 186, 181, 142, 82, 242, 200, 42, 206, 70, 196, 126,
+ 132, 238, 1, 246, 99, 207, 221, 251, 31, 157, 63, 168, 196, 250, 187,
+ 113, 229, 161, 239, 51, 209, 168, 191, 219, 90, 63, 127, 80, 17, 198,
+ 133, 21, 60, 152, 63, 168, 200, 245, 75, 42, 114, 243, 7, 21, 196,
+ 205, 95, 89, 56, 29, 248, 78, 14, 77, 79, 140, 175, 184, 249, 43,
+ 148, 171, 27, 175, 106, 58, 172, 190, 226, 230, 175, 208, 38, 34, 231,
+ 79, 177, 254, 34, 231, 79, 173, 190, 98, 231, 79, 209, 231, 232, 61,
+ 28, 189, 192, 142, 149, 140, 252, 239, 53, 157, 255, 89, 129, 215, 90,
+ 206, 220, 255, 176, 28, 221, 35, 87, 142, 201, 119, 150, 21, 231, 127,
+ 40, 151, 238, 245, 3, 26, 117, 42, 115, 50, 101, 197, 249, 159, 181,
+ 156, 222, 255, 72, 93, 92, 62, 226, 252, 15, 109, 34, 114, 254, 52,
+ 164, 172, 216, 249, 83, 172, 171, 200, 249, 83, 244, 57, 186, 126, 212,
+ 61, 195, 59, 174, 188, 129, 255, 53, 181, 234, 252, 207, 15, 120, 253,
+ 122, 154, 251, 31, 150, 163, 251, 180, 122, 114, 235, 71, 61, 196, 249,
+ 31, 202, 165, 251, 180, 128, 70, 157, 74, 255, 179, 135, 56, 255, 243,
+ 235, 153, 107, 159, 150, 86, 151, 148, 238, 2, 215, 143, 122, 8, 94,
+ 63, 234, 33, 120, 253, 168, 187, 224, 245, 163, 238, 220, 124, 83, 151,
+ 12, 239, 152, 94, 70, 254, 167, 223, 183, 153, 210, 45, 195, 59, 165,
+ 171, 7, 235, 71, 221, 184, 245, 163, 110, 220, 250, 81, 87, 129, 235,
+ 71, 156, 14, 124, 167, 20, 77, 79, 90, 23, 129, 235, 71, 93, 115,
+ 173, 31, 105, 58, 28, 93, 4, 174, 31, 117, 21, 188, 126, 212, 69,
+ 240, 250, 81, 23, 193, 235, 71, 93, 184, 254, 95, 167, 12, 239, 144,
+ 238, 70, 254, 167, 223, 191, 225, 120, 3, 250, 89, 175, 123, 208, 255,
+ 123, 131, 251, 110, 111, 112, 253, 191, 215, 5, 246, 255, 56, 29, 248,
+ 78, 14, 77, 79, 76, 103, 129, 253, 191, 215, 115, 245, 255, 52, 29,
+ 214, 206, 2, 251, 127, 175, 11, 238, 255, 117, 22, 220, 255, 235, 44,
+ 184, 255, 215, 137, 249, 159, 143, 12, 118, 236, 226, 198, 255, 180, 60,
+ 143, 49, 195, 134, 235, 251, 127, 192, 27, 215, 33, 195, 52, 63, 10,
+ 203, 209, 254, 95, 71, 38, 63, 90, 206, 107, 14, 217, 98, 119, 55,
+ 223, 158, 251, 187, 61, 250, 47, 188, 29, 237, 255, 117, 228, 250, 127,
+ 64, 163, 78, 165, 208, 120, 79, 116, 84, 203, 83, 199, 245, 153, 237,
+ 232, 189, 130, 86, 78, 7, 214, 155, 212, 197, 53, 214, 19, 29, 213,
+ 243, 212, 177, 180, 109, 203, 36, 90, 143, 14, 122, 31, 183, 106, 58,
+ 156, 99, 140, 116, 188, 60, 223, 254, 82, 206, 74, 163, 153, 54, 50,
+ 111, 134, 118, 39, 243, 102, 184, 215, 15, 237, 72, 228, 17, 186, 247,
+ 154, 185, 18, 123, 238, 190, 13, 59, 255, 115, 41, 249, 68, 90, 61,
+ 186, 71, 147, 148, 47, 153, 241, 142, 124, 96, 238, 2, 67, 222, 71,
+ 37, 198, 202, 55, 27, 111, 213, 202, 204, 146, 165, 38, 123, 181, 243,
+ 164, 163, 228, 148, 185, 39, 12, 121, 115, 10, 44, 144, 255, 110, 120,
+ 169, 29, 217, 55, 71, 232, 176, 27, 203, 184, 231, 121, 183, 227, 105,
+ 154, 95, 240, 54, 192, 239, 76, 108, 64, 104, 220, 235, 204, 158, 187,
+ 151, 247, 15, 216, 32, 34, 120, 96, 34, 177, 1, 41, 95, 28, 108,
+ 208, 112, 112, 75, 67, 222, 199, 96, 131, 118, 195, 171, 38, 18, 27,
+ 52, 218, 171, 238, 89, 69, 27, 220, 123, 254, 36, 193, 204, 6, 187,
+ 238, 157, 76, 32, 54, 32, 52, 218, 128, 61, 55, 182, 1, 250, 45,
+ 111, 3, 244, 67, 98, 3, 66, 15, 7, 27, 176, 231, 238, 229, 149,
+ 140, 47, 37, 23, 252, 37, 50, 137, 216, 128, 148, 111, 4, 54, 24,
+ 56, 181, 118, 146, 153, 31, 148, 143, 59, 64, 109, 208, 239, 143, 48,
+ 133, 246, 2, 27, 116, 221, 85, 44, 209, 204, 6, 129, 99, 98, 218,
+ 18, 27, 16, 122, 2, 216, 128, 61, 55, 182, 1, 226, 138, 183, 1,
+ 226, 132, 216, 128, 208, 232, 7, 236, 121, 222, 126, 112, 183, 208, 116,
+ 186, 231, 157, 148, 71, 63, 24, 18, 111, 204, 139, 54, 72, 220, 65,
+ 206, 63, 157, 37, 251, 201, 234, 121, 166, 232, 7, 191, 126, 19, 97,
+ 51, 179, 65, 249, 247, 72, 153, 37, 148, 70, 63, 96, 207, 141, 251,
+ 32, 216, 238, 211, 179, 229, 70, 66, 187, 214, 201, 48, 6, 40, 249,
+ 75, 116, 15, 37, 216, 207, 249, 161, 121, 12, 192, 114, 116, 127, 231,
+ 104, 110, 15, 233, 135, 158, 198, 0, 247, 177, 27, 241, 78, 247, 119,
+ 142, 230, 246, 169, 2, 109, 215, 218, 76, 215, 40, 79, 99, 128, 123,
+ 29, 136, 39, 90, 15, 78, 7, 214, 155, 212, 37, 108, 148, 167, 49,
+ 192, 189, 14, 244, 87, 90, 143, 15, 115, 237, 83, 37, 246, 26, 229,
+ 105, 12, 112, 175, 3, 253, 129, 206, 11, 124, 168, 223, 7, 202, 218,
+ 77, 135, 141, 208, 219, 236, 9, 118, 163, 246, 84, 183, 175, 96, 148,
+ 94, 30, 107, 131, 28, 54, 66, 163, 60, 163, 182, 73, 183, 175, 32,
+ 151, 60, 134, 103, 135, 141, 208, 241, 32, 207, 8, 231, 186, 51, 132,
+ 114, 201, 99, 216, 112, 216, 8, 141, 239, 103, 132, 25, 190, 223, 132,
+ 56, 161, 249, 126, 67, 129, 150, 205, 48, 195, 242, 202, 45, 192, 235,
+ 24, 110, 142, 25, 44, 71, 251, 212, 35, 184, 126, 251, 112, 113, 152,
+ 65, 185, 212, 215, 80, 199, 72, 173, 223, 62, 76, 28, 102, 44, 156,
+ 14, 172, 55, 169, 139, 117, 152, 56, 204, 160, 92, 221, 216, 64, 211,
+ 225, 28, 42, 14, 51, 104, 119, 62, 103, 212, 29, 102, 48, 103, 212,
+ 83, 204, 160, 141, 121, 121, 238, 48, 131, 242, 60, 197, 140, 53, 151,
+ 60, 119, 152, 241, 3, 121, 158, 98, 6, 109, 199, 203, 115, 135, 25,
+ 124, 63, 79, 49, 163, 224, 132, 200, 27, 4, 126, 48, 210, 12, 51,
+ 44, 175, 220, 57, 4, 218, 243, 193, 230, 152, 193, 114, 52, 6, 12,
+ 97, 242, 173, 54, 79, 49, 83, 192, 20, 51, 118, 78, 135, 19, 222,
+ 201, 169, 233, 177, 183, 247, 20, 51, 5, 76, 49, 131, 114, 105, 61,
+ 128, 38, 117, 9, 105, 231, 41, 102, 10, 152, 98, 198, 62, 88, 143,
+ 25, 212, 169, 140, 111, 131, 61, 197, 76, 1, 67, 204, 108, 215, 236,
+ 94, 79, 27, 215, 123, 239, 124, 152, 228, 14, 51, 23, 198, 150, 183,
+ 155, 245, 219, 135, 223, 13, 179, 63, 255, 120, 151, 86, 38, 198, 126,
+ 114, 82, 178, 66, 191, 82, 37, 222, 126, 60, 102, 191, 33, 222, 74,
+ 252, 118, 132, 147, 239, 162, 116, 226, 215, 143, 237, 158, 140, 23, 182,
+ 107, 223, 150, 212, 227, 246, 175, 15, 147, 220, 97, 245, 44, 212, 195,
+ 172, 239, 61, 0, 234, 145, 232, 53, 108, 55, 169, 199, 187, 221, 50,
+ 21, 186, 57, 212, 195, 254, 69, 101, 67, 156, 151, 130, 122, 48, 249,
+ 46, 74, 239, 134, 122, 120, 210, 231, 223, 174, 249, 15, 169, 199, 181,
+ 239, 31, 38, 185, 107, 35, 26, 140, 46, 111, 55, 235, 63, 23, 114,
+ 133, 217, 167, 142, 105, 145, 68, 234, 113, 227, 245, 242, 10, 221, 160,
+ 81, 188, 253, 104, 169, 130, 73, 70, 245, 168, 182, 251, 8, 39, 223,
+ 69, 233, 123, 171, 31, 219, 61, 233, 183, 111, 215, 124, 148, 212, 163,
+ 30, 248, 149, 187, 182, 233, 10, 124, 15, 179, 62, 176, 3, 190, 71,
+ 47, 218, 63, 143, 177, 127, 25, 164, 222, 85, 240, 168, 114, 188, 253,
+ 243, 161, 179, 12, 219, 181, 34, 240, 61, 152, 124, 23, 165, 157, 240,
+ 61, 60, 237, 123, 99, 59, 72, 239, 232, 107, 13, 56, 31, 106, 214,
+ 38, 178, 251, 3, 92, 109, 51, 188, 67, 219, 152, 183, 137, 88, 142,
+ 222, 159, 215, 150, 201, 79, 123, 45, 127, 253, 8, 126, 254, 37, 148,
+ 211, 225, 130, 119, 114, 105, 122, 28, 175, 229, 175, 31, 193, 207, 191,
+ 160, 92, 90, 15, 160, 73, 93, 124, 94, 203, 95, 63, 130, 159, 127,
+ 9, 109, 163, 111, 19, 81, 167, 226, 25, 173, 243, 215, 143, 32, 243,
+ 47, 193, 154, 221, 73, 92, 109, 24, 90, 196, 249, 124, 80, 151, 151,
+ 230, 95, 124, 156, 39, 108, 217, 173, 230, 122, 212, 143, 112, 112, 242,
+ 156, 32, 111, 70, 252, 240, 151, 230, 50, 162, 147, 79, 216, 54, 182,
+ 203, 123, 62, 66, 119, 222, 13, 39, 47, 109, 36, 200, 43, 212, 250,
+ 165, 121, 1, 215, 129, 19, 182, 189, 155, 91, 36, 121, 212, 207, 105,
+ 205, 228, 69, 195, 251, 245, 253, 112, 198, 75, 99, 236, 80, 168, 111,
+ 145, 55, 103, 122, 212, 143, 64, 156, 16, 204, 184, 154, 66, 252, 29,
+ 100, 134, 25, 118, 127, 64, 204, 171, 25, 222, 126, 173, 204, 49, 131,
+ 229, 232, 122, 222, 171, 220, 154, 77, 51, 79, 49, 83, 198, 173, 31,
+ 164, 93, 14, 161, 119, 78, 250, 113, 58, 98, 224, 157, 98, 52, 61,
+ 161, 239, 121, 138, 25, 247, 58, 124, 127, 237, 65, 117, 160, 92, 90,
+ 15, 160, 73, 93, 98, 6, 120, 138, 25, 247, 58, 70, 149, 60, 78,
+ 251, 17, 126, 173, 114, 173, 75, 182, 210, 198, 221, 253, 60, 197, 140,
+ 123, 29, 155, 158, 171, 231, 211, 204, 45, 160, 218, 189, 158, 82, 82,
+ 221, 235, 135, 118, 36, 242, 8, 253, 70, 220, 28, 59, 123, 238, 190,
+ 221, 189, 218, 235, 153, 253, 76, 219, 42, 244, 126, 176, 95, 255, 236,
+ 164, 148, 31, 144, 58, 72, 242, 122, 220, 212, 240, 220, 193, 167, 229,
+ 151, 74, 12, 171, 177, 116, 126, 212, 235, 217, 102, 201, 8, 171, 22,
+ 229, 110, 202, 109, 82, 141, 113, 81, 90, 153, 157, 82, 249, 209, 31,
+ 43, 52, 222, 107, 89, 98, 228, 66, 147, 249, 206, 125, 210, 130, 107,
+ 203, 232, 221, 123, 155, 162, 190, 162, 247, 90, 30, 173, 185, 206, 144,
+ 215, 82, 240, 148, 84, 233, 242, 70, 122, 247, 222, 231, 235, 227, 212,
+ 121, 214, 136, 179, 210, 25, 239, 29, 198, 122, 35, 47, 72, 181, 247,
+ 36, 208, 187, 247, 90, 212, 85, 251, 92, 94, 17, 151, 37, 121, 193,
+ 1, 67, 94, 175, 168, 107, 82, 86, 193, 67, 244, 94, 203, 26, 29,
+ 143, 169, 115, 195, 17, 183, 165, 129, 115, 78, 26, 242, 214, 138, 186,
+ 43, 69, 251, 166, 210, 123, 45, 251, 79, 191, 161, 208, 221, 34, 210,
+ 165, 93, 174, 71, 134, 188, 225, 81, 153, 210, 202, 187, 69, 181, 125,
+ 111, 89, 82, 237, 113, 85, 21, 122, 72, 68, 182, 116, 58, 35, 176,
+ 189, 17, 239, 127, 142, 28, 105, 228, 67, 122, 199, 183, 236, 172, 212,
+ 95, 161, 71, 219, 188, 228, 167, 109, 7, 24, 242, 166, 58, 189, 229,
+ 22, 161, 77, 181, 50, 5, 101, 231, 136, 90, 10, 189, 54, 188, 176,
+ 188, 123, 182, 151, 33, 239, 209, 200, 98, 242, 107, 235, 137, 77, 74,
+ 202, 242, 37, 245, 27, 61, 108, 95, 74, 254, 219, 59, 198, 120, 30,
+ 221, 89, 90, 110, 255, 234, 231, 90, 25, 31, 57, 120, 139, 234, 75,
+ 57, 237, 203, 202, 11, 235, 204, 49, 228, 125, 225, 44, 39, 179, 57,
+ 126, 95, 74, 159, 159, 94, 65, 54, 155, 251, 167, 184, 124, 79, 143,
+ 75, 108, 123, 8, 46, 9, 253, 58, 224, 146, 61, 119, 47, 239, 18,
+ 224, 178, 204, 124, 255, 96, 130, 75, 239, 61, 146, 82, 190, 27, 222,
+ 45, 214, 171, 172, 97, 223, 246, 38, 224, 146, 197, 188, 88, 58, 103,
+ 95, 5, 112, 105, 20, 243, 144, 183, 72, 193, 109, 82, 114, 15, 47,
+ 122, 111, 95, 145, 183, 127, 81, 116, 21, 3, 92, 190, 26, 216, 207,
+ 80, 239, 35, 192, 101, 220, 165, 154, 109, 8, 46, 79, 76, 246, 83,
+ 222, 255, 217, 211, 163, 82, 250, 228, 213, 134, 109, 73, 118, 129, 83,
+ 210, 43, 247, 110, 4, 19, 92, 222, 93, 86, 158, 222, 55, 219, 101,
+ 112, 29, 67, 219, 63, 5, 92, 246, 216, 100, 167, 184, 60, 18, 244,
+ 154, 66, 215, 6, 92, 62, 216, 218, 212, 144, 183, 24, 224, 242, 183,
+ 20, 111, 138, 203, 35, 255, 170, 247, 190, 122, 1, 46, 253, 170, 125,
+ 108, 248, 206, 87, 34, 239, 74, 251, 31, 173, 108, 75, 112, 249, 247,
+ 187, 23, 148, 61, 162, 15, 194, 211, 165, 253, 43, 182, 237, 54, 110,
+ 75, 50, 165, 216, 175, 246, 237, 38, 184, 188, 115, 168, 104, 130, 218,
+ 14, 101, 75, 243, 247, 55, 49, 180, 243, 139, 200, 28, 233, 210, 221,
+ 209, 164, 140, 188, 114, 203, 167, 10, 237, 5, 184, 180, 13, 253, 222,
+ 144, 23, 239, 196, 108, 244, 233, 254, 4, 130, 203, 255, 126, 79, 85,
+ 233, 136, 194, 242, 170, 181, 22, 67, 223, 192, 187, 197, 46, 220, 47,
+ 71, 239, 237, 107, 240, 101, 109, 149, 182, 149, 146, 223, 24, 19, 96,
+ 204, 11, 184, 44, 115, 187, 69, 34, 193, 229, 46, 223, 215, 52, 222,
+ 178, 242, 32, 155, 241, 154, 18, 226, 146, 173, 59, 249, 82, 26, 113,
+ 105, 182, 30, 69, 112, 137, 241, 157, 224, 114, 1, 224, 18, 227, 53,
+ 193, 37, 161, 151, 3, 46, 217, 115, 247, 242, 222, 234, 253, 204, 238,
+ 119, 147, 248, 163, 85, 10, 12, 216, 167, 148, 47, 112, 118, 144, 20,
+ 212, 245, 186, 161, 237, 47, 151, 3, 92, 210, 190, 99, 44, 93, 71,
+ 250, 0, 112, 105, 212, 119, 84, 244, 226, 157, 127, 125, 171, 37, 17,
+ 92, 118, 169, 85, 72, 161, 223, 6, 92, 158, 251, 251, 130, 161, 13,
+ 110, 2, 46, 219, 95, 251, 60, 145, 224, 114, 76, 117, 155, 66, 223,
+ 4, 92, 70, 92, 141, 51, 124, 231, 58, 16, 47, 119, 15, 113, 180,
+ 37, 184, 252, 115, 172, 122, 159, 116, 81, 192, 101, 211, 210, 141, 12,
+ 177, 181, 14, 112, 185, 224, 239, 69, 20, 151, 39, 187, 170, 49, 62,
+ 21, 112, 89, 38, 209, 97, 200, 123, 41, 242, 154, 116, 125, 241, 3,
+ 122, 87, 109, 131, 170, 125, 20, 122, 95, 248, 109, 105, 195, 227, 25,
+ 134, 216, 186, 7, 184, 140, 158, 251, 52, 129, 224, 50, 112, 205, 79,
+ 10, 61, 221, 145, 46, 85, 59, 211, 217, 176, 190, 71, 33, 94, 150,
+ 95, 84, 149, 222, 167, 233, 31, 171, 246, 51, 240, 174, 218, 87, 170,
+ 159, 53, 238, 91, 204, 206, 145, 46, 23, 10, 162, 241, 178, 92, 231,
+ 38, 10, 157, 6, 184, 60, 60, 183, 153, 97, 204, 171, 152, 236, 45,
+ 91, 143, 61, 110, 71, 112, 57, 229, 59, 181, 159, 177, 15, 226, 165,
+ 99, 115, 73, 67, 189, 159, 2, 46, 165, 14, 165, 41, 46, 67, 135,
+ 111, 81, 232, 61, 16, 47, 27, 76, 118, 25, 250, 198, 74, 192, 101,
+ 249, 138, 165, 147, 8, 46, 123, 156, 175, 174, 208, 201, 16, 47, 247,
+ 125, 21, 104, 232, 147, 143, 1, 151, 108, 45, 212, 151, 210, 151, 0,
+ 151, 102, 107, 164, 4, 151, 216, 39, 230, 227, 37, 246, 113, 9, 46,
+ 9, 141, 57, 43, 236, 185, 123, 121, 7, 32, 94, 214, 155, 193, 114,
+ 86, 142, 105, 229, 235, 67, 188, 12, 41, 102, 204, 123, 15, 226, 37,
+ 27, 131, 197, 210, 181, 205, 194, 128, 75, 163, 49, 152, 218, 23, 221,
+ 6, 254, 50, 139, 222, 197, 249, 119, 11, 237, 174, 70, 192, 229, 234,
+ 127, 195, 13, 121, 159, 2, 46, 183, 239, 140, 160, 119, 113, 70, 100,
+ 147, 117, 206, 163, 210, 27, 193, 179, 77, 244, 158, 146, 170, 84, 158,
+ 77, 239, 226, 140, 216, 31, 161, 221, 17, 121, 86, 138, 251, 202, 120,
+ 174, 229, 57, 224, 242, 65, 25, 58, 79, 35, 253, 81, 156, 240, 94,
+ 150, 214, 21, 50, 227, 189, 38, 221, 93, 16, 65, 239, 226, 124, 255,
+ 107, 194, 123, 91, 58, 22, 103, 204, 251, 2, 112, 217, 122, 69, 4,
+ 189, 139, 243, 122, 119, 149, 46, 2, 253, 216, 229, 5, 140, 121, 125,
+ 1, 151, 7, 78, 176, 187, 56, 87, 13, 81, 109, 254, 10, 196, 203,
+ 222, 143, 103, 24, 242, 158, 130, 120, 153, 29, 57, 133, 222, 197, 217,
+ 112, 176, 74, 151, 5, 92, 246, 151, 167, 24, 242, 62, 132, 120, 185,
+ 113, 248, 12, 122, 23, 103, 167, 213, 170, 63, 60, 0, 92, 190, 83,
+ 208, 248, 157, 159, 2, 46, 203, 116, 101, 119, 113, 254, 123, 91, 243,
+ 13, 136, 151, 157, 119, 27, 251, 6, 198, 203, 82, 95, 18, 191, 242,
+ 145, 71, 214, 32, 247, 135, 150, 149, 247, 127, 103, 236, 147, 24, 47,
+ 217, 250, 188, 47, 165, 49, 94, 154, 173, 219, 147, 57, 5, 156, 71,
+ 160, 243, 112, 189, 97, 156, 220, 218, 108, 78, 129, 221, 21, 21, 10,
+ 188, 161, 125, 205, 231, 20, 176, 28, 157, 191, 226, 198, 198, 105, 125,
+ 196, 173, 231, 161, 92, 58, 15, 7, 239, 132, 58, 21, 105, 125, 196,
+ 173, 231, 161, 92, 90, 15, 212, 161, 213, 197, 167, 143, 184, 245, 188,
+ 208, 190, 185, 230, 225, 250, 106, 243, 22, 189, 197, 173, 231, 161, 221,
+ 69, 174, 231, 57, 250, 136, 93, 207, 243, 233, 35, 118, 61, 15, 109,
+ 39, 114, 61, 15, 113, 66, 231, 225, 2, 51, 188, 93, 77, 205, 48,
+ 195, 238, 138, 138, 105, 2, 24, 107, 236, 193, 60, 92, 19, 110, 254,
+ 170, 9, 183, 119, 191, 145, 56, 204, 248, 113, 58, 98, 224, 157, 98,
+ 52, 61, 246, 70, 226, 48, 131, 114, 105, 61, 128, 38, 117, 73, 9,
+ 18, 135, 25, 191, 198, 185, 230, 225, 26, 107, 243, 137, 65, 226, 48,
+ 131, 118, 207, 47, 102, 44, 252, 125, 104, 141, 242, 143, 25, 94, 30,
+ 218, 51, 191, 152, 225, 229, 133, 6, 229, 31, 51, 186, 56, 19, 200,
+ 229, 91, 53, 0, 63, 232, 109, 134, 25, 118, 87, 84, 40, 98, 204,
+ 223, 131, 56, 19, 200, 197, 128, 0, 38, 63, 204, 95, 28, 102, 80,
+ 46, 141, 1, 64, 163, 78, 165, 144, 191, 56, 204, 132, 114, 58, 176,
+ 222, 164, 46, 209, 13, 197, 97, 6, 229, 242, 152, 9, 213, 116, 248,
+ 53, 20, 135, 25, 180, 187, 200, 56, 99, 241, 23, 27, 103, 208, 158,
+ 34, 227, 140, 95, 67, 177, 113, 6, 113, 66, 48, 19, 90, 7, 252,
+ 32, 208, 4, 51, 77, 217, 93, 81, 126, 192, 27, 83, 207, 28, 51,
+ 88, 142, 198, 128, 250, 220, 190, 145, 122, 226, 48, 131, 114, 105, 12,
+ 0, 26, 117, 42, 235, 197, 117, 197, 97, 198, 143, 211, 129, 245, 38,
+ 117, 9, 169, 43, 14, 51, 40, 151, 199, 140, 159, 166, 195, 85, 71,
+ 28, 102, 208, 238, 34, 227, 12, 218, 88, 100, 156, 9, 169, 43, 54,
+ 206, 160, 237, 68, 198, 25, 196, 9, 221, 107, 245, 28, 252, 160, 129,
+ 25, 102, 216, 158, 94, 87, 109, 104, 207, 107, 121, 176, 175, 160, 54,
+ 23, 3, 106, 115, 227, 25, 63, 129, 227, 25, 78, 135, 11, 222, 201,
+ 165, 233, 113, 248, 9, 28, 207, 212, 226, 234, 1, 52, 169, 75, 220,
+ 11, 129, 227, 153, 90, 185, 198, 51, 181, 180, 62, 230, 11, 129, 227,
+ 25, 63, 193, 227, 25, 63, 177, 113, 6, 237, 41, 50, 206, 216, 95,
+ 136, 141, 51, 136, 19, 138, 153, 199, 224, 7, 117, 242, 198, 204, 71,
+ 163, 70, 88, 38, 113, 223, 195, 14, 188, 206, 103, 238, 48, 163, 191,
+ 247, 6, 203, 209, 189, 131, 57, 76, 126, 204, 211, 188, 207, 211, 146,
+ 239, 183, 76, 250, 240, 120, 169, 96, 163, 92, 168, 155, 73, 195, 233,
+ 62, 25, 148, 75, 247, 14, 2, 141, 58, 21, 105, 217, 121, 235, 72,
+ 191, 87, 60, 97, 210, 238, 38, 134, 185, 80, 43, 39, 5, 177, 61,
+ 144, 156, 14, 172, 55, 169, 75, 232, 147, 188, 117, 188, 83, 229, 213,
+ 164, 184, 244, 118, 237, 141, 114, 161, 106, 206, 108, 65, 247, 226, 160,
+ 92, 221, 62, 120, 77, 135, 61, 43, 111, 29, 65, 83, 166, 218, 250,
+ 79, 118, 24, 230, 66, 53, 121, 155, 229, 66, 161, 221, 249, 252, 15,
+ 180, 35, 145, 71, 104, 204, 133, 98, 207, 45, 150, 101, 150, 122, 150,
+ 141, 150, 186, 150, 31, 225, 71, 218, 221, 115, 63, 151, 146, 253, 251,
+ 251, 210, 60, 32, 82, 30, 115, 161, 110, 204, 155, 97, 56, 39, 141,
+ 249, 31, 242, 154, 111, 104, 14, 140, 79, 191, 120, 154, 7, 244, 229,
+ 241, 36, 211, 28, 152, 11, 93, 78, 104, 101, 150, 80, 26, 243, 63,
+ 216, 243, 188, 99, 79, 154, 230, 23, 188, 13, 240, 59, 19, 27, 16,
+ 26, 115, 96, 216, 115, 180, 65, 32, 216, 32, 8, 108, 16, 164, 203,
+ 129, 201, 118, 244, 166, 249, 96, 164, 60, 230, 192, 188, 21, 93, 199,
+ 52, 31, 236, 207, 243, 133, 104, 62, 216, 167, 125, 175, 5, 19, 27,
+ 248, 239, 58, 18, 108, 102, 131, 202, 59, 214, 5, 19, 27, 16, 26,
+ 109, 192, 158, 27, 219, 0, 253, 150, 183, 1, 250, 33, 177, 1, 161,
+ 49, 23, 138, 61, 71, 27, 84, 7, 27, 84, 7, 27, 84, 215, 229,
+ 66, 221, 27, 205, 114, 161, 72, 121, 204, 133, 234, 181, 185, 150, 105,
+ 46, 212, 238, 227, 251, 168, 31, 236, 217, 61, 134, 230, 66, 29, 154,
+ 81, 200, 212, 15, 214, 7, 236, 167, 185, 80, 132, 198, 92, 40, 246,
+ 220, 216, 6, 136, 43, 222, 6, 136, 19, 98, 3, 66, 163, 31, 176,
+ 231, 104, 131, 241, 96, 131, 241, 96, 131, 241, 58, 63, 8, 175, 199,
+ 114, 161, 72, 121, 244, 131, 105, 46, 243, 92, 168, 149, 119, 89, 46,
+ 84, 151, 217, 44, 23, 106, 180, 203, 60, 23, 106, 220, 58, 150, 11,
+ 69, 104, 244, 3, 246, 220, 100, 63, 230, 99, 46, 23, 234, 33, 180,
+ 107, 207, 13, 99, 128, 62, 23, 10, 120, 157, 153, 30, 196, 128, 199,
+ 92, 219, 249, 136, 203, 133, 202, 244, 52, 6, 184, 239, 11, 32, 222,
+ 105, 219, 249, 136, 139, 1, 64, 163, 78, 165, 223, 145, 225, 105, 12,
+ 112, 175, 3, 241, 68, 235, 193, 233, 192, 122, 147, 186, 132, 101, 120,
+ 26, 3, 220, 235, 64, 127, 165, 245, 200, 204, 21, 3, 136, 189, 50,
+ 60, 141, 1, 238, 117, 160, 63, 208, 190, 124, 166, 62, 55, 136, 181,
+ 155, 14, 27, 161, 49, 215, 200, 168, 61, 213, 229, 66, 101, 232, 229,
+ 177, 54, 200, 97, 35, 52, 230, 26, 25, 181, 77, 186, 92, 168, 92,
+ 242, 24, 158, 29, 54, 66, 227, 251, 25, 225, 92, 55, 127, 144, 75,
+ 30, 195, 134, 195, 70, 104, 124, 63, 35, 204, 232, 114, 161, 30, 114,
+ 243, 192, 119, 192, 15, 30, 155, 97, 134, 203, 133, 2, 94, 191, 251,
+ 230, 152, 193, 114, 52, 135, 40, 157, 155, 7, 190, 39, 14, 51, 40,
+ 151, 142, 157, 225, 157, 80, 167, 226, 115, 247, 196, 97, 6, 229, 210,
+ 57, 0, 160, 73, 93, 82, 238, 138, 195, 140, 223, 253, 92, 243, 192,
+ 247, 181, 190, 217, 93, 113, 152, 65, 187, 243, 125, 111, 119, 152, 193,
+ 190, 183, 167, 152, 177, 231, 146, 231, 14, 51, 40, 207, 83, 204, 160,
+ 61, 121, 121, 238, 48, 131, 99, 13, 79, 49, 19, 154, 75, 158, 59,
+ 204, 224, 251, 121, 138, 25, 196, 9, 157, 7, 190, 9, 126, 240, 208,
+ 12, 51, 44, 23, 42, 20, 120, 93, 183, 205, 49, 131, 229, 232, 216,
+ 249, 63, 110, 30, 248, 182, 56, 204, 160, 92, 58, 118, 6, 26, 117,
+ 42, 133, 110, 139, 195, 76, 40, 167, 3, 235, 77, 234, 18, 125, 75,
+ 28, 102, 80, 174, 110, 30, 88, 211, 225, 119, 75, 28, 102, 208, 238,
+ 249, 197, 12, 63, 103, 100, 185, 157, 127, 204, 240, 242, 208, 158, 249,
+ 197, 12, 47, 207, 239, 86, 254, 49, 195, 247, 205, 16, 39, 116, 30,
+ 248, 42, 248, 193, 29, 51, 204, 176, 92, 25, 63, 224, 141, 185, 110,
+ 142, 25, 44, 71, 99, 192, 13, 110, 30, 248, 122, 254, 48, 195, 143,
+ 207, 81, 46, 141, 1, 64, 163, 78, 101, 30, 248, 90, 254, 48, 195,
+ 143, 207, 253, 56, 29, 88, 111, 82, 151, 144, 107, 249, 195, 12, 63,
+ 62, 71, 185, 186, 121, 96, 77, 135, 235, 106, 254, 48, 67, 198, 231,
+ 193, 154, 221, 137, 15, 133, 132, 22, 113, 230, 92, 144, 95, 26, 159,
+ 251, 57, 79, 216, 174, 254, 55, 54, 207, 241, 185, 46, 167, 245, 154,
+ 62, 87, 198, 59, 180, 206, 203, 99, 93, 144, 23, 213, 169, 113, 158,
+ 99, 93, 221, 249, 252, 156, 188, 155, 35, 139, 56, 135, 128, 13, 115,
+ 143, 27, 157, 7, 78, 216, 74, 103, 54, 207, 115, 220, 168, 235, 59,
+ 94, 213, 231, 202, 216, 54, 204, 120, 121, 12, 6, 239, 247, 100, 86,
+ 222, 99, 48, 62, 206, 32, 78, 104, 223, 236, 18, 248, 193, 77, 51,
+ 204, 176, 92, 25, 215, 21, 104, 207, 47, 155, 99, 6, 203, 209, 24,
+ 112, 133, 203, 149, 57, 239, 41, 102, 220, 231, 127, 212, 157, 220, 155,
+ 222, 77, 30, 202, 233, 112, 193, 59, 185, 52, 61, 49, 169, 158, 98,
+ 198, 189, 142, 192, 14, 61, 169, 14, 148, 75, 235, 1, 52, 169, 139,
+ 235, 180, 167, 152, 113, 175, 99, 221, 26, 150, 43, 19, 122, 57, 215,
+ 60, 240, 101, 173, 111, 118, 212, 83, 204, 184, 215, 17, 203, 231, 202,
+ 156, 103, 123, 12, 151, 250, 7, 57, 209, 142, 68, 30, 161, 59, 199,
+ 205, 177, 179, 231, 228, 76, 232, 134, 150, 182, 240, 35, 237, 174, 171,
+ 215, 51, 251, 124, 248, 70, 100, 143, 225, 125, 123, 15, 165, 124, 175,
+ 212, 65, 210, 168, 169, 13, 232, 156, 111, 95, 139, 191, 101, 4, 240,
+ 205, 228, 120, 31, 149, 95, 42, 49, 172, 198, 210, 249, 51, 239, 103,
+ 155, 37, 35, 172, 146, 61, 134, 78, 199, 96, 186, 39, 255, 203, 240,
+ 97, 10, 141, 185, 50, 97, 51, 70, 82, 222, 56, 224, 221, 14, 124,
+ 59, 57, 222, 231, 5, 246, 73, 31, 72, 147, 233, 222, 223, 119, 142,
+ 206, 86, 104, 204, 149, 217, 18, 56, 143, 242, 38, 2, 79, 50, 252,
+ 14, 232, 120, 79, 73, 31, 255, 180, 56, 145, 236, 49, 44, 49, 97,
+ 89, 34, 217, 99, 120, 252, 207, 21, 148, 247, 48, 240, 28, 183, 212,
+ 177, 164, 192, 143, 223, 99, 88, 117, 216, 218, 68, 178, 199, 240, 114,
+ 179, 53, 10, 93, 44, 226, 178, 244, 173, 229, 43, 202, 123, 18, 120,
+ 78, 195, 47, 149, 227, 125, 18, 121, 77, 250, 126, 242, 162, 68, 178,
+ 199, 112, 198, 115, 245, 142, 202, 130, 17, 183, 165, 55, 231, 71, 25,
+ 246, 5, 106, 68, 221, 149, 134, 7, 76, 79, 36, 123, 12, 23, 182,
+ 90, 160, 208, 99, 34, 210, 165, 152, 179, 95, 80, 222, 11, 240, 206,
+ 151, 224, 119, 133, 211, 27, 29, 149, 41, 101, 13, 254, 37, 145, 236,
+ 49, 188, 90, 251, 188, 66, 143, 138, 200, 150, 126, 207, 178, 208, 246,
+ 234, 154, 165, 182, 229, 134, 165, 150, 229, 150, 165, 38, 229, 221, 235,
+ 200, 145, 18, 151, 208, 253, 178, 242, 76, 167, 85, 161, 107, 219, 188,
+ 228, 38, 105, 108, 47, 236, 29, 104, 227, 238, 193, 47, 141, 155, 35,
+ 75, 119, 122, 203, 151, 127, 171, 146, 68, 246, 24, 30, 252, 182, 148,
+ 66, 159, 11, 47, 44, 23, 204, 184, 77, 223, 57, 221, 82, 195, 146,
+ 1, 58, 179, 44, 126, 148, 247, 66, 100, 49, 57, 61, 115, 23, 221,
+ 251, 219, 214, 246, 181, 118, 183, 103, 41, 185, 217, 176, 37, 148, 55,
+ 7, 222, 217, 203, 171, 142, 165, 144, 23, 251, 190, 89, 206, 210, 114,
+ 221, 148, 40, 186, 39, 255, 213, 10, 170, 221, 158, 183, 47, 43, 47,
+ 94, 56, 198, 116, 79, 62, 155, 3, 246, 165, 52, 238, 49, 228, 231,
+ 134, 139, 131, 190, 210, 240, 43, 199, 233, 165, 123, 242, 83, 25, 46,
+ 63, 3, 92, 98, 219, 67, 215, 63, 52, 186, 35, 224, 146, 61, 119,
+ 143, 203, 51, 128, 203, 18, 247, 139, 211, 28, 182, 176, 58, 93, 149,
+ 242, 109, 1, 151, 143, 222, 188, 210, 150, 225, 178, 161, 134, 75, 127,
+ 93, 174, 12, 139, 121, 177, 116, 78, 183, 16, 224, 210, 40, 230, 17,
+ 92, 254, 147, 89, 141, 230, 176, 157, 223, 238, 163, 157, 217, 149, 32,
+ 93, 152, 88, 168, 29, 195, 101, 32, 224, 50, 16, 112, 25, 168, 219,
+ 251, 187, 176, 254, 173, 96, 130, 203, 164, 222, 169, 193, 100, 239, 111,
+ 214, 172, 223, 131, 25, 46, 3, 1, 151, 1, 128, 203, 0, 150, 75,
+ 86, 240, 148, 52, 41, 253, 16, 205, 149, 217, 243, 223, 230, 96, 21,
+ 31, 103, 165, 110, 55, 215, 6, 51, 92, 6, 0, 46, 3, 0, 151,
+ 140, 55, 27, 112, 121, 123, 237, 176, 96, 130, 203, 6, 173, 135, 42,
+ 116, 97, 192, 229, 144, 63, 7, 7, 51, 92, 250, 3, 46, 3, 0,
+ 151, 140, 215, 18, 117, 77, 186, 242, 252, 11, 186, 39, 127, 103, 240,
+ 214, 96, 178, 247, 119, 221, 140, 131, 134, 125, 234, 39, 145, 119, 165,
+ 147, 235, 238, 7, 19, 92, 174, 222, 148, 173, 210, 128, 203, 245, 255,
+ 120, 183, 99, 184, 12, 4, 92, 6, 2, 46, 3, 185, 182, 36, 83,
+ 122, 45, 248, 81, 48, 193, 165, 163, 210, 35, 77, 47, 224, 50, 61,
+ 51, 152, 225, 50, 16, 112, 25, 8, 184, 12, 228, 222, 57, 71, 58,
+ 246, 40, 139, 148, 145, 35, 239, 168, 186, 188, 1, 151, 27, 222, 47,
+ 214, 142, 225, 50, 16, 112, 25, 8, 184, 12, 212, 229, 202, 172, 186,
+ 84, 149, 238, 201, 239, 151, 229, 167, 229, 36, 21, 150, 183, 215, 99,
+ 185, 15, 233, 192, 147, 1, 191, 44, 206, 55, 48, 87, 230, 208, 63,
+ 129, 52, 135, 109, 171, 83, 245, 37, 47, 91, 41, 185, 86, 11, 107,
+ 59, 134, 75, 224, 241, 10, 2, 92, 6, 113, 216, 42, 45, 159, 40,
+ 220, 156, 230, 176, 213, 89, 216, 76, 227, 45, 43, 79, 45, 213, 204,
+ 52, 135, 141, 173, 75, 248, 82, 26, 113, 201, 175, 87, 20, 7, 125,
+ 165, 225, 87, 142, 211, 75, 247, 228, 159, 102, 184, 252, 4, 112, 137,
+ 241, 154, 224, 146, 208, 203, 0, 151, 236, 57, 226, 210, 31, 144, 229,
+ 15, 184, 100, 216, 234, 219, 251, 153, 253, 69, 171, 186, 52, 87, 166,
+ 242, 212, 195, 106, 249, 179, 131, 164, 110, 210, 21, 46, 94, 6, 2,
+ 46, 253, 1, 151, 13, 88, 110, 85, 185, 165, 18, 235, 59, 198, 210,
+ 117, 134, 247, 0, 151, 70, 125, 71, 228, 237, 93, 112, 155, 180, 100,
+ 99, 85, 154, 43, 83, 230, 31, 245, 252, 133, 190, 128, 203, 121, 101,
+ 254, 229, 226, 101, 13, 192, 101, 77, 192, 101, 45, 93, 174, 76, 219,
+ 23, 203, 105, 188, 244, 122, 212, 73, 161, 111, 61, 61, 42, 69, 94,
+ 222, 151, 192, 112, 89, 7, 112, 89, 15, 112, 201, 222, 185, 46, 224,
+ 114, 201, 183, 111, 180, 33, 184, 236, 216, 241, 148, 226, 119, 37, 0,
+ 151, 175, 93, 173, 222, 142, 225, 210, 95, 195, 37, 243, 181, 173, 128,
+ 75, 185, 237, 92, 154, 43, 19, 116, 98, 154, 154, 211, 58, 251, 178,
+ 52, 185, 206, 168, 118, 12, 151, 141, 0, 151, 141, 0, 151, 236, 187,
+ 29, 135, 120, 89, 229, 206, 247, 20, 151, 101, 47, 87, 81, 231, 64,
+ 195, 111, 75, 51, 55, 71, 24, 238, 223, 40, 2, 241, 242, 210, 249,
+ 102, 52, 94, 62, 190, 175, 174, 171, 148, 138, 76, 151, 106, 173, 252,
+ 57, 129, 225, 178, 30, 224, 178, 62, 224, 146, 213, 247, 52, 196, 203,
+ 26, 35, 75, 210, 92, 153, 97, 99, 212, 92, 153, 111, 195, 179, 165,
+ 154, 219, 92, 237, 244, 184, 108, 12, 184, 180, 82, 222, 25, 17, 57,
+ 210, 153, 45, 52, 39, 70, 174, 217, 183, 181, 66, 31, 4, 92, 102,
+ 62, 108, 215, 158, 225, 178, 37, 224, 178, 37, 224, 178, 21, 229, 109,
+ 150, 236, 45, 23, 155, 80, 156, 230, 150, 134, 222, 254, 167, 157, 218,
+ 183, 40, 44, 7, 28, 123, 157, 195, 101, 51, 192, 165, 85, 135, 203,
+ 121, 128, 203, 94, 242, 185, 4, 130, 203, 160, 173, 235, 149, 250, 238,
+ 128, 120, 121, 102, 94, 42, 23, 47, 235, 107, 241, 146, 197, 248, 79,
+ 1, 151, 233, 29, 74, 208, 92, 153, 7, 73, 170, 143, 37, 64, 188,
+ 44, 221, 52, 192, 120, 45, 11, 112, 201, 214, 202, 124, 41, 141, 185,
+ 50, 252, 26, 90, 113, 175, 234, 128, 203, 234, 128, 203, 234, 47, 231,
+ 150, 30, 213, 231, 202, 196, 114, 185, 50, 177, 92, 174, 76, 44, 151,
+ 43, 163, 198, 203, 9, 128, 203, 9, 186, 92, 25, 236, 63, 19, 92,
+ 254, 194, 229, 202, 36, 149, 99, 188, 125, 129, 103, 4, 252, 102, 90,
+ 194, 116, 185, 50, 108, 12, 22, 75, 215, 190, 48, 94, 26, 141, 193,
+ 72, 188, 188, 247, 53, 203, 149, 121, 222, 49, 220, 70, 226, 101, 233,
+ 59, 44, 31, 34, 14, 244, 109, 135, 223, 78, 78, 47, 198, 203, 173,
+ 71, 89, 174, 204, 232, 234, 179, 105, 174, 76, 195, 49, 236, 157, 19,
+ 129, 39, 25, 126, 7, 56, 94, 204, 149, 201, 28, 200, 114, 101, 62,
+ 106, 58, 155, 230, 202, 52, 173, 202, 120, 15, 3, 207, 113, 248, 165,
+ 112, 188, 216, 143, 237, 177, 147, 229, 202, 188, 157, 204, 114, 101, 134,
+ 29, 102, 243, 52, 39, 129, 231, 52, 252, 82, 117, 188, 215, 164, 215,
+ 187, 205, 166, 185, 50, 227, 7, 207, 166, 185, 50, 43, 167, 207, 54,
+ 205, 149, 185, 251, 238, 108, 154, 43, 243, 79, 128, 74, 23, 134, 120,
+ 121, 224, 9, 211, 123, 1, 244, 93, 130, 223, 21, 78, 111, 57, 192,
+ 229, 39, 37, 103, 211, 92, 153, 105, 90, 174, 73, 13, 136, 151, 61,
+ 63, 100, 103, 184, 92, 3, 158, 27, 240, 187, 197, 241, 158, 142, 204,
+ 145, 166, 87, 154, 70, 115, 101, 182, 30, 156, 170, 174, 85, 2, 46,
+ 175, 79, 158, 106, 99, 184, 28, 7, 184, 28, 7, 184, 28, 199, 245,
+ 39, 189, 229, 123, 103, 89, 174, 204, 131, 127, 85, 127, 120, 12, 253,
+ 216, 203, 215, 217, 247, 77, 7, 159, 200, 128, 95, 22, 167, 247, 25,
+ 224, 114, 242, 167, 44, 87, 230, 104, 51, 109, 157, 19, 226, 229, 84,
+ 46, 39, 41, 7, 121, 188, 194, 0, 151, 97, 186, 92, 153, 57, 167,
+ 89, 174, 204, 199, 111, 178, 92, 153, 5, 127, 153, 231, 202, 176, 245,
+ 91, 95, 74, 99, 188, 228, 215, 117, 139, 123, 141, 7, 92, 142, 7,
+ 92, 142, 127, 121, 15, 243, 37, 46, 87, 230, 36, 140, 147, 175, 154,
+ 205, 41, 112, 185, 50, 192, 27, 122, 218, 131, 185, 235, 75, 220, 120,
+ 223, 197, 237, 45, 59, 37, 112, 238, 218, 197, 141, 247, 129, 70, 157,
+ 138, 180, 83, 2, 231, 174, 121, 29, 80, 111, 82, 23, 159, 83, 226,
+ 230, 174, 81, 174, 110, 238, 90, 211, 17, 115, 82, 220, 220, 53, 218,
+ 93, 228, 122, 143, 227, 148, 216, 245, 30, 159, 83, 98, 215, 123, 208,
+ 118, 34, 215, 123, 16, 39, 116, 189, 231, 16, 248, 193, 37, 51, 204,
+ 112, 185, 50, 127, 66, 249, 195, 230, 152, 193, 114, 20, 51, 71, 184,
+ 245, 158, 195, 2, 49, 115, 132, 243, 103, 160, 81, 167, 26, 76, 4,
+ 98, 134, 211, 129, 245, 38, 117, 137, 254, 67, 224, 122, 207, 225, 92,
+ 152, 209, 116, 248, 253, 33, 112, 189, 231, 176, 224, 245, 158, 195, 130,
+ 215, 123, 254, 16, 188, 222, 243, 135, 224, 245, 158, 67, 220, 122, 207,
+ 254, 12, 111, 191, 147, 102, 152, 97, 185, 50, 126, 192, 27, 115, 208,
+ 131, 245, 158, 67, 220, 58, 201, 239, 220, 122, 207, 65, 113, 152, 65,
+ 185, 116, 189, 7, 104, 212, 169, 174, 11, 136, 195, 140, 31, 167, 3,
+ 235, 77, 234, 18, 114, 64, 28, 102, 80, 174, 110, 189, 71, 211, 225,
+ 218, 47, 14, 51, 104, 119, 145, 113, 6, 109, 44, 50, 206, 132, 28,
+ 16, 27, 103, 208, 118, 34, 227, 12, 226, 132, 198, 153, 61, 224, 7,
+ 135, 76, 48, 195, 229, 202, 184, 246, 65, 31, 104, 175, 7, 235, 61,
+ 251, 184, 24, 176, 143, 235, 155, 37, 139, 195, 76, 40, 167, 195, 5,
+ 239, 228, 210, 244, 56, 146, 197, 97, 6, 229, 210, 122, 0, 77, 234,
+ 226, 147, 44, 176, 111, 182, 55, 215, 122, 207, 94, 173, 111, 230, 20,
+ 216, 55, 75, 22, 27, 103, 28, 201, 98, 227, 140, 79, 178, 216, 56,
+ 131, 182, 19, 26, 103, 246, 112, 113, 102, 55, 248, 193, 126, 51, 204,
+ 176, 61, 159, 126, 136, 177, 68, 15, 226, 204, 30, 174, 125, 78, 226,
+ 226, 76, 162, 192, 56, 147, 196, 197, 25, 160, 81, 167, 18, 103, 18,
+ 4, 198, 25, 78, 7, 214, 155, 212, 37, 36, 65, 96, 156, 73, 204,
+ 21, 103, 52, 29, 174, 221, 2, 227, 76, 162, 224, 56, 147, 32, 56,
+ 206, 36, 8, 142, 51, 187, 5, 199, 153, 221, 28, 102, 182, 131, 31,
+ 236, 113, 135, 153, 145, 227, 63, 26, 52, 77, 217, 35, 109, 225, 219,
+ 192, 93, 128, 177, 223, 60, 200, 47, 219, 197, 181, 207, 187, 152, 124,
+ 251, 206, 252, 221, 27, 84, 179, 91, 249, 166, 180, 125, 230, 116, 184,
+ 224, 157, 92, 154, 30, 191, 95, 243, 119, 111, 144, 37, 118, 94, 60,
+ 173, 199, 111, 92, 61, 128, 166, 117, 249, 37, 127, 247, 6, 253, 52,
+ 124, 49, 59, 183, 246, 183, 92, 113, 230, 55, 13, 51, 219, 243, 119,
+ 111, 208, 225, 38, 83, 104, 174, 12, 218, 93, 151, 35, 1, 118, 164,
+ 123, 93, 52, 250, 163, 150, 11, 36, 246, 220, 125, 187, 235, 106, 80,
+ 85, 46, 111, 209, 46, 211, 195, 28, 9, 173, 124, 225, 172, 55, 229,
+ 90, 239, 148, 50, 228, 205, 46, 50, 88, 182, 219, 30, 169, 23, 65,
+ 90, 198, 200, 13, 106, 252, 165, 208, 197, 50, 102, 200, 145, 119, 190,
+ 183, 26, 241, 62, 157, 247, 177, 60, 123, 152, 151, 149, 228, 7, 16,
+ 218, 255, 220, 10, 238, 185, 113, 142, 4, 250, 5, 111, 3, 252, 206,
+ 212, 166, 26, 141, 54, 96, 207, 243, 182, 65, 153, 175, 99, 226, 137,
+ 13, 72, 121, 180, 193, 225, 14, 142, 120, 51, 27, 244, 248, 104, 96,
+ 60, 177, 193, 142, 174, 114, 60, 177, 65, 159, 165, 21, 227, 205, 108,
+ 208, 227, 204, 135, 63, 19, 27, 16, 26, 109, 192, 158, 27, 219, 0,
+ 253, 150, 183, 1, 250, 33, 177, 1, 161, 187, 128, 13, 216, 115, 247,
+ 242, 194, 192, 6, 103, 127, 141, 165, 185, 50, 164, 252, 43, 96, 131,
+ 179, 9, 31, 27, 242, 22, 47, 58, 88, 238, 251, 219, 135, 73, 196,
+ 6, 253, 170, 116, 87, 104, 63, 176, 193, 222, 134, 53, 12, 121, 159,
+ 131, 13, 42, 253, 52, 133, 230, 76, 17, 26, 109, 192, 158, 27, 219,
+ 0, 113, 197, 219, 0, 113, 66, 108, 64, 232, 241, 96, 3, 246, 220,
+ 189, 188, 179, 96, 131, 162, 145, 31, 209, 92, 25, 82, 190, 40, 216,
+ 160, 255, 29, 99, 222, 39, 224, 7, 227, 35, 72, 158, 205, 24, 185,
+ 196, 5, 117, 46, 26, 253, 32, 243, 246, 44, 155, 153, 31, 20, 91,
+ 48, 155, 230, 202, 16, 26, 109, 192, 158, 27, 247, 155, 176, 221, 167,
+ 119, 183, 174, 133, 118, 109, 183, 81, 12, 208, 223, 93, 232, 218, 6,
+ 229, 227, 61, 136, 1, 219, 184, 182, 115, 27, 55, 214, 248, 57, 127,
+ 57, 198, 136, 119, 218, 118, 114, 58, 92, 240, 78, 46, 77, 79, 220,
+ 55, 249, 203, 49, 70, 60, 209, 122, 196, 115, 245, 0, 154, 212, 197,
+ 254, 77, 254, 114, 140, 209, 95, 105, 61, 226, 115, 197, 128, 120, 45,
+ 183, 96, 109, 254, 114, 140, 209, 31, 232, 88, 227, 103, 125, 238, 8,
+ 107, 55, 29, 54, 66, 207, 107, 159, 96, 55, 106, 79, 117, 57, 193,
+ 223, 232, 229, 177, 54, 200, 97, 35, 52, 202, 51, 106, 155, 116, 121,
+ 4, 185, 228, 49, 60, 59, 108, 132, 158, 11, 242, 140, 112, 174, 203,
+ 35, 88, 171, 151, 199, 176, 225, 176, 17, 26, 223, 207, 8, 51, 186,
+ 251, 102, 215, 114, 247, 45, 126, 5, 126, 176, 221, 8, 51, 205, 117,
+ 152, 73, 249, 58, 195, 59, 100, 141, 57, 102, 176, 28, 189, 111, 246,
+ 107, 38, 223, 181, 90, 28, 102, 66, 56, 29, 41, 240, 78, 41, 154,
+ 158, 176, 213, 226, 48, 131, 114, 105, 61, 128, 166, 117, 89, 45, 14,
+ 51, 33, 107, 244, 152, 65, 157, 202, 92, 243, 87, 226, 48, 131, 118,
+ 39, 62, 20, 99, 111, 226, 22, 51, 209, 241, 91, 60, 198, 76, 88,
+ 46, 121, 238, 48, 131, 242, 60, 197, 140, 133, 147, 23, 10, 242, 220,
+ 97, 6, 229, 121, 138, 25, 180, 29, 255, 126, 238, 48, 131, 242, 60,
+ 197, 12, 226, 132, 96, 38, 229, 11, 240, 131, 181, 70, 152, 105, 161,
+ 195, 76, 244, 42, 224, 253, 210, 28, 51, 88, 142, 248, 129, 207, 42,
+ 46, 47, 127, 165, 56, 204, 248, 112, 58, 162, 225, 157, 162, 53, 61,
+ 214, 149, 226, 48, 131, 114, 105, 61, 128, 38, 117, 113, 174, 16, 135,
+ 25, 159, 47, 245, 152, 65, 157, 202, 28, 192, 10, 113, 152, 65, 187,
+ 231, 23, 51, 252, 156, 145, 117, 101, 254, 49, 195, 203, 67, 123, 230,
+ 23, 51, 188, 188, 144, 21, 249, 199, 12, 223, 55, 67, 156, 16, 204,
+ 68, 127, 6, 244, 87, 70, 152, 105, 169, 195, 76, 8, 240, 166, 44,
+ 51, 199, 12, 150, 163, 49, 96, 57, 183, 239, 127, 89, 254, 48, 195,
+ 143, 207, 81, 46, 141, 1, 64, 163, 78, 165, 255, 247, 121, 254, 48,
+ 195, 143, 207, 67, 56, 29, 88, 111, 82, 23, 199, 231, 249, 195, 12,
+ 63, 62, 71, 185, 186, 187, 211, 53, 29, 62, 159, 231, 15, 51, 100,
+ 124, 30, 172, 217, 157, 191, 27, 58, 232, 113, 177, 151, 198, 231, 97,
+ 97, 19, 237, 157, 227, 170, 53, 245, 164, 29, 71, 27, 243, 242, 190,
+ 29, 243, 238, 75, 99, 93, 148, 247, 107, 139, 213, 241, 30, 173, 249,
+ 115, 242, 222, 24, 81, 196, 217, 109, 251, 232, 151, 198, 141, 149, 199,
+ 79, 180, 251, 253, 28, 227, 209, 189, 50, 62, 156, 188, 56, 120, 191,
+ 218, 221, 167, 189, 52, 6, 155, 6, 239, 55, 179, 203, 36, 143, 226,
+ 140, 130, 19, 50, 127, 186, 17, 252, 224, 11, 35, 204, 180, 210, 97,
+ 38, 230, 167, 12, 111, 191, 173, 30, 156, 103, 249, 19, 55, 71, 251,
+ 19, 147, 239, 216, 236, 41, 102, 10, 187, 247, 103, 126, 174, 153, 211,
+ 17, 3, 239, 20, 163, 233, 113, 109, 242, 20, 51, 230, 58, 80, 46,
+ 173, 7, 208, 164, 46, 246, 31, 60, 197, 140, 7, 245, 216, 154, 43,
+ 143, 121, 171, 182, 118, 178, 209, 83, 204, 228, 165, 195, 161, 96, 102,
+ 164, 151, 106, 247, 122, 74, 73, 117, 143, 97, 46, 121, 22, 178, 199,
+ 80, 199, 93, 178, 190, 165, 153, 69, 253, 145, 118, 215, 217, 235, 153,
+ 189, 208, 159, 73, 141, 201, 30, 195, 41, 213, 212, 184, 228, 151, 58,
+ 72, 58, 242, 222, 135, 134, 49, 42, 173, 252, 82, 41, 32, 131, 96,
+ 53, 150, 206, 159, 149, 30, 151, 36, 61, 141, 175, 102, 56, 31, 150,
+ 254, 217, 63, 146, 227, 83, 167, 149, 236, 155, 203, 185, 125, 74, 161,
+ 11, 205, 120, 44, 205, 26, 120, 214, 80, 239, 115, 217, 34, 255, 85,
+ 171, 72, 83, 178, 127, 237, 102, 195, 210, 77, 213, 61, 134, 69, 229,
+ 77, 243, 43, 25, 234, 205, 41, 80, 70, 102, 243, 124, 190, 148, 14,
+ 187, 81, 69, 54, 155, 255, 35, 182, 71, 127, 20, 101, 251, 223, 19,
+ 223, 137, 35, 182, 63, 212, 83, 141, 225, 104, 251, 50, 143, 143, 255,
+ 108, 102, 251, 9, 211, 73, 187, 22, 75, 231, 237, 208, 246, 15, 27,
+ 175, 142, 55, 179, 125, 212, 234, 228, 120, 98, 251, 1, 125, 23, 197,
+ 19, 219, 47, 159, 242, 81, 188, 153, 237, 235, 22, 255, 229, 103, 98,
+ 251, 128, 38, 235, 127, 38, 182, 191, 176, 99, 254, 207, 102, 182, 103,
+ 243, 139, 190, 148, 70, 219, 155, 205, 59, 18, 219, 35, 78, 137, 237,
+ 83, 243, 176, 253, 103, 30, 216, 222, 187, 207, 51, 251, 221, 224, 15,
+ 104, 46, 74, 82, 45, 181, 191, 243, 243, 63, 131, 164, 55, 6, 158,
+ 53, 236, 251, 84, 2, 219, 151, 218, 53, 154, 238, 121, 39, 49, 224,
+ 202, 216, 36, 233, 147, 173, 49, 134, 115, 120, 49, 203, 254, 145, 46,
+ 94, 221, 150, 68, 108, 127, 240, 96, 180, 66, 247, 154, 249, 88, 106,
+ 84, 102, 158, 33, 111, 115, 176, 253, 103, 71, 253, 105, 254, 209, 16,
+ 91, 29, 133, 14, 7, 219, 7, 204, 173, 106, 200, 123, 31, 108, 207,
+ 230, 53, 125, 41, 221, 21, 108, 111, 54, 223, 73, 108, 143, 237, 151,
+ 222, 239, 29, 54, 102, 123, 149, 238, 160, 216, 222, 97, 211, 219, 254,
+ 154, 206, 246, 199, 193, 239, 215, 45, 99, 251, 154, 63, 215, 250, 134,
+ 77, 192, 239, 47, 255, 103, 124, 222, 250, 109, 176, 125, 66, 183, 105,
+ 116, 95, 51, 137, 151, 101, 192, 239, 255, 54, 136, 151, 200, 91, 244,
+ 243, 127, 164, 140, 152, 9, 116, 175, 238, 176, 79, 39, 43, 116, 69,
+ 240, 251, 54, 231, 77, 206, 151, 7, 219, 63, 34, 251, 85, 193, 246,
+ 127, 253, 166, 210, 197, 192, 246, 22, 155, 241, 59, 63, 3, 219, 179,
+ 249, 84, 95, 74, 143, 3, 219, 155, 205, 179, 210, 125, 120, 27, 185,
+ 57, 203, 111, 97, 12, 246, 153, 81, 140, 111, 173, 143, 241, 27, 32,
+ 206, 125, 239, 65, 140, 223, 192, 197, 198, 13, 76, 190, 223, 103, 226,
+ 198, 146, 126, 156, 142, 24, 120, 167, 24, 77, 79, 220, 119, 226, 198,
+ 146, 40, 151, 214, 3, 104, 82, 23, 251, 119, 226, 198, 146, 126, 223,
+ 231, 138, 241, 223, 107, 115, 150, 223, 138, 27, 75, 162, 221, 69, 206,
+ 191, 160, 141, 69, 206, 191, 216, 191, 19, 59, 255, 130, 182, 19, 57,
+ 255, 130, 56, 161, 231, 34, 46, 1, 63, 216, 104, 132, 153, 215, 244,
+ 115, 150, 235, 97, 204, 182, 206, 131, 57, 203, 245, 220, 56, 111, 61,
+ 55, 103, 25, 35, 112, 206, 146, 211, 145, 2, 239, 148, 162, 233, 9,
+ 139, 17, 56, 103, 185, 142, 171, 7, 208, 164, 46, 113, 75, 5, 206,
+ 89, 174, 203, 53, 103, 185, 78, 195, 229, 82, 129, 115, 150, 49, 98,
+ 231, 95, 194, 98, 196, 206, 191, 160, 61, 69, 206, 191, 216, 151, 138,
+ 157, 127, 65, 156, 208, 115, 228, 22, 130, 31, 124, 107, 128, 153, 166,
+ 86, 29, 102, 236, 192, 235, 92, 108, 142, 25, 44, 71, 207, 95, 251,
+ 148, 59, 71, 110, 113, 254, 48, 115, 234, 226, 56, 138, 25, 148, 75,
+ 207, 145, 3, 26, 117, 42, 184, 92, 148, 63, 204, 248, 237, 77, 165,
+ 152, 177, 115, 58, 176, 222, 164, 46, 97, 139, 242, 135, 153, 161, 241,
+ 87, 216, 121, 120, 139, 115, 157, 35, 71, 236, 181, 40, 127, 152, 249,
+ 121, 20, 119, 142, 220, 98, 230, 67, 185, 229, 161, 77, 115, 247, 175,
+ 77, 247, 236, 44, 202, 91, 30, 218, 239, 127, 42, 47, 204, 64, 30,
+ 218, 234, 127, 42, 207, 98, 32, 15, 237, 226, 169, 60, 122, 142, 220,
+ 66, 134, 25, 251, 199, 224, 7, 75, 140, 48, 163, 223, 83, 100, 1,
+ 94, 199, 39, 230, 152, 193, 114, 244, 28, 185, 5, 76, 190, 207, 39,
+ 226, 226, 12, 202, 165, 190, 134, 58, 22, 106, 243, 22, 243, 197, 197,
+ 25, 11, 167, 3, 235, 77, 234, 98, 157, 47, 46, 206, 160, 92, 30,
+ 51, 22, 77, 135, 243, 99, 113, 113, 6, 237, 46, 50, 206, 160, 141,
+ 69, 198, 25, 235, 124, 177, 113, 6, 109, 39, 50, 206, 32, 78, 8,
+ 102, 44, 81, 224, 7, 11, 141, 48, 163, 223, 131, 225, 156, 7, 237,
+ 249, 92, 115, 204, 96, 57, 26, 3, 230, 49, 249, 41, 115, 196, 97,
+ 198, 206, 233, 112, 194, 59, 57, 53, 61, 161, 115, 196, 97, 6, 229,
+ 210, 122, 0, 77, 234, 146, 22, 37, 14, 51, 246, 185, 122, 204, 160,
+ 78, 69, 90, 148, 56, 204, 160, 221, 69, 142, 103, 66, 231, 136, 29,
+ 207, 160, 61, 69, 142, 103, 28, 81, 98, 199, 51, 136, 19, 58, 207,
+ 255, 97, 166, 183, 253, 99, 119, 152, 25, 53, 120, 212, 32, 188, 26,
+ 97, 146, 238, 140, 95, 71, 36, 140, 127, 198, 103, 190, 244, 45, 115,
+ 99, 6, 203, 17, 63, 136, 179, 112, 229, 199, 101, 122, 91, 76, 254,
+ 140, 246, 174, 182, 238, 48, 141, 222, 91, 128, 114, 233, 28, 0, 188,
+ 19, 234, 84, 250, 102, 99, 60, 209, 145, 247, 222, 213, 237, 91, 199,
+ 178, 59, 75, 198, 51, 29, 88, 111, 82, 23, 231, 104, 79, 116, 228,
+ 189, 119, 117, 218, 233, 222, 108, 14, 128, 211, 97, 209, 116, 42, 255,
+ 126, 232, 137, 142, 188, 247, 174, 158, 110, 62, 155, 238, 93, 69, 187,
+ 243, 251, 245, 208, 142, 196, 135, 8, 141, 103, 91, 179, 231, 238, 219,
+ 93, 60, 219, 186, 94, 121, 114, 46, 70, 119, 153, 148, 199, 179, 173,
+ 183, 180, 124, 203, 144, 247, 113, 137, 177, 242, 215, 191, 221, 214, 238,
+ 114, 157, 37, 175, 158, 234, 183, 75, 157, 243, 141, 146, 171, 85, 155,
+ 210, 214, 120, 206, 119, 129, 188, 187, 223, 112, 122, 198, 57, 161, 241,
+ 108, 107, 246, 220, 100, 207, 226, 24, 189, 13, 240, 59, 19, 27, 16,
+ 26, 109, 192, 158, 187, 151, 151, 10, 54, 200, 241, 157, 74, 207, 121,
+ 39, 229, 139, 129, 13, 154, 141, 29, 109, 122, 206, 123, 244, 180, 161,
+ 244, 156, 247, 13, 97, 31, 180, 35, 54, 8, 29, 253, 78, 59, 51,
+ 27, 164, 150, 238, 211, 142, 216, 128, 208, 104, 3, 246, 220, 216, 6,
+ 232, 183, 188, 13, 208, 15, 137, 13, 8, 141, 54, 96, 207, 243, 182,
+ 193, 199, 139, 122, 209, 243, 254, 73, 121, 180, 193, 185, 208, 62, 166,
+ 231, 253, 255, 214, 189, 63, 61, 231, 189, 64, 207, 62, 244, 188, 255,
+ 133, 79, 122, 154, 158, 243, 30, 90, 211, 78, 247, 174, 18, 26, 109,
+ 192, 158, 27, 219, 0, 113, 197, 219, 0, 113, 66, 108, 64, 104, 180,
+ 1, 123, 158, 183, 13, 170, 52, 152, 77, 247, 174, 146, 242, 104, 131,
+ 203, 173, 102, 155, 158, 243, 94, 214, 62, 155, 158, 243, 254, 203, 27,
+ 179, 233, 57, 239, 211, 123, 206, 54, 61, 231, 189, 196, 187, 108, 239,
+ 42, 161, 209, 6, 236, 185, 201, 60, 48, 216, 128, 158, 139, 56, 12,
+ 218, 153, 40, 179, 24, 192, 206, 172, 142, 25, 149, 233, 237, 55, 210,
+ 60, 6, 96, 57, 218, 118, 142, 98, 229, 227, 70, 120, 26, 3, 220,
+ 247, 5, 16, 239, 180, 237, 228, 116, 196, 192, 59, 197, 104, 122, 236,
+ 35, 60, 141, 1, 238, 117, 32, 158, 104, 61, 70, 114, 245, 0, 154,
+ 212, 37, 101, 184, 167, 49, 192, 189, 14, 244, 87, 90, 143, 145, 185,
+ 98, 128, 102, 223, 208, 225, 158, 198, 0, 247, 58, 208, 31, 232, 156,
+ 209, 136, 76, 221, 94, 78, 214, 110, 58, 108, 132, 198, 115, 207, 141,
+ 218, 83, 221, 188, 109, 46, 121, 172, 13, 114, 216, 8, 141, 242, 140,
+ 218, 38, 221, 188, 237, 112, 189, 60, 134, 103, 135, 141, 208, 40, 207,
+ 8, 231, 186, 126, 93, 46, 121, 12, 27, 14, 27, 161, 81, 158, 17,
+ 102, 116, 103, 86, 15, 99, 152, 137, 25, 4, 126, 192, 197, 103, 247,
+ 152, 225, 206, 172, 6, 94, 215, 16, 115, 204, 96, 57, 186, 23, 123,
+ 40, 43, 31, 54, 68, 28, 102, 80, 46, 221, 139, 13, 52, 234, 84,
+ 10, 13, 17, 135, 153, 80, 78, 7, 214, 155, 212, 37, 122, 176, 56,
+ 204, 160, 92, 221, 25, 6, 154, 14, 191, 193, 226, 48, 131, 118, 231,
+ 243, 198, 220, 97, 6, 243, 198, 60, 197, 140, 37, 151, 60, 119, 152,
+ 65, 121, 158, 98, 6, 237, 201, 203, 115, 135, 25, 148, 231, 41, 102,
+ 252, 114, 201, 115, 135, 25, 148, 231, 41, 102, 16, 39, 116, 189, 49,
+ 28, 252, 96, 152, 25, 102, 184, 51, 171, 17, 99, 179, 205, 49, 131,
+ 229, 104, 12, 8, 101, 229, 173, 161, 226, 48, 131, 114, 169, 14, 120,
+ 39, 212, 169, 196, 178, 8, 129, 113, 102, 54, 23, 103, 128, 38, 117,
+ 177, 71, 8, 140, 51, 179, 115, 197, 25, 205, 190, 41, 225, 226, 48,
+ 131, 118, 207, 47, 102, 116, 107, 29, 17, 249, 199, 140, 110, 173, 35,
+ 34, 255, 152, 225, 229, 161, 237, 242, 139, 25, 190, 111, 134, 56, 161,
+ 57, 18, 211, 193, 15, 6, 153, 97, 134, 157, 89, 157, 50, 43, 211,
+ 59, 100, 166, 57, 102, 176, 28, 93, 167, 155, 197, 202, 187, 102, 228,
+ 15, 51, 252, 248, 60, 132, 211, 145, 2, 239, 148, 162, 233, 9, 155,
+ 145, 63, 204, 240, 227, 115, 148, 75, 235, 1, 52, 173, 203, 140, 252,
+ 97, 134, 31, 159, 135, 204, 212, 99, 38, 69, 179, 111, 244, 244, 252,
+ 97, 134, 140, 207, 131, 53, 187, 19, 31, 114, 189, 91, 196, 249, 113,
+ 133, 243, 193, 185, 199, 231, 209, 71, 78, 216, 206, 22, 76, 246, 232,
+ 174, 193, 48, 78, 222, 161, 247, 139, 56, 39, 166, 110, 9, 206, 61,
+ 214, 117, 130, 188, 166, 119, 231, 121, 118, 231, 46, 39, 239, 13, 144,
+ 183, 123, 111, 159, 132, 220, 227, 198, 80, 144, 119, 183, 243, 4, 207,
+ 114, 36, 166, 51, 121, 150, 129, 69, 156, 127, 111, 140, 122, 105, 12,
+ 22, 119, 244, 132, 237, 92, 118, 184, 103, 57, 18, 211, 25, 102, 82,
+ 154, 131, 31, 132, 155, 97, 166, 21, 219, 191, 63, 13, 120, 167, 154,
+ 99, 6, 203, 209, 220, 130, 105, 172, 188, 223, 68, 79, 49, 227, 227,
+ 222, 159, 75, 183, 221, 77, 115, 11, 56, 29, 209, 240, 78, 209, 154,
+ 30, 107, 176, 167, 152, 113, 175, 99, 218, 241, 177, 109, 104, 61, 166,
+ 114, 245, 0, 154, 212, 197, 222, 218, 83, 204, 184, 215, 177, 166, 252,
+ 25, 122, 150, 188, 207, 84, 61, 102, 162, 53, 251, 134, 180, 240, 20,
+ 51, 238, 117, 124, 243, 66, 197, 140, 179, 128, 106, 247, 122, 74, 73,
+ 117, 31, 25, 218, 145, 250, 184, 70, 227, 254, 73, 246, 220, 125, 187,
+ 139, 251, 39, 251, 37, 52, 218, 77, 246, 145, 125, 147, 220, 85, 161,
+ 131, 82, 7, 73, 15, 14, 142, 48, 228, 245, 241, 93, 42, 157, 10,
+ 250, 178, 45, 217, 71, 70, 176, 90, 241, 217, 102, 105, 245, 103, 107,
+ 12, 231, 195, 202, 23, 220, 38, 245, 61, 119, 71, 43, 179, 83, 138,
+ 125, 165, 182, 130, 157, 170, 207, 18, 164, 230, 39, 122, 24, 198, 158,
+ 199, 5, 246, 73, 63, 237, 88, 76, 207, 173, 45, 211, 105, 131, 66,
+ 63, 13, 63, 44, 69, 151, 220, 102, 200, 155, 25, 121, 76, 114, 30,
+ 76, 214, 202, 164, 72, 63, 120, 29, 209, 120, 79, 74, 253, 131, 79,
+ 27, 242, 62, 143, 60, 35, 21, 105, 126, 142, 158, 17, 63, 49, 240,
+ 178, 122, 71, 95, 196, 89, 233, 108, 157, 91, 198, 239, 28, 121, 65,
+ 122, 107, 98, 6, 61, 35, 126, 219, 219, 143, 180, 243, 229, 47, 75,
+ 37, 236, 89, 198, 243, 62, 145, 215, 164, 240, 185, 247, 233, 25, 241,
+ 69, 134, 164, 41, 116, 199, 136, 219, 82, 172, 244, 192, 144, 183, 223,
+ 156, 187, 82, 224, 205, 235, 244, 204, 219, 218, 209, 69, 149, 125, 138,
+ 127, 58, 210, 165, 247, 79, 188, 98, 184, 103, 241, 189, 168, 76, 41,
+ 116, 127, 127, 173, 76, 150, 116, 244, 122, 132, 66, 219, 194, 179, 165,
+ 249, 94, 203, 12, 121, 227, 34, 114, 164, 236, 10, 241, 244, 140, 248,
+ 242, 245, 118, 40, 244, 215, 54, 47, 57, 166, 233, 78, 67, 222, 198,
+ 201, 222, 242, 170, 175, 99, 232, 30, 77, 223, 178, 170, 174, 202, 17,
+ 133, 229, 55, 174, 143, 55, 228, 221, 22, 89, 76, 238, 191, 180, 161,
+ 86, 166, 164, 124, 225, 7, 245, 187, 252, 209, 190, 148, 188, 229, 249,
+ 14, 67, 91, 173, 112, 150, 150, 75, 180, 28, 79, 207, 136, 63, 215,
+ 163, 137, 66, 239, 110, 95, 86, 14, 40, 127, 209, 208, 159, 241, 204,
+ 91, 54, 127, 236, 75, 105, 60, 243, 214, 108, 94, 153, 96, 26, 219,
+ 57, 130, 105, 188, 187, 1, 219, 45, 26, 103, 52, 26, 239, 110, 96,
+ 207, 221, 203, 251, 23, 48, 157, 250, 93, 17, 186, 47, 119, 210, 218,
+ 113, 74, 249, 158, 128, 233, 15, 166, 215, 51, 236, 119, 102, 149, 95,
+ 42, 249, 238, 111, 74, 207, 136, 39, 241, 18, 239, 110, 24, 183, 105,
+ 186, 241, 121, 220, 5, 182, 73, 213, 215, 134, 211, 51, 226, 51, 143,
+ 168, 103, 60, 23, 6, 76, 95, 58, 180, 208, 144, 247, 25, 96, 122,
+ 254, 196, 21, 237, 8, 166, 255, 170, 181, 86, 61, 7, 60, 226, 176,
+ 148, 147, 181, 174, 157, 49, 46, 143, 73, 71, 131, 55, 180, 35, 152,
+ 62, 19, 242, 131, 198, 123, 82, 186, 48, 116, 179, 241, 59, 3, 166,
+ 119, 63, 220, 218, 142, 96, 250, 131, 121, 241, 234, 156, 52, 96, 186,
+ 96, 165, 95, 12, 121, 45, 81, 23, 164, 111, 198, 236, 166, 231, 88,
+ 63, 206, 114, 170, 231, 233, 3, 166, 223, 157, 119, 208, 144, 183, 64,
+ 212, 53, 105, 137, 245, 120, 59, 130, 233, 117, 209, 127, 41, 180, 15,
+ 96, 250, 113, 218, 191, 134, 188, 205, 162, 238, 74, 143, 222, 188, 209,
+ 142, 96, 122, 231, 195, 108, 133, 238, 31, 145, 46, 253, 211, 181, 72,
+ 123, 35, 222, 14, 128, 233, 228, 130, 85, 219, 19, 76, 223, 172, 22,
+ 216, 94, 197, 86, 182, 228, 104, 25, 108, 200, 219, 52, 50, 71, 106,
+ 191, 234, 3, 122, 142, 245, 227, 153, 3, 21, 186, 55, 98, 250, 131,
+ 80, 67, 222, 7, 78, 111, 185, 113, 41, 59, 61, 199, 122, 149, 203,
+ 170, 208, 127, 132, 23, 150, 39, 46, 42, 103, 200, 123, 6, 48, 189,
+ 251, 226, 45, 122, 190, 188, 207, 171, 170, 157, 31, 0, 166, 43, 12,
+ 251, 177, 157, 177, 222, 210, 242, 149, 239, 86, 208, 243, 229, 223, 148,
+ 23, 41, 116, 22, 96, 186, 77, 242, 108, 99, 191, 2, 76, 179, 245,
+ 16, 95, 74, 95, 0, 76, 155, 173, 147, 16, 76, 99, 191, 130, 96,
+ 26, 239, 125, 192, 126, 2, 193, 52, 161, 241, 222, 7, 246, 220, 189,
+ 188, 211, 128, 233, 107, 79, 147, 219, 18, 76, 119, 45, 122, 85, 41,
+ 223, 30, 48, 253, 161, 165, 170, 97, 251, 242, 0, 48, 253, 211, 23,
+ 101, 232, 125, 44, 164, 207, 90, 16, 48, 29, 236, 59, 208, 176, 77,
+ 44, 0, 113, 186, 207, 175, 163, 232, 125, 44, 199, 146, 35, 212, 187,
+ 141, 1, 211, 29, 174, 47, 72, 52, 195, 116, 229, 217, 107, 105, 156,
+ 118, 90, 54, 171, 52, 96, 122, 73, 114, 188, 49, 47, 96, 218, 235,
+ 195, 93, 52, 78, 255, 60, 110, 143, 198, 123, 82, 122, 123, 226, 126,
+ 211, 56, 61, 213, 113, 136, 198, 233, 109, 27, 143, 210, 56, 125, 255,
+ 120, 138, 137, 222, 11, 82, 157, 15, 254, 166, 113, 250, 221, 5, 255,
+ 104, 188, 151, 165, 232, 237, 231, 18, 141, 219, 131, 107, 210, 188, 123,
+ 169, 52, 78, 127, 87, 92, 189, 83, 165, 1, 96, 58, 163, 254, 69,
+ 67, 222, 56, 192, 244, 152, 27, 231, 104, 156, 238, 80, 250, 169, 66,
+ 79, 159, 157, 46, 85, 108, 88, 202, 48, 230, 165, 0, 166, 223, 250,
+ 178, 57, 141, 211, 221, 218, 246, 85, 232, 154, 128, 233, 202, 183, 63,
+ 50, 228, 29, 48, 59, 71, 154, 57, 114, 37, 141, 211, 219, 63, 89,
+ 165, 208, 223, 3, 166, 247, 111, 92, 109, 200, 123, 21, 48, 189, 233,
+ 124, 20, 141, 211, 13, 215, 140, 83, 232, 197, 128, 233, 222, 227, 236,
+ 134, 188, 177, 128, 233, 173, 101, 202, 209, 56, 221, 166, 213, 37, 165,
+ 190, 23, 0, 211, 247, 254, 216, 99, 104, 171, 191, 1, 211, 201, 182,
+ 53, 52, 78, 71, 206, 81, 253, 240, 38, 96, 186, 226, 138, 177, 198,
+ 223, 23, 48, 205, 214, 247, 124, 41, 253, 47, 96, 218, 108, 221, 143,
+ 96, 26, 251, 241, 124, 223, 27, 251, 229, 4, 211, 132, 198, 190, 55,
+ 123, 158, 119, 223, 251, 251, 82, 44, 135, 99, 169, 86, 30, 115, 151,
+ 206, 92, 49, 230, 197, 220, 165, 115, 107, 103, 211, 28, 14, 50, 110,
+ 44, 0, 152, 30, 83, 195, 108, 13, 109, 155, 212, 172, 232, 108, 122,
+ 54, 253, 192, 125, 234, 126, 189, 130, 128, 233, 197, 17, 102, 247, 44,
+ 239, 147, 206, 209, 59, 154, 15, 73, 239, 204, 8, 215, 206, 121, 63,
+ 44, 173, 178, 27, 231, 112, 96, 156, 62, 127, 143, 228, 127, 164, 72,
+ 31, 238, 82, 105, 140, 211, 89, 243, 102, 217, 204, 48, 253, 221, 219,
+ 179, 232, 185, 246, 71, 26, 206, 162, 231, 218, 167, 63, 158, 105, 194,
+ 123, 65, 218, 176, 113, 38, 61, 215, 222, 54, 127, 166, 141, 96, 58,
+ 117, 184, 25, 239, 53, 233, 234, 132, 153, 244, 92, 251, 175, 123, 105,
+ 247, 89, 3, 166, 223, 106, 100, 204, 235, 15, 152, 126, 176, 121, 38,
+ 205, 149, 249, 226, 152, 122, 94, 79, 56, 196, 233, 196, 187, 83, 13,
+ 121, 147, 0, 211, 187, 119, 77, 164, 231, 218, 55, 254, 104, 156, 66,
+ 47, 7, 76, 159, 174, 63, 202, 144, 119, 136, 35, 71, 90, 178, 252,
+ 61, 122, 174, 125, 171, 148, 119, 213, 92, 25, 192, 116, 149, 146, 239,
+ 26, 242, 158, 0, 76, 23, 93, 54, 140, 230, 232, 92, 136, 87, 117,
+ 45, 1, 76, 31, 188, 63, 193, 248, 157, 1, 211, 157, 202, 78, 163,
+ 231, 218, 63, 94, 171, 214, 61, 29, 48, 189, 100, 152, 177, 111, 100,
+ 3, 166, 43, 84, 141, 160, 231, 218, 39, 173, 140, 160, 231, 218, 15,
+ 171, 48, 219, 244, 92, 123, 182, 94, 237, 75, 105, 60, 215, 222, 108,
+ 29, 155, 230, 204, 55, 103, 115, 40, 214, 129, 64, 79, 55, 155, 67,
+ 97, 103, 116, 135, 0, 111, 74, 83, 243, 57, 20, 44, 71, 231, 4,
+ 155, 177, 242, 161, 77, 197, 205, 213, 163, 92, 58, 39, 8, 52, 234,
+ 84, 188, 207, 42, 110, 174, 62, 132, 211, 129, 245, 38, 117, 113, 88,
+ 197, 205, 213, 163, 92, 93, 206, 188, 166, 35, 110, 160, 184, 185, 122,
+ 180, 187, 200, 245, 45, 180, 177, 200, 245, 45, 135, 85, 236, 250, 22,
+ 218, 78, 228, 250, 150, 130, 19, 77, 94, 218, 59, 224, 7, 205, 205,
+ 48, 195, 206, 232, 142, 251, 32, 211, 219, 250, 190, 57, 102, 176, 28,
+ 241, 3, 235, 7, 172, 188, 243, 61, 113, 152, 177, 114, 58, 226, 224,
+ 157, 226, 52, 61, 33, 239, 137, 195, 12, 202, 165, 245, 0, 154, 212,
+ 197, 245, 174, 56, 204, 88, 223, 215, 99, 38, 78, 179, 111, 216, 187,
+ 226, 48, 131, 118, 23, 185, 190, 21, 242, 158, 216, 245, 45, 180, 167,
+ 200, 245, 173, 176, 119, 197, 174, 111, 33, 78, 8, 102, 226, 222, 2,
+ 63, 24, 104, 130, 25, 238, 140, 238, 48, 224, 77, 27, 96, 142, 25,
+ 44, 71, 252, 32, 237, 109, 86, 222, 49, 64, 28, 102, 80, 46, 209,
+ 17, 6, 52, 234, 84, 34, 247, 0, 113, 152, 9, 227, 116, 96, 189,
+ 73, 93, 98, 250, 139, 195, 12, 202, 229, 49, 19, 166, 233, 176, 246,
+ 23, 135, 25, 180, 187, 200, 56, 227, 51, 64, 108, 156, 65, 123, 138,
+ 140, 51, 214, 254, 98, 227, 12, 226, 132, 96, 38, 172, 15, 248, 193,
+ 59, 102, 152, 97, 123, 182, 173, 192, 27, 215, 207, 28, 51, 88, 142,
+ 198, 128, 55, 89, 121, 123, 63, 113, 152, 65, 185, 52, 6, 0, 141,
+ 58, 149, 145, 80, 95, 113, 152, 177, 114, 58, 176, 222, 164, 46, 161,
+ 125, 197, 97, 6, 229, 242, 152, 177, 106, 58, 210, 250, 136, 195, 12,
+ 218, 93, 100, 156, 65, 27, 139, 140, 51, 161, 125, 197, 198, 25, 180,
+ 157, 200, 56, 131, 56, 161, 103, 116, 119, 7, 63, 120, 203, 12, 51,
+ 108, 143, 107, 90, 239, 76, 239, 152, 158, 230, 152, 193, 114, 116, 95,
+ 80, 47, 110, 239, 81, 79, 129, 123, 143, 122, 113, 251, 130, 128, 70,
+ 157, 74, 255, 175, 135, 56, 204, 248, 113, 58, 176, 222, 164, 46, 33,
+ 61, 196, 97, 6, 229, 234, 206, 181, 215, 116, 184, 186, 11, 220, 123,
+ 212, 83, 108, 156, 65, 27, 139, 140, 51, 33, 61, 196, 198, 25, 180,
+ 157, 200, 56, 131, 56, 161, 152, 233, 4, 125, 154, 62, 121, 98, 230,
+ 163, 81, 35, 70, 106, 50, 180, 89, 165, 110, 153, 222, 161, 93, 73,
+ 121, 95, 25, 111, 170, 192, 140, 165, 151, 238, 79, 233, 198, 237, 63,
+ 237, 198, 197, 153, 46, 153, 121, 222, 111, 240, 101, 74, 243, 221, 181,
+ 188, 146, 218, 27, 229, 6, 37, 255, 23, 201, 238, 208, 226, 116, 184,
+ 224, 157, 92, 154, 30, 191, 55, 242, 214, 113, 124, 70, 221, 36, 203,
+ 148, 27, 109, 141, 114, 131, 78, 245, 237, 206, 246, 159, 118, 229, 234,
+ 1, 52, 173, 203, 235, 121, 235, 240, 143, 94, 148, 20, 245, 209, 174,
+ 182, 70, 185, 65, 203, 198, 244, 98, 103, 26, 119, 213, 99, 198, 165,
+ 217, 215, 213, 41, 111, 29, 255, 38, 15, 180, 253, 94, 194, 97, 120,
+ 174, 125, 70, 111, 150, 27, 132, 118, 231, 243, 33, 208, 142, 68, 30,
+ 161, 49, 31, 130, 61, 199, 251, 62, 155, 88, 54, 90, 172, 150, 31,
+ 185, 59, 94, 49, 55, 168, 236, 152, 63, 180, 50, 221, 101, 82, 30,
+ 115, 131, 198, 207, 27, 100, 24, 163, 48, 55, 168, 85, 220, 11, 109,
+ 109, 103, 150, 156, 54, 110, 109, 27, 117, 46, 55, 74, 206, 184, 18,
+ 178, 219, 120, 62, 118, 129, 124, 239, 249, 251, 218, 250, 207, 18, 74,
+ 99, 62, 4, 123, 158, 119, 236, 73, 211, 252, 130, 183, 1, 126, 103,
+ 98, 3, 66, 163, 13, 216, 115, 180, 65, 16, 216, 32, 16, 108, 16,
+ 168, 203, 9, 73, 123, 240, 38, 205, 139, 33, 229, 49, 39, 228, 191,
+ 130, 93, 77, 243, 98, 130, 47, 203, 52, 47, 230, 217, 158, 96, 154,
+ 23, 211, 224, 135, 214, 166, 121, 49, 137, 205, 173, 52, 47, 134, 208,
+ 104, 3, 246, 220, 216, 6, 232, 183, 188, 13, 208, 15, 137, 13, 8,
+ 141, 54, 96, 207, 209, 6, 141, 220, 218, 224, 148, 181, 59, 181, 1,
+ 41, 143, 54, 8, 110, 30, 98, 106, 131, 39, 23, 222, 164, 54, 216,
+ 48, 180, 55, 181, 65, 213, 81, 230, 185, 65, 67, 130, 88, 110, 16,
+ 161, 209, 6, 236, 185, 177, 13, 16, 87, 188, 13, 16, 39, 196, 6,
+ 132, 70, 27, 176, 231, 104, 131, 105, 96, 131, 105, 96, 131, 105, 58,
+ 27, 124, 215, 153, 229, 6, 145, 242, 104, 131, 31, 251, 153, 231, 6,
+ 29, 121, 143, 229, 6, 45, 30, 202, 114, 131, 126, 29, 101, 158, 27,
+ 84, 118, 50, 203, 13, 34, 52, 218, 128, 61, 55, 238, 55, 97, 187,
+ 79, 243, 67, 37, 104, 215, 186, 27, 198, 0, 93, 126, 168, 171, 35,
+ 148, 239, 224, 65, 12, 232, 200, 181, 157, 29, 153, 252, 52, 217, 211,
+ 24, 224, 190, 47, 128, 120, 167, 109, 39, 167, 195, 5, 239, 228, 210,
+ 244, 56, 100, 79, 99, 128, 123, 29, 136, 39, 90, 143, 14, 92, 61,
+ 128, 38, 117, 241, 145, 61, 141, 1, 238, 117, 160, 191, 210, 122, 116,
+ 200, 21, 3, 52, 251, 198, 72, 158, 198, 0, 247, 58, 208, 31, 104,
+ 223, 91, 214, 231, 202, 176, 118, 211, 97, 35, 52, 230, 202, 24, 181,
+ 167, 186, 121, 219, 92, 242, 88, 27, 228, 176, 17, 26, 229, 25, 181,
+ 77, 186, 241, 126, 46, 121, 12, 207, 14, 27, 161, 81, 158, 17, 206,
+ 117, 227, 125, 73, 47, 143, 97, 195, 97, 35, 52, 202, 51, 194, 140,
+ 238, 126, 83, 137, 235, 55, 5, 129, 31, 116, 50, 195, 12, 151, 79,
+ 103, 135, 254, 118, 99, 115, 204, 96, 57, 218, 71, 111, 194, 141, 53,
+ 26, 139, 195, 12, 202, 165, 99, 13, 160, 81, 167, 50, 214, 104, 36,
+ 14, 51, 126, 156, 14, 172, 55, 169, 75, 72, 35, 113, 152, 65, 185,
+ 186, 177, 134, 166, 195, 21, 36, 14, 51, 104, 119, 190, 239, 237, 14,
+ 51, 216, 247, 246, 20, 51, 104, 99, 94, 158, 59, 204, 160, 60, 79,
+ 49, 19, 146, 75, 158, 59, 204, 160, 60, 79, 49, 131, 182, 227, 229,
+ 185, 195, 12, 202, 243, 20, 51, 136, 19, 26, 103, 26, 102, 122, 251,
+ 73, 102, 152, 97, 249, 116, 174, 64, 192, 88, 128, 7, 113, 38, 144,
+ 107, 159, 3, 185, 56, 227, 47, 48, 206, 112, 58, 92, 240, 78, 46,
+ 77, 143, 195, 95, 96, 156, 9, 224, 234, 1, 52, 169, 139, 143, 191,
+ 192, 56, 19, 144, 43, 206, 104, 246, 141, 105, 40, 48, 206, 248, 231,
+ 31, 51, 252, 156, 145, 195, 63, 255, 152, 225, 229, 249, 248, 231, 31,
+ 51, 188, 60, 180, 93, 126, 49, 195, 247, 205, 16, 39, 52, 111, 187,
+ 14, 248, 65, 144, 25, 102, 88, 62, 93, 76, 3, 192, 88, 125, 15,
+ 226, 76, 3, 46, 6, 52, 224, 242, 182, 235, 229, 15, 51, 252, 248,
+ 220, 143, 211, 17, 3, 239, 20, 163, 233, 177, 215, 203, 31, 102, 248,
+ 241, 57, 202, 165, 245, 0, 154, 212, 37, 165, 110, 254, 48, 195, 143,
+ 207, 253, 234, 231, 202, 167, 211, 236, 27, 90, 55, 127, 152, 33, 227,
+ 243, 96, 205, 238, 196, 135, 252, 222, 43, 226, 252, 44, 235, 104, 66,
+ 238, 241, 185, 227, 200, 9, 91, 192, 131, 253, 121, 142, 207, 117, 121,
+ 219, 156, 188, 79, 62, 40, 226, 28, 89, 249, 203, 132, 220, 99, 93,
+ 235, 209, 19, 182, 11, 47, 134, 229, 57, 214, 213, 229, 109, 215, 101,
+ 242, 124, 222, 47, 226, 76, 92, 243, 106, 66, 238, 113, 35, 230, 6,
+ 205, 223, 51, 62, 207, 113, 163, 46, 111, 155, 147, 87, 116, 96, 17,
+ 103, 203, 45, 81, 47, 141, 193, 156, 248, 126, 213, 35, 242, 28, 131,
+ 233, 242, 182, 235, 112, 125, 179, 90, 224, 7, 13, 205, 48, 195, 242,
+ 233, 66, 129, 215, 85, 203, 28, 51, 88, 142, 198, 128, 218, 92, 223,
+ 172, 186, 167, 152, 113, 159, 239, 210, 54, 180, 35, 187, 179, 189, 54,
+ 23, 3, 128, 70, 157, 10, 102, 42, 123, 138, 25, 247, 58, 2, 50,
+ 70, 209, 188, 157, 80, 78, 7, 214, 155, 212, 37, 196, 215, 83, 204,
+ 184, 215, 33, 117, 187, 64, 117, 160, 92, 93, 222, 182, 166, 195, 90,
+ 210, 83, 204, 184, 215, 177, 130, 203, 13, 66, 187, 243, 251, 19, 209,
+ 142, 68, 30, 161, 113, 127, 34, 123, 142, 103, 76, 55, 177, 52, 4,
+ 220, 180, 133, 31, 191, 63, 113, 76, 199, 202, 116, 207, 241, 134, 226,
+ 29, 20, 58, 48, 117, 144, 116, 43, 101, 44, 229, 237, 11, 60, 35,
+ 224, 55, 147, 227, 45, 229, 187, 84, 74, 76, 107, 181, 155, 236, 79,
+ 36, 88, 45, 255, 108, 179, 84, 98, 102, 140, 225, 92, 90, 185, 130,
+ 219, 164, 87, 187, 223, 10, 38, 251, 19, 187, 246, 171, 161, 204, 47,
+ 87, 121, 150, 32, 93, 45, 240, 6, 157, 107, 142, 179, 52, 181, 108,
+ 183, 52, 179, 236, 180, 52, 103, 249, 61, 5, 246, 73, 187, 253, 23,
+ 208, 60, 130, 173, 239, 169, 185, 3, 152, 27, 148, 49, 121, 11, 229,
+ 77, 180, 180, 176, 36, 91, 90, 90, 14, 88, 90, 177, 185, 135, 200,
+ 99, 210, 188, 51, 187, 104, 30, 193, 145, 142, 251, 20, 250, 89, 248,
+ 73, 233, 234, 182, 35, 38, 185, 0, 103, 164, 17, 11, 254, 164, 121,
+ 4, 183, 127, 73, 165, 121, 4, 19, 175, 94, 164, 188, 135, 65, 223,
+ 113, 203, 171, 150, 20, 248, 49, 189, 23, 164, 249, 235, 238, 208, 60,
+ 130, 155, 245, 210, 84, 58, 226, 178, 212, 118, 211, 67, 202, 123, 18,
+ 120, 78, 91, 90, 91, 254, 178, 180, 166, 188, 94, 81, 215, 164, 83,
+ 115, 238, 210, 60, 130, 168, 87, 31, 40, 116, 175, 136, 219, 210, 198,
+ 255, 50, 40, 111, 42, 240, 158, 5, 190, 243, 28, 239, 71, 115, 238,
+ 74, 242, 226, 251, 52, 143, 224, 82, 139, 210, 202, 62, 252, 139, 142,
+ 116, 41, 250, 112, 93, 186, 39, 255, 34, 240, 92, 178, 188, 102, 185,
+ 2, 222, 65, 120, 135, 69, 101, 74, 239, 47, 31, 72, 243, 8, 190,
+ 191, 52, 71, 161, 131, 195, 179, 165, 170, 143, 86, 82, 222, 107, 22,
+ 155, 229, 134, 69, 182, 220, 178, 116, 162, 188, 225, 17, 57, 82, 102,
+ 253, 157, 52, 143, 96, 111, 249, 221, 10, 253, 139, 205, 75, 174, 241,
+ 60, 145, 242, 222, 177, 116, 177, 220, 179, 116, 181, 164, 193, 143, 238,
+ 169, 76, 246, 150, 35, 46, 125, 71, 243, 8, 70, 39, 173, 80, 232,
+ 130, 17, 133, 229, 43, 55, 39, 81, 222, 116, 203, 235, 150, 12, 208,
+ 153, 101, 177, 83, 222, 31, 35, 139, 201, 19, 195, 131, 218, 147, 253,
+ 137, 27, 250, 169, 117, 63, 216, 190, 148, 108, 251, 124, 23, 181, 85,
+ 14, 214, 211, 171, 181, 165, 144, 87, 11, 202, 251, 185, 179, 180, 188,
+ 168, 196, 20, 154, 71, 112, 57, 165, 133, 66, 255, 214, 190, 172, 60,
+ 99, 202, 13, 195, 249, 93, 204, 13, 98, 243, 199, 190, 148, 190, 60,
+ 189, 130, 204, 207, 43, 23, 247, 178, 90, 74, 195, 175, 156, 151, 245,
+ 229, 60, 130, 202, 250, 60, 2, 108, 183, 8, 166, 9, 221, 9, 48,
+ 205, 158, 35, 166, 45, 47, 97, 250, 111, 192, 244, 206, 177, 55, 40,
+ 166, 23, 140, 89, 174, 230, 32, 0, 166, 103, 159, 172, 156, 192, 48,
+ 109, 213, 48, 221, 152, 205, 83, 151, 95, 42, 189, 114, 182, 62, 205,
+ 35, 32, 241, 18, 115, 131, 62, 59, 217, 215, 112, 110, 24, 247, 28,
+ 87, 28, 217, 147, 230, 17, 188, 255, 102, 31, 45, 7, 33, 65, 250,
+ 94, 126, 43, 145, 97, 58, 16, 48, 29, 8, 152, 14, 212, 237, 57,
+ 62, 241, 247, 32, 154, 71, 112, 252, 226, 72, 109, 79, 254, 97, 233,
+ 216, 144, 49, 137, 12, 211, 129, 128, 233, 64, 192, 116, 160, 110, 207,
+ 113, 141, 197, 97, 44, 223, 111, 247, 71, 26, 239, 73, 169, 249, 127,
+ 147, 76, 243, 8, 254, 120, 103, 50, 205, 35, 176, 125, 53, 85, 203,
+ 217, 59, 43, 237, 248, 103, 122, 34, 195, 116, 32, 96, 58, 16, 48,
+ 29, 168, 219, 115, 60, 175, 231, 108, 154, 71, 16, 248, 174, 131, 230,
+ 251, 149, 47, 19, 153, 200, 48, 29, 0, 152, 14, 0, 76, 7, 112,
+ 57, 73, 215, 164, 114, 21, 34, 104, 30, 193, 183, 61, 212, 242, 37,
+ 0, 211, 7, 163, 231, 36, 50, 76, 7, 0, 166, 3, 0, 211, 140,
+ 183, 86, 212, 93, 105, 224, 190, 121, 52, 143, 96, 115, 208, 114, 133,
+ 238, 18, 145, 46, 13, 252, 114, 125, 34, 195, 116, 0, 96, 58, 0,
+ 48, 237, 79, 121, 95, 7, 76, 59, 187, 144, 220, 200, 44, 41, 241,
+ 194, 69, 45, 127, 33, 91, 122, 54, 229, 121, 34, 195, 116, 67, 192,
+ 116, 3, 192, 52, 187, 143, 224, 245, 200, 28, 201, 175, 91, 77, 154,
+ 71, 48, 224, 114, 45, 133, 110, 8, 152, 174, 51, 189, 110, 18, 195,
+ 116, 93, 192, 116, 29, 192, 116, 29, 202, 155, 225, 244, 150, 171, 188,
+ 82, 130, 230, 17, 60, 173, 103, 81, 232, 127, 195, 11, 203, 159, 76,
+ 100, 57, 153, 233, 150, 122, 128, 233, 250, 128, 233, 6, 148, 247, 6,
+ 96, 186, 247, 48, 45, 175, 4, 48, 61, 187, 248, 103, 10, 253, 4,
+ 48, 125, 255, 125, 102, 171, 28, 172, 167, 87, 0, 96, 154, 125, 163,
+ 39, 128, 233, 253, 187, 198, 210, 60, 130, 140, 117, 161, 10, 253, 28,
+ 48, 253, 201, 130, 190, 134, 190, 129, 123, 142, 217, 122, 136, 47, 165,
+ 113, 207, 49, 191, 78, 82, 28, 244, 149, 134, 95, 57, 78, 47, 205,
+ 35, 240, 213, 99, 26, 251, 9, 4, 211, 132, 198, 220, 32, 246, 220,
+ 61, 166, 79, 1, 166, 255, 25, 180, 139, 98, 250, 251, 132, 107, 74,
+ 249, 118, 128, 233, 41, 49, 21, 19, 94, 142, 211, 12, 211, 25, 128,
+ 233, 244, 223, 139, 82, 76, 147, 62, 107, 33, 192, 244, 252, 79, 223,
+ 55, 92, 235, 40, 8, 113, 250, 175, 133, 163, 41, 166, 99, 219, 68,
+ 210, 220, 160, 98, 113, 139, 115, 97, 58, 0, 48, 29, 160, 203, 13,
+ 122, 163, 216, 122, 138, 233, 251, 177, 113, 52, 55, 40, 49, 235, 87,
+ 14, 211, 254, 128, 105, 127, 192, 116, 67, 93, 110, 208, 95, 139, 156,
+ 20, 211, 255, 245, 59, 72, 115, 131, 30, 189, 114, 212, 20, 211, 243,
+ 154, 254, 73, 49, 125, 165, 254, 95, 52, 55, 200, 94, 253, 28, 135,
+ 233, 134, 128, 233, 6, 128, 105, 230, 107, 79, 1, 211, 9, 21, 175,
+ 80, 76, 251, 84, 191, 70, 115, 131, 6, 213, 186, 193, 97, 186, 1,
+ 96, 186, 1, 96, 186, 129, 46, 55, 104, 181, 237, 50, 197, 244, 128,
+ 255, 174, 42, 244, 43, 128, 233, 230, 43, 111, 112, 152, 110, 0, 152,
+ 110, 0, 152, 102, 188, 147, 1, 211, 133, 182, 221, 160, 152, 222, 185,
+ 71, 197, 71, 58, 96, 186, 241, 22, 150, 27, 116, 17, 120, 46, 1,
+ 62, 174, 0, 78, 8, 111, 52, 96, 186, 122, 231, 32, 154, 27, 52,
+ 189, 64, 103, 245, 158, 101, 192, 116, 202, 239, 3, 147, 24, 166, 235,
+ 0, 166, 107, 1, 166, 107, 82, 222, 214, 142, 28, 233, 249, 150, 79,
+ 40, 166, 199, 215, 88, 168, 208, 145, 128, 233, 113, 75, 22, 113, 152,
+ 174, 14, 152, 174, 6, 152, 174, 70, 121, 239, 1, 166, 75, 198, 142,
+ 161, 152, 246, 31, 58, 64, 161, 183, 0, 166, 93, 87, 154, 36, 49,
+ 76, 215, 0, 76, 251, 1, 166, 89, 123, 176, 11, 48, 189, 186, 69,
+ 97, 154, 27, 84, 199, 91, 253, 94, 87, 1, 211, 19, 250, 109, 227,
+ 48, 13, 237, 143, 87, 67, 192, 52, 107, 195, 46, 2, 166, 11, 221,
+ 90, 70, 49, 29, 189, 64, 109, 3, 238, 1, 166, 195, 222, 30, 110,
+ 188, 134, 6, 152, 102, 235, 123, 190, 148, 198, 220, 32, 126, 221, 207,
+ 8, 211, 216, 143, 231, 251, 222, 43, 184, 220, 160, 21, 92, 110, 208,
+ 10, 46, 55, 72, 197, 244, 52, 192, 244, 52, 93, 223, 123, 95, 9,
+ 150, 27, 244, 25, 151, 27, 244, 245, 13, 198, 219, 23, 120, 70, 192,
+ 111, 38, 199, 139, 185, 65, 209, 63, 176, 220, 32, 50, 110, 196, 220,
+ 160, 113, 118, 227, 181, 59, 140, 211, 150, 166, 44, 55, 232, 155, 76,
+ 150, 27, 212, 126, 23, 27, 115, 198, 1, 207, 118, 248, 237, 212, 241,
+ 238, 147, 90, 182, 137, 160, 185, 65, 225, 167, 89, 110, 208, 186, 117,
+ 44, 255, 35, 209, 50, 21, 48, 61, 21, 48, 61, 85, 23, 167, 7,
+ 191, 29, 78, 115, 131, 126, 11, 12, 167, 185, 65, 62, 207, 205, 115,
+ 131, 86, 255, 195, 114, 131, 22, 110, 97, 185, 65, 211, 35, 25, 239,
+ 97, 208, 119, 28, 126, 41, 58, 189, 23, 164, 146, 77, 103, 209, 220,
+ 32, 159, 106, 179, 104, 110, 144, 111, 33, 198, 123, 18, 120, 78, 195,
+ 239, 47, 29, 239, 53, 41, 35, 96, 22, 205, 13, 74, 168, 160, 210,
+ 69, 1, 211, 115, 44, 140, 55, 21, 120, 206, 194, 239, 60, 199, 235,
+ 7, 152, 110, 62, 97, 22, 205, 13, 186, 113, 72, 189, 191, 123, 48,
+ 96, 186, 147, 223, 116, 27, 195, 244, 84, 192, 244, 84, 192, 244, 20,
+ 29, 166, 127, 24, 56, 153, 230, 6, 125, 149, 16, 166, 222, 57, 14,
+ 152, 142, 175, 52, 198, 198, 48, 61, 25, 48, 61, 9, 48, 253, 17,
+ 229, 221, 15, 152, 110, 90, 127, 16, 205, 13, 170, 57, 41, 84, 161,
+ 251, 0, 166, 95, 221, 59, 208, 198, 48, 61, 30, 48, 61, 30, 48,
+ 61, 158, 242, 158, 7, 76, 79, 79, 29, 73, 115, 131, 126, 30, 175,
+ 234, 218, 12, 152, 30, 184, 102, 162, 141, 97, 122, 2, 96, 250, 35,
+ 192, 244, 36, 202, 123, 12, 48, 189, 235, 149, 233, 52, 55, 232, 47,
+ 155, 90, 247, 76, 192, 244, 47, 41, 204, 55, 114, 176, 158, 94, 83,
+ 1, 211, 204, 175, 158, 2, 166, 207, 127, 200, 114, 131, 18, 206, 176,
+ 220, 160, 175, 236, 230, 185, 65, 108, 189, 218, 151, 210, 24, 167, 249,
+ 117, 236, 226, 160, 175, 52, 252, 202, 113, 122, 233, 92, 125, 45, 110,
+ 207, 118, 137, 76, 111, 87, 29, 179, 57, 148, 87, 217, 121, 57, 229,
+ 51, 189, 67, 202, 153, 207, 161, 96, 57, 154, 183, 83, 158, 59, 147,
+ 168, 172, 184, 185, 250, 16, 78, 71, 10, 188, 83, 138, 166, 39, 172,
+ 172, 184, 185, 122, 148, 75, 235, 1, 52, 173, 75, 89, 113, 115, 245,
+ 33, 229, 114, 157, 73, 164, 217, 55, 218, 71, 220, 92, 61, 218, 93,
+ 228, 250, 86, 88, 89, 177, 235, 91, 150, 178, 98, 215, 183, 208, 118,
+ 34, 215, 183, 16, 39, 116, 207, 118, 145, 76, 239, 208, 90, 102, 152,
+ 97, 249, 116, 86, 224, 141, 43, 102, 142, 25, 44, 71, 247, 58, 23,
+ 231, 246, 210, 21, 19, 135, 25, 148, 75, 247, 108, 3, 141, 58, 21,
+ 159, 43, 42, 14, 51, 86, 78, 7, 214, 155, 212, 37, 180, 168, 56,
+ 204, 160, 92, 221, 158, 109, 77, 71, 90, 17, 113, 152, 65, 187, 139,
+ 92, 223, 66, 27, 139, 92, 223, 10, 45, 42, 118, 125, 11, 109, 39,
+ 114, 125, 11, 113, 66, 115, 80, 11, 128, 31, 148, 48, 195, 12, 203,
+ 167, 75, 43, 156, 233, 29, 86, 200, 28, 51, 88, 142, 230, 237, 20,
+ 230, 190, 125, 33, 113, 152, 9, 227, 116, 164, 129, 220, 52, 77, 79,
+ 116, 65, 113, 152, 65, 185, 180, 30, 64, 147, 186, 248, 21, 20, 135,
+ 153, 176, 66, 122, 204, 164, 105, 54, 138, 43, 32, 14, 51, 104, 119,
+ 145, 113, 6, 109, 44, 50, 206, 248, 21, 20, 27, 103, 208, 118, 34,
+ 227, 12, 226, 132, 174, 111, 125, 10, 126, 80, 196, 4, 51, 92, 62,
+ 93, 156, 119, 166, 119, 204, 82, 115, 204, 96, 57, 26, 3, 188, 185,
+ 245, 173, 165, 226, 48, 99, 229, 116, 196, 121, 1, 246, 53, 61, 206,
+ 37, 226, 48, 131, 114, 233, 186, 51, 188, 59, 169, 75, 200, 18, 129,
+ 123, 143, 150, 230, 202, 65, 245, 210, 246, 30, 125, 42, 112, 239, 209,
+ 82, 177, 113, 6, 109, 44, 50, 206, 132, 44, 17, 27, 103, 208, 118,
+ 34, 227, 12, 226, 132, 238, 61, 90, 0, 126, 80, 192, 12, 51, 220,
+ 30, 215, 197, 208, 151, 91, 228, 193, 222, 163, 197, 220, 122, 237, 98,
+ 110, 239, 209, 66, 129, 123, 143, 56, 29, 46, 120, 39, 151, 166, 199,
+ 177, 80, 224, 222, 163, 69, 92, 61, 128, 38, 117, 241, 89, 40, 112,
+ 239, 209, 162, 92, 123, 143, 52, 251, 198, 44, 16, 184, 247, 104, 161,
+ 216, 56, 227, 88, 40, 54, 206, 248, 44, 20, 27, 103, 208, 118, 34,
+ 227, 12, 226, 132, 158, 229, 157, 3, 126, 240, 169, 27, 204, 76, 30,
+ 51, 142, 187, 54, 136, 237, 139, 249, 36, 211, 219, 111, 190, 7, 119,
+ 70, 124, 194, 237, 217, 249, 132, 149, 79, 153, 235, 105, 62, 93, 49,
+ 183, 126, 176, 235, 102, 54, 219, 179, 195, 233, 136, 129, 119, 138, 209,
+ 244, 56, 162, 60, 205, 167, 115, 175, 99, 94, 197, 74, 44, 6, 204,
+ 231, 234, 1, 52, 169, 139, 213, 225, 105, 62, 157, 123, 29, 190, 127,
+ 180, 179, 209, 122, 204, 207, 181, 247, 72, 179, 111, 74, 142, 167, 249,
+ 116, 238, 117, 28, 220, 216, 80, 209, 81, 221, 91, 181, 123, 61, 165,
+ 164, 154, 15, 129, 118, 36, 62, 68, 232, 215, 183, 47, 151, 216, 115,
+ 247, 237, 238, 195, 158, 175, 201, 223, 214, 201, 164, 57, 33, 164, 124,
+ 129, 196, 94, 114, 61, 159, 103, 198, 235, 21, 114, 63, 249, 250, 145,
+ 23, 90, 153, 1, 242, 131, 14, 94, 202, 188, 184, 119, 226, 187, 242,
+ 253, 117, 222, 134, 103, 108, 229, 200, 161, 242, 193, 33, 133, 180, 50,
+ 67, 229, 207, 111, 23, 84, 121, 35, 134, 203, 7, 86, 21, 76, 50,
+ 158, 83, 29, 37, 251, 61, 246, 210, 202, 140, 145, 187, 132, 171, 107,
+ 14, 94, 17, 227, 228, 107, 133, 159, 155, 172, 177, 76, 144, 119, 63,
+ 121, 162, 149, 153, 36, 143, 44, 243, 68, 91, 39, 153, 34, 87, 168,
+ 151, 101, 194, 59, 93, 14, 153, 151, 77, 115, 96, 124, 163, 179, 181,
+ 117, 83, 135, 188, 250, 251, 108, 19, 222, 57, 242, 209, 247, 30, 107,
+ 101, 62, 150, 135, 159, 33, 103, 172, 126, 34, 91, 122, 62, 50, 225,
+ 93, 36, 63, 75, 120, 76, 243, 103, 8, 189, 243, 97, 52, 247, 60,
+ 239, 56, 141, 254, 130, 24, 226, 253, 5, 49, 65, 252, 133, 208, 157,
+ 193, 95, 216, 115, 247, 242, 210, 192, 95, 130, 94, 121, 66, 239, 153,
+ 34, 229, 209, 95, 110, 14, 173, 110, 234, 47, 11, 22, 52, 162, 254,
+ 50, 162, 97, 155, 68, 226, 47, 157, 127, 239, 156, 104, 230, 47, 5,
+ 63, 36, 231, 1, 14, 149, 139, 186, 222, 83, 245, 130, 191, 236, 104,
+ 252, 174, 241, 122, 40, 248, 203, 249, 186, 175, 39, 18, 127, 137, 31,
+ 164, 233, 5, 127, 249, 120, 109, 35, 83, 127, 57, 220, 181, 58, 245,
+ 151, 212, 209, 101, 169, 191, 220, 94, 92, 216, 212, 95, 202, 191, 250,
+ 40, 129, 248, 139, 189, 218, 189, 4, 149, 215, 33, 199, 92, 185, 144,
+ 96, 230, 47, 101, 74, 222, 74, 32, 254, 178, 233, 244, 237, 4, 226,
+ 47, 157, 190, 190, 147, 96, 230, 47, 237, 55, 221, 167, 121, 119, 132,
+ 70, 127, 97, 207, 141, 253, 5, 219, 67, 222, 95, 176, 125, 35, 254,
+ 66, 232, 150, 224, 47, 236, 185, 123, 121, 201, 224, 47, 177, 155, 58,
+ 208, 124, 43, 82, 190, 20, 248, 203, 163, 213, 193, 134, 188, 133, 58,
+ 244, 147, 7, 100, 183, 182, 17, 127, 217, 247, 119, 75, 133, 46, 4,
+ 254, 82, 127, 71, 51, 67, 222, 59, 224, 47, 173, 74, 5, 217, 136,
+ 191, 196, 190, 171, 210, 190, 224, 47, 153, 75, 131, 12, 121, 11, 68,
+ 141, 146, 191, 233, 216, 212, 70, 252, 165, 66, 235, 22, 10, 93, 4,
+ 252, 101, 101, 224, 171, 134, 188, 229, 162, 38, 200, 93, 198, 181, 177,
+ 17, 127, 249, 99, 70, 123, 133, 246, 1, 127, 113, 204, 151, 13, 121,
+ 143, 129, 191, 180, 216, 222, 149, 230, 151, 13, 91, 222, 93, 161, 31,
+ 135, 59, 228, 49, 253, 66, 140, 207, 40, 3, 127, 185, 48, 187, 139,
+ 141, 248, 203, 137, 66, 111, 168, 52, 248, 203, 129, 69, 157, 109, 102,
+ 254, 50, 120, 98, 103, 154, 155, 70, 104, 244, 23, 246, 220, 216, 95,
+ 48, 182, 241, 254, 130, 177, 138, 248, 11, 161, 155, 131, 191, 176, 231,
+ 238, 229, 37, 129, 191, 220, 154, 81, 155, 250, 11, 41, 143, 254, 146,
+ 126, 197, 223, 248, 187, 129, 191, 140, 56, 209, 136, 250, 203, 168, 43,
+ 86, 117, 109, 17, 252, 37, 236, 113, 115, 67, 222, 123, 224, 47, 159,
+ 250, 182, 161, 254, 210, 245, 204, 107, 10, 93, 14, 252, 229, 149, 31,
+ 95, 51, 246, 83, 240, 151, 172, 177, 45, 169, 191, 124, 182, 76, 245,
+ 205, 146, 224, 47, 149, 126, 107, 98, 200, 91, 27, 252, 101, 220, 183,
+ 65, 212, 95, 158, 221, 107, 160, 174, 165, 130, 191, 148, 108, 83, 199,
+ 144, 55, 30, 252, 101, 196, 209, 202, 212, 95, 42, 134, 87, 84, 207,
+ 180, 3, 127, 169, 121, 177, 172, 33, 239, 99, 240, 151, 189, 91, 170,
+ 82, 127, 89, 177, 178, 186, 66, 191, 8, 255, 68, 30, 28, 89, 195,
+ 212, 95, 238, 44, 174, 65, 253, 133, 208, 232, 47, 236, 185, 241, 56,
+ 15, 251, 169, 244, 46, 141, 39, 208, 15, 91, 96, 210, 103, 109, 198,
+ 173, 169, 60, 203, 244, 14, 121, 234, 193, 93, 26, 207, 184, 245, 158,
+ 103, 220, 186, 85, 118, 254, 206, 128, 192, 152, 75, 215, 123, 56, 29,
+ 41, 240, 78, 41, 154, 158, 176, 236, 252, 157, 1, 129, 237, 52, 173,
+ 199, 83, 174, 30, 64, 211, 186, 100, 231, 239, 12, 8, 196, 54, 173,
+ 199, 211, 92, 235, 86, 154, 125, 163, 159, 228, 239, 12, 8, 244, 7,
+ 58, 87, 144, 173, 207, 237, 99, 125, 23, 135, 141, 208, 151, 229, 4,
+ 187, 81, 159, 70, 183, 110, 149, 75, 30, 139, 109, 14, 27, 161, 81,
+ 158, 81, 204, 211, 173, 91, 229, 146, 199, 218, 62, 135, 141, 208, 40,
+ 207, 168, 77, 212, 205, 119, 62, 209, 203, 99, 216, 112, 216, 8, 141,
+ 242, 140, 48, 163, 187, 75, 227, 9, 119, 151, 70, 6, 248, 65, 142,
+ 9, 102, 154, 115, 247, 60, 100, 1, 239, 99, 15, 238, 210, 200, 226,
+ 238, 160, 200, 98, 229, 99, 30, 137, 195, 140, 15, 167, 35, 26, 222,
+ 41, 90, 211, 99, 125, 36, 14, 51, 40, 151, 214, 3, 104, 82, 23,
+ 103, 166, 56, 204, 248, 60, 206, 117, 151, 134, 102, 223, 144, 76, 113,
+ 152, 65, 187, 211, 251, 88, 10, 206, 74, 114, 135, 25, 203, 212, 26,
+ 30, 99, 198, 154, 75, 158, 59, 204, 160, 60, 79, 49, 131, 246, 228,
+ 229, 185, 195, 12, 202, 243, 20, 51, 33, 185, 228, 185, 195, 12, 202,
+ 243, 20, 51, 136, 19, 130, 25, 231, 191, 64, 63, 49, 193, 76, 11,
+ 238, 92, 79, 224, 77, 73, 247, 224, 236, 212, 12, 46, 6, 60, 228,
+ 206, 78, 77, 23, 135, 25, 148, 75, 99, 0, 208, 168, 83, 153, 179,
+ 124, 32, 14, 51, 33, 156, 14, 172, 55, 169, 75, 220, 69, 113, 152,
+ 65, 185, 186, 179, 83, 53, 29, 246, 139, 226, 48, 131, 118, 207, 47,
+ 102, 116, 107, 169, 15, 242, 143, 25, 94, 30, 218, 51, 191, 152, 225,
+ 229, 217, 47, 230, 31, 51, 124, 223, 76, 193, 137, 38, 207, 113, 22,
+ 252, 32, 195, 4, 51, 45, 217, 247, 176, 3, 175, 243, 188, 57, 102,
+ 176, 28, 241, 3, 231, 5, 86, 62, 228, 124, 254, 48, 195, 207, 39,
+ 162, 92, 162, 195, 14, 52, 234, 84, 250, 127, 231, 242, 135, 25, 126,
+ 62, 209, 206, 233, 192, 122, 147, 186, 132, 157, 203, 31, 102, 248, 249,
+ 68, 148, 203, 99, 198, 78, 236, 117, 46, 127, 152, 33, 243, 137, 193,
+ 154, 221, 105, 46, 227, 197, 210, 123, 214, 14, 169, 146, 148, 123, 62,
+ 209, 239, 202, 70, 91, 155, 132, 251, 158, 229, 164, 159, 99, 242, 98,
+ 14, 149, 222, 147, 24, 255, 85, 66, 238, 249, 38, 151, 107, 163, 237,
+ 225, 153, 122, 158, 245, 245, 56, 121, 161, 115, 42, 237, 249, 189, 124,
+ 216, 75, 243, 17, 33, 206, 88, 91, 157, 93, 205, 61, 138, 51, 22,
+ 254, 253, 82, 124, 247, 52, 140, 207, 105, 159, 123, 188, 106, 159, 25,
+ 107, 11, 41, 216, 212, 163, 56, 131, 56, 33, 152, 177, 164, 130, 31,
+ 252, 107, 130, 153, 86, 220, 247, 0, 94, 71, 170, 57, 102, 176, 28,
+ 241, 3, 199, 63, 172, 124, 195, 144, 30, 69, 60, 195, 76, 57, 183,
+ 126, 112, 169, 73, 52, 189, 231, 12, 229, 82, 95, 67, 29, 103, 181,
+ 113, 64, 63, 79, 116, 84, 203, 83, 71, 213, 239, 206, 210, 60, 67,
+ 11, 167, 3, 235, 77, 234, 210, 208, 81, 178, 128, 103, 152, 113, 175,
+ 99, 183, 227, 36, 205, 99, 70, 185, 60, 102, 44, 154, 142, 232, 185,
+ 158, 232, 168, 146, 167, 142, 245, 183, 212, 117, 171, 214, 5, 85, 187,
+ 215, 83, 74, 194, 159, 127, 144, 19, 237, 72, 124, 136, 208, 119, 126,
+ 154, 99, 103, 207, 221, 183, 187, 49, 221, 159, 217, 135, 255, 68, 230,
+ 179, 173, 210, 200, 63, 171, 42, 244, 236, 176, 225, 210, 47, 29, 90,
+ 25, 206, 133, 23, 89, 176, 90, 98, 88, 141, 165, 243, 253, 205, 34,
+ 54, 73, 70, 88, 85, 199, 241, 91, 164, 82, 255, 144, 59, 71, 226,
+ 164, 1, 195, 18, 19, 213, 249, 131, 120, 201, 47, 253, 7, 67, 222,
+ 115, 145, 59, 164, 105, 111, 126, 70, 243, 43, 138, 77, 249, 88, 221,
+ 203, 30, 190, 75, 42, 219, 100, 170, 33, 239, 147, 200, 68, 233, 163,
+ 195, 36, 239, 201, 41, 93, 108, 166, 230, 61, 21, 142, 216, 43, 117,
+ 91, 61, 209, 144, 215, 43, 234, 128, 244, 222, 161, 72, 154, 155, 241,
+ 253, 245, 249, 106, 174, 86, 196, 97, 233, 105, 193, 37, 38, 188, 199,
+ 164, 144, 85, 43, 104, 110, 198, 234, 152, 181, 218, 60, 240, 73, 233,
+ 193, 198, 13, 134, 188, 25, 145, 103, 164, 212, 61, 219, 105, 110, 198,
+ 176, 230, 59, 19, 213, 249, 146, 179, 146, 107, 195, 110, 147, 59, 210,
+ 46, 72, 95, 29, 216, 65, 115, 51, 102, 223, 217, 78, 243, 173, 134,
+ 149, 223, 110, 50, 119, 125, 77, 250, 248, 234, 118, 154, 155, 209, 127,
+ 255, 14, 141, 247, 182, 212, 240, 187, 95, 76, 120, 239, 74, 51, 165,
+ 157, 52, 55, 227, 203, 214, 187, 52, 222, 116, 233, 151, 38, 9, 38,
+ 190, 145, 41, 189, 159, 177, 135, 230, 91, 93, 79, 78, 214, 230, 189,
+ 179, 165, 113, 75, 247, 153, 232, 205, 145, 58, 151, 164, 247, 224, 200,
+ 165, 110, 28, 80, 121, 109, 94, 242, 233, 228, 223, 77, 114, 151, 188,
+ 229, 25, 91, 142, 104, 101, 10, 202, 239, 37, 29, 211, 120, 11, 201,
+ 237, 78, 156, 48, 225, 45, 44, 127, 240, 132, 248, 115, 81, 121, 118,
+ 197, 83, 26, 111, 49, 121, 93, 243, 51, 198, 247, 227, 36, 23, 151,
+ 43, 54, 78, 165, 185, 90, 141, 186, 158, 215, 214, 23, 74, 203, 195,
+ 162, 174, 154, 212, 183, 172, 204, 214, 217, 124, 41, 189, 243, 97, 69,
+ 217, 108, 253, 141, 180, 37, 216, 190, 146, 182, 228, 83, 104, 75, 176,
+ 189, 36, 109, 9, 161, 59, 196, 205, 177, 179, 231, 238, 229, 237, 237,
+ 245, 204, 126, 252, 139, 158, 193, 164, 45, 57, 176, 188, 168, 66, 119,
+ 156, 48, 92, 74, 159, 30, 214, 214, 136, 119, 55, 180, 37, 44, 78,
+ 199, 210, 181, 160, 210, 208, 150, 24, 197, 105, 228, 189, 11, 109, 73,
+ 124, 106, 8, 109, 75, 126, 156, 240, 182, 134, 143, 120, 233, 131, 226,
+ 131, 77, 124, 109, 135, 52, 107, 109, 8, 109, 75, 202, 58, 186, 104,
+ 190, 182, 75, 250, 97, 144, 108, 194, 155, 40, 77, 43, 222, 134, 182,
+ 37, 171, 59, 183, 208, 120, 247, 74, 206, 168, 198, 38, 188, 7, 164,
+ 227, 15, 26, 210, 182, 228, 171, 9, 117, 105, 238, 230, 136, 7, 53,
+ 77, 120, 143, 73, 175, 12, 172, 74, 219, 146, 161, 49, 149, 104, 238,
+ 230, 230, 75, 190, 166, 121, 94, 231, 173, 190, 180, 45, 249, 62, 172,
+ 28, 205, 221, 28, 23, 231, 99, 194, 123, 65, 90, 50, 189, 20, 109,
+ 75, 92, 165, 74, 210, 182, 164, 233, 250, 226, 166, 109, 201, 129, 2,
+ 37, 104, 91, 242, 226, 151, 162, 180, 45, 121, 237, 67, 179, 181, 172,
+ 187, 210, 241, 172, 23, 9, 164, 45, 217, 182, 240, 169, 182, 150, 149,
+ 46, 173, 170, 254, 56, 193, 172, 45, 121, 113, 144, 148, 201, 146, 246,
+ 78, 126, 164, 173, 101, 101, 75, 243, 234, 102, 38, 152, 181, 37, 75,
+ 207, 166, 145, 50, 114, 165, 121, 15, 19, 72, 91, 18, 211, 228, 81,
+ 130, 89, 91, 98, 77, 240, 162, 109, 201, 188, 185, 222, 180, 45, 57,
+ 219, 189, 128, 105, 91, 210, 179, 49, 169, 111, 81, 121, 228, 68, 173,
+ 190, 208, 150, 68, 237, 124, 108, 162, 183, 184, 60, 106, 47, 25, 11,
+ 150, 148, 151, 206, 85, 223, 25, 219, 146, 127, 139, 62, 77, 48, 107,
+ 75, 216, 26, 172, 47, 165, 177, 45, 49, 91, 155, 165, 253, 18, 232,
+ 71, 145, 182, 36, 182, 78, 144, 19, 251, 69, 164, 45, 33, 244, 244,
+ 77, 115, 236, 236, 121, 30, 253, 146, 218, 207, 236, 21, 178, 11, 208,
+ 60, 175, 45, 251, 212, 245, 151, 209, 93, 135, 75, 223, 252, 211, 199,
+ 112, 44, 121, 173, 195, 106, 137, 245, 209, 99, 233, 58, 97, 161, 197,
+ 155, 36, 163, 62, 58, 242, 214, 141, 216, 34, 141, 248, 203, 199, 70,
+ 218, 146, 33, 146, 218, 55, 143, 152, 26, 47, 45, 31, 243, 143, 225,
+ 125, 124, 161, 51, 119, 72, 133, 238, 110, 111, 79, 218, 146, 8, 251,
+ 6, 133, 94, 56, 115, 151, 116, 251, 208, 74, 67, 222, 59, 208, 150,
+ 164, 126, 176, 170, 61, 105, 75, 174, 94, 93, 171, 208, 242, 236, 189,
+ 210, 226, 177, 223, 25, 242, 78, 135, 126, 201, 167, 111, 253, 210, 158,
+ 180, 37, 141, 55, 236, 83, 232, 25, 208, 150, 92, 205, 78, 49, 228,
+ 173, 62, 231, 152, 228, 19, 120, 169, 61, 105, 75, 14, 44, 73, 87,
+ 232, 165, 208, 150, 148, 125, 225, 101, 104, 171, 249, 17, 103, 164, 118,
+ 153, 229, 104, 126, 217, 166, 132, 10, 218, 58, 231, 89, 169, 175, 163,
+ 178, 33, 239, 120, 104, 75, 126, 241, 41, 77, 243, 203, 126, 237, 95,
+ 66, 161, 127, 10, 191, 44, 197, 125, 83, 212, 120, 125, 21, 218, 146,
+ 58, 43, 138, 210, 252, 178, 42, 13, 84, 186, 0, 180, 37, 229, 118,
+ 22, 49, 228, 45, 29, 117, 87, 202, 172, 88, 132, 230, 151, 253, 25,
+ 164, 242, 250, 67, 91, 178, 95, 46, 102, 200, 155, 5, 109, 201, 193,
+ 147, 37, 105, 126, 89, 245, 63, 213, 247, 127, 16, 158, 45, 133, 158,
+ 240, 49, 228, 189, 14, 109, 201, 200, 26, 229, 105, 126, 217, 249, 59,
+ 42, 157, 211, 222, 75, 238, 188, 219, 215, 120, 109, 49, 217, 91, 254,
+ 99, 79, 121, 154, 95, 22, 189, 86, 45, 95, 30, 218, 146, 225, 225,
+ 21, 140, 215, 248, 146, 11, 203, 83, 23, 85, 178, 145, 182, 228, 135,
+ 69, 234, 186, 91, 16, 180, 37, 95, 46, 126, 197, 120, 173, 13, 218,
+ 146, 208, 183, 234, 208, 220, 52, 185, 159, 186, 62, 120, 46, 188, 180,
+ 60, 175, 151, 241, 218, 226, 83, 104, 75, 216, 250, 188, 47, 165, 19,
+ 161, 45, 49, 91, 183, 167, 253, 146, 185, 172, 45, 105, 1, 253, 18,
+ 28, 255, 144, 182, 132, 208, 163, 96, 140, 195, 158, 231, 129, 203, 174,
+ 207, 236, 75, 94, 244, 164, 109, 73, 137, 141, 109, 21, 186, 227, 251,
+ 195, 165, 37, 75, 234, 27, 242, 206, 124, 123, 181, 196, 198, 231, 177,
+ 116, 13, 121, 251, 252, 77, 146, 209, 248, 28, 121, 83, 103, 110, 145,
+ 118, 132, 134, 208, 182, 228, 234, 113, 245, 238, 177, 47, 167, 197, 75,
+ 233, 5, 140, 239, 42, 43, 229, 216, 33, 121, 183, 30, 71, 243, 77,
+ 91, 188, 170, 222, 49, 182, 28, 198, 56, 75, 154, 79, 50, 241, 211,
+ 68, 105, 209, 70, 146, 119, 232, 148, 98, 98, 62, 82, 104, 43, 244,
+ 75, 190, 91, 101, 124, 87, 89, 61, 104, 75, 166, 45, 26, 71, 115,
+ 85, 15, 37, 140, 86, 232, 14, 208, 150, 124, 123, 119, 164, 33, 239,
+ 183, 48, 198, 217, 51, 114, 24, 205, 85, 181, 134, 170, 57, 148, 31,
+ 67, 91, 210, 237, 77, 227, 251, 213, 150, 58, 206, 72, 101, 175, 246,
+ 162, 109, 73, 223, 134, 61, 105, 91, 50, 127, 108, 119, 67, 222, 221,
+ 208, 150, 148, 94, 208, 151, 182, 37, 171, 6, 189, 169, 249, 233, 101,
+ 233, 204, 107, 253, 141, 207, 213, 133, 182, 196, 225, 223, 159, 182, 37,
+ 139, 199, 246, 183, 145, 126, 201, 202, 159, 251, 155, 172, 189, 223, 149,
+ 54, 86, 27, 64, 219, 146, 65, 131, 212, 242, 229, 161, 45, 241, 221,
+ 248, 150, 33, 239, 51, 104, 75, 198, 119, 239, 71, 219, 146, 215, 239,
+ 171, 49, 237, 41, 180, 37, 117, 63, 239, 109, 200, 251, 16, 218, 146,
+ 90, 119, 122, 209, 182, 228, 243, 190, 42, 253, 2, 218, 146, 194, 187,
+ 123, 26, 242, 122, 67, 91, 18, 242, 110, 47, 218, 150, 12, 140, 83,
+ 203, 151, 132, 182, 100, 68, 33, 99, 222, 74, 208, 150, 252, 247, 101,
+ 119, 218, 150, 252, 217, 90, 221, 47, 82, 7, 218, 146, 174, 169, 175,
+ 27, 242, 150, 129, 49, 78, 70, 175, 14, 180, 45, 249, 40, 198, 166,
+ 237, 17, 41, 45, 151, 149, 90, 219, 204, 250, 37, 108, 239, 134, 47,
+ 165, 127, 131, 182, 196, 108, 79, 7, 153, 35, 195, 121, 49, 186, 22,
+ 115, 42, 211, 219, 113, 214, 100, 142, 172, 53, 155, 127, 113, 252, 13,
+ 101, 255, 50, 159, 35, 195, 114, 116, 222, 231, 111, 86, 62, 250, 140,
+ 184, 181, 24, 11, 167, 195, 1, 239, 228, 208, 244, 248, 157, 17, 183,
+ 22, 131, 114, 105, 61, 176, 222, 154, 142, 184, 211, 226, 214, 98, 44,
+ 127, 233, 231, 200, 28, 154, 125, 237, 167, 197, 173, 197, 160, 221, 69,
+ 174, 95, 250, 157, 17, 187, 126, 137, 246, 20, 185, 126, 105, 63, 45,
+ 118, 253, 18, 113, 66, 243, 238, 238, 195, 119, 73, 53, 193, 204, 107,
+ 220, 58, 1, 240, 58, 255, 244, 96, 45, 230, 20, 183, 134, 113, 146,
+ 91, 139, 249, 83, 28, 102, 80, 46, 93, 139, 1, 26, 117, 42, 145,
+ 34, 69, 28, 102, 236, 156, 14, 172, 55, 169, 75, 88, 138, 56, 204,
+ 160, 92, 221, 90, 140, 166, 35, 238, 190, 56, 204, 160, 221, 69, 174,
+ 95, 162, 141, 69, 174, 95, 134, 165, 136, 93, 191, 68, 219, 137, 92,
+ 191, 68, 156, 208, 187, 31, 111, 131, 31, 156, 50, 198, 76, 83, 43,
+ 151, 19, 118, 47, 211, 219, 122, 215, 131, 187, 31, 239, 113, 121, 119,
+ 247, 184, 187, 31, 239, 228, 15, 51, 55, 35, 70, 179, 220, 107, 78,
+ 71, 28, 188, 83, 156, 166, 39, 228, 78, 254, 48, 83, 48, 229, 14,
+ 93, 239, 65, 185, 180, 30, 64, 147, 186, 184, 254, 203, 31, 102, 90,
+ 54, 255, 182, 61, 173, 199, 221, 92, 121, 119, 154, 125, 195, 254, 203,
+ 31, 102, 66, 155, 126, 196, 238, 126, 188, 195, 249, 144, 238, 207, 97,
+ 67, 155, 18, 58, 47, 61, 47, 237, 67, 49, 144, 135, 246, 251, 159,
+ 202, 67, 123, 230, 37, 15, 109, 245, 63, 149, 23, 102, 32, 15, 237,
+ 226, 169, 60, 122, 247, 227, 109, 238, 28, 145, 235, 224, 7, 247, 77,
+ 48, 195, 229, 16, 133, 1, 111, 218, 77, 15, 238, 126, 188, 205, 229,
+ 94, 223, 226, 238, 126, 188, 41, 46, 206, 160, 92, 154, 123, 13, 52,
+ 234, 196, 50, 62, 55, 197, 197, 153, 48, 78, 7, 214, 155, 212, 37,
+ 230, 134, 184, 56, 131, 114, 117, 119, 63, 106, 58, 172, 55, 196, 197,
+ 25, 180, 187, 200, 56, 227, 115, 83, 108, 156, 65, 123, 138, 140, 51,
+ 214, 27, 98, 227, 12, 226, 132, 158, 35, 114, 25, 252, 224, 182, 9,
+ 102, 184, 61, 204, 86, 224, 141, 187, 234, 193, 221, 143, 215, 185, 24,
+ 112, 141, 59, 71, 228, 170, 56, 204, 160, 92, 26, 3, 128, 70, 157,
+ 202, 236, 193, 21, 113, 152, 177, 114, 58, 176, 222, 164, 46, 161, 87,
+ 196, 97, 6, 229, 234, 206, 17, 209, 116, 164, 93, 22, 135, 25, 180,
+ 187, 200, 241, 12, 218, 88, 228, 120, 38, 244, 138, 216, 241, 12, 218,
+ 78, 228, 120, 6, 113, 66, 207, 201, 223, 14, 126, 112, 61, 47, 204,
+ 96, 122, 247, 36, 221, 29, 70, 105, 151, 50, 189, 99, 246, 120, 112,
+ 247, 227, 37, 46, 6, 92, 98, 229, 125, 18, 61, 197, 76, 113, 183,
+ 126, 112, 241, 200, 183, 236, 254, 95, 78, 71, 154, 11, 176, 175, 233,
+ 113, 236, 242, 20, 51, 238, 117, 212, 72, 232, 69, 117, 160, 92, 154,
+ 15, 11, 245, 38, 117, 73, 251, 213, 83, 204, 184, 215, 145, 22, 104,
+ 163, 152, 65, 185, 186, 115, 68, 92, 26, 46, 119, 120, 138, 25, 247,
+ 58, 106, 206, 87, 247, 150, 13, 240, 86, 237, 94, 79, 41, 169, 230,
+ 6, 161, 29, 137, 15, 17, 26, 115, 85, 217, 243, 60, 246, 96, 244,
+ 124, 77, 110, 182, 245, 59, 173, 76, 119, 153, 148, 247, 78, 236, 37,
+ 175, 94, 107, 204, 139, 185, 135, 255, 6, 146, 50, 3, 100, 111, 199,
+ 122, 141, 247, 93, 185, 254, 233, 117, 38, 188, 161, 242, 133, 229, 49,
+ 90, 153, 161, 242, 157, 37, 223, 168, 231, 103, 63, 27, 41, 255, 216,
+ 116, 173, 33, 111, 78, 129, 241, 242, 204, 97, 107, 180, 50, 147, 228,
+ 137, 151, 190, 106, 167, 174, 35, 78, 150, 39, 56, 190, 106, 103, 188,
+ 142, 56, 69, 94, 113, 118, 149, 86, 102, 154, 220, 232, 232, 42, 141,
+ 119, 186, 188, 63, 113, 149, 9, 239, 12, 121, 247, 8, 34, 127, 150,
+ 156, 241, 190, 74, 99, 174, 106, 106, 43, 99, 189, 152, 123, 88, 188,
+ 225, 74, 173, 204, 199, 114, 249, 186, 43, 53, 189, 243, 229, 74, 181,
+ 87, 154, 232, 253, 68, 62, 148, 78, 202, 44, 148, 155, 13, 39, 239,
+ 188, 72, 94, 243, 143, 89, 125, 23, 203, 245, 45, 223, 104, 101, 150,
+ 80, 250, 252, 244, 165, 220, 243, 188, 99, 60, 250, 26, 226, 143, 247,
+ 53, 196, 19, 241, 53, 66, 163, 175, 177, 231, 121, 251, 218, 241, 211,
+ 125, 169, 175, 145, 242, 232, 107, 131, 110, 247, 52, 245, 53, 235, 244,
+ 238, 212, 215, 42, 87, 235, 74, 125, 205, 146, 248, 186, 169, 175, 157,
+ 121, 210, 129, 250, 90, 253, 2, 18, 245, 181, 101, 101, 218, 153, 250,
+ 90, 215, 203, 173, 169, 175, 213, 28, 222, 156, 250, 154, 111, 145, 102,
+ 166, 190, 246, 188, 105, 19, 234, 107, 203, 150, 52, 166, 190, 214, 240,
+ 191, 70, 166, 190, 118, 119, 112, 99, 234, 107, 199, 107, 88, 169, 175,
+ 245, 41, 253, 170, 169, 175, 157, 146, 122, 82, 95, 251, 171, 106, 79,
+ 234, 107, 3, 138, 244, 52, 245, 181, 234, 150, 14, 212, 215, 158, 92,
+ 104, 71, 125, 237, 239, 221, 173, 77, 125, 109, 102, 251, 102, 212, 215,
+ 8, 141, 190, 198, 158, 27, 251, 26, 182, 195, 188, 175, 97, 187, 74,
+ 124, 141, 208, 232, 107, 236, 121, 222, 190, 246, 90, 57, 27, 205, 121,
+ 36, 229, 209, 215, 42, 52, 53, 230, 69, 95, 251, 118, 128, 141, 230,
+ 60, 254, 213, 202, 70, 115, 30, 139, 85, 48, 227, 13, 149, 71, 174,
+ 104, 79, 115, 30, 219, 13, 104, 111, 35, 190, 246, 118, 161, 246, 54,
+ 51, 95, 203, 153, 210, 142, 230, 45, 206, 58, 167, 210, 232, 107, 107,
+ 50, 140, 215, 22, 45, 201, 83, 228, 31, 187, 18, 249, 211, 228, 158,
+ 27, 84, 218, 27, 124, 45, 221, 203, 248, 157, 189, 146, 103, 200, 195,
+ 234, 216, 105, 206, 99, 153, 37, 54, 109, 141, 202, 33, 175, 107, 221,
+ 206, 100, 205, 122, 142, 188, 243, 68, 19, 154, 243, 248, 196, 170, 230,
+ 135, 150, 5, 95, 91, 61, 200, 106, 200, 91, 60, 249, 19, 185, 120,
+ 253, 86, 54, 226, 107, 91, 195, 213, 92, 209, 226, 224, 107, 43, 206,
+ 180, 55, 121, 231, 197, 114, 131, 83, 175, 211, 124, 73, 66, 163, 175,
+ 177, 231, 198, 190, 134, 241, 152, 247, 53, 140, 175, 196, 215, 8, 141,
+ 190, 198, 158, 231, 237, 107, 43, 86, 55, 164, 190, 70, 202, 163, 175,
+ 21, 153, 211, 208, 212, 215, 42, 191, 219, 144, 250, 218, 250, 143, 27,
+ 82, 95, 11, 138, 111, 104, 234, 107, 17, 93, 253, 89, 62, 246, 74,
+ 127, 234, 107, 11, 159, 251, 155, 250, 90, 181, 31, 2, 168, 175, 77,
+ 234, 16, 64, 125, 173, 120, 64, 128, 169, 175, 21, 62, 238, 79, 125,
+ 173, 205, 40, 127, 234, 107, 227, 10, 250, 155, 250, 218, 210, 63, 26,
+ 80, 95, 235, 57, 80, 173, 99, 69, 240, 181, 208, 95, 140, 245, 222,
+ 6, 95, 155, 181, 160, 53, 245, 53, 223, 94, 42, 93, 14, 124, 237,
+ 98, 83, 227, 181, 54, 31, 240, 181, 198, 63, 55, 163, 190, 246, 239,
+ 127, 141, 52, 63, 93, 36, 151, 169, 239, 111, 178, 182, 184, 88, 158,
+ 50, 132, 229, 230, 18, 26, 125, 141, 61, 55, 30, 215, 98, 191, 156,
+ 244, 209, 99, 78, 64, 191, 243, 178, 89, 31, 157, 221, 153, 24, 10,
+ 188, 174, 120, 243, 62, 58, 150, 163, 231, 35, 109, 99, 229, 195, 226,
+ 243, 55, 174, 197, 126, 2, 61, 31, 105, 27, 119, 62, 18, 208, 168,
+ 83, 41, 20, 159, 191, 113, 45, 198, 7, 90, 15, 78, 7, 214, 155,
+ 212, 37, 250, 231, 252, 141, 107, 177, 93, 160, 245, 136, 207, 117, 47,
+ 143, 166, 195, 239, 231, 252, 141, 107, 209, 31, 232, 124, 98, 188, 62,
+ 87, 149, 245, 183, 28, 54, 66, 63, 233, 144, 96, 55, 234, 135, 233,
+ 242, 43, 114, 201, 99, 49, 213, 97, 35, 52, 202, 51, 138, 181, 186,
+ 92, 218, 159, 245, 242, 88, 187, 233, 176, 17, 26, 229, 25, 181, 167,
+ 186, 117, 196, 92, 242, 24, 54, 28, 54, 66, 163, 60, 35, 204, 240,
+ 227, 90, 196, 9, 61, 235, 239, 8, 248, 193, 118, 51, 204, 176, 59,
+ 19, 253, 128, 55, 230, 152, 57, 102, 176, 28, 29, 15, 30, 231, 206,
+ 250, 59, 38, 14, 51, 40, 151, 158, 143, 4, 52, 234, 84, 214, 53,
+ 142, 138, 195, 140, 31, 167, 3, 235, 77, 234, 18, 114, 84, 28, 102,
+ 80, 174, 238, 158, 81, 77, 135, 235, 136, 56, 204, 160, 221, 233, 220,
+ 200, 11, 103, 123, 119, 152, 177, 76, 253, 215, 230, 41, 102, 208, 198,
+ 188, 60, 119, 152, 65, 121, 158, 98, 38, 132, 151, 247, 212, 217, 222,
+ 29, 102, 28, 147, 255, 181, 121, 138, 25, 180, 29, 149, 247, 196, 217,
+ 222, 29, 102, 44, 32, 207, 83, 204, 32, 78, 232, 89, 127, 191, 131,
+ 31, 156, 48, 195, 12, 187, 51, 209, 117, 24, 218, 243, 63, 204, 49,
+ 131, 229, 104, 12, 56, 204, 157, 245, 119, 72, 28, 102, 66, 57, 29,
+ 46, 120, 39, 151, 166, 199, 113, 72, 28, 102, 80, 46, 173, 7, 208,
+ 164, 46, 62, 135, 196, 97, 38, 244, 143, 92, 103, 253, 105, 246, 141,
+ 249, 93, 28, 102, 208, 238, 249, 197, 12, 63, 167, 239, 56, 148, 127,
+ 204, 232, 214, 48, 14, 229, 31, 51, 186, 53, 140, 223, 243, 143, 25,
+ 190, 111, 134, 56, 161, 243, 167, 123, 193, 15, 142, 152, 97, 134, 221,
+ 153, 24, 115, 16, 218, 243, 3, 30, 156, 245, 119, 144, 139, 1, 7,
+ 185, 123, 70, 247, 231, 15, 51, 252, 252, 169, 31, 167, 35, 6, 222,
+ 41, 70, 211, 99, 223, 159, 63, 204, 240, 243, 167, 40, 151, 214, 3,
+ 104, 82, 151, 148, 125, 249, 195, 12, 63, 127, 234, 119, 32, 215, 89,
+ 127, 154, 125, 67, 247, 229, 15, 51, 100, 254, 52, 88, 179, 59, 241,
+ 33, 151, 179, 244, 158, 11, 15, 55, 188, 52, 127, 234, 227, 218, 104,
+ 235, 28, 240, 173, 71, 113, 193, 158, 75, 158, 213, 58, 224, 165, 57,
+ 50, 148, 215, 179, 68, 79, 143, 228, 161, 61, 169, 188, 51, 165, 247,
+ 76, 170, 213, 241, 165, 121, 16, 235, 229, 141, 182, 98, 141, 219, 123,
+ 20, 103, 66, 57, 121, 150, 11, 165, 247, 140, 247, 169, 251, 210, 88,
+ 215, 5, 242, 126, 24, 237, 239, 81, 156, 65, 156, 208, 190, 153, 19,
+ 252, 224, 119, 51, 204, 180, 98, 125, 109, 224, 117, 57, 61, 24, 207,
+ 236, 229, 98, 64, 50, 135, 153, 237, 111, 228, 43, 55, 119, 67, 115,
+ 7, 187, 103, 52, 153, 139, 1, 64, 163, 78, 44, 83, 249, 183, 55,
+ 242, 149, 155, 59, 171, 111, 122, 27, 90, 15, 78, 7, 214, 155, 212,
+ 37, 174, 69, 191, 34, 158, 97, 198, 189, 142, 7, 95, 165, 208, 220,
+ 92, 148, 171, 27, 207, 104, 58, 42, 191, 230, 137, 142, 188, 115, 115,
+ 235, 220, 102, 185, 185, 104, 119, 178, 111, 125, 140, 127, 144, 19, 237,
+ 72, 124, 136, 208, 13, 227, 230, 216, 217, 115, 247, 237, 238, 245, 158,
+ 207, 236, 163, 250, 44, 210, 112, 96, 149, 252, 71, 196, 42, 244, 43,
+ 19, 134, 75, 253, 3, 14, 25, 198, 148, 39, 11, 86, 75, 12, 171,
+ 177, 116, 125, 195, 43, 98, 147, 100, 132, 85, 139, 150, 155, 187, 241,
+ 147, 245, 90, 153, 56, 201, 49, 120, 189, 118, 103, 103, 188, 244, 118,
+ 240, 122, 67, 222, 130, 81, 59, 164, 6, 161, 223, 107, 101, 118, 74,
+ 227, 178, 212, 88, 90, 46, 98, 151, 52, 55, 218, 120, 14, 190, 100,
+ 84, 162, 20, 252, 39, 169, 175, 83, 170, 58, 106, 150, 66, 151, 136,
+ 216, 43, 37, 53, 30, 100, 200, 123, 55, 242, 128, 244, 251, 169, 102,
+ 244, 126, 211, 33, 213, 171, 41, 244, 131, 240, 195, 82, 167, 225, 5,
+ 140, 231, 219, 35, 143, 73, 207, 236, 46, 45, 31, 41, 69, 250, 233,
+ 120, 106, 176, 90, 223, 147, 210, 236, 247, 254, 52, 204, 83, 194, 251,
+ 77, 99, 122, 220, 209, 202, 164, 74, 37, 94, 188, 80, 232, 130, 17,
+ 103, 165, 158, 169, 197, 12, 245, 122, 71, 93, 144, 122, 44, 173, 76,
+ 239, 55, 109, 211, 161, 65, 59, 149, 247, 178, 212, 229, 113, 75, 67,
+ 222, 167, 145, 215, 164, 202, 75, 122, 208, 251, 77, 39, 253, 248, 174,
+ 66, 63, 15, 191, 45, 109, 56, 52, 202, 144, 55, 59, 242, 174, 212,
+ 220, 54, 141, 222, 111, 218, 247, 105, 184, 118, 175, 106, 186, 180, 237,
+ 92, 164, 137, 111, 100, 74, 33, 187, 29, 90, 153, 44, 233, 122, 249,
+ 72, 109, 190, 61, 91, 154, 53, 198, 140, 55, 71, 106, 84, 51, 138,
+ 148, 145, 103, 204, 136, 210, 230, 204, 189, 228, 223, 207, 68, 153, 204,
+ 153, 123, 203, 62, 79, 72, 153, 130, 114, 177, 97, 115, 52, 222, 66,
+ 114, 129, 63, 231, 24, 223, 65, 155, 92, 88, 94, 244, 23, 41, 83,
+ 84, 254, 176, 228, 199, 234, 59, 219, 138, 201, 221, 228, 79, 76, 244,
+ 22, 151, 11, 93, 248, 84, 43, 83, 82, 94, 21, 242, 153, 134, 163,
+ 210, 114, 210, 171, 95, 154, 212, 183, 172, 204, 214, 21, 125, 41, 141,
+ 249, 116, 102, 235, 141, 164, 45, 193, 246, 149, 180, 37, 227, 160, 45,
+ 193, 246, 146, 180, 37, 132, 182, 66, 91, 194, 158, 187, 151, 87, 165,
+ 215, 51, 123, 175, 13, 163, 105, 91, 50, 45, 64, 189, 11, 248, 85,
+ 104, 75, 134, 118, 93, 107, 218, 150, 176, 56, 29, 75, 215, 175, 176,
+ 45, 49, 138, 211, 164, 45, 249, 75, 238, 69, 219, 146, 35, 187, 180,
+ 181, 44, 104, 75, 156, 205, 66, 76, 238, 14, 222, 33, 149, 217, 223,
+ 151, 182, 37, 191, 84, 82, 121, 139, 64, 91, 210, 103, 116, 87, 67,
+ 222, 98, 208, 150, 92, 94, 101, 163, 109, 201, 133, 77, 234, 58, 82,
+ 41, 104, 75, 218, 236, 174, 102, 200, 155, 14, 109, 73, 151, 198, 55,
+ 131, 73, 91, 178, 222, 251, 160, 66, 103, 65, 91, 210, 48, 245, 91,
+ 195, 246, 0, 243, 252, 111, 102, 174, 161, 109, 201, 205, 143, 230, 40,
+ 116, 97, 104, 75, 250, 92, 236, 107, 200, 251, 56, 242, 140, 148, 253,
+ 243, 218, 182, 164, 45, 233, 52, 231, 23, 133, 46, 15, 109, 201, 157,
+ 126, 199, 13, 99, 197, 147, 200, 11, 82, 192, 189, 185, 193, 164, 45,
+ 185, 228, 245, 131, 122, 172, 92, 248, 101, 233, 156, 239, 49, 67, 189,
+ 89, 120, 95, 91, 208, 189, 96, 210, 150, 196, 84, 206, 86, 105, 204,
+ 167, 243, 46, 96, 242, 125, 239, 74, 25, 201, 207, 130, 73, 91, 50,
+ 127, 177, 202, 139, 121, 254, 85, 251, 103, 25, 234, 125, 1, 109, 73,
+ 235, 110, 15, 130, 73, 91, 210, 219, 245, 72, 107, 119, 179, 165, 113,
+ 147, 159, 5, 155, 181, 37, 251, 211, 139, 210, 182, 228, 148, 179, 52,
+ 109, 75, 46, 45, 241, 53, 109, 75, 234, 204, 170, 74, 219, 146, 200,
+ 106, 53, 104, 91, 242, 239, 174, 90, 166, 109, 73, 163, 243, 181, 105,
+ 91, 210, 108, 87, 3, 141, 183, 152, 220, 230, 203, 32, 211, 182, 100,
+ 119, 242, 171, 180, 45, 137, 255, 43, 152, 182, 37, 171, 44, 175, 155,
+ 182, 37, 108, 221, 216, 151, 210, 216, 150, 152, 173, 39, 211, 126, 9,
+ 244, 163, 104, 91, 82, 43, 200, 137, 253, 34, 210, 150, 16, 58, 251,
+ 135, 57, 118, 246, 220, 189, 188, 229, 85, 159, 217, 83, 215, 22, 167,
+ 249, 116, 111, 157, 85, 207, 16, 61, 60, 116, 184, 116, 178, 150, 113,
+ 110, 110, 111, 104, 75, 88, 31, 61, 150, 174, 79, 214, 129, 182, 196,
+ 168, 143, 174, 174, 107, 108, 145, 58, 124, 222, 134, 230, 211, 181, 169,
+ 168, 158, 141, 186, 0, 218, 146, 59, 171, 140, 207, 198, 13, 158, 183,
+ 67, 250, 127, 180, 93, 7, 96, 83, 213, 215, 191, 73, 10, 5, 25,
+ 22, 68, 134, 50, 202, 134, 50, 236, 96, 183, 205, 107, 203, 222, 5,
+ 10, 20, 16, 218, 180, 73, 219, 208, 54, 9, 73, 186, 24, 109, 5,
+ 100, 201, 222, 178, 172, 34, 75, 65, 202, 80, 144, 182, 73, 4, 65,
+ 28, 104, 21, 197, 173, 117, 15, 80, 64, 101, 202, 248, 126, 231, 190,
+ 151, 151, 87, 90, 192, 127, 202, 39, 158, 247, 206, 189, 239, 222, 223,
+ 29, 231, 220, 115, 206, 125, 35, 29, 254, 122, 31, 249, 123, 186, 17,
+ 11, 196, 103, 28, 123, 230, 30, 137, 92, 217, 227, 222, 207, 83, 246,
+ 228, 151, 68, 254, 56, 180, 190, 252, 61, 93, 181, 29, 62, 156, 159,
+ 63, 227, 104, 228, 219, 93, 254, 188, 231, 247, 181, 219, 242, 143, 71,
+ 118, 218, 125, 90, 254, 54, 183, 223, 23, 14, 206, 175, 157, 249, 78,
+ 100, 78, 139, 151, 238, 89, 215, 153, 123, 42, 178, 235, 147, 75, 228,
+ 111, 115, 127, 253, 105, 129, 86, 28, 239, 71, 145, 51, 236, 115, 239,
+ 89, 247, 16, 226, 146, 226, 186, 107, 181, 110, 91, 210, 98, 206, 11,
+ 156, 255, 3, 182, 228, 224, 237, 87, 238, 89, 247, 2, 226, 146, 209,
+ 139, 223, 208, 186, 109, 73, 75, 149, 216, 127, 29, 226, 146, 174, 121,
+ 63, 222, 179, 110, 108, 222, 79, 145, 51, 252, 85, 242, 247, 116, 23,
+ 198, 87, 231, 252, 161, 153, 191, 71, 118, 157, 95, 235, 158, 243, 252,
+ 14, 108, 201, 190, 149, 53, 229, 239, 233, 178, 54, 139, 58, 86, 15,
+ 182, 164, 203, 206, 123, 215, 125, 104, 246, 165, 72, 221, 222, 58, 242,
+ 247, 116, 117, 103, 60, 44, 126, 243, 13, 91, 114, 124, 192, 189, 127,
+ 143, 246, 91, 216, 18, 125, 138, 252, 13, 110, 212, 147, 49, 226, 55,
+ 181, 55, 180, 170, 168, 254, 17, 13, 239, 251, 61, 157, 254, 90, 3,
+ 249, 123, 186, 174, 39, 164, 111, 160, 97, 75, 124, 87, 221, 187, 110,
+ 27, 216, 18, 231, 134, 198, 242, 247, 116, 23, 183, 61, 206, 249, 39,
+ 96, 75, 206, 239, 187, 247, 61, 153, 27, 176, 37, 27, 95, 106, 227,
+ 249, 187, 145, 7, 197, 189, 233, 153, 89, 117, 163, 118, 159, 12, 188,
+ 239, 183, 185, 158, 247, 2, 26, 200, 60, 125, 155, 123, 191, 247, 5,
+ 228, 184, 164, 183, 199, 150, 44, 233, 208, 217, 69, 251, 31, 183, 45,
+ 113, 243, 189, 246, 206, 137, 240, 228, 87, 142, 247, 225, 192, 27, 17,
+ 139, 26, 14, 149, 109, 201, 141, 111, 196, 53, 186, 214, 148, 20, 249,
+ 122, 192, 189, 159, 55, 54, 134, 45, 241, 236, 207, 119, 202, 207, 159,
+ 187, 194, 150, 220, 107, 127, 238, 182, 37, 221, 236, 93, 100, 91, 178,
+ 166, 187, 248, 108, 62, 6, 182, 164, 213, 149, 123, 207, 223, 19, 115,
+ 95, 141, 108, 241, 240, 19, 178, 45, 177, 159, 21, 127, 127, 249, 218,
+ 83, 71, 34, 223, 253, 236, 222, 191, 43, 190, 43, 175, 36, 242, 229,
+ 95, 163, 101, 91, 178, 180, 233, 68, 206, 111, 134, 45, 169, 43, 36,
+ 222, 179, 110, 45, 196, 37, 246, 243, 41, 242, 183, 185, 250, 254, 233,
+ 156, 95, 128, 184, 228, 139, 245, 247, 254, 174, 119, 29, 246, 56, 199,
+ 143, 102, 200, 223, 230, 198, 46, 201, 20, 127, 219, 26, 182, 228, 253,
+ 241, 89, 247, 172, 219, 28, 182, 164, 217, 71, 118, 249, 219, 220, 129,
+ 210, 247, 196, 97, 176, 37, 173, 76, 150, 123, 214, 157, 10, 91, 18,
+ 215, 38, 93, 254, 54, 247, 233, 127, 196, 254, 79, 132, 45, 73, 56,
+ 166, 191, 103, 93, 1, 113, 73, 217, 208, 39, 101, 91, 114, 121, 252,
+ 4, 206, 111, 192, 30, 39, 197, 112, 239, 239, 107, 207, 195, 150, 20,
+ 133, 142, 151, 109, 9, 203, 27, 39, 253, 13, 218, 191, 34, 7, 30,
+ 29, 123, 159, 239, 122, 47, 69, 126, 49, 203, 243, 109, 174, 35, 114,
+ 140, 108, 75, 182, 84, 27, 125, 159, 118, 111, 70, 46, 125, 211, 243,
+ 109, 174, 230, 49, 145, 191, 5, 91, 146, 107, 30, 113, 159, 103, 254,
+ 234, 40, 123, 140, 231, 219, 220, 126, 71, 60, 223, 230, 214, 241, 191,
+ 119, 221, 198, 176, 37, 166, 215, 61, 223, 230, 126, 48, 72, 252, 54,
+ 183, 45, 108, 201, 161, 79, 239, 125, 191, 184, 246, 27, 15, 69, 109,
+ 174, 235, 249, 54, 247, 234, 104, 209, 6, 92, 131, 45, 201, 250, 178,
+ 167, 112, 191, 184, 196, 243, 222, 71, 3, 153, 63, 2, 91, 114, 191,
+ 247, 65, 228, 103, 49, 46, 197, 125, 229, 151, 47, 169, 203, 142, 222,
+ 239, 30, 153, 231, 111, 98, 22, 236, 189, 164, 246, 127, 229, 63, 220,
+ 87, 222, 171, 184, 31, 187, 87, 113, 143, 108, 207, 131, 123, 22, 227,
+ 175, 104, 163, 0, 125, 42, 144, 218, 137, 216, 243, 224, 158, 197, 16,
+ 174, 60, 14, 240, 238, 177, 148, 238, 126, 112, 207, 98, 252, 95, 185,
+ 227, 190, 178, 52, 191, 241, 187, 31, 220, 179, 24, 154, 247, 7, 249,
+ 252, 50, 98, 207, 131, 125, 126, 73, 243, 249, 32, 159, 95, 198, 239,
+ 126, 176, 207, 47, 105, 157, 200, 239, 201, 236, 184, 164, 142, 119, 221,
+ 111, 205, 120, 254, 38, 102, 60, 173, 177, 93, 255, 225, 190, 242, 203,
+ 138, 251, 177, 47, 41, 222, 147, 217, 245, 0, 223, 147, 121, 73, 113,
+ 95, 25, 60, 181, 201, 11, 237, 122, 128, 239, 201, 40, 218, 160, 113,
+ 187, 199, 178, 124, 231, 3, 124, 79, 102, 215, 29, 247, 149, 165, 54,
+ 252, 119, 62, 192, 247, 100, 118, 61, 216, 231, 151, 108, 215, 131, 125,
+ 126, 73, 243, 249, 32, 159, 95, 250, 239, 124, 176, 207, 47, 105, 157,
+ 200, 207, 98, 182, 66, 15, 94, 190, 207, 154, 81, 252, 77, 76, 127,
+ 212, 45, 216, 246, 31, 222, 147, 217, 161, 240, 1, 219, 21, 239, 201,
+ 108, 171, 218, 154, 169, 187, 245, 5, 143, 15, 216, 174, 240, 1, 224,
+ 169, 77, 30, 77, 190, 88, 181, 53, 115, 230, 141, 30, 30, 95, 166,
+ 104, 131, 198, 237, 30, 75, 244, 139, 85, 91, 51, 175, 124, 50, 212,
+ 243, 158, 204, 182, 59, 222, 147, 145, 218, 40, 219, 90, 181, 53, 115,
+ 179, 105, 19, 207, 123, 50, 219, 238, 254, 173, 42, 205, 169, 155, 191,
+ 91, 59, 21, 222, 147, 121, 241, 238, 120, 52, 127, 255, 43, 94, 244,
+ 61, 240, 104, 174, 254, 87, 60, 154, 187, 187, 225, 209, 188, 252, 87,
+ 60, 57, 54, 219, 170, 136, 205, 54, 65, 15, 118, 220, 111, 205, 40,
+ 254, 38, 230, 11, 208, 205, 231, 254, 195, 123, 50, 47, 40, 124, 192,
+ 11, 138, 216, 108, 203, 3, 124, 79, 70, 209, 70, 1, 250, 84, 38,
+ 181, 19, 177, 229, 1, 198, 102, 207, 41, 214, 37, 120, 247, 88, 74,
+ 55, 63, 192, 216, 236, 185, 59, 98, 51, 105, 126, 227, 55, 63, 192,
+ 216, 108, 203, 131, 245, 51, 17, 91, 30, 172, 159, 161, 249, 124, 144,
+ 126, 38, 126, 243, 131, 245, 51, 180, 78, 228, 216, 108, 61, 244, 96,
+ 235, 253, 214, 140, 226, 29, 102, 212, 45, 219, 240, 31, 98, 179, 77,
+ 138, 152, 102, 163, 34, 54, 219, 240, 0, 99, 179, 141, 138, 117, 9,
+ 158, 218, 228, 133, 54, 60, 192, 216, 76, 209, 6, 141, 219, 61, 150,
+ 229, 207, 62, 192, 216, 108, 195, 29, 177, 153, 212, 134, 255, 179, 15,
+ 48, 54, 219, 240, 96, 247, 51, 108, 195, 131, 221, 207, 208, 124, 62,
+ 200, 253, 140, 255, 179, 15, 118, 63, 67, 235, 68, 254, 59, 178, 107,
+ 160, 7, 155, 148, 107, 102, 100, 194, 96, 139, 89, 252, 163, 66, 229,
+ 48, 164, 184, 1, 117, 253, 215, 93, 82, 135, 132, 236, 136, 60, 245,
+ 94, 97, 228, 160, 200, 22, 111, 164, 188, 59, 61, 114, 100, 212, 29,
+ 177, 217, 122, 133, 15, 88, 167, 240, 51, 107, 43, 211, 131, 157, 145,
+ 116, 95, 16, 227, 137, 8, 9, 153, 19, 49, 50, 170, 206, 93, 245,
+ 128, 202, 200, 62, 96, 157, 194, 7, 128, 167, 54, 185, 159, 249, 79,
+ 109, 212, 253, 79, 109, 248, 175, 187, 195, 7, 72, 99, 41, 93, 243,
+ 95, 218, 120, 248, 190, 109, 132, 73, 115, 82, 121, 28, 177, 147, 99,
+ 121, 120, 69, 237, 218, 140, 245, 97, 3, 65, 189, 42, 238, 207, 31,
+ 48, 30, 141, 245, 65, 224, 201, 127, 19, 110, 141, 226, 239, 91, 173,
+ 70, 156, 179, 190, 50, 253, 235, 86, 169, 254, 185, 255, 59, 245, 94,
+ 154, 235, 212, 123, 173, 162, 94, 25, 168, 115, 92, 238, 176, 73, 112,
+ 235, 159, 252, 247, 128, 86, 43, 222, 57, 94, 117, 73, 29, 189, 166,
+ 178, 54, 186, 87, 218, 70, 52, 234, 18, 133, 132, 108, 140, 76, 74,
+ 122, 44, 106, 214, 230, 199, 93, 205, 110, 132, 71, 220, 169, 227, 84,
+ 166, 99, 37, 125, 43, 88, 117, 55, 221, 104, 16, 21, 255, 252, 77,
+ 103, 244, 19, 45, 129, 165, 230, 143, 56, 169, 238, 157, 127, 168, 128,
+ 174, 83, 27, 217, 18, 86, 91, 94, 146, 177, 17, 193, 214, 72, 186,
+ 230, 198, 115, 243, 61, 90, 149, 42, 242, 105, 238, 77, 152, 247, 116,
+ 118, 4, 36, 63, 239, 249, 250, 118, 36, 181, 237, 190, 119, 232, 230,
+ 211, 108, 157, 162, 60, 249, 140, 141, 81, 53, 97, 31, 131, 242, 107,
+ 215, 171, 248, 247, 167, 87, 41, 126, 7, 131, 93, 86, 211, 28, 87,
+ 156, 211, 30, 149, 206, 105, 193, 74, 200, 121, 197, 37, 245, 245, 219,
+ 125, 143, 222, 186, 221, 176, 111, 243, 211, 239, 149, 140, 57, 181, 88,
+ 184, 115, 78, 169, 156, 188, 166, 87, 42, 236, 198, 242, 138, 115, 26,
+ 15, 251, 167, 102, 239, 68, 141, 238, 189, 108, 63, 217, 194, 145, 81,
+ 143, 242, 217, 84, 87, 50, 167, 116, 93, 94, 211, 138, 54, 168, 79,
+ 5, 82, 59, 5, 145, 151, 43, 180, 113, 245, 229, 233, 111, 196, 140,
+ 173, 222, 247, 135, 207, 91, 29, 178, 241, 54, 26, 210, 253, 226, 74,
+ 219, 232, 168, 90, 32, 255, 22, 18, 225, 150, 219, 111, 73, 109, 228,
+ 71, 84, 108, 35, 122, 172, 234, 232, 164, 177, 103, 163, 14, 127, 192,
+ 14, 69, 241, 54, 26, 221, 181, 141, 175, 46, 205, 231, 109, 28, 148,
+ 230, 164, 173, 84, 38, 111, 253, 51, 111, 184, 247, 26, 241, 252, 44,
+ 242, 154, 77, 115, 35, 149, 123, 144, 41, 208, 137, 197, 160, 253, 10,
+ 221, 152, 184, 167, 78, 212, 168, 222, 203, 130, 121, 121, 54, 44, 202,
+ 93, 118, 92, 199, 167, 165, 185, 149, 246, 24, 172, 9, 243, 133, 110,
+ 116, 1, 185, 117, 67, 243, 249, 75, 81, 110, 124, 146, 133, 155, 111,
+ 253, 243, 159, 81, 202, 118, 39, 169, 210, 217, 108, 208, 94, 85, 122,
+ 185, 152, 240, 130, 52, 239, 109, 249, 136, 193, 103, 213, 56, 170, 156,
+ 123, 55, 255, 217, 147, 175, 151, 251, 157, 141, 238, 232, 75, 2, 104,
+ 33, 243, 244, 165, 113, 245, 181, 145, 54, 169, 205, 234, 227, 106, 202,
+ 237, 23, 239, 24, 24, 245, 216, 109, 207, 179, 177, 67, 24, 251, 55,
+ 32, 31, 69, 95, 78, 61, 181, 48, 42, 229, 211, 86, 61, 249, 202,
+ 122, 105, 167, 60, 7, 55, 79, 191, 21, 69, 178, 119, 167, 131, 49,
+ 246, 88, 80, 158, 98, 14, 118, 205, 249, 67, 110, 139, 116, 197, 205,
+ 27, 78, 54, 238, 171, 156, 131, 61, 104, 239, 99, 80, 126, 237, 205,
+ 154, 59, 231, 128, 244, 194, 61, 7, 43, 90, 14, 61, 234, 174, 71,
+ 186, 225, 230, 183, 213, 157, 247, 134, 18, 47, 191, 118, 38, 95, 231,
+ 241, 10, 89, 142, 204, 175, 22, 65, 122, 196, 159, 251, 140, 93, 34,
+ 219, 228, 141, 55, 124, 162, 122, 189, 207, 122, 186, 211, 75, 49, 111,
+ 175, 130, 190, 84, 204, 95, 113, 108, 116, 212, 12, 105, 158, 198, 142,
+ 157, 47, 143, 233, 229, 220, 237, 81, 81, 138, 118, 107, 98, 12, 129,
+ 160, 113, 138, 249, 155, 216, 245, 61, 121, 206, 72, 151, 221, 188, 179,
+ 89, 141, 190, 74, 185, 205, 197, 188, 189, 12, 250, 76, 49, 127, 242,
+ 111, 134, 192, 166, 200, 126, 225, 201, 203, 106, 255, 85, 149, 217, 151,
+ 94, 229, 214, 131, 143, 219, 190, 196, 93, 86, 23, 76, 185, 124, 223,
+ 184, 132, 202, 201, 246, 37, 206, 179, 22, 3, 167, 92, 126, 96, 113,
+ 137, 191, 162, 13, 234, 83, 129, 212, 142, 107, 242, 229, 7, 22, 151,
+ 16, 110, 57, 251, 34, 181, 17, 253, 159, 218, 248, 111, 113, 9, 205,
+ 137, 55, 126, 191, 51, 187, 8, 218, 87, 241, 126, 206, 228, 7, 139,
+ 23, 253, 128, 240, 228, 152, 225, 73, 143, 254, 21, 78, 188, 172, 38,
+ 125, 172, 168, 127, 189, 43, 245, 111, 101, 147, 46, 171, 137, 244, 97,
+ 31, 189, 81, 248, 193, 180, 190, 47, 233, 222, 61, 90, 250, 217, 236,
+ 10, 49, 3, 149, 169, 44, 102, 8, 156, 84, 153, 220, 104, 205, 13,
+ 193, 250, 241, 59, 70, 169, 145, 81, 53, 165, 152, 65, 197, 42, 123,
+ 129, 218, 29, 51, 16, 150, 59, 102, 248, 117, 220, 202, 163, 31, 60,
+ 19, 19, 117, 231, 189, 168, 231, 179, 114, 163, 108, 150, 144, 163, 158,
+ 121, 121, 218, 167, 11, 203, 128, 37, 25, 236, 121, 206, 153, 80, 171,
+ 239, 91, 3, 79, 72, 101, 60, 253, 56, 242, 232, 162, 190, 127, 183,
+ 234, 127, 204, 93, 183, 136, 61, 130, 250, 77, 84, 249, 181, 59, 87,
+ 152, 83, 154, 71, 63, 197, 120, 105, 142, 43, 204, 41, 253, 48, 99,
+ 37, 115, 26, 136, 186, 68, 73, 73, 117, 223, 56, 245, 222, 151, 81,
+ 115, 92, 239, 148, 204, 113, 109, 168, 16, 51, 80, 153, 202, 230, 52,
+ 127, 194, 221, 230, 244, 100, 212, 67, 159, 182, 14, 19, 99, 134, 58,
+ 119, 141, 195, 168, 140, 123, 78, 9, 203, 61, 167, 71, 91, 212, 61,
+ 42, 214, 23, 241, 220, 124, 151, 162, 91, 145, 158, 124, 81, 215, 218,
+ 195, 190, 154, 21, 54, 182, 251, 168, 69, 10, 191, 120, 82, 230, 47,
+ 204, 175, 81, 206, 87, 156, 96, 70, 86, 71, 101, 228, 24, 110, 121,
+ 140, 31, 201, 216, 57, 194, 29, 119, 89, 221, 179, 82, 189, 103, 108,
+ 252, 200, 241, 102, 107, 154, 190, 66, 254, 125, 55, 223, 149, 206, 147,
+ 39, 142, 112, 231, 157, 122, 175, 105, 228, 255, 0, 34, 173, 65, 75,
+ 36, 123, 0, 255, 197, 196, 50, 70, 35, 43, 139, 189, 172, 126, 212,
+ 189, 127, 77, 43, 47, 227, 152, 88, 147, 33, 219, 46, 221, 247, 177,
+ 228, 192, 9, 103, 219, 69, 157, 242, 151, 203, 104, 164, 186, 129, 152,
+ 199, 210, 81, 240, 51, 163, 69, 162, 200, 142, 168, 195, 143, 122, 223,
+ 219, 248, 207, 237, 92, 72, 7, 26, 72, 229, 27, 184, 239, 159, 140,
+ 21, 219, 181, 160, 126, 23, 156, 237, 125, 205, 38, 119, 57, 186, 230,
+ 46, 183, 28, 60, 213, 243, 71, 185, 230, 20, 111, 27, 172, 93, 221,
+ 229, 150, 43, 202, 69, 128, 167, 122, 5, 177, 146, 175, 200, 191, 170,
+ 118, 151, 139, 80, 148, 187, 16, 115, 89, 77, 245, 10, 163, 47, 171,
+ 123, 73, 114, 117, 151, 163, 107, 238, 114, 5, 224, 169, 158, 37, 90,
+ 196, 43, 240, 187, 46, 227, 21, 40, 202, 69, 131, 167, 122, 133, 102,
+ 248, 78, 242, 237, 58, 15, 94, 180, 162, 28, 3, 79, 245, 162, 205,
+ 226, 90, 75, 31, 144, 102, 118, 151, 99, 138, 114, 133, 99, 80, 6,
+ 233, 50, 211, 101, 181, 192, 241, 18, 237, 238, 114, 116, 205, 93, 46,
+ 30, 60, 213, 179, 160, 92, 232, 29, 227, 136, 87, 148, 243, 3, 79,
+ 245, 2, 165, 113, 216, 141, 153, 6, 119, 57, 63, 69, 57, 23, 228,
+ 71, 245, 252, 129, 71, 119, 145, 202, 246, 223, 144, 199, 75, 215, 220,
+ 229, 44, 224, 169, 158, 43, 93, 92, 207, 86, 131, 65, 150, 155, 69,
+ 81, 142, 244, 129, 234, 229, 167, 139, 237, 234, 236, 102, 171, 187, 156,
+ 191, 162, 28, 233, 15, 213, 11, 76, 23, 245, 39, 3, 5, 221, 229,
+ 232, 90, 3, 165, 143, 70, 185, 11, 146, 190, 54, 104, 249, 23, 239,
+ 95, 160, 164, 67, 110, 187, 151, 104, 54, 217, 173, 230, 52, 168, 137,
+ 127, 184, 255, 64, 93, 186, 97, 152, 57, 217, 152, 216, 53, 217, 96,
+ 239, 155, 97, 181, 26, 76, 164, 103, 82, 129, 14, 29, 217, 53, 142,
+ 65, 154, 237, 175, 192, 48, 39, 76, 53, 36, 218, 81, 223, 3, 70,
+ 0, 35, 179, 76, 188, 18, 159, 103, 30, 107, 199, 122, 234, 176, 70,
+ 183, 60, 191, 211, 27, 237, 201, 55, 38, 249, 119, 48, 153, 237, 254,
+ 34, 102, 87, 163, 62, 205, 96, 55, 166, 27, 252, 195, 252, 3, 59,
+ 250, 235, 76, 122, 255, 14, 21, 175, 116, 15, 236, 216, 135, 5, 121,
+ 218, 177, 40, 240, 152, 164, 135, 180, 187, 39, 157, 115, 231, 183, 174,
+ 153, 102, 48, 37, 219, 83, 208, 107, 163, 201, 222, 161, 220, 200, 71,
+ 163, 29, 51, 41, 156, 206, 222, 161, 163, 127, 128, 127, 183, 238, 29,
+ 253, 59, 249, 119, 231, 248, 157, 73, 79, 21, 56, 164, 111, 36, 3,
+ 235, 48, 163, 173, 226, 20, 68, 74, 23, 109, 52, 13, 188, 62, 25,
+ 40, 210, 213, 10, 245, 255, 75, 71, 208, 229, 14, 202, 246, 58, 118,
+ 100, 242, 61, 74, 37, 166, 7, 68, 167, 215, 147, 109, 202, 52, 184,
+ 123, 82, 174, 126, 87, 139, 217, 34, 103, 116, 236, 236, 31, 212, 81,
+ 158, 195, 64, 229, 28, 214, 172, 57, 144, 242, 233, 142, 172, 191, 178,
+ 157, 36, 116, 27, 213, 209, 113, 127, 37, 108, 31, 198, 124, 169, 124,
+ 7, 90, 11, 233, 138, 242, 247, 235, 88, 103, 8, 153, 121, 228, 152,
+ 175, 168, 203, 126, 183, 112, 204, 198, 212, 55, 37, 230, 157, 234, 16,
+ 238, 223, 165, 107, 47, 15, 134, 91, 255, 57, 6, 214, 158, 219, 166,
+ 147, 29, 127, 84, 25, 79, 197, 122, 236, 122, 76, 172, 197, 106, 78,
+ 182, 26, 108, 54, 110, 209, 249, 127, 134, 236, 202, 109, 58, 3, 78,
+ 160, 17, 235, 86, 34, 249, 94, 193, 175, 149, 219, 116, 42, 47, 219,
+ 174, 84, 177, 124, 105, 138, 104, 211, 7, 140, 238, 223, 95, 182, 93,
+ 169, 10, 219, 69, 229, 80, 207, 130, 114, 237, 72, 119, 109, 25, 9,
+ 178, 237, 82, 148, 243, 3, 79, 245, 2, 83, 68, 92, 37, 158, 159,
+ 162, 156, 107, 42, 108, 23, 210, 101, 201, 151, 213, 244, 180, 160, 215,
+ 142, 243, 30, 219, 53, 85, 97, 187, 192, 83, 189, 124, 148, 107, 195,
+ 202, 143, 195, 162, 40, 231, 15, 158, 234, 249, 163, 92, 39, 242, 51,
+ 71, 254, 146, 241, 252, 21, 229, 74, 49, 63, 84, 207, 149, 116, 89,
+ 221, 146, 48, 166, 37, 200, 120, 116, 205, 93, 142, 230, 145, 234, 69,
+ 160, 92, 228, 29, 237, 230, 43, 202, 209, 188, 83, 189, 50, 195, 101,
+ 53, 173, 203, 252, 79, 47, 202, 237, 6, 26, 203, 219, 66, 170, 87,
+ 96, 16, 231, 197, 208, 145, 245, 119, 219, 194, 210, 20, 111, 109, 161,
+ 216, 39, 210, 113, 139, 2, 35, 221, 150, 108, 51, 152, 108, 124, 61,
+ 151, 183, 5, 99, 120, 54, 44, 193, 164, 192, 201, 30, 253, 12, 84,
+ 212, 101, 9, 105, 6, 247, 58, 35, 217, 40, 108, 162, 12, 219, 213,
+ 104, 139, 54, 219, 140, 180, 114, 58, 192, 234, 245, 113, 247, 33, 95,
+ 81, 190, 166, 91, 125, 19, 116, 214, 187, 90, 101, 51, 147, 237, 153,
+ 191, 178, 174, 209, 98, 86, 152, 164, 187, 154, 51, 26, 4, 213, 39,
+ 189, 32, 121, 202, 245, 211, 209, 174, 46, 217, 96, 67, 101, 79, 167,
+ 81, 55, 202, 172, 55, 26, 200, 14, 218, 184, 191, 234, 71, 113, 70,
+ 82, 229, 125, 238, 234, 230, 129, 97, 200, 212, 165, 117, 112, 99, 78,
+ 34, 3, 232, 78, 116, 244, 239, 226, 31, 52, 153, 204, 98, 80, 96,
+ 96, 215, 64, 22, 18, 236, 150, 105, 153, 225, 63, 218, 66, 197, 88,
+ 185, 241, 243, 23, 49, 184, 175, 50, 40, 237, 223, 64, 93, 228, 104,
+ 233, 158, 36, 242, 103, 223, 37, 22, 142, 28, 29, 105, 77, 215, 217,
+ 51, 172, 6, 86, 249, 189, 228, 68, 96, 38, 122, 108, 68, 141, 74,
+ 246, 83, 231, 84, 98, 185, 167, 42, 105, 163, 44, 30, 58, 236, 139,
+ 53, 100, 72, 203, 52, 218, 238, 30, 183, 6, 238, 90, 223, 54, 117,
+ 109, 168, 179, 179, 230, 82, 120, 209, 245, 70, 33, 174, 83, 59, 157,
+ 29, 213, 159, 134, 127, 119, 107, 110, 136, 191, 34, 214, 174, 62, 192,
+ 207, 57, 99, 90, 71, 231, 160, 128, 117, 65, 119, 143, 197, 239, 164,
+ 251, 197, 240, 255, 61, 175, 124, 251, 119, 195, 255, 95, 242, 64, 249,
+ 141, 118, 172, 90, 180, 112, 135, 152, 213, 104, 7, 255, 182, 123, 119,
+ 173, 246, 92, 140, 51, 223, 219, 182, 232, 102, 189, 246, 238, 250, 183,
+ 111, 117, 22, 244, 183, 106, 57, 207, 245, 154, 114, 128, 255, 142, 109,
+ 241, 123, 197, 11, 206, 230, 57, 247, 77, 29, 200, 31, 70, 129, 231,
+ 121, 241, 185, 81, 7, 40, 189, 31, 249, 224, 67, 220, 245, 231, 247,
+ 170, 227, 200, 62, 214, 199, 57, 57, 250, 153, 32, 69, 125, 65, 81,
+ 223, 73, 121, 58, 94, 135, 49, 202, 215, 113, 44, 177, 254, 219, 153,
+ 198, 146, 155, 69, 95, 56, 116, 51, 23, 239, 119, 223, 47, 38, 249,
+ 147, 156, 221, 242, 47, 104, 36, 233, 11, 233, 77, 115, 145, 146, 12,
+ 233, 25, 86, 254, 219, 207, 149, 75, 225, 169, 179, 173, 28, 134, 195,
+ 9, 66, 187, 227, 9, 206, 55, 162, 38, 10, 79, 47, 109, 20, 177,
+ 224, 239, 9, 66, 255, 87, 94, 20, 252, 203, 201, 247, 191, 236, 197,
+ 60, 148, 117, 37, 79, 200, 91, 63, 35, 44, 119, 216, 150, 208, 58,
+ 3, 87, 85, 248, 38, 241, 173, 27, 121, 66, 236, 191, 77, 67, 115,
+ 94, 107, 198, 127, 83, 248, 252, 130, 154, 69, 127, 148, 229, 9, 223,
+ 110, 255, 151, 239, 81, 47, 125, 218, 60, 108, 124, 206, 191, 197, 53,
+ 190, 201, 187, 171, 252, 124, 74, 134, 5, 46, 174, 111, 32, 55, 199,
+ 172, 151, 230, 132, 220, 190, 157, 39, 60, 110, 122, 101, 59, 165, 111,
+ 172, 183, 108, 63, 189, 108, 117, 59, 119, 223, 173, 243, 253, 156, 147,
+ 158, 232, 232, 12, 88, 184, 52, 152, 255, 78, 242, 247, 121, 194, 251,
+ 207, 125, 23, 186, 183, 245, 31, 188, 253, 53, 174, 79, 138, 82, 175,
+ 229, 9, 91, 34, 196, 191, 91, 58, 229, 244, 31, 97, 117, 235, 13,
+ 45, 30, 247, 173, 216, 254, 204, 97, 29, 132, 195, 25, 53, 156, 151,
+ 126, 47, 45, 166, 250, 41, 231, 91, 11, 179, 98, 250, 58, 223, 233,
+ 126, 144, 63, 119, 157, 25, 211, 87, 72, 78, 107, 46, 68, 119, 22,
+ 248, 223, 65, 14, 236, 113, 48, 188, 119, 103, 65, 123, 107, 230, 116,
+ 241, 91, 132, 209, 117, 157, 181, 107, 175, 112, 54, 254, 253, 49, 39,
+ 127, 231, 72, 219, 90, 248, 167, 67, 63, 33, 76, 250, 221, 215, 87,
+ 127, 136, 114, 234, 178, 155, 10, 13, 119, 79, 230, 223, 213, 168, 78,
+ 93, 8, 47, 252, 123, 136, 227, 209, 166, 57, 188, 254, 233, 189, 58,
+ 109, 205, 164, 63, 181, 36, 35, 165, 252, 73, 198, 119, 174, 127, 210,
+ 137, 178, 199, 69, 178, 27, 19, 140, 186, 123, 200, 127, 212, 190, 20,
+ 167, 50, 61, 200, 254, 137, 243, 85, 91, 35, 87, 201, 71, 26, 109,
+ 96, 21, 228, 95, 107, 82, 158, 80, 20, 147, 20, 246, 89, 221, 209,
+ 225, 241, 45, 34, 42, 252, 14, 245, 111, 243, 102, 9, 207, 238, 45,
+ 46, 249, 163, 207, 199, 252, 218, 242, 117, 71, 195, 143, 28, 207, 21,
+ 26, 143, 119, 240, 249, 127, 248, 227, 247, 195, 223, 92, 93, 189, 36,
+ 126, 73, 110, 165, 242, 127, 21, 178, 122, 161, 109, 92, 88, 64, 73,
+ 71, 254, 119, 16, 142, 55, 138, 43, 254, 22, 121, 79, 157, 121, 129,
+ 235, 90, 241, 199, 1, 161, 191, 133, 108, 57, 82, 44, 221, 51, 182,
+ 65, 254, 19, 32, 255, 67, 171, 79, 115, 249, 231, 159, 201, 21, 190,
+ 251, 250, 195, 226, 243, 175, 23, 241, 249, 47, 219, 114, 61, 172, 235,
+ 220, 60, 97, 93, 196, 68, 222, 159, 212, 85, 135, 75, 166, 59, 245,
+ 225, 27, 150, 138, 237, 151, 254, 222, 93, 120, 234, 201, 64, 231, 245,
+ 23, 63, 210, 82, 253, 219, 39, 78, 59, 110, 142, 159, 171, 61, 49,
+ 35, 142, 95, 247, 141, 157, 235, 200, 251, 217, 230, 188, 101, 111, 205,
+ 229, 247, 22, 242, 27, 102, 180, 118, 104, 174, 159, 229, 233, 216, 189,
+ 7, 157, 135, 178, 7, 70, 244, 8, 201, 228, 243, 243, 126, 219, 219,
+ 142, 47, 141, 67, 29, 1, 181, 196, 191, 27, 86, 54, 37, 91, 91,
+ 52, 53, 203, 25, 187, 122, 55, 111, 255, 135, 71, 199, 10, 27, 54,
+ 180, 211, 46, 126, 94, 252, 27, 133, 243, 71, 158, 112, 142, 207, 186,
+ 40, 60, 252, 204, 158, 114, 242, 39, 25, 87, 176, 255, 208, 9, 87,
+ 19, 145, 236, 58, 171, 45, 195, 118, 119, 5, 120, 183, 172, 188, 108,
+ 51, 191, 73, 20, 246, 143, 252, 218, 17, 252, 79, 161, 179, 42, 242,
+ 127, 228, 201, 92, 225, 211, 14, 223, 133, 31, 249, 243, 163, 226, 78,
+ 105, 5, 21, 190, 89, 189, 188, 45, 79, 88, 217, 239, 233, 208, 252,
+ 155, 99, 249, 252, 31, 109, 63, 179, 120, 205, 123, 57, 194, 212, 140,
+ 56, 62, 95, 151, 59, 13, 47, 89, 127, 45, 206, 113, 58, 59, 167,
+ 82, 249, 127, 254, 111, 158, 16, 242, 113, 199, 176, 192, 182, 226, 223,
+ 53, 15, 110, 31, 80, 124, 10, 121, 227, 15, 175, 228, 233, 238, 91,
+ 150, 134, 78, 237, 190, 58, 244, 208, 45, 81, 254, 118, 200, 255, 73,
+ 200, 63, 215, 62, 128, 219, 228, 169, 103, 103, 9, 62, 207, 44, 60,
+ 242, 203, 0, 53, 95, 175, 103, 38, 143, 236, 243, 41, 116, 37, 39,
+ 189, 6, 175, 111, 30, 168, 214, 142, 59, 194, 66, 71, 160, 28, 165,
+ 243, 98, 125, 4, 253, 194, 199, 157, 77, 62, 248, 52, 156, 234, 127,
+ 220, 249, 159, 162, 134, 183, 102, 57, 35, 231, 222, 230, 253, 111, 124,
+ 107, 150, 208, 107, 75, 81, 241, 184, 173, 255, 114, 249, 69, 35, 127,
+ 228, 214, 127, 195, 147, 107, 205, 20, 255, 78, 96, 239, 1, 218, 14,
+ 167, 223, 118, 46, 233, 16, 192, 215, 127, 191, 143, 27, 133, 205, 169,
+ 155, 43, 188, 215, 238, 95, 94, 127, 234, 159, 89, 206, 233, 77, 247,
+ 21, 23, 53, 201, 21, 191, 171, 251, 33, 87, 251, 231, 197, 43, 37,
+ 89, 183, 197, 111, 117, 246, 236, 141, 117, 198, 214, 154, 234, 140, 30,
+ 188, 180, 156, 252, 73, 198, 21, 214, 255, 227, 158, 184, 33, 221, 96,
+ 215, 221, 75, 7, 198, 76, 31, 95, 206, 54, 135, 60, 187, 175, 232,
+ 106, 114, 154, 112, 173, 112, 227, 225, 170, 200, 63, 246, 143, 60, 225,
+ 192, 183, 142, 176, 159, 230, 158, 61, 242, 244, 250, 205, 21, 254, 246,
+ 252, 98, 216, 127, 237, 185, 230, 197, 91, 142, 61, 201, 117, 227, 227,
+ 46, 77, 195, 62, 120, 53, 79, 248, 237, 7, 45, 159, 143, 207, 90,
+ 79, 47, 218, 229, 212, 150, 164, 30, 174, 220, 254, 175, 2, 126, 135,
+ 178, 162, 176, 173, 143, 28, 231, 216, 171, 125, 138, 139, 179, 254, 204,
+ 19, 222, 60, 216, 139, 167, 63, 251, 245, 104, 232, 143, 7, 34, 67,
+ 151, 42, 228, 63, 25, 242, 143, 121, 242, 5, 46, 127, 225, 209, 153,
+ 66, 167, 201, 47, 21, 13, 153, 28, 204, 229, 63, 122, 194, 142, 208,
+ 166, 144, 191, 186, 78, 62, 255, 219, 214, 53, 167, 4, 107, 223, 250,
+ 119, 93, 175, 230, 13, 69, 249, 189, 122, 235, 71, 237, 135, 73, 205,
+ 157, 154, 109, 245, 74, 168, 126, 157, 78, 147, 138, 223, 184, 62, 203,
+ 185, 59, 70, 148, 255, 209, 235, 179, 132, 126, 97, 103, 139, 127, 188,
+ 122, 141, 203, 255, 125, 228, 159, 186, 122, 45, 252, 237, 250, 98, 253,
+ 29, 13, 67, 180, 7, 79, 142, 114, 77, 13, 20, 229, 111, 99, 113,
+ 97, 181, 110, 207, 18, 52, 61, 111, 137, 223, 223, 23, 218, 157, 155,
+ 126, 113, 21, 31, 243, 21, 191, 213, 28, 56, 113, 173, 54, 171, 221,
+ 191, 37, 191, 21, 138, 223, 88, 69, 47, 110, 225, 10, 180, 219, 156,
+ 173, 6, 191, 89, 78, 254, 228, 243, 101, 255, 143, 120, 143, 108, 63,
+ 249, 255, 252, 71, 69, 74, 203, 72, 71, 148, 124, 119, 233, 149, 212,
+ 83, 239, 223, 51, 254, 160, 176, 114, 197, 51, 206, 153, 191, 6, 29,
+ 200, 107, 60, 34, 98, 241, 212, 83, 66, 88, 244, 187, 7, 170, 226,
+ 255, 87, 118, 158, 42, 124, 25, 215, 36, 120, 193, 184, 25, 129, 127,
+ 127, 253, 190, 227, 206, 90, 213, 83, 59, 11, 63, 246, 9, 119, 246,
+ 220, 211, 152, 63, 195, 5, 47, 80, 222, 188, 191, 159, 230, 207, 122,
+ 89, 146, 99, 95, 243, 109, 43, 247, 223, 43, 126, 171, 138, 255, 175,
+ 38, 181, 255, 113, 168, 150, 199, 107, 63, 160, 125, 202, 91, 60, 198,
+ 143, 167, 55, 189, 63, 53, 228, 231, 109, 93, 228, 246, 143, 109, 174,
+ 237, 124, 111, 167, 221, 241, 89, 255, 65, 60, 239, 37, 75, 77, 33,
+ 228, 250, 120, 231, 230, 106, 223, 240, 254, 6, 95, 31, 207, 243, 28,
+ 189, 135, 240, 250, 43, 144, 239, 236, 61, 68, 142, 255, 190, 14, 95,
+ 237, 252, 66, 55, 207, 153, 241, 115, 79, 158, 183, 188, 199, 76, 33,
+ 105, 250, 19, 218, 41, 111, 126, 199, 199, 15, 222, 65, 121, 95, 108,
+ 94, 202, 227, 63, 87, 35, 255, 144, 87, 63, 153, 45, 199, 127, 35,
+ 62, 255, 72, 27, 109, 202, 21, 126, 202, 157, 93, 46, 254, 35, 25,
+ 223, 185, 254, 73, 39, 226, 31, 193, 158, 184, 37, 236, 127, 138, 217,
+ 170, 203, 190, 187, 244, 156, 198, 191, 130, 149, 233, 182, 157, 71, 185,
+ 242, 190, 31, 37, 36, 58, 84, 221, 170, 178, 254, 247, 27, 115, 133,
+ 143, 191, 53, 5, 182, 60, 250, 217, 62, 195, 254, 31, 42, 248, 255,
+ 15, 95, 206, 17, 52, 131, 19, 28, 66, 227, 24, 241, 217, 254, 224,
+ 4, 45, 229, 253, 213, 104, 60, 223, 95, 92, 41, 154, 184, 223, 47,
+ 105, 255, 222, 123, 201, 191, 237, 158, 181, 251, 191, 217, 247, 12, 151,
+ 255, 51, 127, 157, 15, 185, 5, 249, 151, 188, 60, 142, 199, 243, 7,
+ 223, 89, 221, 62, 99, 211, 79, 219, 220, 245, 237, 119, 200, 127, 215,
+ 158, 27, 218, 144, 29, 83, 156, 95, 204, 24, 207, 229, 21, 188, 99,
+ 138, 176, 3, 121, 143, 221, 28, 198, 211, 175, 69, 47, 13, 105, 156,
+ 191, 91, 150, 127, 55, 253, 81, 231, 130, 103, 91, 151, 172, 47, 88,
+ 201, 235, 151, 212, 10, 116, 62, 246, 85, 111, 103, 151, 199, 167, 112,
+ 121, 53, 249, 170, 55, 207, 251, 163, 145, 147, 203, 179, 3, 242, 47,
+ 53, 114, 6, 187, 235, 127, 174, 95, 234, 234, 49, 244, 185, 240, 131,
+ 97, 237, 185, 252, 23, 45, 92, 163, 93, 112, 198, 46, 212, 206, 154,
+ 44, 198, 255, 103, 236, 78, 202, 91, 59, 253, 77, 158, 238, 188, 114,
+ 99, 200, 191, 131, 183, 202, 242, 63, 211, 178, 129, 163, 125, 215, 121,
+ 17, 227, 132, 241, 221, 148, 242, 39, 57, 187, 229, 239, 234, 40, 218,
+ 125, 210, 137, 136, 122, 34, 233, 236, 105, 186, 123, 108, 255, 216, 83,
+ 155, 26, 29, 80, 166, 187, 12, 91, 44, 52, 125, 183, 179, 179, 253,
+ 137, 54, 251, 171, 34, 255, 146, 183, 146, 133, 192, 234, 170, 160, 245,
+ 151, 158, 219, 31, 158, 80, 241, 239, 101, 183, 63, 216, 90, 136, 252,
+ 176, 159, 144, 180, 187, 17, 31, 47, 120, 103, 7, 228, 229, 71, 140,
+ 229, 243, 103, 186, 94, 243, 64, 89, 141, 109, 247, 92, 255, 243, 158,
+ 154, 127, 32, 105, 72, 14, 223, 175, 253, 118, 244, 26, 151, 255, 180,
+ 35, 121, 92, 254, 143, 143, 89, 214, 254, 177, 160, 239, 183, 187, 235,
+ 103, 72, 246, 223, 45, 255, 224, 171, 51, 132, 53, 55, 187, 57, 222,
+ 188, 50, 128, 183, 183, 238, 102, 55, 109, 8, 242, 22, 22, 205, 221,
+ 71, 233, 15, 150, 143, 12, 62, 19, 122, 49, 80, 126, 111, 229, 208,
+ 111, 194, 194, 183, 163, 35, 150, 111, 28, 192, 231, 191, 218, 202, 233,
+ 194, 198, 183, 70, 57, 90, 14, 12, 226, 250, 10, 94, 75, 121, 125,
+ 30, 58, 195, 241, 26, 15, 8, 10, 138, 124, 232, 140, 44, 255, 190,
+ 79, 190, 24, 177, 167, 186, 143, 235, 250, 121, 235, 65, 254, 27, 103,
+ 63, 229, 9, 199, 159, 253, 61, 108, 105, 245, 54, 188, 252, 158, 103,
+ 127, 47, 110, 129, 188, 203, 23, 222, 230, 235, 97, 196, 188, 39, 130,
+ 243, 102, 191, 37, 143, 63, 108, 246, 120, 87, 183, 221, 219, 34, 102,
+ 173, 168, 209, 93, 41, 127, 146, 241, 157, 235, 159, 116, 130, 117, 133,
+ 47, 232, 116, 89, 157, 104, 213, 153, 140, 25, 233, 119, 149, 222, 199,
+ 95, 110, 47, 183, 254, 87, 92, 171, 235, 154, 122, 161, 141, 163, 81,
+ 204, 233, 144, 160, 42, 200, 191, 65, 96, 174, 240, 237, 41, 159, 32,
+ 117, 215, 87, 246, 173, 139, 248, 187, 194, 250, 255, 225, 68, 182, 112,
+ 124, 254, 52, 199, 240, 135, 219, 242, 246, 193, 107, 41, 111, 83, 248,
+ 30, 222, 108, 234, 39, 221, 246, 63, 123, 173, 219, 190, 123, 201, 255,
+ 236, 69, 159, 131, 61, 95, 81, 117, 224, 254, 243, 171, 91, 92, 254,
+ 57, 230, 28, 46, 255, 14, 215, 78, 181, 27, 21, 249, 240, 54, 165,
+ 252, 167, 64, 254, 237, 37, 249, 251, 6, 78, 21, 6, 190, 255, 190,
+ 99, 97, 193, 87, 124, 254, 7, 191, 255, 190, 182, 6, 242, 22, 12,
+ 136, 230, 233, 254, 63, 254, 29, 60, 224, 157, 126, 178, 252, 141, 49,
+ 105, 194, 213, 205, 190, 17, 99, 206, 104, 184, 252, 227, 119, 46, 118,
+ 76, 109, 151, 233, 28, 58, 74, 199, 245, 23, 188, 160, 67, 222, 47,
+ 255, 116, 228, 235, 169, 43, 242, 235, 95, 234, 40, 219, 255, 228, 220,
+ 116, 215, 75, 189, 55, 185, 244, 225, 111, 242, 188, 63, 38, 212, 214,
+ 62, 181, 102, 150, 176, 117, 233, 112, 94, 31, 188, 243, 119, 228, 77,
+ 12, 88, 193, 211, 19, 95, 125, 42, 228, 81, 163, 77, 94, 255, 221,
+ 191, 153, 224, 250, 233, 179, 247, 35, 234, 236, 243, 43, 39, 127, 146,
+ 179, 91, 254, 36, 111, 254, 96, 179, 158, 39, 254, 51, 232, 238, 181,
+ 251, 135, 93, 58, 107, 117, 142, 239, 151, 42, 248, 133, 62, 234, 26,
+ 54, 113, 154, 246, 242, 51, 231, 132, 13, 213, 159, 117, 77, 157, 60,
+ 188, 74, 251, 127, 253, 190, 9, 130, 163, 251, 92, 173, 235, 72, 92,
+ 88, 239, 173, 191, 87, 88, 255, 29, 227, 27, 8, 45, 198, 14, 22,
+ 222, 95, 57, 145, 95, 59, 126, 184, 191, 179, 120, 23, 98, 172, 168,
+ 95, 120, 122, 90, 189, 167, 181, 95, 78, 251, 194, 113, 250, 216, 228,
+ 74, 229, 79, 190, 222, 241, 250, 207, 7, 146, 230, 95, 228, 235, 191,
+ 52, 183, 54, 151, 255, 63, 239, 214, 221, 201, 159, 81, 175, 63, 187,
+ 61, 186, 197, 107, 173, 220, 125, 207, 148, 226, 255, 118, 146, 252, 135,
+ 180, 15, 22, 186, 133, 191, 167, 205, 252, 70, 252, 221, 133, 191, 67,
+ 46, 58, 182, 172, 209, 9, 218, 113, 173, 74, 196, 87, 163, 31, 114,
+ 198, 254, 246, 148, 35, 189, 241, 112, 209, 254, 206, 243, 143, 232, 209,
+ 184, 44, 98, 212, 154, 212, 8, 170, 191, 239, 100, 83, 225, 208, 250,
+ 65, 194, 178, 154, 103, 120, 249, 215, 215, 15, 114, 30, 89, 241, 168,
+ 16, 17, 23, 203, 99, 157, 213, 200, 143, 140, 139, 213, 214, 122, 59,
+ 155, 215, 95, 180, 241, 104, 68, 151, 209, 93, 35, 6, 60, 218, 219,
+ 65, 245, 59, 52, 157, 40, 156, 248, 250, 140, 227, 131, 1, 5, 124,
+ 188, 113, 253, 90, 104, 95, 105, 52, 64, 40, 12, 18, 255, 22, 251,
+ 200, 75, 183, 29, 115, 254, 248, 203, 177, 126, 134, 248, 219, 38, 193,
+ 215, 135, 186, 218, 174, 58, 27, 97, 131, 140, 202, 237, 255, 58, 221,
+ 177, 254, 187, 138, 118, 95, 41, 127, 254, 117, 193, 93, 164, 183, 240,
+ 172, 85, 24, 35, 201, 191, 197, 196, 105, 142, 127, 32, 255, 141, 144,
+ 127, 167, 201, 195, 157, 85, 145, 255, 218, 135, 210, 132, 86, 101, 103,
+ 74, 142, 95, 111, 81, 210, 240, 72, 73, 5, 249, 255, 242, 91, 47,
+ 97, 110, 141, 32, 129, 125, 83, 196, 227, 245, 1, 103, 58, 59, 111,
+ 213, 237, 38, 108, 62, 150, 200, 231, 175, 40, 190, 137, 35, 121, 70,
+ 7, 109, 208, 154, 156, 255, 23, 249, 159, 242, 77, 17, 54, 140, 217,
+ 168, 93, 182, 120, 45, 111, 239, 235, 126, 91, 29, 251, 158, 183, 10,
+ 134, 79, 183, 243, 254, 204, 254, 105, 137, 118, 222, 140, 183, 195, 47,
+ 238, 17, 127, 239, 224, 243, 118, 195, 35, 142, 245, 63, 17, 241, 221,
+ 236, 175, 156, 110, 249, 67, 230, 66, 147, 154, 103, 194, 221, 242, 119,
+ 66, 254, 117, 33, 115, 73, 254, 225, 127, 79, 137, 117, 60, 44, 201,
+ 127, 161, 36, 255, 160, 6, 189, 185, 252, 108, 51, 199, 10, 223, 159,
+ 171, 229, 156, 230, 183, 137, 235, 143, 61, 242, 79, 237, 207, 67, 250,
+ 11, 195, 126, 252, 134, 247, 231, 237, 159, 214, 105, 83, 15, 239, 208,
+ 134, 189, 40, 254, 29, 245, 16, 73, 254, 87, 39, 76, 115, 148, 219,
+ 255, 117, 244, 200, 159, 226, 61, 178, 253, 228, 255, 11, 218, 139, 148,
+ 146, 145, 110, 176, 222, 227, 6, 192, 243, 75, 155, 105, 219, 212, 140,
+ 208, 126, 54, 251, 140, 227, 215, 69, 42, 33, 254, 212, 10, 103, 173,
+ 183, 222, 114, 54, 94, 212, 176, 74, 235, 255, 221, 14, 121, 194, 163,
+ 143, 116, 9, 63, 243, 73, 215, 146, 250, 182, 41, 21, 190, 77, 216,
+ 176, 116, 150, 240, 121, 204, 153, 240, 86, 187, 14, 241, 107, 67, 30,
+ 255, 169, 36, 113, 213, 44, 225, 140, 90, 252, 61, 180, 181, 95, 189,
+ 88, 50, 142, 189, 86, 210, 185, 125, 238, 255, 139, 255, 31, 16, 215,
+ 64, 88, 116, 100, 164, 51, 237, 134, 248, 183, 129, 198, 78, 142, 22,
+ 206, 235, 235, 11, 62, 215, 63, 228, 242, 184, 181, 189, 77, 248, 57,
+ 223, 43, 225, 109, 206, 137, 251, 127, 219, 95, 249, 206, 122, 199, 223,
+ 10, 79, 109, 92, 139, 183, 93, 237, 246, 59, 37, 127, 233, 115, 5,
+ 237, 195, 49, 188, 252, 69, 125, 174, 115, 217, 205, 15, 74, 86, 188,
+ 46, 240, 180, 6, 249, 167, 95, 23, 194, 159, 136, 23, 247, 159, 253,
+ 78, 36, 8, 231, 114, 95, 142, 24, 155, 213, 131, 235, 79, 205, 97,
+ 83, 156, 218, 171, 55, 28, 219, 236, 226, 223, 169, 9, 155, 119, 83,
+ 251, 240, 231, 147, 156, 53, 14, 85, 231, 250, 99, 76, 249, 169, 248,
+ 213, 143, 30, 210, 86, 91, 40, 182, 255, 246, 164, 62, 174, 134, 121,
+ 59, 34, 46, 44, 82, 149, 223, 255, 181, 175, 232, 255, 73, 39, 242,
+ 219, 138, 36, 255, 233, 191, 187, 72, 239, 155, 243, 189, 202, 173, 205,
+ 167, 223, 93, 34, 124, 121, 125, 155, 243, 165, 182, 230, 226, 170, 196,
+ 127, 113, 65, 86, 225, 151, 220, 212, 18, 77, 233, 185, 34, 207, 223,
+ 22, 245, 252, 231, 251, 207, 80, 33, 118, 211, 99, 194, 174, 176, 98,
+ 126, 255, 53, 237, 137, 199, 156, 155, 6, 15, 17, 190, 233, 243, 43,
+ 159, 191, 153, 173, 71, 148, 252, 56, 233, 147, 240, 31, 6, 86, 46,
+ 255, 193, 123, 243, 132, 179, 154, 161, 37, 87, 122, 55, 224, 247, 15,
+ 14, 223, 28, 18, 30, 134, 188, 165, 19, 58, 243, 116, 155, 181, 77,
+ 139, 122, 191, 211, 166, 104, 243, 237, 242, 247, 127, 154, 117, 152, 207,
+ 253, 239, 129, 134, 25, 194, 128, 177, 171, 28, 131, 227, 223, 227, 247,
+ 27, 99, 102, 172, 210, 14, 251, 118, 154, 112, 234, 84, 11, 190, 254,
+ 222, 61, 249, 74, 216, 141, 9, 254, 218, 196, 147, 226, 254, 125, 123,
+ 181, 233, 66, 204, 107, 197, 130, 240, 227, 215, 124, 253, 38, 159, 172,
+ 227, 220, 120, 114, 148, 243, 234, 149, 134, 188, 60, 120, 161, 245, 228,
+ 122, 206, 129, 97, 226, 119, 61, 223, 35, 127, 107, 216, 115, 37, 145,
+ 169, 98, 253, 239, 198, 244, 116, 125, 58, 236, 33, 215, 187, 87, 215,
+ 115, 249, 191, 17, 186, 222, 145, 219, 216, 40, 12, 104, 184, 138, 215,
+ 95, 222, 218, 230, 60, 214, 181, 192, 241, 237, 141, 218, 124, 62, 158,
+ 110, 118, 178, 164, 87, 226, 34, 237, 185, 96, 241, 254, 207, 224, 143,
+ 213, 174, 55, 246, 154, 34, 134, 44, 13, 43, 39, 127, 146, 113, 133,
+ 253, 31, 116, 34, 190, 181, 72, 137, 58, 171, 229, 94, 247, 255, 22,
+ 213, 74, 40, 247, 55, 253, 74, 130, 190, 42, 73, 77, 154, 44, 236,
+ 122, 101, 93, 81, 85, 228, 159, 154, 169, 19, 90, 255, 88, 219, 113,
+ 99, 196, 172, 146, 53, 223, 253, 84, 65, 254, 53, 62, 110, 40, 124,
+ 87, 58, 66, 248, 108, 158, 153, 183, 63, 250, 177, 1, 206, 26, 141,
+ 31, 22, 22, 205, 93, 207, 231, 163, 186, 159, 201, 177, 125, 184, 160,
+ 77, 157, 96, 175, 84, 254, 191, 221, 202, 19, 78, 207, 254, 179, 79,
+ 235, 81, 7, 185, 188, 63, 252, 229, 183, 35, 203, 144, 247, 221, 199,
+ 165, 220, 126, 63, 180, 239, 96, 209, 149, 167, 74, 67, 247, 222, 204,
+ 147, 215, 63, 237, 255, 38, 249, 110, 230, 235, 127, 238, 182, 1, 194,
+ 236, 204, 150, 194, 249, 159, 235, 115, 249, 191, 100, 110, 233, 28, 191,
+ 115, 128, 240, 183, 185, 63, 239, 207, 67, 243, 76, 197, 135, 250, 90,
+ 67, 55, 95, 117, 235, 207, 54, 237, 249, 157, 199, 34, 86, 175, 45,
+ 224, 242, 143, 107, 216, 222, 153, 51, 83, 235, 60, 236, 91, 159, 247,
+ 55, 123, 166, 86, 56, 29, 22, 224, 236, 149, 43, 254, 190, 228, 243,
+ 200, 223, 156, 59, 167, 100, 249, 231, 162, 252, 173, 51, 198, 186, 182,
+ 47, 156, 226, 186, 249, 236, 26, 46, 255, 157, 218, 28, 167, 16, 220,
+ 81, 251, 72, 96, 75, 94, 127, 199, 55, 254, 142, 219, 35, 102, 58,
+ 7, 21, 229, 115, 253, 223, 157, 215, 209, 241, 176, 238, 209, 18, 215,
+ 80, 177, 254, 197, 188, 169, 174, 105, 11, 135, 69, 216, 222, 235, 85,
+ 78, 254, 36, 227, 59, 229, 79, 58, 161, 188, 255, 119, 47, 29, 48,
+ 15, 105, 85, 46, 54, 111, 38, 172, 211, 94, 57, 244, 169, 54, 243,
+ 183, 86, 225, 85, 145, 255, 208, 244, 56, 97, 254, 38, 75, 201, 198,
+ 73, 133, 197, 197, 223, 92, 169, 32, 255, 236, 99, 190, 194, 134, 235,
+ 177, 194, 210, 199, 182, 240, 249, 110, 180, 119, 188, 243, 92, 104, 117,
+ 97, 254, 222, 27, 188, 63, 71, 166, 189, 81, 178, 121, 196, 142, 240,
+ 75, 183, 102, 85, 42, 255, 244, 75, 121, 194, 51, 126, 179, 194, 14,
+ 165, 54, 228, 242, 27, 53, 104, 102, 241, 232, 43, 121, 66, 219, 218,
+ 187, 185, 252, 183, 30, 105, 84, 252, 100, 226, 142, 208, 241, 55, 242,
+ 100, 255, 79, 242, 79, 110, 178, 147, 203, 127, 195, 19, 213, 29, 147,
+ 215, 205, 18, 84, 133, 226, 239, 252, 249, 174, 152, 229, 212, 135, 251,
+ 56, 246, 86, 143, 226, 237, 255, 58, 170, 83, 73, 220, 170, 222, 37,
+ 131, 231, 136, 245, 55, 60, 182, 209, 53, 242, 179, 235, 17, 93, 234,
+ 254, 197, 229, 223, 102, 255, 215, 37, 175, 255, 51, 203, 121, 113, 222,
+ 92, 94, 254, 240, 63, 179, 132, 78, 230, 159, 74, 34, 34, 211, 57,
+ 222, 5, 228, 15, 139, 76, 47, 137, 171, 33, 233, 207, 165, 25, 14,
+ 199, 234, 125, 174, 175, 98, 195, 185, 252, 15, 246, 204, 114, 110, 190,
+ 145, 238, 112, 245, 253, 131, 215, 255, 176, 87, 142, 246, 187, 192, 44,
+ 103, 108, 81, 17, 79, 107, 179, 95, 47, 153, 81, 243, 124, 201, 239,
+ 129, 226, 248, 219, 246, 181, 185, 236, 203, 31, 141, 24, 115, 34, 160,
+ 156, 252, 201, 231, 43, 229, 207, 109, 63, 252, 63, 171, 43, 146, 219,
+ 255, 223, 45, 6, 12, 92, 218, 204, 209, 14, 254, 255, 75, 248, 255,
+ 111, 23, 169, 156, 211, 225, 255, 175, 158, 120, 203, 121, 125, 97, 195,
+ 42, 197, 127, 111, 189, 158, 43, 188, 235, 95, 86, 124, 114, 113, 181,
+ 162, 63, 67, 222, 172, 176, 255, 203, 30, 54, 67, 216, 221, 180, 175,
+ 99, 109, 76, 99, 46, 191, 214, 227, 251, 106, 127, 249, 125, 186, 240,
+ 166, 113, 50, 47, 251, 227, 178, 141, 125, 54, 108, 138, 15, 143, 221,
+ 156, 247, 255, 226, 255, 19, 14, 63, 175, 221, 247, 156, 213, 25, 61,
+ 169, 39, 111, 239, 157, 247, 172, 194, 138, 118, 47, 104, 125, 30, 142,
+ 225, 250, 184, 163, 224, 179, 176, 30, 29, 154, 149, 148, 74, 247, 159,
+ 215, 143, 106, 237, 10, 142, 74, 114, 148, 254, 22, 199, 227, 175, 193,
+ 236, 221, 146, 63, 224, 255, 247, 213, 141, 225, 242, 254, 19, 254, 255,
+ 244, 173, 15, 74, 246, 189, 46, 254, 214, 104, 208, 195, 49, 225, 109,
+ 16, 11, 184, 253, 255, 212, 227, 9, 194, 69, 248, 255, 71, 178, 122,
+ 240, 190, 215, 184, 152, 237, 220, 253, 152, 222, 113, 114, 188, 248, 155,
+ 178, 195, 103, 79, 214, 142, 41, 203, 118, 118, 237, 116, 152, 247, 103,
+ 152, 121, 127, 120, 237, 185, 171, 75, 86, 79, 200, 45, 231, 255, 63,
+ 133, 140, 202, 237, 255, 234, 86, 92, 255, 164, 19, 101, 181, 68, 242,
+ 124, 94, 92, 185, 244, 126, 56, 223, 171, 220, 189, 217, 121, 240, 255,
+ 191, 193, 255, 191, 208, 198, 28, 86, 149, 245, 79, 191, 49, 64, 191,
+ 171, 64, 191, 133, 176, 71, 254, 253, 2, 197, 254, 47, 236, 25, 199,
+ 173, 173, 25, 194, 51, 123, 215, 240, 241, 183, 211, 88, 157, 246, 29,
+ 203, 28, 183, 124, 3, 184, 173, 136, 110, 215, 75, 251, 79, 179, 55,
+ 139, 115, 92, 51, 42, 149, 127, 14, 124, 253, 190, 189, 67, 74, 138,
+ 63, 13, 228, 235, 253, 88, 225, 144, 240, 125, 200, 235, 21, 250, 60,
+ 127, 9, 254, 155, 130, 39, 66, 187, 213, 254, 229, 245, 163, 119, 248,
+ 255, 230, 87, 231, 114, 255, 255, 254, 135, 163, 132, 184, 106, 245, 132,
+ 38, 250, 189, 188, 253, 147, 49, 245, 157, 41, 171, 71, 9, 173, 84,
+ 9, 60, 109, 110, 219, 162, 36, 242, 91, 87, 137, 207, 203, 226, 252,
+ 127, 60, 110, 174, 176, 117, 198, 178, 136, 192, 143, 252, 249, 250, 15,
+ 135, 255, 63, 12, 255, 127, 252, 74, 67, 222, 95, 240, 194, 213, 39,
+ 235, 57, 11, 224, 243, 249, 243, 7, 228, 79, 68, 44, 16, 37, 249,
+ 255, 195, 240, 255, 53, 134, 63, 228, 218, 113, 117, 61, 159, 31, 223,
+ 181, 233, 206, 88, 199, 94, 109, 171, 223, 31, 225, 245, 181, 194, 1,
+ 71, 187, 195, 102, 231, 228, 139, 199, 185, 254, 189, 173, 81, 107, 19,
+ 114, 215, 148, 76, 8, 23, 215, 255, 166, 38, 173, 92, 198, 171, 186,
+ 136, 172, 239, 58, 150, 147, 63, 201, 184, 194, 243, 63, 232, 132, 171,
+ 166, 72, 146, 237, 191, 171, 6, 188, 241, 80, 66, 185, 223, 248, 60,
+ 6, 255, 63, 13, 254, 63, 106, 239, 186, 208, 170, 200, 127, 78, 74,
+ 158, 48, 170, 254, 229, 176, 236, 232, 99, 71, 154, 172, 207, 169, 16,
+ 255, 107, 154, 228, 10, 89, 159, 92, 13, 183, 39, 126, 206, 253, 247,
+ 216, 144, 107, 37, 15, 109, 157, 37, 12, 60, 106, 231, 101, 179, 187,
+ 117, 235, 211, 82, 200, 44, 177, 46, 172, 124, 253, 239, 129, 175, 255,
+ 125, 73, 73, 159, 152, 132, 119, 184, 252, 155, 156, 124, 237, 200, 115,
+ 240, 245, 135, 254, 173, 193, 199, 51, 244, 196, 59, 161, 191, 159, 169,
+ 81, 108, 187, 225, 121, 254, 75, 235, 127, 89, 207, 5, 92, 254, 198,
+ 213, 225, 194, 165, 57, 157, 132, 214, 22, 241, 249, 227, 222, 191, 59,
+ 57, 63, 156, 31, 46, 52, 123, 237, 11, 94, 255, 197, 167, 118, 21,
+ 151, 196, 198, 151, 172, 88, 38, 214, 15, 233, 219, 69, 72, 101, 207,
+ 71, 212, 46, 91, 212, 155, 234, 247, 134, 255, 223, 8, 255, 191, 202,
+ 183, 62, 151, 31, 120, 225, 37, 248, 255, 2, 248, 124, 30, 131, 33,
+ 95, 143, 88, 96, 153, 228, 255, 135, 195, 255, 127, 7, 255, 95, 246,
+ 236, 26, 62, 63, 61, 45, 51, 157, 51, 119, 125, 22, 62, 127, 168,
+ 134, 215, 79, 202, 250, 172, 68, 181, 44, 215, 217, 242, 214, 21, 62,
+ 31, 1, 241, 26, 109, 143, 133, 111, 21, 117, 254, 78, 148, 191, 49,
+ 122, 144, 235, 214, 156, 43, 66, 164, 169, 91, 57, 249, 147, 140, 43,
+ 60, 255, 171, 85, 169, 255, 175, 84, 7, 94, 30, 210, 170, 156, 108,
+ 90, 194, 255, 255, 9, 255, 63, 250, 183, 86, 37, 85, 145, 127, 226,
+ 249, 4, 33, 187, 231, 248, 240, 210, 35, 89, 97, 187, 135, 156, 173,
+ 224, 255, 255, 114, 61, 34, 60, 114, 35, 90, 40, 85, 23, 242, 249,
+ 254, 160, 83, 180, 179, 78, 70, 125, 33, 90, 251, 37, 239, 207, 205,
+ 83, 207, 134, 251, 143, 126, 161, 164, 115, 118, 229, 241, 127, 236, 229,
+ 60, 97, 248, 134, 252, 176, 208, 137, 63, 112, 249, 127, 197, 242, 139,
+ 227, 254, 65, 222, 71, 157, 56, 222, 95, 7, 127, 13, 245, 173, 22,
+ 80, 252, 254, 245, 60, 249, 249, 15, 201, 191, 218, 204, 149, 92, 254,
+ 157, 51, 85, 142, 197, 191, 204, 18, 150, 46, 90, 201, 203, 31, 62,
+ 55, 203, 121, 243, 37, 149, 163, 227, 167, 93, 120, 250, 181, 249, 163,
+ 194, 34, 39, 207, 43, 62, 125, 81, 172, 255, 113, 235, 5, 46, 215,
+ 75, 31, 70, 76, 104, 55, 72, 180, 255, 133, 95, 151, 56, 224, 255,
+ 223, 157, 55, 151, 247, 215, 9, 255, 223, 47, 253, 167, 146, 169, 240,
+ 249, 60, 222, 71, 126, 119, 196, 2, 9, 146, 255, 63, 113, 97, 134,
+ 227, 93, 248, 255, 67, 177, 225, 124, 126, 214, 117, 205, 118, 214, 217,
+ 105, 118, 148, 54, 92, 203, 235, 143, 186, 106, 213, 118, 153, 149, 237,
+ 12, 217, 222, 130, 167, 75, 84, 185, 225, 155, 110, 235, 194, 63, 105,
+ 38, 214, 223, 218, 125, 132, 75, 181, 110, 129, 112, 187, 36, 184, 156,
+ 252, 233, 153, 159, 82, 254, 252, 29, 32, 122, 254, 87, 77, 36, 241,
+ 253, 159, 187, 59, 128, 220, 179, 173, 180, 19, 15, 39, 8, 141, 142,
+ 39, 56, 157, 81, 19, 157, 179, 150, 54, 138, 120, 230, 239, 9, 194,
+ 176, 87, 94, 172, 146, 255, 255, 25, 242, 105, 145, 250, 84, 241, 182,
+ 191, 119, 21, 253, 62, 101, 121, 133, 247, 127, 70, 97, 93, 182, 105,
+ 244, 120, 232, 11, 147, 58, 242, 249, 78, 221, 84, 173, 168, 229, 183,
+ 121, 66, 190, 85, 197, 231, 111, 101, 94, 64, 241, 162, 137, 170, 240,
+ 99, 95, 254, 255, 188, 255, 83, 92, 150, 39, 188, 51, 246, 151, 208,
+ 113, 99, 196, 223, 154, 126, 237, 198, 23, 69, 163, 175, 229, 9, 62,
+ 187, 71, 112, 251, 187, 199, 247, 74, 241, 175, 3, 135, 134, 181, 251,
+ 90, 108, 127, 112, 163, 14, 194, 94, 115, 13, 231, 192, 6, 159, 240,
+ 111, 115, 12, 231, 91, 11, 121, 49, 125, 157, 117, 122, 28, 228, 253,
+ 5, 47, 232, 210, 154, 11, 99, 58, 11, 92, 215, 31, 69, 254, 168,
+ 206, 130, 195, 253, 254, 79, 211, 209, 117, 157, 15, 215, 94, 225, 244,
+ 251, 253, 49, 222, 247, 134, 161, 173, 133, 86, 129, 253, 132, 88, 125,
+ 1, 175, 95, 244, 69, 148, 211, 100, 110, 42, 176, 101, 83, 184, 63,
+ 222, 247, 248, 223, 37, 151, 255, 26, 162, 109, 255, 136, 120, 255, 107,
+ 213, 94, 157, 246, 146, 225, 79, 45, 201, 168, 220, 254, 175, 90, 37,
+ 251, 63, 232, 68, 188, 70, 36, 241, 253, 159, 187, 203, 191, 254, 190,
+ 148, 114, 243, 59, 208, 254, 137, 211, 97, 107, 228, 234, 112, 90, 227,
+ 168, 202, 250, 175, 151, 145, 39, 252, 121, 107, 114, 113, 73, 72, 96,
+ 73, 98, 231, 138, 239, 255, 156, 59, 55, 75, 248, 37, 190, 164, 228,
+ 160, 105, 63, 215, 247, 65, 237, 143, 134, 167, 190, 149, 43, 52, 205,
+ 16, 239, 7, 204, 235, 189, 167, 228, 157, 117, 183, 194, 116, 151, 42,
+ 95, 255, 70, 200, 106, 214, 115, 137, 97, 9, 123, 67, 185, 189, 204,
+ 93, 156, 88, 188, 1, 121, 63, 124, 254, 54, 127, 126, 239, 168, 23,
+ 94, 52, 107, 243, 155, 125, 118, 41, 222, 255, 33, 255, 159, 191, 100,
+ 7, 127, 166, 242, 122, 143, 60, 225, 93, 221, 177, 226, 129, 199, 215,
+ 243, 190, 253, 125, 250, 231, 176, 188, 156, 60, 161, 201, 124, 241, 183,
+ 241, 255, 222, 182, 38, 252, 130, 209, 86, 178, 251, 43, 177, 253, 161,
+ 197, 193, 66, 225, 236, 64, 231, 217, 3, 111, 242, 245, 255, 196, 91,
+ 167, 29, 141, 99, 231, 106, 143, 204, 136, 227, 239, 79, 213, 143, 157,
+ 235, 152, 241, 179, 205, 249, 88, 70, 107, 46, 63, 202, 87, 101, 180,
+ 214, 246, 146, 222, 255, 49, 238, 61, 232, 60, 144, 61, 48, 226, 108,
+ 112, 38, 151, 223, 160, 185, 87, 28, 97, 103, 7, 57, 18, 13, 19,
+ 121, 253, 216, 152, 108, 109, 157, 148, 44, 103, 224, 137, 61, 188, 253,
+ 151, 199, 140, 119, 182, 251, 188, 163, 227, 246, 73, 13, 111, 191, 113,
+ 255, 19, 206, 159, 210, 46, 10, 255, 190, 183, 167, 156, 252, 73, 198,
+ 21, 246, 127, 208, 9, 150, 43, 146, 244, 238, 199, 93, 21, 224, 88,
+ 89, 126, 185, 247, 191, 108, 223, 36, 10, 93, 162, 191, 118, 212, 253,
+ 167, 80, 168, 138, 252, 77, 207, 231, 10, 95, 15, 254, 160, 164, 241,
+ 171, 207, 135, 189, 16, 240, 102, 133, 247, 127, 66, 79, 230, 9, 151,
+ 182, 169, 194, 226, 222, 111, 203, 231, 191, 250, 208, 217, 197, 11, 139,
+ 167, 11, 15, 93, 24, 206, 231, 239, 143, 178, 199, 195, 255, 73, 29,
+ 161, 237, 184, 116, 122, 229, 254, 255, 223, 60, 225, 74, 84, 231, 48,
+ 161, 243, 122, 142, 253, 229, 250, 206, 197, 175, 33, 207, 49, 102, 37,
+ 79, 47, 217, 178, 182, 232, 197, 179, 171, 138, 182, 223, 242, 200, 159,
+ 214, 191, 37, 225, 56, 127, 166, 242, 217, 249, 89, 66, 195, 167, 123,
+ 247, 121, 180, 68, 197, 229, 83, 125, 125, 100, 209, 243, 216, 83, 94,
+ 56, 176, 140, 219, 131, 245, 7, 85, 142, 201, 155, 86, 20, 239, 251,
+ 73, 244, 191, 177, 90, 31, 225, 82, 191, 230, 206, 247, 244, 165, 252,
+ 253, 143, 115, 205, 254, 41, 106, 114, 107, 150, 179, 241, 220, 219, 188,
+ 255, 224, 133, 190, 27, 138, 138, 235, 110, 21, 223, 231, 249, 122, 206,
+ 237, 146, 144, 173, 255, 150, 164, 74, 239, 255, 36, 134, 14, 208, 62,
+ 124, 250, 109, 231, 238, 14, 226, 254, 109, 246, 246, 3, 161, 31, 204,
+ 205, 21, 54, 31, 252, 146, 215, 223, 127, 49, 203, 121, 217, 180, 183,
+ 216, 231, 236, 44, 62, 254, 182, 167, 114, 29, 150, 85, 159, 134, 23,
+ 77, 23, 127, 159, 55, 229, 133, 88, 231, 186, 198, 83, 157, 103, 198,
+ 44, 45, 31, 255, 231, 86, 242, 252, 79, 83, 233, 251, 63, 149, 234,
+ 192, 171, 9, 227, 143, 40, 211, 239, 172, 223, 87, 244, 65, 114, 154,
+ 112, 102, 214, 198, 94, 85, 145, 127, 194, 31, 121, 130, 53, 182, 164,
+ 248, 55, 245, 178, 162, 31, 114, 103, 86, 120, 255, 103, 25, 100, 213,
+ 172, 244, 82, 209, 188, 31, 234, 241, 249, 206, 154, 171, 10, 171, 129,
+ 189, 214, 212, 246, 225, 124, 62, 114, 235, 212, 46, 190, 144, 30, 30,
+ 62, 227, 80, 229, 246, 191, 7, 240, 87, 197, 149, 132, 69, 132, 159,
+ 226, 242, 126, 122, 110, 73, 113, 247, 63, 243, 132, 58, 83, 123, 242,
+ 244, 249, 186, 239, 22, 61, 251, 85, 68, 81, 246, 29, 242, 111, 46,
+ 244, 224, 235, 127, 104, 251, 153, 66, 116, 226, 202, 35, 237, 63, 13,
+ 228, 242, 239, 255, 189, 189, 40, 226, 231, 60, 225, 219, 69, 63, 240,
+ 254, 60, 117, 42, 208, 241, 121, 202, 79, 197, 187, 234, 136, 242, 91,
+ 113, 228, 71, 109, 90, 78, 43, 103, 63, 85, 27, 254, 254, 87, 76,
+ 235, 73, 197, 39, 174, 207, 114, 174, 138, 17, 229, 255, 230, 245, 89,
+ 66, 108, 175, 179, 197, 239, 93, 189, 198, 229, 191, 4, 249, 199, 174,
+ 94, 43, 121, 95, 122, 255, 103, 88, 227, 16, 237, 150, 147, 163, 92,
+ 243, 3, 69, 249, 39, 7, 173, 15, 173, 6, 123, 215, 162, 240, 45,
+ 94, 191, 176, 196, 238, 124, 182, 246, 137, 226, 234, 187, 214, 112, 249,
+ 251, 180, 95, 235, 216, 180, 247, 141, 240, 199, 159, 177, 241, 250, 19,
+ 22, 181, 112, 109, 154, 106, 115, 190, 58, 248, 77, 46, 127, 250, 29,
+ 40, 250, 62, 200, 18, 127, 89, 61, 207, 253, 61, 95, 102, 249, 239,
+ 13, 35, 251, 218, 140, 118, 166, 75, 53, 232, 153, 248, 205, 97, 96,
+ 96, 144, 244, 142, 185, 248, 45, 137, 63, 202, 103, 137, 84, 122, 242,
+ 166, 231, 55, 85, 144, 255, 180, 251, 123, 18, 127, 233, 91, 194, 191,
+ 254, 46, 135, 125, 191, 247, 202, 221, 239, 168, 135, 73, 24, 110, 188,
+ 82, 63, 180, 133, 180, 101, 122, 90, 185, 207, 132, 239, 247, 158, 178,
+ 18, 143, 48, 228, 254, 129, 231, 125, 156, 253, 79, 185, 254, 221, 239,
+ 189, 215, 114, 253, 83, 224, 93, 80, 163, 127, 72, 23, 246, 191, 3,
+ 239, 62, 239, 81, 42, 241, 8, 195, 141, 151, 15, 158, 240, 163, 39,
+ 151, 159, 191, 251, 189, 151, 167, 196, 203, 87, 224, 249, 129, 39, 252,
+ 248, 254, 166, 114, 243, 119, 191, 247, 188, 148, 120, 126, 10, 188, 229,
+ 179, 16, 39, 18, 94, 209, 29, 227, 189, 207, 123, 67, 74, 60, 194,
+ 112, 227, 249, 131, 39, 252, 136, 130, 148, 114, 253, 187, 223, 123, 40,
+ 74, 60, 127, 5, 94, 225, 204, 203, 106, 194, 47, 75, 155, 90, 14,
+ 239, 126, 239, 53, 40, 241, 8, 195, 141, 23, 1, 158, 240, 203, 250,
+ 149, 199, 187, 223, 115, 114, 37, 94, 132, 2, 175, 116, 6, 116, 5,
+ 233, 64, 255, 244, 114, 120, 247, 123, 238, 86, 78, 159, 103, 40, 244,
+ 25, 60, 239, 227, 194, 242, 191, 41, 115, 191, 231, 56, 229, 244, 89,
+ 129, 119, 97, 58, 244, 25, 233, 248, 127, 141, 229, 231, 239, 62, 207,
+ 5, 202, 233, 243, 116, 133, 62, 131, 39, 252, 210, 27, 102, 223, 59,
+ 245, 249, 126, 152, 178, 62, 43, 240, 252, 192, 19, 126, 33, 75, 171,
+ 32, 143, 123, 61, 183, 46, 167, 207, 10, 188, 130, 28, 232, 51, 199,
+ 52, 85, 42, 143, 123, 97, 202, 127, 47, 51, 199, 131, 23, 8, 158,
+ 240, 149, 127, 127, 92, 150, 199, 125, 58, 40, 255, 86, 133, 2, 207,
+ 149, 125, 89, 77, 248, 241, 199, 43, 149, 199, 61, 17, 229, 223, 170,
+ 200, 246, 224, 69, 131, 231, 125, 188, 232, 145, 135, 230, 63, 236, 251,
+ 149, 120, 209, 10, 188, 50, 248, 2, 194, 47, 140, 79, 175, 196, 62,
+ 223, 123, 192, 242, 111, 143, 102, 121, 240, 44, 224, 9, 63, 126, 216,
+ 165, 74, 236, 243, 127, 195, 179, 40, 240, 200, 87, 241, 62, 222, 170,
+ 212, 62, 255, 167, 249, 99, 74, 60, 9, 63, 223, 113, 87, 251, 124,
+ 87, 76, 183, 15, 38, 191, 235, 246, 193, 101, 67, 160, 43, 241, 30,
+ 63, 204, 125, 176, 221, 104, 74, 70, 171, 70, 123, 98, 74, 176, 228,
+ 132, 221, 62, 216, 31, 117, 163, 135, 98, 61, 69, 167, 251, 150, 30,
+ 78, 241, 149, 109, 96, 166, 194, 6, 102, 72, 120, 141, 254, 241, 218,
+ 7, 19, 134, 108, 3, 193, 19, 254, 242, 122, 222, 251, 224, 8, 5,
+ 94, 169, 29, 250, 130, 116, 105, 200, 37, 175, 125, 48, 97, 200, 54,
+ 16, 60, 225, 151, 5, 121, 239, 131, 227, 21, 120, 23, 108, 232, 27,
+ 210, 254, 79, 121, 239, 131, 9, 67, 182, 129, 224, 9, 63, 250, 5,
+ 179, 215, 62, 56, 95, 129, 231, 7, 158, 240, 253, 119, 120, 239, 131,
+ 253, 20, 120, 5, 86, 232, 51, 245, 113, 171, 209, 107, 31, 76, 24,
+ 178, 13, 4, 207, 251, 24, 237, 189, 15, 14, 84, 224, 185, 166, 193,
+ 6, 34, 93, 214, 214, 123, 31, 76, 24, 178, 13, 4, 79, 248, 165,
+ 129, 38, 175, 125, 112, 180, 2, 175, 112, 36, 236, 11, 210, 236, 51,
+ 239, 125, 48, 97, 200, 235, 13, 60, 225, 151, 125, 225, 189, 15, 142,
+ 80, 224, 149, 142, 192, 122, 67, 186, 160, 200, 123, 31, 76, 24, 242,
+ 122, 3, 79, 248, 254, 193, 222, 251, 224, 120, 5, 222, 133, 225, 144,
+ 5, 210, 101, 19, 189, 247, 193, 132, 33, 175, 55, 240, 132, 31, 239,
+ 242, 222, 7, 231, 43, 240, 252, 192, 19, 126, 65, 247, 169, 94, 251,
+ 96, 63, 5, 94, 193, 48, 172, 55, 26, 243, 33, 239, 125, 48, 97,
+ 200, 235, 13, 60, 225, 199, 239, 243, 222, 7, 7, 42, 240, 92, 240,
+ 47, 132, 31, 223, 210, 123, 31, 76, 24, 242, 122, 3, 79, 248, 101,
+ 223, 121, 239, 131, 163, 135, 150, 247, 193, 132, 207, 54, 121, 239, 131,
+ 201, 239, 186, 125, 112, 96, 24, 124, 91, 102, 57, 31, 108, 215, 153,
+ 244, 228, 132, 105, 51, 236, 222, 6, 203, 62, 216, 130, 186, 5, 168,
+ 19, 93, 116, 75, 109, 241, 59, 83, 83, 142, 59, 134, 40, 250, 56,
+ 68, 194, 155, 225, 189, 15, 102, 10, 188, 229, 131, 17, 39, 12, 161,
+ 223, 45, 240, 222, 7, 19, 134, 188, 239, 2, 79, 248, 209, 179, 188,
+ 247, 193, 254, 10, 188, 194, 65, 152, 67, 164, 93, 58, 239, 125, 48,
+ 97, 200, 54, 16, 60, 225, 199, 127, 229, 189, 15, 142, 80, 224, 149,
+ 14, 132, 13, 68, 186, 32, 223, 123, 31, 76, 24, 178, 13, 4, 79,
+ 248, 165, 107, 188, 247, 193, 241, 10, 188, 11, 3, 128, 133, 116, 193,
+ 94, 239, 125, 48, 97, 200, 54, 16, 60, 225, 251, 77, 240, 222, 7,
+ 231, 43, 240, 252, 192, 19, 126, 190, 202, 123, 31, 236, 167, 192, 43,
+ 232, 15, 44, 164, 151, 247, 244, 222, 7, 19, 134, 108, 3, 193, 19,
+ 190, 235, 27, 239, 125, 112, 160, 2, 207, 213, 15, 178, 32, 204, 239,
+ 189, 247, 193, 132, 33, 219, 64, 240, 132, 95, 240, 246, 93, 109, 254,
+ 125, 245, 57, 90, 129, 87, 40, 96, 172, 72, 199, 135, 123, 239, 131,
+ 9, 67, 94, 111, 224, 9, 223, 47, 193, 123, 31, 28, 161, 192, 43,
+ 213, 98, 189, 33, 173, 252, 187, 245, 255, 171, 15, 38, 12, 121, 189,
+ 129, 39, 252, 248, 48, 239, 125, 112, 188, 2, 239, 66, 56, 214, 155,
+ 150, 246, 213, 119, 141, 137, 238, 235, 131, 9, 67, 94, 111, 224, 9,
+ 191, 192, 233, 189, 15, 206, 87, 224, 249, 129, 39, 124, 255, 14, 222,
+ 251, 96, 63, 5, 30, 249, 43, 194, 47, 248, 213, 123, 31, 76, 24,
+ 74, 31, 76, 248, 254, 159, 121, 239, 131, 201, 239, 186, 125, 112, 97,
+ 16, 226, 131, 33, 74, 31, 108, 231, 251, 95, 120, 94, 163, 93, 246,
+ 192, 30, 31, 236, 10, 165, 248, 19, 250, 90, 221, 228, 91, 86, 236,
+ 217, 7, 83, 190, 188, 230, 66, 165, 239, 91, 170, 121, 239, 131, 163,
+ 21, 120, 101, 125, 176, 230, 144, 182, 216, 188, 247, 193, 132, 33, 223,
+ 235, 0, 79, 248, 254, 83, 189, 247, 193, 22, 5, 30, 3, 79, 248,
+ 126, 81, 222, 251, 96, 166, 192, 91, 222, 27, 99, 69, 58, 255, 144,
+ 247, 62, 152, 48, 228, 152, 3, 60, 225, 199, 47, 241, 222, 7, 251,
+ 43, 240, 10, 123, 193, 127, 32, 29, 127, 208, 123, 31, 76, 24, 178,
+ 13, 4, 79, 248, 174, 120, 239, 125, 112, 132, 2, 175, 180, 39, 108,
+ 96, 47, 250, 13, 169, 169, 229, 108, 254, 255, 226, 131, 9, 67, 182,
+ 129, 224, 9, 63, 63, 194, 123, 31, 28, 175, 192, 187, 208, 3, 54,
+ 16, 233, 248, 54, 222, 251, 96, 194, 144, 109, 32, 120, 194, 143, 190,
+ 233, 189, 15, 206, 87, 224, 249, 129, 39, 252, 11, 23, 189, 247, 193,
+ 126, 10, 188, 130, 238, 152, 59, 164, 203, 126, 240, 126, 31, 76, 24,
+ 114, 204, 1, 158, 240, 227, 135, 120, 239, 131, 3, 21, 120, 174, 110,
+ 180, 199, 68, 31, 167, 121, 239, 131, 9, 67, 182, 127, 224, 9, 191,
+ 236, 160, 247, 62, 56, 90, 129, 87, 22, 130, 181, 129, 244, 133, 67,
+ 222, 223, 139, 38, 12, 217, 254, 129, 231, 125, 252, 214, 123, 31, 108,
+ 81, 224, 49, 240, 132, 111, 41, 243, 222, 7, 51, 5, 222, 114, 248,
+ 23, 194, 143, 239, 239, 189, 15, 38, 12, 217, 254, 129, 39, 124, 215,
+ 21, 239, 125, 176, 127, 112, 121, 31, 76, 248, 17, 7, 188, 247, 193,
+ 228, 119, 221, 62, 216, 127, 23, 100, 17, 86, 209, 7, 243, 15, 110,
+ 197, 187, 210, 240, 196, 30, 31, 28, 129, 186, 203, 81, 39, 250, 113,
+ 147, 111, 126, 174, 199, 7, 83, 190, 108, 3, 3, 69, 188, 194, 71,
+ 188, 247, 193, 132, 33, 219, 64, 240, 132, 239, 223, 209, 123, 31, 28,
+ 175, 192, 179, 92, 160, 251, 128, 24, 119, 92, 21, 124, 240, 5, 197,
+ 120, 243, 161, 47, 129, 244, 27, 185, 222, 251, 96, 194, 144, 251, 183,
+ 15, 58, 8, 124, 215, 58, 239, 125, 48, 97, 200, 58, 3, 158, 240,
+ 203, 54, 123, 239, 131, 153, 2, 111, 121, 33, 250, 135, 116, 244, 214,
+ 42, 60, 15, 46, 84, 248, 244, 189, 208, 23, 224, 185, 182, 120, 239,
+ 131, 9, 67, 246, 233, 224, 9, 63, 162, 177, 247, 62, 56, 66, 129,
+ 87, 250, 10, 124, 58, 210, 5, 45, 189, 247, 193, 132, 33, 235, 51,
+ 120, 194, 143, 111, 234, 189, 15, 142, 87, 224, 93, 216, 3, 249, 34,
+ 237, 58, 237, 189, 15, 38, 12, 217, 167, 131, 39, 252, 130, 51, 222,
+ 251, 224, 124, 5, 158, 31, 120, 194, 95, 126, 192, 123, 31, 236, 167,
+ 192, 43, 216, 13, 127, 73, 99, 158, 236, 189, 15, 38, 12, 217, 167,
+ 131, 39, 252, 130, 113, 222, 251, 224, 64, 5, 158, 235, 101, 96, 33,
+ 173, 252, 155, 161, 255, 171, 15, 38, 12, 217, 167, 131, 39, 252, 232,
+ 92, 239, 247, 193, 209, 10, 188, 178, 151, 160, 43, 132, 25, 97, 242,
+ 218, 7, 19, 134, 108, 175, 192, 19, 126, 193, 50, 239, 125, 176, 69,
+ 129, 199, 192, 19, 126, 97, 45, 239, 125, 48, 83, 224, 145, 191, 34,
+ 124, 255, 143, 188, 247, 193, 132, 161, 244, 193, 132, 159, 191, 202, 123,
+ 31, 76, 126, 215, 237, 131, 227, 183, 96, 172, 65, 21, 125, 112, 136,
+ 199, 1, 151, 123, 39, 171, 112, 39, 116, 127, 11, 189, 131, 100, 242,
+ 141, 31, 224, 241, 193, 148, 47, 219, 192, 157, 34, 222, 5, 149, 247,
+ 62, 56, 66, 129, 87, 186, 3, 125, 68, 218, 101, 170, 194, 59, 89,
+ 59, 20, 54, 16, 60, 225, 151, 25, 188, 247, 193, 241, 10, 188, 11,
+ 219, 49, 31, 72, 231, 167, 84, 225, 157, 172, 237, 10, 27, 8, 158,
+ 240, 93, 39, 170, 240, 78, 150, 2, 207, 15, 60, 225, 251, 47, 244,
+ 222, 7, 251, 41, 240, 10, 182, 97, 172, 72, 71, 111, 241, 222, 7,
+ 19, 134, 108, 3, 193, 19, 190, 197, 207, 123, 31, 28, 168, 192, 115,
+ 189, 8, 123, 128, 116, 129, 206, 123, 31, 76, 24, 178, 13, 4, 79,
+ 248, 236, 33, 239, 125, 112, 180, 2, 175, 108, 43, 100, 75, 125, 20,
+ 188, 247, 193, 132, 33, 219, 64, 240, 132, 239, 119, 205, 123, 31, 108,
+ 81, 224, 49, 240, 132, 191, 252, 119, 239, 125, 48, 83, 224, 45, 127,
+ 1, 178, 69, 250, 194, 23, 222, 251, 96, 194, 144, 247, 53, 224, 9,
+ 223, 127, 128, 247, 62, 216, 95, 129, 87, 248, 60, 198, 138, 244, 242,
+ 169, 222, 251, 96, 194, 144, 237, 31, 120, 194, 47, 248, 192, 123, 31,
+ 28, 161, 192, 43, 45, 128, 253, 67, 186, 240, 128, 247, 251, 96, 194,
+ 144, 237, 31, 120, 194, 47, 60, 227, 253, 62, 56, 94, 129, 87, 248,
+ 28, 236, 31, 210, 249, 59, 189, 247, 193, 132, 33, 207, 31, 120, 194,
+ 247, 143, 244, 222, 7, 71, 40, 240, 200, 95, 17, 126, 254, 223, 222,
+ 251, 96, 194, 80, 250, 96, 194, 207, 63, 234, 189, 15, 38, 191, 43,
+ 191, 147, 181, 10, 99, 221, 85, 209, 7, 119, 187, 139, 15, 190, 176,
+ 25, 235, 125, 181, 68, 35, 61, 127, 123, 130, 242, 101, 31, 178, 89,
+ 250, 219, 37, 35, 189, 247, 193, 249, 10, 60, 63, 240, 132, 95, 214,
+ 198, 123, 31, 236, 167, 192, 43, 216, 132, 249, 35, 204, 137, 222, 251,
+ 96, 194, 144, 125, 8, 120, 194, 47, 235, 228, 189, 15, 14, 84, 224,
+ 185, 54, 98, 253, 34, 29, 253, 138, 247, 62, 152, 48, 100, 31, 2,
+ 158, 240, 11, 158, 245, 222, 7, 71, 43, 240, 202, 54, 192, 135, 32,
+ 237, 90, 234, 189, 15, 38, 12, 217, 135, 128, 39, 252, 252, 245, 222,
+ 251, 96, 139, 2, 143, 129, 39, 124, 86, 223, 251, 231, 193, 76, 129,
+ 183, 252, 89, 248, 16, 26, 115, 105, 121, 159, 254, 191, 248, 96, 194,
+ 144, 125, 8, 120, 194, 247, 111, 236, 189, 15, 246, 87, 224, 21, 174,
+ 135, 255, 64, 58, 240, 124, 21, 222, 201, 90, 175, 176, 129, 224, 9,
+ 63, 254, 163, 42, 188, 147, 165, 192, 43, 93, 7, 27, 136, 180, 95,
+ 191, 138, 250, 252, 159, 223, 201, 90, 167, 240, 33, 224, 9, 127, 249,
+ 132, 42, 188, 147, 165, 192, 187, 176, 22, 62, 4, 233, 248, 209, 85,
+ 120, 39, 107, 173, 194, 254, 129, 39, 252, 130, 29, 85, 120, 39, 75,
+ 129, 231, 7, 158, 240, 253, 166, 87, 225, 157, 44, 5, 94, 193, 26,
+ 172, 53, 164, 11, 83, 238, 42, 143, 251, 191, 147, 181, 70, 97, 255,
+ 192, 19, 126, 252, 51, 85, 120, 39, 75, 129, 231, 130, 111, 33, 124,
+ 139, 111, 21, 222, 201, 90, 173, 176, 127, 224, 9, 191, 224, 100, 21,
+ 222, 201, 90, 125, 199, 59, 89, 72, 251, 189, 84, 133, 119, 178, 86,
+ 41, 158, 7, 255, 138, 185, 219, 82, 209, 7, 119, 191, 139, 15, 182,
+ 144, 207, 254, 141, 158, 167, 154, 124, 3, 179, 60, 251, 96, 202, 151,
+ 251, 184, 74, 250, 187, 146, 185, 85, 120, 39, 75, 129, 183, 124, 37,
+ 228, 129, 116, 254, 212, 42, 188, 147, 181, 82, 97, 3, 193, 19, 126,
+ 129, 174, 10, 239, 100, 41, 240, 10, 87, 192, 30, 32, 29, 161, 247,
+ 140, 87, 243, 63, 250, 96, 194, 144, 109, 32, 120, 194, 47, 59, 85,
+ 133, 119, 178, 20, 120, 165, 203, 177, 222, 144, 46, 155, 91, 133, 119,
+ 178, 150, 43, 198, 123, 30, 99, 5, 158, 223, 134, 42, 60, 15, 62,
+ 175, 24, 47, 120, 194, 143, 46, 244, 254, 219, 164, 8, 5, 94, 233,
+ 159, 24, 239, 121, 250, 182, 203, 123, 31, 76, 24, 178, 205, 7, 79,
+ 248, 174, 106, 85, 120, 30, 172, 192, 187, 240, 7, 198, 139, 116, 105,
+ 104, 21, 158, 7, 255, 161, 176, 249, 224, 9, 191, 244, 159, 42, 60,
+ 15, 86, 224, 249, 129, 39, 252, 232, 159, 171, 240, 60, 88, 129, 87,
+ 112, 14, 107, 23, 105, 203, 71, 85, 120, 30, 124, 78, 97, 243, 193,
+ 19, 126, 89, 100, 21, 158, 7, 43, 240, 92, 103, 97, 11, 144, 142,
+ 78, 170, 194, 243, 224, 179, 10, 155, 15, 158, 240, 227, 223, 173, 194,
+ 243, 96, 5, 94, 217, 239, 208, 61, 164, 93, 129, 222, 251, 96, 194,
+ 144, 99, 94, 240, 132, 95, 118, 170, 10, 207, 131, 21, 120, 12, 60,
+ 225, 71, 188, 88, 133, 231, 193, 10, 188, 229, 240, 47, 132, 31, 223,
+ 185, 10, 207, 131, 127, 83, 216, 123, 240, 188, 143, 231, 170, 240, 60,
+ 248, 183, 59, 158, 7, 255, 70, 239, 24, 86, 225, 121, 240, 175, 30,
+ 31, 124, 97, 9, 250, 182, 170, 162, 15, 238, 113, 23, 31, 28, 65,
+ 62, 123, 41, 202, 211, 111, 9, 86, 247, 236, 131, 41, 95, 182, 129,
+ 191, 72, 62, 120, 88, 21, 158, 7, 255, 162, 176, 129, 224, 9, 191,
+ 192, 191, 10, 207, 131, 21, 120, 23, 126, 134, 189, 66, 186, 112, 156,
+ 247, 62, 152, 48, 100, 27, 8, 158, 240, 11, 218, 123, 191, 15, 206,
+ 87, 224, 249, 129, 231, 125, 220, 230, 189, 15, 246, 83, 224, 21, 252,
+ 4, 27, 72, 125, 92, 227, 189, 15, 38, 12, 217, 6, 130, 39, 252,
+ 252, 69, 222, 251, 224, 64, 5, 158, 235, 71, 204, 29, 210, 17, 171,
+ 189, 223, 7, 19, 134, 108, 3, 193, 19, 126, 252, 112, 239, 125, 112,
+ 180, 2, 175, 236, 7, 216, 63, 164, 45, 254, 169, 94, 239, 131, 9,
+ 67, 182, 129, 224, 9, 191, 236, 17, 239, 125, 176, 69, 129, 199, 126,
+ 160, 247, 157, 160, 51, 191, 123, 239, 131, 153, 2, 111, 249, 247, 24,
+ 43, 97, 158, 242, 222, 7, 19, 134, 108, 3, 193, 19, 190, 69, 239,
+ 253, 62, 216, 95, 129, 87, 248, 29, 98, 94, 164, 163, 199, 86, 225,
+ 189, 232, 239, 20, 49, 32, 120, 194, 47, 27, 94, 133, 247, 162, 21,
+ 120, 165, 101, 176, 45, 223, 209, 183, 118, 85, 120, 47, 186, 76, 97,
+ 255, 192, 19, 126, 105, 70, 21, 222, 139, 86, 224, 21, 46, 3, 22,
+ 210, 165, 51, 189, 223, 7, 19, 134, 60, 127, 224, 9, 223, 127, 190,
+ 247, 62, 56, 66, 129, 87, 10, 255, 66, 248, 129, 26, 239, 125, 48,
+ 97, 200, 243, 7, 158, 247, 241, 77, 239, 125, 112, 252, 210, 242, 62,
+ 152, 240, 3, 111, 123, 239, 131, 201, 239, 186, 125, 176, 101, 14, 198,
+ 251, 107, 69, 31, 220, 243, 46, 62, 56, 159, 124, 246, 28, 241, 61,
+ 209, 192, 111, 60, 62, 152, 242, 101, 31, 178, 68, 194, 27, 236, 189,
+ 15, 246, 83, 224, 21, 44, 134, 189, 95, 66, 127, 159, 59, 221, 107,
+ 31, 76, 24, 178, 15, 1, 79, 248, 150, 209, 222, 251, 224, 64, 5,
+ 158, 235, 25, 248, 144, 197, 244, 251, 198, 222, 251, 96, 194, 144, 125,
+ 8, 120, 194, 191, 112, 221, 123, 31, 28, 173, 192, 43, 91, 4, 31,
+ 130, 180, 255, 10, 239, 125, 48, 97, 200, 62, 4, 60, 225, 71, 204,
+ 243, 222, 7, 91, 20, 120, 12, 60, 225, 23, 220, 246, 222, 7, 51,
+ 5, 222, 242, 133, 144, 237, 34, 250, 190, 203, 251, 231, 193, 132, 33,
+ 251, 16, 240, 132, 191, 156, 165, 122, 189, 15, 246, 87, 224, 21, 46,
+ 0, 22, 210, 129, 121, 222, 251, 96, 194, 144, 109, 224, 2, 122, 214,
+ 143, 117, 252, 179, 247, 62, 56, 66, 129, 87, 58, 31, 88, 11, 40,
+ 206, 247, 222, 7, 19, 134, 108, 3, 193, 19, 254, 242, 108, 239, 125,
+ 112, 188, 2, 239, 194, 60, 248, 15, 234, 99, 174, 247, 62, 152, 48,
+ 228, 24, 26, 60, 225, 23, 12, 246, 222, 7, 231, 43, 240, 252, 192,
+ 19, 126, 217, 38, 239, 125, 176, 159, 2, 175, 224, 105, 216, 63, 164,
+ 151, 79, 243, 222, 7, 19, 134, 108, 255, 192, 19, 126, 180, 221, 123,
+ 31, 28, 168, 192, 115, 205, 197, 220, 33, 93, 54, 219, 123, 31, 76,
+ 24, 178, 253, 3, 79, 248, 241, 75, 188, 247, 193, 209, 10, 60, 242,
+ 87, 188, 143, 78, 239, 125, 48, 97, 40, 125, 48, 225, 23, 94, 246,
+ 222, 7, 147, 223, 157, 167, 192, 187, 176, 68, 233, 131, 179, 116, 105,
+ 169, 156, 85, 124, 153, 196, 109, 152, 88, 6, 117, 75, 175, 136, 84,
+ 152, 228, 241, 193, 76, 209, 199, 229, 179, 165, 119, 178, 108, 222, 251,
+ 96, 194, 144, 109, 32, 225, 1, 159, 37, 120, 191, 15, 246, 87, 224,
+ 21, 62, 5, 125, 70, 218, 47, 199, 123, 31, 76, 24, 50, 222, 109,
+ 216, 64, 224, 249, 247, 170, 194, 247, 193, 183, 21, 54, 21, 60, 225,
+ 151, 157, 174, 194, 189, 104, 5, 94, 233, 45, 224, 33, 29, 189, 187,
+ 10, 247, 162, 111, 41, 108, 42, 120, 194, 95, 190, 162, 10, 223, 7,
+ 43, 240, 46, 220, 132, 62, 33, 29, 255, 114, 21, 190, 15, 190, 169,
+ 176, 169, 224, 9, 191, 52, 166, 10, 223, 7, 43, 240, 252, 192, 19,
+ 126, 89, 231, 42, 124, 31, 172, 192, 43, 184, 1, 155, 138, 116, 116,
+ 72, 21, 190, 15, 190, 161, 176, 169, 224, 9, 63, 255, 139, 42, 124,
+ 31, 172, 192, 115, 253, 11, 123, 133, 116, 252, 215, 85, 248, 62, 248,
+ 95, 133, 77, 5, 79, 248, 254, 111, 84, 225, 251, 96, 5, 94, 217,
+ 117, 216, 212, 127, 233, 123, 54, 239, 125, 48, 97, 200, 49, 37, 120,
+ 194, 143, 159, 236, 189, 15, 182, 40, 240, 24, 120, 194, 47, 59, 234,
+ 189, 15, 102, 10, 188, 229, 215, 16, 83, 94, 39, 251, 226, 189, 15,
+ 38, 12, 217, 158, 130, 39, 124, 127, 135, 247, 247, 162, 253, 21, 120,
+ 133, 87, 97, 11, 174, 209, 239, 230, 85, 225, 157, 172, 171, 10, 251,
+ 7, 158, 240, 203, 90, 87, 225, 157, 44, 5, 30, 247, 85, 72, 199,
+ 255, 88, 133, 119, 178, 174, 220, 241, 78, 22, 240, 10, 190, 251, 223,
+ 125, 240, 192, 97, 35, 163, 106, 227, 252, 213, 245, 250, 108, 168, 91,
+ 190, 243, 76, 190, 42, 150, 207, 52, 72, 244, 27, 17, 25, 116, 35,
+ 138, 177, 65, 77, 69, 39, 76, 215, 199, 32, 115, 68, 228, 240, 254,
+ 191, 96, 209, 4, 152, 12, 217, 118, 22, 96, 177, 26, 50, 89, 64,
+ 146, 209, 106, 67, 2, 86, 210, 206, 178, 89, 14, 155, 206, 178, 88,
+ 118, 186, 209, 132, 3, 236, 112, 14, 113, 57, 196, 161, 82, 150, 81,
+ 143, 130, 198, 4, 102, 210, 165, 27, 38, 5, 119, 155, 204, 50, 108,
+ 44, 41, 77, 151, 204, 44, 58, 61, 163, 139, 70, 125, 66, 154, 57,
+ 49, 149, 80, 211, 12, 122, 12, 68, 44, 26, 212, 35, 112, 50, 179,
+ 155, 237, 44, 49, 195, 154, 105, 160, 35, 227, 229, 236, 57, 22, 3,
+ 179, 165, 152, 179, 82, 13, 57, 204, 98, 182, 81, 25, 67, 154, 33,
+ 157, 241, 11, 86, 116, 139, 99, 4, 88, 13, 73, 84, 130, 46, 217,
+ 236, 214, 73, 33, 193, 147, 69, 222, 56, 157, 131, 101, 234, 210, 152,
+ 212, 174, 209, 98, 70, 227, 86, 115, 58, 65, 81, 29, 91, 90, 134,
+ 213, 146, 194, 116, 137, 60, 21, 16, 96, 75, 180, 26, 45, 118, 27,
+ 10, 81, 191, 145, 45, 102, 80, 113, 137, 195, 8, 77, 6, 150, 102,
+ 48, 1, 19, 135, 0, 26, 1, 31, 165, 141, 153, 232, 146, 141, 137,
+ 199, 0, 180, 156, 198, 2, 108, 134, 180, 52, 234, 68, 34, 3, 151,
+ 200, 2, 50, 76, 122, 115, 92, 66, 70, 18, 227, 12, 13, 138, 51,
+ 28, 42, 209, 156, 110, 161, 137, 97, 188, 231, 54, 131, 33, 149, 233,
+ 173, 186, 172, 233, 102, 244, 55, 197, 156, 166, 103, 137, 105, 70, 139,
+ 13, 35, 166, 179, 193, 164, 103, 38, 131, 157, 146, 56, 81, 10, 24,
+ 54, 94, 129, 87, 71, 5, 51, 161, 74, 231, 32, 38, 246, 31, 157,
+ 195, 60, 192, 73, 165, 99, 54, 168, 31, 1, 233, 70, 75, 186, 206,
+ 50, 41, 8, 50, 48, 167, 50, 18, 116, 146, 149, 198, 68, 220, 180,
+ 12, 93, 154, 209, 158, 195, 236, 22, 93, 178, 129, 79, 9, 38, 34,
+ 193, 136, 198, 178, 173, 6, 11, 203, 161, 131, 61, 139, 250, 96, 207,
+ 162, 46, 208, 165, 68, 179, 222, 64, 50, 177, 240, 114, 1, 22, 93,
+ 98, 170, 65, 79, 2, 103, 118, 67, 118, 162, 153, 161, 49, 187, 116,
+ 52, 25, 146, 249, 44, 234, 185, 64, 3, 204, 9, 83, 13, 137, 152,
+ 97, 148, 99, 22, 171, 121, 170, 120, 204, 225, 199, 233, 84, 195, 66,
+ 191, 41, 99, 78, 178, 77, 10, 153, 204, 231, 136, 206, 40, 204, 59,
+ 150, 136, 113, 90, 211, 209, 118, 26, 179, 50, 192, 50, 76, 158, 33,
+ 41, 46, 19, 209, 7, 46, 37, 233, 18, 153, 201, 108, 165, 19, 114,
+ 232, 20, 144, 162, 51, 233, 209, 169, 0, 11, 151, 96, 128, 205, 78,
+ 103, 27, 179, 81, 95, 108, 84, 10, 50, 164, 163, 221, 74, 163, 177,
+ 101, 164, 161, 103, 137, 152, 26, 70, 74, 199, 149, 172, 67, 128, 222,
+ 108, 180, 119, 236, 208, 17, 92, 162, 46, 45, 45, 1, 67, 165, 84,
+ 166, 193, 106, 51, 154, 77, 76, 199, 160, 111, 124, 104, 188, 74, 80,
+ 143, 201, 152, 243, 116, 29, 169, 70, 130, 97, 18, 82, 72, 216, 39,
+ 117, 155, 140, 255, 197, 102, 209, 69, 196, 35, 57, 140, 174, 163, 73,
+ 36, 141, 54, 3, 151, 166, 61, 195, 154, 144, 1, 53, 22, 23, 125,
+ 162, 217, 100, 183, 210, 138, 228, 35, 73, 166, 67, 2, 29, 48, 203,
+ 118, 106, 123, 186, 65, 172, 170, 55, 88, 236, 41, 34, 203, 225, 209,
+ 158, 56, 87, 86, 179, 133, 47, 98, 98, 114, 220, 12, 95, 209, 98,
+ 14, 24, 18, 176, 65, 103, 231, 50, 166, 51, 108, 2, 73, 152, 235,
+ 134, 13, 66, 72, 2, 38, 179, 209, 124, 36, 25, 13, 113, 124, 88,
+ 152, 96, 76, 103, 90, 70, 178, 145, 43, 115, 2, 178, 12, 166, 76,
+ 170, 162, 207, 176, 210, 56, 49, 103, 36, 33, 190, 142, 179, 153, 193,
+ 100, 176, 38, 231, 48, 189, 17, 3, 177, 97, 162, 68, 173, 7, 195,
+ 85, 130, 165, 232, 140, 38, 59, 2, 52, 123, 16, 29, 130, 25, 148,
+ 85, 44, 161, 75, 183, 192, 42, 232, 244, 114, 29, 152, 108, 200, 205,
+ 12, 247, 14, 88, 172, 89, 126, 53, 69, 151, 102, 182, 217, 161, 159,
+ 1, 233, 200, 157, 212, 107, 50, 163, 153, 181, 89, 12, 137, 86, 126,
+ 76, 230, 199, 4, 150, 110, 180, 90, 233, 144, 76, 135, 4, 166, 75,
+ 79, 176, 210, 129, 115, 201, 116, 96, 134, 116, 250, 89, 95, 147, 88,
+ 1, 243, 206, 116, 105, 150, 20, 29, 131, 213, 225, 57, 108, 58, 77,
+ 6, 211, 233, 245, 44, 149, 132, 144, 2, 141, 195, 218, 213, 7, 241,
+ 99, 48, 31, 113, 48, 89, 8, 43, 202, 98, 169, 192, 20, 144, 133,
+ 72, 100, 86, 104, 51, 21, 231, 99, 224, 215, 197, 241, 101, 36, 120,
+ 114, 18, 204, 102, 18, 115, 114, 2, 172, 7, 214, 65, 156, 104, 18,
+ 33, 86, 190, 68, 226, 72, 227, 232, 156, 70, 115, 2, 43, 27, 68,
+ 170, 106, 194, 140, 27, 249, 47, 16, 179, 164, 20, 234, 102, 26, 173,
+ 170, 164, 20, 62, 209, 217, 57, 252, 34, 211, 231, 64, 221, 73, 22,
+ 162, 177, 238, 222, 125, 50, 231, 76, 25, 48, 87, 54, 40, 179, 129,
+ 219, 43, 115, 26, 228, 110, 201, 166, 67, 14, 29, 166, 51, 200, 146,
+ 40, 152, 217, 176, 32, 179, 57, 23, 0, 45, 230, 138, 141, 35, 230,
+ 141, 155, 94, 146, 42, 166, 158, 95, 130, 180, 9, 8, 22, 152, 214,
+ 171, 213, 108, 167, 83, 150, 81, 26, 46, 250, 171, 151, 116, 214, 158,
+ 130, 188, 20, 44, 31, 42, 72, 133, 116, 88, 183, 140, 86, 59, 105,
+ 78, 74, 16, 75, 193, 60, 6, 177, 36, 28, 67, 88, 138, 17, 157,
+ 167, 162, 180, 120, 184, 102, 233, 236, 113, 38, 43, 179, 152, 236, 182,
+ 12, 126, 204, 4, 182, 205, 156, 150, 33, 158, 50, 153, 217, 138, 134,
+ 50, 196, 83, 38, 55, 217, 25, 252, 8, 47, 151, 138, 133, 135, 90,
+ 226, 25, 233, 4, 244, 61, 193, 48, 221, 206, 76, 88, 119, 196, 102,
+ 194, 54, 113, 195, 4, 163, 37, 122, 41, 24, 54, 172, 173, 0, 114,
+ 27, 9, 228, 40, 205, 86, 216, 54, 202, 227, 174, 193, 144, 201, 27,
+ 197, 48, 245, 40, 133, 106, 65, 116, 192, 172, 193, 28, 26, 248, 188,
+ 19, 71, 230, 140, 116, 65, 92, 2, 41, 8, 46, 153, 168, 227, 217,
+ 230, 36, 150, 3, 10, 32, 235, 147, 164, 75, 55, 166, 229, 112, 135,
+ 26, 144, 153, 132, 165, 207, 103, 62, 145, 79, 44, 157, 116, 122, 43,
+ 183, 185, 48, 86, 92, 61, 144, 13, 11, 100, 39, 227, 67, 141, 90,
+ 117, 22, 172, 16, 123, 186, 206, 150, 202, 50, 131, 88, 102, 48, 203,
+ 12, 97, 153, 221, 152, 37, 195, 132, 235, 162, 185, 206, 200, 148, 150,
+ 39, 4, 69, 19, 106, 50, 115, 211, 138, 205, 12, 164, 104, 39, 219,
+ 29, 192, 93, 0, 150, 117, 90, 134, 157, 27, 86, 76, 117, 150, 129,
+ 91, 163, 0, 125, 22, 181, 41, 165, 48, 110, 76, 47, 169, 127, 34,
+ 7, 193, 145, 252, 113, 82, 18, 55, 237, 233, 88, 33, 64, 209, 139,
+ 39, 187, 120, 74, 231, 221, 13, 208, 139, 167, 116, 82, 150, 0, 120,
+ 114, 99, 98, 106, 14, 159, 115, 248, 69, 210, 139, 0, 51, 172, 182,
+ 45, 35, 221, 44, 89, 110, 180, 201, 235, 219, 210, 205, 102, 73, 117,
+ 176, 118, 244, 198, 76, 110, 63, 225, 46, 68, 253, 178, 39, 113, 109,
+ 200, 226, 81, 67, 6, 63, 102, 242, 99, 22, 154, 196, 26, 230, 209,
+ 11, 124, 143, 184, 18, 200, 174, 91, 164, 137, 196, 57, 136, 14, 193,
+ 116, 8, 161, 3, 173, 77, 41, 194, 128, 252, 161, 186, 228, 173, 172,
+ 180, 8, 3, 116, 226, 138, 11, 128, 75, 55, 144, 71, 206, 50, 91,
+ 185, 7, 74, 208, 33, 141, 160, 33, 9, 94, 64, 90, 2, 102, 88,
+ 113, 58, 235, 221, 62, 76, 47, 45, 10, 184, 91, 242, 7, 76, 239,
+ 102, 204, 9, 30, 15, 33, 182, 103, 52, 101, 74, 105, 76, 19, 196,
+ 106, 19, 165, 196, 205, 58, 4, 46, 250, 104, 234, 17, 231, 50, 44,
+ 238, 11, 89, 176, 201, 88, 215, 60, 137, 115, 166, 81, 172, 146, 96,
+ 206, 144, 188, 175, 62, 195, 130, 238, 211, 49, 41, 137, 78, 228, 212,
+ 113, 34, 75, 108, 75, 162, 31, 52, 135, 147, 132, 14, 97, 101, 195,
+ 214, 144, 226, 66, 111, 173, 118, 35, 204, 63, 220, 46, 228, 96, 135,
+ 241, 215, 103, 164, 167, 231, 196, 5, 49, 171, 187, 12, 13, 144, 108,
+ 162, 30, 58, 99, 207, 166, 120, 138, 132, 11, 127, 14, 11, 142, 104,
+ 197, 12, 31, 203, 125, 153, 57, 45, 13, 54, 128, 174, 99, 224, 148,
+ 155, 70, 161, 137, 197, 12, 125, 72, 72, 144, 103, 9, 142, 132, 151,
+ 33, 169, 37, 67, 88, 124, 4, 110, 38, 24, 38, 218, 104, 195, 138,
+ 48, 91, 140, 137, 3, 36, 3, 40, 42, 160, 9, 50, 35, 103, 2,
+ 147, 101, 20, 253, 108, 138, 25, 70, 31, 135, 100, 58, 36, 208, 33,
+ 149, 77, 55, 64, 165, 113, 72, 166, 67, 2, 29, 82, 201, 252, 167,
+ 98, 253, 217, 236, 146, 37, 52, 219, 50, 172, 6, 150, 108, 197, 252,
+ 33, 42, 34, 145, 19, 19, 101, 206, 30, 173, 211, 27, 17, 237, 218,
+ 82, 115, 56, 62, 218, 49, 242, 198, 104, 22, 233, 204, 87, 56, 49,
+ 41, 70, 238, 3, 172, 252, 152, 204, 143, 9, 252, 152, 202, 143, 162,
+ 7, 0, 3, 167, 44, 90, 5, 240, 50, 131, 94, 112, 103, 206, 244,
+ 8, 130, 72, 62, 230, 36, 146, 15, 78, 228, 195, 233, 4, 93, 78,
+ 129, 191, 162, 224, 1, 188, 17, 209, 0, 143, 8, 69, 183, 1, 229,
+ 77, 193, 82, 177, 200, 28, 133, 9, 8, 152, 16, 11, 162, 48, 50,
+ 37, 55, 2, 95, 142, 131, 17, 150, 28, 28, 14, 70, 186, 76, 37,
+ 105, 46, 177, 72, 147, 13, 38, 44, 59, 216, 126, 30, 125, 232, 210,
+ 81, 202, 150, 205, 108, 136, 91, 40, 28, 48, 208, 1, 222, 32, 25,
+ 125, 160, 104, 129, 135, 123, 60, 108, 16, 131, 230, 12, 30, 180, 24,
+ 244, 201, 134, 209, 252, 56, 144, 31, 163, 88, 18, 92, 15, 98, 84,
+ 3, 10, 101, 91, 200, 87, 231, 240, 99, 146, 213, 48, 141, 51, 52,
+ 30, 49, 166, 207, 182, 37, 166, 176, 28, 58, 100, 235, 96, 159, 114,
+ 232, 144, 77, 139, 214, 134, 58, 252, 100, 211, 37, 33, 226, 129, 118,
+ 147, 173, 135, 17, 54, 81, 160, 13, 20, 10, 204, 141, 233, 124, 54,
+ 160, 96, 92, 127, 220, 33, 174, 77, 178, 203, 220, 185, 115, 78, 111,
+ 22, 199, 102, 182, 65, 201, 173, 182, 56, 155, 65, 236, 54, 133, 37,
+ 192, 179, 167, 35, 32, 163, 179, 88, 138, 56, 138, 1, 232, 108, 20,
+ 179, 200, 59, 163, 25, 113, 127, 3, 173, 20, 153, 36, 106, 94, 100,
+ 211, 205, 153, 70, 137, 69, 0, 153, 110, 192, 196, 5, 192, 110, 32,
+ 210, 15, 160, 232, 74, 52, 29, 56, 82, 76, 19, 144, 108, 53, 103,
+ 88, 104, 43, 129, 101, 67, 122, 29, 144, 132, 42, 136, 176, 80, 24,
+ 162, 48, 154, 25, 223, 39, 136, 177, 19, 102, 138, 229, 80, 136, 111,
+ 37, 171, 203, 157, 14, 31, 52, 154, 203, 242, 88, 20, 74, 121, 236,
+ 137, 5, 43, 80, 97, 109, 200, 39, 203, 215, 168, 164, 219, 38, 209,
+ 21, 11, 207, 33, 151, 174, 75, 19, 57, 93, 14, 15, 188, 18, 17,
+ 212, 241, 173, 150, 206, 74, 150, 133, 161, 139, 188, 91, 201, 86, 35,
+ 109, 87, 200, 193, 129, 210, 179, 89, 58, 4, 154, 141, 109, 64, 142,
+ 153, 226, 23, 30, 140, 242, 179, 142, 199, 53, 57, 82, 58, 71, 74,
+ 147, 216, 101, 38, 135, 163, 137, 187, 44, 106, 60, 1, 30, 9, 151,
+ 160, 85, 217, 210, 25, 110, 35, 33, 25, 19, 14, 187, 203, 123, 168,
+ 103, 220, 181, 96, 153, 51, 238, 6, 129, 46, 70, 12, 217, 252, 100,
+ 52, 241, 62, 34, 201, 207, 80, 66, 216, 35, 150, 106, 64, 152, 133,
+ 77, 41, 157, 117, 60, 244, 227, 44, 47, 98, 53, 243, 86, 51, 131,
+ 245, 36, 0, 163, 157, 92, 45, 136, 130, 1, 84, 161, 20, 204, 31,
+ 84, 204, 142, 117, 202, 18, 225, 175, 48, 43, 140, 162, 43, 152, 24,
+ 62, 61, 36, 70, 218, 174, 225, 76, 243, 150, 14, 243, 148, 32, 30,
+ 205, 188, 211, 169, 22, 51, 0, 224, 251, 80, 129, 118, 56, 180, 101,
+ 165, 157, 176, 168, 4, 36, 213, 108, 126, 164, 189, 130, 53, 135, 199,
+ 152, 105, 226, 34, 231, 187, 60, 113, 187, 107, 225, 209, 25, 109, 189,
+ 210, 200, 130, 144, 191, 228, 219, 48, 163, 61, 77, 220, 159, 235, 141,
+ 86, 73, 39, 145, 63, 169, 23, 237, 0, 147, 40, 146, 182, 242, 16,
+ 195, 36, 45, 89, 88, 157, 180, 12, 132, 116, 180, 183, 151, 55, 238,
+ 86, 131, 157, 246, 213, 52, 38, 178, 131, 216, 1, 33, 39, 195, 106,
+ 74, 202, 48, 37, 210, 30, 40, 128, 174, 88, 152, 217, 108, 33, 33,
+ 217, 140, 124, 173, 5, 112, 179, 64, 198, 1, 195, 66, 199, 121, 100,
+ 193, 239, 203, 241, 208, 10, 61, 20, 21, 75, 148, 45, 133, 58, 113,
+ 80, 155, 180, 20, 49, 178, 176, 24, 179, 227, 160, 124, 113, 124, 3,
+ 110, 207, 182, 75, 114, 2, 71, 183, 152, 3, 44, 57, 113, 100, 234,
+ 56, 99, 200, 228, 174, 25, 28, 100, 96, 23, 253, 154, 232, 250, 116,
+ 153, 6, 238, 202, 236, 134, 116, 11, 13, 191, 7, 166, 129, 26, 114,
+ 243, 98, 56, 234, 78, 81, 175, 50, 220, 9, 218, 217, 32, 67, 153,
+ 180, 25, 166, 201, 201, 28, 123, 138, 217, 228, 78, 217, 72, 251, 221,
+ 9, 105, 63, 104, 147, 125, 149, 141, 235, 35, 95, 222, 100, 80, 56,
+ 3, 239, 174, 19, 23, 60, 95, 68, 220, 222, 219, 105, 147, 164, 207,
+ 22, 249, 28, 226, 115, 152, 184, 20, 196, 117, 192, 75, 98, 42, 69,
+ 179, 9, 134, 108, 40, 87, 35, 114, 247, 32, 93, 170, 157, 223, 153,
+ 201, 164, 72, 25, 209, 35, 246, 7, 136, 255, 2, 16, 0, 6, 32,
+ 2, 12, 224, 197, 3, 16, 119, 34, 224, 48, 100, 160, 233, 148, 105,
+ 48, 64, 70, 147, 148, 202, 154, 70, 24, 30, 155, 64, 5, 41, 224,
+ 68, 38, 157, 40, 41, 181, 195, 121, 131, 85, 50, 172, 118, 143, 193,
+ 193, 181, 108, 58, 228, 240, 18, 113, 182, 44, 4, 163, 156, 51, 144,
+ 221, 165, 43, 98, 30, 49, 98, 22, 93, 5, 4, 191, 117, 33, 178,
+ 124, 13, 113, 179, 7, 45, 163, 60, 90, 80, 201, 6, 113, 223, 141,
+ 138, 202, 36, 93, 38, 45, 232, 216, 33, 211, 108, 212, 75, 5, 202,
+ 103, 240, 225, 98, 178, 245, 50, 128, 156, 226, 253, 230, 234, 157, 97,
+ 228, 75, 72, 188, 141, 35, 121, 37, 218, 210, 192, 206, 113, 223, 64,
+ 235, 64, 186, 233, 67, 81, 99, 55, 178, 224, 54, 67, 16, 29, 130,
+ 233, 16, 194, 32, 13, 189, 217, 196, 111, 44, 96, 69, 114, 80, 210,
+ 7, 190, 200, 172, 217, 160, 28, 177, 42, 101, 144, 136, 160, 74, 162,
+ 156, 197, 35, 13, 26, 242, 230, 235, 145, 210, 112, 42, 144, 21, 114,
+ 68, 38, 93, 151, 152, 66, 203, 64, 220, 225, 243, 18, 124, 199, 101,
+ 32, 173, 195, 153, 124, 19, 133, 201, 220, 95, 138, 93, 224, 67, 225,
+ 183, 207, 96, 33, 147, 2, 249, 145, 119, 120, 154, 120, 228, 253, 158,
+ 22, 130, 192, 108, 154, 164, 135, 34, 99, 225, 55, 29, 209, 4, 44,
+ 10, 173, 38, 110, 101, 48, 26, 126, 203, 9, 97, 173, 184, 156, 16,
+ 86, 240, 190, 99, 203, 75, 55, 90, 40, 34, 68, 244, 74, 71, 132,
+ 167, 60, 80, 32, 51, 38, 37, 121, 52, 140, 184, 49, 81, 140, 235,
+ 40, 234, 48, 233, 16, 125, 144, 150, 138, 91, 122, 132, 120, 226, 54,
+ 144, 70, 194, 221, 14, 213, 225, 97, 111, 138, 49, 77, 79, 140, 168,
+ 151, 4, 139, 16, 131, 20, 132, 74, 82, 207, 176, 113, 16, 55, 254,
+ 48, 199, 54, 38, 25, 15, 19, 98, 46, 115, 22, 109, 216, 209, 65,
+ 88, 124, 222, 35, 244, 156, 239, 221, 41, 250, 183, 88, 13, 10, 239,
+ 71, 238, 221, 227, 39, 197, 158, 80, 21, 168, 165, 89, 12, 17, 204,
+ 180, 167, 33, 247, 193, 131, 44, 233, 182, 25, 122, 153, 158, 32, 174,
+ 107, 92, 12, 225, 251, 158, 100, 233, 204, 131, 209, 116, 76, 191, 45,
+ 205, 204, 55, 76, 220, 87, 100, 99, 71, 238, 137, 80, 41, 135, 162,
+ 91, 218, 96, 73, 230, 141, 16, 221, 60, 76, 1, 44, 64, 0, 217,
+ 68, 186, 141, 151, 68, 13, 33, 108, 227, 231, 116, 115, 134, 205, 16,
+ 135, 136, 194, 16, 103, 53, 112, 67, 72, 119, 123, 232, 10, 212, 206,
+ 150, 102, 148, 78, 113, 162, 109, 149, 18, 8, 219, 36, 206, 144, 35,
+ 115, 114, 94, 10, 65, 80, 85, 210, 118, 27, 2, 65, 152, 116, 140,
+ 54, 93, 202, 166, 218, 18, 135, 218, 110, 78, 206, 75, 193, 254, 134,
+ 240, 109, 8, 12, 245, 54, 66, 181, 81, 35, 6, 202, 51, 80, 158,
+ 129, 242, 12, 200, 75, 162, 114, 73, 84, 46, 137, 202, 37, 241, 114,
+ 54, 125, 10, 56, 58, 80, 141, 36, 170, 145, 68, 53, 146, 168, 6,
+ 228, 71, 141, 227, 200, 121, 3, 231, 169, 150, 137, 208, 77, 132, 110,
+ 202, 2, 161, 54, 229, 36, 81, 78, 18, 114, 146, 40, 199, 12, 95,
+ 23, 20, 220, 11, 138, 135, 64, 138, 51, 220, 253, 137, 89, 70, 41,
+ 75, 188, 241, 141, 164, 196, 137, 158, 211, 76, 62, 131, 132, 164, 75,
+ 163, 57, 98, 208, 69, 76, 8, 229, 75, 215, 113, 129, 79, 150, 24,
+ 0, 199, 97, 30, 40, 0, 21, 79, 113, 146, 42, 74, 41, 110, 108,
+ 168, 42, 221, 59, 227, 53, 137, 129, 30, 27, 249, 125, 56, 126, 206,
+ 145, 90, 71, 236, 153, 38, 222, 99, 19, 91, 140, 147, 235, 208, 21,
+ 44, 26, 40, 53, 178, 220, 146, 15, 72, 164, 37, 225, 185, 245, 200,
+ 232, 230, 113, 0, 15, 41, 2, 192, 114, 134, 246, 233, 226, 182, 132,
+ 116, 151, 124, 121, 0, 48, 41, 130, 225, 102, 152, 14, 193, 244, 248,
+ 34, 217, 96, 31, 225, 222, 24, 219, 205, 201, 201, 105, 6, 57, 137,
+ 74, 25, 34, 135, 30, 43, 19, 88, 17, 70, 93, 154, 92, 142, 22,
+ 56, 173, 53, 43, 221, 69, 75, 163, 157, 3, 236, 53, 67, 56, 15,
+ 61, 52, 80, 104, 79, 27, 66, 121, 247, 141, 234, 50, 79, 101, 196,
+ 200, 129, 34, 160, 145, 226, 253, 97, 104, 60, 157, 121, 129, 4, 179,
+ 62, 71, 220, 179, 103, 164, 65, 213, 105, 179, 64, 243, 66, 203, 3,
+ 203, 58, 64, 60, 27, 77, 60, 252, 163, 139, 193, 140, 246, 239, 162,
+ 132, 211, 115, 96, 118, 113, 209, 146, 97, 231, 143, 22, 108, 98, 105,
+ 68, 77, 33, 244, 36, 64, 76, 209, 196, 128, 232, 214, 142, 190, 59,
+ 183, 24, 124, 171, 47, 198, 217, 60, 72, 53, 98, 59, 79, 251, 7,
+ 216, 88, 61, 197, 75, 201, 220, 32, 83, 130, 143, 208, 125, 63, 36,
+ 88, 230, 96, 98, 77, 122, 184, 135, 0, 30, 36, 96, 188, 169, 134,
+ 68, 179, 5, 145, 28, 191, 243, 170, 167, 251, 14, 250, 73, 65, 212,
+ 65, 3, 173, 243, 113, 20, 80, 163, 5, 50, 31, 60, 156, 229, 19,
+ 194, 173, 167, 116, 63, 129, 243, 210, 45, 4, 90, 222, 58, 180, 226,
+ 169, 131, 201, 206, 72, 187, 35, 75, 175, 55, 232, 43, 43, 105, 182,
+ 167, 24, 172, 212, 60, 172, 30, 249, 113, 168, 14, 78, 100, 233, 41,
+ 32, 231, 113, 28, 140, 32, 120, 169, 101, 200, 221, 205, 33, 38, 16,
+ 123, 64, 55, 167, 68, 142, 180, 203, 106, 4, 0, 221, 24, 129, 117,
+ 139, 131, 54, 197, 5, 201, 28, 221, 20, 53, 235, 220, 185, 30, 30,
+ 106, 103, 142, 134, 70, 200, 250, 19, 96, 55, 75, 162, 39, 113, 199,
+ 144, 86, 39, 195, 10, 39, 98, 2, 210, 176, 103, 226, 240, 180, 129,
+ 21, 109, 59, 111, 94, 230, 225, 45, 165, 4, 114, 185, 167, 161, 28,
+ 206, 240, 108, 49, 11, 222, 139, 130, 94, 8, 150, 159, 3, 232, 168,
+ 75, 179, 241, 93, 25, 109, 29, 233, 44, 62, 21, 9, 224, 55, 78,
+ 249, 237, 40, 242, 60, 196, 208, 253, 77, 29, 127, 162, 68, 30, 0,
+ 110, 147, 223, 11, 193, 58, 147, 166, 134, 183, 195, 239, 251, 240, 172,
+ 32, 73, 144, 65, 242, 53, 145, 35, 31, 238, 174, 65, 188, 52, 137,
+ 238, 193, 72, 0, 138, 71, 6, 226, 141, 92, 43, 53, 75, 12, 38,
+ 128, 223, 54, 166, 4, 73, 73, 7, 149, 32, 85, 162, 187, 136, 210,
+ 189, 150, 0, 186, 217, 194, 55, 147, 20, 211, 27, 249, 67, 138, 0,
+ 76, 60, 221, 183, 7, 182, 123, 52, 124, 103, 66, 207, 190, 232, 44,
+ 46, 92, 189, 24, 61, 195, 185, 26, 164, 123, 79, 110, 221, 163, 218,
+ 18, 47, 173, 58, 186, 65, 79, 119, 12, 161, 229, 113, 162, 138, 103,
+ 154, 177, 129, 32, 189, 54, 153, 248, 95, 5, 176, 67, 165, 50, 68,
+ 185, 89, 232, 109, 92, 210, 158, 184, 100, 56, 64, 146, 152, 200, 144,
+ 238, 232, 232, 54, 131, 180, 123, 226, 235, 114, 82, 207, 201, 76, 188,
+ 106, 182, 160, 9, 171, 251, 182, 147, 152, 114, 171, 50, 51, 97, 183,
+ 66, 237, 218, 248, 34, 69, 239, 229, 12, 10, 192, 177, 66, 41, 114,
+ 10, 72, 38, 91, 199, 183, 108, 201, 210, 131, 39, 158, 195, 111, 228,
+ 209, 83, 72, 138, 51, 184, 43, 231, 174, 151, 162, 70, 126, 79, 84,
+ 103, 76, 163, 51, 162, 29, 143, 36, 224, 174, 61, 9, 186, 249, 98,
+ 47, 23, 74, 40, 2, 139, 4, 132, 132, 28, 52, 145, 30, 111, 136,
+ 240, 6, 91, 16, 29, 184, 129, 8, 225, 227, 21, 227, 47, 29, 177,
+ 208, 69, 126, 66, 175, 96, 50, 12, 38, 190, 214, 165, 199, 47, 210,
+ 189, 68, 108, 117, 68, 69, 73, 227, 61, 11, 128, 242, 64, 138, 180,
+ 50, 104, 254, 40, 60, 225, 83, 109, 35, 195, 41, 26, 116, 190, 170,
+ 166, 211, 146, 158, 158, 46, 190, 77, 19, 51, 33, 186, 255, 139, 244,
+ 188, 159, 158, 94, 100, 240, 35, 182, 155, 88, 10, 25, 226, 137, 98,
+ 147, 52, 51, 100, 151, 193, 143, 124, 177, 98, 222, 51, 48, 195, 140,
+ 2, 107, 54, 140, 2, 146, 97, 16, 90, 20, 245, 29, 17, 83, 176,
+ 141, 31, 141, 252, 152, 196, 143, 180, 13, 79, 12, 225, 57, 33, 60,
+ 39, 132, 231, 116, 227, 57, 221, 120, 78, 55, 172, 83, 204, 63, 29,
+ 146, 216, 224, 126, 64, 76, 176, 234, 16, 42, 15, 198, 150, 122, 168,
+ 33, 39, 138, 239, 107, 193, 176, 49, 124, 159, 203, 91, 141, 193, 38,
+ 109, 24, 137, 148, 24, 22, 205, 159, 55, 14, 32, 119, 220, 87, 188,
+ 165, 50, 152, 111, 58, 249, 35, 207, 193, 233, 81, 25, 73, 108, 56,
+ 10, 50, 201, 162, 16, 27, 205, 31, 89, 17, 215, 55, 170, 31, 185,
+ 203, 190, 244, 44, 49, 10, 129, 42, 235, 111, 202, 28, 14, 87, 58,
+ 140, 172, 196, 120, 236, 29, 217, 112, 201, 185, 177, 113, 3, 232, 78,
+ 60, 63, 242, 58, 195, 17, 36, 247, 167, 232, 154, 152, 40, 29, 84,
+ 38, 138, 84, 46, 202, 156, 205, 162, 12, 211, 99, 208, 91, 244, 40,
+ 42, 218, 76, 51, 57, 130, 158, 42, 244, 229, 143, 17, 162, 233, 41,
+ 2, 70, 39, 166, 134, 15, 160, 152, 128, 31, 7, 163, 92, 140, 152,
+ 236, 103, 160, 123, 172, 227, 197, 232, 33, 138, 54, 21, 82, 214, 56,
+ 114, 107, 195, 197, 35, 250, 204, 134, 143, 17, 111, 154, 15, 167, 133,
+ 60, 50, 113, 48, 180, 5, 93, 183, 35, 211, 192, 134, 209, 200, 19,
+ 196, 122, 3, 249, 93, 132, 132, 72, 241, 150, 117, 66, 52, 221, 178,
+ 30, 70, 49, 249, 120, 126, 243, 105, 52, 191, 157, 196, 5, 57, 154,
+ 47, 32, 62, 192, 49, 124, 91, 42, 86, 29, 128, 13, 145, 52, 187,
+ 81, 3, 233, 70, 203, 56, 236, 218, 67, 250, 241, 83, 112, 63, 54,
+ 134, 66, 27, 18, 25, 103, 162, 200, 191, 114, 110, 12, 188, 51, 103,
+ 184, 120, 16, 65, 65, 117, 33, 92, 158, 53, 146, 238, 20, 136, 21,
+ 185, 188, 56, 203, 37, 58, 22, 110, 19, 253, 102, 9, 99, 196, 125,
+ 24, 78, 124, 200, 56, 247, 215, 83, 201, 68, 107, 36, 118, 112, 140,
+ 64, 7, 166, 153, 19, 32, 156, 49, 180, 225, 225, 210, 224, 156, 36,
+ 97, 222, 60, 118, 153, 252, 246, 101, 127, 186, 109, 3, 85, 238, 47,
+ 62, 153, 136, 202, 192, 114, 7, 15, 129, 88, 237, 238, 179, 49, 17,
+ 221, 36, 177, 83, 134, 56, 117, 152, 167, 244, 4, 54, 56, 85, 199,
+ 202, 117, 120, 140, 33, 141, 244, 172, 31, 162, 195, 145, 38, 140, 147,
+ 98, 50, 236, 104, 232, 18, 230, 23, 206, 140, 54, 199, 44, 97, 4,
+ 60, 238, 24, 110, 140, 89, 194, 112, 10, 216, 221, 137, 24, 51, 22,
+ 157, 59, 1, 253, 78, 48, 235, 172, 122, 119, 218, 93, 223, 157, 238,
+ 235, 54, 222, 238, 12, 8, 204, 131, 59, 26, 122, 107, 78, 247, 164,
+ 228, 106, 208, 10, 27, 102, 214, 157, 244, 160, 185, 111, 192, 179, 132,
+ 254, 217, 216, 6, 217, 8, 154, 114, 209, 50, 191, 169, 33, 242, 145,
+ 210, 205, 121, 112, 122, 189, 184, 122, 20, 89, 92, 149, 60, 233, 49,
+ 164, 251, 119, 36, 1, 143, 57, 191, 179, 38, 87, 43, 79, 210, 61,
+ 86, 79, 206, 157, 21, 160, 87, 158, 132, 168, 132, 138, 180, 188, 149,
+ 242, 228, 113, 149, 245, 36, 197, 249, 241, 164, 165, 105, 145, 51, 198,
+ 136, 254, 59, 97, 140, 232, 198, 196, 190, 147, 101, 163, 231, 213, 146,
+ 30, 243, 225, 112, 92, 178, 69, 98, 15, 137, 227, 89, 238, 88, 37,
+ 146, 60, 4, 61, 47, 224, 11, 172, 175, 116, 23, 80, 154, 42, 119,
+ 146, 227, 185, 23, 162, 167, 247, 80, 2, 88, 180, 116, 218, 203, 42,
+ 51, 99, 232, 201, 78, 140, 89, 153, 53, 218, 76, 78, 121, 152, 49,
+ 213, 160, 204, 29, 134, 64, 177, 98, 238, 0, 114, 219, 89, 100, 114,
+ 42, 32, 136, 34, 119, 231, 177, 152, 97, 253, 71, 168, 152, 138, 169,
+ 241, 207, 71, 250, 87, 3, 254, 161, 6, 254, 249, 240, 163, 31, 171,
+ 141, 127, 141, 113, 246, 99, 254, 252, 24, 200, 202, 88, 52, 107, 202,
+ 236, 224, 27, 48, 61, 40, 141, 249, 243, 151, 153, 162, 217, 110, 245,
+ 78, 22, 173, 106, 204, 22, 168, 178, 217, 65, 214, 141, 249, 169, 34,
+ 112, 101, 16, 155, 139, 171, 97, 168, 19, 200, 126, 229, 229, 106, 163,
+ 214, 32, 28, 207, 169, 136, 163, 150, 232, 207, 147, 15, 67, 78, 103,
+ 22, 129, 84, 182, 234, 28, 235, 128, 242, 53, 52, 11, 52, 253, 192,
+ 181, 97, 139, 85, 22, 148, 41, 96, 11, 24, 33, 174, 102, 155, 88,
+ 44, 107, 160, 166, 214, 27, 179, 175, 80, 47, 2, 189, 184, 128, 252,
+ 166, 232, 85, 99, 92, 101, 172, 23, 35, 140, 77, 64, 44, 21, 191,
+ 187, 69, 235, 53, 144, 26, 196, 82, 64, 157, 113, 45, 141, 193, 243,
+ 160, 55, 249, 232, 65, 24, 48, 194, 128, 86, 67, 21, 1, 132, 97,
+ 44, 27, 165, 155, 2, 163, 27, 40, 13, 184, 84, 127, 53, 242, 44,
+ 170, 6, 168, 81, 128, 178, 139, 89, 60, 80, 196, 127, 62, 104, 115,
+ 76, 204, 232, 190, 203, 80, 238, 33, 204, 229, 67, 252, 172, 98, 181,
+ 192, 215, 228, 164, 1, 190, 56, 203, 106, 86, 141, 213, 145, 231, 187,
+ 26, 171, 11, 222, 23, 156, 47, 248, 135, 193, 139, 51, 95, 13, 189,
+ 208, 200, 101, 124, 88, 117, 86, 15, 105, 119, 57, 95, 164, 235, 35,
+ 237, 46, 91, 3, 233, 71, 100, 9, 138, 229, 169, 100, 3, 126, 244,
+ 212, 241, 197, 191, 71, 121, 29, 79, 189, 26, 200, 107, 40, 73, 222,
+ 7, 61, 245, 65, 207, 125, 208, 243, 70, 188, 30, 93, 173, 9, 122,
+ 8, 84, 11, 163, 172, 129, 20, 3, 169, 192, 215, 102, 77, 48, 18,
+ 198, 71, 64, 61, 247, 67, 141, 122, 200, 171, 142, 107, 245, 65, 143,
+ 224, 90, 3, 16, 181, 216, 144, 95, 123, 76, 186, 70, 232, 141, 192,
+ 169, 81, 90, 141, 92, 186, 246, 56, 80, 31, 71, 233, 199, 129, 237,
+ 139, 35, 225, 169, 33, 3, 53, 107, 6, 106, 206, 203, 212, 100, 45,
+ 144, 83, 155, 99, 60, 14, 125, 100, 172, 37, 242, 91, 161, 124, 107,
+ 96, 182, 1, 82, 91, 92, 107, 39, 213, 105, 15, 234, 0, 234, 136,
+ 84, 53, 228, 7, 128, 239, 4, 234, 12, 234, 194, 241, 154, 35, 191,
+ 57, 80, 154, 243, 183, 227, 186, 34, 239, 9, 80, 32, 90, 169, 195,
+ 219, 96, 44, 8, 233, 96, 80, 8, 240, 187, 161, 92, 119, 80, 15,
+ 164, 123, 130, 122, 225, 122, 111, 156, 251, 128, 66, 209, 183, 48, 244,
+ 136, 230, 62, 28, 164, 149, 234, 137, 125, 110, 137, 249, 33, 60, 177,
+ 95, 52, 46, 1, 20, 129, 126, 71, 130, 162, 64, 125, 65, 253, 64,
+ 253, 65, 3, 64, 3, 65, 131, 248, 120, 154, 177, 193, 24, 97, 125,
+ 169, 63, 143, 98, 164, 67, 48, 210, 161, 160, 97, 192, 24, 46, 225,
+ 141, 0, 141, 4, 69, 131, 70, 129, 70, 131, 198, 128, 98, 64, 99,
+ 209, 143, 113, 160, 241, 232, 95, 44, 16, 27, 34, 111, 2, 104, 34,
+ 104, 18, 232, 73, 204, 216, 100, 204, 214, 20, 224, 199, 209, 27, 213,
+ 244, 198, 52, 40, 1, 125, 72, 4, 233, 81, 198, 0, 74, 2, 159,
+ 12, 74, 1, 25, 65, 83, 65, 169, 160, 52, 80, 58, 200, 132, 217,
+ 174, 203, 251, 88, 147, 153, 233, 77, 86, 208, 52, 180, 107, 5, 217,
+ 144, 103, 71, 153, 12, 80, 38, 40, 11, 121, 217, 200, 203, 193, 121,
+ 58, 159, 167, 142, 92, 63, 149, 248, 51, 184, 30, 248, 112, 201, 85,
+ 147, 198, 73, 125, 39, 189, 153, 137, 242, 179, 32, 205, 218, 188, 239,
+ 173, 88, 46, 40, 15, 229, 243, 165, 57, 126, 74, 158, 91, 31, 54,
+ 27, 52, 71, 154, 171, 17, 24, 103, 107, 62, 151, 190, 176, 74, 190,
+ 236, 105, 208, 60, 208, 124, 208, 2, 208, 66, 208, 34, 208, 51, 40,
+ 187, 24, 180, 4, 180, 84, 106, 219, 141, 187, 12, 180, 28, 180, 2,
+ 180, 18, 121, 171, 64, 171, 65, 107, 64, 79, 128, 214, 130, 214, 129,
+ 214, 131, 158, 149, 230, 102, 3, 151, 37, 245, 179, 3, 219, 136, 241,
+ 108, 66, 223, 55, 227, 250, 22, 104, 99, 83, 133, 110, 60, 199, 231,
+ 89, 13, 11, 83, 113, 174, 159, 7, 189, 0, 218, 10, 122, 17, 180,
+ 13, 180, 29, 180, 3, 229, 119, 130, 118, 41, 244, 233, 37, 208, 203,
+ 160, 221, 200, 223, 3, 122, 5, 173, 239, 149, 245, 169, 11, 159, 197,
+ 250, 60, 221, 21, 250, 43, 182, 79, 237, 22, 222, 209, 238, 62, 208,
+ 126, 208, 1, 208, 65, 208, 171, 160, 215, 64, 135, 64, 135, 65, 175,
+ 131, 142, 128, 138, 64, 197, 160, 18, 144, 3, 228, 4, 185, 64, 111,
+ 128, 142, 130, 142, 1, 251, 77, 232, 195, 113, 208, 9, 200, 227, 57,
+ 208, 91, 200, 59, 9, 122, 27, 244, 14, 232, 93, 148, 123, 15, 116,
+ 10, 244, 62, 232, 3, 122, 91, 22, 180, 7, 244, 33, 232, 35, 148,
+ 57, 13, 250, 24, 117, 63, 145, 117, 216, 61, 174, 174, 236, 12, 234,
+ 124, 10, 250, 12, 244, 57, 232, 11, 208, 151, 40, 243, 21, 168, 30,
+ 31, 247, 19, 176, 95, 226, 58, 250, 26, 244, 13, 174, 127, 43, 201,
+ 182, 57, 95, 245, 180, 62, 130, 96, 179, 130, 248, 202, 87, 73, 50,
+ 41, 148, 202, 148, 221, 97, 75, 191, 3, 125, 15, 250, 1, 244, 35,
+ 232, 39, 208, 207, 160, 39, 64, 191, 112, 157, 246, 133, 191, 243, 101,
+ 191, 193, 18, 136, 235, 63, 132, 253, 14, 59, 114, 22, 116, 78, 234,
+ 243, 31, 18, 246, 159, 40, 111, 64, 217, 243, 124, 189, 249, 194, 151,
+ 249, 178, 139, 160, 191, 64, 127, 195, 242, 144, 13, 254, 7, 116, 9,
+ 101, 47, 131, 174, 128, 174, 162, 151, 215, 232, 5, 111, 208, 191, 160,
+ 27, 176, 78, 212, 183, 155, 82, 185, 91, 160, 107, 160, 27, 176, 88,
+ 245, 65, 12, 228, 30, 211, 109, 158, 47, 182, 205, 84, 106, 166, 2,
+ 169, 65, 26, 144, 15, 168, 26, 168, 58, 200, 87, 5, 31, 0, 170,
+ 169, 234, 206, 30, 82, 117, 99, 181, 84, 61, 177, 226, 60, 99, 169,
+ 173, 162, 177, 180, 99, 117, 84, 237, 88, 93, 21, 141, 169, 23, 123,
+ 88, 5, 47, 172, 162, 177, 213, 98, 245, 80, 183, 190, 74, 57, 46,
+ 31, 110, 75, 30, 81, 209, 152, 197, 246, 27, 224, 250, 163, 160, 134,
+ 160, 70, 138, 126, 208, 90, 234, 6, 34, 95, 208, 24, 215, 154, 128,
+ 30, 3, 61, 14, 106, 10, 106, 6, 106, 14, 195, 221, 2, 228, 175,
+ 122, 130, 181, 84, 245, 70, 191, 122, 115, 171, 172, 98, 238, 254, 54,
+ 98, 173, 64, 173, 85, 162, 175, 105, 131, 115, 91, 80, 59, 80, 123,
+ 80, 7, 149, 91, 254, 110, 31, 231, 195, 58, 170, 200, 159, 244, 129,
+ 174, 104, 88, 128, 74, 195, 58, 129, 58, 131, 186, 160, 157, 174, 160,
+ 219, 104, 225, 9, 156, 253, 96, 245, 201, 103, 6, 168, 124, 80, 198,
+ 7, 101, 124, 42, 41, 19, 198, 113, 3, 113, 45, 8, 109, 5, 243,
+ 60, 198, 66, 84, 226, 90, 239, 166, 18, 125, 68, 119, 85, 77, 214,
+ 67, 21, 206, 125, 126, 79, 180, 223, 75, 165, 133, 62, 10, 72, 135,
+ 179, 222, 40, 211, 7, 20, 138, 216, 132, 244, 47, 76, 129, 115, 27,
+ 43, 222, 7, 231, 25, 160, 100, 250, 210, 0, 100, 132, 5, 32, 31,
+ 26, 174, 234, 139, 113, 121, 100, 165, 85, 185, 245, 206, 45, 159, 154,
+ 76, 64, 187, 17, 160, 72, 96, 71, 169, 4, 214, 87, 21, 201, 250,
+ 169, 162, 88, 127, 212, 29, 192, 101, 215, 143, 13, 196, 245, 65, 104,
+ 191, 29, 104, 176, 234, 78, 61, 85, 179, 33, 210, 28, 14, 229, 50,
+ 245, 101, 195, 80, 111, 184, 170, 191, 228, 67, 61, 250, 53, 130, 151,
+ 99, 108, 36, 250, 30, 13, 26, 5, 106, 198, 215, 73, 119, 54, 90,
+ 229, 238, 215, 0, 30, 35, 145, 157, 31, 195, 231, 166, 29, 139, 81,
+ 13, 68, 222, 64, 122, 231, 157, 251, 233, 177, 42, 242, 169, 237, 96,
+ 203, 61, 118, 115, 28, 202, 142, 7, 197, 130, 38, 160, 208, 68, 232,
+ 227, 36, 208, 147, 178, 78, 210, 28, 12, 98, 147, 85, 131, 217, 20,
+ 94, 95, 156, 143, 56, 62, 39, 181, 88, 60, 159, 143, 33, 76, 39,
+ 233, 106, 2, 206, 137, 42, 113, 140, 122, 149, 184, 30, 13, 56, 39,
+ 129, 146, 65, 41, 32, 163, 202, 151, 199, 142, 110, 251, 48, 21, 237,
+ 166, 130, 210, 64, 233, 32, 19, 198, 107, 6, 89, 64, 211, 64, 86,
+ 144, 13, 100, 7, 101, 128, 50, 81, 63, 11, 148, 13, 202, 1, 77,
+ 7, 205, 0, 205, 4, 205, 2, 229, 130, 242, 128, 147, 15, 122, 10,
+ 244, 39, 198, 62, 91, 69, 118, 172, 22, 155, 131, 126, 207, 5, 61,
+ 13, 154, 199, 229, 51, 128, 205, 7, 45, 64, 157, 133, 192, 94, 4,
+ 122, 6, 124, 16, 230, 99, 49, 104, 137, 74, 180, 71, 75, 81, 126,
+ 153, 106, 40, 188, 143, 199, 230, 23, 72, 62, 98, 57, 202, 175, 0,
+ 173, 4, 173, 2, 173, 6, 173, 1, 173, 5, 173, 3, 173, 87, 137,
+ 118, 255, 117, 201, 246, 63, 11, 204, 13, 200, 219, 8, 218, 4, 218,
+ 140, 54, 183, 112, 189, 246, 101, 207, 33, 93, 0, 122, 30, 244, 2,
+ 104, 43, 232, 69, 208, 54, 208, 118, 208, 14, 208, 78, 208, 46, 208,
+ 75, 168, 243, 50, 104, 55, 104, 15, 232, 21, 21, 217, 119, 146, 27,
+ 217, 118, 26, 239, 48, 62, 191, 123, 113, 173, 16, 180, 79, 210, 183,
+ 253, 56, 31, 0, 29, 4, 189, 10, 122, 13, 116, 8, 116, 24, 244,
+ 58, 48, 142, 0, 187, 8, 84, 12, 42, 81, 13, 199, 90, 29, 142,
+ 25, 28, 14, 29, 34, 153, 249, 192, 158, 251, 112, 28, 7, 202, 59,
+ 85, 20, 71, 140, 224, 54, 199, 165, 18, 125, 247, 27, 56, 31, 5,
+ 29, 227, 237, 137, 114, 122, 19, 116, 28, 116, 2, 244, 22, 232, 36,
+ 174, 189, 13, 122, 7, 244, 46, 232, 61, 80, 56, 234, 158, 194, 249,
+ 125, 208, 7, 160, 82, 208, 135, 160, 143, 64, 167, 97, 139, 62, 6,
+ 125, 2, 254, 12, 232, 83, 208, 103, 160, 207, 65, 95, 128, 190, 148,
+ 236, 194, 87, 56, 127, 13, 250, 6, 244, 45, 168, 140, 143, 1, 62,
+ 7, 244, 61, 232, 7, 208, 143, 208, 137, 159, 64, 63, 131, 126, 1,
+ 253, 170, 26, 201, 119, 63, 245, 177, 54, 126, 131, 140, 127, 71, 250,
+ 172, 138, 98, 14, 232, 56, 198, 255, 135, 42, 154, 253, 73, 250, 173,
+ 162, 241, 143, 98, 23, 160, 55, 23, 85, 195, 216, 95, 92, 127, 70,
+ 192, 126, 208, 92, 143, 134, 189, 162, 58, 20, 15, 186, 109, 44, 108,
+ 9, 249, 33, 156, 255, 65, 95, 46, 129, 46, 3, 227, 138, 106, 12,
+ 34, 153, 49, 244, 93, 9, 159, 211, 171, 184, 126, 13, 116, 29, 244,
+ 47, 232, 6, 232, 38, 201, 159, 124, 17, 234, 220, 150, 100, 199, 212,
+ 226, 252, 171, 212, 176, 245, 32, 13, 200, 71, 45, 206, 49, 197, 191,
+ 213, 212, 240, 175, 32, 95, 181, 24, 127, 158, 87, 209, 120, 176, 51,
+ 66, 153, 154, 160, 135, 64, 181, 64, 181, 65, 117, 64, 117, 65, 15,
+ 83, 125, 80, 61, 80, 125, 208, 35, 168, 219, 0, 244, 168, 122, 52,
+ 107, 168, 30, 195, 26, 169, 99, 96, 143, 26, 193, 174, 208, 190, 163,
+ 33, 107, 172, 110, 200, 154, 128, 30, 67, 153, 199, 65, 77, 65, 205,
+ 64, 205, 81, 183, 5, 200, 31, 212, 18, 212, 74, 61, 22, 241, 192,
+ 88, 178, 58, 210, 24, 125, 88, 107, 96, 181, 81, 215, 100, 109, 213,
+ 181, 88, 59, 181, 103, 207, 209, 30, 229, 59, 128, 58, 130, 2, 212,
+ 180, 175, 17, 125, 78, 39, 240, 157, 213, 62, 124, 127, 20, 170, 162,
+ 62, 140, 67, 140, 60, 14, 152, 227, 36, 76, 236, 71, 80, 166, 43,
+ 199, 133, 223, 83, 139, 117, 8, 43, 16, 237, 4, 225, 28, 140, 105,
+ 11, 1, 117, 3, 223, 29, 212, 67, 77, 243, 175, 102, 61, 193, 247,
+ 2, 245, 86, 147, 157, 25, 15, 29, 31, 15, 220, 241, 114, 95, 63,
+ 97, 30, 204, 191, 201, 143, 168, 99, 209, 126, 44, 202, 196, 202, 101,
+ 234, 33, 146, 10, 5, 94, 24, 240, 195, 65, 90, 144, 160, 22, 237,
+ 106, 132, 90, 92, 107, 145, 56, 71, 129, 250, 226, 90, 63, 156, 251,
+ 171, 41, 6, 87, 179, 1, 56, 15, 68, 31, 7, 225, 60, 88, 61,
+ 17, 154, 54, 17, 216, 19, 21, 216, 212, 126, 45, 54, 68, 26, 207,
+ 80, 181, 219, 223, 210, 184, 38, 129, 159, 132, 242, 147, 238, 40, 223,
+ 138, 13, 83, 139, 250, 214, 71, 45, 174, 7, 170, 59, 28, 52, 130,
+ 250, 133, 113, 55, 151, 108, 64, 103, 245, 147, 168, 243, 36, 48, 158,
+ 148, 49, 70, 170, 91, 176, 104, 140, 103, 20, 104, 52, 205, 29, 151,
+ 129, 15, 27, 3, 138, 1, 238, 88, 200, 125, 28, 104, 60, 250, 29,
+ 11, 154, 0, 154, 168, 158, 44, 237, 97, 177, 39, 66, 185, 39, 49,
+ 206, 201, 160, 41, 160, 56, 80, 60, 72, 7, 74, 0, 37, 130, 244,
+ 192, 53, 168, 197, 125, 105, 18, 202, 207, 82, 77, 65, 63, 196, 189,
+ 109, 50, 198, 155, 2, 50, 170, 71, 178, 169, 40, 147, 10, 74, 3,
+ 165, 131, 76, 32, 51, 201, 10, 52, 13, 100, 5, 217, 56, 14, 252,
+ 2, 206, 25, 234, 56, 196, 112, 113, 124, 39, 166, 2, 101, 170, 107,
+ 179, 44, 174, 59, 241, 88, 9, 241, 124, 119, 70, 249, 217, 40, 151,
+ 131, 242, 159, 168, 220, 251, 110, 29, 116, 80, 199, 119, 110, 158, 235,
+ 113, 108, 58, 104, 134, 122, 10, 155, 137, 178, 179, 64, 185, 160, 60,
+ 80, 62, 230, 225, 41, 204, 65, 107, 85, 67, 54, 27, 231, 57, 200,
+ 155, 11, 122, 26, 52, 15, 227, 187, 10, 123, 50, 31, 252, 2, 208,
+ 66, 164, 23, 129, 158, 1, 45, 6, 45, 65, 222, 82, 208, 50, 208,
+ 114, 181, 40, 203, 21, 152, 195, 149, 160, 85, 160, 213, 160, 53, 160,
+ 181, 152, 131, 117, 160, 245, 234, 4, 126, 103, 225, 89, 148, 221, 160,
+ 38, 187, 231, 195, 54, 170, 19, 249, 157, 166, 77, 106, 218, 203, 38,
+ 178, 205, 72, 111, 1, 61, 167, 22, 247, 105, 5, 106, 26, 147, 30,
+ 179, 169, 71, 41, 61, 143, 91, 155, 75, 251, 43, 146, 211, 243, 40,
+ 251, 2, 250, 178, 21, 229, 95, 4, 109, 227, 229, 13, 252, 206, 203,
+ 118, 181, 123, 255, 73, 251, 78, 218, 95, 138, 123, 79, 113, 223, 89,
+ 83, 218, 119, 38, 33, 218, 79, 162, 111, 11, 129, 157, 196, 118, 160,
+ 142, 251, 94, 134, 184, 215, 19, 239, 5, 236, 4, 238, 46, 208, 75,
+ 160, 151, 65, 187, 65, 123, 64, 175, 128, 246, 146, 29, 195, 60, 238,
+ 3, 237, 7, 191, 30, 253, 60, 128, 126, 29, 228, 54, 129, 100, 79,
+ 123, 117, 236, 153, 112, 253, 53, 181, 1, 251, 190, 36, 118, 72, 157,
+ 196, 14, 131, 94, 199, 188, 28, 81, 39, 99, 31, 81, 139, 21, 113,
+ 190, 22, 43, 150, 215, 6, 141, 37, 5, 215, 82, 120, 68, 167, 82,
+ 220, 55, 40, 225, 243, 109, 196, 220, 25, 121, 164, 87, 241, 154, 184,
+ 255, 88, 143, 29, 99, 11, 16, 3, 221, 89, 134, 246, 176, 14, 244,
+ 201, 9, 114, 161, 223, 111, 128, 218, 163, 205, 163, 72, 31, 3, 189,
+ 9, 58, 14, 58, 1, 122, 11, 116, 18, 244, 54, 232, 29, 208, 187,
+ 160, 247, 64, 167, 64, 239, 3, 235, 3, 80, 41, 232, 67, 208, 71,
+ 160, 211, 100, 131, 89, 42, 251, 88, 157, 134, 246, 210, 232, 219, 240,
+ 74, 219, 79, 69, 253, 116, 208, 39, 106, 49, 246, 63, 131, 243, 167,
+ 160, 207, 164, 182, 62, 231, 125, 75, 135, 76, 218, 177, 47, 164, 121,
+ 41, 31, 227, 81, 236, 133, 253, 29, 202, 125, 5, 250, 26, 244, 141,
+ 90, 220, 31, 215, 99, 38, 72, 216, 132, 182, 77, 60, 14, 166, 249,
+ 248, 86, 186, 78, 123, 211, 50, 181, 47, 143, 133, 190, 83, 155, 185,
+ 55, 168, 207, 177, 197, 54, 190, 71, 91, 63, 64, 22, 63, 162, 204,
+ 79, 160, 159, 65, 191, 128, 126, 5, 253, 6, 250, 29, 116, 22, 116,
+ 142, 203, 152, 98, 76, 101, 159, 124, 216, 31, 232, 243, 104, 156, 255,
+ 196, 156, 158, 87, 91, 88, 109, 126, 23, 196, 82, 110, 14, 242, 85,
+ 180, 247, 242, 236, 37, 47, 0, 239, 162, 186, 49, 251, 11, 237, 254,
+ 173, 158, 134, 40, 100, 26, 191, 115, 34, 218, 51, 178, 201, 62, 236,
+ 31, 201, 14, 94, 194, 249, 50, 232, 138, 218, 227, 15, 175, 130, 174,
+ 129, 174, 131, 254, 5, 221, 0, 221, 4, 221, 2, 221, 6, 193, 193,
+ 50, 21, 72, 13, 210, 128, 124, 64, 213, 64, 213, 65, 190, 160, 26,
+ 160, 154, 160, 135, 64, 181, 64, 181, 65, 117, 64, 117, 65, 15, 131,
+ 252, 64, 245, 64, 245, 65, 143, 128, 26, 128, 30, 5, 53, 4, 53,
+ 2, 53, 6, 53, 1, 61, 6, 122, 28, 212, 20, 212, 12, 212, 28,
+ 212, 2, 228, 15, 106, 169, 97, 172, 21, 168, 53, 168, 13, 168, 173,
+ 198, 202, 218, 129, 218, 107, 124, 88, 7, 80, 71, 80, 0, 168, 19,
+ 168, 179, 198, 151, 117, 1, 117, 5, 61, 129, 186, 129, 160, 32, 80,
+ 48, 40, 68, 99, 99, 221, 64, 221, 193, 247, 0, 245, 212, 208, 90,
+ 105, 195, 122, 105, 200, 7, 217, 177, 154, 232, 99, 89, 187, 180, 79,
+ 16, 231, 188, 55, 202, 244, 1, 133, 106, 196, 249, 167, 253, 86, 24,
+ 202, 135, 107, 50, 48, 255, 84, 78, 212, 27, 45, 202, 8, 28, 47,
+ 147, 239, 65, 220, 242, 162, 123, 13, 125, 212, 89, 124, 159, 53, 22,
+ 251, 132, 8, 141, 91, 207, 178, 177, 70, 225, 27, 129, 27, 165, 17,
+ 203, 247, 197, 216, 250, 129, 250, 107, 114, 248, 189, 64, 113, 127, 67,
+ 245, 24, 27, 128, 252, 129, 154, 233, 168, 35, 166, 7, 161, 206, 96,
+ 208, 219, 146, 108, 251, 168, 103, 200, 253, 25, 130, 54, 134, 74, 253,
+ 29, 166, 153, 201, 191, 114, 31, 171, 162, 53, 234, 195, 134, 107, 102,
+ 49, 95, 169, 220, 80, 92, 24, 1, 26, 169, 17, 49, 62, 65, 123,
+ 209, 154, 92, 148, 111, 199, 70, 33, 127, 52, 104, 140, 38, 15, 125,
+ 200, 67, 141, 60, 89, 15, 123, 75, 216, 49, 56, 143, 5, 141, 211,
+ 184, 199, 233, 222, 95, 229, 179, 241, 26, 113, 237, 197, 226, 218, 4,
+ 62, 47, 79, 241, 121, 157, 168, 153, 141, 51, 249, 216, 124, 172, 157,
+ 124, 250, 141, 3, 70, 95, 29, 79, 210, 120, 230, 236, 73, 9, 147,
+ 218, 153, 172, 81, 115, 63, 62, 69, 227, 198, 158, 3, 236, 60, 22,
+ 135, 252, 120, 144, 14, 216, 9, 154, 185, 124, 239, 155, 168, 17, 247,
+ 124, 95, 168, 159, 198, 218, 31, 196, 244, 10, 76, 7, 48, 156, 106,
+ 81, 174, 6, 228, 39, 97, 142, 146, 113, 78, 1, 133, 34, 207, 136,
+ 243, 84, 205, 60, 126, 199, 157, 202, 167, 106, 220, 117, 230, 179, 52,
+ 9, 39, 29, 103, 19, 200, 172, 89, 192, 239, 117, 39, 202, 248, 212,
+ 102, 95, 102, 209, 136, 243, 58, 13, 249, 86, 210, 123, 182, 144, 223,
+ 123, 108, 38, 223, 223, 38, 187, 78, 241, 232, 34, 46, 95, 63, 46,
+ 99, 183, 124, 9, 227, 25, 172, 121, 119, 190, 47, 179, 161, 143, 118,
+ 141, 184, 167, 188, 32, 237, 43, 105, 31, 153, 129, 188, 76, 80, 22,
+ 218, 203, 214, 44, 150, 251, 220, 236, 142, 113, 126, 34, 221, 239, 204,
+ 65, 95, 166, 107, 150, 192, 238, 83, 27, 162, 221, 156, 129, 250, 99,
+ 84, 100, 215, 220, 122, 130, 189, 163, 102, 41, 90, 17, 211, 111, 75,
+ 54, 107, 22, 242, 115, 65, 121, 160, 124, 205, 50, 254, 132, 226, 254,
+ 109, 209, 94, 97, 57, 183, 82, 164, 115, 79, 65, 46, 179, 65, 115,
+ 128, 49, 23, 244, 52, 215, 187, 21, 92, 15, 231, 97, 220, 243, 185,
+ 174, 33, 94, 208, 136, 58, 72, 122, 52, 70, 51, 7, 109, 205, 161,
+ 159, 116, 129, 126, 204, 41, 167, 31, 164, 23, 11, 53, 158, 189, 252,
+ 23, 234, 81, 252, 62, 9, 237, 131, 23, 1, 255, 25, 208, 98, 208,
+ 18, 141, 15, 223, 23, 44, 5, 191, 12, 180, 92, 67, 235, 110, 37,
+ 250, 41, 238, 115, 190, 80, 123, 48, 87, 0, 115, 37, 214, 245, 42,
+ 13, 237, 133, 17, 135, 128, 95, 163, 169, 197, 218, 171, 250, 178, 181,
+ 154, 190, 108, 29, 174, 175, 215, 136, 251, 187, 103, 53, 226, 30, 239,
+ 21, 201, 103, 210, 62, 127, 161, 74, 121, 239, 115, 8, 235, 194, 219,
+ 168, 201, 54, 160, 205, 141, 146, 12, 55, 225, 188, 25, 180, 5, 244,
+ 28, 168, 0, 244, 188, 70, 148, 237, 11, 56, 111, 213, 136, 99, 120,
+ 17, 231, 109, 160, 237, 160, 29, 154, 242, 247, 84, 119, 34, 189, 11,
+ 125, 123, 73, 211, 149, 189, 140, 185, 219, 13, 106, 135, 118, 246, 104,
+ 220, 253, 236, 203, 94, 65, 255, 246, 130, 10, 53, 140, 235, 151, 251,
+ 30, 195, 62, 169, 223, 52, 134, 253, 224, 15, 0, 235, 32, 232, 85,
+ 140, 249, 53, 62, 214, 249, 210, 30, 144, 238, 195, 175, 98, 135, 52,
+ 116, 79, 179, 38, 59, 172, 33, 127, 133, 189, 59, 202, 30, 1, 21,
+ 129, 138, 65, 37, 32, 7, 200, 169, 161, 231, 21, 140, 185, 208, 222,
+ 27, 154, 213, 210, 115, 26, 95, 118, 20, 215, 142, 129, 222, 68, 91,
+ 199, 65, 39, 52, 107, 176, 46, 215, 160, 228, 154, 59, 98, 118, 113,
+ 141, 61, 39, 173, 187, 242, 49, 58, 233, 195, 90, 96, 174, 69, 189,
+ 181, 220, 6, 137, 251, 107, 248, 120, 21, 233, 192, 186, 255, 235, 236,
+ 92, 114, 26, 134, 129, 48, 236, 104, 186, 235, 138, 75, 112, 6, 164,
+ 74, 89, 32, 144, 96, 211, 75, 32, 245, 58, 221, 181, 168, 105, 120,
+ 174, 56, 73, 161, 45, 239, 247, 155, 2, 226, 28, 124, 191, 39, 9,
+ 1, 177, 234, 98, 148, 100, 60, 246, 216, 227, 177, 199, 254, 103, 17,
+ 124, 160, 79, 89, 159, 178, 94, 24, 153, 199, 227, 133, 80, 143, 173,
+ 117, 60, 103, 30, 140, 230, 47, 54, 243, 131, 189, 28, 216, 102, 208,
+ 233, 45, 64, 73, 244, 169, 102, 56, 196, 255, 27, 197, 121, 254, 8,
+ 187, 142, 173, 23, 38, 150, 114, 119, 74, 145, 75, 145, 75, 233, 79,
+ 51, 76, 139, 253, 226, 24, 27, 157, 64, 167, 133, 191, 42, 62, 44,
+ 213, 176, 164, 178, 143, 245, 190, 157, 33, 127, 14, 93, 64, 151, 166,
+ 76, 129, 235, 187, 66, 223, 181, 249, 30, 114, 195, 243, 22, 186, 179,
+ 1, 235, 99, 160, 223, 139, 196, 188, 98, 55, 113, 61, 37, 14, 215,
+ 137, 109, 122, 140, 104, 37, 235, 81, 230, 222, 50, 74, 50, 234, 100,
+ 124, 203, 110, 101, 189, 82, 110, 173, 26, 163, 100, 31, 208, 241, 104,
+ 67, 244, 40, 127, 58, 172, 238, 166, 79, 166, 57, 212, 28, 11, 63,
+ 115, 204, 68, 247, 177, 86, 146, 227, 11, 57, 178, 57, 178, 90, 199,
+ 210, 225, 254, 234, 241, 197, 109, 243, 204, 248, 54, 160, 23, 232, 21,
+ 122, 179, 45, 90, 94, 12, 51, 222, 223, 25, 219, 7, 54, 252, 180,
+ 237, 130, 167, 126, 53, 216, 203, 197, 219, 169, 120, 126, 119, 22, 111,
+ 247, 31, 222, 94, 156, 183, 153, 237, 71, 92, 254, 119, 206, 146, 115,
+ 28, 122, 190, 108, 181, 189, 178, 172, 60, 240, 55, 121, 216, 88, 60, };
+
+ *dataSize = 138801;
+
+ // allocate a new array
+ *data = new unsigned char[138801];
+ // and copy it. Now we are certain that the calling function
+ // can control the memory location
+ for(int i = 0; i < 138801 /* tmp array size */; i++)
+ {
+ (*data)[i] = load_blend[i];
+ }
+
+}
+
+
+
diff --git a/source/gameengine/GamePlayer/common/GPC_RawLoadDotBlendArray.h b/source/gameengine/GamePlayer/common/GPC_RawLoadDotBlendArray.h
new file mode 100644
index 00000000000..b82d24c5705
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/GPC_RawLoadDotBlendArray.h
@@ -0,0 +1,40 @@
+/**
+ * $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 __GPC_RAWLOADDOTBLENDARRAY_H
+#define __GPC_RAWLOADDOTBLENDARRAY_H
+
+
+void GetRawLoadingAnimation(unsigned char **data, int *dataSize);
+
+
+#endif // __GPC_RAWLOADDOTBLENDARRAY_H
diff --git a/source/gameengine/GamePlayer/common/GPC_RawLogoArrays.cpp b/source/gameengine/GamePlayer/common/GPC_RawLogoArrays.cpp
new file mode 100644
index 00000000000..0afb241408e
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/GPC_RawLogoArrays.cpp
@@ -0,0 +1,1462 @@
+/**
+ * $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 *****
+ */
+
+// This file is automatically generated. Do not edit by hand!
+
+
+
+#include "GPC_RawLogoArrays.h"
+
+
+void GetRawBlenderLogo(unsigned char **data, int *width, int *height)
+{
+ // create an array that will automatically be deleted when)
+ // we're outta this scope
+ static unsigned char logo_blender_raw[]= { 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20, 21, 44, 44, 44,
+ 45, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 12, 12, 12, 124,
+ 124, 124, 124, 232, 232, 232, 232, 248, 248, 248, 248, 243, 243, 243, 243,
+ 160, 160, 160, 160, 44, 44, 44, 44, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 13, 13, 13, 13, 172, 172, 172, 173, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 235,
+ 235, 235, 235, 95, 95, 95, 95, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 88, 88, 88,
+ 255, 255, 255, 255, 255, 255, 255, 255, 254, 235, 217, 255, 253, 202, 152,
+ 255, 253, 216, 183, 255, 255, 250, 246, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 155, 155, 155, 155, 20, 20, 20, 20, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 255, 255, 255, 255, 255,
+ 249, 245, 255, 250, 162, 78, 255, 250, 145, 40, 255, 250, 149, 49, 255,
+ 251, 175, 104, 255, 254, 236, 219, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 202, 202, 202, 203, 53, 53, 53, 53, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 113, 113, 113, 113, 255, 255, 255, 255, 255, 253, 253, 255, 251, 196,
+ 147, 255, 249, 150, 51, 255, 249, 152, 55, 255, 248, 149, 50, 255, 249,
+ 160, 74, 255, 253, 219, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 236, 236, 236, 236, 90, 90, 90, 90, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 11, 11, 11, 76, 76,
+ 76, 76, 120, 120, 120, 120, 138, 138, 138, 138, 167, 167, 167, 167, 167,
+ 167, 167, 167, 167, 167, 167, 167, 163, 163, 163, 164, 196, 196, 196, 198,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 252, 206, 166,
+ 255, 248, 153, 61, 255, 247, 149, 52, 255, 247, 150, 53, 255, 247, 150,
+ 54, 255, 251, 196, 150, 255, 255, 249, 246, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 143, 143, 143, 143, 14, 14, 14, 14, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 43, 43, 43, 42, 198, 198, 198, 199, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 226, 203, 255,
+ 248, 165, 85, 255, 246, 150, 53, 255, 246, 151, 55, 255, 246, 145, 46,
+ 255, 248, 175, 106, 255, 253, 238, 226, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 189, 189, 189, 189, 39, 39, 39, 39, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 22, 22, 22, 22, 214, 214, 214, 216, 255,
+ 255, 255, 255, 255, 255, 255, 255, 252, 245, 238, 255, 251, 233, 218, 255,
+ 251, 231, 215, 255, 251, 232, 216, 255, 251, 232, 216, 255, 252, 232, 216,
+ 255, 252, 232, 216, 255, 252, 232, 216, 255, 252, 232, 216, 255, 252, 232,
+ 216, 255, 252, 232, 217, 255, 252, 236, 223, 255, 251, 214, 186, 255, 245,
+ 156, 72, 255, 245, 150, 54, 255, 245, 151, 56, 255, 245, 146, 48, 255,
+ 246, 159, 76, 255, 252, 223, 198, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 226, 226, 226, 226, 71, 71, 71, 71, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 93, 93, 93, 93, 255, 255, 255, 255, 253, 253, 252, 255, 248, 209,
+ 173, 255, 244, 155, 66, 255, 244, 152, 62, 255, 245, 152, 62, 255, 245,
+ 153, 62, 255, 245, 153, 62, 255, 245, 152, 62, 255, 245, 152, 62, 255,
+ 245, 152, 62, 255, 245, 152, 62, 255, 245, 152, 62, 255, 245, 152, 62,
+ 255, 245, 153, 62, 255, 245, 155, 66, 255, 244, 152, 62, 255, 244, 150,
+ 56, 255, 244, 150, 57, 255, 244, 150, 56, 255, 243, 146, 49, 255, 243,
+ 147, 54, 255, 249, 203, 162, 255, 254, 253, 254, 255, 255, 255, 255, 255,
+ 248, 248, 248, 248, 143, 143, 143, 143, 120, 120, 120, 120, 120, 120, 120,
+ 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+ 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+ 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+ 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+ 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+ 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+ 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+ 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+ 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+ 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 119, 119, 119, 120, 119,
+ 119, 119, 120, 119, 119, 119, 120, 119, 119, 119, 120, 119, 119, 119, 120,
+ 119, 119, 119, 120, 119, 119, 119, 120, 119, 119, 119, 120, 119, 119, 119,
+ 120, 119, 119, 119, 120, 119, 119, 119, 120, 119, 119, 119, 120, 119, 119,
+ 119, 120, 119, 119, 119, 120, 119, 119, 119, 120, 119, 119, 119, 120, 119,
+ 119, 119, 120, 119, 119, 119, 120, 119, 119, 119, 120, 118, 118, 118, 120,
+ 118, 118, 118, 120, 118, 118, 118, 120, 118, 118, 118, 120, 118, 118, 118,
+ 120, 118, 118, 118, 119, 118, 118, 118, 119, 118, 118, 118, 120, 118, 118,
+ 118, 119, 111, 111, 111, 112, 75, 75, 75, 75, 20, 20, 20, 20, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 125, 125, 125, 126,
+ 255, 255, 255, 255, 250, 242, 234, 255, 242, 149, 57, 255, 242, 142, 42,
+ 255, 243, 146, 48, 255, 243, 146, 48, 255, 243, 146, 48, 255, 243, 145,
+ 48, 255, 243, 145, 48, 255, 243, 147, 51, 255, 244, 149, 55, 255, 244,
+ 149, 55, 255, 243, 149, 54, 255, 243, 149, 54, 255, 243, 149, 55, 255,
+ 243, 148, 52, 255, 243, 146, 49, 255, 243, 146, 49, 255, 243, 146, 49,
+ 255, 243, 147, 52, 255, 242, 149, 55, 255, 242, 147, 52, 255, 241, 142,
+ 45, 255, 246, 181, 122, 255, 252, 244, 238, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 223, 223, 223, 223, 102, 102, 102, 102, 12, 12,
+ 12, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 109, 109, 109, 110, 255, 255, 255, 255, 251,
+ 251, 250, 255, 245, 194, 149, 255, 243, 166, 90, 255, 243, 167, 95, 255,
+ 243, 168, 96, 255, 243, 168, 96, 255, 244, 168, 96, 255, 244, 173, 105,
+ 255, 244, 164, 89, 255, 242, 148, 55, 255, 242, 149, 56, 255, 242, 149,
+ 56, 255, 242, 148, 54, 255, 241, 143, 46, 255, 242, 149, 58, 255, 244,
+ 165, 90, 255, 244, 172, 102, 255, 244, 169, 96, 255, 242, 154, 69, 255,
+ 241, 142, 45, 255, 241, 146, 50, 255, 241, 147, 54, 255, 240, 141, 42,
+ 255, 243, 166, 94, 255, 251, 237, 226, 255, 254, 255, 255, 255, 253, 253,
+ 253, 255, 253, 253, 253, 255, 254, 254, 254, 255, 225, 232, 238, 255, 215,
+ 224, 231, 255, 246, 247, 249, 255, 255, 254, 254, 255, 253, 253, 253, 255,
+ 253, 253, 253, 255, 253, 253, 253, 255, 253, 253, 253, 255, 253, 253, 253,
+ 255, 253, 253, 253, 255, 253, 253, 253, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 254, 254, 254, 255, 253, 253, 253, 255, 253,
+ 253, 253, 255, 253, 253, 253, 255, 253, 253, 253, 255, 253, 253, 253, 255,
+ 253, 253, 253, 255, 253, 253, 253, 255, 253, 253, 253, 255, 253, 253, 253,
+ 255, 253, 253, 253, 255, 253, 253, 253, 255, 253, 253, 253, 255, 253, 253,
+ 253, 255, 253, 253, 253, 255, 253, 253, 253, 255, 253, 253, 253, 255, 253,
+ 253, 253, 255, 253, 253, 253, 255, 253, 253, 253, 255, 253, 253, 253, 255,
+ 253, 253, 253, 255, 253, 253, 253, 255, 253, 253, 253, 255, 253, 253, 253,
+ 255, 252, 252, 252, 255, 252, 252, 252, 255, 252, 252, 252, 255, 253, 253,
+ 253, 255, 255, 254, 253, 255, 244, 246, 247, 255, 208, 220, 229, 255, 234,
+ 238, 241, 255, 253, 253, 253, 255, 252, 252, 252, 255, 251, 251, 251, 255,
+ 251, 251, 251, 255, 251, 251, 251, 255, 251, 251, 251, 255, 251, 251, 251,
+ 255, 251, 251, 251, 255, 251, 251, 251, 255, 250, 250, 250, 255, 250, 250,
+ 250, 255, 250, 250, 250, 255, 250, 250, 250, 255, 250, 250, 250, 255, 250,
+ 250, 250, 255, 249, 249, 249, 255, 249, 249, 249, 255, 253, 253, 252, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 184, 183, 183, 182, 25, 25, 25,
+ 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 45, 45, 45, 45, 244, 244, 244, 248, 255, 255, 255, 255, 250, 252,
+ 254, 255, 250, 247, 246, 255, 250, 248, 246, 255, 250, 248, 246, 255, 250,
+ 249, 248, 255, 251, 254, 255, 255, 249, 230, 214, 255, 243, 167, 95, 255,
+ 241, 145, 50, 255, 241, 148, 56, 255, 241, 145, 51, 255, 241, 148, 56,
+ 255, 245, 182, 123, 255, 249, 227, 209, 255, 255, 253, 250, 255, 255, 255,
+ 254, 255, 255, 255, 254, 255, 253, 241, 232, 255, 246, 195, 152, 255, 241,
+ 155, 72, 255, 240, 142, 45, 255, 240, 147, 54, 255, 240, 141, 43, 255,
+ 242, 161, 86, 255, 250, 233, 222, 255, 252, 255, 255, 255, 252, 252, 253,
+ 255, 255, 255, 255, 255, 154, 181, 201, 255, 8, 78, 129, 255, 70, 124,
+ 161, 255, 249, 249, 250, 255, 255, 255, 254, 255, 253, 253, 253, 255, 253,
+ 253, 253, 255, 253, 253, 253, 255, 253, 253, 253, 255, 253, 253, 253, 255,
+ 254, 254, 254, 255, 213, 226, 233, 255, 119, 159, 186, 255, 127, 167, 191,
+ 255, 245, 247, 249, 255, 254, 254, 254, 255, 252, 252, 253, 255, 252, 252,
+ 252, 255, 253, 253, 253, 255, 255, 255, 254, 255, 255, 254, 254, 255, 253,
+ 253, 253, 255, 252, 252, 252, 255, 253, 253, 253, 255, 253, 253, 253, 255,
+ 253, 253, 253, 255, 252, 252, 252, 255, 252, 252, 252, 255, 252, 252, 252,
+ 255, 252, 252, 252, 255, 252, 252, 252, 255, 253, 253, 253, 255, 252, 252,
+ 252, 255, 252, 252, 252, 255, 252, 252, 252, 255, 252, 252, 252, 255, 252,
+ 252, 252, 255, 252, 252, 252, 255, 252, 252, 252, 255, 252, 252, 252, 255,
+ 252, 252, 252, 255, 252, 252, 252, 255, 255, 255, 255, 255, 206, 218, 228,
+ 255, 38, 105, 148, 255, 13, 91, 139, 255, 202, 213, 222, 255, 255, 255,
+ 255, 255, 251, 251, 251, 255, 251, 251, 251, 255, 251, 251, 251, 255, 253,
+ 252, 252, 255, 253, 252, 252, 255, 251, 251, 251, 255, 250, 250, 250, 255,
+ 250, 250, 250, 255, 250, 250, 250, 255, 250, 250, 250, 255, 249, 249, 249,
+ 255, 249, 249, 249, 255, 249, 249, 249, 255, 249, 249, 249, 255, 250, 250,
+ 249, 255, 252, 252, 251, 255, 228, 232, 236, 255, 198, 210, 220, 255, 226,
+ 229, 234, 255, 239, 244, 249, 255, 179, 181, 183, 190, 15, 15, 14, 13,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 94, 94, 94, 94, 220, 220, 220, 220, 250, 251, 251, 254, 250, 251, 252,
+ 255, 250, 251, 252, 255, 250, 253, 255, 255, 250, 255, 255, 255, 246, 216,
+ 188, 255, 241, 151, 62, 255, 240, 144, 49, 255, 240, 148, 56, 255, 240,
+ 145, 50, 255, 240, 149, 59, 255, 247, 214, 184, 255, 254, 255, 255, 255,
+ 255, 255, 255, 255, 238, 241, 245, 255, 210, 220, 230, 255, 215, 224, 232,
+ 255, 249, 252, 254, 255, 255, 255, 255, 255, 249, 234, 222, 255, 241, 165,
+ 94, 255, 239, 142, 44, 255, 239, 146, 53, 255, 238, 141, 44, 255, 240,
+ 156, 78, 255, 250, 237, 226, 255, 252, 255, 255, 255, 255, 255, 255, 255,
+ 154, 181, 201, 255, 0, 71, 125, 255, 29, 98, 142, 255, 246, 246, 248,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 252, 252, 252, 255, 255, 255, 255, 255, 173,
+ 199, 214, 255, 0, 68, 122, 255, 0, 83, 132, 255, 236, 241, 244, 255,
+ 255, 255, 254, 255, 255, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 251, 248, 248, 255, 254, 250, 250, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 254, 253, 255, 252, 252, 252, 255, 253, 253, 253, 255, 255,
+ 255, 254, 255, 255, 255, 254, 255, 253, 253, 252, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 253, 253, 252, 255, 251, 251, 251, 255, 251, 251, 251, 255, 253, 252,
+ 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 177, 201, 216, 255, 0, 81, 132, 255,
+ 7, 86, 136, 255, 203, 213, 222, 255, 255, 255, 255, 255, 251, 251, 251,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 249, 247, 247, 255, 248, 246,
+ 246, 255, 255, 255, 253, 255, 255, 255, 255, 255, 252, 251, 251, 255, 249,
+ 249, 249, 255, 249, 249, 249, 255, 251, 251, 250, 255, 251, 250, 250, 255,
+ 251, 250, 249, 255, 255, 255, 254, 255, 255, 251, 250, 255, 253, 251, 249,
+ 255, 218, 225, 231, 255, 155, 174, 193, 255, 175, 186, 200, 255, 170, 184,
+ 200, 255, 240, 244, 248, 255, 134, 133, 133, 133, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56,
+ 56, 56, 57, 237, 237, 237, 239, 252, 252, 252, 255, 249, 254, 255, 255,
+ 249, 247, 246, 255, 243, 191, 141, 255, 239, 144, 50, 255, 239, 144, 50,
+ 255, 239, 147, 55, 255, 239, 146, 52, 255, 239, 146, 55, 255, 246, 214,
+ 185, 255, 253, 255, 255, 255, 252, 253, 254, 255, 156, 184, 203, 255, 38,
+ 103, 146, 255, 11, 89, 137, 255, 11, 87, 136, 255, 65, 123, 160, 255,
+ 199, 214, 225, 255, 255, 255, 255, 255, 250, 238, 229, 255, 239, 159, 82,
+ 255, 237, 142, 47, 255, 238, 145, 52, 255, 236, 137, 37, 255, 244, 193,
+ 145, 255, 251, 255, 255, 255, 255, 255, 255, 255, 154, 181, 201, 255, 0,
+ 73, 126, 255, 41, 105, 147, 255, 227, 231, 236, 255, 176, 198, 212, 255,
+ 134, 170, 194, 255, 120, 161, 187, 255, 151, 178, 198, 255, 203, 217, 226,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 178, 201, 215, 255, 0, 79,
+ 130, 255, 15, 93, 139, 255, 235, 241, 244, 255, 255, 255, 255, 255, 244,
+ 246, 247, 255, 163, 190, 207, 255, 101, 144, 174, 255, 54, 109, 148, 255,
+ 65, 116, 153, 255, 114, 154, 181, 255, 175, 198, 212, 255, 245, 246, 247,
+ 255, 253, 253, 253, 255, 246, 247, 248, 255, 236, 240, 244, 255, 238, 242,
+ 245, 255, 255, 254, 252, 255, 200, 215, 225, 255, 128, 164, 188, 255, 104,
+ 147, 177, 255, 128, 165, 189, 255, 186, 202, 216, 255, 248, 247, 248, 255,
+ 252, 252, 252, 255, 254, 254, 253, 255, 252, 251, 251, 255, 186, 203, 216,
+ 255, 135, 171, 194, 255, 121, 162, 188, 255, 140, 174, 196, 255, 191, 209,
+ 221, 255, 171, 196, 212, 255, 3, 86, 135, 255, 9, 87, 136, 255, 202,
+ 212, 221, 255, 255, 255, 255, 255, 254, 252, 251, 255, 186, 204, 217, 255,
+ 115, 157, 184, 255, 61, 116, 154, 255, 56, 111, 151, 255, 101, 146, 175,
+ 255, 169, 191, 208, 255, 240, 242, 243, 255, 254, 253, 252, 255, 247, 247,
+ 247, 255, 244, 243, 244, 255, 246, 243, 244, 255, 246, 247, 246, 255, 163,
+ 190, 206, 255, 90, 132, 165, 255, 139, 167, 189, 255, 236, 237, 239, 255,
+ 198, 206, 217, 255, 198, 205, 215, 255, 181, 193, 206, 255, 246, 247, 248,
+ 255, 229, 228, 228, 233, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 62, 62, 62, 63, 209, 209, 209, 212, 250, 251,
+ 251, 253, 249, 254, 255, 255, 247, 235, 223, 255, 240, 170, 103, 255, 237,
+ 139, 41, 255, 237, 144, 52, 255, 238, 146, 54, 255, 238, 145, 54, 255,
+ 238, 140, 44, 255, 242, 181, 123, 255, 251, 255, 255, 255, 253, 253, 253,
+ 255, 133, 169, 192, 255, 0, 78, 130, 255, 0, 82, 132, 255, 2, 85,
+ 134, 255, 2, 85, 134, 255, 0, 78, 129, 255, 23, 92, 138, 255, 196,
+ 210, 221, 255, 255, 255, 255, 255, 245, 212, 185, 255, 236, 141, 46, 255,
+ 237, 144, 51, 255, 236, 141, 45, 255, 239, 163, 90, 255, 250, 248, 247,
+ 255, 255, 255, 255, 255, 153, 181, 200, 255, 0, 75, 127, 255, 22, 93,
+ 139, 255, 42, 106, 148, 255, 0, 69, 122, 255, 0, 63, 118, 255, 0,
+ 62, 117, 255, 0, 70, 123, 255, 9, 84, 133, 255, 150, 179, 199, 255,
+ 255, 255, 255, 255, 178, 201, 215, 255, 0, 78, 129, 255, 14, 92, 138,
+ 255, 241, 245, 247, 255, 234, 240, 243, 255, 69, 126, 163, 255, 0, 70,
+ 123, 255, 0, 72, 124, 255, 43, 109, 150, 255, 39, 106, 147, 255, 0,
+ 74, 126, 255, 0, 72, 125, 255, 107, 149, 177, 255, 255, 255, 255, 255,
+ 176, 199, 213, 255, 15, 89, 136, 255, 28, 101, 145, 255, 101, 145, 174,
+ 255, 0, 79, 129, 255, 0, 70, 122, 255, 0, 69, 122, 255, 0, 71,
+ 124, 255, 0, 78, 128, 255, 125, 162, 186, 255, 255, 255, 254, 255, 246,
+ 247, 248, 255, 107, 151, 179, 255, 1, 80, 130, 255, 0, 69, 123, 255,
+ 0, 65, 120, 255, 0, 67, 121, 255, 0, 77, 128, 255, 30, 102, 146,
+ 255, 8, 88, 136, 255, 10, 88, 136, 255, 204, 213, 222, 255, 248, 250,
+ 250, 255, 111, 154, 182, 255, 0, 81, 131, 255, 0, 73, 126, 255, 37,
+ 105, 148, 255, 52, 115, 154, 255, 4, 83, 132, 255, 0, 74, 126, 255,
+ 74, 128, 163, 255, 236, 239, 242, 255, 223, 228, 232, 255, 61, 114, 152,
+ 255, 63, 114, 152, 255, 89, 137, 168, 255, 0, 76, 127, 255, 0, 57,
+ 114, 255, 73, 125, 161, 255, 255, 250, 248, 255, 249, 248, 248, 255, 247,
+ 247, 247, 255, 247, 247, 246, 255, 245, 245, 245, 255, 255, 255, 255, 255,
+ 112, 112, 112, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 107, 107, 107, 108,
+ 246, 246, 246, 249, 255, 255, 255, 255, 247, 252, 255, 255, 243, 215, 190,
+ 255, 237, 151, 69, 255, 236, 139, 43, 255, 236, 144, 53, 255, 236, 145,
+ 53, 255, 237, 145, 53, 255, 237, 144, 52, 255, 236, 143, 53, 255, 245,
+ 217, 197, 255, 255, 255, 255, 255, 206, 218, 227, 255, 8, 87, 135, 255,
+ 0, 83, 132, 255, 5, 86, 135, 255, 5, 86, 135, 255, 5, 86, 135,
+ 255, 5, 86, 134, 255, 0, 76, 127, 255, 73, 128, 162, 255, 251, 252,
+ 253, 255, 250, 241, 234, 255, 237, 151, 69, 255, 236, 141, 48, 255, 236,
+ 142, 49, 255, 236, 145, 57, 255, 247, 230, 219, 255, 255, 255, 255, 255,
+ 153, 180, 200, 255, 0, 76, 127, 255, 0, 79, 129, 255, 8, 87, 134,
+ 255, 100, 146, 176, 255, 144, 174, 196, 255, 123, 163, 188, 255, 36, 104,
+ 147, 255, 0, 75, 126, 255, 10, 82, 130, 255, 202, 214, 223, 255, 186,
+ 206, 219, 255, 0, 78, 128, 255, 15, 93, 138, 255, 243, 245, 246, 255,
+ 113, 152, 179, 255, 0, 68, 120, 255, 7, 82, 131, 255, 154, 181, 201,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 163, 186, 203, 255, 2, 79,
+ 129, 255, 0, 75, 126, 255, 167, 188, 204, 255, 177, 199, 212, 255, 0,
+ 77, 127, 255, 0, 79, 129, 255, 0, 80, 129, 255, 90, 140, 171, 255,
+ 185, 197, 211, 255, 158, 181, 200, 255, 28, 100, 144, 255, 0, 75, 126,
+ 255, 34, 102, 145, 255, 252, 251, 249, 255, 147, 178, 197, 255, 0, 73,
+ 125, 255, 0, 79, 130, 255, 60, 120, 158, 255, 139, 173, 195, 255, 147,
+ 175, 196, 255, 83, 135, 167, 255, 0, 81, 130, 255, 1, 83, 133, 255,
+ 11, 88, 136, 255, 214, 219, 226, 255, 167, 192, 207, 255, 0, 75, 127,
+ 255, 0, 79, 129, 255, 116, 156, 182, 255, 255, 254, 252, 255, 255, 255,
+ 254, 255, 196, 208, 219, 255, 25, 96, 140, 255, 0, 71, 124, 255, 110,
+ 153, 180, 255, 219, 224, 229, 255, 7, 87, 134, 255, 0, 79, 130, 255,
+ 0, 80, 129, 255, 72, 126, 161, 255, 124, 161, 187, 255, 168, 191, 207,
+ 255, 249, 247, 246, 255, 246, 246, 246, 255, 245, 245, 245, 255, 245, 245,
+ 244, 255, 244, 244, 244, 255, 255, 255, 255, 255, 166, 166, 166, 171, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 22,
+ 22, 22, 157, 157, 157, 158, 255, 255, 255, 255, 250, 254, 255, 255, 246,
+ 247, 248, 255, 240, 196, 154, 255, 234, 141, 50, 255, 235, 141, 47, 255,
+ 235, 144, 53, 255, 235, 141, 48, 255, 235, 143, 52, 255, 235, 144, 53,
+ 255, 235, 142, 50, 255, 236, 149, 63, 255, 246, 237, 230, 255, 255, 255,
+ 255, 255, 167, 192, 208, 255, 0, 81, 131, 255, 3, 85, 133, 255, 5,
+ 86, 134, 255, 5, 85, 134, 255, 5, 85, 134, 255, 4, 85, 134, 255,
+ 0, 81, 131, 255, 40, 104, 146, 255, 240, 243, 245, 255, 251, 249, 250,
+ 255, 237, 163, 99, 255, 235, 139, 43, 255, 235, 142, 50, 255, 234, 139,
+ 47, 255, 243, 209, 184, 255, 255, 255, 255, 255, 152, 180, 199, 255, 0,
+ 75, 126, 255, 2, 76, 127, 255, 143, 172, 193, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 191, 207, 218, 255, 4, 83, 131,
+ 255, 0, 70, 122, 255, 107, 150, 178, 255, 186, 205, 217, 255, 0, 79,
+ 128, 255, 20, 95, 141, 255, 207, 218, 226, 255, 15, 90, 136, 255, 0,
+ 76, 127, 255, 33, 101, 144, 255, 170, 193, 208, 255, 172, 195, 210, 255,
+ 173, 197, 211, 255, 157, 185, 203, 255, 8, 88, 135, 255, 0, 75, 126,
+ 255, 40, 105, 146, 255, 155, 181, 200, 255, 1, 83, 131, 255, 0, 74,
+ 125, 255, 92, 140, 172, 255, 255, 255, 254, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 137, 171, 192, 255, 0, 73, 124, 255, 20, 95, 141, 255,
+ 223, 229, 235, 255, 39, 104, 145, 255, 0, 75, 126, 255, 50, 112, 151,
+ 255, 243, 242, 243, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253,
+ 252, 255, 101, 144, 173, 255, 0, 76, 127, 255, 12, 89, 135, 255, 200,
+ 208, 218, 255, 71, 125, 160, 255, 0, 77, 128, 255, 12, 89, 136, 255,
+ 152, 180, 198, 255, 174, 197, 211, 255, 170, 194, 209, 255, 177, 197, 210,
+ 255, 61, 118, 155, 255, 0, 75, 126, 255, 44, 110, 150, 255, 202, 212,
+ 221, 255, 17, 92, 137, 255, 0, 75, 126, 255, 76, 130, 164, 255, 251,
+ 248, 246, 255, 255, 255, 254, 255, 255, 252, 250, 255, 244, 244, 244, 255,
+ 244, 244, 244, 255, 244, 244, 244, 255, 244, 244, 244, 255, 243, 243, 243,
+ 255, 254, 254, 254, 255, 172, 172, 172, 179, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 31, 31, 31, 31, 199, 199, 199, 202, 255, 255, 255,
+ 255, 247, 252, 255, 255, 244, 235, 228, 255, 237, 175, 114, 255, 232, 137,
+ 42, 255, 233, 141, 49, 255, 234, 142, 51, 255, 233, 138, 44, 255, 235,
+ 156, 79, 255, 234, 146, 59, 255, 234, 142, 51, 255, 234, 142, 50, 255,
+ 235, 146, 59, 255, 245, 229, 219, 255, 255, 255, 255, 255, 192, 208, 219,
+ 255, 0, 81, 130, 255, 1, 83, 132, 255, 4, 85, 133, 255, 4, 85,
+ 133, 255, 4, 85, 133, 255, 4, 85, 133, 255, 0, 78, 128, 255, 53,
+ 115, 153, 255, 245, 247, 249, 255, 250, 246, 244, 255, 236, 155, 80, 255,
+ 234, 139, 45, 255, 233, 142, 50, 255, 232, 137, 42, 255, 241, 201, 169,
+ 255, 255, 255, 255, 255, 152, 179, 198, 255, 0, 73, 123, 255, 15, 92,
+ 137, 255, 235, 238, 240, 255, 254, 252, 251, 255, 248, 248, 248, 255, 252,
+ 251, 250, 255, 242, 243, 244, 255, 33, 99, 142, 255, 0, 71, 124, 255,
+ 76, 131, 165, 255, 175, 198, 213, 255, 0, 79, 128, 255, 22, 97, 142,
+ 255, 182, 198, 211, 255, 9, 85, 133, 255, 0, 81, 129, 255, 0, 81,
+ 129, 255, 0, 72, 123, 255, 0, 71, 122, 255, 0, 71, 122, 255, 0,
+ 72, 123, 255, 0, 75, 125, 255, 0, 73, 124, 255, 14, 88, 134, 255,
+ 134, 166, 187, 255, 1, 83, 131, 255, 2, 79, 128, 255, 185, 198, 210,
+ 255, 255, 255, 255, 255, 248, 248, 248, 255, 255, 255, 255, 255, 161, 186,
+ 202, 255, 0, 74, 125, 255, 23, 97, 141, 255, 204, 216, 225, 255, 14,
+ 91, 137, 255, 0, 72, 124, 255, 103, 147, 175, 255, 255, 255, 252, 255,
+ 248, 248, 248, 255, 247, 247, 247, 255, 255, 255, 255, 255, 174, 196, 211,
+ 255, 0, 79, 129, 255, 12, 89, 135, 255, 179, 194, 207, 255, 20, 95,
+ 141, 255, 1, 82, 131, 255, 4, 84, 133, 255, 0, 77, 127, 255, 0,
+ 74, 124, 255, 0, 74, 125, 255, 0, 74, 125, 255, 0, 77, 127, 255,
+ 0, 76, 125, 255, 15, 89, 135, 255, 184, 198, 210, 255, 18, 93, 138,
+ 255, 0, 72, 123, 255, 136, 169, 191, 255, 255, 255, 253, 255, 244, 244,
+ 244, 255, 244, 244, 244, 255, 244, 244, 244, 255, 243, 243, 243, 255, 243,
+ 243, 243, 255, 243, 243, 243, 255, 242, 242, 242, 255, 255, 255, 255, 255,
+ 165, 165, 165, 171, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, 198,
+ 198, 198, 203, 255, 255, 255, 255, 244, 249, 253, 255, 241, 219, 201, 255,
+ 233, 154, 79, 255, 231, 135, 38, 255, 232, 141, 51, 255, 232, 140, 48,
+ 255, 232, 137, 42, 255, 237, 176, 119, 255, 243, 230, 220, 255, 234, 149,
+ 67, 255, 233, 140, 49, 255, 233, 142, 51, 255, 232, 138, 45, 255, 240,
+ 201, 168, 255, 249, 254, 255, 255, 243, 243, 244, 255, 72, 126, 160, 255,
+ 0, 73, 124, 255, 2, 83, 131, 255, 4, 84, 132, 255, 4, 84, 132,
+ 255, 0, 80, 130, 255, 0, 74, 125, 255, 147, 175, 195, 255, 255, 255,
+ 255, 255, 245, 229, 216, 255, 233, 144, 55, 255, 233, 140, 48, 255, 233,
+ 140, 49, 255, 232, 138, 47, 255, 241, 210, 186, 255, 255, 255, 255, 255,
+ 151, 178, 197, 255, 0, 73, 123, 255, 11, 88, 134, 255, 218, 225, 231,
+ 255, 255, 255, 253, 255, 247, 247, 247, 255, 255, 253, 252, 255, 232, 236,
+ 239, 255, 18, 92, 137, 255, 0, 71, 123, 255, 83, 136, 167, 255, 178,
+ 199, 213, 255, 0, 79, 128, 255, 22, 96, 140, 255, 189, 204, 215, 255,
+ 6, 84, 132, 255, 0, 76, 126, 255, 45, 108, 148, 255, 166, 183, 200,
+ 255, 162, 179, 197, 255, 160, 179, 197, 255, 168, 184, 200, 255, 175, 189,
+ 204, 255, 167, 183, 200, 255, 175, 190, 205, 255, 154, 180, 198, 255, 0,
+ 78, 128, 255, 7, 84, 132, 255, 206, 214, 222, 255, 254, 253, 251, 255,
+ 247, 247, 247, 255, 255, 255, 254, 255, 157, 183, 200, 255, 0, 74, 124,
+ 255, 22, 96, 141, 255, 210, 220, 227, 255, 20, 93, 138, 255, 0, 72,
+ 124, 255, 88, 136, 168, 255, 255, 255, 252, 255, 249, 249, 248, 255, 247,
+ 247, 247, 255, 255, 255, 255, 255, 164, 188, 204, 255, 0, 77, 127, 255,
+ 12, 88, 134, 255, 186, 198, 210, 255, 38, 104, 146, 255, 0, 78, 128,
+ 255, 22, 93, 138, 255, 159, 177, 196, 255, 162, 181, 198, 255, 159, 178,
+ 196, 255, 164, 182, 199, 255, 173, 187, 203, 255, 165, 182, 199, 255, 171,
+ 186, 202, 255, 199, 209, 218, 255, 12, 89, 134, 255, 0, 77, 126, 255,
+ 175, 189, 202, 255, 254, 251, 249, 255, 243, 243, 243, 255, 243, 243, 243,
+ 255, 243, 243, 243, 255, 243, 243, 243, 255, 242, 242, 242, 255, 242, 242,
+ 242, 255, 242, 242, 242, 255, 255, 255, 255, 255, 127, 127, 127, 127, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 123, 123, 123, 126, 255, 255, 255, 255, 244, 247,
+ 250, 255, 237, 204, 174, 255, 230, 140, 50, 255, 230, 136, 43, 255, 231,
+ 141, 52, 255, 231, 138, 45, 255, 231, 138, 48, 255, 237, 190, 146, 255,
+ 245, 246, 249, 255, 245, 247, 251, 255, 235, 164, 103, 255, 231, 137, 42,
+ 255, 232, 141, 51, 255, 231, 137, 43, 255, 235, 163, 95, 255, 244, 243,
+ 244, 255, 252, 253, 254, 255, 228, 230, 234, 255, 79, 129, 162, 255, 0,
+ 79, 128, 255, 0, 72, 123, 255, 0, 73, 124, 255, 17, 88, 134, 255,
+ 128, 164, 186, 255, 251, 249, 248, 255, 249, 253, 255, 255, 238, 189, 144,
+ 255, 231, 137, 42, 255, 232, 141, 50, 255, 232, 139, 47, 255, 232, 144,
+ 57, 255, 244, 231, 221, 255, 255, 255, 255, 255, 151, 177, 196, 255, 0,
+ 74, 124, 255, 0, 74, 125, 255, 91, 138, 169, 255, 244, 244, 245, 255,
+ 255, 255, 253, 255, 251, 250, 248, 255, 128, 163, 187, 255, 0, 77, 127,
+ 255, 0, 69, 121, 255, 136, 167, 190, 255, 187, 206, 217, 255, 0, 77,
+ 127, 255, 18, 92, 137, 255, 226, 231, 235, 255, 51, 111, 149, 255, 0,
+ 69, 121, 255, 38, 103, 143, 255, 227, 231, 234, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 206, 217, 225, 255, 145, 173, 193, 255, 229, 234, 237,
+ 255, 255, 255, 255, 255, 169, 192, 207, 255, 0, 76, 126, 255, 7, 85,
+ 132, 255, 210, 217, 224, 255, 253, 251, 250, 255, 246, 246, 246, 255, 255,
+ 255, 253, 255, 157, 182, 200, 255, 0, 74, 124, 255, 17, 93, 138, 255,
+ 238, 239, 241, 255, 89, 135, 165, 255, 0, 72, 123, 255, 19, 90, 135,
+ 255, 180, 197, 211, 255, 255, 251, 249, 255, 255, 254, 251, 255, 220, 226,
+ 231, 255, 52, 112, 150, 255, 0, 77, 126, 255, 10, 86, 132, 255, 209,
+ 214, 221, 255, 121, 157, 182, 255, 0, 70, 122, 255, 12, 86, 133, 255,
+ 188, 202, 214, 255, 255, 255, 255, 255, 255, 255, 255, 255, 227, 232, 235,
+ 255, 142, 173, 194, 255, 222, 227, 231, 255, 255, 255, 254, 255, 210, 218,
+ 224, 255, 10, 86, 132, 255, 0, 77, 125, 255, 175, 189, 202, 255, 254,
+ 250, 248, 255, 242, 242, 242, 255, 242, 242, 242, 255, 242, 242, 242, 255,
+ 242, 242, 242, 255, 242, 242, 242, 255, 241, 241, 241, 255, 246, 246, 246,
+ 255, 231, 231, 231, 241, 39, 39, 39, 38, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 9,
+ 215, 215, 215, 222, 249, 253, 255, 255, 239, 219, 201, 255, 229, 139, 51,
+ 255, 229, 137, 45, 255, 229, 140, 50, 255, 229, 135, 41, 255, 230, 143,
+ 57, 255, 238, 204, 173, 255, 244, 249, 253, 255, 245, 246, 248, 255, 244,
+ 250, 255, 255, 237, 194, 154, 255, 230, 135, 40, 255, 231, 141, 50, 255,
+ 231, 140, 50, 255, 231, 136, 44, 255, 237, 185, 141, 255, 245, 248, 253,
+ 255, 251, 252, 254, 255, 251, 248, 246, 255, 175, 193, 207, 255, 113, 152,
+ 179, 255, 128, 162, 186, 255, 210, 217, 224, 255, 255, 253, 252, 255, 248,
+ 254, 255, 255, 240, 211, 185, 255, 230, 139, 49, 255, 231, 139, 47, 255,
+ 231, 140, 50, 255, 230, 136, 42, 255, 233, 158, 87, 255, 245, 244, 243,
+ 255, 255, 255, 255, 255, 148, 175, 194, 255, 0, 69, 121, 255, 0, 78,
+ 127, 255, 0, 74, 124, 255, 41, 104, 144, 255, 109, 149, 176, 255, 65,
+ 120, 156, 255, 0, 75, 124, 255, 0, 69, 121, 255, 36, 100, 141, 255,
+ 239, 240, 241, 255, 177, 199, 212, 255, 0, 71, 123, 255, 6, 86, 132,
+ 255, 241, 244, 244, 255, 190, 203, 214, 255, 13, 83, 129, 255, 0, 68,
+ 119, 255, 24, 94, 138, 255, 119, 160, 185, 255, 107, 151, 178, 255, 4,
+ 82, 129, 255, 0, 57, 112, 255, 70, 120, 155, 255, 254, 253, 252, 255,
+ 166, 190, 205, 255, 0, 70, 122, 255, 0, 80, 128, 255, 207, 215, 222,
+ 255, 253, 251, 250, 255, 246, 246, 246, 255, 255, 255, 253, 255, 154, 180,
+ 198, 255, 0, 68, 120, 255, 8, 87, 134, 255, 240, 243, 243, 255, 192,
+ 207, 217, 255, 4, 80, 128, 255, 0, 73, 124, 255, 3, 82, 129, 255,
+ 82, 130, 162, 255, 101, 143, 171, 255, 21, 90, 135, 255, 0, 72, 123,
+ 255, 0, 78, 127, 255, 1, 80, 128, 255, 204, 212, 219, 255, 222, 228,
+ 233, 255, 36, 101, 143, 255, 0, 70, 121, 255, 11, 85, 131, 255, 104,
+ 147, 174, 255, 119, 158, 183, 255, 35, 100, 141, 255, 0, 62, 116, 255,
+ 34, 98, 140, 255, 232, 233, 235, 255, 211, 218, 224, 255, 2, 81, 129,
+ 255, 0, 72, 121, 255, 172, 186, 200, 255, 253, 250, 248, 255, 242, 242,
+ 242, 255, 241, 241, 241, 255, 241, 241, 241, 255, 241, 241, 241, 255, 240,
+ 240, 240, 255, 241, 241, 241, 255, 255, 255, 255, 255, 140, 140, 140, 145,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 231, 231, 231, 238, 245,
+ 251, 255, 255, 236, 199, 168, 255, 227, 130, 35, 255, 228, 136, 45, 255,
+ 227, 132, 37, 255, 230, 152, 77, 255, 239, 219, 202, 255, 244, 250, 255,
+ 255, 251, 251, 252, 255, 245, 245, 245, 255, 244, 248, 251, 255, 240, 221,
+ 204, 255, 230, 140, 52, 255, 230, 138, 47, 255, 230, 140, 50, 255, 230,
+ 139, 48, 255, 229, 136, 44, 255, 235, 180, 132, 255, 243, 235, 230, 255,
+ 246, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 252, 255, 255, 255, 244, 244, 245, 255, 238, 198, 161, 255, 230, 141,
+ 53, 255, 230, 138, 45, 255, 230, 139, 49, 255, 230, 139, 49, 255, 229,
+ 132, 36, 255, 236, 184, 136, 255, 245, 250, 254, 255, 254, 253, 252, 255,
+ 164, 185, 201, 255, 39, 95, 137, 255, 72, 121, 155, 255, 141, 170, 190,
+ 255, 31, 96, 139, 255, 0, 70, 120, 255, 0, 70, 120, 255, 5, 81,
+ 128, 255, 62, 115, 151, 255, 201, 211, 219, 255, 255, 255, 254, 255, 185,
+ 203, 214, 255, 41, 100, 141, 255, 52, 112, 149, 255, 233, 237, 239, 255,
+ 255, 254, 252, 255, 187, 202, 213, 255, 74, 123, 157, 255, 17, 88, 133,
+ 255, 0, 70, 120, 255, 0, 72, 122, 255, 20, 92, 136, 255, 75, 124,
+ 158, 255, 183, 200, 212, 255, 253, 253, 252, 255, 179, 197, 210, 255, 41,
+ 99, 141, 255, 47, 107, 146, 255, 213, 219, 225, 255, 251, 249, 248, 255,
+ 245, 245, 245, 255, 253, 252, 251, 255, 170, 190, 204, 255, 40, 97, 138,
+ 255, 54, 113, 150, 255, 232, 236, 239, 255, 254, 252, 249, 255, 165, 186,
+ 201, 255, 39, 101, 142, 255, 2, 79, 127, 255, 0, 71, 121, 255, 0,
+ 73, 123, 255, 52, 111, 150, 255, 113, 152, 178, 255, 46, 107, 146, 255,
+ 46, 106, 145, 255, 203, 211, 218, 255, 255, 254, 252, 255, 213, 219, 226,
+ 255, 90, 136, 166, 255, 21, 91, 136, 255, 0, 74, 124, 255, 0, 72,
+ 122, 255, 14, 87, 133, 255, 65, 118, 154, 255, 166, 190, 205, 255, 249,
+ 249, 247, 255, 212, 219, 224, 255, 48, 107, 145, 255, 40, 99, 139, 255,
+ 181, 193, 205, 255, 250, 248, 246, 255, 241, 241, 241, 255, 241, 241, 241,
+ 255, 240, 240, 240, 255, 240, 240, 240, 255, 240, 240, 240, 255, 255, 255,
+ 255, 255, 199, 199, 199, 205, 10, 10, 10, 9, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 8, 8, 8, 7, 194, 194, 194, 202, 250, 253, 254, 255, 238, 227,
+ 219, 255, 230, 161, 95, 255, 228, 143, 60, 255, 231, 170, 111, 255, 239,
+ 231, 224, 255, 245, 250, 254, 255, 255, 255, 255, 255, 159, 159, 159, 163,
+ 136, 136, 136, 139, 253, 253, 254, 255, 243, 246, 250, 255, 234, 179, 130,
+ 255, 228, 132, 36, 255, 229, 139, 50, 255, 229, 139, 50, 255, 229, 138,
+ 48, 255, 229, 134, 41, 255, 230, 150, 72, 255, 236, 193, 154, 255, 239,
+ 216, 194, 255, 240, 223, 211, 255, 240, 220, 203, 255, 238, 204, 172, 255,
+ 232, 163, 97, 255, 228, 135, 42, 255, 229, 137, 46, 255, 229, 139, 49,
+ 255, 229, 139, 49, 255, 229, 135, 43, 255, 229, 140, 54, 255, 241, 223,
+ 207, 255, 245, 248, 251, 255, 244, 244, 244, 255, 241, 241, 242, 255, 236,
+ 237, 239, 255, 239, 239, 240, 255, 253, 250, 248, 255, 233, 235, 237, 255,
+ 190, 200, 211, 255, 173, 187, 200, 255, 201, 210, 218, 255, 244, 244, 244,
+ 255, 252, 251, 248, 255, 245, 245, 244, 255, 242, 242, 243, 255, 237, 238,
+ 239, 255, 238, 239, 240, 255, 244, 244, 244, 255, 245, 245, 244, 255, 253,
+ 250, 248, 255, 248, 246, 245, 255, 224, 228, 232, 255, 197, 206, 215, 255,
+ 201, 209, 217, 255, 228, 231, 235, 255, 248, 247, 245, 255, 252, 249, 248,
+ 255, 244, 244, 244, 255, 242, 242, 242, 255, 237, 238, 239, 255, 237, 238,
+ 239, 255, 243, 243, 243, 255, 244, 244, 244, 255, 244, 244, 244, 255, 244,
+ 244, 244, 255, 241, 242, 242, 255, 237, 238, 239, 255, 237, 238, 239, 255,
+ 243, 243, 243, 255, 244, 244, 244, 255, 252, 249, 247, 255, 232, 234, 236,
+ 255, 192, 201, 212, 255, 173, 187, 200, 255, 198, 207, 216, 255, 241, 241,
+ 241, 255, 250, 247, 246, 255, 236, 237, 238, 255, 236, 237, 238, 255, 241,
+ 241, 241, 255, 243, 243, 243, 255, 249, 247, 246, 255, 250, 246, 245, 255,
+ 227, 230, 233, 255, 199, 208, 216, 255, 193, 203, 212, 255, 220, 225, 229,
+ 255, 243, 242, 242, 255, 251, 248, 246, 255, 241, 241, 241, 255, 240, 240,
+ 240, 255, 234, 235, 237, 255, 233, 234, 236, 255, 237, 238, 238, 255, 240,
+ 240, 240, 255, 240, 240, 240, 255, 240, 240, 240, 255, 240, 240, 240, 255,
+ 244, 244, 244, 255, 254, 254, 254, 255, 194, 194, 194, 199, 43, 43, 43,
+ 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 84, 84, 84, 87, 253, 253, 252, 255, 246, 247, 248, 255, 240, 238, 238,
+ 255, 239, 234, 229, 255, 240, 242, 243, 255, 250, 252, 254, 255, 247, 247,
+ 246, 252, 134, 134, 134, 134, 0, 0, 0, 0, 30, 30, 30, 31, 226,
+ 226, 225, 235, 248, 250, 253, 255, 240, 231, 225, 255, 230, 154, 83, 255,
+ 227, 133, 39, 255, 228, 138, 49, 255, 228, 138, 49, 255, 228, 138, 49,
+ 255, 228, 135, 44, 255, 227, 133, 39, 255, 228, 138, 49, 255, 228, 140,
+ 55, 255, 228, 139, 52, 255, 227, 134, 42, 255, 227, 134, 41, 255, 228,
+ 138, 48, 255, 228, 138, 49, 255, 228, 138, 49, 255, 228, 135, 43, 255,
+ 228, 137, 47, 255, 237, 205, 176, 255, 245, 248, 252, 255, 253, 253, 253,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 255, 253, 253,
+ 253, 255, 253, 253, 253, 255, 254, 254, 254, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 254, 253, 255,
+ 252, 252, 252, 255, 252, 252, 252, 255, 252, 252, 252, 255, 255, 254, 253,
+ 255, 255, 254, 253, 255, 252, 252, 252, 255, 251, 251, 251, 255, 251, 251,
+ 251, 255, 252, 252, 252, 255, 254, 254, 254, 255, 225, 225, 225, 232, 141,
+ 141, 141, 145, 8, 8, 8, 7, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 124,
+ 124, 124, 127, 236, 236, 236, 242, 255, 255, 255, 255, 254, 255, 255, 255,
+ 254, 255, 255, 255, 215, 215, 215, 219, 98, 98, 98, 99, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 90, 90, 92, 255, 255,
+ 255, 255, 244, 247, 250, 255, 238, 224, 214, 255, 229, 152, 81, 255, 226,
+ 131, 36, 255, 227, 137, 47, 255, 227, 138, 49, 255, 227, 138, 49, 255,
+ 227, 137, 48, 255, 227, 137, 47, 255, 227, 136, 46, 255, 227, 136, 46,
+ 255, 227, 137, 48, 255, 227, 138, 48, 255, 227, 138, 48, 255, 227, 137,
+ 48, 255, 226, 133, 39, 255, 227, 137, 48, 255, 235, 196, 160, 255, 244,
+ 249, 254, 255, 247, 248, 248, 255, 183, 183, 183, 190, 162, 162, 162, 169,
+ 163, 163, 163, 170, 164, 164, 164, 170, 164, 164, 164, 170, 164, 164, 164,
+ 170, 164, 164, 164, 170, 164, 164, 164, 170, 164, 164, 164, 170, 164, 164,
+ 164, 170, 164, 164, 164, 170, 164, 164, 164, 170, 164, 164, 164, 170, 164,
+ 164, 164, 170, 164, 164, 164, 170, 164, 164, 164, 170, 164, 164, 164, 170,
+ 164, 164, 164, 170, 164, 164, 164, 170, 164, 164, 164, 170, 164, 164, 164,
+ 170, 164, 164, 164, 170, 164, 164, 164, 170, 164, 164, 164, 170, 164, 164,
+ 164, 170, 164, 164, 164, 170, 164, 164, 164, 170, 164, 164, 164, 170, 164,
+ 164, 164, 170, 163, 163, 163, 170, 163, 163, 163, 170, 163, 163, 163, 170,
+ 163, 163, 163, 170, 163, 163, 163, 170, 163, 163, 163, 170, 163, 163, 163,
+ 170, 163, 163, 163, 170, 163, 163, 163, 170, 163, 163, 163, 170, 163, 163,
+ 163, 170, 163, 163, 163, 170, 163, 163, 163, 170, 163, 163, 163, 170, 163,
+ 163, 163, 170, 163, 163, 163, 170, 163, 163, 163, 170, 162, 162, 162, 170,
+ 162, 162, 162, 170, 162, 162, 162, 170, 162, 162, 162, 170, 162, 162, 162,
+ 170, 162, 162, 162, 170, 162, 162, 162, 170, 162, 162, 162, 170, 162, 162,
+ 162, 170, 162, 162, 162, 169, 162, 162, 162, 169, 162, 162, 162, 169, 162,
+ 162, 162, 169, 161, 161, 161, 169, 161, 161, 161, 169, 161, 161, 161, 169,
+ 161, 161, 161, 169, 161, 161, 161, 169, 162, 162, 162, 171, 156, 156, 156,
+ 162, 112, 112, 112, 112, 32, 32, 32, 32, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47,
+ 47, 46, 131, 131, 131, 134, 147, 147, 147, 152, 105, 105, 105, 106, 12,
+ 12, 12, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 2, 2, 2, 2, 144, 144, 144, 147, 254, 254, 254,
+ 255, 243, 246, 250, 255, 238, 228, 221, 255, 230, 168, 111, 255, 225, 134,
+ 45, 255, 225, 131, 37, 255, 226, 135, 43, 255, 226, 136, 46, 255, 226,
+ 137, 48, 255, 226, 137, 48, 255, 226, 137, 48, 255, 226, 137, 47, 255,
+ 226, 135, 45, 255, 225, 133, 40, 255, 225, 130, 36, 255, 228, 152, 76,
+ 255, 237, 209, 184, 255, 244, 248, 253, 255, 255, 255, 255, 255, 167, 167,
+ 167, 172, 5, 5, 5, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 9, 9, 9, 8, 153, 153, 153, 158, 249, 249, 249, 255,
+ 246, 248, 251, 255, 239, 242, 246, 255, 235, 207, 184, 255, 229, 165, 105,
+ 255, 226, 146, 70, 255, 225, 135, 48, 255, 224, 130, 38, 255, 224, 129,
+ 34, 255, 224, 129, 34, 255, 224, 131, 40, 255, 226, 141, 58, 255, 228,
+ 158, 91, 255, 233, 190, 151, 255, 240, 237, 235, 255, 247, 251, 255, 255,
+ 250, 250, 251, 255, 177, 177, 177, 180, 23, 23, 23, 22, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 113, 113, 113, 115, 225, 225, 225, 233, 253,
+ 254, 254, 255, 244, 248, 252, 255, 239, 241, 244, 255, 238, 232, 228, 255,
+ 235, 209, 191, 255, 232, 190, 152, 255, 231, 184, 138, 255, 232, 185, 138,
+ 255, 232, 196, 164, 255, 237, 225, 217, 255, 240, 240, 240, 255, 246, 250,
+ 255, 255, 255, 255, 255, 255, 230, 230, 230, 235, 110, 110, 110, 111, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 40, 40, 40, 40, 149, 149, 149, 153, 220, 220,
+ 220, 229, 251, 252, 252, 255, 252, 254, 255, 255, 249, 253, 255, 255, 246,
+ 252, 255, 255, 245, 251, 255, 255, 246, 252, 255, 255, 248, 254, 255, 255,
+ 253, 255, 255, 255, 250, 251, 252, 255, 217, 218, 218, 226, 153, 153, 153,
+ 157, 45, 45, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 102, 102, 102,
+ 102, 152, 152, 152, 157, 175, 175, 175, 185, 197, 197, 197, 210, 202, 203,
+ 203, 215, 197, 197, 197, 209, 180, 180, 180, 188, 155, 155, 155, 160, 97,
+ 97, 97, 98, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 7, 7, 7, 7, 8, 8, 8, 8, 7, 7, 7,
+ 6, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
+
+ *width = 115;
+ *height = 32;
+
+ // only load the requested logo
+ // allocate a new array
+ *data = new unsigned char[14720];
+ // and copy it. Now we are certain that the calling function
+ // can control the memory location
+ for(int i = 0; i < 14720 /* tmp array size */; i++)
+ {
+ (*data)[i] = logo_blender_raw[i];
+ }
+
+}
+
+
+void GetRawBlender3DLogo(unsigned char **data, int *width, int *height)
+{
+ // create an array that will automatically be deleted when)
+ // we're outta this scope
+ static unsigned char logo_blender3d_raw[]= {255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255,
+ 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255,
+ 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0,
+ 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255,
+ 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255,
+ 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255,
+ 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0,
+ 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255,
+ 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 57, 255, 255,
+ 255, 243, 255, 255, 255, 252, 255, 255, 255, 251, 255, 255, 255, 200, 255,
+ 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0,
+ 255, 255, 255, 57, 255, 255, 255, 243, 255, 255, 255, 252, 255, 255, 255,
+ 251, 255, 255, 255, 200, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255,
+ 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255,
+ 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0,
+ 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255,
+ 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255,
+ 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255,
+ 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 141, 255, 255, 255, 248,
+ 255, 255, 255, 253, 255, 255, 255, 248, 255, 255, 255, 141, 255, 255, 255,
+ 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255,
+ 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255,
+ 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0,
+ 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255,
+ 17, 255, 255, 255, 159, 255, 255, 255, 231, 255, 255, 255, 247, 255, 255,
+ 255, 247, 255, 255, 255, 234, 255, 255, 255, 176, 255, 255, 255, 36, 255,
+ 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0,
+ 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 141, 255, 255, 255,
+ 248, 255, 255, 255, 253, 255, 255, 255, 248, 255, 255, 255, 141, 255, 255,
+ 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255,
+ 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0,
+ 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255,
+ 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255,
+ 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255,
+ 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0,
+ 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255,
+ 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255,
+ 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255,
+ 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0,
+ 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255,
+ 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255,
+ 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255,
+ 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0,
+ 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255,
+ 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255,
+ 255, 86, 207, 207, 207, 255, 70, 70, 70, 255, 118, 118, 118, 255, 255,
+ 255, 255, 236, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0,
+ 255, 255, 255, 0, 255, 255, 255, 86, 207, 207, 207, 255, 70, 70, 70,
+ 255, 118, 118, 118, 255, 255, 255, 255, 236, 255, 255, 255, 0, 255, 255,
+ 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255,
+ 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0,
+ 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255,
+ 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255,
+ 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255,
+ 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 170,
+ 153, 153, 153, 255, 70, 70, 70, 255, 153, 153, 153, 255, 255, 255, 255,
+ 170, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255,
+ 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255,
+ 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0,
+ 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255,
+ 141, 255, 255, 255, 255, 239, 239, 239, 255, 153, 153, 153, 255, 137, 137,
+ 137, 255, 137, 137, 137, 255, 153, 153, 153, 255, 223, 223, 223, 255, 255,
+ 255, 255, 255, 255, 255, 255, 141, 255, 255, 255, 0, 255, 255, 255, 0,
+ 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255,
+ 170, 153, 153, 153, 255, 70, 70, 70, 255, 153, 153, 153, 255, 255, 255,
+ 255, 170, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255,
+ 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0,
+ 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255,
+ 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255,
+ 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255,
+ 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0,
+ 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255,
+ 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 86, 255, 255,
+ 255, 172, 255, 255, 255, 172, 255, 255, 255, 86, 255, 255, 255, 86, 255,
+ 255, 255, 144, 255, 255, 255, 144, 255, 255, 255, 57, 255, 255, 255, 86,
+ 255, 255, 255, 144, 255, 255, 255, 207, 255, 255, 255, 207, 255, 255, 255,
+ 172, 255, 255, 255, 86, 255, 255, 255, 86, 255, 255, 255, 144, 255, 255,
+ 255, 144, 255, 255, 255, 57, 255, 255, 255, 86, 255, 255, 255, 144, 255,
+ 255, 255, 207, 255, 255, 255, 207, 255, 255, 255, 172, 255, 255, 255, 86,
+ 255, 255, 255, 86, 255, 255, 255, 144, 255, 255, 255, 144, 255, 255, 255,
+ 57, 255, 255, 255, 86, 255, 255, 255, 144, 255, 255, 255, 144, 255, 255,
+ 255, 57, 255, 255, 255, 144, 187, 187, 187, 255, 0, 0, 0, 253, 70,
+ 70, 70, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 255, 255,
+ 255, 255, 255, 251, 255, 255, 255, 207, 255, 255, 255, 163, 187, 187, 187,
+ 255, 0, 0, 0, 253, 70, 70, 70, 255, 255, 255, 255, 251, 255, 255,
+ 255, 0, 255, 255, 255, 141, 255, 255, 255, 235, 255, 255, 255, 254, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 255, 255, 255, 188,
+ 255, 255, 255, 54, 255, 255, 255, 198, 255, 255, 255, 234, 255, 255, 255,
+ 243, 255, 255, 255, 248, 255, 255, 255, 254, 255, 255, 255, 254, 255, 255,
+ 255, 251, 255, 255, 255, 207, 255, 255, 255, 17, 255, 255, 255, 0, 255,
+ 255, 255, 170, 255, 255, 255, 250, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 137, 137, 137, 255, 0, 0, 0, 253, 137, 137, 137,
+ 255, 255, 255, 255, 228, 255, 255, 255, 141, 255, 255, 255, 235, 255, 255,
+ 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 255,
+ 255, 255, 188, 255, 255, 255, 54, 255, 255, 255, 198, 255, 255, 255, 234,
+ 255, 255, 255, 237, 255, 255, 255, 248, 255, 255, 255, 254, 255, 255, 255,
+ 253, 255, 255, 255, 255, 153, 153, 153, 255, 0, 0, 0, 253, 0, 0,
+ 0, 253, 0, 0, 0, 253, 0, 0, 0, 253, 0, 0, 0, 253, 0,
+ 0, 0, 253, 153, 153, 153, 255, 255, 255, 255, 251, 255, 255, 255, 0,
+ 255, 255, 255, 170, 255, 255, 255, 250, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 137, 137, 137, 255, 0, 0, 0, 253, 137, 137,
+ 137, 255, 255, 255, 255, 228, 255, 255, 255, 0, 255, 255, 255, 0, 255,
+ 255, 255, 0, 255, 255, 255, 86, 255, 255, 255, 215, 255, 255, 255, 240,
+ 255, 255, 255, 231, 255, 255, 255, 159, 255, 255, 255, 17, 255, 255, 255,
+ 0, 255, 255, 255, 57, 255, 255, 255, 206, 255, 255, 255, 237, 255, 255,
+ 255, 231, 255, 255, 255, 159, 255, 255, 255, 35, 255, 255, 255, 105, 255,
+ 255, 255, 142, 255, 255, 255, 208, 255, 255, 255, 229, 255, 255, 255, 237,
+ 255, 255, 255, 215, 255, 255, 255, 205, 255, 255, 255, 228, 255, 255, 255,
+ 234, 255, 255, 255, 198, 255, 255, 255, 36, 255, 255, 255, 0, 255, 255,
+ 255, 227, 187, 187, 187, 255, 187, 187, 187, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 187, 187, 187, 255, 207, 207, 207, 255, 255, 255, 255, 254,
+ 255, 255, 255, 255, 187, 187, 187, 255, 207, 207, 207, 255, 187, 187, 187,
+ 255, 187, 187, 187, 255, 255, 255, 255, 255, 255, 255, 255, 255, 187, 187,
+ 187, 255, 207, 207, 207, 255, 255, 255, 255, 254, 255, 255, 255, 255, 187,
+ 187, 187, 255, 207, 207, 207, 255, 187, 187, 187, 255, 187, 187, 187, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 187, 187, 187, 255, 207, 207, 207,
+ 255, 255, 255, 255, 254, 255, 255, 255, 255, 187, 187, 187, 255, 207, 207,
+ 207, 255, 255, 255, 255, 170, 255, 255, 255, 172, 187, 187, 187, 255, 0,
+ 0, 0, 253, 70, 70, 70, 255, 153, 153, 153, 255, 86, 86, 86, 255,
+ 70, 70, 70, 255, 118, 118, 118, 255, 239, 239, 239, 255, 255, 255, 255,
+ 255, 187, 187, 187, 255, 0, 0, 0, 253, 70, 70, 70, 255, 255, 255,
+ 255, 254, 255, 255, 255, 246, 255, 255, 255, 255, 153, 153, 153, 255, 118,
+ 118, 118, 255, 69, 69, 69, 254, 70, 70, 70, 255, 137, 137, 137, 255,
+ 239, 239, 239, 255, 255, 255, 255, 254, 223, 223, 223, 255, 137, 137, 137,
+ 255, 153, 153, 153, 255, 169, 169, 169, 255, 102, 102, 102, 255, 70, 70,
+ 70, 255, 118, 118, 118, 255, 239, 239, 239, 255, 255, 255, 255, 236, 255,
+ 255, 255, 236, 255, 255, 255, 255, 137, 137, 137, 255, 70, 70, 70, 255,
+ 70, 70, 70, 255, 137, 137, 137, 255, 118, 118, 118, 255, 0, 0, 0,
+ 253, 137, 137, 137, 255, 255, 255, 255, 254, 255, 255, 255, 255, 153, 153,
+ 153, 255, 118, 118, 118, 255, 69, 69, 69, 254, 70, 70, 70, 255, 137,
+ 137, 137, 255, 239, 239, 239, 255, 255, 255, 255, 254, 223, 223, 223, 255,
+ 137, 137, 137, 255, 153, 153, 153, 255, 207, 207, 207, 255, 86, 86, 86,
+ 255, 70, 70, 70, 255, 223, 223, 223, 255, 0, 0, 0, 253, 0, 0,
+ 0, 253, 137, 137, 137, 255, 255, 255, 255, 255, 239, 239, 239, 255, 86,
+ 86, 86, 255, 0, 0, 0, 253, 34, 34, 34, 255, 255, 255, 255, 253,
+ 255, 255, 255, 236, 255, 255, 255, 255, 137, 137, 137, 255, 70, 70, 70,
+ 255, 70, 70, 70, 255, 137, 137, 137, 255, 118, 118, 118, 255, 0, 0,
+ 0, 253, 137, 137, 137, 255, 255, 255, 255, 233, 255, 255, 255, 0, 255,
+ 255, 255, 0, 255, 255, 255, 214, 255, 255, 255, 255, 187, 187, 187, 255,
+ 137, 137, 137, 255, 153, 153, 153, 255, 239, 239, 239, 255, 255, 255, 255,
+ 254, 255, 255, 255, 224, 255, 255, 255, 255, 207, 207, 207, 255, 137, 137,
+ 137, 255, 153, 153, 153, 255, 239, 239, 239, 255, 255, 255, 255, 255, 239,
+ 239, 239, 255, 187, 187, 187, 255, 223, 223, 223, 255, 169, 169, 169, 255,
+ 137, 137, 137, 255, 187, 187, 187, 255, 255, 255, 255, 255, 153, 153, 153,
+ 255, 137, 137, 137, 255, 223, 223, 223, 255, 255, 255, 255, 255, 255, 255,
+ 255, 36, 255, 255, 255, 205, 86, 86, 86, 255, 0, 0, 0, 253, 239,
+ 239, 239, 255, 222, 222, 222, 255, 0, 0, 0, 253, 18, 18, 18, 255,
+ 255, 255, 255, 255, 207, 207, 207, 255, 0, 0, 0, 253, 137, 137, 137,
+ 255, 86, 86, 86, 255, 0, 0, 0, 253, 239, 239, 239, 255, 222, 222,
+ 222, 255, 0, 0, 0, 253, 18, 18, 18, 255, 255, 255, 255, 255, 207,
+ 207, 207, 255, 0, 0, 0, 253, 137, 137, 137, 255, 86, 86, 86, 255,
+ 0, 0, 0, 253, 239, 239, 239, 255, 222, 222, 222, 255, 0, 0, 0,
+ 253, 18, 18, 18, 255, 255, 255, 255, 255, 207, 207, 207, 255, 0, 0,
+ 0, 253, 137, 137, 137, 255, 255, 255, 255, 116, 255, 255, 255, 172, 187,
+ 187, 187, 255, 0, 0, 0, 253, 0, 0, 0, 253, 0, 0, 0, 253,
+ 70, 70, 70, 254, 33, 33, 33, 255, 0, 0, 0, 253, 18, 18, 18,
+ 255, 239, 239, 239, 255, 187, 187, 187, 255, 0, 0, 0, 253, 70, 70,
+ 70, 255, 255, 255, 255, 254, 255, 255, 255, 255, 50, 50, 50, 255, 0,
+ 0, 0, 253, 69, 69, 69, 254, 137, 137, 137, 254, 103, 103, 103, 254,
+ 0, 0, 0, 253, 18, 18, 18, 255, 239, 239, 239, 255, 187, 187, 187,
+ 255, 0, 0, 0, 253, 0, 0, 0, 253, 18, 18, 18, 255, 69, 69,
+ 69, 254, 18, 18, 18, 255, 0, 0, 0, 253, 70, 70, 70, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 70, 70, 70, 255, 0, 0, 0, 253,
+ 18, 18, 18, 255, 69, 69, 69, 254, 18, 18, 18, 255, 0, 0, 0,
+ 253, 0, 0, 0, 253, 137, 137, 137, 255, 255, 255, 255, 255, 50, 50,
+ 50, 255, 0, 0, 0, 253, 69, 69, 69, 254, 137, 137, 137, 254, 103,
+ 103, 103, 254, 0, 0, 0, 253, 18, 18, 18, 255, 239, 239, 239, 255,
+ 187, 187, 187, 255, 0, 0, 0, 253, 34, 34, 34, 255, 18, 18, 18,
+ 255, 0, 0, 0, 253, 0, 0, 0, 253, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 86, 86, 86, 255, 0, 0, 0, 253, 34, 34, 34, 255,
+ 255, 255, 255, 253, 255, 255, 255, 255, 70, 70, 70, 255, 0, 0, 0,
+ 253, 18, 18, 18, 255, 69, 69, 69, 254, 18, 18, 18, 255, 0, 0,
+ 0, 253, 0, 0, 0, 253, 137, 137, 137, 255, 255, 255, 255, 233, 255,
+ 255, 255, 0, 255, 255, 255, 57, 255, 255, 255, 255, 102, 102, 102, 255,
+ 0, 0, 0, 253, 49, 49, 49, 253, 18, 18, 18, 255, 18, 18, 18,
+ 255, 223, 223, 223, 255, 255, 255, 255, 255, 102, 102, 102, 255, 0, 0,
+ 0, 253, 49, 49, 49, 253, 18, 18, 18, 255, 18, 18, 18, 255, 207,
+ 207, 207, 255, 187, 187, 187, 255, 0, 0, 0, 253, 18, 18, 18, 255,
+ 50, 50, 50, 254, 18, 18, 18, 255, 0, 0, 0, 253, 34, 34, 34,
+ 255, 70, 70, 70, 253, 18, 18, 18, 255, 0, 0, 0, 253, 223, 223,
+ 223, 255, 255, 255, 255, 170, 255, 255, 255, 230, 153, 153, 153, 255, 0,
+ 0, 0, 253, 169, 169, 169, 255, 153, 153, 153, 255, 18, 18, 18, 255,
+ 0, 0, 0, 253, 207, 207, 207, 255, 137, 137, 137, 255, 0, 0, 0,
+ 253, 207, 207, 207, 255, 153, 153, 153, 255, 0, 0, 0, 253, 169, 169,
+ 169, 255, 153, 153, 153, 255, 18, 18, 18, 255, 0, 0, 0, 253, 207,
+ 207, 207, 255, 137, 137, 137, 255, 0, 0, 0, 253, 207, 207, 207, 255,
+ 153, 153, 153, 255, 0, 0, 0, 253, 169, 169, 169, 255, 153, 153, 153,
+ 255, 18, 18, 18, 255, 0, 0, 0, 253, 207, 207, 207, 255, 137, 137,
+ 137, 255, 0, 0, 0, 253, 207, 207, 207, 255, 255, 255, 255, 170, 255,
+ 255, 255, 172, 187, 187, 187, 255, 0, 0, 0, 253, 18, 18, 18, 255,
+ 207, 207, 207, 255, 255, 255, 255, 255, 255, 255, 255, 255, 86, 86, 86,
+ 255, 0, 0, 0, 253, 137, 137, 137, 255, 187, 187, 187, 255, 0, 0,
+ 0, 253, 70, 70, 70, 255, 255, 255, 255, 255, 169, 169, 169, 255, 0,
+ 0, 0, 253, 86, 86, 86, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 137, 137, 137, 255, 0, 0, 0, 253, 137, 137, 137,
+ 255, 187, 187, 187, 255, 0, 0, 0, 253, 0, 0, 0, 253, 207, 207,
+ 207, 255, 255, 255, 255, 255, 223, 223, 223, 255, 0, 0, 0, 253, 0,
+ 0, 0, 253, 255, 255, 255, 255, 187, 187, 187, 255, 0, 0, 0, 253,
+ 34, 34, 34, 255, 239, 239, 239, 255, 255, 255, 255, 255, 239, 239, 239,
+ 255, 50, 50, 50, 255, 0, 0, 0, 253, 137, 137, 137, 255, 169, 169,
+ 169, 255, 0, 0, 0, 253, 86, 86, 86, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 137, 137, 137, 255, 0, 0, 0, 253,
+ 137, 137, 137, 255, 187, 187, 187, 255, 0, 0, 0, 253, 0, 0, 0,
+ 253, 137, 137, 137, 255, 255, 255, 255, 255, 169, 169, 169, 255, 255, 255,
+ 255, 255, 255, 255, 255, 0, 255, 255, 255, 86, 138, 138, 138, 236, 0,
+ 0, 0, 253, 0, 0, 0, 253, 0, 0, 0, 253, 18, 18, 18, 255,
+ 223, 223, 223, 255, 255, 255, 255, 255, 187, 187, 187, 255, 0, 0, 0,
+ 253, 34, 34, 34, 255, 239, 239, 239, 255, 255, 255, 255, 255, 239, 239,
+ 239, 255, 50, 50, 50, 255, 0, 0, 0, 253, 137, 137, 137, 255, 255,
+ 255, 255, 233, 255, 255, 255, 0, 255, 255, 255, 170, 207, 207, 207, 255,
+ 0, 0, 0, 253, 118, 118, 118, 255, 255, 255, 255, 255, 187, 187, 187,
+ 255, 0, 0, 0, 253, 137, 137, 137, 254, 207, 207, 207, 255, 0, 0,
+ 0, 253, 118, 118, 118, 255, 255, 255, 255, 255, 239, 239, 239, 255, 0,
+ 0, 0, 253, 86, 86, 86, 255, 187, 187, 187, 255, 0, 0, 0, 253,
+ 86, 86, 86, 255, 255, 255, 255, 255, 169, 169, 169, 255, 0, 0, 0,
+ 253, 102, 102, 102, 255, 255, 255, 255, 255, 169, 169, 169, 255, 0, 0,
+ 0, 253, 137, 137, 137, 255, 255, 255, 255, 198, 255, 255, 255, 141, 239,
+ 239, 239, 255, 0, 0, 0, 253, 102, 102, 102, 255, 102, 102, 102, 255,
+ 86, 86, 86, 255, 18, 18, 18, 255, 137, 137, 137, 255, 86, 86, 86,
+ 255, 34, 34, 34, 255, 255, 255, 255, 255, 239, 239, 239, 255, 0, 0,
+ 0, 253, 102, 102, 102, 255, 102, 102, 102, 255, 86, 86, 86, 255, 18,
+ 18, 18, 255, 137, 137, 137, 255, 86, 86, 86, 255, 34, 34, 34, 255,
+ 255, 255, 255, 255, 239, 239, 239, 255, 0, 0, 0, 253, 102, 102, 102,
+ 255, 102, 102, 102, 255, 86, 86, 86, 255, 18, 18, 18, 255, 137, 137,
+ 137, 255, 86, 86, 86, 255, 34, 34, 34, 255, 255, 255, 255, 255, 255,
+ 255, 255, 57, 255, 255, 255, 172, 187, 187, 187, 255, 0, 0, 0, 253,
+ 70, 70, 70, 255, 255, 255, 255, 255, 255, 255, 255, 57, 255, 255, 255,
+ 245, 187, 187, 187, 255, 0, 0, 0, 253, 70, 70, 70, 255, 187, 187,
+ 187, 255, 0, 0, 0, 253, 70, 70, 70, 255, 255, 255, 255, 255, 137,
+ 137, 137, 255, 0, 0, 0, 253, 0, 0, 0, 253, 0, 0, 0, 253,
+ 0, 0, 0, 253, 0, 0, 0, 253, 0, 0, 0, 253, 0, 0, 0,
+ 253, 70, 70, 70, 255, 187, 187, 187, 255, 0, 0, 0, 253, 70, 70,
+ 70, 255, 255, 255, 255, 255, 255, 255, 255, 95, 255, 255, 255, 255, 0,
+ 0, 0, 253, 0, 0, 0, 253, 255, 255, 255, 255, 137, 137, 137, 255,
+ 0, 0, 0, 253, 137, 137, 137, 255, 255, 255, 255, 254, 255, 255, 255,
+ 35, 255, 255, 255, 253, 137, 137, 137, 255, 0, 0, 0, 253, 137, 137,
+ 137, 255, 137, 137, 137, 255, 0, 0, 0, 253, 0, 0, 0, 253, 0,
+ 0, 0, 253, 0, 0, 0, 253, 0, 0, 0, 253, 0, 0, 0, 253,
+ 0, 0, 0, 253, 70, 70, 70, 255, 187, 187, 187, 255, 0, 0, 0,
+ 253, 50, 50, 50, 255, 255, 255, 255, 255, 255, 255, 255, 222, 255, 255,
+ 255, 213, 255, 255, 255, 252, 255, 255, 255, 254, 255, 255, 255, 254, 187,
+ 187, 187, 255, 137, 137, 137, 255, 137, 137, 137, 255, 34, 34, 34, 255,
+ 0, 0, 0, 253, 34, 34, 34, 255, 255, 255, 255, 255, 137, 137, 137,
+ 255, 0, 0, 0, 253, 137, 137, 137, 255, 255, 255, 255, 254, 255, 255,
+ 255, 35, 255, 255, 255, 253, 137, 137, 137, 255, 0, 0, 0, 253, 137,
+ 137, 137, 255, 255, 255, 255, 233, 255, 255, 255, 0, 255, 255, 255, 194,
+ 137, 137, 137, 255, 0, 0, 0, 253, 187, 187, 187, 255, 255, 255, 255,
+ 242, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 137, 137,
+ 137, 255, 0, 0, 0, 253, 187, 187, 187, 255, 255, 255, 255, 234, 255,
+ 255, 255, 255, 70, 70, 70, 255, 18, 18, 18, 255, 187, 187, 187, 255,
+ 0, 0, 0, 253, 137, 137, 137, 255, 255, 255, 255, 253, 187, 187, 187,
+ 255, 0, 0, 0, 253, 137, 137, 137, 255, 255, 255, 255, 252, 187, 187,
+ 187, 255, 0, 0, 0, 253, 137, 137, 137, 255, 255, 255, 255, 233, 255,
+ 255, 255, 17, 255, 255, 255, 255, 70, 70, 70, 255, 34, 34, 34, 255,
+ 50, 50, 50, 255, 137, 137, 137, 255, 86, 86, 86, 255, 70, 70, 70,
+ 255, 0, 0, 0, 253, 118, 118, 118, 255, 255, 255, 255, 253, 255, 255,
+ 255, 255, 70, 70, 70, 255, 34, 34, 34, 255, 50, 50, 50, 255, 137,
+ 137, 137, 255, 86, 86, 86, 255, 70, 70, 70, 255, 0, 0, 0, 253,
+ 118, 118, 118, 255, 255, 255, 255, 253, 255, 255, 255, 255, 70, 70, 70,
+ 255, 34, 34, 34, 255, 50, 50, 50, 255, 137, 137, 137, 255, 86, 86,
+ 86, 255, 70, 70, 70, 255, 0, 0, 0, 253, 118, 118, 118, 255, 255,
+ 255, 255, 255, 255, 255, 255, 252, 255, 255, 255, 254, 187, 187, 187, 255,
+ 0, 0, 0, 253, 50, 50, 50, 255, 255, 255, 255, 255, 255, 255, 255,
+ 250, 255, 255, 255, 255, 153, 153, 153, 255, 0, 0, 0, 253, 86, 86,
+ 86, 255, 187, 187, 187, 255, 0, 0, 0, 253, 70, 70, 70, 255, 255,
+ 255, 255, 255, 137, 137, 137, 255, 0, 0, 0, 253, 86, 86, 86, 255,
+ 187, 187, 187, 255, 187, 187, 187, 255, 187, 187, 187, 255, 187, 187, 187,
+ 255, 187, 187, 187, 255, 207, 207, 207, 255, 187, 187, 187, 255, 0, 0,
+ 0, 253, 70, 70, 70, 255, 255, 255, 255, 254, 255, 255, 255, 0, 255,
+ 255, 255, 255, 0, 0, 0, 253, 0, 0, 0, 253, 255, 255, 255, 255,
+ 137, 137, 137, 255, 0, 0, 0, 253, 102, 102, 102, 255, 255, 255, 255,
+ 255, 255, 255, 255, 243, 255, 255, 255, 255, 118, 118, 118, 255, 0, 0,
+ 0, 253, 137, 137, 137, 255, 137, 137, 137, 255, 0, 0, 0, 253, 86,
+ 86, 86, 255, 187, 187, 187, 255, 187, 187, 187, 255, 187, 187, 187, 255,
+ 187, 187, 187, 255, 187, 187, 187, 255, 207, 207, 207, 255, 187, 187, 187,
+ 255, 0, 0, 0, 253, 70, 70, 70, 255, 255, 255, 255, 254, 255, 255,
+ 255, 0, 255, 255, 255, 86, 153, 153, 153, 255, 70, 70, 70, 255, 102,
+ 102, 102, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 255, 255,
+ 187, 187, 187, 255, 0, 0, 0, 253, 0, 0, 0, 253, 187, 187, 187,
+ 255, 137, 137, 137, 255, 0, 0, 0, 253, 102, 102, 102, 255, 255, 255,
+ 255, 255, 255, 255, 255, 243, 255, 255, 255, 255, 118, 118, 118, 255, 0,
+ 0, 0, 253, 137, 137, 137, 255, 255, 255, 255, 254, 255, 255, 255, 252,
+ 255, 255, 255, 254, 153, 153, 153, 255, 0, 0, 0, 253, 169, 169, 169,
+ 255, 255, 255, 255, 251, 255, 255, 255, 255, 187, 187, 187, 255, 207, 207,
+ 207, 255, 153, 153, 153, 255, 0, 0, 0, 253, 169, 169, 169, 255, 255,
+ 255, 255, 248, 255, 255, 255, 255, 50, 50, 50, 255, 34, 34, 34, 255,
+ 187, 187, 187, 255, 0, 0, 0, 253, 137, 137, 137, 255, 255, 255, 255,
+ 249, 187, 187, 187, 255, 0, 0, 0, 253, 137, 137, 137, 255, 255, 255,
+ 255, 249, 187, 187, 187, 255, 0, 0, 0, 253, 137, 137, 137, 255, 255,
+ 255, 255, 233, 255, 255, 255, 0, 255, 255, 255, 241, 137, 137, 137, 255,
+ 0, 0, 0, 253, 0, 0, 0, 253, 207, 207, 207, 255, 153, 153, 153,
+ 255, 0, 0, 0, 253, 0, 0, 0, 253, 207, 207, 207, 255, 255, 255,
+ 255, 200, 255, 255, 255, 241, 137, 137, 137, 255, 0, 0, 0, 253, 0,
+ 0, 0, 253, 207, 207, 207, 255, 153, 153, 153, 255, 0, 0, 0, 253,
+ 0, 0, 0, 253, 207, 207, 207, 255, 255, 255, 255, 200, 255, 255, 255,
+ 241, 137, 137, 137, 255, 0, 0, 0, 253, 0, 0, 0, 253, 207, 207,
+ 207, 255, 153, 153, 153, 255, 0, 0, 0, 253, 0, 0, 0, 253, 207,
+ 207, 207, 255, 207, 207, 207, 255, 70, 70, 70, 255, 118, 118, 118, 255,
+ 187, 187, 187, 255, 0, 0, 0, 253, 0, 0, 0, 253, 86, 86, 86,
+ 255, 187, 187, 187, 255, 153, 153, 153, 255, 18, 18, 18, 255, 0, 0,
+ 0, 253, 169, 169, 169, 255, 187, 187, 187, 255, 0, 0, 0, 253, 70,
+ 70, 70, 255, 255, 255, 255, 255, 223, 223, 223, 255, 0, 0, 0, 253,
+ 18, 18, 18, 255, 169, 169, 169, 255, 255, 255, 255, 255, 223, 223, 223,
+ 255, 50, 50, 50, 255, 0, 0, 0, 253, 138, 138, 138, 248, 187, 187,
+ 187, 255, 0, 0, 0, 253, 70, 70, 70, 255, 255, 255, 255, 254, 255,
+ 255, 255, 0, 255, 255, 255, 255, 0, 0, 0, 253, 0, 0, 0, 253,
+ 255, 255, 255, 255, 223, 223, 223, 255, 18, 18, 18, 255, 0, 0, 0,
+ 253, 137, 137, 137, 255, 187, 187, 187, 255, 137, 137, 137, 255, 0, 0,
+ 0, 253, 0, 0, 0, 253, 137, 137, 137, 255, 223, 223, 223, 255, 0,
+ 0, 0, 253, 18, 18, 18, 255, 169, 169, 169, 255, 255, 255, 255, 255,
+ 223, 223, 223, 255, 50, 50, 50, 255, 0, 0, 0, 253, 138, 138, 138,
+ 248, 187, 187, 187, 255, 0, 0, 0, 253, 70, 70, 70, 255, 255, 255,
+ 255, 254, 255, 255, 255, 0, 255, 255, 255, 141, 186, 186, 186, 252, 0,
+ 0, 0, 253, 0, 0, 0, 253, 118, 118, 118, 255, 187, 187, 187, 255,
+ 169, 169, 169, 255, 50, 50, 50, 255, 0, 0, 0, 253, 18, 18, 18,
+ 255, 255, 255, 255, 255, 223, 223, 223, 255, 18, 18, 18, 255, 0, 0,
+ 0, 253, 137, 137, 137, 255, 187, 187, 187, 255, 137, 137, 137, 255, 0,
+ 0, 0, 253, 0, 0, 0, 253, 137, 137, 137, 255, 207, 207, 207, 255,
+ 70, 70, 70, 255, 118, 118, 118, 255, 223, 223, 223, 255, 0, 0, 0,
+ 253, 86, 86, 86, 255, 239, 239, 239, 255, 137, 137, 137, 255, 0, 0,
+ 0, 253, 153, 153, 153, 249, 223, 223, 223, 255, 0, 0, 0, 253, 86,
+ 86, 86, 255, 239, 239, 239, 255, 187, 187, 187, 255, 0, 0, 0, 253,
+ 102, 102, 102, 255, 187, 187, 187, 255, 0, 0, 0, 253, 137, 137, 137,
+ 255, 255, 255, 255, 249, 187, 187, 187, 255, 0, 0, 0, 253, 137, 137,
+ 137, 255, 255, 255, 255, 249, 187, 187, 187, 255, 0, 0, 0, 253, 137,
+ 137, 137, 255, 255, 255, 255, 233, 255, 255, 255, 0, 255, 255, 255, 170,
+ 223, 223, 223, 255, 0, 0, 0, 253, 18, 18, 18, 255, 255, 255, 255,
+ 255, 223, 223, 223, 255, 0, 0, 0, 253, 34, 34, 34, 255, 255, 255,
+ 255, 255, 255, 255, 255, 57, 255, 255, 255, 170, 223, 223, 223, 255, 0,
+ 0, 0, 253, 18, 18, 18, 255, 255, 255, 255, 255, 223, 223, 223, 255,
+ 0, 0, 0, 253, 34, 34, 34, 255, 255, 255, 255, 255, 255, 255, 255,
+ 57, 255, 255, 255, 170, 223, 223, 223, 255, 0, 0, 0, 253, 18, 18,
+ 18, 255, 255, 255, 255, 255, 223, 223, 223, 255, 0, 0, 0, 253, 34,
+ 34, 34, 255, 255, 255, 255, 255, 187, 187, 187, 247, 0, 0, 0, 253,
+ 70, 70, 70, 253, 187, 187, 187, 255, 0, 0, 0, 253, 34, 34, 34,
+ 255, 50, 50, 50, 255, 0, 0, 0, 253, 0, 0, 0, 253, 0, 0,
+ 0, 253, 137, 137, 137, 255, 255, 255, 255, 255, 187, 187, 187, 255, 0,
+ 0, 0, 253, 70, 70, 70, 255, 255, 255, 255, 241, 255, 255, 255, 255,
+ 169, 169, 169, 255, 34, 34, 34, 255, 0, 0, 0, 253, 0, 0, 0,
+ 253, 0, 0, 0, 253, 18, 18, 18, 255, 137, 137, 137, 255, 255, 255,
+ 255, 255, 187, 187, 187, 255, 0, 0, 0, 253, 70, 70, 70, 255, 255,
+ 255, 255, 236, 255, 255, 255, 0, 255, 255, 255, 255, 0, 0, 0, 253,
+ 0, 0, 0, 253, 255, 255, 255, 255, 255, 255, 255, 254, 153, 153, 153,
+ 255, 18, 18, 18, 255, 0, 0, 0, 253, 0, 0, 0, 253, 18, 18,
+ 18, 255, 70, 70, 70, 255, 0, 0, 0, 253, 137, 137, 137, 255, 255,
+ 255, 255, 255, 169, 169, 169, 255, 34, 34, 34, 255, 0, 0, 0, 253,
+ 0, 0, 0, 253, 0, 0, 0, 253, 18, 18, 18, 255, 137, 137, 137,
+ 255, 255, 255, 255, 255, 187, 187, 187, 255, 0, 0, 0, 253, 70, 70,
+ 70, 255, 255, 255, 255, 236, 255, 255, 255, 0, 255, 255, 255, 86, 255,
+ 255, 255, 255, 153, 153, 153, 255, 34, 34, 34, 255, 0, 0, 0, 253,
+ 0, 0, 0, 253, 0, 0, 0, 253, 0, 0, 0, 253, 50, 50, 50,
+ 255, 187, 187, 187, 255, 255, 255, 255, 254, 255, 255, 255, 254, 153, 153,
+ 153, 255, 18, 18, 18, 255, 0, 0, 0, 253, 0, 0, 0, 253, 18,
+ 18, 18, 255, 70, 70, 70, 255, 0, 0, 0, 253, 137, 137, 137, 255,
+ 187, 187, 187, 251, 0, 0, 0, 253, 70, 70, 70, 252, 255, 255, 255,
+ 255, 153, 153, 153, 255, 18, 18, 18, 255, 0, 0, 0, 253, 0, 0,
+ 0, 253, 102, 102, 102, 255, 255, 255, 255, 255, 255, 255, 255, 255, 153,
+ 153, 153, 255, 18, 18, 18, 255, 0, 0, 0, 253, 0, 0, 0, 253,
+ 70, 70, 70, 255, 239, 239, 239, 255, 187, 187, 187, 255, 0, 0, 0,
+ 253, 137, 137, 137, 255, 255, 255, 255, 215, 187, 187, 187, 255, 0, 0,
+ 0, 253, 137, 137, 137, 255, 255, 255, 255, 215, 187, 187, 187, 255, 0,
+ 0, 0, 253, 137, 137, 137, 255, 255, 255, 255, 170, 255, 255, 255, 0,
+ 255, 255, 255, 36, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 251, 255, 255, 255, 0, 255, 255, 255, 36, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 251, 255, 255, 255, 0, 255, 255, 255, 36, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 215, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 236,
+ 255, 255, 255, 113, 255, 255, 255, 253, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 215, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 236, 255, 255, 255, 0, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 141, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 222, 255, 255, 255, 253, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 215, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 236, 255, 255, 255, 0, 255,
+ 255, 255, 0, 255, 255, 255, 141, 255, 255, 255, 253, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 250, 255, 255, 255, 86, 255, 255,
+ 255, 141, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 214, 255,
+ 255, 255, 141, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 246, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 215, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 215, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 170, };
+
+ *width = 136;
+ *height = 11;
+
+ // only load the requested logo
+ // allocate a new array
+ *data = new unsigned char[5984];
+ // and copy it. Now we are certain that the calling function
+ // can control the memory location
+ for(int i = 0; i < 5984 /* tmp array size */; i++)
+ {
+ (*data)[i] = logo_blender3d_raw[i];
+ }
+
+}
+
+
+
diff --git a/source/gameengine/GamePlayer/common/GPC_RawLogoArrays.h b/source/gameengine/GamePlayer/common/GPC_RawLogoArrays.h
new file mode 100644
index 00000000000..84598f7bfe8
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/GPC_RawLogoArrays.h
@@ -0,0 +1,44 @@
+/**
+ * $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 __GPC_RAWLOGOARRAYS_H
+#define __GPC_RAWLOGOARRAYS_H
+
+
+void GetRawBlenderLogo(unsigned char **data, int *width, int *height);
+void GetRawBlender3DLogo(unsigned char **data, int *width, int *height);
+#if 0
+void GetRawNaNLogo(unsigned char **data, int *width, int *height);
+#endif
+
+#endif // __GPC_RAWLOGOARRAYS_H
+
diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
new file mode 100644
index 00000000000..329cf1c4bad
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
@@ -0,0 +1,498 @@
+/**
+ * $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
+#pragma warning (disable : 4786)
+#include <windows.h>
+#endif
+
+#include <GL/gl.h>
+#include <iostream>
+
+#include "GPC_RenderTools.h"
+
+#include "RAS_IRenderTools.h"
+#include "RAS_IRasterizer.h"
+#include "RAS_LightObject.h"
+#include "RAS_ICanvas.h"
+
+// next two includes/dependencies come from the shadow feature
+// it needs the gameobject and the sumo physics scene for a raycast
+#include "KX_GameObject.h"
+
+#include "GPC_PolygonMaterial.h"
+#include "Value.h"
+
+//#include "KX_BlenderGL.h" // for text printing
+//#include "KX_BlenderClientObject.h"
+#include "STR_String.h"
+#include "RAS_BucketManager.h" // for polymaterial (needed for textprinting)
+
+
+// Blender includes
+/* This list includes only data type definitions */
+#include "DNA_object_types.h"
+#include "DNA_material_types.h"
+#include "DNA_image_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_group_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_camera_types.h"
+#include "DNA_property_types.h"
+#include "DNA_text_types.h"
+#include "DNA_sensor_types.h"
+#include "DNA_controller_types.h"
+#include "DNA_actuator_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_world_types.h"
+
+#include "BKE_global.h"
+#include "BKE_image.h"
+#include "BKE_bmfont.h"
+#include "BKE_bmfont_types.h"
+#include "BKE_main.h"
+
+#include "IMB_imbuf_types.h"
+// End of Blender includes
+
+
+GPC_RenderTools::GPC_RenderTools()
+{
+ m_font = BMF_GetFont(BMF_kHelvetica10);
+}
+
+
+GPC_RenderTools::~GPC_RenderTools()
+{
+}
+
+
+void GPC_RenderTools::EndFrame(RAS_IRasterizer* rasty)
+{
+}
+
+
+void GPC_RenderTools::BeginFrame(RAS_IRasterizer* rasty)
+{
+ m_clientobject=NULL;
+ m_modified=true;
+ DisableOpenGLLights();
+
+}
+
+int GPC_RenderTools::ProcessLighting(int layer)
+{
+ int result = false;
+
+ if (layer < 0)
+ {
+ DisableOpenGLLights();
+ result = false;
+ } else
+ {
+ if (m_clientobject)
+ {
+ if (applyLights(layer))
+ {
+ EnableOpenGLLights();
+ result = true;
+ } else
+ {
+ DisableOpenGLLights();
+ result = false;
+ }
+ }
+ }
+ return result;
+}
+
+
+void GPC_RenderTools::RenderText2D(RAS_TEXT_RENDER_MODE mode,
+ const char* text,
+ int xco,
+ int yco,
+ int width,
+ int height)
+{
+ STR_String tmpstr(text);
+ int lines;
+ char* s = tmpstr.Ptr();
+ char* p;
+
+ // Save and change OpenGL settings
+ int texture2D;
+ glGetIntegerv(GL_TEXTURE_2D, (GLint*)&texture2D);
+ glDisable(GL_TEXTURE_2D);
+ int fog;
+ glGetIntegerv(GL_FOG, (GLint*)&fog);
+ glDisable(GL_FOG);
+
+ // Set up viewing settings
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glOrtho(0, width, 0, height, -1, 1);
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+
+ // Actual drawing
+ unsigned char colors[2][3] = {
+ {0x00, 0x00, 0x00},
+ {0xFF, 0xFF, 0xFF}
+ };
+ int numTimes = mode == RAS_TEXT_PADDED ? 2 : 1;
+ for (int i = 0; i < numTimes; i++) {
+ glColor3ub(colors[i][0], colors[i][1], colors[i][2]);
+ glRasterPos2i(xco, yco);
+ for (p = s, lines = 0; *p; p++) {
+ if (*p == '\n')
+ {
+ lines++;
+ glRasterPos2i(xco, yco-(lines*18));
+ }
+ BMF_DrawCharacter(m_font, *p);
+ }
+ xco += 1;
+ yco += 1;
+ }
+
+ // Restore view settings
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+
+ // Restore OpenGL Settings
+ fog ? ::glEnable(GL_FOG) : ::glDisable(GL_FOG);
+ texture2D ? ::glEnable(GL_TEXTURE_2D) : ::glDisable(GL_TEXTURE_2D);
+}
+
+/**
+ * Copied from KX_BlenderRenderTools.cpp in KX_blenderhook
+ * Renders text into a (series of) polygon(s), using a texture font,
+ * Each character consists of one polygon (one quad or two triangles)
+ */
+void GPC_RenderTools::RenderText(
+ int mode,
+ RAS_IPolyMaterial* polymat,
+ float v1[3], float v2[3], float v3[3], float v4[3])
+{
+ STR_String mytext = ((CValue*)m_clientobject)->GetPropertyText("Text");
+
+ GPC_PolygonMaterial* blenderpoly = (GPC_PolygonMaterial*)polymat;
+ struct TFace* tface = blenderpoly->GetTFace();
+
+ BL_RenderText(mode, mytext, mytext.Length(), tface, v1, v2, v3, v4);
+}
+
+
+
+/**
+ * Copied from KX_BlenderGL.cpp in KX_blenderhook
+ */
+void GPC_RenderTools::BL_RenderText(
+ int mode,
+ const char* textstr,
+ int textlen,
+ struct TFace* tface,
+ float v1[3],float v2[3],float v3[3],float v4[3])
+{
+ struct Image* ima;
+
+ if (mode & TF_BMFONT) {
+ //char string[MAX_PROPSTRING];
+// float tmat[4][4];
+ int characters, index, character;
+ float centerx, centery, sizex, sizey, transx, transy, movex, movey, advance;
+
+// bProperty *prop;
+
+ // string = "Frank van Beek";
+
+ characters = textlen;
+
+ ima = (struct Image*) tface->tpage;
+ if (ima == NULL) {
+ characters = 0;
+ }
+
+ glPushMatrix();
+ for (index = 0; index < characters; index++) {
+ // lets calculate offset stuff
+ character = textstr[index];
+
+ // space starts at offset 1
+ // character = character - ' ' + 1;
+
+ matrixGlyph(ima->ibuf, character, & centerx, &centery, &sizex, &sizey, &transx, &transy, &movex, &movey, &advance);
+
+ glBegin(GL_POLYGON);
+ // printf(" %c %f %f %f %f\n", character, tface->uv[0][0], tface->uv[0][1], );
+ // glTexCoord2f((tface->uv[0][0] - centerx) * sizex + transx, (tface->uv[0][1] - centery) * sizey + transy);
+ glTexCoord2f((tface->uv[0][0] - centerx) * sizex + transx, (tface->uv[0][1] - centery) * sizey + transy);
+
+ BL_spack(tface->col[0]);
+ // glVertex3fv(v1);
+ glVertex3f(sizex * v1[0] + movex, sizey * v1[1] + movey, v1[2]);
+
+ glTexCoord2f((tface->uv[1][0] - centerx) * sizex + transx, (tface->uv[1][1] - centery) * sizey + transy);
+ BL_spack(tface->col[1]);
+ // glVertex3fv(v2);
+ glVertex3f(sizex * v2[0] + movex, sizey * v2[1] + movey, v2[2]);
+
+ glTexCoord2f((tface->uv[2][0] - centerx) * sizex + transx, (tface->uv[2][1] - centery) * sizey + transy);
+ BL_spack(tface->col[2]);
+ // glVertex3fv(v3);
+ glVertex3f(sizex * v3[0] + movex, sizey * v3[1] + movey, v3[2]);
+
+ if(v4) {
+ // glTexCoord2f((tface->uv[3][0] - centerx) * sizex + transx, 1.0 - (1.0 - tface->uv[3][1]) * sizey - transy);
+ glTexCoord2f((tface->uv[3][0] - centerx) * sizex + transx, (tface->uv[3][1] - centery) * sizey + transy);
+ BL_spack(tface->col[3]);
+ // glVertex3fv(v4);
+ glVertex3f(sizex * v4[0] + movex, sizey * v4[1] + movey, v4[2]);
+ }
+ glEnd();
+
+ glTranslatef(advance, 0.0, 0.0);
+ }
+ glPopMatrix();
+
+ }
+}
+
+
+RAS_IPolyMaterial* GPC_RenderTools::CreateBlenderPolyMaterial(
+ const STR_String &texname,
+ bool ba,const STR_String& matname,int tile,int tilexrep,int tileyrep,int mode,int transparant,int lightlayer
+ ,bool bIsTriangle,void* clientobject,void* tface)
+{
+ return new GPC_PolygonMaterial(texname, ba,matname,tile,tilexrep,tileyrep,
+ mode,transparant,lightlayer,bIsTriangle,clientobject,tface);
+}
+
+
+int GPC_RenderTools::applyLights(int objectlayer)
+{
+// taken from blender source, incompatibility between Blender Object / GameObject
+
+ int count;
+ float vec[4];
+
+ vec[3]= 1.0;
+
+ for(count=0; count<8; count++)
+ glDisable((GLenum)(GL_LIGHT0+count));
+
+ count= 0;
+
+ //std::vector<struct RAS_LightObject*> m_lights;
+ std::vector<struct RAS_LightObject*>::iterator lit = m_lights.begin();
+
+
+ for (lit = m_lights.begin(); !(lit==m_lights.end()); ++lit)
+ {
+ RAS_LightObject* lightdata = (*lit);
+ if (lightdata->m_layer & objectlayer)
+ {
+
+ glPushMatrix();
+ glLoadMatrixf(m_viewmat);
+
+
+ vec[0] = (*(lightdata->m_worldmatrix))(0,3);
+ vec[1] = (*(lightdata->m_worldmatrix))(1,3);
+ vec[2] = (*(lightdata->m_worldmatrix))(2,3);
+ vec[3] = 1;
+
+
+ if(lightdata->m_type==RAS_LightObject::LIGHT_SUN) {
+
+ vec[0] = (*(lightdata->m_worldmatrix))(0,2);
+ vec[1] = (*(lightdata->m_worldmatrix))(1,2);
+ vec[2] = (*(lightdata->m_worldmatrix))(2,2);
+ //vec[0]= base->object->obmat[2][0];
+ //vec[1]= base->object->obmat[2][1];
+ //vec[2]= base->object->obmat[2][2];
+ vec[3]= 0.0;
+ glLightfv((GLenum)(GL_LIGHT0+count), GL_POSITION, vec);
+ }
+ else {
+ //vec[3]= 1.0;
+ glLightfv((GLenum)(GL_LIGHT0+count), GL_POSITION, vec);
+ glLightf((GLenum)(GL_LIGHT0+count), GL_CONSTANT_ATTENUATION, 1.0);
+ glLightf((GLenum)(GL_LIGHT0+count), GL_LINEAR_ATTENUATION, lightdata->m_att1/lightdata->m_distance);
+ // without this next line it looks backward compatible.
+ //attennuation still is acceptable
+ // glLightf((GLenum)(GL_LIGHT0+count), GL_QUADRATIC_ATTENUATION, la->att2/(la->dist*la->dist));
+
+ if(lightdata->m_type==RAS_LightObject::LIGHT_SPOT) {
+ vec[0] = -(*(lightdata->m_worldmatrix))(0,2);
+ vec[1] = -(*(lightdata->m_worldmatrix))(1,2);
+ vec[2] = -(*(lightdata->m_worldmatrix))(2,2);
+ //vec[0]= -base->object->obmat[2][0];
+ //vec[1]= -base->object->obmat[2][1];
+ //vec[2]= -base->object->obmat[2][2];
+ glLightfv((GLenum)(GL_LIGHT0+count), GL_SPOT_DIRECTION, vec);
+ glLightf((GLenum)(GL_LIGHT0+count), GL_SPOT_CUTOFF, lightdata->m_spotsize/2.0);
+ glLightf((GLenum)(GL_LIGHT0+count), GL_SPOT_EXPONENT, 128.0*lightdata->m_spotblend);
+ }
+ else glLightf((GLenum)(GL_LIGHT0+count), GL_SPOT_CUTOFF, 180.0);
+ }
+
+ vec[0]= lightdata->m_energy*lightdata->m_red;
+ vec[1]= lightdata->m_energy*lightdata->m_green;
+ vec[2]= lightdata->m_energy*lightdata->m_blue;
+ vec[3]= 1.0;
+ glLightfv((GLenum)(GL_LIGHT0+count), GL_DIFFUSE, vec);
+ glLightfv((GLenum)(GL_LIGHT0+count), GL_SPECULAR, vec);
+ glEnable((GLenum)(GL_LIGHT0+count));
+
+ glPopMatrix();
+
+ count++;
+ if(count>7)
+ break;
+ }
+ }
+
+ return count;
+
+}
+
+
+void GPC_RenderTools::applyTransform(RAS_IRasterizer* rasty,double* oglmatrix,int objectdrawmode )
+{
+ if (objectdrawmode & RAS_IPolyMaterial::BILLBOARD_SCREENALIGNED ||
+ objectdrawmode & RAS_IPolyMaterial::BILLBOARD_AXISALIGNED)
+ {
+ // rotate the billboard/halo
+ //page 360/361 3D Game Engine Design, David Eberly for a discussion
+ // on screen aligned and axis aligned billboards
+ // assumed is that the preprocessor transformed all billboard polygons
+ // so that their normal points into the positive x direction (1.0 , 0.0 , 0.0)
+ // when new parenting for objects is done, this rotation
+ // will be moved into the object
+
+ MT_Point3 objpos (oglmatrix[12],oglmatrix[13],oglmatrix[14]);
+ MT_Point3 campos = rasty->GetCameraPosition();
+ MT_Vector3 dir = (campos - objpos).safe_normalized();
+ MT_Vector3 up(0,0,1.0);
+
+ KX_GameObject* gameobj = (KX_GameObject*) this->m_clientobject;
+ // get scaling of halo object
+ MT_Vector3 size = gameobj->GetSGNode()->GetLocalScale();
+
+ bool screenaligned = (objectdrawmode & RAS_IPolyMaterial::BILLBOARD_SCREENALIGNED)!=0;//false; //either screen or axisaligned
+ if (screenaligned)
+ {
+ up = (up - up.dot(dir) * dir).safe_normalized();
+ } else
+ {
+ dir = (dir - up.dot(dir)*up).safe_normalized();
+ }
+
+ MT_Vector3 left = dir.normalized();
+ dir = (left.cross(up)).normalized();
+
+ // we have calculated the row vectors, now we keep
+ // local scaling into account:
+
+ left *= size[0];
+ dir *= size[1];
+ up *= size[2];
+ double maat[16]={
+ left[0], left[1],left[2], 0,
+ dir[0], dir[1],dir[2],0,
+ up[0],up[1],up[2],0,
+ 0,0,0,1};
+ glTranslated(objpos[0],objpos[1],objpos[2]);
+ glMultMatrixd(maat);
+
+ } else
+ {
+ if (objectdrawmode & RAS_IPolyMaterial::SHADOW)
+ {
+ // shadow must be cast to the ground, physics system needed here!
+ KX_GameObject* gameobj = (KX_GameObject*) this->m_clientobject;
+ MT_Point3 frompoint(oglmatrix[12],oglmatrix[13],oglmatrix[14]);
+ MT_Vector3 direction = MT_Vector3(0,0,-1);
+
+
+ direction.normalize();
+ direction *= 100000;
+
+ MT_Point3 topoint = frompoint + direction;
+ MT_Point3 resultpoint;
+ MT_Vector3 resultnormal;
+
+ //todo: replace by physicsenvironment raycast
+
+ //SM_Scene* scene = (SM_Scene*) m_auxilaryClientInfo;
+
+ SM_Object* hitObj = 0;
+ //scene->rayTest(gameobj->GetSumoObject(),frompoint,topoint,
+ // resultpoint, resultnormal);
+
+
+ if (hitObj)
+ {
+ MT_Vector3 left(oglmatrix[0],oglmatrix[1],oglmatrix[2]);
+ MT_Vector3 dir = -(left.cross(resultnormal)).normalized();
+ left = (dir.cross(resultnormal)).normalized();
+ // for the up vector, we take the 'resultnormal' returned by the physics
+
+ double maat[16]={
+ left[0], left[1],left[2], 0,
+ dir[0], dir[1],dir[2],0,
+ resultnormal[0],resultnormal[1],resultnormal[2],0,
+ 0,0,0,1};
+ glTranslated(resultpoint[0],resultpoint[1],resultpoint[2]);
+ glMultMatrixd(maat);
+ // glMultMatrixd(oglmatrix);
+ } else
+ {
+ glMultMatrixd(oglmatrix);
+ }
+
+
+ } else
+ {
+
+ // 'normal' object
+ glMultMatrixd(oglmatrix);
+ }
+ }
+}
diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.h b/source/gameengine/GamePlayer/common/GPC_RenderTools.h
new file mode 100644
index 00000000000..7021e7a4a43
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.h
@@ -0,0 +1,176 @@
+/**
+ * $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 __GPC_RENDERTOOLS_H
+#define __GPC_RENDERTOOLS_H
+
+#if defined(WIN32) || defined(__APPLE__)
+ #ifdef WIN32
+ #include <windows.h>
+ #include <GL/gl.h>
+ #else // WIN32
+ // __APPLE__ is defined
+ #include <AGL/gl.h>
+ #endif // WIN32
+#else //defined(WIN32) || defined(__APPLE__)
+ #include <GL/gl.h>
+#endif //defined(WIN32) || defined(__APPLE__)
+
+
+#include "RAS_IRenderTools.h"
+
+#include "BMF_Api.h"
+
+
+class GPC_RenderTools : public RAS_IRenderTools
+{
+public:
+ GPC_RenderTools();
+ virtual ~GPC_RenderTools();
+
+ virtual void EndFrame(RAS_IRasterizer* rasty);
+ virtual void BeginFrame(RAS_IRasterizer* rasty);
+
+ void DisableOpenGLLights()
+ {
+ glDisable(GL_LIGHTING);
+ glDisable(GL_COLOR_MATERIAL);
+ glDisableClientState(GL_NORMAL_ARRAY);
+ }
+
+ void EnableOpenGLLights()
+ {
+ glEnable(GL_LIGHTING);
+ glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);
+ glEnable(GL_COLOR_MATERIAL);
+ glEnableClientState(GL_NORMAL_ARRAY);
+ }
+
+ int ProcessLighting(int layer);
+
+ void Perspective(int a, int width, int height, float mat[4][4], float viewmat[4][4])
+ {
+ if(a== 0)
+ {
+ glMatrixMode(GL_PROJECTION);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ }
+ else
+ {
+ if(a== 1)
+ {
+ glMatrixMode(GL_PROJECTION);
+ glMatrixMode(GL_MODELVIEW);
+ }
+ }
+ }
+
+ /**
+ * @attention mode is ignored here
+ */
+ virtual void RenderText2D(
+ RAS_TEXT_RENDER_MODE mode,
+ const char* text,
+ int xco,
+ int yco,
+ int width,
+ int height);
+
+ /**
+ * Renders text into a (series of) polygon(s), using a texture font,
+ * Each character consists of one polygon (one quad or two triangles)
+ */
+ virtual void RenderText(
+ int mode,
+ RAS_IPolyMaterial* polymat,
+ float v1[3],
+ float v2[3],
+ float v3[3],
+ float v4[3]);
+
+ void Render(RAS_IRasterizer* rasty,double* oglmatrix,int objectdrawmode)
+ {
+ glPopMatrix();
+ glPushMatrix();
+ glMultMatrixd(oglmatrix);
+ }
+
+ void applyTransform(RAS_IRasterizer* rasty, double* oglmatrix, int objectdrawmode);
+
+ virtual void PushMatrix()
+ {
+ glPushMatrix();
+ }
+
+ virtual void PopMatrix()
+ {
+ glPopMatrix();
+ }
+
+ virtual class RAS_IPolyMaterial* CreateBlenderPolyMaterial(
+ const STR_String &texname,
+ bool ba,
+ const STR_String& matname,
+ int tile,
+ int tilexrep,int tileyrep,
+ int mode,
+ int transparant,
+ int lightlayer,
+ bool bIsTriangle,
+ void* clientobject,
+ void* tface);
+
+ int applyLights(int objectlayer);
+
+protected:
+ /**
+ * Copied from KX_BlenderGL.cpp in KX_blenderhook
+ */
+ void BL_RenderText(
+ int mode,
+ const char* textstr,
+ int textlen,
+ struct TFace* tface,
+ float v1[3],float v2[3],float v3[3],float v4[3]);
+ void BL_spack(unsigned int ucol)
+ {
+ char *cp = (char *)&ucol;
+ glColor3ub(cp[3], cp[2], cp[1]);
+ }
+
+
+ BMF_Font* m_font;
+};
+
+
+#endif // __GPC_RENDERTOOLS_H
diff --git a/source/gameengine/GamePlayer/common/GPC_System.cpp b/source/gameengine/GamePlayer/common/GPC_System.cpp
new file mode 100644
index 00000000000..7c5c16a0b48
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/GPC_System.cpp
@@ -0,0 +1,90 @@
+/**
+ * $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 "GPC_System.h"
+
+#include "GPC_KeyboardDevice.h"
+#include "NG_NetworkDeviceInterface.h"
+
+
+GPC_System::GPC_System()
+// : m_ndi(0)
+{
+}
+
+/*
+void GPC_System::NextFrame()
+{
+ // Have the imput devices proceed
+ std::vector<SCA_IInputDevice*>::iterator idev;
+ for (idev = m_inputDevices.begin(); !(idev == m_inputDevices.end()); idev++) {
+ (*idev)->NextFrame();
+ }
+
+ // Have the network device proceed
+ if (m_ndi) {
+ m_ndi->NextFrame();
+ }
+}
+
+void GPC_System::StartMainLoop()
+{
+}
+
+
+void GPC_System::Sleep(int millisec)
+{
+ // do nothing for now ;)
+}
+
+
+void GPC_System::AddKey(unsigned char key, bool down)
+{
+ GPC_KeyboardDevice* keydev = (GPC_KeyboardDevice*) this->GetKeyboardDevice();
+ if (keydev) {
+ //SCA_IInputDevice::KX_EnumInputs inp = keydev->ToNative(key);
+ keydev->ConvertEvent(key, down);
+ }
+}
+
+
+void GPC_System::SetNetworkDevice(NG_NetworkDeviceInterface* ndi)
+{
+ m_ndi = ndi;
+}
+
+
+NG_NetworkDeviceInterface* GPC_System::GetNetworkDevice() const
+{
+ return m_ndi;
+}
+*/ \ No newline at end of file
diff --git a/source/gameengine/GamePlayer/common/GPC_System.h b/source/gameengine/GamePlayer/common/GPC_System.h
new file mode 100644
index 00000000000..00720f13072
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/GPC_System.h
@@ -0,0 +1,64 @@
+/**
+ * $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 __GPC_SYSTEM_H
+#define __GPC_SYSTEM_H
+
+#if defined(WIN32)
+#pragma warning (disable:4786) // suppress stl-MSVC debug info warning
+#endif /* WIN32 */
+
+#include "KX_ISystem.h"
+
+//class NG_NetworkDeviceInterface;
+
+class GPC_System : public KX_ISystem
+{
+public:
+ GPC_System();
+
+// virtual void NextFrame();
+// virtual void StartMainLoop();
+ virtual double GetTimeInSeconds() = 0;
+// virtual void Sleep(int millisec);
+ //virtual bool IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode);
+// void AddKey(unsigned char key, bool down);
+
+// virtual void SetNetworkDevice(NG_NetworkDeviceInterface* ndi);
+// virtual NG_NetworkDeviceInterface* GetNetworkDevice() const;
+
+//protected:
+// NG_NetworkDeviceInterface* m_ndi;
+};
+
+
+#endif // __GPC_SYSTEM_H
diff --git a/source/gameengine/GamePlayer/common/Makefile b/source/gameengine/GamePlayer/common/Makefile
new file mode 100644
index 00000000000..f55b1198c63
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/Makefile
@@ -0,0 +1,83 @@
+#
+# $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 = common
+DIR = $(OCGDIR)/gameengine/GamePlayer/$(LIBNAME)
+
+include nan_compile.mk
+
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+CPPFLAGS += -I$(OPENGL_HEADERS)
+
+CPPFLAGS += -I../../../blender/blenkernel
+CPPFLAGS += -I../../../blender/blenloader
+CPPFLAGS += -I../../../blender/blenlib
+CPPFLAGS += -I../../../blender/imbuf
+CPPFLAGS += -I../../../blender/makesdna
+CPPFLAGS += -I../../../kernel/gen_system
+CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
+
+CPPFLAGS += -I$(NAN_FUZZICS)/include
+CPPFLAGS += -I$(NAN_STRING)/include
+CPPFLAGS += -I$(NAN_MOTO)/include
+CPPFLAGS += -I$(NAN_SUMO)/include
+CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
+CPPFLAGS += -I$(NAN_BMFONT)/include
+CPPFLAGS += -I../../../gameengine/Converter
+CPPFLAGS += -I../../../gameengine/Expressions
+CPPFLAGS += -I../../../gameengine/GameLogic
+CPPFLAGS += -I../../../gameengine/Converter
+CPPFLAGS += -I../../../gameengine/Ketsji
+CPPFLAGS += -I../../../gameengine/Ketsji/KXNetwork
+CPPFLAGS += -I../../../gameengine/Network
+CPPFLAGS += -I../../../gameengine/Network/LoopBackNetwork
+CPPFLAGS += -I../../../gameengine/Rasterizer
+CPPFLAGS += -I../../../gameengine/SceneGraph
+CPPFLAGS += -I../../../gameengine/SoundSystem
+CPPFLAGS += -I../../../gameengine/Rasterizer/RAS_OpenGLRasterizer
+
+###############################
+
+SOURCEDIR = source/gameengine/GamePlayer/common
+DIRS =
+ifeq ($(OS),windows)
+# Still
+ DIRS = windows
+else
+ ifneq ($(OS),darwin)
+ DIRS = unix
+ endif
+endif
+
+include nan_subdirs.mk
diff --git a/source/gameengine/GamePlayer/common/bmfont.cpp b/source/gameengine/GamePlayer/common/bmfont.cpp
new file mode 100644
index 00000000000..752f2017c94
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/bmfont.cpp
@@ -0,0 +1,301 @@
+/**
+ * bmfont.c
+ *
+ * 04-10-2000 frank
+ *
+ * $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 *****
+ *
+ */
+
+/**
+ * Two external functions:
+ *
+ * void detectBitmapFont(ImBuf *ibuf)
+ * detects if an image buffer contains a bitmap font. It makes the
+ * specific bitmap data which is stored in the bitmap invisible to blender.
+ *
+ * void matrixGlyph(ImBuf * ibuf, unsigned short unicode, *float x 7)
+ * returns all the information about the character (unicode) in the floats
+ *
+ * Room for improvement:
+ * add kerning data in the bitmap
+ * all calculations in matrixGlyph() are static and could be done during
+ * initialization
+ */
+
+#include <stdio.h>
+
+#include "MEM_guardedalloc.h"
+#include "BLI_blenlib.h"
+#include "BKE_global.h"
+#include "IMB_imbuf_types.h"
+
+#include "BKE_bmfont.h"
+#include "BKE_bmfont_types.h"
+
+/*MAART:
+void printfGlyph(bmGlyph * glyph)
+{
+ printf("unicode: %d '%c'\n", glyph->unicode, glyph->unicode);
+ printf(" locx: %4d locy: %4d\n", glyph->locx, glyph->locy);
+ printf(" sizex: %3d sizey: %3d\n", glyph->sizex, glyph->sizey);
+ printf(" ofsx: %3d ofsy: %3d\n", glyph->ofsx, glyph->ofsy);
+ printf(" advan: %3d reser: %3d\n", glyph->advance, glyph->reserved);
+}
+*/
+
+#define MAX2(x,y) ( (x)>(y) ? (x) : (y) )
+#define MAX3(x,y,z) MAX2( MAX2((x),(y)) , (z) )
+
+void calcAlpha(ImBuf * ibuf)
+{
+ int i;
+ char * rect;
+
+ if (ibuf) {
+ rect = (char *) ibuf->rect;
+ for (i = ibuf->x * ibuf->y ; i > 0 ; i--) {
+ rect[3] = MAX3(rect[0], rect[1], rect[2]);
+ rect += 4;
+ }
+ }
+}
+
+void readBitmapFontVersion0(ImBuf * ibuf, unsigned char * rect, int step)
+{
+ int glyphcount, bytes, i, index, linelength, ysize;
+ unsigned char * buffer;
+ bmFont * bmfont;
+
+ linelength = ibuf->x * step;
+
+ glyphcount = (rect[6 * step] << 8) | rect[7 * step];
+ bytes = ((glyphcount - 1) * sizeof(bmGlyph)) + sizeof(bmFont);
+
+ ysize = (bytes + (ibuf->x - 1)) / ibuf->x;
+
+ if (ysize < ibuf->y) {
+ // we're first going to copy all data into a liniar buffer.
+ // step can be 4 or 1 bytes, and the data is not sequential because
+ // the bitmap was flipped vertically.
+
+ buffer = (unsigned char*)MEM_mallocN(bytes, "readBitmapFontVersion0:buffer");
+
+ index = 0;
+ for (i = 0; i < bytes; i++) {
+ buffer[i] = rect[index];
+ index += step;
+ if (index >= linelength) {
+ // we've read one line, no skip to the line *before* that
+ rect -= linelength;
+ index -= linelength;
+ }
+ }
+
+ // we're now going to endian convert the data
+
+ bmfont = (bmFont*)MEM_mallocN(bytes, "readBitmapFontVersion0:bmfont");
+ index = 0;
+
+ // first read the header
+ bmfont->magic[0] = buffer[index++];
+ bmfont->magic[1] = buffer[index++];
+ bmfont->magic[2] = buffer[index++];
+ bmfont->magic[3] = buffer[index++];
+ bmfont->version = (buffer[index] << 8) | buffer[index + 1]; index += 2;
+ bmfont->glyphcount = (buffer[index] << 8) | buffer[index + 1]; index += 2;
+ bmfont->xsize = (buffer[index] << 8) | buffer[index + 1]; index += 2;
+ bmfont->ysize = (buffer[index] << 8) | buffer[index + 1]; index += 2;
+
+ for (i = 0; i < bmfont->glyphcount; i++) {
+ bmfont->glyphs[i].unicode = (buffer[index] << 8) | buffer[index + 1]; index += 2;
+ bmfont->glyphs[i].locx = (buffer[index] << 8) | buffer[index + 1]; index += 2;
+ bmfont->glyphs[i].locy = (buffer[index] << 8) | buffer[index + 1]; index += 2;
+ bmfont->glyphs[i].ofsx = buffer[index++];
+ bmfont->glyphs[i].ofsy = buffer[index++];
+ bmfont->glyphs[i].sizex = buffer[index++];
+ bmfont->glyphs[i].sizey = buffer[index++];
+ bmfont->glyphs[i].advance = buffer[index++];
+ bmfont->glyphs[i].reserved = buffer[index++];
+ /* MAART:
+ if (G.f & G_DEBUG) {
+ printfGlyph(&bmfont->glyphs[i]);
+ }
+ */
+ }
+
+ MEM_freeN(buffer);
+
+ /* MAART:
+ if (G.f & G_DEBUG) {
+ printf("Oldy = %d Newy = %d\n", ibuf->y, ibuf->y - ysize);
+ printf("glyphcount = %d\n", glyphcount);
+ printf("bytes = %d\n", bytes);
+ }
+ */
+
+ // we've read the data from the image. Now we're going
+ // to crop the image vertically so only the bitmap data
+ // remains visible
+
+ ibuf->y -= ysize;
+ ibuf->userdata = bmfont;
+ ibuf->userflags |= IB_BITMAPFONT;
+
+ if (ibuf->depth < 32) {
+ // we're going to fake alpha here:
+ calcAlpha(ibuf);
+ }
+ } else {
+ /* MAART:
+ printf("readBitmapFontVersion0: corrupted bitmapfont\n");
+ */
+ }
+}
+
+void detectBitmapFont(ImBuf *ibuf)
+{
+ unsigned char * rect;
+ unsigned short version;
+ long i;
+
+ if (ibuf != NULL) {
+ // bitmap must have an x size that is a power of two
+ if (is_power_of_two(ibuf->x)) {
+ rect = (unsigned char *) (ibuf->rect + (ibuf->x * (ibuf->y - 1)));
+ // printf ("starts with: %s %c %c %c %c\n", rect, rect[0], rect[1], rect[2], rect[3]);
+ if (rect[0] == 'B' && rect[1] == 'F' && rect[2] == 'N' && rect[3] == 'T') {
+ // printf("found 8bit font !\n");
+ // round y size down
+ // do the 8 bit font stuff. (not yet)
+ } else {
+ // we try all 4 possible combinations
+ for (i = 0; i < 4; i++) {
+ if (rect[0] == 'B' && rect[4] == 'F' && rect[8] == 'N' && rect[12] == 'T') {
+ // printf("found 24bit font !\n");
+ // We're going to parse the file:
+
+ version = (rect[16] << 8) | rect[20];
+
+ if (version == 0) {
+ readBitmapFontVersion0(ibuf, rect, 4);
+ } else {
+ //printf("detectBitmapFont :Unsupported version %d\n", version);
+ }
+
+ // on succes ibuf->userdata points to the bitmapfont
+ if (ibuf->userdata) {
+ break;
+ }
+ }
+ rect++;
+ }
+ }
+ }
+ }
+}
+
+int locateGlyph(bmFont *bmfont, unsigned short unicode)
+{
+ int min, max, current = 0;
+
+ if (bmfont) {
+ min = 0;
+ max = bmfont->glyphcount;
+ while (1) {
+ // look halfway for glyph
+ current = (min + max) >> 1;
+
+ if (bmfont->glyphs[current].unicode == unicode) {
+ break;
+ } else if (bmfont->glyphs[current].unicode < unicode) {
+ // have to move up
+ min = current;
+ } else {
+ // have to move down
+ max = current;
+ }
+
+ if (max - min <= 1) {
+ // unable to locate glyph
+ current = 0;
+ break;
+ }
+ }
+ }
+
+ return(current);
+}
+
+void matrixGlyph(ImBuf * ibuf, unsigned short unicode,
+ float *centerx, float *centery,
+ float *sizex, float *sizey,
+ float *transx, float *transy,
+ float *movex, float *movey,
+ float *advance)
+{
+ int index;
+ bmFont *bmfont;
+
+ *centerx = *centery = 0.0;
+ *sizex = *sizey = 1.0;
+ *transx = *transy = 0.0;
+ *movex = *movey = 0.0;
+ *advance = 1.0;
+
+ if (ibuf) {
+ bmfont = (bmFont*)ibuf->userdata;
+ if (bmfont && (ibuf->userflags & IB_BITMAPFONT)) {
+ index = locateGlyph(bmfont, unicode);
+ if (index) {
+
+ *sizex = (bmfont->glyphs[index].sizex) / (float) (bmfont->glyphs[0].sizex);
+ *sizey = (bmfont->glyphs[index].sizey) / (float) (bmfont->glyphs[0].sizey);
+
+ *transx = bmfont->glyphs[index].locx / (float) ibuf->x;
+ *transy = (ibuf->y - bmfont->glyphs[index].locy) / (float) ibuf->y;
+
+ *centerx = bmfont->glyphs[0].locx / (float) ibuf->x;
+ *centery = (ibuf->y - bmfont->glyphs[0].locy) / (float) ibuf->y;
+
+ // 2.0 units is the default size of an object
+
+ *movey = (float)(1.0 - *sizey + 2.0 * (bmfont->glyphs[index].ofsy - bmfont->glyphs[0].ofsy) / (float) bmfont->glyphs[0].sizey);
+ *movex = (float)(*sizex - 1.0 + 2.0 * (bmfont->glyphs[index].ofsx - bmfont->glyphs[0].ofsx) / (float) bmfont->glyphs[0].sizex);
+
+ *advance = (float)(2.0 * bmfont->glyphs[index].advance / (float) bmfont->glyphs[0].advance);
+
+ // printfGlyph(&bmfont->glyphs[index]);
+ // printf("%c %d %0.5f %0.5f %0.5f %0.5f %0.5f \n", unicode, index, *sizex, *sizey, *transx, *transy, *advance);
+ }
+ }
+ }
+}
diff --git a/source/gameengine/GamePlayer/common/load.blend b/source/gameengine/GamePlayer/common/load.blend
new file mode 100644
index 00000000000..1490fba6108
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/load.blend
Binary files differ
diff --git a/source/gameengine/GamePlayer/common/logo_blender.raw b/source/gameengine/GamePlayer/common/logo_blender.raw
new file mode 100644
index 00000000000..82bf25a2c6e
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/logo_blender.raw
Binary files differ
diff --git a/source/gameengine/GamePlayer/common/logo_blender3d.raw b/source/gameengine/GamePlayer/common/logo_blender3d.raw
new file mode 100644
index 00000000000..6a86626bb10
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/logo_blender3d.raw
Binary files differ
diff --git a/source/gameengine/GamePlayer/common/logo_nan.raw b/source/gameengine/GamePlayer/common/logo_nan.raw
new file mode 100644
index 00000000000..b86308bd017
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/logo_nan.raw
Binary files differ
diff --git a/source/gameengine/GamePlayer/common/unix/GPU_Canvas.cpp b/source/gameengine/GamePlayer/common/unix/GPU_Canvas.cpp
new file mode 100644
index 00000000000..29f0bffe1c5
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/unix/GPU_Canvas.cpp
@@ -0,0 +1,72 @@
+/**
+ * $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 "GPU_Canvas.h"
+
+GPU_Canvas::GPU_Canvas(KXH_plugin_handle p, int width, int height)
+ : GPC_Canvas(width, height), m_plugin(p)
+{
+ /* intentionally empty */
+}
+
+
+GPU_Canvas::~GPU_Canvas(void)
+{
+ /* intentionally empty */
+}
+
+void GPU_Canvas::Init(void)
+{
+ /* intentionally empty */
+}
+
+void GPU_Canvas::SwapBuffers(void)
+{
+ if (m_plugin) KXH_swap_buffers(m_plugin);
+}
+
+bool
+GPU_Canvas::BeginDraw(void)
+{
+ if (m_plugin) {
+ return KXH_begin_draw(m_plugin);
+ } else {
+ return false;
+ }
+}
+
+void GPU_Canvas::EndDraw(void)
+{
+ if (m_plugin) KXH_end_draw(m_plugin);
+}
diff --git a/source/gameengine/GamePlayer/common/unix/GPU_Canvas.h b/source/gameengine/GamePlayer/common/unix/GPU_Canvas.h
new file mode 100644
index 00000000000..5b3309a83bf
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/unix/GPU_Canvas.h
@@ -0,0 +1,60 @@
+/**
+ * $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 __GPU_CANVAS_H
+#define __GPU_CANVAS_H
+
+#include <iostream>
+
+#include "KXH_ketsji_hooks.h"
+#include "GPC_Canvas.h"
+
+class GPU_Canvas : public GPC_Canvas
+{
+private:
+
+ /** Handle to the drawing resource. */
+ KXH_plugin_handle m_plugin;
+
+public:
+ GPU_Canvas(KXH_plugin_handle display, int width, int height);
+ virtual ~GPU_Canvas();
+
+ virtual void Init(void);
+
+ bool BeginDraw(void);
+ void EndDraw(void);
+ virtual void SwapBuffers(void);
+
+};
+
+#endif // __GPU_CANVAS_H
diff --git a/source/gameengine/GamePlayer/common/unix/GPU_Engine.cpp b/source/gameengine/GamePlayer/common/unix/GPU_Engine.cpp
new file mode 100644
index 00000000000..56b1340eb92
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/unix/GPU_Engine.cpp
@@ -0,0 +1,307 @@
+/**
+ * $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 <assert.h>
+#include <unistd.h>
+
+#include "GPU_Engine.h"
+
+#include "GPC_MouseDevice.h"
+
+#include "GPU_Canvas.h"
+#include "GPU_KeyboardDevice.h"
+#include "GPU_System.h"
+
+#include "BLI_blenlib.h"
+#include "BLO_readfile.h"
+
+#include "SND_DeviceManager.h"
+
+#include "NG_NetworkScene.h"
+#include "NG_LoopBackNetworkDeviceInterface.h"
+#include "SND_DeviceManager.h"
+#include "KX_BlenderSceneConverter.h"
+#include "SM_Scene.h"
+#include "KX_KetsjiEngine.h"
+
+#include "GPC_RenderTools.h"
+#include "GPC_RawImage.h"
+
+
+void Redraw(GPU_Engine *engine); // -the- redraw function
+
+// callback functions
+/*
+void RedrawCallback(Widget, XtPointer closure, XEvent *, Boolean *continue_to_dispatch);
+
+void KeyDownCallback(Widget w, XtPointer closure, XEvent *event, Boolean *continue_to_dispatch);
+void KeyUpCallback(Widget w, XtPointer closure, XEvent *event, Boolean *continue_to_dispatch);
+
+void ButtonPressReleaseCallback(Widget w, XtPointer closure, XEvent *event, Boolean *continue_to_dispatch);
+void PointerMotionCallback(Widget w, XtPointer closure, XEvent *event, Boolean *continue_to_dispatch);
+
+void TimeOutCallback(XtPointer closure, XtIntervalId *id);
+*/
+
+GPU_Engine::GPU_Engine(char *customLoadingAnimationURL,
+ int foregroundColor, int backgroundColor, int frameRate) :
+ GPC_Engine(customLoadingAnimationURL, foregroundColor, backgroundColor,
+ frameRate), m_timerTimeOutMsecs(10)
+{
+}
+
+
+GPU_Engine::~GPU_Engine()
+{
+}
+
+/*
+bool GPU_Engine::Initialize(Display *display, Window window, int width, int height)
+{
+ SND_DeviceManager::Subscribe();
+ m_audiodevice = SND_DeviceManager::Instance();
+
+ m_keyboarddev = new GPU_KeyboardDevice();
+ m_mousedev = new GPC_MouseDevice();
+
+ // constructor only initializes data
+ // m_canvas = new GPU_Canvas(display, window, width, height);
+ //m_canvas->Init(); // create the actual visual and rendering context
+ //cout << "GPU_Canvas created and initialized, m_canvas " << m_canvas << endl;
+ //AddEventHandlers(); // done here (in GPU_Engine) since the event handlers need access to 'this', ie the engine
+
+ // put the Blender logo in the topleft corner
+ if(m_BlenderLogo != 0)
+ // adding a banner automatically enables them
+ m_BlenderLogoId = m_canvas->AddBanner(m_BlenderLogo->Width(), m_BlenderLogo->Height(),
+ m_BlenderLogo->Width(), m_BlenderLogo->Height(),
+ m_BlenderLogo->Data(), GPC_Canvas::alignTopLeft);
+
+ // put the Blender3D logo in the bottom right corner
+ if(m_Blender3DLogo != 0)
+ // adding a banner automatically enables them
+ m_Blender3DLogoId = m_canvas->AddBanner(m_Blender3DLogo->Width(), m_Blender3DLogo->Height(),
+ m_Blender3DLogo->Width(), m_Blender3DLogo->Height(),
+ m_Blender3DLogo->Data(), GPC_Canvas::alignTopLeft);
+
+#if 0
+ // put the NaN logo in the bottom right corner
+ if(m_NaNLogo != 0)
+ // adding a banner automatically enables them
+ m_NaNLogoId = m_canvas->AddBanner(m_NaNLogo->Width(), m_NaNLogo->Height(),
+ m_NaNLogo->Width(), m_NaNLogo->Height(),
+ m_NaNLogo->Data(), GPC_Canvas::alignBottomRight);
+#endif
+ // enable the display of all banners
+ m_canvas->SetBannerDisplayEnabled(true);
+
+ m_rendertools = new GPC_RenderTools();
+
+ m_networkdev = new NG_LoopBackNetworkDeviceInterface();
+ assert(m_networkdev);
+
+ // creation of system needs 'current rendering context', this is taken care
+ // of by the GPU_Canvas::Init()
+ m_system = new GPU_System();
+
+ m_system->SetKeyboardDevice((GPU_KeyboardDevice *)m_keyboarddev);
+ m_system->SetMouseDevice(m_mousedev);
+ m_system->SetNetworkDevice(m_networkdev);
+
+ m_initialized = true;
+
+ return m_initialized;
+}
+*/
+
+/*
+void GPU_Engine::HandleNewWindow(Window window)
+{
+ // everything only if it's really a new window
+ if(window != ((GPU_Canvas *)m_canvas)->GetWindow())
+ {
+ cout << "GPU_Engine::HandleNewWindow(), new window so calling SetNewWindowMakeNewWidgetAndMakeCurrent()" << endl;
+ // We don't have to remove the event handlers ourselves, they are destroyed by X11
+
+ // make canvas aware of new window, and make it current
+ ((GPU_Canvas *)m_canvas)->SetNewWindowMakeNewWidgetAndMakeCurrent(window);
+
+ // and add event handlers to new widget
+ AddEventHandlers();
+ cout << "GPU_Engine::HandleNewWindow(), event handlers added" << endl;
+ }
+}
+*/
+/*
+void GPU_Engine::AddEventHandlers(void)
+{
+ Widget widget = ((GPU_Canvas *)m_canvas)->GetWidget();
+
+ // redraw
+ // MUST be the *Raw* event handler, the normal one doesn't work!
+ XtAddRawEventHandler(widget, ExposureMask, FALSE, RedrawCallback, this);
+#if 0
+ // key down
+ XtAddRawEventHandler(widget, KeyPressMask, FALSE, KeyDownCallback, this);
+ // key up
+ XtAddRawEventHandler(widget, KeyReleaseMask, FALSE, KeyUpCallback, this);
+
+ // mouse button press
+ XtAddRawEventHandler(widget, ButtonPressMask, FALSE, ButtonPressReleaseCallback, this);
+ // mouse button release
+ XtAddRawEventHandler(widget, ButtonReleaseMask, FALSE, ButtonPressReleaseCallback, this);
+ // mouse motion
+ XtAddRawEventHandler(widget, PointerMotionMask, FALSE, PointerMotionCallback, this);
+#endif
+#if 0
+ // time out, not a real timer. New time out will be set in callback
+ m_timerId = XtAppAddTimeOut(XtWidgetToApplicationContext(widget),
+ m_timerTimeOutMsecs, TimeOutCallback, this);
+#endif
+}
+*/
+
+void Redraw(GPU_Engine *engine)
+{
+/* if(engine->Running())
+ {
+ if(engine->Loading())
+ {
+ engine->UpdateLoadingAnimation();
+ }
+
+ engine->m_system->DoMainLoopCallback();
+ }*/
+}
+
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++
+ * Callback functions
+ +++++++++++++++++++++++++++++++++++++++++++++++++*/
+void RedrawCallback(Widget, XtPointer closure, XEvent *, Boolean *continue_to_dispatch)
+{
+ GPU_Engine *engine = (GPU_Engine *)closure;
+
+ Redraw(engine);
+
+ *continue_to_dispatch = True;
+}
+
+
+void KeyDownCallback(Widget, XtPointer closure, XEvent *event, Boolean *continue_to_dispatch)
+{
+/* GPU_Engine *engine = (GPU_Engine *)closure;
+ XKeyEvent *keyEvent = (XKeyEvent *)event;
+
+ if(engine->Running())
+ engine->m_system->AddKey(int(keyEvent->keycode), 1);
+
+ *continue_to_dispatch = True;*/
+}
+
+
+void KeyUpCallback(Widget, XtPointer closure, XEvent *event, Boolean *continue_to_dispatch)
+{
+/* GPU_Engine *engine = (GPU_Engine *)closure;
+ XKeyEvent *keyEvent = (XKeyEvent *)event;
+
+ if(engine->Running())
+ engine->m_system->AddKey(int(keyEvent->keycode), 0);
+
+ *continue_to_dispatch = True;*/
+}
+
+
+void ButtonPressReleaseCallback(Widget, XtPointer closure, XEvent *event, Boolean *continue_to_dispatch)
+{
+ GPU_Engine *engine = (GPU_Engine *)closure;
+ XButtonEvent *buttonEvent = (XButtonEvent *)event;
+ bool isDown;
+ GPC_MouseDevice::TButtonId button;
+
+ if(engine->Running())
+ {
+ // determine type of event, press or release
+ isDown = false;
+ if(buttonEvent->type == ButtonPress)
+ isDown = true;
+ // determine which button exactly generated this event
+ switch(buttonEvent->button)
+ {
+ case 1:
+ button = GPC_MouseDevice::buttonLeft;
+ break;
+ case 2:
+ button = GPC_MouseDevice::buttonMiddle;
+ break;
+ case 3:
+ button = GPC_MouseDevice::buttonRight;
+ break;
+ }
+ engine->m_mousedev->ConvertButtonEvent(button,
+ isDown, buttonEvent->x, buttonEvent->y);
+ }
+
+ *continue_to_dispatch = True;
+}
+
+
+void PointerMotionCallback(Widget w, XtPointer closure, XEvent *event, Boolean *continue_to_dispatch)
+{
+ GPU_Engine *engine = (GPU_Engine *)closure;
+ XButtonEvent *buttonEvent = (XButtonEvent *)event;
+
+ if(engine->Running())
+ {
+ engine->m_mousedev->ConvertMoveEvent(buttonEvent->x, buttonEvent->y);
+ }
+
+ *continue_to_dispatch = True;
+}
+
+/*
+void TimeOutCallback(XtPointer closure, XtIntervalId *id)
+{
+ GPU_Engine *engine = (GPU_Engine *)closure;
+
+ Redraw(engine);
+ // add a new time out since there is no real timer for X (not a simple one like under windows)
+ // TODO Have to get faster timer !
+
+ if(engine->Running())
+ engine->m_timerId = XtAppAddTimeOut(XtWidgetToApplicationContext(
+ ((GPU_Canvas *)engine->m_canvas)->GetWidget()),
+ engine->m_timerTimeOutMsecs, TimeOutCallback,
+ closure);
+}
+
+*/
diff --git a/source/gameengine/GamePlayer/common/unix/GPU_Engine.h b/source/gameengine/GamePlayer/common/unix/GPU_Engine.h
new file mode 100644
index 00000000000..fe8743f7695
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/unix/GPU_Engine.h
@@ -0,0 +1,65 @@
+/**
+ * $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 __GPU_ENGINE_H
+#define __GPU_ENGINE_H
+
+
+#include <X11/Xlib.h>
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+
+#define Object DNA_Object // tricky stuff !!! but without it it doesn't compile...
+
+#include "GPC_Engine.h"
+
+
+class GPU_Engine : public GPC_Engine
+{
+public:
+ XtIntervalId m_timerId;
+ unsigned long m_timerTimeOutMsecs;
+
+public:
+ GPU_Engine(char *customLoadingAnimation,
+ int foregroundColor, int backgroundColor, int frameRate);
+ virtual ~GPU_Engine();
+ bool Initialize(Display *display, Window window, int width, int height);
+
+ void HandleNewWindow(Window window);
+
+private:
+ void AddEventHandlers();
+};
+
+
+#endif // __GPU_ENGINE_H
diff --git a/source/gameengine/GamePlayer/common/unix/GPU_KeyboardDevice.cpp b/source/gameengine/GamePlayer/common/unix/GPU_KeyboardDevice.cpp
new file mode 100644
index 00000000000..125adcc4b7b
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/unix/GPU_KeyboardDevice.cpp
@@ -0,0 +1,137 @@
+/**
+ * $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 "GPU_KeyboardDevice.h"
+
+void GPU_KeyboardDevice::register_X_key_down_event(KeySym k)
+{
+ ConvertEvent(k, 1);
+}
+
+void GPU_KeyboardDevice::register_X_key_up_event(KeySym k)
+{
+ ConvertEvent(k, 0);
+}
+
+
+#define map_x_key_to_kx_key(x,y) m_reverseKeyTranslateTable[x] = y;
+
+GPU_KeyboardDevice::GPU_KeyboardDevice(void)
+{
+ unsigned int i = 0;
+
+ // Needed?
+ m_reverseKeyTranslateTable.clear();
+
+ for (i = XK_A; i< XK_Z; i++) {
+ m_reverseKeyTranslateTable[i]
+ = (SCA_IInputDevice::KX_EnumInputs)
+ (((unsigned int)SCA_IInputDevice::KX_AKEY) + i - XK_A);
+ }
+
+ // Shifted versions: should not occur: KX doesn't distinguish
+ for (i = XK_a; i< XK_z; i++) {
+ m_reverseKeyTranslateTable[i]
+ = (SCA_IInputDevice::KX_EnumInputs)
+ (((int)SCA_IInputDevice::KX_AKEY) + i - XK_a);
+ }
+
+ for (i = XK_0; i< XK_9; i++) {
+ m_reverseKeyTranslateTable[i]
+ = (SCA_IInputDevice::KX_EnumInputs)
+ (((int)SCA_IInputDevice::KX_ZEROKEY) + i - XK_0);
+ }
+
+ for (i = XK_F1; i< XK_F12; i++) {
+ m_reverseKeyTranslateTable[i]
+ = (SCA_IInputDevice::KX_EnumInputs)
+ (((int)SCA_IInputDevice::KX_F1KEY) + i - XK_F1);
+ }
+
+ // the remainder:
+ map_x_key_to_kx_key(XK_BackSpace, SCA_IInputDevice::KX_BACKSPACEKEY);
+ map_x_key_to_kx_key(XK_Tab, SCA_IInputDevice::KX_TABKEY);
+ map_x_key_to_kx_key(XK_Return, SCA_IInputDevice::KX_RETKEY);
+ map_x_key_to_kx_key(XK_Escape, SCA_IInputDevice::KX_ESCKEY);
+ map_x_key_to_kx_key(XK_space, SCA_IInputDevice::KX_SPACEKEY);
+
+ map_x_key_to_kx_key(XK_Shift_L, SCA_IInputDevice::KX_LEFTSHIFTKEY);
+ map_x_key_to_kx_key(XK_Shift_R, SCA_IInputDevice::KX_RIGHTSHIFTKEY);
+ map_x_key_to_kx_key(XK_Control_L, SCA_IInputDevice::KX_LEFTCTRLKEY);
+ map_x_key_to_kx_key(XK_Control_R, SCA_IInputDevice::KX_RIGHTCTRLKEY);
+ map_x_key_to_kx_key(XK_Alt_L, SCA_IInputDevice::KX_LEFTALTKEY);
+ map_x_key_to_kx_key(XK_Alt_R, SCA_IInputDevice::KX_RIGHTALTKEY);
+
+ map_x_key_to_kx_key(XK_Insert, SCA_IInputDevice::KX_INSERTKEY);
+ map_x_key_to_kx_key(XK_Delete, SCA_IInputDevice::KX_DELKEY);
+ map_x_key_to_kx_key(XK_Home, SCA_IInputDevice::KX_HOMEKEY);
+ map_x_key_to_kx_key(XK_End, SCA_IInputDevice::KX_ENDKEY);
+ map_x_key_to_kx_key(XK_Page_Up, SCA_IInputDevice::KX_PAGEUPKEY);
+ map_x_key_to_kx_key(XK_Page_Down, SCA_IInputDevice::KX_PAGEDOWNKEY);
+
+ map_x_key_to_kx_key(XK_Left, SCA_IInputDevice::KX_LEFTARROWKEY);
+ map_x_key_to_kx_key(XK_Right, SCA_IInputDevice::KX_RIGHTARROWKEY);
+ map_x_key_to_kx_key(XK_Up, SCA_IInputDevice::KX_UPARROWKEY);
+ map_x_key_to_kx_key(XK_Down, SCA_IInputDevice::KX_DOWNARROWKEY);
+
+ map_x_key_to_kx_key(XK_KP_0, SCA_IInputDevice::KX_PAD0);
+ map_x_key_to_kx_key(XK_KP_1, SCA_IInputDevice::KX_PAD1);
+ map_x_key_to_kx_key(XK_KP_2, SCA_IInputDevice::KX_PAD2);
+ map_x_key_to_kx_key(XK_KP_3, SCA_IInputDevice::KX_PAD3);
+ map_x_key_to_kx_key(XK_KP_4, SCA_IInputDevice::KX_PAD4);
+ map_x_key_to_kx_key(XK_KP_5, SCA_IInputDevice::KX_PAD5);
+ map_x_key_to_kx_key(XK_KP_6, SCA_IInputDevice::KX_PAD6);
+ map_x_key_to_kx_key(XK_KP_7, SCA_IInputDevice::KX_PAD7);
+ map_x_key_to_kx_key(XK_KP_8, SCA_IInputDevice::KX_PAD8);
+ map_x_key_to_kx_key(XK_KP_9, SCA_IInputDevice::KX_PAD9);
+ map_x_key_to_kx_key(XK_KP_Decimal, SCA_IInputDevice::KX_PADPERIOD);
+
+ map_x_key_to_kx_key(XK_KP_Insert, SCA_IInputDevice::KX_INSERTKEY);
+ map_x_key_to_kx_key(XK_KP_End, SCA_IInputDevice::KX_ENDKEY);
+ map_x_key_to_kx_key(XK_KP_Down, SCA_IInputDevice::KX_DOWNARROWKEY);
+ map_x_key_to_kx_key(XK_KP_Page_Down,SCA_IInputDevice::KX_PAGEDOWNKEY);
+ map_x_key_to_kx_key(XK_KP_Left, SCA_IInputDevice::KX_LEFTARROWKEY);
+ map_x_key_to_kx_key(XK_KP_Right, SCA_IInputDevice::KX_RIGHTARROWKEY);
+ map_x_key_to_kx_key(XK_KP_Home, SCA_IInputDevice::KX_HOMEKEY);
+ map_x_key_to_kx_key(XK_KP_Up, SCA_IInputDevice::KX_UPARROWKEY);
+ map_x_key_to_kx_key(XK_KP_Page_Up, SCA_IInputDevice::KX_PAGEUPKEY);
+ map_x_key_to_kx_key(XK_KP_Delete, SCA_IInputDevice::KX_DELKEY);
+
+ map_x_key_to_kx_key(XK_KP_Enter, SCA_IInputDevice::KX_PADENTER);
+ map_x_key_to_kx_key(XK_KP_Add, SCA_IInputDevice::KX_PADPLUSKEY);
+ map_x_key_to_kx_key(XK_KP_Subtract, SCA_IInputDevice::KX_PADMINUS);
+ map_x_key_to_kx_key(XK_KP_Multiply, SCA_IInputDevice::KX_PADASTERKEY);
+ map_x_key_to_kx_key(XK_KP_Divide, SCA_IInputDevice::KX_PADSLASHKEY);
+
+ map_x_key_to_kx_key(XK_Caps_Lock, SCA_IInputDevice::KX_CAPSLOCKKEY);
+
+}
diff --git a/source/gameengine/GamePlayer/common/unix/GPU_KeyboardDevice.h b/source/gameengine/GamePlayer/common/unix/GPU_KeyboardDevice.h
new file mode 100644
index 00000000000..24226bf6bfd
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/unix/GPU_KeyboardDevice.h
@@ -0,0 +1,64 @@
+/**
+ * $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 __GPU_KEYBOARDDEVICE_H
+#define __GPU_KEYBOARDDEVICE_H
+
+#include <X11/keysym.h>
+#include <X11/X.h> // Brilliant name, eh? Stupid !@#!$!@#@@% This is
+ // actually needed so as not to get name clashes between Object from
+ // blender and Object from X11... The proper include would be
+ // Intrinsic.h . Yes, we are a bunch of sado-masochists. Let's hurt
+ // ourselves!
+
+#include "GPC_KeyboardDevice.h"
+
+class GPU_KeyboardDevice : public GPC_KeyboardDevice
+{
+public:
+
+ void register_X_key_down_event(KeySym k);
+ void register_X_key_up_event(KeySym k);
+
+ GPU_KeyboardDevice(void);
+ virtual ~GPU_KeyboardDevice()
+ {
+ /* intentionally empty */
+ }
+
+ private:
+ SCA_IInputDevice::KX_EnumInputs
+ convert_x_keycode_to_kx_keycode(unsigned int key);
+};
+
+
+#endif // _GPU_KEYBOARDDEVICE_H
diff --git a/source/gameengine/GamePlayer/common/unix/GPU_PolygonMaterial.h b/source/gameengine/GamePlayer/common/unix/GPU_PolygonMaterial.h
new file mode 100644
index 00000000000..a0629c14158
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/unix/GPU_PolygonMaterial.h
@@ -0,0 +1,57 @@
+/**
+ * $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 __GPU_POLYGONMATERIAL_H
+#define __GPU_POLYGONMATERIAL_H
+
+
+#include "BP_PolygonMaterial.h"
+
+
+class GPU_PolygonMaterial : public BP_PolygonMaterial
+{
+public:
+ GPUPolygonMaterial(const STR_String& texname, bool ba,const STR_String& matname,
+ int tile, int tileXrep, int tileYrep, int mode, int transparant,
+ int lightlayer,bool bIsTriangle,void* clientobject,void* tpage) :
+ BP_PolygonMaterial(texname, ba,matname, tile, tileXrep, tileYrep,
+ mode, transparant, lightlayer, bIsTriangle, clientobject),
+ m_tface(tpage)
+ {
+ }
+
+ virtual ~GPU_PolygonMaterial()
+ {
+ }
+};
+
+#endif // __GPU_POLYGONMATERIAL_H
diff --git a/source/gameengine/GamePlayer/common/unix/GPU_System.cpp b/source/gameengine/GamePlayer/common/unix/GPU_System.cpp
new file mode 100644
index 00000000000..d7484c97dc2
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/unix/GPU_System.cpp
@@ -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 *****
+ */
+
+#include <sys/time.h>
+
+#include "GPU_System.h"
+
+
+static struct timeval startTime;
+static int startTimeDone = 0;
+
+
+double GPU_System::GetTimeInSeconds()
+{
+ if(!startTimeDone)
+ {
+ gettimeofday(&startTime, NULL);
+ startTimeDone = 1;
+ }
+
+ struct timeval now;
+ gettimeofday(&now, NULL);
+ // next '1000' are used for precision
+ long ticks = (now.tv_sec - startTime.tv_sec) * 1000 + (now.tv_usec - startTime.tv_usec) / 1000;
+ double secs = (double)ticks / 1000.0;
+ return secs;
+}
diff --git a/source/gameengine/GamePlayer/common/unix/GPU_System.h b/source/gameengine/GamePlayer/common/unix/GPU_System.h
new file mode 100644
index 00000000000..7a578fb75ad
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/unix/GPU_System.h
@@ -0,0 +1,51 @@
+/**
+ * $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 __GPU_SYSTEM_H
+#define __GPU_SYSTEM_H
+
+
+#include "GPC_System.h"
+
+
+class GPU_System : public GPC_System
+{
+public:
+ GPU_System()
+ {
+ }
+
+ virtual double GetTimeInSeconds();
+};
+
+
+#endif // __GPU_SYSTEM_H
diff --git a/source/gameengine/GamePlayer/common/unix/Makefile b/source/gameengine/GamePlayer/common/unix/Makefile
new file mode 100644
index 00000000000..5f6a52ded9a
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/unix/Makefile
@@ -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 *****
+#
+#
+
+LIBNAME = unix
+DIR = $(OCGDIR)/gameengine/GamePlayer/common/$(LIBNAME)
+
+include nan_compile.mk
+
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+CPPFLAGS += -I$(OPENGL_HEADERS)
+CPPFLAGS += -I$(NAN_STRING)/include
+
+CPPFLAGS += -I..
+CPPFLAGS += -I../../netscape/src/ketsji
+CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
+
+# Game Engine
+CPPFLAGS += -I../../../../gameengine/Converter
+CPPFLAGS += -I../../../../gameengine/Expressions
+CPPFLAGS += -I../../../../gameengine/GameLogic
+CPPFLAGS += -I../../../../gameengine/Ketsji
+CPPFLAGS += -I../../../../gameengine/Ketsji/KXNetwork
+CPPFLAGS += -I../../../../gameengine/Network
+CPPFLAGS += -I../../../../gameengine/Network/LoopBackNetwork
+CPPFLAGS += -I../../../../gameengine/Rasterizer
+CPPFLAGS += -I../../../../gameengine/Rasterizer/RAS_OpenGLRasterizer
+CPPFLAGS += -I../../../../gameengine/SceneGraph
+ifeq ($(NAN_SND), OPENAL)
+ CPPFLAGS += -I../../../../gameengine/SoundSystem
+ CPPFLAGS += -I../../../../gameengine/SoundSystem/SND_OpenAL
+else
+ CPPFLAGS += -I../../../../gameengine/SoundSystem
+ CPPFLAGS += -I../../../../gameengine/SoundSystem/SND_Dummy
+endif
+
+CPPFLAGS += -I../../../../sumo/Fuzzics/include
+CPPFLAGS += -I../../../../sumo/include
+CPPFLAGS += -I$(NAN_MOTO)/include
+CPPFLAGS += -I$(NAN_BMFONT)/include
+
+# Blender stuff
+CPPFLAGS += -I../../../../blender/blenkernel
+CPPFLAGS += -I../../../../blender/blenlib
+CPPFLAGS += -I../../../../blender/blenloader
+CPPFLAGS += -I../../../../blender/imbuf
+CPPFLAGS += -I../../../../blender/makesdna
+CPPFLAGS += -I../../../../kernel/gen_system
+
+CPPFLAGS += -I../../kernel/gen_system
+
diff --git a/source/gameengine/GamePlayer/common/windows/GPW_Canvas.cpp b/source/gameengine/GamePlayer/common/windows/GPW_Canvas.cpp
new file mode 100644
index 00000000000..de3f49e867e
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/windows/GPW_Canvas.cpp
@@ -0,0 +1,174 @@
+/**
+ * $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 "GPW_Canvas.h"
+
+GPW_Canvas::GPW_Canvas(HWND hWnd, HDC hDC, int width, int height)
+ : GPC_Canvas(width, height), m_hWnd(hWnd), m_hRC(0), m_hDC(hDC)
+{
+}
+
+
+GPW_Canvas::~GPW_Canvas()
+{
+ if (m_hRC) {
+ ::wglDeleteContext(m_hRC);
+ }
+ //if (m_hDC) {
+ // ::ReleaseDC(m_hWnd, m_hDC);
+ //}
+}
+
+
+void GPW_Canvas::Init()
+{
+
+// log_entry("GPW_Canvas::Init");
+
+ /*
+ * Color and depth bit values are not to be trusted.
+ * For instance, on TNT2:
+ * When the screen color depth is set to 16 bit, we get 5 color bits
+ * and 16 depth bits.
+ * When the screen color depth is set to 32 bit, we get 8 color bits
+ * and 24 depth bits.
+ * Just to be safe, we request high quality settings.
+ */
+ PIXELFORMATDESCRIPTOR pfd =
+ {
+ sizeof(PIXELFORMATDESCRIPTOR), // iSize
+ 1, // iVersion
+ PFD_DRAW_TO_WINDOW |
+ PFD_SUPPORT_OPENGL |
+// PFD_STEREO |
+ PFD_DOUBLEBUFFER, // dwFlags
+ PFD_TYPE_RGBA, // iPixelType
+ 32, // cColorBits
+ 0, 0, // cRedBits, cRedShift (ignored)
+ 0, 0, // cGreenBits, cGreenShift (ignored)
+ 0, 0, // cBlueBits, cBlueShift (ignored)
+ 0, 0, // cAlphaBits, cAlphaShift (ignored)
+ 0, 0, 0, 0, 0, // cAccum_X_Bits
+ 32, // cDepthBits
+ 0, // cStencilBits
+ 0, // cAuxBuffers
+ PFD_MAIN_PLANE, // iLayerType
+ 0, // bReserved
+ 0, // dwLayerMask
+ 0, // dwVisibleMask
+ 0 // dwDamageMask
+ };
+ PIXELFORMATDESCRIPTOR match;
+
+ // Look what we get back for this pixel format
+ int pixelFormat = ::ChoosePixelFormat(m_hDC, &pfd);
+ if (!pixelFormat) {
+ DWORD error = ::GetLastError();
+ }
+ ::DescribePixelFormat(m_hDC, pixelFormat, sizeof(match), &match);
+
+ // Activate the pixel format for this context
+ ::SetPixelFormat(m_hDC, ::ChoosePixelFormat(m_hDC, &match), &match);
+
+ // Create the OpenGL context and make it current
+ m_hRC = ::wglCreateContext(m_hDC);
+ ::wglMakeCurrent(m_hDC, m_hRC);
+
+}
+
+void GPW_Canvas::SetMousePosition(int x, int y)
+{
+ POINT point = { x, y };
+ if (m_hWnd)
+ {
+ ::ClientToScreen(m_hWnd, &point);
+ ::SetCursorPos(point.x, point.y);
+ }
+}
+
+
+void GPW_Canvas::SetMouseState(RAS_MouseState mousestate)
+{
+ LPCSTR id;
+ switch (mousestate)
+ {
+ case MOUSE_INVISIBLE:
+ HideCursor();
+ break;
+ case MOUSE_WAIT:
+ ::SetCursor(::LoadCursor(0, IDC_WAIT));
+ ShowCursor();
+ break;
+ case MOUSE_NORMAL:
+ ::SetCursor(::LoadCursor(0, IDC_ARROW));
+ ShowCursor();
+ break;
+ }
+}
+
+
+bool GPW_Canvas::BeginDraw(void)
+{
+ ::wglMakeCurrent(m_hDC, m_hRC);
+ // check errors, anyone?
+ return true;
+}
+
+
+void GPW_Canvas::EndDraw(void)
+{
+ ::wglMakeCurrent(NULL, NULL);
+}
+
+void GPW_Canvas::SwapBuffers(void)
+{
+ if (m_hDC) {
+ ::SwapBuffers(m_hDC);
+ }
+}
+
+
+void GPW_Canvas::HideCursor(void)
+{
+ int count = ::ShowCursor(FALSE);
+ while (count >= 0)
+ {
+ count = ::ShowCursor(FALSE);
+ }
+}
+
+
+void GPW_Canvas::ShowCursor(void)
+{
+ ::ShowCursor(TRUE);
+}
+
diff --git a/source/gameengine/GamePlayer/common/windows/GPW_Canvas.h b/source/gameengine/GamePlayer/common/windows/GPW_Canvas.h
new file mode 100644
index 00000000000..59e3eef5b10
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/windows/GPW_Canvas.h
@@ -0,0 +1,119 @@
+/**
+ * $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 _GPW_CANVAS_H_
+#define _GPW_CANVAS_H_
+
+#ifdef WIN32
+#pragma warning (disable:4786) // suppress stl-MSVC debug info warning
+#endif
+
+#include <iostream>
+#include <windows.h>
+#include <gl/gl.h>
+
+#include "GPC_Canvas.h"
+
+
+class GPW_Canvas : public GPC_Canvas
+{
+protected:
+ /** The window handle. */
+ HWND m_hWnd;
+ /** Rendering context. */
+ HGLRC m_hRC;
+ /** Device Context. */
+ HDC m_hDC;
+
+public:
+ /**
+ * Constructor.
+ */
+ GPW_Canvas(HWND hWnd, HDC hDC, int width, int height);
+
+ /**
+ * Destructor.
+ */
+ virtual ~GPW_Canvas(void);
+
+ virtual void Init(void);
+
+ /**
+ * Moves the cursor to a new location.
+ * @param x The x-coordinate of the new location.
+ * @param x The y-coordinate of the new location.
+ */
+ virtual void SetMousePosition(int x, int y);
+
+ /**
+ * Sets the cursor shape and/or visibility.
+ * @param mousestate The new state ofthe cursor.
+ */
+ virtual void SetMouseState(RAS_MouseState mousestate);
+
+ bool BeginDraw(void);
+ void EndDraw(void);
+
+ virtual void SwapBuffers(void);
+
+ virtual HDC GetHDC(void)
+ {
+ return m_hDC;
+ }
+
+ virtual void SetHDC(HDC hDC)
+ {
+ if (hDC != m_hDC) {
+ m_hDC = hDC;
+ }
+ }
+
+ virtual HGLRC GetHGLRC(void)
+ {
+ return m_hRC;
+ }
+
+protected:
+ /**
+ * Hides the mouse cursor.
+ */
+ void HideCursor(void);
+
+ /**
+ * Shows the mouse cursor.
+ */
+ void ShowCursor(void);
+};
+
+
+
+#endif // _GPW_CANVAS_H_
diff --git a/source/gameengine/GamePlayer/common/windows/GPW_Engine.cpp b/source/gameengine/GamePlayer/common/windows/GPW_Engine.cpp
new file mode 100644
index 00000000000..ff4dca9c50e
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/windows/GPW_Engine.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 *****
+ */
+
+#pragma warning (disable : 4786)
+
+#include <assert.h>
+
+#include "GPC_MouseDevice.h"
+#include "GPC_RenderTools.h"
+#include "GPC_RawImage.h"
+
+#include "GPW_Canvas.h"
+#include "GPW_Engine.h"
+#include "GPW_KeyboardDevice.h"
+#include "GPW_System.h"
+
+#include "SND_DeviceManager.h"
+
+#include "NG_NetworkScene.h"
+#include "NG_LoopBackNetworkDeviceInterface.h"
+
+
+GPW_Engine::GPW_Engine(char *customLoadingAnimationURL,
+ int foregroundColor, int backgroundColor, int frameRate) :
+ GPC_Engine(customLoadingAnimationURL, foregroundColor, backgroundColor,
+ frameRate)
+{
+}
+
+
+GPW_Engine::~GPW_Engine()
+{
+}
+
+
+bool GPW_Engine::Initialize(HDC hdc, int width, int height)
+{
+ SND_DeviceManager::Subscribe();
+ m_audiodevice = SND_DeviceManager::Instance();
+
+ m_keyboarddev = new GPW_KeyboardDevice();
+ m_mousedev = new GPC_MouseDevice();
+
+ // constructor only initializes data
+ m_canvas = new GPW_Canvas(0, hdc, width, height);
+ m_canvas->Init(); // create the actual visual and rendering context
+
+ // put the Blender logo in the topleft corner
+ if(m_BlenderLogo != 0)
+ // adding a banner automatically enables them
+ m_BlenderLogoId = m_canvas->AddBanner(m_BlenderLogo->Width(), m_BlenderLogo->Height(),
+ m_BlenderLogo->Width(), m_BlenderLogo->Height(),
+ m_BlenderLogo->Data(), GPC_Canvas::alignTopLeft);
+
+ // put the Blender3D logo in the bottom right corner
+ if(m_Blender3DLogo != 0)
+ // adding a banner automatically enables them
+ m_Blender3DLogoId = m_canvas->AddBanner(m_Blender3DLogo->Width(), m_Blender3DLogo->Height(),
+ m_Blender3DLogo->Width(), m_Blender3DLogo->Height(),
+ m_Blender3DLogo->Data(), GPC_Canvas::alignBottomRight);
+#if 0
+ // put the NaN logo in the bottom right corner
+ if(m_NaNLogo != 0)
+ // adding a banner automatically enables them
+ m_NaNLogoId = m_canvas->AddBanner(m_NaNLogo->Width(), m_NaNLogo->Height(),
+ m_NaNLogo->Width(), m_NaNLogo->Height(),
+ m_NaNLogo->Data(), GPC_Canvas::alignBottomRight);
+#endif
+ // enable the display of all banners
+ m_canvas->SetBannerDisplayEnabled(true);
+
+ // stuff that must be done after creation of a rendering context
+ //m_canvas->InitPostRenderingContext();
+
+ m_rendertools = new GPC_RenderTools();
+
+ m_networkdev = new NG_LoopBackNetworkDeviceInterface();
+ assert(m_networkdev);
+
+ // creation of system needs 'current rendering context', this is taken care
+ // of by the GPW_Canvas
+ m_system = new GPW_System();
+
+// m_system->SetKeyboardDevice((GPW_KeyboardDevice *)m_keyboarddev);
+// m_system->SetMouseDevice(m_mousedev);
+// m_system->SetNetworkDevice(m_networkdev);
+
+ m_initialized = true;
+
+ return m_initialized;
+}
diff --git a/source/gameengine/GamePlayer/common/windows/GPW_Engine.h b/source/gameengine/GamePlayer/common/windows/GPW_Engine.h
new file mode 100644
index 00000000000..7fcd6413e1e
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/windows/GPW_Engine.h
@@ -0,0 +1,50 @@
+/**
+ * $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 __GPW_ENGINE_H
+#define __GPW_ENGINE_H
+
+
+#include "GPC_Engine.h"
+
+
+class GPW_Engine : public GPC_Engine
+{
+public:
+ GPW_Engine(char *customLoadingAnimation,
+ int foregroundColor, int backgroundColor, int frameRate);
+ virtual ~GPW_Engine();
+ bool Initialize(HDC hdc, int width, int height);
+};
+
+
+#endif // __GPW_ENGINE_H
diff --git a/source/gameengine/GamePlayer/common/windows/GPW_KeyboardDevice.cpp b/source/gameengine/GamePlayer/common/windows/GPW_KeyboardDevice.cpp
new file mode 100644
index 00000000000..b9c884af525
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/windows/GPW_KeyboardDevice.cpp
@@ -0,0 +1,280 @@
+/**
+ * $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 "GPW_KeyboardDevice.h"
+
+
+// Key code values not found in winuser.h
+#ifndef VK_MINUS
+#define VK_MINUS 0xBD
+#endif // VK_MINUS
+#ifndef VK_SEMICOLON
+#define VK_SEMICOLON 0xBA
+#endif // VK_SEMICOLON
+#ifndef VK_PERIOD
+#define VK_PERIOD 0xBE
+#endif // VK_PERIOD
+#ifndef VK_COMMA
+#define VK_COMMA 0xBC
+#endif // VK_COMMA
+#ifndef VK_QUOTE
+#define VK_QUOTE 0xDE
+#endif // VK_QUOTE
+#ifndef VK_BACK_QUOTE
+#define VK_BACK_QUOTE 0xC0
+#endif // VK_BACK_QUOTE
+#ifndef VK_SLASH
+#define VK_SLASH 0xBF
+#endif // VK_SLASH
+#ifndef VK_BACK_SLASH
+#define VK_BACK_SLASH 0xDC
+#endif // VK_BACK_SLASH
+#ifndef VK_EQUALS
+#define VK_EQUALS 0xBB
+#endif // VK_EQUALS
+#ifndef VK_OPEN_BRACKET
+#define VK_OPEN_BRACKET 0xDB
+#endif // VK_OPEN_BRACKET
+#ifndef VK_CLOSE_BRACKET
+#define VK_CLOSE_BRACKET 0xDD
+#endif // VK_CLOSE_BRACKET
+
+
+
+GPW_KeyboardDevice::GPW_KeyboardDevice(void)
+{
+ m_seperateLeftRight = false;
+ m_seperateLeftRightInitialized = false;
+
+ m_reverseKeyTranslateTable['A' ] = KX_AKEY ;
+ m_reverseKeyTranslateTable['B' ] = KX_BKEY ;
+ m_reverseKeyTranslateTable['C' ] = KX_CKEY ;
+ m_reverseKeyTranslateTable['D' ] = KX_DKEY ;
+ m_reverseKeyTranslateTable['E' ] = KX_EKEY ;
+ m_reverseKeyTranslateTable['F' ] = KX_FKEY ;
+ m_reverseKeyTranslateTable['G' ] = KX_GKEY ;
+ m_reverseKeyTranslateTable['H' ] = KX_HKEY ;
+ m_reverseKeyTranslateTable['I' ] = KX_IKEY ;
+ m_reverseKeyTranslateTable['J' ] = KX_JKEY ;
+ m_reverseKeyTranslateTable['K' ] = KX_KKEY ;
+ m_reverseKeyTranslateTable['L' ] = KX_LKEY ;
+ m_reverseKeyTranslateTable['M' ] = KX_MKEY ;
+ m_reverseKeyTranslateTable['N' ] = KX_NKEY ;
+ m_reverseKeyTranslateTable['O' ] = KX_OKEY ;
+ m_reverseKeyTranslateTable['P' ] = KX_PKEY ;
+ m_reverseKeyTranslateTable['Q' ] = KX_QKEY ;
+ m_reverseKeyTranslateTable['R' ] = KX_RKEY ;
+ m_reverseKeyTranslateTable['S' ] = KX_SKEY ;
+ m_reverseKeyTranslateTable['T' ] = KX_TKEY ;
+ m_reverseKeyTranslateTable['U' ] = KX_UKEY ;
+ m_reverseKeyTranslateTable['V' ] = KX_VKEY ;
+ m_reverseKeyTranslateTable['W' ] = KX_WKEY ;
+ m_reverseKeyTranslateTable['X' ] = KX_XKEY ;
+ m_reverseKeyTranslateTable['Y' ] = KX_YKEY ;
+ m_reverseKeyTranslateTable['Z' ] = KX_ZKEY ;
+
+ m_reverseKeyTranslateTable['0' ] = KX_ZEROKEY ;
+ m_reverseKeyTranslateTable['1' ] = KX_ONEKEY ;
+ m_reverseKeyTranslateTable['2' ] = KX_TWOKEY ;
+ m_reverseKeyTranslateTable['3' ] = KX_THREEKEY ;
+ m_reverseKeyTranslateTable['4' ] = KX_FOURKEY ;
+ m_reverseKeyTranslateTable['5' ] = KX_FIVEKEY ;
+ m_reverseKeyTranslateTable['6' ] = KX_SIXKEY ;
+ m_reverseKeyTranslateTable['7' ] = KX_SEVENKEY ;
+ m_reverseKeyTranslateTable['8' ] = KX_EIGHTKEY ;
+ m_reverseKeyTranslateTable['9' ] = KX_NINEKEY ;
+
+ // Middle keyboard area keys
+ m_reverseKeyTranslateTable[VK_PAUSE ] = KX_PAUSEKEY ;
+ m_reverseKeyTranslateTable[VK_INSERT ] = KX_INSERTKEY ;
+ m_reverseKeyTranslateTable[VK_DELETE ] = KX_DELKEY ;
+ m_reverseKeyTranslateTable[VK_HOME ] = KX_HOMEKEY ;
+ m_reverseKeyTranslateTable[VK_END ] = KX_ENDKEY ;
+ m_reverseKeyTranslateTable[VK_PRIOR ] = KX_PAGEUPKEY ;
+ m_reverseKeyTranslateTable[VK_NEXT ] = KX_PAGEDOWNKEY ;
+
+ // Arrow keys
+ m_reverseKeyTranslateTable[VK_UP ] = KX_UPARROWKEY ;
+ m_reverseKeyTranslateTable[VK_DOWN ] = KX_DOWNARROWKEY ;
+ m_reverseKeyTranslateTable[VK_LEFT ] = KX_LEFTARROWKEY ;
+ m_reverseKeyTranslateTable[VK_RIGHT ] = KX_RIGHTARROWKEY ;
+
+ // Function keys
+ m_reverseKeyTranslateTable[VK_F1 ] = KX_F1KEY ;
+ m_reverseKeyTranslateTable[VK_F2 ] = KX_F2KEY ;
+ m_reverseKeyTranslateTable[VK_F3 ] = KX_F3KEY ;
+ m_reverseKeyTranslateTable[VK_F4 ] = KX_F4KEY ;
+ m_reverseKeyTranslateTable[VK_F5 ] = KX_F5KEY ;
+ m_reverseKeyTranslateTable[VK_F6 ] = KX_F6KEY ;
+ m_reverseKeyTranslateTable[VK_F7 ] = KX_F7KEY ;
+ m_reverseKeyTranslateTable[VK_F8 ] = KX_F8KEY ;
+ m_reverseKeyTranslateTable[VK_F9 ] = KX_F9KEY ;
+ m_reverseKeyTranslateTable[VK_F10 ] = KX_F10KEY ;
+ m_reverseKeyTranslateTable[VK_F11 ] = KX_F11KEY ;
+ m_reverseKeyTranslateTable[VK_F12 ] = KX_F12KEY ;
+
+ // Numpad keys
+ m_reverseKeyTranslateTable[VK_NUMPAD0 ] = KX_PAD0 ;
+ m_reverseKeyTranslateTable[VK_NUMPAD1 ] = KX_PAD1 ;
+ m_reverseKeyTranslateTable[VK_NUMPAD2 ] = KX_PAD2 ;
+ m_reverseKeyTranslateTable[VK_NUMPAD3 ] = KX_PAD3 ;
+ m_reverseKeyTranslateTable[VK_NUMPAD4 ] = KX_PAD4 ;
+ m_reverseKeyTranslateTable[VK_NUMPAD5 ] = KX_PAD5 ;
+ m_reverseKeyTranslateTable[VK_NUMPAD6 ] = KX_PAD6 ;
+ m_reverseKeyTranslateTable[VK_NUMPAD7 ] = KX_PAD7 ;
+ m_reverseKeyTranslateTable[VK_NUMPAD8 ] = KX_PAD8 ;
+ m_reverseKeyTranslateTable[VK_NUMPAD9 ] = KX_PAD9 ;
+ m_reverseKeyTranslateTable[VK_MULTIPLY ] = KX_PADASTERKEY ;
+ m_reverseKeyTranslateTable[VK_ADD ] = KX_PADPLUSKEY ;
+ m_reverseKeyTranslateTable[VK_DECIMAL ] = KX_PADPERIOD ;
+ m_reverseKeyTranslateTable[VK_SUBTRACT ] = KX_PADMINUS ;
+ m_reverseKeyTranslateTable[VK_DIVIDE ] = KX_PADSLASHKEY ;
+ m_reverseKeyTranslateTable[VK_SEPARATOR ] = KX_PADENTER ;
+
+ // Other keys
+ m_reverseKeyTranslateTable[VK_CAPITAL ] = KX_CAPSLOCKKEY ;
+ m_reverseKeyTranslateTable[VK_ESCAPE ] = KX_ESCKEY ;
+ m_reverseKeyTranslateTable[VK_TAB ] = KX_TABKEY ;
+ //m_reverseKeyTranslateTable[VK_RETURN ] = KX_RETKEY ;
+ m_reverseKeyTranslateTable[VK_SPACE ] = KX_SPACEKEY ;
+ m_reverseKeyTranslateTable[VK_RETURN ] = KX_LINEFEEDKEY ;
+ m_reverseKeyTranslateTable[VK_BACK ] = KX_BACKSPACEKEY ;
+ m_reverseKeyTranslateTable[VK_SEMICOLON ] = KX_SEMICOLONKEY ;
+ m_reverseKeyTranslateTable[VK_PERIOD ] = KX_PERIODKEY ;
+ m_reverseKeyTranslateTable[VK_COMMA ] = KX_COMMAKEY ;
+ m_reverseKeyTranslateTable[VK_QUOTE ] = KX_QUOTEKEY ;
+ m_reverseKeyTranslateTable[VK_BACK_QUOTE ] = KX_ACCENTGRAVEKEY ;
+ m_reverseKeyTranslateTable[VK_MINUS ] = KX_MINUSKEY ;
+ m_reverseKeyTranslateTable[VK_SLASH ] = KX_SLASHKEY ;
+ m_reverseKeyTranslateTable[VK_BACK_SLASH ] = KX_BACKSLASHKEY ;
+ m_reverseKeyTranslateTable[VK_EQUALS ] = KX_EQUALKEY ;
+ m_reverseKeyTranslateTable[VK_OPEN_BRACKET ] = KX_LEFTBRACKETKEY ;
+ m_reverseKeyTranslateTable[VK_CLOSE_BRACKET ] = KX_RIGHTBRACKETKEY ;
+
+ /*
+ * Need to handle Ctrl, Alt and Shift keys differently.
+ * Win32 messages do not discriminate left and right keys.
+ */
+ m_reverseKeyTranslateTable[VK_LCONTROL ] = KX_LEFTCTRLKEY ;
+ m_reverseKeyTranslateTable[VK_RCONTROL ] = KX_RIGHTCTRLKEY ;
+ m_reverseKeyTranslateTable[VK_LMENU ] = KX_LEFTALTKEY ;
+ m_reverseKeyTranslateTable[VK_RMENU ] = KX_RIGHTALTKEY ;
+ m_reverseKeyTranslateTable[VK_RSHIFT ] = KX_RIGHTSHIFTKEY ;
+ m_reverseKeyTranslateTable[VK_LSHIFT ] = KX_LEFTSHIFTKEY ;
+}
+
+
+GPW_KeyboardDevice::~GPW_KeyboardDevice(void)
+{
+}
+
+
+void GPW_KeyboardDevice::ConvertWinEvent(WPARAM wParam, bool isDown)
+{
+ if ((wParam == VK_SHIFT) || (wParam == VK_MENU) || (wParam == VK_CONTROL)) {
+ ConvertModifierKey(wParam, isDown);
+ }
+ else {
+ ConvertEvent(wParam, isDown);
+ }
+}
+
+
+void GPW_KeyboardDevice::ConvertModifierKey(WPARAM wParam, bool isDown)
+{
+ /*
+ GetKeyState and GetAsyncKeyState only work with Win95, Win98, NT4,
+ Terminal Server and Windows 2000.
+ But on WinME it always returns zero. These two functions are simply
+ skipped by Millenium Edition!
+
+ Official explanation from Microsoft:
+ Intentionally disabled.
+ It didn't work all that well on some newer hardware, and worked less
+ well with the passage of time, so it was fully disabled in ME.
+ */
+ if (!m_seperateLeftRightInitialized && isDown) {
+ CheckForSeperateLeftRight(wParam);
+ }
+ if (m_seperateLeftRight) {
+ bool down = HIBYTE(::GetKeyState(VK_LSHIFT)) != 0;
+ ConvertEvent(VK_LSHIFT, down);
+ down = HIBYTE(::GetKeyState(VK_RSHIFT)) != 0;
+ ConvertEvent(VK_RSHIFT, down);
+ down = HIBYTE(::GetKeyState(VK_LMENU)) != 0;
+ ConvertEvent(VK_LMENU, down);
+ down = HIBYTE(::GetKeyState(VK_RMENU)) != 0;
+ ConvertEvent(VK_RMENU, down);
+ down = HIBYTE(::GetKeyState(VK_LCONTROL)) != 0;
+ ConvertEvent(VK_LCONTROL, down);
+ down = HIBYTE(::GetKeyState(VK_RCONTROL)) != 0;
+ ConvertEvent(VK_RCONTROL, down);
+ }
+ else {
+ bool down = HIBYTE(::GetKeyState(VK_SHIFT)) != 0;
+ ConvertEvent(VK_LSHIFT, down);
+ ConvertEvent(VK_RSHIFT, down);
+ down = HIBYTE(::GetKeyState(VK_MENU)) != 0;
+ ConvertEvent(VK_LMENU, down);
+ ConvertEvent(VK_RMENU, down);
+ down = HIBYTE(::GetKeyState(VK_CONTROL)) != 0;
+ ConvertEvent(VK_LCONTROL, down);
+ ConvertEvent(VK_RCONTROL, down);
+ }
+}
+
+
+void GPW_KeyboardDevice::CheckForSeperateLeftRight(WPARAM wParam)
+{
+ // Check whether this system supports seperate left and right keys
+ switch (wParam) {
+ case VK_SHIFT:
+ m_seperateLeftRight =
+ (HIBYTE(::GetKeyState(VK_LSHIFT)) != 0) ||
+ (HIBYTE(::GetKeyState(VK_RSHIFT)) != 0) ?
+ true : false;
+ break;
+ case VK_CONTROL:
+ m_seperateLeftRight =
+ (HIBYTE(::GetKeyState(VK_LCONTROL)) != 0) ||
+ (HIBYTE(::GetKeyState(VK_RCONTROL)) != 0) ?
+ true : false;
+ break;
+ case VK_MENU:
+ m_seperateLeftRight =
+ (HIBYTE(::GetKeyState(VK_LMENU)) != 0) ||
+ (HIBYTE(::GetKeyState(VK_RMENU)) != 0) ?
+ true : false;
+ break;
+ }
+ m_seperateLeftRightInitialized = true;
+}
diff --git a/source/gameengine/GamePlayer/common/windows/GPW_KeyboardDevice.h b/source/gameengine/GamePlayer/common/windows/GPW_KeyboardDevice.h
new file mode 100644
index 00000000000..663c0ee2563
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/windows/GPW_KeyboardDevice.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 _GPW_KEYBOARDDEVICE_H_
+#define _GPW_KEYBOARDDEVICE_H_
+
+#pragma warning (disable : 4786)
+
+#include <windows.h>
+
+#include "GPC_KeyboardDevice.h"
+
+/**
+ * Win32 implementation of GPC_KeyboardDevice.
+ * The contructor fills the keyboard code translation map.
+ * Base class GPC_KeyboardDevice does the rest.
+ * @see SCA_IInputDevice
+ */
+class GPW_KeyboardDevice : public GPC_KeyboardDevice
+{
+public:
+ GPW_KeyboardDevice(void);
+
+ virtual ~GPW_KeyboardDevice(void);
+
+ void ConvertWinEvent(WPARAM wParam, bool isDown);
+
+protected:
+
+ void ConvertModifierKey(WPARAM wParam, bool isDown);
+
+ void CheckForSeperateLeftRight(WPARAM wParam);
+
+ /** Stores the capability of this system to distinguish left and right modifier keys. */
+ bool m_seperateLeftRight;
+ /** Stores the initialization state of the member m_leftRightDistinguishable. */
+ bool m_seperateLeftRightInitialized;
+};
+
+#endif //_GPW_KEYBOARDDEVICE_H_
diff --git a/source/gameengine/GamePlayer/common/windows/GPW_System.cpp b/source/gameengine/GamePlayer/common/windows/GPW_System.cpp
new file mode 100644
index 00000000000..ba71e036fc4
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/windows/GPW_System.cpp
@@ -0,0 +1,93 @@
+/**
+ * $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 *****
+ * Timing routine taken and modified from KX_BlenderSystem.cpp
+ */
+
+#include <windows.h>
+
+#include "GPW_System.h"
+
+
+GPW_System::GPW_System(void)
+{
+ m_freq = 0;
+ m_lastCount = 0;
+ m_lastRest = 0;
+ m_lastTime = 0;
+}
+
+
+double GPW_System::GetTimeInSeconds()
+{
+#if 0
+ double secs = ::GetTickCount();
+ secs /= 1000.;
+ return secs;
+#else
+
+ // 03/20/1999 Thomas Hieber: completely redone to get true Millisecond
+ // accuracy instead of very rough ticks. This routine will also provide
+ // correct wrap around at the end of "long"
+
+ // m_freq was set to -1, if the current Hardware does not support
+ // high resolution timers. We will use GetTickCount instead then.
+ if (m_freq < 0) {
+ return ::GetTickCount();
+ }
+
+ // m_freq is 0, the first time this function is being called.
+ if (m_freq == 0) {
+ // Try to determine the frequency of the high resulution timer
+ if (!::QueryPerformanceFrequency((LARGE_INTEGER*)&m_freq)) {
+ // There is no such timer....
+ m_freq = -1;
+ return 0;
+ }
+ }
+
+ // Retrieve current count
+ __int64 count = 0;
+ ::QueryPerformanceCounter((LARGE_INTEGER*)&count);
+
+ // Calculate the time passed since last call, and add the rest of
+ // those tics that didn't make it into the last reported time.
+ __int64 delta = 1000*(count-m_lastCount) + m_lastRest;
+
+ m_lastTime += (long)(delta/m_freq); // Save the new value
+ m_lastRest = delta%m_freq; // Save those ticks not being counted
+ m_lastCount = count; // Save last count
+
+ // Return a high quality measurement of time
+ return m_lastTime/1000.0;
+#endif
+}
+
+
diff --git a/source/gameengine/GamePlayer/common/windows/GPW_System.h b/source/gameengine/GamePlayer/common/windows/GPW_System.h
new file mode 100644
index 00000000000..50b005d8342
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/windows/GPW_System.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 *****
+ * Timing routine taken and modified from KX_BlenderSystem.cpp
+ */
+
+#ifndef _GPW_SYSTEM_H_
+#define _GPW_SYSTEM_H_
+
+#pragma warning (disable:4786) // suppress stl-MSVC debug info warning
+
+#include "GPC_System.h"
+
+#if defined(__CYGWIN32__)
+# define __int64 long long
+#endif
+
+
+class GPW_System : public GPC_System
+{
+public:
+ GPW_System();
+
+ virtual double GetTimeInSeconds();
+protected:
+
+ __int64 m_freq;
+ __int64 m_lastCount;
+ __int64 m_lastRest;
+ long m_lastTime;
+
+};
+
+
+#endif //_GPW_SYSTEM_H_
diff --git a/source/gameengine/GamePlayer/common/windows/Makefile b/source/gameengine/GamePlayer/common/windows/Makefile
new file mode 100644
index 00000000000..bc8d1da6f9a
--- /dev/null
+++ b/source/gameengine/GamePlayer/common/windows/Makefile
@@ -0,0 +1,66 @@
+#
+# $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 *****
+#
+#
+# ATTENTION: this Makefile is only used for win builds!
+
+LIBNAME = windows
+DIR = $(OCGDIR)/gameengine/GamePlayer/common/$(LIBNAME)
+
+include nan_compile.mk
+
+CPPFLAGS += -I..
+CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
+
+CPPFLAGS += -I$(SRCHOME)/gameengine/GameLogic
+CPPFLAGS += -I$(SRCHOME)/gameengine/Rasterizer
+CPPFLAGS += -I$(SRCHOME)/gameengine/Ketsji
+CPPFLAGS += -I$(SRCHOME)/gameengine/SoundSystem
+CPPFLAGS += -I$(SRCHOME)/gameengine/Network
+CPPFLAGS += -I$(SRCHOME)/gameengine/Network/LoopBackNetwork
+
+CPPFLAGS += -I$(SRCHOME)/sumo/Fuzzics/include
+CPPFLAGS += -I$(SRCHOME)/sumo/include
+
+CPPFLAGS += -I$(NAN_MOTO)/include
+CPPFLAGS += -I$(NAN_STRING)/include
+CPPFLAGS += -I$(NAN_BMFONT)/include
+
+# Blender stuff
+CPPFLAGS += -I$(SRCHOME)/blender/blenkernel
+CPPFLAGS += -I$(SRCHOME)/blender/blenlib
+CPPFLAGS += -I$(SRCHOME)/blender/blenloader
+CPPFLAGS += -I$(SRCHOME)/blender/imbuf
+CPPFLAGS += -I$(SRCHOME)/blender/makesdna
+CPPFLAGS += -I$(SRCHOME)/kernel/gen_system
+
+CPPFLAGS += -I../../kernel/gen_system
+
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
new file mode 100644
index 00000000000..07ed803b205
--- /dev/null
+++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
@@ -0,0 +1,607 @@
+/**
+ * $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 *****
+ * GHOST Blender Player application implementation file.
+ */
+
+#ifdef WIN32
+ #pragma warning (disable:4786) // suppress stl-MSVC debug info warning
+#endif
+
+#include "GPG_Application.h"
+
+#include <iostream>
+#include <assert.h>
+
+/**********************************
+ * Begin Blender include block
+ **********************************/
+#ifdef __cplusplus
+extern "C"
+{
+#endif // __cplusplus
+#include "BLI_blenlib.h"
+#include "BLO_readfile.h"
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+/**********************************
+ * End Blender include block
+ **********************************/
+
+
+#include "SYS_System.h"
+#include "KX_KetsjiEngine.h"
+
+// include files needed by "KX_BlenderSceneConverter.h"
+#include "GEN_Map.h"
+#include "SCA_IActuator.h"
+#include "RAS_MeshObject.h"
+#include "RAS_OpenGLRasterizer.h"
+#include "KX_PythonInit.h"
+#include "KX_PyConstraintBinding.h"
+
+#include "KX_BlenderSceneConverter.h"
+#include "NG_LoopBackNetworkDeviceInterface.h"
+#include "SND_DeviceManager.h"
+
+#include "GPC_MouseDevice.h"
+#include "GPC_RenderTools.h"
+#include "GPG_Canvas.h"
+#include "GPG_KeyboardDevice.h"
+#include "GPG_System.h"
+
+#include "STR_String.h"
+
+#include "GHOST_ISystem.h"
+#include "GHOST_IEvent.h"
+#include "GHOST_IEventConsumer.h"
+#include "GHOST_IWindow.h"
+#include "GHOST_Rect.h"
+
+
+static void frameTimerProc(GHOST_ITimerTask* task, GHOST_TUns64 time);
+
+static GHOST_ISystem* fSystem = 0;
+static const int kTimerFreq = 10;
+
+GPG_Application::GPG_Application(GHOST_ISystem* system, struct Main *maggie, STR_String startSceneName)
+ : m_maggie(maggie), m_startSceneName(startSceneName), m_exitRequested(0),
+ m_system(system), m_mainWindow(0), m_frameTimer(0), m_cursor(GHOST_kStandardCursorFirstCursor),
+ m_mouse(0), m_keyboard(0), m_rasterizer(0), m_canvas(0), m_rendertools(0), m_kxsystem(0), m_networkdevice(0), m_audiodevice(0), m_sceneconverter(0),
+ m_engineInitialized(0), m_engineRunning(0), m_ketsjiengine(0)
+{
+ fSystem = system;
+}
+
+
+
+GPG_Application::~GPG_Application(void)
+{
+ exitEngine();
+ fSystem->disposeWindow(m_mainWindow);
+}
+
+
+
+bool GPG_Application::SetGameEngineData(struct Main *maggie, STR_String startSceneName)
+{
+ bool result = false;
+
+ if (maggie != NULL && startSceneName != "")
+ {
+ m_maggie = maggie;
+ m_startSceneName = startSceneName;
+ result = true;
+ }
+
+ return result;
+}
+
+
+
+bool GPG_Application::startWindow(STR_String& title,
+ int windowLeft,
+ int windowTop,
+ int windowWidth,
+ int windowHeight,
+ const bool stereoVisual,
+ const int stereoMode)
+{
+ bool success;
+ // Create the main window
+ //STR_String title ("Blender Player - GHOST");
+ m_mainWindow = fSystem->createWindow(title, windowLeft, windowTop, windowWidth, windowHeight, GHOST_kWindowStateNormal,
+ GHOST_kDrawingContextTypeOpenGL, stereoVisual);
+ if (!m_mainWindow) {
+ printf("error: could not create main window\n");
+ exit(-1);
+ }
+
+ /* Check the size of the client rectangle of the window and resize the window
+ * so that the client rectangle has the size requested.
+ */
+ m_mainWindow->setClientSize(windowWidth, windowHeight);
+
+ success = initEngine(m_mainWindow, stereoMode);
+ if (success) {
+ success = startEngine();
+ }
+ return success;
+}
+
+
+
+bool GPG_Application::startFullScreen(
+ int width,
+ int height,
+ int bpp,int frequency,
+ const bool stereoVisual,
+ const int stereoMode)
+{
+ bool success;
+ // Create the main window
+ GHOST_DisplaySetting setting;
+ setting.xPixels = width;
+ setting.yPixels = height;
+ setting.bpp = bpp;
+ setting.frequency = frequency;
+
+ fSystem->beginFullScreen(setting, &m_mainWindow, stereoVisual);
+
+ success = initEngine(m_mainWindow, stereoMode);
+ if (success) {
+ success = startEngine();
+ }
+ return success;
+}
+
+
+
+bool GPG_Application::StartGameEngine(int stereoMode)
+{
+ bool success = initEngine(m_mainWindow, stereoMode);
+
+ if (success)
+ success = startEngine();
+
+ return success;
+}
+
+
+
+void GPG_Application::StopGameEngine()
+{
+ exitEngine();
+}
+
+
+
+bool GPG_Application::processEvent(GHOST_IEvent* event)
+{
+ bool handled = true;
+
+ switch (event->getType())
+ {
+ case GHOST_kEventUnknown:
+ break;
+
+ case GHOST_kEventButtonDown:
+ handled = handleButton(event, true);
+ break;
+
+ case GHOST_kEventButtonUp:
+ handled = handleButton(event, false);
+ break;
+
+ case GHOST_kEventCursorMove:
+ handled = handleCursorMove(event);
+ break;
+
+ case GHOST_kEventKeyDown:
+ handleKey(event, true);
+ break;
+
+ case GHOST_kEventKeyUp:
+ handleKey(event, false);
+ break;
+
+
+ case GHOST_kEventWindowClose:
+ m_exitRequested = KX_EXIT_REQUEST_OUTSIDE;
+ break;
+
+ case GHOST_kEventWindowActivate:
+ handled = false;
+ break;
+ case GHOST_kEventWindowDeactivate:
+ handled = false;
+ break;
+
+ case GHOST_kEventWindowUpdate:
+ {
+ GHOST_IWindow* window = event->getWindow();
+ if (!m_system->validWindow(window)) break;
+ // Update the state of the game engine
+ if (m_kxsystem && !m_exitRequested)
+ {
+ // Proceed to next frame
+ window->activateDrawingContext();
+
+ // first check if we want to exit
+ m_exitRequested = m_ketsjiengine->GetExitCode();
+
+ // kick the engine
+ m_ketsjiengine->NextFrame();
+
+ // render the frame
+ m_ketsjiengine->Render();
+ }
+ m_exitString = m_ketsjiengine->GetExitString();
+ }
+ break;
+
+ case GHOST_kEventWindowSize:
+ {
+ GHOST_IWindow* window = event->getWindow();
+ if (!m_system->validWindow(window)) break;
+ if (m_canvas) {
+ GHOST_Rect bnds;
+ window->getClientBounds(bnds);
+ m_canvas->Resize(bnds.getWidth(), bnds.getHeight());
+ }
+ }
+ break;
+
+ default:
+ handled = false;
+ break;
+ }
+ return handled;
+}
+
+
+
+int GPG_Application::getExitRequested(void)
+{
+ return m_exitRequested;
+}
+
+
+
+const STR_String& GPG_Application::getExitString(void)
+{
+ return m_exitString;
+}
+
+
+
+bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode)
+{
+ if (!m_engineInitialized)
+ {
+ // get and set the preferences
+ SYS_SystemHandle syshandle = SYS_GetSystem();
+ if (syshandle)
+ {
+ // SYS_WriteCommandLineInt(syshandle, "fixedtime", 0);
+ SYS_WriteCommandLineInt(syshandle, "vertexarrays",1);
+ //bool properties = (SYS_GetCommandLineInt(syshandle, "show_properties", 0) != 0);
+ //bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0);
+ //bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0);
+
+ // create the canvas, rasterizer and rendertools
+ m_canvas = new GPG_Canvas(window);
+ if (m_canvas)
+ {
+ m_canvas->Init();
+ m_rendertools = new GPC_RenderTools();
+ if (m_rendertools)
+ {
+ m_rasterizer = new RAS_OpenGLRasterizer(m_canvas);
+ m_rasterizer->SetStereoMode(stereoMode);
+ if (m_rasterizer)
+ {
+ // create the inputdevices
+ m_keyboard = new GPG_KeyboardDevice();
+ if (m_keyboard)
+ {
+ m_mouse = new GPC_MouseDevice();
+ if (m_mouse)
+ {
+ // create a networkdevice
+ m_networkdevice = new NG_LoopBackNetworkDeviceInterface();
+ if (m_networkdevice)
+ {
+ // get an audiodevice
+ SND_DeviceManager::Subscribe();
+ m_audiodevice = SND_DeviceManager::Instance();
+ if (m_audiodevice)
+ {
+ m_audiodevice->UseCD();
+ // create a ketsjisystem (only needed for timing and stuff)
+ m_kxsystem = new GPG_System (m_system);
+ if (m_kxsystem)
+ {
+ // create the ketsjiengine
+ m_ketsjiengine = new KX_KetsjiEngine(m_kxsystem);
+
+ // set the devices
+ m_ketsjiengine->SetKeyboardDevice(m_keyboard);
+ m_ketsjiengine->SetMouseDevice(m_mouse);
+ m_ketsjiengine->SetNetworkDevice(m_networkdevice);
+ m_ketsjiengine->SetCanvas(m_canvas);
+ m_ketsjiengine->SetRenderTools(m_rendertools);
+ m_ketsjiengine->SetRasterizer(m_rasterizer);
+ m_ketsjiengine->SetNetworkDevice(m_networkdevice);
+ m_ketsjiengine->SetAudioDevice(m_audiodevice);
+
+ m_ketsjiengine->SetUseFixedTime(false);
+ //m_ketsjiengine->SetTimingDisplay(frameRate, profile, properties);
+
+ m_engineInitialized = true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return m_engineInitialized;
+}
+
+
+
+bool GPG_Application::startEngine(void)
+{
+ if (m_engineRunning) {
+ return false;
+ }
+
+ // Temporary hack to disable banner display for NaN approved content.
+ /*
+ m_canvas->SetBannerDisplayEnabled(true);
+ Camera* cam;
+ cam = (Camera*)G.scene->camera->data;
+ if (cam) {
+ if (((cam->flag) & 48)==48) {
+ m_canvas->SetBannerDisplayEnabled(false);
+ }
+ }
+ else {
+ showError(CString("Camera data invalid."));
+ return false;
+ }
+ */
+
+ // create a scene converter, create and convert the stratingscene
+ m_sceneconverter = new KX_BlenderSceneConverter(m_maggie, m_ketsjiengine);
+ if (m_sceneconverter)
+ {
+ STR_String startscenename = m_startSceneName.Ptr();
+ m_ketsjiengine->SetSceneConverter(m_sceneconverter);
+
+ // if (always_use_expand_framing)
+ // sceneconverter->SetAlwaysUseExpandFraming(true);
+
+
+ KX_Scene* startscene = new KX_Scene(m_keyboard,
+ m_mouse,
+ m_networkdevice,
+ m_audiodevice,
+ startscenename);
+
+ // some python things
+ PyObject* m_dictionaryobject = initGamePythonScripting("Ketsji", psl_Lowest);
+ m_ketsjiengine->SetPythonDictionary(m_dictionaryobject);
+ initRasterizer(m_rasterizer, m_canvas);
+ initGameLogic(startscene);
+ initGameKeys();
+ initPythonConstraintBinding();
+
+ m_sceneconverter->ConvertScene(
+ startscenename,
+ startscene,
+ m_dictionaryobject,
+ m_keyboard,
+ m_rendertools,
+ m_canvas);
+ m_ketsjiengine->AddScene(startscene);
+
+ // Create a timer that is used to kick the engine
+ if (!m_frameTimer) {
+ m_frameTimer = m_system->installTimer(0, kTimerFreq, frameTimerProc, m_mainWindow);
+ }
+ m_rasterizer->Init();
+ m_ketsjiengine->StartEngine();
+ m_engineRunning = true;
+
+ }
+
+ if (!m_engineRunning)
+ {
+ stopEngine();
+ }
+
+ return m_engineRunning;
+}
+
+
+void GPG_Application::stopEngine()
+{
+ // when exiting the mainloop
+ exitGamePythonScripting();
+ m_ketsjiengine->StopEngine();
+ m_networkdevice->Disconnect();
+
+ if (m_sceneconverter) {
+ delete m_sceneconverter;
+ m_sceneconverter = 0;
+ }
+ if (m_system && m_frameTimer) {
+ m_system->removeTimer(m_frameTimer);
+ m_frameTimer = 0;
+ }
+ m_engineRunning = false;
+}
+
+
+void GPG_Application::exitEngine()
+{
+ if (m_ketsjiengine)
+ {
+ stopEngine();
+ delete m_ketsjiengine;
+ m_ketsjiengine = 0;
+ }
+ if (m_kxsystem)
+ {
+ delete m_kxsystem;
+ m_kxsystem = 0;
+ }
+ if (m_audiodevice)
+ {
+ SND_DeviceManager::Unsubscribe();
+ m_audiodevice = 0;
+ }
+ if (m_networkdevice)
+ {
+ delete m_networkdevice;
+ m_networkdevice = 0;
+ }
+ if (m_mouse)
+ {
+ delete m_mouse;
+ m_mouse = 0;
+ }
+ if (m_keyboard)
+ {
+ delete m_keyboard;
+ m_keyboard = 0;
+ }
+ if (m_rasterizer)
+ {
+ delete m_rasterizer;
+ m_rasterizer = 0;
+ }
+ if (m_rendertools)
+ {
+ delete m_rendertools;
+ m_rendertools = 0;
+ }
+ if (m_canvas)
+ {
+ delete m_canvas;
+ m_canvas = 0;
+ }
+
+ m_exitRequested = 0;
+ m_engineInitialized = false;
+}
+
+
+bool GPG_Application::handleButton(GHOST_IEvent* event, bool isDown)
+{
+ bool handled = false;
+ assert(event);
+ if (m_mouse)
+ {
+ GHOST_TEventDataPtr eventData = ((GHOST_IEvent*)event)->getData();
+ GHOST_TEventButtonData* buttonData = static_cast<GHOST_TEventButtonData*>(eventData);
+ GPC_MouseDevice::TButtonId button;
+ switch (buttonData->button)
+ {
+ case GHOST_kButtonMaskMiddle:
+ button = GPC_MouseDevice::buttonMiddle;
+ break;
+ case GHOST_kButtonMaskRight:
+ button = GPC_MouseDevice::buttonRight;
+ break;
+ case GHOST_kButtonMaskLeft:
+ default:
+ button = GPC_MouseDevice::buttonLeft;
+ break;
+ }
+ m_mouse->ConvertButtonEvent(button, isDown);
+ handled = true;
+ }
+ return handled;
+}
+
+
+bool GPG_Application::handleCursorMove(GHOST_IEvent* event)
+{
+ bool handled = false;
+ assert(event);
+ if (m_mouse && m_mainWindow)
+ {
+ GHOST_TEventDataPtr eventData = ((GHOST_IEvent*)event)->getData();
+ GHOST_TEventCursorData* cursorData = static_cast<GHOST_TEventCursorData*>(eventData);
+ GHOST_TInt32 x, y;
+ m_mainWindow->screenToClient(cursorData->x, cursorData->y, x, y);
+ m_mouse->ConvertMoveEvent(x, y);
+ handled = true;
+ }
+ return handled;
+}
+
+
+bool GPG_Application::handleKey(GHOST_IEvent* event, bool isDown)
+{
+ bool handled = false;
+ assert(event);
+ if (m_keyboard)
+ {
+ GHOST_TEventDataPtr eventData = ((GHOST_IEvent*)event)->getData();
+ GHOST_TEventKeyData* keyData = static_cast<GHOST_TEventKeyData*>(eventData);
+ if (fSystem->getFullScreen()) {
+ if (keyData->key == GHOST_kKeyEsc) {
+ m_exitRequested = KX_EXIT_REQUEST_OUTSIDE;
+ }
+ }
+ m_keyboard->ConvertEvent(keyData->key, isDown);
+ handled = true;
+ }
+ return handled;
+}
+
+
+
+static void frameTimerProc(GHOST_ITimerTask* task, GHOST_TUns64 time)
+{
+ GHOST_IWindow* window = (GHOST_IWindow*)task->getUserData();
+ if (fSystem->validWindow(window)) {
+ window->invalidate();
+ }
+}
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.h b/source/gameengine/GamePlayer/ghost/GPG_Application.h
new file mode 100644
index 00000000000..ac502630440
--- /dev/null
+++ b/source/gameengine/GamePlayer/ghost/GPG_Application.h
@@ -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 *****
+ * GHOST Blender Player application declaration file.
+ */
+
+#include "GHOST_IEventConsumer.h"
+
+#include "STR_String.h"
+
+class KX_KetsjiEngine;
+class KX_ISceneConverter;
+class NG_LoopBackNetworkDeviceInterface;
+class SND_IAudioDevice;
+class RAS_IRasterizer;
+class GHOST_IEvent;
+class GHOST_ISystem;
+class GHOST_ITimerTask;
+class GHOST_IWindow;
+class GPC_MouseDevice;
+class GPC_RenderTools;
+class GPG_Canvas;
+class GPG_KeyboardDevice;
+class GPG_System;
+struct Main;
+
+class GPG_Application : public GHOST_IEventConsumer
+{
+public:
+ GPG_Application(GHOST_ISystem* system, struct Main *maggie, STR_String startSceneName);
+ ~GPG_Application(void);
+
+ bool SetGameEngineData(struct Main *maggie, STR_String startSceneName);
+ bool startWindow(STR_String& title, int windowLeft, int windowTop, int windowWidth, int windowHeight,
+ const bool stereoVisual, const int stereoMode);
+ bool startFullScreen(int width, int height, int bpp, int frequency, const bool stereoVisual, const int stereoMode);
+ virtual bool processEvent(GHOST_IEvent* event);
+ int getExitRequested(void);
+ const STR_String& getExitString(void);
+ bool StartGameEngine(int stereoMode);
+ void StopGameEngine();
+
+protected:
+ bool handleButton(GHOST_IEvent* event, bool isDown);
+ bool handleCursorMove(GHOST_IEvent* event);
+ bool handleKey(GHOST_IEvent* event, bool isDown);
+
+ /**
+ * Initializes the game engine.
+ */
+ bool initEngine(GHOST_IWindow* window, int stereoMode);
+
+ /**
+ * Starts the game engine.
+ */
+ bool startEngine(void);
+
+ /**
+ * Stop the game engine.
+ */
+ void stopEngine(void);
+
+ /**
+ * Shuts the game engine down.
+ */
+ void exitEngine(void);
+
+ /* The game data */
+ STR_String m_startSceneName;
+ struct Main* m_maggie;
+
+ /* Exit state. */
+ int m_exitRequested;
+ STR_String m_exitString;
+ /* GHOST system abstraction. */
+ GHOST_ISystem* m_system;
+ /* Main window. */
+ GHOST_IWindow* m_mainWindow;
+ /* Timer to advance frames. */
+ GHOST_ITimerTask* m_frameTimer;
+ /* The cursor shape displayed. */
+ GHOST_TStandardCursor m_cursor;
+
+ /** Engine construction state. */
+ bool m_engineInitialized;
+ /** Engine state. */
+ bool m_engineRunning;
+
+ /** the gameengine itself */
+ KX_KetsjiEngine* m_ketsjiengine;
+ /** The game engine's system abstraction. */
+ GPG_System* m_kxsystem;
+ /** The game engine's keyboard abstraction. */
+ GPG_KeyboardDevice* m_keyboard;
+ /** The game engine's mouse abstraction. */
+ GPC_MouseDevice* m_mouse;
+ /** The game engine's canvas abstraction. */
+ GPG_Canvas* m_canvas;
+ /** The game engine's platform dependent render tools. */
+ GPC_RenderTools* m_rendertools;
+ /** the rasterizer */
+ RAS_IRasterizer* m_rasterizer;
+ /** Converts Blender data files. */
+ KX_ISceneConverter* m_sceneconverter;
+ /** Network interface. */
+ NG_LoopBackNetworkDeviceInterface* m_networkdevice;
+ /** Sound device. */
+ SND_IAudioDevice* m_audiodevice;
+};
+
+
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Canvas.cpp b/source/gameengine/GamePlayer/ghost/GPG_Canvas.cpp
new file mode 100644
index 00000000000..da71d40acc0
--- /dev/null
+++ b/source/gameengine/GamePlayer/ghost/GPG_Canvas.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 *****
+ */
+
+#include "GPG_Canvas.h"
+
+#include <assert.h>
+
+#include "GHOST_ISystem.h"
+
+
+GPG_Canvas::GPG_Canvas(GHOST_IWindow* window)
+: GPC_Canvas(0, 0), m_window(window)
+{
+ if (m_window)
+ {
+ GHOST_Rect bnds;
+ m_window->getClientBounds(bnds);
+ this->Resize(bnds.getWidth(), bnds.getHeight());
+ }
+}
+
+
+GPG_Canvas::~GPG_Canvas(void)
+{
+}
+
+
+void GPG_Canvas::Init()
+{
+ if (m_window)
+ {
+ GHOST_TSuccess success;
+ success = m_window->setDrawingContextType(GHOST_kDrawingContextTypeOpenGL);
+ assert(success == GHOST_kSuccess);
+ }
+}
+
+void GPG_Canvas::SetMousePosition(int x, int y)
+{
+ GHOST_ISystem* system = GHOST_ISystem::getSystem();
+ if (system && m_window)
+ {
+ GHOST_TInt32 gx = (GHOST_TInt32)x;
+ GHOST_TInt32 gy = (GHOST_TInt32)y;
+ GHOST_TInt32 cx;
+ GHOST_TInt32 cy;
+ m_window->clientToScreen(gx, gy, cx, cy);
+ system->setCursorPosition(cx, cy);
+ }
+}
+
+
+void GPG_Canvas::SetMouseState(RAS_MouseState mousestate)
+{
+ if (m_window)
+ {
+ switch (mousestate)
+ {
+ case MOUSE_INVISIBLE:
+ m_window->setCursorVisibility(false);
+ break;
+ case MOUSE_WAIT:
+ m_window->setCursorShape(GHOST_kStandardCursorWait);
+ m_window->setCursorVisibility(true);
+ break;
+ case MOUSE_NORMAL:
+ m_window->setCursorShape(GHOST_kStandardCursorRightArrow);
+ m_window->setCursorVisibility(true);
+ break;
+ }
+ }
+}
+
+
+void GPG_Canvas::SwapBuffers()
+{
+ if (m_window)
+ {
+ m_window->swapBuffers();
+ }
+}
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Canvas.h b/source/gameengine/GamePlayer/ghost/GPG_Canvas.h
new file mode 100644
index 00000000000..12ac3701be8
--- /dev/null
+++ b/source/gameengine/GamePlayer/ghost/GPG_Canvas.h
@@ -0,0 +1,64 @@
+/**
+ * $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 _GPG_CANVAS_H_
+#define _GPG_CANVAS_H_
+
+#ifdef WIN32
+#pragma warning (disable : 4786)
+#endif // WIN32
+
+#include "GPC_Canvas.h"
+
+#include "GHOST_IWindow.h"
+
+
+class GPG_Canvas : public GPC_Canvas
+{
+protected:
+ /** GHOST window. */
+ GHOST_IWindow* m_window;
+
+public:
+ GPG_Canvas(GHOST_IWindow* window);
+ virtual ~GPG_Canvas(void);
+
+ virtual void Init(void);
+ virtual void SetMousePosition(int x, int y);
+ virtual void SetMouseState(RAS_MouseState mousestate);
+ virtual void SwapBuffers();
+
+ bool BeginDraw() { return true;};
+ void EndDraw() {};
+};
+
+#endif // _GPG_CANVAS_H_
diff --git a/source/gameengine/GamePlayer/ghost/GPG_KeyboardDevice.cpp b/source/gameengine/GamePlayer/ghost/GPG_KeyboardDevice.cpp
new file mode 100644
index 00000000000..7971a86bcbc
--- /dev/null
+++ b/source/gameengine/GamePlayer/ghost/GPG_KeyboardDevice.cpp
@@ -0,0 +1,156 @@
+/**
+ * $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 *****
+ * GHOST Blender Player keyboard device implementation.
+ */
+
+
+#include "GPG_KeyboardDevice.h"
+
+
+GPG_KeyboardDevice::GPG_KeyboardDevice(void)
+{
+ m_reverseKeyTranslateTable[GHOST_kKeyA ] = KX_AKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyB ] = KX_BKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyC ] = KX_CKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyD ] = KX_DKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyE ] = KX_EKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyF ] = KX_FKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyG ] = KX_GKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyH ] = KX_HKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyI ] = KX_IKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyJ ] = KX_JKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyK ] = KX_KKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyL ] = KX_LKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyM ] = KX_MKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyN ] = KX_NKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyO ] = KX_OKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyP ] = KX_PKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyQ ] = KX_QKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyR ] = KX_RKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyS ] = KX_SKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyT ] = KX_TKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyU ] = KX_UKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyV ] = KX_VKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyW ] = KX_WKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyX ] = KX_XKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyY ] = KX_YKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyZ ] = KX_ZKEY ;
+
+ m_reverseKeyTranslateTable[GHOST_kKey0 ] = KX_ZEROKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKey1 ] = KX_ONEKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKey2 ] = KX_TWOKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKey3 ] = KX_THREEKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKey4 ] = KX_FOURKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKey5 ] = KX_FIVEKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKey6 ] = KX_SIXKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKey7 ] = KX_SEVENKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKey8 ] = KX_EIGHTKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKey9 ] = KX_NINEKEY ;
+
+ // Middle keyboard area keys
+ m_reverseKeyTranslateTable[GHOST_kKeyPause ] = KX_PAUSEKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyInsert ] = KX_INSERTKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyDelete ] = KX_DELKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyHome ] = KX_HOMEKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyEnd ] = KX_ENDKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyUpPage ] = KX_PAGEUPKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyDownPage ] = KX_PAGEDOWNKEY ;
+
+ // Arrow keys
+ m_reverseKeyTranslateTable[GHOST_kKeyUpArrow ] = KX_UPARROWKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyDownArrow ] = KX_DOWNARROWKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyLeftArrow ] = KX_LEFTARROWKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyRightArrow ] = KX_RIGHTARROWKEY ;
+
+ // Function keys
+ m_reverseKeyTranslateTable[GHOST_kKeyF1 ] = KX_F1KEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyF2 ] = KX_F2KEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyF3 ] = KX_F3KEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyF4 ] = KX_F4KEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyF5 ] = KX_F5KEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyF6 ] = KX_F6KEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyF7 ] = KX_F7KEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyF8 ] = KX_F8KEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyF9 ] = KX_F9KEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyF10 ] = KX_F10KEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyF11 ] = KX_F11KEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyF12 ] = KX_F12KEY ;
+
+ // Numpad keys
+ m_reverseKeyTranslateTable[GHOST_kKeyNumpad0 ] = KX_PAD0 ;
+ m_reverseKeyTranslateTable[GHOST_kKeyNumpad1 ] = KX_PAD1 ;
+ m_reverseKeyTranslateTable[GHOST_kKeyNumpad2 ] = KX_PAD2 ;
+ m_reverseKeyTranslateTable[GHOST_kKeyNumpad3 ] = KX_PAD3 ;
+ m_reverseKeyTranslateTable[GHOST_kKeyNumpad4 ] = KX_PAD4 ;
+ m_reverseKeyTranslateTable[GHOST_kKeyNumpad5 ] = KX_PAD5 ;
+ m_reverseKeyTranslateTable[GHOST_kKeyNumpad6 ] = KX_PAD6 ;
+ m_reverseKeyTranslateTable[GHOST_kKeyNumpad7 ] = KX_PAD7 ;
+ m_reverseKeyTranslateTable[GHOST_kKeyNumpad8 ] = KX_PAD8 ;
+ m_reverseKeyTranslateTable[GHOST_kKeyNumpad9 ] = KX_PAD9 ;
+ m_reverseKeyTranslateTable[GHOST_kKeyNumpadAsterisk ] = KX_PADASTERKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyNumpadPlus ] = KX_PADPLUSKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyNumpadPeriod ] = KX_PADPERIOD ;
+ m_reverseKeyTranslateTable[GHOST_kKeyNumpadMinus ] = KX_PADMINUS ;
+ m_reverseKeyTranslateTable[GHOST_kKeyNumpadSlash ] = KX_PADSLASHKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyNumpadEnter ] = KX_PADENTER ;
+
+ // Other keys
+ m_reverseKeyTranslateTable[GHOST_kKeyCapsLock ] = KX_CAPSLOCKKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyEsc ] = KX_ESCKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyTab ] = KX_TABKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeySpace ] = KX_SPACEKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyEnter ] = KX_RETKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyBackSpace ] = KX_BACKSPACEKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeySemicolon ] = KX_SEMICOLONKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyPeriod ] = KX_PERIODKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyComma ] = KX_COMMAKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyQuote ] = KX_QUOTEKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyAccentGrave ] = KX_ACCENTGRAVEKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyMinus ] = KX_MINUSKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeySlash ] = KX_SLASHKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyBackslash ] = KX_BACKSLASHKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyEqual ] = KX_EQUALKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyLeftBracket ] = KX_LEFTBRACKETKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyRightBracket ] = KX_RIGHTBRACKETKEY ;
+
+ // Modifier keys.
+ m_reverseKeyTranslateTable[GHOST_kKeyLeftControl ] = KX_LEFTCTRLKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyRightControl ] = KX_RIGHTCTRLKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyLeftAlt ] = KX_LEFTALTKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyRightAlt ] = KX_RIGHTALTKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyLeftShift ] = KX_LEFTSHIFTKEY ;
+ m_reverseKeyTranslateTable[GHOST_kKeyRightShift ] = KX_RIGHTSHIFTKEY ;
+}
+
+
+GPG_KeyboardDevice::~GPG_KeyboardDevice(void)
+{
+}
diff --git a/source/gameengine/GamePlayer/ghost/GPG_KeyboardDevice.h b/source/gameengine/GamePlayer/ghost/GPG_KeyboardDevice.h
new file mode 100644
index 00000000000..0b77664f4e5
--- /dev/null
+++ b/source/gameengine/GamePlayer/ghost/GPG_KeyboardDevice.h
@@ -0,0 +1,57 @@
+/**
+ * $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 *****
+ * GHOST Blender Player keyboard device.
+ */
+
+#ifndef _GPG_KEYBOARDDEVICE_H_
+#define _GPG_KEYBOARDDEVICE_H_
+
+#ifdef WIN32
+#pragma warning (disable : 4786)
+#endif // WIN32
+
+#include "GHOST_Types.h"
+#include "GPC_KeyboardDevice.h"
+
+/**
+ * GHOST implementation of GPC_KeyboardDevice.
+ * The contructor fills the keyboard code translation map.
+ * Base class GPC_KeyboardDevice does the rest.
+ * @see SCA_IInputDevice
+ */
+class GPG_KeyboardDevice : public GPC_KeyboardDevice
+{
+public:
+ GPG_KeyboardDevice(void);
+ virtual ~GPG_KeyboardDevice(void);
+};
+
+#endif //_GPG_KEYBOARDDEVICE_H_
diff --git a/source/gameengine/GamePlayer/ghost/GPG_System.cpp b/source/gameengine/GamePlayer/ghost/GPG_System.cpp
new file mode 100644
index 00000000000..6084505bbba
--- /dev/null
+++ b/source/gameengine/GamePlayer/ghost/GPG_System.cpp
@@ -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 *****
+ * Blender Player system on GHOST.
+ */
+
+#include "GPG_System.h"
+
+#include <assert.h>
+
+#include "GHOST_ISystem.h"
+
+
+GPG_System::GPG_System(GHOST_ISystem* system)
+: m_system(system)
+{
+ assert(m_system);
+}
+
+
+double GPG_System::GetTimeInSeconds()
+{
+ GHOST_TInt64 millis = (GHOST_TInt64)m_system->getMilliSeconds();
+ double time = (double)millis;
+ time /= 1000.;
+ return time;
+}
+
+
diff --git a/source/gameengine/GamePlayer/ghost/GPG_System.h b/source/gameengine/GamePlayer/ghost/GPG_System.h
new file mode 100644
index 00000000000..f0bb186d370
--- /dev/null
+++ b/source/gameengine/GamePlayer/ghost/GPG_System.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 *****
+ * Blender Player system on GHOST.
+ */
+
+#ifndef _GPG_SYSTEM_H_
+#define _GPG_SYSTEM_H_
+
+#ifdef WIN32
+#pragma warning (disable:4786) // suppress stl-MSVC debug info warning
+#endif // WIN32
+
+#include "GPC_System.h"
+
+class GHOST_ISystem;
+
+class GPG_System : public GPC_System
+{
+ GHOST_ISystem* m_system;
+
+public:
+ GPG_System(GHOST_ISystem* system);
+
+ virtual double GetTimeInSeconds();
+};
+
+
+#endif // _GPG_SYSTEM_H_
diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
new file mode 100644
index 00000000000..df683cb91cf
--- /dev/null
+++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
@@ -0,0 +1,597 @@
+/**
+* $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 *****
+* Start up of the Blender Player on GHOST.
+*/
+
+#include <iostream>
+#include <math.h>
+
+#ifdef __linux__
+#ifdef __alpha__
+#include <signal.h>
+#endif /* __alpha__ */
+#endif /* __linux__ */
+
+#ifdef __APPLE__
+// Can't use Carbon right now because of double defined type ID (In Carbon.h and DNA_ID.h, sigh)
+//#include <Carbon/Carbon.h>
+//#include <CFBundle.h>
+#endif // __APPLE__
+#include "GEN_messaging.h"
+#include "KX_KetsjiEngine.h"
+
+/**********************************
+* Begin Blender include block
+**********************************/
+#ifdef __cplusplus
+extern "C"
+{
+#endif // __cplusplus
+
+#include "BLI_blenlib.h"
+#include "DNA_scene_types.h"
+#include "BLO_readfile.h"
+
+ int GHOST_HACK_getFirstFile(char buf[]);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+/**********************************
+* End Blender include block
+**********************************/
+
+#include "SYS_System.h"
+#include "GPG_Application.h"
+#include "GPC_PolygonMaterial.h"
+
+#include "GHOST_ISystem.h"
+#include "RAS_IRasterizer.h"
+
+#include "BKE_main.h"
+
+#ifdef WIN32
+#ifdef NDEBUG
+#include <windows.h>
+#include <wincon.h>
+#endif // NDEBUG
+#endif // WIN32
+
+const int kMinWindowWidth = 100;
+const int kMinWindowHeight = 100;
+
+void usage(char* program)
+{
+ char * consoleoption;
+#ifdef _WIN32
+ consoleoption = "-c ";
+#else
+ consoleoption = "";
+#endif
+
+ printf("usage: %s [-p l t w h] [-f fw fh fb ff] %s[-g gamengineoptions] "
+ "-s stereomode filename.blend\n", program, consoleoption);
+ printf(" -p: specify window position\n");
+ printf(" l = window left coordinate\n");
+ printf(" t = window top coordinate\n");
+ printf(" w = window width\n");
+ printf(" h = window height\n");
+ printf(" -f: start game in full screen mode\n");
+ printf(" fw = full screen mode pixel width\n");
+ printf(" fh = full screen mode pixel height\n");
+ printf(" fb = full screen mode bits per pixel\n");
+ printf(" ff = full screen mode frequency\n");
+ printf(" -s: start player in stereo\n");
+ printf(" stereomode = hwpageflip or syncdoubling depending on the type of stereo you want\n");
+#ifdef _WIN32
+ printf(" -c: keep console window open\n");
+#endif
+ printf("\n");
+ printf("example: %s -p 10 10 320 200 -g noaudio c:\\loadtest.blend\n", program);
+}
+
+char *get_filename(int argc, char **argv) {
+#ifdef __APPLE__
+/* On Mac we park the game file (called game.blend) in the application bundle.
+* The executable is located in the bundle as well.
+* Therefore, we can locate the game relative to the executable.
+ */
+ int srclen = ::strlen(argv[0]);
+ int len = 0;
+ char *filename = NULL;
+
+ if (argc > 1) {
+ if (BLI_exists(argv[argc-1])) {
+ len = ::strlen(argv[argc-1]);
+ filename = new char [len + 1];
+ ::strcpy(filename, argv[argc-1]);
+ return(filename);
+ }
+ if (::strncmp(argv[argc-1], "-psn_", 5)==0) {
+ static char firstfilebuf[512];
+ if (GHOST_HACK_getFirstFile(firstfilebuf)) {
+ len = ::strlen(firstfilebuf);
+ filename = new char [len + 1];
+ ::strcpy(filename, firstfilebuf);
+ return(filename);
+ }
+ }
+ }
+
+ srclen -= ::strlen("MacOS/blenderplayer");
+ if (srclen > 0) {
+ len = srclen + ::strlen("Resources/game.blend");
+ filename = new char [len + 1];
+ ::strcpy(filename, argv[0]);
+ ::strcpy(filename + srclen, "Resources/game.blend");
+ //::printf("looking for file: %s\n", filename);
+
+ if (BLI_exists(filename)) {
+ return (filename);
+ }
+ }
+
+ return(NULL);
+#else
+ return (argc>1)?argv[argc-1]:NULL;
+#endif // !_APPLE
+}
+
+BlendFileData *load_game_data(char *progname, char *filename) {
+ BlendReadError error;
+ BlendFileData *bfd;
+
+ /* try to load ourself, will only work if we are a runtime */
+ bfd= BLO_read_from_file(progname, &error);
+
+ if (!bfd) {
+ if (filename) {
+ bfd= BLO_read_from_file(filename, &error);
+ }
+ }
+
+ if (bfd && bfd->type == BLENFILETYPE_BLEND) {
+ BLO_blendfiledata_free(bfd);
+ bfd = NULL;
+ error = BRE_NOT_A_PUBFILE;
+ }
+
+ if (!bfd) {
+ if (filename) {
+ printf("Loading %s failed: %s\n", filename, BLO_bre_as_string(error));
+ }
+ }
+
+ return bfd;
+}
+
+int main(int argc, char** argv)
+{
+ int i;
+ bool error = false;
+ SYS_SystemHandle syshandle = SYS_GetSystem();
+ bool fullScreen = false;
+ bool fullScreenParFound = false;
+ bool windowParFound = false;
+ bool closeConsole = true;
+ int stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
+ bool stereoWindow = false;
+ bool stereoParFound = false;
+ int windowLeft = 100;
+ int windowTop = 100;
+ int windowWidth = 640;
+ int windowHeight = 480;
+ int fullScreenWidth = 640;
+ int fullScreenHeight= 480;
+ int fullScreenBpp = 16;
+ int fullScreenFrequency = 60;
+
+#ifdef __linux__
+#ifdef __alpha__
+ signal (SIGFPE, SIG_IGN);
+#endif /* __alpha__ */
+#endif /* __linux__ */
+
+#ifdef __APPLE__
+ // Can't use Carbon right now because of double defined type ID (In Carbon.h and DNA_ID.h, sigh)
+ /*
+ IBNibRef nibRef;
+ WindowRef window;
+ OSStatus err;
+
+ // Create a Nib reference passing the name of the nib file (without the .nib extension)
+ // CreateNibReference only searches into the application bundle.
+ err = ::CreateNibReference(CFSTR("main"), &nibRef);
+ if (err) return -1;
+
+ // Once the nib reference is created, set the menu bar. "MainMenu" is the name of the menu bar
+ // object. This name is set in InterfaceBuilder when the nib is created.
+ err = ::SetMenuBarFromNib(nibRef, CFSTR("MenuBar"));
+ if (err) return -1;
+
+ // We don't need the nib reference anymore.
+ ::DisposeNibReference(nibRef);
+ */
+#endif // __APPLE__
+
+ GEN_init_messaging_system();
+
+ // Parse command line options
+#ifndef NDEBUG
+ printf("argv[0] = '%s'\n", argv[0]);
+#endif
+ for (i = 1; (i < argc) && !error; i++)
+ {
+#ifndef NDEBUG
+ printf("argv[%d] = '%s'\n", i, argv[i]);
+#endif
+
+ if (argv[i][0] == '-')
+ {
+ switch (argv[i][1])
+ {
+ case 'g':
+ // Parse game options
+ {
+ i++;
+ if (i < argc)
+ {
+ char* paramname = argv[i];
+ // Check for single value versus assignment
+ if (i+1 < argc && (*(argv[i+1]) == '='))
+ {
+ i++;
+ if (i + 1 < argc)
+ {
+ i++;
+ // Assignment
+ SYS_WriteCommandLineString(syshandle, paramname, argv[i]);
+ }
+ else
+ {
+ error = true;
+ printf("error: argument assignment %s without value.\n", paramname);
+ }
+ }
+ else
+ {
+ SYS_WriteCommandLineInt(syshandle, argv[i], 1);
+ }
+ }
+ }
+ break;
+
+ case 'p':
+ // Parse window position and size options
+ if (argv[i][2] == 0) {
+ i++;
+ if ((i + 4) < argc)
+ {
+ windowLeft = atoi(argv[i++]);
+ windowTop = atoi(argv[i++]);
+ windowWidth = atoi(argv[i++]);
+ windowHeight = atoi(argv[i]);
+ windowParFound = true;
+ }
+ else
+ {
+ error = true;
+ printf("error: too few options for window argument.\n");
+ }
+ }
+ break;
+
+ case 'f':
+ // Parse window position and size options
+ {
+ fullScreen = true;
+ i++;
+ if ((i + 4) < argc)
+ {
+ fullScreenWidth = atoi(argv[i++]);
+ fullScreenHeight = atoi(argv[i++]);
+ fullScreenBpp = atoi(argv[i++]);
+ fullScreenFrequency = atoi(argv[i]);
+ fullScreenParFound = true;
+ }
+ else
+ {
+ error = true;
+ printf("error: too few options for fullscreen argument.\n");
+ }
+ }
+ break;
+ case 'c':
+ i++;
+ closeConsole = false;
+ break;
+ case 's': // stereo
+ i++;
+ if ((i + 1) < argc)
+ {
+ if(!strcmp(argv[i], "nostereo")) // ok, redundant but clear
+ stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
+
+ // only the hardware pageflip method needs a stereo window
+ if(!strcmp(argv[i], "hwpageflip")) {
+ stereomode = RAS_IRasterizer::RAS_STEREO_QUADBUFFERED;
+ stereoWindow = true;
+ }
+ if(!strcmp(argv[i], "syncdoubling"))
+ stereomode = RAS_IRasterizer::RAS_STEREO_ABOVEBELOW;
+#if 0
+ // future stuff
+ if(strcmp(argv[i], "stencil")
+ stereomode = RAS_STEREO_STENCIL;
+#endif
+
+ i++;
+ stereoParFound = true;
+ }
+ else
+ {
+ error = true;
+ printf("error: too few options for stereo argument.\n");
+ }
+ break;
+ }
+ }
+ else
+ {
+ }
+ }
+
+ if ((windowWidth < kMinWindowWidth) || (windowHeight < kMinWindowHeight))
+ {
+ error = true;
+ printf("error: window size too small.\n");
+ }
+
+ if (error)
+ {
+ usage(argv[0]);
+ }
+ else
+ {
+#ifdef __APPLE__
+ //SYS_WriteCommandLineInt(syshandle, "show_framerate", 1);
+ SYS_WriteCommandLineInt(syshandle, "nomipmap", 1);
+ //fullScreen = false; // Can't use full screen
+#endif
+ if (SYS_GetCommandLineInt(syshandle, "nomipmap", 0))
+ {
+ GPC_PolygonMaterial::SetMipMappingEnabled(0);
+ }
+
+ // Create the system
+ if (GHOST_ISystem::createSystem() == GHOST_kSuccess)
+ {
+ GHOST_ISystem* system = GHOST_ISystem::getSystem();
+ assertd(system);
+
+ // process first batch of events. If the user
+ // drops a file on top off the blenderplayer icon, we
+ // recieve an event with the filename
+
+ system->processEvents(0);
+
+ // this bracket is needed for app (see below) to get out
+ // of scope before GHOST_ISystem::disposeSystem() is called.
+ {
+ int exitcode = KX_EXIT_REQUEST_NO_REQUEST;
+ STR_String exitstring = "";
+ GPG_Application app(system, NULL, exitstring);
+ bool firstTimeRunning = true;
+
+ do
+ {
+ // Read the Blender file
+ char *filename = get_filename(argc, argv);
+ char *titlename;
+ char pathname[160];
+ BlendFileData *bfd;
+
+ // if we got an exitcode 3 (KX_EXIT_REQUEST_START_OTHER_GAME) load a different file
+ if (exitcode == KX_EXIT_REQUEST_START_OTHER_GAME)
+ {
+ char basedpath[160];
+
+ // base the actuator filename with respect
+ // to the original file working directory
+ strcpy(basedpath, exitstring.Ptr());
+ BLI_convertstringcode(basedpath, pathname, 0);
+
+ bfd = load_game_data(NULL, basedpath);
+ }
+ else
+ {
+ bfd = load_game_data(argv[0], filename);
+ }
+
+ //::printf("game data loaded from %s\n", filename);
+
+ if (!bfd) {
+ usage(argv[0]);
+ error = true;
+ exitcode = KX_EXIT_REQUEST_QUIT_GAME;
+ }
+ else
+ {
+#ifdef WIN32
+#ifdef NDEBUG
+ if (closeConsole)
+ {
+ ::FreeConsole(); // Close a console window
+ }
+#endif // NDEBUG
+#endif // WIN32
+ Main *maggie = bfd->main;
+ Scene *scene = bfd->curscene;
+ strcpy (pathname, maggie->name);
+ char *startscenename = scene->id.name + 2;
+
+ titlename = maggie->name;
+
+ // Check whether the game should be displayed full-screen
+ if ((!fullScreenParFound) && (!windowParFound))
+ {
+ // Only use file settings when command line did not override
+ if (scene->r.fullscreen) {
+ //printf("fullscreen option found in Blender file\n");
+ fullScreen = true;
+ fullScreenWidth= scene->r.xplay;
+ fullScreenHeight= scene->r.yplay;
+ fullScreenFrequency= scene->r.freqplay;
+ fullScreenBpp = scene->r.depth;
+ }
+ else
+ {
+ fullScreen = false;
+ windowWidth = scene->r.xplay;
+ windowHeight = scene->r.yplay;
+ }
+ }
+
+
+ // Check whether the game should be displayed in stereo
+ if (!stereoParFound)
+ {
+ if(scene->r.stereomode == RAS_IRasterizer::RAS_STEREO_NOSTEREO) // ok, redundant but clear
+ stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
+
+ // only the hardware pageflip method needs a stereo window
+ if(scene->r.stereomode == RAS_IRasterizer::RAS_STEREO_QUADBUFFERED) {
+ stereomode = RAS_IRasterizer::RAS_STEREO_QUADBUFFERED;
+ stereoWindow = true;
+ }
+ if(scene->r.stereomode == RAS_IRasterizer::RAS_STEREO_ABOVEBELOW)
+ stereomode = RAS_IRasterizer::RAS_STEREO_ABOVEBELOW;
+#if 0
+ // future stuff
+ if(scene->r.stereomode == RAS_IRasterizer::RAS_STEREO_STENCIL)
+ stereomode = RAS_STEREO_STENCIL;
+#endif
+ }
+
+ // GPG_Application app (system, maggie, startscenename);
+ app.SetGameEngineData(maggie, startscenename);
+
+ if (firstTimeRunning)
+ {
+ firstTimeRunning = false;
+
+ if (fullScreen)
+ {
+ app.startFullScreen(fullScreenWidth, fullScreenHeight, fullScreenBpp, fullScreenFrequency,
+ stereoWindow, stereomode);
+ }
+ else
+ {
+#ifdef __APPLE__
+ // on Mac's we'll show the executable name instead of the 'game.blend' name
+ char tempname[1024], *appstring;
+ ::strcpy(tempname, titlename);
+
+ appstring = strstr(tempname, ".app/");
+ if (appstring) {
+ appstring[2] = 0;
+ titlename = &tempname[0];
+ }
+#endif
+ // Strip the path so that we have the name of the game file
+ STR_String path = titlename;
+#ifndef WIN32
+ vector<STR_String> parts = path.Explode('/');
+#else // WIN32
+ vector<STR_String> parts = path.Explode('\\');
+#endif // WIN32
+ STR_String title;
+ if (parts.size())
+ {
+ title = parts[parts.size()-1];
+ parts = title.Explode('.');
+ if (parts.size() > 1)
+ {
+ title = parts[0];
+ }
+ }
+ else
+ {
+ title = "blenderplayer";
+ }
+ app.startWindow(title, windowLeft, windowTop, windowWidth, windowHeight,
+ stereoWindow, stereomode);
+ }
+ }
+ else
+ {
+ app.StartGameEngine(stereomode);
+ exitcode = KX_EXIT_REQUEST_NO_REQUEST;
+ }
+
+ // Add the application as event consumer
+ system->addEventConsumer(&app);
+
+ // Enter main loop
+ bool run = true;
+ while (run)
+ {
+ system->processEvents(true);
+ system->dispatchEvents();
+ if (exitcode = app.getExitRequested())
+ {
+ run = false;
+ exitstring = app.getExitString();
+ }
+ }
+ app.StopGameEngine();
+ BLO_blendfiledata_free(bfd);
+
+#ifdef __APPLE__
+ if (filename) {
+ delete [] filename;
+ }
+#endif // __APPLE__
+ }
+ } while (exitcode == KX_EXIT_REQUEST_RESTART_GAME || exitcode == KX_EXIT_REQUEST_START_OTHER_GAME);
+ }
+ // Dispose the system
+ GHOST_ISystem::disposeSystem();
+ } else {
+ error = true;
+ printf("error: couldn't create a system.\n");
+ }
+ }
+
+ return error ? -1 : 0;
+}
+
+
diff --git a/source/gameengine/GamePlayer/ghost/Makefile b/source/gameengine/GamePlayer/ghost/Makefile
new file mode 100644
index 00000000000..7e9735a4bd8
--- /dev/null
+++ b/source/gameengine/GamePlayer/ghost/Makefile
@@ -0,0 +1,82 @@
+#
+# $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 *****
+#
+# Makefile for GHOST game player
+
+LIBNAME = ghost
+DIR = $(OCGDIR)/gameengine/GamePlayer/ghost
+
+include nan_compile.mk
+
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+# OpenGL header files
+CPPFLAGS += -I$(OPENGL_HEADERS)
+CPPFLAGS += -I$(NAN_STRING)/include
+CPPFLAGS += -I$(NAN_BMFONT)/include
+
+CPPFLAGS += -I../../GamePlayer/common
+
+# Game Engine includes
+CPPFLAGS += -I../../Converter
+CPPFLAGS += -I../../Expressions
+CPPFLAGS += -I../../GameLogic
+CPPFLAGS += -I../../Ketsji
+CPPFLAGS += -I../../Ketsji/KXNetwork
+CPPFLAGS += -I../../Network
+CPPFLAGS += -I../../Network/LoopBackNetwork
+CPPFLAGS += -I../../Rasterizer
+CPPFLAGS += -I../../Rasterizer/RAS_OpenGLRasterizer
+CPPFLAGS += -I../../SceneGraph
+CPPFLAGS += -I../../SoundSystem
+CPPFLAGS += -I../../SoundSystem/SND_OpenAL
+
+# Sumo
+CPPFLAGS += -I../../../sumo/Fuzzics/include
+CPPFLAGS += -I../../../sumo/include
+CPPFLAGS += -I$(NAN_MOTO)/include
+
+# Blender includes
+CPPFLAGS += -I../../../blender/blenkernel
+CPPFLAGS += -I../../../blender/blenlib
+CPPFLAGS += -I../../../blender/blenloader
+CPPFLAGS += -I../../../blender/imbuf
+CPPFLAGS += -I../../../blender/makesdna
+CPPFLAGS += -I../../../blender/readblenfile
+
+# kernel? GEN? stuff
+CPPFLAGS += -I../../../kernel/gen_system
+CPPFLAGS += -I../../../kernel/gen_messaging
+
+CPPFLAGS += -I$(NAN_STRING)/include
+CPPFLAGS += -I$(NAN_GHOST)/include
+CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
+
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp
new file mode 100644
index 00000000000..99aa798cfa5
--- /dev/null
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp
@@ -0,0 +1,92 @@
+/**
+ * $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 *****
+ * Ketsji Logic Extenstion: Network Event Manager generic implementation
+ */
+
+// Ketsji specific sensor part
+#include "SCA_ISensor.h"
+
+// Ketsji specific network part
+#include "KX_NetworkEventManager.h"
+
+// Network module specific
+#include "NG_NetworkDeviceInterface.h"
+#include "NG_NetworkMessage.h"
+#include "NG_NetworkObject.h"
+
+KX_NetworkEventManager::KX_NetworkEventManager(class SCA_LogicManager*
+logicmgr, class NG_NetworkDeviceInterface *ndi) :
+SCA_EventManager(NETWORK_EVENTMGR), m_logicmgr(logicmgr), m_ndi(ndi)
+{
+ //printf("KX_NetworkEventManager constructor\n");
+}
+
+KX_NetworkEventManager::~KX_NetworkEventManager()
+{
+ //printf("KX_NetworkEventManager destructor\n");
+}
+
+void KX_NetworkEventManager::RegisterSensor(class SCA_ISensor* sensor)
+{
+ //printf("KX_NetworkEventManager RegisterSensor\n");
+ m_sensors.push_back(sensor);
+}
+
+void KX_NetworkEventManager::RemoveSensor(class SCA_ISensor* sensor)
+{
+ //printf("KX_NetworkEventManager RemoveSensor\n");
+ // Network specific RemoveSensor stuff goes here
+
+ // parent
+ SCA_EventManager::RemoveSensor(sensor);
+}
+
+void KX_NetworkEventManager::NextFrame(double curtime, double deltatime)
+{
+// printf("KX_NetworkEventManager::proceed %.2f - %.2f\n", curtime, deltatime);
+ // each frame, the logicmanager will call the network
+ // eventmanager to look for network events, and process it's
+ // 'network' sensors
+ vector<class SCA_ISensor*>::iterator it;
+
+ for (it = m_sensors.begin(); !(it==m_sensors.end()); it++) {
+// printf("KX_NetworkEventManager::proceed sensor %.2f\n", curtime);
+ // process queue
+ (*it)->Activate(m_logicmgr, NULL);
+ }
+
+ // now a list of triggerer sensors has been built
+}
+
+void KX_NetworkEventManager::EndFrame()
+{
+}
+
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h
new file mode 100644
index 00000000000..521a3b4d030
--- /dev/null
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h
@@ -0,0 +1,59 @@
+/**
+ * $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 *****
+ * Ketsji Logic Extenstion: Network Event Manager class
+ */
+#ifndef KX_NETWORK_EVENTMANAGER_H
+#define KX_NETWORK_EVENTMANAGER_H
+
+#include "SCA_EventManager.h"
+
+class KX_NetworkEventManager : public SCA_EventManager
+{
+ class SCA_LogicManager* m_logicmgr;
+ class NG_NetworkDeviceInterface* m_ndi;
+
+public:
+ KX_NetworkEventManager(class SCA_LogicManager* logicmgr,
+ class NG_NetworkDeviceInterface *ndi);
+ virtual ~KX_NetworkEventManager ();
+
+ virtual void RegisterSensor(class SCA_ISensor* sensor);
+ virtual void RemoveSensor(class SCA_ISensor* sensor);
+
+ virtual void NextFrame(double curtime, double deltatime);
+ virtual void EndFrame();
+
+ SCA_LogicManager* GetLogicManager() { return m_logicmgr; }
+ class NG_NetworkDeviceInterface* GetNetworkDevice() {
+ return m_ndi; }
+};
+
+#endif //KX_NETWORK_EVENTMANAGER_H
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp
new file mode 100644
index 00000000000..1eb85d60b29
--- /dev/null
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp
@@ -0,0 +1,208 @@
+/**
+ * $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 *****
+ * Ketsji Logic Extenstion: Network Message Actuator generic implementation
+ */
+
+#include "NG_NetworkScene.h"
+#include "KX_NetworkMessageActuator.h"
+
+KX_NetworkMessageActuator::KX_NetworkMessageActuator(
+ SCA_IObject* gameobj, // the actuator controlling object
+ NG_NetworkScene* networkscene, // needed for replication
+ const STR_String &toPropName,
+ const STR_String &subject,
+ int bodyType,
+ const STR_String &body,
+ PyTypeObject* T) :
+ SCA_IActuator(gameobj,T),
+ m_networkscene(networkscene),
+ m_toPropName(toPropName),
+ m_subject(subject),
+ m_bodyType(bodyType),
+ m_body(body)
+{
+}
+
+KX_NetworkMessageActuator::~KX_NetworkMessageActuator()
+{
+}
+
+// returns true if the actuators needs to be running over several frames
+bool KX_NetworkMessageActuator::Update(double curtime, double deltatime)
+{
+ //printf("update messageactuator\n");
+ bool bNegativeEvent = IsNegativeEvent();
+ RemoveAllEvents();
+
+ if (bNegativeEvent) {
+ return false; // do nothing on negative events
+ //printf("messageactuator false event\n");
+ }
+ //printf("messageactuator true event\n");
+
+ if (m_bodyType == 1) // ACT_MESG_PROP in DNA_actuator_types.h
+ {
+ m_networkscene->SendMessage(
+ m_toPropName,
+ GetParent()->GetName(),
+ m_subject,
+ GetParent()->GetPropertyText(m_body,""));
+ } else
+ {
+ m_networkscene->SendMessage(
+ m_toPropName,
+ GetParent()->GetName(),
+ m_subject,
+ m_body);
+ }
+ return false;
+}
+
+CValue* KX_NetworkMessageActuator::GetReplica()
+{
+ KX_NetworkMessageActuator* replica =
+ new KX_NetworkMessageActuator(*this);
+ replica->ProcessReplica();
+
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+/* -------------------------------------------------------------------- */
+/* Python interface --------------------------------------------------- */
+/* -------------------------------------------------------------------- */
+
+/* Integration hooks -------------------------------------------------- */
+PyTypeObject KX_NetworkMessageActuator::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "KX_NetworkMessageActuator",
+ sizeof(KX_NetworkMessageActuator),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject KX_NetworkMessageActuator::Parents[] = {
+ &KX_NetworkMessageActuator::Type,
+ &SCA_IActuator::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef KX_NetworkMessageActuator::Methods[] = {
+ {"setToPropName", (PyCFunction)
+ KX_NetworkMessageActuator::sPySetToPropName, METH_VARARGS},
+ {"setSubject", (PyCFunction)
+ KX_NetworkMessageActuator::sPySetSubject, METH_VARARGS},
+ {"setBodyType", (PyCFunction)
+ KX_NetworkMessageActuator::sPySetBodyType, METH_VARARGS},
+ {"setBody", (PyCFunction)
+ KX_NetworkMessageActuator::sPySetBody, METH_VARARGS},
+ {NULL,NULL} // Sentinel
+};
+
+PyObject* KX_NetworkMessageActuator::_getattr(char* attr) {
+ _getattr_up(SCA_IActuator);
+}
+
+// 1. SetToPropName
+PyObject* KX_NetworkMessageActuator::PySetToPropName(
+ PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ char* ToPropName;
+
+ if (PyArg_ParseTuple(args, "s", &ToPropName)) {
+ m_toPropName = ToPropName;
+ }
+
+ Py_Return;
+}
+
+// 2. SetSubject
+PyObject* KX_NetworkMessageActuator::PySetSubject(
+ PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ char* Subject;
+
+ if (PyArg_ParseTuple(args, "s", &Subject)) {
+ m_subject = Subject;
+ }
+
+ Py_Return;
+}
+
+// 3. SetBodyType
+PyObject* KX_NetworkMessageActuator::PySetBodyType(
+ PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ int BodyType;
+
+ if (PyArg_ParseTuple(args, "i", &BodyType)) {
+ m_bodyType = BodyType;
+ }
+
+ Py_Return;
+}
+
+// 4. SetBody
+PyObject* KX_NetworkMessageActuator::PySetBody(
+ PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ char* Body;
+
+ if (PyArg_ParseTuple(args, "s", &Body)) {
+ m_body = Body;
+ }
+
+ Py_Return;
+}
+
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h
new file mode 100644
index 00000000000..2ab4319821c
--- /dev/null
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h
@@ -0,0 +1,77 @@
+/**
+ * $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 *****
+ * Ketsji Logic Extenstion: Network Message Actuator class
+ */
+#ifndef __KX_NETWORKMESSAGEACTUATOR_H
+#define __KX_NETWORKMESSAGEACTUATOR_H
+
+#include "STR_String.h"
+
+#include "SCA_IActuator.h"
+
+#include "NG_NetworkMessage.h"
+
+class KX_NetworkMessageActuator : public SCA_IActuator
+{
+ Py_Header;
+ bool m_lastEvent;
+ class NG_NetworkScene* m_networkscene; // needed for replication
+ STR_String m_toPropName;
+ STR_String m_subject;
+ int m_bodyType;
+ STR_String m_body;
+public:
+ KX_NetworkMessageActuator(
+ SCA_IObject* gameobj,
+ NG_NetworkScene* networkscene,
+ const STR_String &toPropName,
+ const STR_String &subject,
+ int bodyType,
+ const STR_String &body,
+ PyTypeObject* T=&Type);
+ virtual ~KX_NetworkMessageActuator();
+
+ virtual bool Update(double curtime, double deltatime);
+ virtual CValue* GetReplica();
+
+ /* ------------------------------------------------------------ */
+ /* Python interface ------------------------------------------- */
+ /* ------------------------------------------------------------ */
+
+ virtual PyObject* _getattr(char *attr);
+
+ KX_PYMETHOD(KX_NetworkMessageActuator, SetToPropName);
+ KX_PYMETHOD(KX_NetworkMessageActuator, SetSubject);
+ KX_PYMETHOD(KX_NetworkMessageActuator, SetBodyType);
+ KX_PYMETHOD(KX_NetworkMessageActuator, SetBody);
+
+};
+#endif //__KX_NETWORKMESSAGEACTUATOR_H
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp
new file mode 100644
index 00000000000..1eeceb55469
--- /dev/null
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp
@@ -0,0 +1,258 @@
+/**
+ * $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 *****
+ * Ketsji Logic Extenstion: Network Message Sensor generic implementation
+ */
+
+#include "KX_NetworkMessageSensor.h"
+#include "KX_NetworkEventManager.h"
+#include "NG_NetworkMessage.h"
+#include "NG_NetworkScene.h"
+#include "NG_NetworkObject.h"
+#include "SCA_IObject.h"
+#include "InputParser.h"
+#include "ListValue.h"
+#include "StringValue.h"
+
+#ifdef NAN_NET_DEBUG
+ #include <iostream>
+#endif
+
+KX_NetworkMessageSensor::KX_NetworkMessageSensor(
+ class KX_NetworkEventManager* eventmgr, // our eventmanager
+ class NG_NetworkScene *NetworkScene, // our scene
+ SCA_IObject* gameobj, // the sensor controlling object
+ const STR_String &subject,
+ PyTypeObject* T
+) :
+ SCA_ISensor(gameobj,eventmgr,T),
+ m_Networkeventmgr(eventmgr),
+ m_NetworkScene(NetworkScene),
+ m_subject(subject),
+ m_frame_message_count (0),
+ m_IsUp(false),
+ m_BodyList(NULL)
+{
+}
+
+KX_NetworkMessageSensor::~KX_NetworkMessageSensor()
+{
+}
+
+CValue* KX_NetworkMessageSensor::GetReplica() {
+ // This is the standard sensor implementation of GetReplica
+ // There may be more network message sensor specific stuff to do here.
+ CValue* replica = new KX_NetworkMessageSensor(*this);
+
+ if (replica == NULL) return NULL;
+
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+// Return true only for flank (UP and DOWN)
+bool KX_NetworkMessageSensor::Evaluate(CValue* event)
+{
+ bool result = false;
+ bool WasUp = m_IsUp;
+
+ m_IsUp = false;
+ if (m_BodyList) {
+ m_BodyList->Release();
+ m_BodyList = NULL;
+ }
+
+ STR_String toname=GetParent()->GetName();
+ STR_String subject = this->m_subject;
+
+ vector<NG_NetworkMessage*> messages =
+ m_NetworkScene->FindMessages(toname,"",subject,true);
+
+ m_frame_message_count = messages.size();
+
+ if (!messages.empty()) {
+#ifdef NAN_NET_DEBUG
+ printf("KX_NetworkMessageSensor found one or more messages\n");
+#endif
+ m_IsUp = true;
+ m_BodyList = new CListValue();
+ }
+
+ vector<NG_NetworkMessage*>::iterator mesit;
+ for (mesit=messages.begin();mesit!=messages.end();mesit++)
+ {
+ // save the body
+ STR_String body = (*mesit)->GetMessageText();
+#ifdef NAN_NET_DEBUG
+ if (body) {
+ cout << "body [" << body << "]\n";
+ }
+#endif
+ m_BodyList->Add(new CStringValue(body,"body"));
+
+ // free the message
+ (*mesit)->Release();
+ }
+ messages.clear();
+
+ result = (WasUp != m_IsUp);
+
+ // Return true if the message received state has changed.
+ return result;
+}
+
+// return true for being up (no flank needed)
+bool KX_NetworkMessageSensor::IsPositiveTrigger()
+{
+// printf("KX_NetworkMessageSensor IsPositiveTrigger\n");
+ return m_IsUp;
+}
+
+/* --------------------------------------------------------------------- */
+/* Python interface ---------------------------------------------------- */
+/* --------------------------------------------------------------------- */
+
+/* Integration hooks --------------------------------------------------- */
+PyTypeObject KX_NetworkMessageSensor::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "KX_NetworkMessageSensor",
+ sizeof(KX_NetworkMessageSensor),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject KX_NetworkMessageSensor::Parents[] = {
+ &KX_NetworkMessageSensor::Type,
+ &SCA_ISensor::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef KX_NetworkMessageSensor::Methods[] = {
+ {"setSubjectFilterText", (PyCFunction)
+ KX_NetworkMessageSensor::sPySetSubjectFilterText, METH_VARARGS,
+ SetSubjectFilterText_doc},
+ {"getFrameMessageCount", (PyCFunction)
+ KX_NetworkMessageSensor::sPyGetFrameMessageCount, METH_VARARGS,
+ GetFrameMessageCount_doc},
+ {"getBodies", (PyCFunction)
+ KX_NetworkMessageSensor::sPyGetBodies, METH_VARARGS,
+ GetBodies_doc},
+ {"getSubject", (PyCFunction)
+ KX_NetworkMessageSensor::sPyGetSubject, METH_VARARGS,
+ GetSubject_doc},
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* KX_NetworkMessageSensor::_getattr(char* attr) {
+ _getattr_up(SCA_ISensor); // implicit return!
+}
+
+// 1. Set the message subject that this sensor listens for
+char KX_NetworkMessageSensor::SetSubjectFilterText_doc[] =
+"\tsetSubjectFilterText(value)\n"
+"\tChange the message subject text that this sensor is listening to.\n";
+
+PyObject* KX_NetworkMessageSensor::PySetSubjectFilterText(
+ PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ char* Subject;
+
+ if (PyArg_ParseTuple(args, "s", &Subject))
+ {
+ m_subject = Subject;
+ }
+
+ Py_Return;
+}
+
+// 2. Get the number of messages received since the last frame
+char KX_NetworkMessageSensor::GetFrameMessageCount_doc[] =
+"\tgetFrameMessageCount()\n"
+"\tGet the number of messages received since the last frame.\n";
+
+PyObject* KX_NetworkMessageSensor::PyGetFrameMessageCount(
+ PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ return PyInt_FromLong(long(m_frame_message_count));
+}
+
+// 3. Get the message bodies
+char KX_NetworkMessageSensor::GetBodies_doc[] =
+"\tgetBodies()\n"
+"\tGet the list of message bodies.\n";
+
+PyObject* KX_NetworkMessageSensor::PyGetBodies(
+ PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ if (m_BodyList) {
+ return ((PyObject*) m_BodyList->AddRef());
+ }
+
+ Py_Return;
+}
+
+// 4. Get the message subject
+char KX_NetworkMessageSensor::GetSubject_doc[] =
+"\tgetSubject()\n"
+"\tGet the subject of the message.\n";
+
+PyObject* KX_NetworkMessageSensor::PyGetSubject(
+ PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ if (m_subject) {
+ return PyString_FromString(m_subject);
+ }
+
+ Py_Return;
+}
+
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h
new file mode 100644
index 00000000000..2c30befd883
--- /dev/null
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h
@@ -0,0 +1,85 @@
+/**
+ * $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 *****
+ * Ketsji Logic Extenstion: Network Message Sensor class
+ */
+#ifndef __KX_NETWORKMESSAGE_SENSOR_H
+#define __KX_NETWORKMESSAGE_SENSOR_H
+
+#include "SCA_ISensor.h"
+
+class KX_NetworkEventManager;
+class NG_NetworkScene;
+
+class KX_NetworkMessageSensor : public SCA_ISensor
+{
+ // note: Py_Header MUST BE the first listed here
+ Py_Header;
+ KX_NetworkEventManager *m_Networkeventmgr;
+ NG_NetworkScene *m_NetworkScene;
+
+ // The subject we filter on.
+ STR_String m_subject;
+
+ // The number of messages caught since the last frame.
+ int m_frame_message_count;
+
+ bool m_IsUp;
+
+ class CListValue* m_BodyList;
+public:
+ KX_NetworkMessageSensor(
+ KX_NetworkEventManager* eventmgr, // our eventmanager
+ NG_NetworkScene *NetworkScene, // our scene
+ SCA_IObject* gameobj, // the sensor controlling object
+ const STR_String &subject,
+ PyTypeObject* T=&Type
+ );
+ virtual ~KX_NetworkMessageSensor();
+
+ virtual CValue* GetReplica();
+ virtual bool Evaluate(CValue* event);
+ virtual bool IsPositiveTrigger();
+ void EndFrame();
+
+ /* ------------------------------------------------------------- */
+ /* Python interface -------------------------------------------- */
+ /* ------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(char *attr);
+
+ KX_PYMETHOD_DOC(KX_NetworkMessageSensor, SetSubjectFilterText);
+ KX_PYMETHOD_DOC(KX_NetworkMessageSensor, GetFrameMessageCount);
+ KX_PYMETHOD_DOC(KX_NetworkMessageSensor, GetBodies);
+ KX_PYMETHOD_DOC(KX_NetworkMessageSensor, GetSubject);
+
+
+};
+#endif //__KX_NETWORKMESSAGE_SENSOR_H
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkObjectActuator.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkObjectActuator.cpp
new file mode 100644
index 00000000000..a7800aea8c8
--- /dev/null
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkObjectActuator.cpp
@@ -0,0 +1,31 @@
+/**
+ * $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 *****
+ */
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkObjectActuator.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkObjectActuator.h
new file mode 100644
index 00000000000..a7800aea8c8
--- /dev/null
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkObjectActuator.h
@@ -0,0 +1,31 @@
+/**
+ * $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 *****
+ */
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkObjectSensor.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkObjectSensor.cpp
new file mode 100644
index 00000000000..a7800aea8c8
--- /dev/null
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkObjectSensor.cpp
@@ -0,0 +1,31 @@
+/**
+ * $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 *****
+ */
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkObjectSensor.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkObjectSensor.h
new file mode 100644
index 00000000000..a7800aea8c8
--- /dev/null
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkObjectSensor.h
@@ -0,0 +1,31 @@
+/**
+ * $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 *****
+ */
diff --git a/source/gameengine/Ketsji/KXNetwork/Makefile b/source/gameengine/Ketsji/KXNetwork/Makefile
new file mode 100644
index 00000000000..bce2cbc29a3
--- /dev/null
+++ b/source/gameengine/Ketsji/KXNetwork/Makefile
@@ -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 *****
+#
+#
+
+LIBNAME = KXNetwork
+DIR = $(OCGDIR)/gameengine/ketsji/$(LIBNAME)
+
+include nan_compile.mk
+
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
+CPPFLAGS += -I$(NAN_STRING)/include
+CPPFLAGS += -I../../Expressions
+CPPFLAGS += -I../../GameLogic
+CPPFLAGS += -I../../Network
+CPPFLAGS += -I../../../kernel/gen_system
+CPPFLAGS += -I..
+
diff --git a/source/gameengine/Ketsji/KX_CDActuator.cpp b/source/gameengine/Ketsji/KX_CDActuator.cpp
new file mode 100644
index 00000000000..e69e0e98960
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_CDActuator.cpp
@@ -0,0 +1,252 @@
+/**
+ * KX_CDActuator.cpp
+ *
+ * $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 "KX_CDActuator.h"
+#include "SND_CDObject.h"
+#include "KX_GameObject.h"
+#include "SND_Scene.h" // needed for replication
+#include <iostream>
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+KX_CDActuator::KX_CDActuator(SCA_IObject* gameobject,
+ SND_Scene* soundscene,
+ KX_CDACT_TYPE type,
+ int track,
+ short start,
+ short end,
+ PyTypeObject* T)
+ : SCA_IActuator(gameobject,T)
+{
+ m_soundscene = soundscene;
+ m_type = type;
+ m_track = track;
+ m_lastEvent = true;
+ m_isplaying = false;
+ m_startFrame = start;
+ m_endFrame = end;
+ m_gain = SND_CDObject::Instance()->GetGain();
+}
+
+
+
+KX_CDActuator::~KX_CDActuator()
+{
+}
+
+
+/* hmmm, do we want this? */
+CValue* KX_CDActuator::GetReplica()
+{
+ KX_CDActuator* replica = new KX_CDActuator(*this);
+ replica->ProcessReplica();
+
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+ return replica;
+};
+
+
+
+bool KX_CDActuator::Update(double curtime,double deltatime)
+{
+ bool result = false;
+ bool bNegativeEvent = IsNegativeEvent();
+
+ RemoveAllEvents();
+
+ if (!bNegativeEvent)
+ {
+ switch (m_type)
+ {
+ case KX_CDACT_PLAY_ALL:
+ {
+ SND_CDObject::Instance()->SetPlaymode(SND_CD_ALL);
+ SND_CDObject::Instance()->SetTrack(1);
+ SND_CDObject::Instance()->SetPlaystate(SND_MUST_PLAY);
+ result = true;
+ break;
+ }
+ case KX_CDACT_PLAY_TRACK:
+ {
+ SND_CDObject::Instance()->SetPlaymode(SND_CD_TRACK);
+ SND_CDObject::Instance()->SetTrack(m_track);
+ SND_CDObject::Instance()->SetPlaystate(SND_MUST_PLAY);
+ result = true;
+ break;
+ }
+ case KX_CDACT_LOOP_TRACK:
+ {
+ SND_CDObject::Instance()->SetPlaymode(SND_CD_ALL);
+ SND_CDObject::Instance()->SetTrack(m_track);
+ SND_CDObject::Instance()->SetPlaystate(SND_MUST_PLAY);
+ result = true;
+ break;
+ }
+ case KX_CDACT_STOP:
+ {
+ SND_CDObject::Instance()->SetPlaystate(SND_MUST_STOP);
+ break;
+ }
+ case KX_CDACT_PAUSE:
+ {
+ SND_CDObject::Instance()->SetPlaystate(SND_MUST_PAUSE);
+ result = true;
+ break;
+ }
+ case KX_CDACT_RESUME:
+ {
+ SND_CDObject::Instance()->SetPlaystate(SND_MUST_RESUME);
+ result = true;
+ break;
+ }
+ case KX_CDACT_VOLUME:
+ {
+ SND_CDObject::Instance()->SetGain(m_gain);
+ result = true;
+ break;
+ }
+ default:
+ // implement me !!
+ break;
+ }
+ }
+ return result;
+}
+
+
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject KX_CDActuator::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "KX_SoundActuator",
+ sizeof(KX_CDActuator),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+
+
+PyParentObject KX_CDActuator::Parents[] = {
+ &KX_CDActuator::Type,
+ &SCA_IActuator::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+
+
+PyMethodDef KX_CDActuator::Methods[] = {
+ {"startCD",(PyCFunction) KX_CDActuator::sPyStartCD,METH_VARARGS,NULL},
+ {"pauseCD",(PyCFunction) KX_CDActuator::sPyPauseCD,METH_VARARGS,NULL},
+ {"stopCD",(PyCFunction) KX_CDActuator::sPyStopCD,METH_VARARGS,NULL},
+ {"setGain",(PyCFunction) KX_CDActuator::sPySetGain,METH_VARARGS,NULL},
+ {"getGain",(PyCFunction) KX_CDActuator::sPyGetGain,METH_VARARGS,NULL},
+ {NULL,NULL,NULL,NULL} //Sentinel
+};
+
+
+
+PyObject* KX_CDActuator::_getattr(char* attr)
+{
+ _getattr_up(SCA_IActuator);
+}
+
+
+
+
+PyObject* KX_CDActuator::PyStartCD(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ SND_CDObject::Instance()->SetPlaystate(SND_MUST_PLAY);
+ Py_Return;
+}
+
+
+
+PyObject* KX_CDActuator::PyPauseCD(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ SND_CDObject::Instance()->SetPlaystate(SND_MUST_PAUSE);
+ Py_Return;
+}
+
+
+
+PyObject* KX_CDActuator::PyStopCD(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ SND_CDObject::Instance()->SetPlaystate(SND_MUST_STOP);
+ Py_Return;
+}
+
+
+
+PyObject* KX_CDActuator::PySetGain(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ float gain = 1.0;
+ if (!PyArg_ParseTuple(args, "f", &gain))
+ return NULL;
+
+ SND_CDObject::Instance()->SetGain(gain);
+
+ Py_Return;
+}
+
+
+
+PyObject* KX_CDActuator::PyGetGain(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ float gain = SND_CDObject::Instance()->GetGain();
+ PyObject* result = PyFloat_FromDouble(gain);
+
+ return result;
+} \ No newline at end of file
diff --git a/source/gameengine/Ketsji/KX_CDActuator.h b/source/gameengine/Ketsji/KX_CDActuator.h
new file mode 100644
index 00000000000..48570523f51
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_CDActuator.h
@@ -0,0 +1,97 @@
+/**
+ * KX_CDActuator.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_CDACTUATOR
+#define __KX_CDACTUATOR
+
+#include "SCA_IActuator.h"
+#include "SND_CDObject.h"
+
+
+class KX_CDActuator : public SCA_IActuator
+{
+ Py_Header;
+ bool m_lastEvent;
+ bool m_isplaying;
+ /* just some handles to the audio-data... */
+ class SND_Scene* m_soundscene;
+ int m_track;
+ float m_gain;
+ short m_startFrame;
+ short m_endFrame;
+
+public:
+ enum KX_CDACT_TYPE
+ {
+ KX_CDACT_NODEF = 0,
+ KX_CDACT_PLAY_ALL,
+ KX_CDACT_PLAY_TRACK,
+ KX_CDACT_LOOP_TRACK,
+ KX_CDACT_VOLUME,
+ KX_CDACT_STOP,
+ KX_CDACT_PAUSE,
+ KX_CDACT_RESUME,
+ KX_SOUNDACT_MAX
+ };
+
+ KX_CDACT_TYPE m_type;
+
+ KX_CDActuator(SCA_IObject* gameobject,
+ SND_Scene* soundscene,
+ KX_CDACT_TYPE type,
+ int track,
+ short start,
+ short end,
+ PyTypeObject* T=&Type);
+
+ ~KX_CDActuator();
+
+ bool Update(double curtime,double deltatime);
+
+ CValue* GetReplica();
+
+ /* -------------------------------------------------------------------- */
+ /* Python interface --------------------------------------------------- */
+ /* -------------------------------------------------------------------- */
+
+ PyObject* _getattr(char *attr);
+
+ KX_PYMETHOD(KX_CDActuator,StartCD);
+ KX_PYMETHOD(KX_CDActuator,PauseCD);
+ KX_PYMETHOD(KX_CDActuator,StopCD);
+ KX_PYMETHOD(KX_CDActuator,SetGain);
+ KX_PYMETHOD(KX_CDActuator,GetGain);
+};
+#endif //__KX_CDACTUATOR
+
diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp
new file mode 100644
index 00000000000..919355d411a
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_Camera.cpp
@@ -0,0 +1,181 @@
+/*
+ * $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 *****
+ * Camera in the gameengine. Cameras are also used for views.
+ */
+
+#include "KX_Camera.h"
+
+KX_Camera::KX_Camera(void* sgReplicationInfo,
+ SG_Callbacks callbacks,
+ const RAS_CameraData& camdata)
+ :
+ KX_GameObject(sgReplicationInfo,callbacks)
+{
+ // setting a name would be nice...
+ m_name = "cam";
+ m_camdata = camdata;
+ SetProperty("camera",new CIntValue(1));
+}
+
+
+
+KX_Camera::~KX_Camera()
+{
+}
+
+
+
+MT_Transform KX_Camera::GetWorldToCamera() const
+{
+ MT_Transform camtrans;
+ MT_Transform trans;
+
+ trans.setBasis(NodeGetWorldOrientation());
+ trans.setOrigin(NodeGetWorldPosition());
+
+ camtrans.invert(trans);
+
+ return camtrans;
+}
+
+
+
+MT_Transform KX_Camera::GetCameraToWorld() const
+{
+ MT_Transform trans;
+ trans.setBasis(NodeGetWorldOrientation());
+ trans.setOrigin(NodeGetWorldPosition());
+
+ return trans;
+}
+
+
+
+void KX_Camera::CorrectLookUp(MT_Scalar speed)
+{
+}
+
+
+
+const MT_Point3 KX_Camera::GetCameraLocation()
+{
+ /* this is the camera locatio in cam coords... */
+ //return m_trans1.getOrigin();
+ //return MT_Point3(0,0,0); <-----
+ /* .... I want it in world coords */
+ MT_Transform trans;
+ trans.setBasis(NodeGetWorldOrientation());
+
+ return NodeGetWorldPosition();
+}
+
+
+
+/* I want the camera orientation as well. */
+const MT_Quaternion KX_Camera::GetCameraOrientation()
+{
+ MT_Transform trans;
+ trans.setBasis(NodeGetWorldOrientation());
+ trans.setOrigin(NodeGetWorldPosition());
+
+ return trans.getRotation();
+}
+
+
+
+/**
+* Sets the projection matrix that is used by the rasterizer.
+*/
+void KX_Camera::SetProjectionMatrix(const MT_Matrix4x4 & mat)
+{
+ m_projection_matrix = mat;
+}
+
+
+
+/**
+* Sets the modelview matrix that is used by the rasterizer.
+*/
+void KX_Camera::SetModelviewMatrix(const MT_Matrix4x4 & mat)
+{
+ m_modelview_matrix = mat;
+}
+
+
+
+/**
+* Gets the projection matrix that is used by the rasterizer.
+*/
+void KX_Camera::GetProjectionMatrix(MT_Matrix4x4 & mat)
+{
+ mat = m_projection_matrix;
+}
+
+
+
+/**
+* Gets the modelview matrix that is used by the rasterizer.
+*/
+void KX_Camera::GetModelviewMatrix(MT_Matrix4x4 & mat)
+{
+ mat = m_modelview_matrix;
+}
+
+
+
+/*
+* These getters retrieve the clip data and the focal length
+*/
+float KX_Camera::GetLens()
+{
+ return m_camdata.m_lens;
+}
+
+
+
+float KX_Camera::GetCameraNear()
+{
+ return m_camdata.m_clipstart;
+}
+
+
+
+float KX_Camera::GetCameraFar()
+{
+ return m_camdata.m_clipend;
+}
+
+
+
+RAS_CameraData* KX_Camera::GetCameraData()
+{
+ return &m_camdata;
+}
diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h
new file mode 100644
index 00000000000..0bc80102e45
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_Camera.h
@@ -0,0 +1,114 @@
+/*
+ * $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 *****
+ * Camera in the gameengine. Cameras are also used for views.
+ */
+
+#ifndef __KX_CAMERA
+#define __KX_CAMERA
+
+
+#include "MT_Transform.h"
+#include "MT_Matrix3x3.h"
+#include "MT_Matrix4x4.h"
+#include "MT_Vector3.h"
+#include "MT_Point3.h"
+#include "KX_GameObject.h"
+#include "IntValue.h"
+#include "RAS_CameraData.h"
+
+
+class KX_Camera : public KX_GameObject
+{
+
+ /** Camera parameters (clips distances, focal lenght). These
+ * params are closely tied to BLender. In the gameengine, only the
+ * projection and modelview matrices are relevant. There's a
+ * conversion being done in the engine class. Why is it stored
+ * here? It doesn't really have a function here. */
+ RAS_CameraData m_camdata;
+
+ // Never used, I think...
+// void MoveTo(const MT_Point3& movevec)
+// {
+ /*MT_Transform camtrans;
+ camtrans.invert(m_trans1);
+ MT_Matrix3x3 camorient = camtrans.getBasis();
+ camtrans.translate(camorient.inverse()*movevec);
+ m_trans1.invert(camtrans);
+ */
+// }
+
+ /**
+ * Storage for the projection matrix that is passed to the
+ * rasterizer. */
+ MT_Matrix4x4 m_projection_matrix;
+
+ /**
+ * Storage for the modelview matrix that is passed to the
+ * rasterizer. */
+ MT_Matrix4x4 m_modelview_matrix;
+
+public:
+
+ KX_Camera(void* sgReplicationInfo,SG_Callbacks callbacks,const RAS_CameraData& camdata);
+ virtual ~KX_Camera();
+
+ MT_Transform GetWorldToCamera() const;
+ MT_Transform GetCameraToWorld() const;
+
+ void CorrectLookUp(MT_Scalar speed);
+ const MT_Point3 GetCameraLocation();
+
+ /* I want the camera orientation as well. */
+ const MT_Quaternion GetCameraOrientation();
+
+ /** Sets the projection matrix that is used by the rasterizer. */
+ void SetProjectionMatrix(const MT_Matrix4x4 & mat);
+
+ /** Sets the modelview matrix that is used by the rasterizer. */
+ void SetModelviewMatrix(const MT_Matrix4x4 & mat);
+
+ /** Gets the projection matrix that is used by the rasterizer. */
+ void GetProjectionMatrix(MT_Matrix4x4 & mat);
+
+ /** Gets the modelview matrix that is used by the rasterizer. */
+ void GetModelviewMatrix(MT_Matrix4x4 & mat);
+
+ /** Gets the focal lenght. */
+ float GetLens();
+ /** Gets the near clip distance. */
+ float GetCameraNear();
+ /** Gets the far clip distance. */
+ float GetCameraFar();
+ /** Gets all camera data. */
+ RAS_CameraData* GetCameraData();
+};
+#endif //__KX_CAMERA
diff --git a/source/gameengine/Ketsji/KX_CameraActuator.cpp b/source/gameengine/Ketsji/KX_CameraActuator.cpp
new file mode 100644
index 00000000000..8a6ed0106f5
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_CameraActuator.cpp
@@ -0,0 +1,368 @@
+/**
+ * KX_CameraActuator.cpp
+ *
+ * $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 "KX_CameraActuator.h"
+#include <iostream>
+#include <math.h>
+#include "KX_GameObject.h"
+
+STR_String KX_CameraActuator::X_AXIS_STRING = "x";
+STR_String KX_CameraActuator::Y_AXIS_STRING = "y";
+
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+KX_CameraActuator::KX_CameraActuator(
+ SCA_IObject* gameobj,
+ const CValue *obj,
+ MT_Scalar hght,
+ MT_Scalar minhght,
+ MT_Scalar maxhght,
+ bool xytog,
+ PyTypeObject* T
+):
+ SCA_IActuator(gameobj, T),
+ m_ob (obj),
+ m_height (hght),
+ m_minHeight (minhght),
+ m_maxHeight (maxhght),
+ m_x (xytog)
+{
+ // nothing to do
+}
+
+KX_CameraActuator::~KX_CameraActuator()
+{
+ //nothing to do
+}
+
+ CValue*
+KX_CameraActuator::
+GetReplica(
+) {
+ KX_CameraActuator* replica = new KX_CameraActuator(*this);
+ replica->ProcessReplica();
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+ return replica;
+};
+
+
+
+
+/* three functions copied from blender arith... don't know if there's an equivalent */
+
+float Normalise(float *n)
+{
+ float d;
+
+ d= n[0]*n[0]+n[1]*n[1]+n[2]*n[2];
+ /* FLT_EPSILON is too large! A larger value causes normalise errors in a scaled down utah teapot */
+ if(d>0.0000000000001) {
+ d= sqrt(d);
+
+ n[0]/=d;
+ n[1]/=d;
+ n[2]/=d;
+ } else {
+ n[0]=n[1]=n[2]= 0.0;
+ d= 0.0;
+ }
+ return d;
+}
+
+void Crossf(float *c, float *a, float *b)
+{
+ c[0] = a[1] * b[2] - a[2] * b[1];
+ c[1] = a[2] * b[0] - a[0] * b[2];
+ c[2] = a[0] * b[1] - a[1] * b[0];
+}
+
+
+void VecUpMat3(float *vec, float mat[][3], short axis)
+{
+
+ // Construct a camera matrix s.t. the specified axis
+
+ // maps to the given vector (*vec). Also defines the rotation
+
+ // about this axis by mapping one of the other axis to the y-axis.
+
+
+ float inp;
+ short cox = 0, coy = 0, coz = 0;
+
+ /* up varieeren heeft geen zin, is eigenlijk helemaal geen up!
+ * zie VecUpMat3old
+ */
+
+ if(axis==0) {
+ cox= 0; coy= 1; coz= 2; /* Y up Z tr */
+ }
+ if(axis==1) {
+ cox= 1; coy= 2; coz= 0; /* Z up X tr */
+ }
+ if(axis==2) {
+ cox= 2; coy= 0; coz= 1; /* X up Y tr */
+ }
+ if(axis==3) {
+ cox= 0; coy= 1; coz= 2; /* Y op -Z tr */
+ vec[0]= -vec[0];
+ vec[1]= -vec[1];
+ vec[2]= -vec[2];
+ }
+ if(axis==4) {
+ cox= 1; coy= 0; coz= 2; /* */
+ }
+ if(axis==5) {
+ cox= 2; coy= 1; coz= 0; /* Y up X tr */
+ }
+
+ mat[coz][0]= vec[0];
+ mat[coz][1]= vec[1];
+ mat[coz][2]= vec[2];
+ Normalise((float *)mat[coz]);
+
+ inp= mat[coz][2];
+ mat[coy][0]= - inp*mat[coz][0];
+ mat[coy][1]= - inp*mat[coz][1];
+ mat[coy][2]= 1.0 - inp*mat[coz][2];
+
+ Normalise((float *)mat[coy]);
+
+ Crossf(mat[cox], mat[coy], mat[coz]);
+
+}
+
+bool KX_CameraActuator::Update(double curtime,double deltatime)
+{
+ bool result = true;
+
+ KX_GameObject *obj = (KX_GameObject*) GetParent();
+ MT_Point3 from = obj->NodeGetWorldPosition();
+ MT_Matrix3x3 frommat = obj->NodeGetWorldOrientation();
+ /* These casts are _very_ dangerous!!! */
+ MT_Point3 lookat = ((KX_GameObject*)m_ob)->NodeGetWorldPosition();
+ MT_Matrix3x3 actormat = ((KX_GameObject*)m_ob)->NodeGetWorldOrientation();
+
+
+
+ float fp1[3], fp2[3], rc[3];
+ float inp, fac; //, factor = 0.0; /* some factor... */
+ float mindistsq, maxdistsq, distsq;
+ float mat[3][3];
+
+ /* wondering... is it really neccesary/desirable to suppress negative */
+ /* events here? */
+ bool bNegativeEvent = IsNegativeEvent();
+ RemoveAllEvents();
+
+ if (bNegativeEvent) return false;
+
+ /* The rules: */
+ /* CONSTRAINT 1: not implemented */
+ /* CONSTRAINT 2: can camera see actor? */
+ /* CONSTRAINT 3: fixed height relative to floor below actor. */
+ /* CONSTRAINT 4: camera rotates behind actor */
+ /* CONSTRAINT 5: minimum / maximum distance */
+ /* CONSTRAINT 6: again: fixed height relative to floor below actor */
+ /* CONSTRAINT 7: track to floor below actor */
+ /* CONSTRAINT 8: look a little bit left or right, depending on how the
+
+ character is looking (horizontal x)
+ */
+
+ /* ...and then set the camera position. Since we assume the parent of */
+ /* this actuator is always a camera, just set the parent position and */
+ /* rotation. We do not check whether we really have a camera as parent. */
+ /* It may be better to turn this into a general tracking actuator later */
+ /* on, since lots of plausible relations can be filled in here. */
+
+ /* ... set up some parameters ... */
+ /* missing here: the 'floorloc' of the actor's shadow */
+
+ mindistsq= m_minHeight*m_minHeight;
+ maxdistsq= m_maxHeight*m_maxHeight;
+
+ /* C1: not checked... is a future option */
+
+ /* C2: blender test_visibility function. Can this be a ray-test? */
+
+ /* C3: fixed height */
+ from[2] = (15.0*from[2] + lookat[2] + m_height)/16.0;
+
+
+ /* C4: camera behind actor */
+ if (m_x) {
+ fp1[0] = actormat[0][0];
+ fp1[1] = actormat[1][0];
+ fp1[2] = actormat[2][0];
+
+ fp2[0] = frommat[0][0];
+ fp2[1] = frommat[1][0];
+ fp2[2] = frommat[2][0];
+ }
+ else {
+ fp1[0] = actormat[0][1];
+ fp1[1] = actormat[1][1];
+ fp1[2] = actormat[2][1];
+
+ fp2[0] = frommat[0][1];
+ fp2[1] = frommat[1][1];
+ fp2[2] = frommat[2][1];
+ }
+
+ inp= fp1[0]*fp2[0] + fp1[1]*fp2[1] + fp1[2]*fp2[2];
+ fac= (-1.0 + inp)/32.0;
+
+ from[0]+= fac*fp1[0];
+ from[1]+= fac*fp1[1];
+ from[2]+= fac*fp1[2];
+
+ /* alleen alstie ervoor ligt: cross testen en loodrechte bijtellen */
+ if(inp<0.0) {
+ if(fp1[0]*fp2[1] - fp1[1]*fp2[0] > 0.0) {
+ from[0]-= fac*fp1[1];
+ from[1]+= fac*fp1[0];
+ }
+ else {
+ from[0]+= fac*fp1[1];
+ from[1]-= fac*fp1[0];
+ }
+ }
+
+ /* CONSTRAINT 5: minimum / maximum afstand */
+
+ rc[0]= (lookat[0]-from[0]);
+ rc[1]= (lookat[1]-from[1]);
+ rc[2]= (lookat[2]-from[2]);
+ distsq= rc[0]*rc[0] + rc[1]*rc[1] + rc[2]*rc[2];
+
+ if(distsq > maxdistsq) {
+ distsq = 0.15*(distsq-maxdistsq)/distsq;
+
+ from[0] += distsq*rc[0];
+ from[1] += distsq*rc[1];
+ from[2] += distsq*rc[2];
+ }
+ else if(distsq < mindistsq) {
+ distsq = 0.15*(mindistsq-distsq)/mindistsq;
+
+ from[0] -= distsq*rc[0];
+ from[1] -= distsq*rc[1];
+ from[2] -= distsq*rc[2];
+ }
+
+
+ /* CONSTRAINT 7: track to schaduw */
+ rc[0]= (lookat[0]-from[0]);
+ rc[1]= (lookat[1]-from[1]);
+ rc[2]= (lookat[2]-from[2]);
+ VecUpMat3(rc, mat, 3); /* y up Track -z */
+
+
+
+
+ /* now set the camera position and rotation */
+
+ obj->NodeSetLocalPosition(from);
+
+ actormat[0][0]= mat[0][0]; actormat[0][1]= mat[1][0]; actormat[0][2]= mat[2][0];
+ actormat[1][0]= mat[0][1]; actormat[1][1]= mat[1][1]; actormat[1][2]= mat[2][1];
+ actormat[2][0]= mat[0][2]; actormat[2][1]= mat[1][2]; actormat[2][2]= mat[2][2];
+ obj->NodeSetLocalOrientation(actormat);
+
+ return result;
+}
+
+CValue *KX_CameraActuator::findObject(char *obName)
+{
+ /* hook to object system */
+ return NULL;
+}
+
+bool KX_CameraActuator::string2axischoice(const char *axisString)
+{
+ bool res = true;
+
+ res = !(axisString == Y_AXIS_STRING);
+
+ return res;
+}
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject KX_CameraActuator::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "KX_CameraActuator",
+ sizeof(KX_CameraActuator),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject KX_CameraActuator::Parents[] = {
+ &KX_CameraActuator::Type,
+ &SCA_IActuator::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef KX_CameraActuator::Methods[] = {
+ {NULL,NULL,NULL,NULL} //Sentinel
+};
+
+PyObject* KX_CameraActuator::_getattr(char* attr) {
+ _getattr_up(SCA_IActuator);
+}
+
+
+/* eof */
diff --git a/source/gameengine/Ketsji/KX_CameraActuator.h b/source/gameengine/Ketsji/KX_CameraActuator.h
new file mode 100644
index 00000000000..1d819864cff
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_CameraActuator.h
@@ -0,0 +1,128 @@
+/**
+ * KX_CameraActuator.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_CAMERAACTUATOR
+#define __KX_CAMERAACTUATOR
+
+#include "SCA_IActuator.h"
+#include "MT_Scalar.h"
+
+
+/**
+ * The camera actuator does a Robbie Muller prespective for you. This is a
+ * weird set of rules that positions the camera sort of behind the object,
+ * tracking, while avoiding any objects between the 'ideal' position and the
+ * actor being tracked.
+ */
+
+
+class KX_CameraActuator : public SCA_IActuator
+{
+
+private :
+ Py_Header;
+
+ /** Object that will be tracked. */
+ const CValue *m_ob;
+
+ /** height (float), */
+ const MT_Scalar m_height;
+
+ /** min (float), */
+ const MT_Scalar m_minHeight;
+
+ /** max (float), */
+ const MT_Scalar m_maxHeight;
+
+ /** xy toggle (pick one): true == x, false == y */
+ bool m_x;
+
+ /* get the KX_IGameObject with this name */
+ CValue *findObject(char *obName);
+
+ /* parse x or y to a toggle pick */
+ bool string2axischoice(const char *axisString);
+
+ public:
+ static STR_String X_AXIS_STRING;
+ static STR_String Y_AXIS_STRING;
+
+ /**
+ * Set the bool toggle to true to use x lock, false for y lock
+ */
+ KX_CameraActuator(
+
+ SCA_IObject *gameobj,
+ const CValue *ob,
+ MT_Scalar hght,
+ MT_Scalar minhght,
+ MT_Scalar maxhght,
+ bool xytog,
+ PyTypeObject* T=&Type
+
+ );
+
+
+ ~KX_CameraActuator();
+
+
+
+ /** Methods Inherited from CValue */
+
+
+ CValue* GetReplica();
+
+
+ /** Methods inherited from SCA_IActuator */
+
+
+ bool Update(
+
+ double curtime,
+
+ double deltatime
+
+ );
+
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(char *attr);
+
+
+
+};
+#endif //__KX_CAMERAACTUATOR
diff --git a/source/gameengine/Ketsji/KX_CameraIpoSGController.cpp b/source/gameengine/Ketsji/KX_CameraIpoSGController.cpp
new file mode 100644
index 00000000000..2e736864a44
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_CameraIpoSGController.cpp
@@ -0,0 +1,125 @@
+/**
+ * $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 "KX_CameraIpoSGController.h"
+
+#include "KX_ScalarInterpolator.h"
+#include "KX_Camera.h"
+
+#include "RAS_CameraData.h"
+
+
+bool KX_CameraIpoSGController::Update(double currentTime)
+{
+ if (m_modified)
+ {
+ T_InterpolatorList::iterator i;
+ for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) {
+ (*i)->Execute(m_ipotime);
+ }
+
+ RAS_CameraData* camdata;
+
+ SG_Spatial* ob = (SG_Spatial*)m_pObject;
+ KX_Camera* kxcamera = (KX_Camera*) ob->GetSGClientObject();
+ camdata = kxcamera->GetCameraData();
+
+
+ if (m_modify_lens) {
+ camdata->m_lens = m_lens;
+ }
+
+ if (m_modify_clipstart ) {
+ camdata->m_clipstart = m_clipstart;
+ }
+
+ if (m_modify_clipend) {
+ camdata->m_clipend = m_clipend;
+ }
+
+ m_modified=false;
+ }
+ return false;
+}
+
+
+void KX_CameraIpoSGController::AddInterpolator(KX_IInterpolator* interp)
+{
+ this->m_interpolators.push_back(interp);
+}
+
+SG_Controller* KX_CameraIpoSGController::GetReplica(class SG_Node* destnode)
+{
+ KX_CameraIpoSGController* iporeplica = new KX_CameraIpoSGController(*this);
+ // clear object that ipo acts on
+ iporeplica->ClearObject();
+
+ // dirty hack, ask Gino for a better solution in the ipo implementation
+ // hacken en zagen, in what we call datahiding, not written for replication :(
+
+ T_InterpolatorList oldlist = m_interpolators;
+ iporeplica->m_interpolators.clear();
+
+ T_InterpolatorList::iterator i;
+ for (i = oldlist.begin(); !(i == oldlist.end()); ++i) {
+ KX_ScalarInterpolator* copyipo = new KX_ScalarInterpolator(*((KX_ScalarInterpolator*)*i));
+ iporeplica->AddInterpolator(copyipo);
+
+ MT_Scalar* scaal = ((KX_ScalarInterpolator*)*i)->GetTarget();
+ int orgbase = (int)this;
+ int orgloc = (int)scaal;
+ int offset = orgloc-orgbase;
+ int newaddrbase = (int)iporeplica + offset;
+ MT_Scalar* blaptr = (MT_Scalar*) newaddrbase;
+ copyipo->SetNewTarget((MT_Scalar*)blaptr);
+ }
+
+ return iporeplica;
+}
+
+KX_CameraIpoSGController::~KX_CameraIpoSGController()
+{
+
+ T_InterpolatorList::iterator i;
+ for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) {
+ delete (*i);
+ }
+
+}
+
+ void
+KX_CameraIpoSGController::SetOption(
+ int option,
+ int value)
+{
+ /* Setting options */
+
+}
diff --git a/source/gameengine/Ketsji/KX_CameraIpoSGController.h b/source/gameengine/Ketsji/KX_CameraIpoSGController.h
new file mode 100644
index 00000000000..3ebbcc343d4
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_CameraIpoSGController.h
@@ -0,0 +1,91 @@
+/**
+ * $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_CAMERAIPOSGCONTROLLER_H
+#define KX_CAMERAIPOSGCONTROLLER_H
+
+#include "SG_Controller.h"
+#include "SG_Spatial.h"
+
+#include "KX_IInterpolator.h"
+
+struct RAS_CameraData;
+
+class KX_CameraIpoSGController : public SG_Controller
+{
+public:
+ MT_Scalar m_lens;
+ MT_Scalar m_clipstart;
+ MT_Scalar m_clipend;
+
+private:
+ T_InterpolatorList m_interpolators;
+ unsigned short m_modify_lens : 1;
+ unsigned short m_modify_clipstart : 1;
+ unsigned short m_modify_clipend : 1;
+ bool m_modified;
+
+ double m_ipotime;
+public:
+ KX_CameraIpoSGController() : m_ipotime(0.0),
+ m_modify_lens(false),
+ m_modify_clipstart(false),
+ m_modify_clipend(false),
+ m_modified(true)
+ {}
+
+ ~KX_CameraIpoSGController();
+ SG_Controller* GetReplica(class SG_Node* destnode);
+ bool Update(double time);
+
+ void
+ SetOption(
+ int option,
+ int value
+ );
+
+ void SetSimulatedTime(double time) {
+ m_ipotime = time;
+ m_modified = true;
+ }
+ void SetModifyLens(bool modify) {
+ m_modify_lens = modify;
+ }
+ void SetModifyClipEnd(bool modify) {
+ m_modify_clipend = modify;
+ }
+ void SetModifyClipStart(bool modify) {
+ m_modify_clipstart = modify;
+ }
+ void AddInterpolator(KX_IInterpolator* interp);
+};
+
+#endif // KX_CAMERAIPOSGCONTROLLER_H
diff --git a/source/gameengine/Ketsji/KX_ClientObjectInfo.h b/source/gameengine/Ketsji/KX_ClientObjectInfo.h
new file mode 100644
index 00000000000..8aec115e44d
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_ClientObjectInfo.h
@@ -0,0 +1,46 @@
+/**
+ * $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_CLIENTOBJECT_INFO_H
+#define __KX_CLIENTOBJECT_INFO_H
+
+/**
+ * Client Type and Additional Info. This structure can be use instead of a bare void* pointer, for safeness, and additional info for callbacks
+ */
+
+struct KX_ClientObjectInfo
+{
+ int m_type;
+ void* m_clientobject;
+ void* m_auxilary_info;
+};
+
+#endif //__KX_CLIENTOBJECT_INFO_H
diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
new file mode 100644
index 00000000000..8aab3e7648d
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
@@ -0,0 +1,369 @@
+/**
+ * Apply a constraint to a position or rotation value
+ *
+ * $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"
+#include "KX_ConstraintActuator.h"
+#include "SCA_IObject.h"
+#include "MT_Point3.h"
+#include "MT_Matrix3x3.h"
+#include "KX_GameObject.h"
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+KX_ConstraintActuator::KX_ConstraintActuator(SCA_IObject *gameobj,
+ int dampTime,
+ float minBound,
+ float maxBound,
+ int locrotxyz,
+ PyTypeObject* T)
+ : SCA_IActuator(gameobj, T)
+{
+ m_dampTime = dampTime;
+ m_locrot = locrotxyz;
+ /* The units of bounds are determined by the type of constraint. To */
+ /* make the constraint application easier and more transparent later on, */
+ /* I think converting the bounds to the applicable domain makes more */
+ /* sense. */
+ switch (m_locrot) {
+ case KX_ACT_CONSTRAINT_LOCX:
+ case KX_ACT_CONSTRAINT_LOCY:
+ case KX_ACT_CONSTRAINT_LOCZ:
+ m_minimumBound = minBound;
+ m_maximumBound = maxBound;
+ break;
+ case KX_ACT_CONSTRAINT_ROTX:
+ case KX_ACT_CONSTRAINT_ROTY:
+ case KX_ACT_CONSTRAINT_ROTZ:
+ /* The user interface asks for degrees, we are radian. */
+ m_minimumBound = MT_radians(minBound);
+ m_maximumBound = MT_radians(maxBound);
+ break;
+ default:
+ ; /* error */
+ }
+
+} /* End of constructor */
+
+KX_ConstraintActuator::~KX_ConstraintActuator()
+{
+ // there's nothing to be done here, really....
+} /* end of destructor */
+
+bool KX_ConstraintActuator::Update(double curtime,double deltatime)
+{
+
+ bool result = false;
+ bool bNegativeEvent = IsNegativeEvent();
+ RemoveAllEvents();
+
+ if (bNegativeEvent)
+ return false; // do nothing on negative events
+
+ /* Constraint clamps the values to the specified range, with a sort of */
+ /* low-pass filtered time response, if the damp time is unequal to 0. */
+
+ /* Having to retrieve location/rotation and setting it afterwards may not */
+ /* be efficient enough... Somthing to look at later. */
+ KX_GameObject *parent = (KX_GameObject*) GetParent();
+ MT_Point3 position = parent->NodeGetWorldPosition();
+ MT_Matrix3x3 rotation = parent->NodeGetWorldOrientation();
+// MT_Vector3 eulerrot = rotation.getEuler();
+
+ switch (m_locrot) {
+ case KX_ACT_CONSTRAINT_LOCX:
+ Clamp(position[0], m_minimumBound, m_maximumBound);
+ break;
+ case KX_ACT_CONSTRAINT_LOCY:
+ Clamp(position[1], m_minimumBound, m_maximumBound);
+ break;
+ case KX_ACT_CONSTRAINT_LOCZ:
+ Clamp(position[2], m_minimumBound, m_maximumBound);
+ break;
+
+// case KX_ACT_CONSTRAINT_ROTX:
+// /* The angles are Euler angles (I think that's what they are called) */
+// /* but we need to convert from/to the MT_Matrix3x3. */
+// Clamp(eulerrot[0], m_minimumBound, m_maximumBound);
+// break;
+// case KX_ACT_CONSTRAINT_ROTY:
+// Clamp(eulerrot[1], m_minimumBound, m_maximumBound);
+// break;
+// case KX_ACT_CONSTRAINT_ROTZ:
+// Clamp(eulerrot[2], m_minimumBound, m_maximumBound);
+// break;
+// default:
+// ; /* error */
+ }
+
+ /* Will be replaced by a filtered clamp. */
+
+
+ switch (m_locrot) {
+ case KX_ACT_CONSTRAINT_LOCX:
+ case KX_ACT_CONSTRAINT_LOCY:
+ case KX_ACT_CONSTRAINT_LOCZ:
+ parent->NodeSetLocalPosition(position);
+ break;
+
+
+// case KX_ACT_CONSTRAINT_ROTX:
+// case KX_ACT_CONSTRAINT_ROTY:
+// case KX_ACT_CONSTRAINT_ROTZ:
+// rotation.setEuler(eulerrot);
+// parent->NodeSetLocalOrientation(rotation);
+ break;
+
+ default:
+ ; /* error */
+ }
+
+ return false;
+} /* end of KX_ConstraintActuator::Update(double curtime,double deltatime) */
+
+void KX_ConstraintActuator::Clamp(MT_Scalar &var,
+ float min,
+ float max) {
+ if (var < min) {
+ var = min;
+ } else if (var > max) {
+ var = max;
+ }
+}
+
+
+bool KX_ConstraintActuator::IsValidMode(KX_ConstraintActuator::KX_CONSTRAINTTYPE m)
+{
+ bool res = false;
+
+ if ( (m > KX_ACT_CONSTRAINT_NODEF) && (m < KX_ACT_CONSTRAINT_MAX)) {
+ res = true;
+ }
+
+ return res;
+}
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject KX_ConstraintActuator::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "KX_ConstraintActuator",
+ sizeof(KX_ConstraintActuator),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject KX_ConstraintActuator::Parents[] = {
+ &KX_ConstraintActuator::Type,
+ &SCA_IActuator::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef KX_ConstraintActuator::Methods[] = {
+ {"setDamp", (PyCFunction) KX_ConstraintActuator::sPySetDamp, METH_VARARGS, SetDamp_doc},
+ {"getDamp", (PyCFunction) KX_ConstraintActuator::sPyGetDamp, METH_VARARGS, GetDamp_doc},
+ {"setMin", (PyCFunction) KX_ConstraintActuator::sPySetMin, METH_VARARGS, SetMin_doc},
+ {"getMin", (PyCFunction) KX_ConstraintActuator::sPyGetMin, METH_VARARGS, GetMin_doc},
+ {"setMax", (PyCFunction) KX_ConstraintActuator::sPySetMax, METH_VARARGS, SetMax_doc},
+ {"getMax", (PyCFunction) KX_ConstraintActuator::sPyGetMax, METH_VARARGS, GetMax_doc},
+ {"setLimit", (PyCFunction) KX_ConstraintActuator::sPySetLimit, METH_VARARGS, SetLimit_doc},
+ {"getLimit", (PyCFunction) KX_ConstraintActuator::sPyGetLimit, METH_VARARGS, GetLimit_doc},
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* KX_ConstraintActuator::_getattr(char* attr) {
+ _getattr_up(SCA_IActuator);
+}
+
+/* 2. setDamp */
+char KX_ConstraintActuator::SetDamp_doc[] =
+"setDamp(duration)\n"
+"\t- duration: integer\n"
+"\tSets the time with which the constraint application is delayed.\n"
+"\tIf the duration is negative, it is set to 0.\n";
+PyObject* KX_ConstraintActuator::PySetDamp(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ int dampArg;
+ if(!PyArg_ParseTuple(args, "i", &dampArg)) {
+ return NULL;
+ }
+
+ m_dampTime = dampArg;
+ if (m_dampTime < 0) m_dampTime = 0;
+
+ Py_Return;
+}
+/* 3. getDamp */
+char KX_ConstraintActuator::GetDamp_doc[] =
+"GetDamp()\n"
+"\tReturns the damping time for application of the constraint.\n";
+PyObject* KX_ConstraintActuator::PyGetDamp(PyObject* self,
+ PyObject* args,
+ PyObject* kwds){
+ return PyInt_FromLong(m_dampTime);
+}
+
+/* 4. setMin */
+char KX_ConstraintActuator::SetMin_doc[] =
+"setMin(lower_bound)\n"
+"\t- lower_bound: float\n"
+"\tSets the lower value of the interval to which the value\n"
+"\tis clipped.\n";
+PyObject* KX_ConstraintActuator::PySetMin(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ float minArg;
+ if(!PyArg_ParseTuple(args, "f", &minArg)) {
+ return NULL;
+ }
+
+ switch (m_locrot) {
+ case KX_ACT_CONSTRAINT_LOCX:
+ case KX_ACT_CONSTRAINT_LOCY:
+ case KX_ACT_CONSTRAINT_LOCZ:
+ m_minimumBound = minArg;
+ break;
+ case KX_ACT_CONSTRAINT_ROTX:
+ case KX_ACT_CONSTRAINT_ROTY:
+ case KX_ACT_CONSTRAINT_ROTZ:
+ m_minimumBound = MT_radians(minArg);
+ break;
+ default:
+ ; /* error */
+ }
+
+ Py_Return;
+}
+/* 5. getMin */
+char KX_ConstraintActuator::GetMin_doc[] =
+"getMin()\n"
+"\tReturns the lower value of the interval to which the value\n"
+"\tis clipped.\n";
+PyObject* KX_ConstraintActuator::PyGetMin(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ return PyFloat_FromDouble(m_minimumBound);
+}
+
+/* 6. setMax */
+char KX_ConstraintActuator::SetMax_doc[] =
+"setMax(upper_bound)\n"
+"\t- upper_bound: float\n"
+"\tSets the upper value of the interval to which the value\n"
+"\tis clipped.\n";
+PyObject* KX_ConstraintActuator::PySetMax(PyObject* self,
+ PyObject* args,
+ PyObject* kwds){
+ float maxArg;
+ if(!PyArg_ParseTuple(args, "f", &maxArg)) {
+ return NULL;
+ }
+
+ switch (m_locrot) {
+ case KX_ACT_CONSTRAINT_LOCX:
+ case KX_ACT_CONSTRAINT_LOCY:
+ case KX_ACT_CONSTRAINT_LOCZ:
+ m_maximumBound = maxArg;
+ break;
+ case KX_ACT_CONSTRAINT_ROTX:
+ case KX_ACT_CONSTRAINT_ROTY:
+ case KX_ACT_CONSTRAINT_ROTZ:
+ m_maximumBound = MT_radians(maxArg);
+ break;
+ default:
+ ; /* error */
+ }
+
+ Py_Return;
+}
+/* 7. getMax */
+char KX_ConstraintActuator::GetMax_doc[] =
+"getMax()\n"
+"\tReturns the upper value of the interval to which the value\n"
+"\tis clipped.\n";
+PyObject* KX_ConstraintActuator::PyGetMax(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ return PyFloat_FromDouble(m_maximumBound);
+}
+
+
+/* This setter/getter probably for the constraint type */
+/* 8. setLimit */
+char KX_ConstraintActuator::SetLimit_doc[] =
+"setLimit(type)\n"
+"\t- type: KX_CONSTRAINTACT_LOCX, KX_CONSTRAINTACT_LOCY,\n"
+"\t KX_CONSTRAINTACT_LOCZ, KX_CONSTRAINTACT_ROTX,\n"
+"\t KX_CONSTRAINTACT_ROTY, or KX_CONSTRAINTACT_ROTZ.\n"
+"\tSets the type of constraint.\n";
+PyObject* KX_ConstraintActuator::PySetLimit(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ int locrotArg;
+ if(!PyArg_ParseTuple(args, "i", &locrotArg)) {
+ return NULL;
+ }
+
+ if (IsValidMode((KX_CONSTRAINTTYPE)locrotArg)) m_locrot = locrotArg;
+
+ Py_Return;
+}
+/* 9. getLimit */
+char KX_ConstraintActuator::GetLimit_doc[] =
+"getLimit(type)\n"
+"\tReturns the type of constraint.\n";
+PyObject* KX_ConstraintActuator::PyGetLimit(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ return PyInt_FromLong(m_locrot);
+}
+
+/* eof */
diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.h b/source/gameengine/Ketsji/KX_ConstraintActuator.h
new file mode 100644
index 00000000000..247e7ea55f9
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_ConstraintActuator.h
@@ -0,0 +1,109 @@
+/**
+ * KX_ConstraintActuator.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_CONSTRAINTACTUATOR
+#define __KX_CONSTRAINTACTUATOR
+
+#include "SCA_IActuator.h"
+#include "MT_Scalar.h"
+
+
+class KX_ConstraintActuator : public SCA_IActuator
+{
+ Py_Header;
+
+ // Damp time (int),
+ int m_dampTime;
+ // min (float),
+ float m_minimumBound;
+ // max (float),
+ float m_maximumBound;
+ // locrotxyz choice (pick one): only one choice allowed at a time!
+ int m_locrot;
+
+ /**
+ * Clamp <var> to <min>, <max>. Borders are included (in as far as
+ * float comparisons are good for equality...).
+ */
+ void Clamp(MT_Scalar &var, float min, float max);
+
+
+ public:
+ enum KX_CONSTRAINTTYPE {
+ KX_ACT_CONSTRAINT_NODEF = 0,
+ KX_ACT_CONSTRAINT_LOCX,
+ KX_ACT_CONSTRAINT_LOCY,
+ KX_ACT_CONSTRAINT_LOCZ,
+ KX_ACT_CONSTRAINT_ROTX,
+ KX_ACT_CONSTRAINT_ROTY,
+ KX_ACT_CONSTRAINT_ROTZ,
+ KX_ACT_CONSTRAINT_MAX
+ };
+
+ bool IsValidMode(KX_CONSTRAINTTYPE m);
+
+ KX_ConstraintActuator(SCA_IObject* gameobj,
+ int damptime,
+ float min,
+ float max,
+ int locrot,
+ PyTypeObject* T=&Type);
+ virtual ~KX_ConstraintActuator();
+ virtual CValue* GetReplica() {
+ KX_ConstraintActuator* replica = new KX_ConstraintActuator(*this);
+ replica->ProcessReplica();
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+ return replica;
+ };
+
+ virtual bool Update(double curtime,double deltatime);
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(char *attr);
+
+ KX_PYMETHOD_DOC(KX_ConstraintActuator,SetDamp);
+ KX_PYMETHOD_DOC(KX_ConstraintActuator,GetDamp);
+ KX_PYMETHOD_DOC(KX_ConstraintActuator,SetMin);
+ KX_PYMETHOD_DOC(KX_ConstraintActuator,GetMin);
+ KX_PYMETHOD_DOC(KX_ConstraintActuator,SetMax);
+ KX_PYMETHOD_DOC(KX_ConstraintActuator,GetMax);
+ KX_PYMETHOD_DOC(KX_ConstraintActuator,SetLimit);
+ KX_PYMETHOD_DOC(KX_ConstraintActuator,GetLimit);
+
+};
+#endif //__KX_CONSTRAINTACTUATOR
diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp
new file mode 100644
index 00000000000..0a741aa55ac
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp
@@ -0,0 +1,131 @@
+/**
+ * $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 <Python.h>
+
+#include "KX_ConstraintWrapper.h"
+#include "PHY_IPhysicsEnvironment.h"
+
+KX_ConstraintWrapper::KX_ConstraintWrapper(
+ PHY_ConstraintType ctype,
+ int constraintId,
+ PHY_IPhysicsEnvironment* physenv,PyTypeObject *T)
+: m_constraintType(ctype),m_constraintId(constraintId),m_physenv(physenv),PyObjectPlus(T)
+{
+}
+KX_ConstraintWrapper::~KX_ConstraintWrapper()
+{
+}
+//python integration methods
+PyObject* KX_ConstraintWrapper::PyTestMethod(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyObject* KX_ConstraintWrapper::PyGetConstraintId(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ return PyInt_FromLong(m_constraintId);
+}
+
+
+
+
+//python specific stuff
+PyTypeObject KX_ConstraintWrapper::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "KX_ConstraintWrapper",
+ sizeof(KX_ConstraintWrapper),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject KX_ConstraintWrapper::Parents[] = {
+ &KX_ConstraintWrapper::Type,
+ NULL
+};
+
+PyObject* KX_ConstraintWrapper::_getattr(char* attr)
+{
+ //here you can search for existing data members (like mass,friction etc.)
+ _getattr_up(PyObjectPlus);
+}
+
+int KX_ConstraintWrapper::_setattr(char* attr,PyObject* pyobj)
+{
+
+ PyTypeObject* type = pyobj->ob_type;
+ int result = 1;
+
+ if (type == &PyList_Type)
+ {
+ result = 0;
+ }
+ if (type == &PyFloat_Type)
+ {
+ result = 0;
+
+ }
+ if (type == &PyInt_Type)
+ {
+ result = 0;
+ }
+ if (type == &PyString_Type)
+ {
+ result = 0;
+ }
+ if (result)
+ result = PyObjectPlus::_setattr(attr,pyobj);
+ return result;
+};
+
+
+PyMethodDef KX_ConstraintWrapper::Methods[] = {
+ {"testMethod",(PyCFunction) KX_ConstraintWrapper::sPyTestMethod, METH_VARARGS},
+ {"getConstraintId",(PyCFunction) KX_ConstraintWrapper::sPyGetConstraintId, METH_VARARGS},
+ {NULL,NULL} //Sentinel
+};
diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.h b/source/gameengine/Ketsji/KX_ConstraintWrapper.h
new file mode 100644
index 00000000000..3211a74192f
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.h
@@ -0,0 +1,57 @@
+/**
+ * $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_CONSTRAINT_WRAPPER
+#define KX_CONSTRAINT_WRAPPER
+
+#include "Value.h"
+#include "PHY_DynamicTypes.h"
+
+class KX_ConstraintWrapper : public PyObjectPlus
+{
+ Py_Header;
+ PyObject* _getattr(char* attr);
+ virtual int _setattr(char *attr, PyObject *value);
+public:
+ KX_ConstraintWrapper(PHY_ConstraintType ctype,int constraintId,class PHY_IPhysicsEnvironment* physenv,PyTypeObject *T = &Type);
+ virtual ~KX_ConstraintWrapper ();
+ int getConstraintId() { return m_constraintId;};
+
+ KX_PYMETHOD(KX_ConstraintWrapper,TestMethod);
+ KX_PYMETHOD(KX_ConstraintWrapper,GetConstraintId);
+
+private:
+ int m_constraintId;
+ PHY_ConstraintType m_constraintType;
+ PHY_IPhysicsEnvironment* m_physenv;
+};
+
+#endif //KX_CONSTRAINT_WRAPPER
diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h
new file mode 100644
index 00000000000..f74349a3e1a
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h
@@ -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 *****
+ */
+#ifndef KX_CONVERTPHYSICSOBJECTS
+#define KX_CONVERTPHYSICSOBJECTS
+
+
+
+
+//#define USE_SUMO_SOLID
+//solid is not available yet
+
+//#define USE_ODE
+//ode is not available yet
+
+
+class RAS_MeshObject;
+class KX_Scene;
+
+
+struct KX_Bounds
+{
+ float m_center[3];
+ float m_extends[3];
+};
+
+struct KX_ObjectProperties
+{
+ bool m_dyna;
+ double m_radius;
+ bool m_angular_rigidbody;
+ bool m_in_active_layer;
+ bool m_ghost;
+ class KX_GameObject* m_dynamic_parent;
+ bool m_isactor;
+ bool m_concave;
+ bool m_isdeformable;
+ bool m_implicitsphere ;
+ bool m_implicitbox;
+ KX_Bounds m_boundingbox;
+};
+
+#ifdef USE_ODE
+
+
+void KX_ConvertODEEngineObject(KX_GameObject* gameobj,
+ RAS_MeshObject* meshobj,
+ KX_Scene* kxscene,
+ struct PHY_ShapeProps* shapeprops,
+ struct PHY_MaterialProps* smmaterial,
+ struct KX_ObjectProperties* objprop);
+
+
+#endif //USE_ODE
+
+
+void KX_ConvertDynamoObject(KX_GameObject* gameobj,
+ RAS_MeshObject* meshobj,
+ KX_Scene* kxscene,
+ struct PHY_ShapeProps* shapeprops,
+ struct PHY_MaterialProps* smmaterial,
+ struct KX_ObjectProperties* objprop);
+
+
+
+#ifdef USE_SUMO_SOLID
+
+
+
+
+
+void KX_ConvertSumoObject( class KX_GameObject* gameobj,
+ class RAS_MeshObject* meshobj,
+ class KX_Scene* kxscene,
+ struct PHY_ShapeProps* shapeprops,
+ struct PHY_MaterialProps* smmaterial,
+ struct KX_ObjectProperties* objprop);
+#endif
+
+
+
+#endif //KX_CONVERTPHYSICSOBJECTS
diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
new file mode 100644
index 00000000000..01d02b58132
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
@@ -0,0 +1,427 @@
+/**
+ * $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 *****
+ */
+#pragma warning (disable : 4786)
+
+#include "KX_ConvertPhysicsObject.h"
+#include "KX_GameObject.h"
+#include "RAS_MeshObject.h"
+#include "KX_Scene.h"
+#include "SYS_System.h"
+
+#include "PHY_Pro.h" //todo cleanup
+#include "KX_ClientObjectInfo.h"
+
+#include "GEN_Map.h"
+#include "GEN_HashedPtr.h"
+
+#include "KX_PhysicsEngineEnums.h"
+#include "PHY_Pro.h"
+
+#include "KX_MotionState.h" // bridge between motionstate and scenegraph node
+#ifdef USE_ODE
+
+#include "KX_OdePhysicsController.h"
+#include "odephysicsenvironment.h"
+#endif //USE_ODE
+
+
+// USE_SUMO_SOLID is defined in headerfile KX_ConvertPhysicsObjects.h
+#ifdef USE_SUMO_SOLID
+
+
+#include "SumoPhysicsEnvironment.h"
+#include "KX_SumoPhysicsController.h"
+
+
+// sumo physics specific
+#include "SM_Object.h"
+#include "SM_FhObject.h"
+#include "SM_Scene.h"
+#include "SM_ClientObjectInfo.h"
+
+#include "KX_SumoPhysicsController.h"
+
+GEN_Map<GEN_HashedPtr,DT_ShapeHandle> map_gamemesh_to_sumoshape;
+
+// forward declarations
+void BL_RegisterSumoObject(KX_GameObject* gameobj,class SM_Scene* sumoScene,DT_SceneHandle solidscene,class SM_Object* sumoObj,const char* matname,bool isDynamic,bool isActor);
+DT_ShapeHandle CreateShapeFromMesh(RAS_MeshObject* meshobj);
+
+
+void KX_ConvertSumoObject( class KX_GameObject* gameobj,
+ class RAS_MeshObject* meshobj,
+ class KX_Scene* kxscene,
+ PHY_ShapeProps* kxshapeprops,
+ PHY_MaterialProps* kxmaterial,
+ struct KX_ObjectProperties* objprop)
+
+
+{
+
+ SM_ShapeProps* smprop = new SM_ShapeProps;
+
+ smprop->m_ang_drag = kxshapeprops->m_ang_drag;
+ smprop->m_do_anisotropic = kxshapeprops->m_do_anisotropic;
+ smprop->m_do_fh = kxshapeprops->m_do_fh;
+ smprop->m_do_rot_fh = kxshapeprops->m_do_rot_fh ;
+ smprop->m_friction_scaling[0] = kxshapeprops->m_friction_scaling[0];
+ smprop->m_friction_scaling[1] = kxshapeprops->m_friction_scaling[1];
+ smprop->m_friction_scaling[2] = kxshapeprops->m_friction_scaling[2];
+ smprop->m_inertia = kxshapeprops->m_inertia;
+ smprop->m_lin_drag = kxshapeprops->m_lin_drag;
+ smprop->m_mass = kxshapeprops->m_mass;
+
+
+ SM_MaterialProps* smmaterial = new SM_MaterialProps;
+
+ smmaterial->m_fh_damping = kxmaterial->m_fh_damping;
+ smmaterial->m_fh_distance = kxmaterial->m_fh_distance;
+ smmaterial->m_fh_normal = kxmaterial->m_fh_normal;
+ smmaterial->m_fh_spring = kxmaterial->m_fh_spring;
+ smmaterial->m_friction = kxmaterial->m_friction;
+ smmaterial->m_restitution = kxmaterial->m_restitution;
+
+ class SumoPhysicsEnvironment* sumoEnv =
+ (SumoPhysicsEnvironment*)kxscene->GetPhysicsEnvironment();
+
+ SM_Scene* sceneptr = sumoEnv->GetSumoScene();
+
+
+
+ SM_Object* sumoObj=NULL;
+
+ if (objprop->m_dyna)
+ {
+
+ DT_ShapeHandle shape = DT_Sphere(0.0);
+
+ if (objprop->m_ghost)
+ {
+
+ sumoObj = new SM_Object(shape,NULL,smprop,NULL);
+ } else
+ {
+ sumoObj = new SM_Object(shape,smmaterial,smprop,NULL);
+ }
+
+ double radius = objprop->m_radius;
+
+ MT_Scalar margin = radius;//0.5;
+ sumoObj->setMargin(margin);
+
+ //if (bRigidBody)
+ //{
+ if (objprop->m_in_active_layer)
+ {
+ DT_AddObject(sumoEnv->GetSolidScene(),
+ sumoObj->getObjectHandle());
+ }
+ //}
+
+ if (objprop->m_angular_rigidbody)
+ {
+ sumoObj->setRigidBody(true);
+ } else
+ {
+ sumoObj->setRigidBody(false);
+ }
+
+ bool isDynamic = true;
+ bool isActor = true;
+
+ BL_RegisterSumoObject(gameobj,sceneptr,sumoEnv->GetSolidScene(),sumoObj,NULL,isDynamic,isActor);
+
+ }
+ else {
+ // non physics object
+ if (meshobj)
+ {
+ int numpolys = meshobj->NumPolygons();
+
+ {
+
+ DT_ShapeHandle complexshape=0;
+
+ if (objprop->m_implicitbox)
+ {
+ complexshape = DT_Box(objprop->m_boundingbox.m_extends[0],objprop->m_boundingbox.m_extends[1],objprop->m_boundingbox.m_extends[2]);
+ } else
+ {
+ if (numpolys>0)
+ {
+ complexshape = CreateShapeFromMesh(meshobj);
+ }
+ }
+
+ if (complexshape)
+ {
+ SM_Object *dynamicParent = NULL;
+
+ if (objprop->m_dynamic_parent)
+ {
+ // problem is how to find the dynamic parent
+ // in the scenegraph
+ KX_SumoPhysicsController* sumoctrl =
+ (KX_SumoPhysicsController*)
+ objprop->m_dynamic_parent->GetPhysicsController();
+
+ if (sumoctrl)
+ {
+ dynamicParent = sumoctrl->GetSumoObject();
+ }
+
+ assert(dynamicParent);
+ }
+
+
+ if (objprop->m_ghost)
+ {
+ sumoObj = new SM_Object(complexshape,NULL,NULL, dynamicParent);
+ } else
+ {
+ sumoObj = new SM_Object(complexshape,smmaterial,NULL, dynamicParent);
+ }
+
+ if (objprop->m_in_active_layer)
+ {
+ DT_AddObject(sumoEnv->GetSolidScene(),
+ sumoObj->getObjectHandle());
+ }
+
+
+ const STR_String& matname=meshobj->GetMaterialName(0);
+
+
+ BL_RegisterSumoObject(gameobj,sceneptr,
+ sumoEnv->GetSolidScene(),sumoObj,
+ matname.ReadPtr(),
+ objprop->m_dyna,
+ objprop->m_isactor);
+
+ }
+ }
+ }
+ }
+
+ // physics object get updated here !
+
+
+ // lazy evaluation because Havok doesn't support scaling !gameobj->UpdateTransform();
+
+ if (objprop->m_in_active_layer && sumoObj)
+ {
+ sceneptr->add(*sumoObj);
+ }
+
+}
+
+
+
+void BL_RegisterSumoObject(KX_GameObject* gameobj,class SM_Scene* sumoScene,DT_SceneHandle solidscene,class SM_Object* sumoObj,const char* matname,bool isDynamic,bool isActor) {
+
+
+
+ //gameobj->SetDynamic(isDynamic);
+
+ PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode());
+
+ // need easy access, not via 'node' etc.
+ KX_SumoPhysicsController* physicscontroller = new KX_SumoPhysicsController(sumoScene,solidscene,sumoObj,motionstate,isDynamic);
+ gameobj->SetPhysicsController(physicscontroller);
+ physicscontroller->setClientInfo(gameobj);
+
+ gameobj->GetSGNode()->AddSGController(physicscontroller);
+
+ //gameobj->GetClientInfo()->m_type = (isActor ? 1 : 0);
+ //gameobj->GetClientInfo()->m_clientobject = gameobj;
+
+ // store materialname in auxinfo, needed for touchsensors
+ //gameobj->GetClientInfo()->m_auxilary_info = (matname? (void*)(matname+2) : NULL);
+
+ physicscontroller->SetObject(gameobj->GetSGNode());
+
+ //gameobj->SetDynamicsScaling(MT_Vector3(1.0, 1.0, 1.0));
+
+};
+
+
+
+DT_ShapeHandle CreateShapeFromMesh(RAS_MeshObject* meshobj)
+{
+
+ DT_ShapeHandle* shapeptr = map_gamemesh_to_sumoshape[GEN_HashedPtr(meshobj)];
+ if (shapeptr)
+ {
+ return *shapeptr;
+ }
+
+ // todo: shared meshes
+ DT_ShapeHandle shape = DT_NewComplexShape();
+ int p=0;
+ int numpolys = meshobj->NumPolygons();
+ if (!numpolys)
+ {
+ return NULL;
+ }
+ int numvalidpolys = 0;
+
+
+
+ for (p=0;p<meshobj->m_triangle_indices.size();p++)
+ {
+ RAS_TriangleIndex& idx = meshobj->m_triangle_indices[p];
+
+ // only add polygons that have the collisionflag set
+ if (idx.m_collider)
+ {
+ DT_Begin();
+ for (int v=0;v<3;v++)
+ {
+ int num = meshobj->m_xyz_index_to_vertex_index_mapping[idx.m_index[v]].size();
+ if (num != 1)
+ {
+ int i=0;
+ }
+ RAS_MatArrayIndex& vertindex = meshobj->m_xyz_index_to_vertex_index_mapping[idx.m_index[v]][0];
+
+ numvalidpolys++;
+
+ {
+ const MT_Point3& pt = meshobj->GetVertex(vertindex.m_array,
+ vertindex.m_index,
+ (RAS_IPolyMaterial*)vertindex.m_matid)->xyz();
+ DT_Vertex(pt[0],pt[1],pt[2]);
+ }
+ }
+ DT_End();
+ }
+ }
+
+ DT_EndComplexShape();
+
+ if (numvalidpolys > 0)
+ {
+ map_gamemesh_to_sumoshape.insert(GEN_HashedPtr(meshobj),shape);
+ return shape;
+ }
+
+ // memleak... todo: delete shape
+ return NULL;
+}
+
+
+void KX_ClearSumoSharedShapes()
+{
+ int numshapes = map_gamemesh_to_sumoshape.size();
+ for (int i=0;i<numshapes ;i++)
+ {
+ DT_ShapeHandle shape = *map_gamemesh_to_sumoshape.at(i);
+ DT_DeleteShape(shape);
+ }
+
+ map_gamemesh_to_sumoshape.clear();
+}
+
+
+
+
+
+#endif //USE_SUMO_SOLID
+
+
+#ifdef USE_ODE
+
+void KX_ConvertODEEngineObject(KX_GameObject* gameobj,
+ RAS_MeshObject* meshobj,
+ KX_Scene* kxscene,
+ struct PHY_ShapeProps* shapeprops,
+ struct PHY_MaterialProps* smmaterial,
+ struct KX_ObjectProperties* objprop)
+{
+ // not yet, future extension :)
+ bool dyna=objprop->m_dyna;
+ bool fullRigidBody= ( objprop->m_dyna && objprop->m_angular_rigidbody) != 0;
+ bool phantom = objprop->m_ghost;
+ class PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode());
+
+ class ODEPhysicsEnvironment* odeEnv =
+ (ODEPhysicsEnvironment*)kxscene->GetPhysicsEnvironment();
+
+ dxSpace* space = odeEnv->GetOdeSpace();
+ dxWorld* world = odeEnv->GetOdeWorld();
+
+ if (!objprop->m_implicitsphere &&
+ MT_fuzzyZero(objprop->m_boundingbox.m_extends[0]) ||
+ MT_fuzzyZero(objprop->m_boundingbox.m_extends[1]) ||
+ MT_fuzzyZero(objprop->m_boundingbox.m_extends[2])
+ )
+ {
+
+ } else
+ {
+
+ KX_OdePhysicsController* physicscontroller =
+ new KX_OdePhysicsController(
+ dyna,
+ fullRigidBody,
+ phantom,
+ motionstate,
+ space,
+ world,
+ shapeprops->m_mass,
+ smmaterial->m_friction,
+ smmaterial->m_restitution,
+ objprop->m_implicitsphere,
+ objprop->m_boundingbox.m_center,
+ objprop->m_boundingbox.m_extends,
+ objprop->m_radius
+ );
+
+ gameobj->SetPhysicsController(physicscontroller);
+ physicscontroller->setClientInfo(gameobj);
+ gameobj->GetSGNode()->AddSGController(physicscontroller);
+
+ bool isActor = objprop->m_isactor;
+ STR_String materialname;
+ if (meshobj)
+ materialname = meshobj->GetMaterialName(0);
+
+ const char* matname = materialname.ReadPtr();
+
+
+ physicscontroller->SetObject(gameobj->GetSGNode());
+
+ }
+}
+
+
+#endif // USE_ODE
diff --git a/source/gameengine/Ketsji/KX_EmptyObject.cpp b/source/gameengine/Ketsji/KX_EmptyObject.cpp
new file mode 100644
index 00000000000..d3b120066d9
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_EmptyObject.cpp
@@ -0,0 +1,32 @@
+/**
+ * $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 "KX_EmptyObject.h"
diff --git a/source/gameengine/Ketsji/KX_EmptyObject.h b/source/gameengine/Ketsji/KX_EmptyObject.h
new file mode 100644
index 00000000000..472cabe047e
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_EmptyObject.h
@@ -0,0 +1,45 @@
+/**
+ * $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_EMPTYOBJECT
+#define __KX_EMPTYOBJECT
+#include "KX_GameObject.h"
+
+class KX_EmptyObject : public KX_GameObject
+{
+public:
+ KX_EmptyObject(void* sgReplicationInfo,SG_Callbacks callbacks) :
+ KX_GameObject(sgReplicationInfo,callbacks)
+ {};
+ virtual ~KX_EmptyObject() {};
+
+};
+#endif //__KX_EMPTYOBJECT
diff --git a/source/gameengine/Ketsji/KX_GameActuator.cpp b/source/gameengine/Ketsji/KX_GameActuator.cpp
new file mode 100644
index 00000000000..240cef164a3
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_GameActuator.cpp
@@ -0,0 +1,186 @@
+/**
+* global game 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 "SCA_IActuator.h"
+#include "KX_GameActuator.h"
+//#include <iostream>
+#include "KX_Scene.h"
+#include "KX_KetsjiEngine.h"
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+KX_GameActuator::KX_GameActuator(SCA_IObject *gameobj,
+ int mode,
+ const STR_String& filename,
+ const STR_String& loadinganimationname,
+ KX_Scene* scene,
+ KX_KetsjiEngine* ketsjiengine,
+ PyTypeObject* T)
+ : SCA_IActuator(gameobj, T)
+{
+ m_mode = mode;
+ m_filename = filename;
+ m_loadinganimationname = loadinganimationname;
+ m_scene = scene;
+ m_ketsjiengine = ketsjiengine;
+} /* End of constructor */
+
+
+
+KX_GameActuator::~KX_GameActuator()
+{
+ // there's nothing to be done here, really....
+} /* end of destructor */
+
+
+
+CValue* KX_GameActuator::GetReplica()
+{
+ KX_GameActuator* replica = new KX_GameActuator(*this);
+ replica->ProcessReplica();
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+bool KX_GameActuator::Update(double curtime, double deltatime)
+{
+ bool result = false;
+ bool bNegativeEvent = IsNegativeEvent();
+ RemoveAllEvents();
+
+ if (bNegativeEvent)
+ return false; // do nothing on negative events
+
+ switch (m_mode)
+ {
+ case KX_GAME_LOAD:
+ case KX_GAME_START:
+ {
+ if (m_ketsjiengine)
+ {
+ STR_String exitstring = "start other game";
+ m_ketsjiengine->RequestExit(KX_EXIT_REQUEST_START_OTHER_GAME);
+ m_ketsjiengine->SetNameNextGame(m_filename);
+ m_scene->AddDebugProperty((this)->GetParent(), exitstring);
+ }
+
+ break;
+ }
+ case KX_GAME_RESTART:
+ {
+ if (m_ketsjiengine)
+ {
+ STR_String exitstring = "restarting game";
+ m_ketsjiengine->RequestExit(KX_EXIT_REQUEST_RESTART_GAME);
+ m_scene->AddDebugProperty((this)->GetParent(), exitstring);
+ }
+ break;
+ }
+ case KX_GAME_QUIT:
+ {
+ if (m_ketsjiengine)
+ {
+ STR_String exitstring = "quiting game";
+ m_ketsjiengine->RequestExit(KX_EXIT_REQUEST_QUIT_GAME);
+ m_scene->AddDebugProperty((this)->GetParent(), exitstring);
+ }
+ break;
+ }
+ default:
+ ; /* do nothing? this is an internal error !!! */
+ }
+
+ return false;
+}
+
+
+
+
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject KX_GameActuator::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "KX_SceneActuator",
+ sizeof(KX_GameActuator),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+
+
+PyParentObject KX_GameActuator::Parents[] =
+{
+ &KX_GameActuator::Type,
+ &SCA_IActuator::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+
+
+PyMethodDef KX_GameActuator::Methods[] =
+{
+ {NULL,NULL} //Sentinel
+};
+
+
+
+PyObject* KX_GameActuator::_getattr(char* attr)
+{
+ _getattr_up(SCA_IActuator);
+}
+
+
diff --git a/source/gameengine/Ketsji/KX_GameActuator.h b/source/gameengine/Ketsji/KX_GameActuator.h
new file mode 100644
index 00000000000..7f2af86db42
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_GameActuator.h
@@ -0,0 +1,86 @@
+
+//
+// actuator for global game 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 *****
+//
+
+#ifndef __KX_GAMEACTUATOR
+#define __KX_GAMEACTUATOR
+
+#include "SCA_IActuator.h"
+
+class KX_GameActuator : public SCA_IActuator
+{
+ Py_Header;
+ int m_mode;
+ bool m_restart;
+ STR_String m_filename;
+ STR_String m_loadinganimationname;
+ class KX_Scene* m_scene;
+ class KX_KetsjiEngine* m_ketsjiengine;
+
+ public:
+ enum KX_GameActuatorMode
+ {
+ KX_GAME_NODEF = 0,
+ KX_GAME_LOAD,
+ KX_GAME_START,
+ KX_GAME_RESTART,
+ KX_GAME_QUIT,
+ KX_GAME_MAX
+
+ };
+
+ KX_GameActuator(SCA_IObject* gameobj,
+ int mode,
+ const STR_String& filename,
+ const STR_String& loadinganimationname,
+ KX_Scene* scene,
+ KX_KetsjiEngine* ketsjiEngine,
+ PyTypeObject* T=&Type);
+ virtual ~KX_GameActuator();
+
+ virtual CValue* GetReplica();
+
+ virtual bool Update(double curtime,double deltatime);
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(char *attr);
+
+
+}; /* end of class KX_GameActuator */
+
+#endif
+
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
new file mode 100644
index 00000000000..1f8b3a8e1ac
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -0,0 +1,1096 @@
+/**
+ * $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 *****
+ * Game object wrapper
+ */
+
+#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
+
+
+#define KX_INERTIA_INFINITE 10000
+#include "RAS_IPolygonMaterial.h"
+#include "KX_GameObject.h"
+#include "RAS_MeshObject.h"
+#include "KX_MeshProxy.h"
+#include <stdio.h> // printf
+#include "SG_Controller.h"
+#include "KX_IPhysicsController.h"
+#include "SG_Node.h"
+#include "SG_Controller.h"
+#include "KX_ClientObjectInfo.h"
+#include "RAS_BucketManager.h"
+
+// This file defines relationships between parents and children
+// in the game engine.
+
+#include "KX_SG_NodeRelationships.h"
+
+KX_GameObject::KX_GameObject(
+ void* sgReplicationInfo,
+ SG_Callbacks callbacks,
+ PyTypeObject* T
+) :
+ SCA_IObject(T),
+ m_bUseObjectColor(false),
+ m_bDyna(false),
+ m_bSuspendDynamics(false),
+ m_pPhysicsController1(NULL),
+ m_bVisible(true)
+{
+ m_ignore_activity_culling = false;
+ m_pClient_info = new KX_ClientObjectInfo();
+ m_pSGNode = new SG_Node(this,sgReplicationInfo,callbacks);
+
+ // define the relationship between this node and it's parent.
+
+ KX_NormalParentRelation * parent_relation =
+ KX_NormalParentRelation::New();
+ m_pSGNode->SetParentRelation(parent_relation);
+
+
+};
+
+
+
+KX_GameObject::~KX_GameObject()
+{
+ // is this delete somewhere ?
+ //if (m_sumoObj)
+ // delete m_sumoObj;
+ delete m_pClient_info;
+ //if (m_pSGNode)
+ // delete m_pSGNode;
+
+}
+
+
+
+CValue* KX_GameObject:: Calc(VALUE_OPERATOR op, CValue *val)
+{
+ return NULL;
+}
+
+
+
+CValue* KX_GameObject::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val)
+{
+ return NULL;
+}
+
+
+
+const STR_String & KX_GameObject::GetText()
+{
+ return m_text;
+}
+
+
+
+float KX_GameObject::GetNumber()
+{
+ return 0;
+}
+
+
+
+STR_String KX_GameObject::GetName()
+{
+ return m_name;
+}
+
+
+
+void KX_GameObject::SetName(STR_String name)
+{
+ m_name = name;
+}; // Set the name of the value
+
+
+
+void KX_GameObject::ReplicaSetName(STR_String name)
+{
+}
+
+
+
+
+
+
+KX_IPhysicsController* KX_GameObject::GetPhysicsController()
+{
+ return m_pPhysicsController1;
+}
+
+
+
+
+
+KX_GameObject* KX_GameObject::GetParent()
+{
+ KX_GameObject* result = NULL;
+ SG_Node* node = m_pSGNode;
+
+ while (node && !result)
+ {
+ node = node->GetSGParent();
+ if (node)
+ result = (KX_GameObject*)node->GetSGClientObject();
+ }
+
+ if (result)
+ result->AddRef();
+
+ return result;
+
+}
+
+
+
+void KX_GameObject::ProcessReplica(KX_GameObject* replica)
+{
+ replica->m_pPhysicsController1 = NULL;
+ replica->m_pSGNode = NULL;
+ replica->m_pClient_info = new KX_ClientObjectInfo(*m_pClient_info);
+ replica->m_pClient_info->m_clientobject = replica;
+}
+
+
+
+CValue* KX_GameObject::GetReplica()
+{
+ KX_GameObject* replica = new KX_GameObject(*this);
+
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+ ProcessReplica(replica);
+
+ return replica;
+}
+
+
+
+void KX_GameObject::ApplyForce(const MT_Vector3& force,bool local)
+{
+ if (m_pPhysicsController1)
+ m_pPhysicsController1->ApplyForce(force,local);
+}
+
+
+
+void KX_GameObject::ApplyTorque(const MT_Vector3& torque,bool local)
+{
+ if (m_pPhysicsController1)
+ m_pPhysicsController1->ApplyTorque(torque,local);
+}
+
+
+
+void KX_GameObject::ApplyMovement(const MT_Vector3& dloc,bool local)
+{
+ if (this->IsDynamic())
+ {
+ m_pPhysicsController1->RelativeTranslate(dloc,local);
+ }
+ else
+ {
+ GetSGNode()->RelativeTranslate(dloc,GetSGNode()->GetSGParent(),local);
+ }
+}
+
+
+
+void KX_GameObject::ApplyRotation(const MT_Vector3& drot,bool local)
+{
+ MT_Matrix3x3 rotmat(drot);
+
+ if (this->IsDynamic()) //m_pPhysicsController)
+ m_pPhysicsController1->RelativeRotate(rotmat.transposed(),local);
+ else
+ // in worldspace
+ GetSGNode()->RelativeRotate(rotmat.transposed(),local);
+}
+
+
+
+/**
+GetOpenGL Matrix, returns an OpenGL 'compatible' matrix
+*/
+double* KX_GameObject::GetOpenGLMatrix()
+{
+ // todo: optimize and only update if necessary
+ double* fl = m_OpenGL_4x4Matrix.getPointer();
+ MT_Transform trans;
+
+ trans.setOrigin(GetSGNode()->GetWorldPosition());
+ trans.setBasis(GetSGNode()->GetWorldOrientation());
+
+ MT_Vector3 scaling = GetSGNode()->GetWorldScaling();
+
+ trans.scale(scaling[0], scaling[1], scaling[2]);
+ trans.getValue(fl);
+
+ return fl;
+}
+
+
+
+void KX_GameObject::Bucketize()
+{
+ double* fl = GetOpenGLMatrix();
+
+ for (int i=0;i<m_meshes.size();i++)
+ m_meshes[i]->Bucketize(fl, this, m_bUseObjectColor, m_objectColor);
+}
+
+
+
+void KX_GameObject::RemoveMeshes()
+{
+ double* fl = GetOpenGLMatrix();
+
+ for (int i=0;i<m_meshes.size();i++)
+ m_meshes[i]->RemoveFromBuckets(fl, this);
+
+ //note: meshes can be shared, and are deleted by KX_BlenderSceneConverter
+
+ m_meshes.clear();
+}
+
+
+
+void KX_GameObject::UpdateNonDynas()
+{
+ if (m_pPhysicsController1)
+ {
+ m_pPhysicsController1->SetSumoTransform(true);
+ }
+}
+
+
+
+void KX_GameObject::UpdateTransform()
+{
+ if (m_pPhysicsController1)
+ {
+ m_pPhysicsController1->SetSumoTransform(false);
+ }
+}
+
+
+
+void KX_GameObject::SetDebugColor(unsigned int bgra)
+{
+ for (int i=0;i<m_meshes.size();i++)
+ m_meshes[i]->DebugColor(bgra);
+}
+
+
+
+void KX_GameObject::ResetDebugColor()
+{
+ SetDebugColor(0xff000000);
+}
+
+
+
+void KX_GameObject::UpdateIPO(float curframetime,
+ bool recurse,
+ bool ipo_as_force,
+ bool force_local)
+{
+
+ // The ipo-actuator needs a sumo reference... this is retrieved (unfortunately)
+ // by the iposgcontr itself...
+// ipocontr->SetSumoReference(gameobj->GetSumoScene(),
+// gameobj->GetSumoObject());
+
+
+ // The ipo has to be treated as a force, and not a displacement!
+ // For this case, we send some settings to the controller. This
+ // may need some caching...
+ if (ipo_as_force) {
+ SGControllerList::iterator it = GetSGNode()->GetSGControllerList().begin();
+
+ while (it != GetSGNode()->GetSGControllerList().end()) {
+ (*it)->SetOption(SG_Controller::SG_CONTR_IPO_IPO_AS_FORCE, ipo_as_force);
+ (*it)->SetOption(SG_Controller::SG_CONTR_IPO_FORCES_ACT_LOCAL, force_local);
+ it++;
+ }
+ }
+
+ // The rest is the 'normal' update procedure.
+ GetSGNode()->SetSimulatedTime(curframetime,recurse);
+ GetSGNode()->UpdateWorldData(curframetime);
+ UpdateTransform();
+}
+
+
+/*
+void KX_GameObject::RegisterSumoObject(class SM_Scene* sumoScene,
+ DT_SceneHandle solidscene,
+ class SM_Object* sumoObj,
+ const char* matname,
+ bool isDynamic,
+ bool isActor)
+{
+ m_bDyna = isDynamic;
+
+ // need easy access, not via 'node' etc.
+ m_pPhysicsController = new KX_PhysicsController(sumoScene,solidscene,sumoObj,isDynamic);
+
+ GetSGNode()->AddSGController(m_pPhysicsController);
+
+ m_pClient_info->m_type = (isActor ? 1 : 0);
+ m_pClient_info->m_clientobject = this;
+
+ // store materialname in auxinfo, needed for touchsensors
+ m_pClient_info->m_auxilary_info = (matname? (void*)(matname+2) : NULL);
+ m_pPhysicsController->SetObject(this->GetSGNode());
+}
+*/
+
+bool
+KX_GameObject::GetVisible(
+ void
+ )
+{
+ return m_bVisible;
+}
+
+void
+KX_GameObject::SetVisible(
+ bool v
+ )
+{
+ m_bVisible = v;
+}
+
+// used by Python, and the actuatorshould _not_ be misused by the
+// scene!
+void
+KX_GameObject::MarkVisible(
+ bool visible
+ )
+{
+ /* If explicit visibility settings are used, this is
+ * determined on this level. Maybe change this to mesh level
+ * later on? */
+
+ for (int i=0;i<m_meshes.size();i++)
+ {
+ double* fl = GetOpenGLMatrix();
+ m_meshes[i]->MarkVisible(fl,this,visible,m_bUseObjectColor,m_objectColor);
+ }
+}
+
+
+// Always use the flag?
+void
+KX_GameObject::MarkVisible(
+ void
+ )
+{
+ for (int i=0;i<m_meshes.size();i++)
+ {
+ double* fl = GetOpenGLMatrix();
+ m_meshes[i]->MarkVisible(fl,
+ this,
+ m_bVisible,
+ m_bUseObjectColor,
+ m_objectColor
+ );
+ }
+}
+
+void KX_GameObject::addLinearVelocity(const MT_Vector3& lin_vel,bool local)
+{
+// if (m_pPhysicsController1)
+// m_pPhysicsController1->AddLinearVelocity(lin_vel,local);
+}
+
+
+
+void KX_GameObject::setLinearVelocity(const MT_Vector3& lin_vel,bool local)
+{
+ if (m_pPhysicsController1)
+ m_pPhysicsController1->SetLinearVelocity(lin_vel,local);
+}
+
+
+
+void KX_GameObject::setAngularVelocity(const MT_Vector3& ang_vel,bool local)
+{
+ if (m_pPhysicsController1)
+ m_pPhysicsController1->SetAngularVelocity(ang_vel,local);
+}
+
+
+
+void KX_GameObject::SetObjectColor(const MT_Vector4& rgbavec)
+{
+ m_bUseObjectColor = true;
+ m_objectColor = rgbavec;
+}
+
+
+
+MT_Vector3 KX_GameObject::GetLinearVelocity()
+{
+ MT_Vector3 velocity(0.0,0.0,0.0);
+
+ if (m_pPhysicsController1)
+ {
+ velocity = m_pPhysicsController1->GetLinearVelocity();
+ }
+ return velocity;
+
+}
+
+
+// scenegraph node stuff
+
+void KX_GameObject::NodeSetLocalPosition(const MT_Point3& trans)
+{
+ if (m_pPhysicsController1)
+ {
+ m_pPhysicsController1->setPosition(trans);
+ }
+
+ GetSGNode()->SetLocalPosition(trans);
+}
+
+
+
+void KX_GameObject::NodeSetLocalOrientation(const MT_Matrix3x3& rot)
+{
+ if (m_pPhysicsController1)
+ {
+ m_pPhysicsController1->setOrientation(rot.getRotation());
+ }
+
+ GetSGNode()->SetLocalOrientation(rot);
+}
+
+
+
+void KX_GameObject::NodeSetLocalScale(const MT_Vector3& scale)
+{
+ if (m_pPhysicsController1)
+ {
+ m_pPhysicsController1->setScaling(scale);
+ }
+
+ GetSGNode()->SetLocalScale(scale);
+}
+
+
+
+void KX_GameObject::NodeSetRelativeScale(const MT_Vector3& scale)
+{
+ GetSGNode()->RelativeScale(scale);
+}
+
+
+
+void KX_GameObject::NodeUpdateGS(double time,bool bInitiator)
+{
+ GetSGNode()->UpdateWorldData(time);
+}
+
+
+
+const MT_Matrix3x3& KX_GameObject::NodeGetWorldOrientation() const
+{
+ return GetSGNode()->GetWorldOrientation();
+}
+
+
+
+const MT_Vector3& KX_GameObject::NodeGetWorldScaling() const
+{
+ return GetSGNode()->GetWorldScaling();
+}
+
+
+
+const MT_Point3& KX_GameObject::NodeGetWorldPosition() const
+{
+ return GetSGNode()->GetWorldPosition();
+}
+
+/* Suspend/ resume: for the dynamic behaviour, there is a simple
+ * method. For the residual motion, there is not. I wonder what the
+ * correct solution is for Sumo. Remove from the motion-update tree?
+ *
+ * So far, only switch the physics and logic.
+ * */
+
+void KX_GameObject::Resume(void)
+{
+ if (m_suspended) {
+ SCA_IObject::Resume();
+ GetPhysicsController()->RestoreDynamics();
+
+ m_suspended = false;
+ }
+}
+
+void KX_GameObject::Suspend(void)
+{
+ if ((!m_ignore_activity_culling)
+ && (!m_suspended)) {
+ SCA_IObject::Suspend();
+ GetPhysicsController()->SuspendDynamics();
+ m_suspended = true;
+ }
+}
+
+
+
+
+/* ------- python stuff ---------------------------------------------------*/
+
+
+
+
+PyMethodDef KX_GameObject::Methods[] = {
+ {"setVisible",(PyCFunction) KX_GameObject::sPySetVisible, METH_VARARGS},
+ {"setPosition", (PyCFunction) KX_GameObject::sPySetPosition, METH_VARARGS},
+ {"getPosition", (PyCFunction) KX_GameObject::sPyGetPosition, METH_VARARGS},
+ {"getLinearVelocity", (PyCFunction) KX_GameObject::sPyGetLinearVelocity, METH_VARARGS},
+ {"getVelocity", (PyCFunction) KX_GameObject::sPyGetVelocity, METH_VARARGS},
+ {"getOrientation", (PyCFunction) KX_GameObject::sPyGetOrientation, METH_VARARGS},
+ {"setOrientation", (PyCFunction) KX_GameObject::sPySetOrientation, METH_VARARGS},
+ {"getMass", (PyCFunction) KX_GameObject::sPyGetMass, METH_VARARGS},
+ {"getReactionForce", (PyCFunction) KX_GameObject::sPyGetReactionForce, METH_VARARGS},
+ {"applyImpulse", (PyCFunction) KX_GameObject::sPyApplyImpulse, METH_VARARGS},
+ {"suspendDynamics", (PyCFunction)KX_GameObject::sPySuspendDynamics,METH_VARARGS},
+ {"restoreDynamics", (PyCFunction)KX_GameObject::sPyRestoreDynamics,METH_VARARGS},
+ {"enableRigidBody", (PyCFunction)KX_GameObject::sPyEnableRigidBody,METH_VARARGS},
+ {"disableRigidBody", (PyCFunction)KX_GameObject::sPyDisableRigidBody,METH_VARARGS},
+ {"getParent", (PyCFunction)KX_GameObject::sPyGetParent,METH_VARARGS},
+ {"getMesh", (PyCFunction)KX_GameObject::sPyGetMesh,METH_VARARGS},
+ {"getPhysicsId", (PyCFunction)KX_GameObject::sPyGetPhysicsId,METH_VARARGS},
+
+
+ {NULL,NULL} //Sentinel
+};
+
+
+
+
+bool KX_GameObject::ConvertPythonVectorArgs(PyObject* args,
+ MT_Vector3& pos,
+ MT_Vector3& pos2)
+{
+ PyObject* pylist;
+ PyObject* pylist2;
+ bool error = (PyArg_ParseTuple(args,"OO",&pylist,&pylist2)) != 0;
+
+ pos = ConvertPythonPylist(pylist);
+ pos2 = ConvertPythonPylist(pylist2);
+
+ return error;
+}
+
+
+
+PyObject* KX_GameObject::sPySetPosition(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ return ((KX_GameObject*) self)->PySetPosition(self, args, kwds);
+}
+
+
+
+PyObject* KX_GameObject::PyGetPosition(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ MT_Point3 pos = NodeGetWorldPosition();
+
+ PyObject* resultlist = PyList_New(3);
+ int index;
+ for (index=0;index<3;index++)
+ {
+ PyList_SetItem(resultlist,index,PyFloat_FromDouble(pos[index]));
+ }
+
+ return resultlist;
+
+}
+
+
+
+PyTypeObject KX_GameObject::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "KX_GameObject",
+ sizeof(KX_GameObject),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+
+
+PyParentObject KX_GameObject::Parents[] = {
+ &KX_GameObject::Type,
+ &SCA_IObject::Type,
+ &CValue::Type,
+ NULL
+};
+
+
+
+
+PyObject* KX_GameObject::_getattr(char* attr)
+{
+ _getattr_up(SCA_IObject);
+}
+
+
+
+PyObject* KX_GameObject::PyGetLinearVelocity(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ // only can get the velocity if we have a physics object connected to us...
+ MT_Vector3 velocity = GetLinearVelocity();
+
+ PyObject* resultlist = PyList_New(3);
+ int index;
+ for (index=0;index<3;index++)
+ {
+ PyList_SetItem(resultlist,index,PyFloat_FromDouble(velocity[index]));
+ }
+
+ return resultlist;
+}
+
+
+
+PyObject* KX_GameObject::PySetVisible(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ int visible = 1;
+
+ if (PyArg_ParseTuple(args,"i",&visible))
+ {
+ MarkVisible(visible!=0);
+ m_bVisible = (visible!=0);
+ }
+ else
+ {
+ return NULL;
+ }
+ Py_Return;
+
+}
+
+
+
+PyObject* KX_GameObject::PyGetVelocity(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ // only can get the velocity if we have a physics object connected to us...
+ MT_Vector3 velocity(0.0,0.0,0.0);
+ MT_Point3 point(0.0,0.0,0.0);
+
+
+ MT_Point3 pos;
+ PyObject* pylist;
+ bool error = false;
+
+ int len = PyTuple_Size(args);
+
+ if ((len > 0) && PyArg_ParseTuple(args,"O",&pylist))
+ {
+ if (pylist->ob_type == &CListValue::Type)
+ {
+ CListValue* listval = (CListValue*) pylist;
+ if (listval->GetCount() == 3)
+ {
+ int index;
+ for (index=0;index<3;index++)
+ {
+ pos[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<3;index++)
+ {
+ pos[index] = PyFloat_AsDouble(PyList_GetItem(pylist,index));
+ }
+ }
+ else
+ {
+ error = true;
+ }
+ }
+
+ if (!error)
+ point = pos;
+ }
+
+
+ if (m_pPhysicsController1)
+ {
+ velocity = m_pPhysicsController1->GetVelocity(point);
+ }
+
+ PyObject* resultlist = PyList_New(3);
+ int index;
+ for (index=0;index<3;index++)
+ {
+ PyList_SetItem(resultlist,index,PyFloat_FromDouble(velocity[index]));
+ }
+
+ return resultlist;
+}
+
+
+
+PyObject* KX_GameObject::PyGetMass(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ PyObject* pymass = NULL;
+
+ float mass = GetPhysicsController()->GetMass();
+ pymass = PyFloat_FromDouble(mass);
+
+ if (pymass)
+ return pymass;
+
+ Py_Return;
+}
+
+
+
+PyObject* KX_GameObject::PyGetReactionForce(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ // only can get the velocity if we have a physics object connected to us...
+
+ MT_Vector3 reaction_force = GetPhysicsController()->getReactionForce();
+
+ PyObject* resultlist = PyList_New(3);
+ int index;
+ for (index=0;index<3;index++)
+ {
+ PyList_SetItem(resultlist,index,
+ PyFloat_FromDouble(reaction_force[index]));
+ }
+
+ return resultlist;
+}
+
+
+
+PyObject* KX_GameObject::PyEnableRigidBody(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+
+ GetPhysicsController()->setRigidBody(true);
+
+ Py_Return;
+}
+
+
+
+PyObject* KX_GameObject::PyDisableRigidBody(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ GetPhysicsController()->setRigidBody(false);
+
+ Py_Return;
+}
+
+
+
+PyObject* KX_GameObject::PyGetParent(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ KX_GameObject* parent = this->GetParent();
+ if (parent)
+ return parent;
+ Py_Return;
+}
+
+
+
+PyObject* KX_GameObject::PyGetMesh(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ if (m_meshes.size() > 0)
+ {
+ KX_MeshProxy* meshproxy = new KX_MeshProxy(m_meshes[0]);
+ return meshproxy;
+ }
+
+ Py_Return;
+}
+
+
+
+PyObject* KX_GameObject::PyApplyImpulse(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+
+ MT_Point3 attach(0, 1, 0);
+ MT_Vector3 impulse(1, 0, 0);
+
+ if (ConvertPythonVectorArgs(args,attach,impulse))
+ {
+ if (m_pPhysicsController1)
+ {
+ m_pPhysicsController1->applyImpulse(attach, impulse);
+ }
+
+ }
+
+ Py_Return;
+}
+
+
+
+PyObject* KX_GameObject::PySuspendDynamics(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ if (m_bSuspendDynamics)
+ {
+ Py_Return;
+ }
+
+ if (m_pPhysicsController1)
+ {
+ m_pPhysicsController1->SuspendDynamics();
+ }
+ m_bSuspendDynamics = true;
+
+ Py_Return;
+}
+
+
+
+PyObject* KX_GameObject::PyRestoreDynamics(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+
+ if (!m_bSuspendDynamics)
+ {
+ Py_Return;
+ }
+
+ if (m_pPhysicsController1)
+ {
+ m_pPhysicsController1->RestoreDynamics();
+ }
+ m_bSuspendDynamics = false;
+
+ Py_Return;
+}
+
+
+
+PyObject* KX_GameObject::PyGetOrientation(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) //keywords
+{
+ // do the conversion of a C++ matrix to a python list
+
+ PyObject* resultlist = PyList_New(3);
+
+
+ int row,col;
+ const MT_Matrix3x3& orient = NodeGetWorldOrientation();
+
+ int index = 0;
+ for (row=0;row<3;row++)
+ {
+ PyObject* veclist = PyList_New(3);
+
+ for (col=0;col<3;col++)
+ {
+ const MT_Scalar fl = orient[row][col];
+ PyList_SetItem(veclist,col,PyFloat_FromDouble(fl));
+ }
+ PyList_SetItem(resultlist,row,veclist);
+
+ }
+ return resultlist;
+}
+
+
+
+PyObject* KX_GameObject::PySetOrientation(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ MT_Matrix3x3 matrix;
+
+ PyObject* pylist;
+ bool error = false;
+ int row,col;
+
+ PyArg_ParseTuple(args,"O",&pylist);
+
+ if (pylist->ob_type == &CListValue::Type)
+ {
+ CListValue* listval = (CListValue*) pylist;
+ if (listval->GetCount() == 3)
+ {
+ for (row=0;row<3;row++) // each row has a 3-vector [x,y,z]
+ {
+ CListValue* vecval = (CListValue*)listval->GetValue(row);
+ for (col=0;col<3;col++)
+ {
+ matrix[row][col] = vecval->GetValue(col)->GetNumber();
+
+ }
+ }
+ }
+ else
+ {
+ error = true;
+ }
+ }
+ else
+ {
+ // assert the list is long enough...
+ int numitems = PyList_Size(pylist);
+ if (numitems == 3)
+ {
+ for (row=0;row<3;row++) // each row has a 3-vector [x,y,z]
+ {
+
+ PyObject* veclist = PyList_GetItem(pylist,row); // here we have a vector3 list
+ for (col=0;col<3;col++)
+ {
+ matrix[row][col] = PyFloat_AsDouble(PyList_GetItem(veclist,col));
+
+ }
+ }
+ }
+ else
+ {
+ error = true;
+ }
+ }
+
+ if (!error)
+ {
+ if (m_pPhysicsController1)
+ {
+ m_pPhysicsController1->setOrientation(matrix.getRotation());
+ }
+ NodeSetLocalOrientation(matrix);
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+
+PyObject* KX_GameObject::PySetPosition(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ // make a general function for this, it's needed many times
+
+ MT_Point3 pos = ConvertPythonVectorArg(args);
+ if (this->m_pPhysicsController1)
+ {
+ this->m_pPhysicsController1->setPosition(pos);
+ }
+ NodeSetLocalPosition(pos);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyObject* KX_GameObject::PyGetPhysicsId(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ KX_IPhysicsController* ctrl = GetPhysicsController();
+ int physid=0;
+ if (ctrl)
+ {
+ physid= (int)ctrl->GetUserData();
+ }
+ return PyInt_FromLong(physid);
+}
+
+/* ---------------------------------------------------------------------
+ * Some stuff taken from the header
+ * --------------------------------------------------------------------- */
+void KX_GameObject::Relink(GEN_Map<GEN_HashedPtr, void*> *map_parameter)
+{
+ /* intentionally empty ? */
+}
+
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
new file mode 100644
index 00000000000..c9c9ccafd0d
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -0,0 +1,614 @@
+/*
+ * $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 *****
+ * General KX game object.
+ */
+
+#ifndef __KX_GAMEOBJECT
+#define __KX_GAMEOBJECT
+
+
+#ifdef WIN32
+// get rid of this stupid "warning 'this' used in initialiser list", generated by VC when including Solid/Sumo
+#pragma warning (disable : 4355)
+#endif
+
+
+#include "ListValue.h"
+#include "SCA_IObject.h"
+#include "SG_Node.h"
+#include "MT_Transform.h"
+#include "MT_CmMatrix4x4.h"
+#include "GEN_Map.h"
+#include "GEN_HashedPtr.h"
+
+#define KX_FIXED_FRAME_PER_SEC 25.0f
+#define KX_FIXED_SEC_PER_FRAME (1.0f / KX_FIXED_FRAME_PER_SEC)
+#define KX_OB_DYNAMIC 1
+
+
+//Forward declarations.
+struct KX_ClientObjectInfo;
+class RAS_MeshObject;
+class KX_IPhysicsController;
+class SM_Object;
+
+class KX_GameObject : public SCA_IObject
+{
+ Py_Header;
+
+ bool m_bDyna;
+ KX_ClientObjectInfo* m_pClient_info;
+ STR_String m_name;
+ STR_String m_text;
+ std::vector<RAS_MeshObject*> m_meshes;
+
+ bool m_bSuspendDynamics;
+ bool m_bUseObjectColor;
+ MT_Vector4 m_objectColor;
+
+ // Is this object set to be visible? Only useful for the
+ // visibility subsystem right now.
+ bool m_bVisible;
+
+ KX_IPhysicsController* m_pPhysicsController1;
+ SG_Node* m_pSGNode;
+
+protected:
+ MT_CmMatrix4x4 m_OpenGL_4x4Matrix;
+
+public:
+ virtual void /* This function should be virtual - derived classed override it */
+ Relink(
+ GEN_Map<GEN_HashedPtr, void*> *map
+ );
+
+ /**
+ * Compute an OpenGl compatable 4x4 matrix. Has the
+ * side effect of storing the result internally. The
+ * memory for the matrix remains the property of this class.
+ */
+ double*
+ GetOpenGLMatrix(
+ );
+
+ /**
+ * Return a pointer to a MT_CmMatrix4x4 storing the
+ * opengl transformation for this object. This is updated
+ * by a call to GetOpenGLMatrix(). This class owns the
+ * memory for the returned matrix.
+ */
+
+ MT_CmMatrix4x4*
+ GetOpenGLMatrixPtr(
+ ) {
+ return &m_OpenGL_4x4Matrix;
+ };
+
+ /**
+ * Get a pointer to the game object that is the parent of
+ * this object. Or NULL if there is no parent. The returned
+ * object is part of a reference counting scheme. Calling
+ * this function ups the reference count on the returned
+ * object. It is the responsibility of the caller to decrement
+ * the reference count when you have finished with it.
+ */
+ KX_GameObject*
+ GetParent(
+ );
+
+
+ /**
+ * Construct a game object. This class also inherits the
+ * default constructors - use those with care!
+ */
+
+ KX_GameObject(
+ void* sgReplicationInfo,
+ SG_Callbacks callbacks,
+ PyTypeObject* T=&Type
+ );
+
+ virtual
+ ~KX_GameObject(
+ );
+
+ CValue*
+ AddRef() {
+ /* temporarily to find memleaks */ return CValue::AddRef();
+ }
+
+ /**
+ * @section Stuff which is here due to poor design.
+ * Inherited from CValue and needs an implementation.
+ * Do not expect these functions do to anything sensible.
+ */
+
+ /**
+ * Inherited from CValue -- does nothing!
+ */
+ CValue*
+ Calc(
+ VALUE_OPERATOR op,
+ CValue *val
+ );
+
+ /**
+ * Inherited from CValue -- does nothing!
+ */
+ CValue*
+ CalcFinal(
+ VALUE_DATA_TYPE dtype,
+ VALUE_OPERATOR op,
+ CValue *val
+ );
+
+ /**
+ * Inherited from CValue -- does nothing!
+ */
+ const
+ STR_String &
+ GetText(
+ );
+
+ /**
+ * Inherited from CValue -- does nothing!
+ */
+ float
+ GetNumber(
+ );
+
+ /**
+ * @section Inherited from CValue. These are the useful
+ * part of the CValue interface that this class implements.
+ */
+
+ /**
+ * Inherited from CValue -- returns the name of this object.
+ */
+ STR_String
+ GetName(
+ );
+
+ /**
+ * Inherited from CValue -- set the name of this object.
+ */
+ void
+ SetName(
+ STR_String name
+ );
+
+ /**
+ * Inherited from CValue -- does nothing.
+ */
+ void
+ ReplicaSetName(
+ STR_String name
+ );
+
+ /**
+ * Inherited from CValue -- return a new copy of this
+ * instance allocated on the heap. Ownership of the new
+ * object belongs with the caller.
+ */
+ CValue*
+ GetReplica(
+ );
+
+ /**
+ * Inherited from CValue -- Makes sure any internal
+ * data owned by this class is deep copied. Called internally
+ */
+ void
+ ProcessReplica(
+ KX_GameObject* replica
+ );
+
+ /**
+ * Return the linear velocity of the game object.
+ */
+ MT_Vector3
+ GetLinearVelocity(
+ );
+
+ /**
+ * Quick'n'dirty obcolor ipo stuff
+ */
+
+ void
+ SetObjectColor(
+ const MT_Vector4& rgbavec
+ );
+
+
+
+
+ /**
+ * @return a pointer to the physics controller owned by this class.
+ */
+
+ KX_IPhysicsController*
+ GetPhysicsController(
+ ) ;
+
+ void SetPhysicsController
+ (KX_IPhysicsController* physicscontroller)
+ { m_pPhysicsController1 = physicscontroller;};
+
+
+ /**
+ * @section Coordinate system manipulation functions
+ */
+
+ void
+ NodeSetLocalPosition(
+ const MT_Point3& trans
+ );
+
+ void
+ NodeSetLocalOrientation(
+ const MT_Matrix3x3& rot
+ );
+
+ void
+ NodeSetLocalScale(
+ const MT_Vector3& scale
+ );
+
+ void
+ NodeSetRelativeScale(
+ const MT_Vector3& scale
+ );
+
+ void
+ NodeUpdateGS(
+ double time,
+ bool bInitiator
+ );
+
+ const
+ MT_Matrix3x3&
+ NodeGetWorldOrientation(
+ ) const;
+
+ const
+ MT_Vector3&
+ NodeGetWorldScaling(
+ ) const;
+
+ const
+ MT_Point3&
+ NodeGetWorldPosition(
+ ) const;
+
+
+ /**
+ * @section scene graph node accessor functions.
+ */
+
+ SG_Node*
+ GetSGNode(
+ ) {
+ return m_pSGNode;
+ }
+
+ const
+ SG_Node*
+ GetSGNode(
+ ) const {
+ return m_pSGNode;
+ }
+
+ /**
+ * Set the Scene graph node for this game object.
+ * warning - it is your responsibility to make sure
+ * all controllers look at this new node. You must
+ * also take care of the memory associated with the
+ * old node. This class takes ownership of the new
+ * node.
+ */
+ void
+ SetSGNode(
+ SG_Node* node
+ ){
+ m_pSGNode = node;
+ }
+
+ bool
+ IsDynamic(
+ ) const {
+ return m_bDyna;
+ }
+
+
+ /**
+ * @section Physics accessors for this node.
+ *
+ * All these calls get passed directly to the physics controller
+ * owned by this object.
+ * This is real interface bloat. Why not just use the physics controller
+ * directly? I think this is because the python interface is in the wrong
+ * place.
+ */
+
+ void
+ ApplyForce(
+ const MT_Vector3& force, bool local
+ );
+
+ void
+ ApplyTorque(
+ const MT_Vector3& torque,
+ bool local
+ );
+
+ void
+ ApplyRotation(
+ const MT_Vector3& drot,
+ bool local
+ );
+
+ void
+ ApplyMovement(
+ const MT_Vector3& dloc,
+ bool local
+ );
+
+ void
+ addLinearVelocity(
+ const MT_Vector3& lin_vel,
+ bool local
+ );
+
+ void
+ setLinearVelocity(
+ const MT_Vector3& lin_vel,
+ bool local
+ );
+
+ void
+ setAngularVelocity(
+ const MT_Vector3& ang_vel,
+ bool local
+ );
+
+ /**
+ * Update the physics object transform based upon the current SG_Node
+ * position.
+ */
+ void
+ UpdateTransform(
+ );
+
+ /**
+ * Only update the transform if it's a non-dynamic object
+ */
+ void
+ UpdateNonDynas(
+ );
+
+ /**
+ * Odd function to update an ipo. ???
+ */
+ void
+ UpdateIPO(
+ float curframetime,
+ bool resurse,
+ bool ipo_as_force,
+ bool force_ipo_local
+ );
+
+ /**
+ * @section Mesh accessor functions.
+ */
+
+ /**
+ * Run through the meshes associated with this
+ * object and bucketize them. See RAS_Mesh for
+ * more details on this function. Interesting to
+ * note that polygon bucketizing seems to happen on a per
+ * object basis. Which may explain why there is such
+ * a big performance gain when all static objects
+ * are joined into 1.
+ */
+ void
+ Bucketize(
+ );
+
+ /**
+ * Clear the meshes associated with this class
+ * and remove from the bucketing system.
+ * Don't think this actually deletes any of the meshes.
+ */
+ void
+ RemoveMeshes(
+ );
+
+ /**
+ * Add a mesh to the set of meshes associated with this
+ * node. Meshes added in this way are not deleted by this class.
+ * Make sure you call RemoveMeshes() before deleting the
+ * mesh though,
+ */
+ void
+ AddMesh(
+ RAS_MeshObject* mesh
+ ){
+ m_meshes.push_back(mesh);
+ }
+
+ /**
+ * Pick out a mesh associated with the integer 'num'.
+ */
+ RAS_MeshObject*
+ GetMesh(
+ int num
+ ) const {
+ return m_meshes[num];
+ }
+
+ /**
+ * Return the number of meshes currently associated with this
+ * game object.
+ */
+ int
+ GetMeshCount(
+ ) const {
+ return m_meshes.size();
+ }
+
+ /**
+ * Set the debug color of the meshes associated with this
+ * class. Does this still work?
+ */
+ void
+ SetDebugColor(
+ unsigned int bgra
+ );
+
+ /**
+ * Reset the debug color of meshes associated with this class.
+ */
+ void
+ ResetDebugColor(
+ );
+
+ /**
+ * Set the visibility of the meshes associated with this
+ * object.
+ */
+ void
+ MarkVisible(
+ bool visible
+ );
+
+ /**
+ * Set the visibility according to the visibility flag.
+ */
+ void
+ MarkVisible(
+ void
+ );
+
+
+ /**
+ * Was this object marked visible? (only for the ewxplicit
+ * visibility system).
+ */
+ bool
+ GetVisible(
+ void
+ );
+
+ /**
+ * Set visibility flag of this object
+ */
+ void
+ SetVisible(
+ bool b
+ );
+
+
+ /**
+ * @section Logic bubbling methods.
+ */
+
+ /**
+ * Stop making progress
+ */
+ void Suspend(void);
+
+ /**
+ * Resume making progress
+ */
+ void Resume(void);
+
+ /**
+ * @section Python interface functions.
+ */
+
+ virtual
+ PyObject*
+ _getattr(
+ char *attr
+ );
+
+ PyObject*
+ PySetPosition(
+ PyObject* self,
+ PyObject* args,
+ PyObject* kwds
+ );
+
+ static
+ PyObject*
+ sPySetPosition(
+ PyObject* self,
+ PyObject* args,
+ PyObject* kwds
+ );
+
+ KX_PYMETHOD(KX_GameObject,GetPosition);
+ KX_PYMETHOD(KX_GameObject,GetLinearVelocity);
+ KX_PYMETHOD(KX_GameObject,GetVelocity);
+ KX_PYMETHOD(KX_GameObject,GetMass);
+ KX_PYMETHOD(KX_GameObject,GetReactionForce);
+ KX_PYMETHOD(KX_GameObject,GetOrientation);
+ KX_PYMETHOD(KX_GameObject,SetOrientation);
+ KX_PYMETHOD(KX_GameObject,SetVisible);
+ KX_PYMETHOD(KX_GameObject,SuspendDynamics);
+ KX_PYMETHOD(KX_GameObject,RestoreDynamics);
+ KX_PYMETHOD(KX_GameObject,EnableRigidBody);
+ KX_PYMETHOD(KX_GameObject,DisableRigidBody);
+ KX_PYMETHOD(KX_GameObject,ApplyImpulse);
+ KX_PYMETHOD(KX_GameObject,GetMesh);
+ KX_PYMETHOD(KX_GameObject,GetParent);
+ KX_PYMETHOD(KX_GameObject,GetPhysicsId);
+
+private :
+
+ /**
+ * Random internal function to convert python function arguments
+ * to 2 vectors.
+ * @return true if conversion was possible.
+ */
+
+ bool
+ ConvertPythonVectorArgs(
+ PyObject* args,
+ MT_Vector3& pos,
+ MT_Vector3& pos2
+ );
+
+};
+
+
+#endif //__KX_GAMEOBJECT
+
diff --git a/source/gameengine/Ketsji/KX_IInterpolator.h b/source/gameengine/Ketsji/KX_IInterpolator.h
new file mode 100644
index 00000000000..974f458681b
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_IInterpolator.h
@@ -0,0 +1,46 @@
+/**
+ * $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_IINTERPOLATOR_H
+#define KX_IINTERPOLATOR_H
+
+#include <vector>
+
+class KX_IInterpolator {
+public:
+ virtual ~KX_IInterpolator() {}
+
+ virtual void Execute(float currentTime) const = 0;
+};
+
+typedef std::vector<KX_IInterpolator *> T_InterpolatorList;
+
+#endif
diff --git a/source/gameengine/Ketsji/KX_IPOTransform.h b/source/gameengine/Ketsji/KX_IPOTransform.h
new file mode 100644
index 00000000000..9f9f4a92602
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_IPOTransform.h
@@ -0,0 +1,92 @@
+/**
+ * An abstract object you can move around in a 3d world, and has some logic
+ *
+ * $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_IPOTRANSFORM_H
+#define KX_IPOTRANSFORM_H
+
+#include "MT_Transform.h"
+
+class KX_IPOTransform {
+public:
+ KX_IPOTransform() :
+ m_position(0.0, 0.0, 0.0),
+ m_eulerAngles(0.0, 0.0, 0.0),
+ m_scaling(1.0, 1.0, 1.0),
+ m_deltaPosition(0.0, 0.0, 0.0),
+ m_deltaEulerAngles(0.0, 0.0, 0.0),
+ m_deltaScaling(0.0, 0.0, 0.0)
+ {}
+
+ MT_Transform GetTransform() const {
+ return MT_Transform(m_position + m_deltaPosition,
+ MT_Matrix3x3(m_eulerAngles + m_deltaEulerAngles,
+ m_scaling + m_deltaScaling));
+ }
+
+ MT_Point3& GetPosition() { return m_position; }
+ MT_Vector3& GetEulerAngles() { return m_eulerAngles; }
+ MT_Vector3& GetScaling() { return m_scaling; }
+
+ const MT_Point3& GetPosition() const { return m_position; }
+ const MT_Vector3& GetEulerAngles() const { return m_eulerAngles; }
+ const MT_Vector3& GetScaling() const { return m_scaling; }
+
+ MT_Vector3& GetDeltaPosition() { return m_deltaPosition; }
+ MT_Vector3& GetDeltaEulerAngles() { return m_deltaEulerAngles; }
+ MT_Vector3& GetDeltaScaling() { return m_deltaScaling; }
+
+ void SetPosition(const MT_Point3& pos) { m_position = pos; }
+ void SetEulerAngles(const MT_Vector3& eul) { m_eulerAngles = eul; }
+ void SetScaling(const MT_Vector3& scaling) { m_scaling = scaling; }
+
+ void ClearDeltaStuff() {
+ m_deltaPosition.setValue(0.0, 0.0, 0.0);
+ m_deltaEulerAngles.setValue(0.0, 0.0, 0.0);
+ m_deltaScaling.setValue(0.0, 0.0, 0.0);
+ }
+
+protected:
+ MT_Point3 m_position;
+ MT_Vector3 m_eulerAngles;
+ MT_Vector3 m_scaling;
+ MT_Vector3 m_deltaPosition;
+ MT_Vector3 m_deltaEulerAngles;
+ MT_Vector3 m_deltaScaling;
+};
+
+#endif
+
+
+
+
diff --git a/source/gameengine/Ketsji/KX_IPO_SGController.cpp b/source/gameengine/Ketsji/KX_IPO_SGController.cpp
new file mode 100644
index 00000000000..ea5617b017a
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_IPO_SGController.cpp
@@ -0,0 +1,193 @@
+/**
+ * $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 *****
+ * Scenegraph controller for ipos.
+ */
+
+#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 "KX_IPO_SGController.h"
+#include "KX_ScalarInterpolator.h"
+#include "KX_GameObject.h"
+
+// All objects should start on frame 1! Will we ever need an object to
+// start on another frame, the 1.0 should change.
+KX_IpoSGController::KX_IpoSGController()
+: m_ipotime(1.0),
+ m_modify_position(false),
+ m_modify_orientation(false),
+ m_modify_scaling(false),
+ m_modified(true),
+ m_ipo_as_force(false),
+ m_force_ipo_acts_local(false)
+{
+ m_sumo_object = NULL;
+ m_game_object = NULL;
+
+}
+
+
+void KX_IpoSGController::SetOption(
+ int option,
+ int value)
+{
+ switch (option) {
+ case SG_CONTR_IPO_IPO_AS_FORCE:
+ m_ipo_as_force = (value != 0);
+ m_modified = true;
+ break;
+ case SG_CONTR_IPO_FORCES_ACT_LOCAL:
+ m_force_ipo_acts_local = (value != 0);
+ m_modified = true;
+ break;
+ default:
+ ; /* just ignore the rest */
+ }
+}
+
+ void
+KX_IpoSGController::UpdateSumoReference(
+ )
+{
+ if (m_game_object) {
+ m_sumo_object = 0;//m_game_object->GetSumoObject();
+ }
+}
+
+ void
+KX_IpoSGController::SetGameObject(
+ KX_GameObject* go
+ )
+{
+ m_game_object = go;
+}
+
+
+
+bool KX_IpoSGController::Update(double currentTime)
+{
+ if (m_modified)
+ {
+ T_InterpolatorList::iterator i;
+ for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) {
+ (*i)->Execute(m_ipotime);//currentTime);
+ }
+
+ SG_Spatial* ob = (SG_Spatial*)m_pObject;
+
+ if (m_modify_position) {
+ if (m_ipo_as_force) {
+ /*
+ UpdateSumoReference();
+ if (m_sumo_object && ob) {
+ m_sumo_object->applyCenterForce(m_force_ipo_acts_local ?
+ ob->GetWorldOrientation() * m_ipo_xform.GetPosition() :
+ m_ipo_xform.GetPosition());
+ m_sumo_object->calcXform();
+ }
+ */
+
+ } else {
+ ob->SetLocalPosition(m_ipo_xform.GetPosition());
+ }
+ }
+ if (m_modify_orientation) {
+ if (m_ipo_as_force) {
+ /*
+ UpdateSumoReference();
+ if (m_sumo_object && ob) {
+ m_sumo_object->applyTorque(m_force_ipo_acts_local ?
+ ob->GetWorldOrientation() * m_ipo_xform.GetEulerAngles() :
+ m_ipo_xform.GetEulerAngles());
+ m_sumo_object->calcXform();
+ }
+ */
+
+ } else {
+ ob->SetLocalOrientation(MT_Matrix3x3(m_ipo_xform.GetEulerAngles()));
+ }
+ }
+ if (m_modify_scaling)
+ ob->SetLocalScale(m_ipo_xform.GetScaling());
+
+ m_modified=false;
+ }
+ return false;
+}
+
+
+void KX_IpoSGController::AddInterpolator(KX_IInterpolator* interp)
+{
+ this->m_interpolators.push_back(interp);
+}
+
+SG_Controller* KX_IpoSGController::GetReplica(class SG_Node* destnode)
+{
+ KX_IpoSGController* iporeplica = new KX_IpoSGController(*this);
+ // clear object that ipo acts on in the replica.
+ iporeplica->ClearObject();
+
+ // dirty hack, ask Gino for a better solution in the ipo implementation
+ // hacken en zagen, in what we call datahiding, not written for replication :(
+
+ T_InterpolatorList oldlist = m_interpolators;
+ iporeplica->m_interpolators.clear();
+
+ T_InterpolatorList::iterator i;
+ for (i = oldlist.begin(); !(i == oldlist.end()); ++i) {
+ KX_ScalarInterpolator* copyipo = new KX_ScalarInterpolator(*((KX_ScalarInterpolator*)*i));
+ iporeplica->AddInterpolator(copyipo);
+
+ MT_Scalar* scaal = ((KX_ScalarInterpolator*)*i)->GetTarget();
+ int orgbase = (int)&m_ipo_xform;
+ int orgloc = (int)scaal;
+ int offset = orgloc-orgbase;
+ int newaddrbase = (int)&iporeplica->m_ipo_xform;
+ newaddrbase += offset;
+ MT_Scalar* blaptr = (MT_Scalar*) newaddrbase;
+ copyipo->SetNewTarget((MT_Scalar*)blaptr);
+ }
+
+ return iporeplica;
+}
+
+KX_IpoSGController::~KX_IpoSGController()
+{
+
+ T_InterpolatorList::iterator i;
+ for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) {
+ delete (*i);
+ }
+
+}
diff --git a/source/gameengine/Ketsji/KX_IPO_SGController.h b/source/gameengine/Ketsji/KX_IPO_SGController.h
new file mode 100644
index 00000000000..201a0051881
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_IPO_SGController.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 __IPO_SGCONTROLLER_H
+#define __IPO_SGCONTROLLER_H
+
+#include "SG_Controller.h"
+#include "SG_Spatial.h"
+
+#include "KX_IPOTransform.h"
+#include "KX_IInterpolator.h"
+
+class KX_IpoSGController : public SG_Controller
+{
+ KX_IPOTransform m_ipo_xform;
+ T_InterpolatorList m_interpolators;
+ /* Why not bools? */
+ short m_modify_position : 1;
+ short m_modify_orientation : 1;
+ short m_modify_scaling : 1;
+
+ /** Interpret the ipo as a force rather than a displacement? */
+ bool m_ipo_as_force;
+
+ /** Ipo-as-force acts in local rather than in global coordinates? */
+ bool m_force_ipo_acts_local;
+
+ /** Were settings altered since the last update? */
+ bool m_modified;
+
+ /** Local time of this ipo.*/
+ double m_ipotime;
+
+ /** A reference to the sm scene an eventually associated physics object is in. */
+// class SM_Scene* m_sumo_scene;
+
+ /** A reference an eventually associated physics object is in. */
+ class SM_Object* m_sumo_object;
+
+ /** A reference to the original game object. */
+ class KX_GameObject* m_game_object;
+
+public:
+ KX_IpoSGController();
+
+ virtual ~KX_IpoSGController();
+
+ virtual SG_Controller* GetReplica(class SG_Node* destnode);
+
+ void
+ SetOption(
+ int option,
+ int value
+ );
+
+ /** Set sumo data. */
+ void UpdateSumoReference();
+ /** Set reference to the corresponding game object. */
+ void SetGameObject(class KX_GameObject*);
+
+ void SetModifyPosition(bool modifypos) {
+ m_modify_position=modifypos;
+ }
+ void SetModifyOrientation(bool modifyorient) {
+ m_modify_orientation=modifyorient;
+ }
+ void SetModifyScaling(bool modifyscale) {
+ m_modify_scaling=modifyscale;
+ }
+
+ KX_IPOTransform& GetIPOTransform()
+ {
+ return m_ipo_xform;
+ }
+ void AddInterpolator(KX_IInterpolator* interp);
+ virtual bool Update(double time);
+ virtual void SetSimulatedTime(double time)
+ {
+ m_ipotime = time;
+ m_modified = true;
+ }
+};
+#endif //__IPO_SGCONTROLLER_H
diff --git a/source/gameengine/Ketsji/KX_IPhysicsController.cpp b/source/gameengine/Ketsji/KX_IPhysicsController.cpp
new file mode 100644
index 00000000000..5ef22dd4f74
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_IPhysicsController.cpp
@@ -0,0 +1,45 @@
+/**
+ * $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 "KX_IPhysicsController.h"
+
+
+KX_IPhysicsController::KX_IPhysicsController(bool dyna,void* userdata)
+
+: m_bDyna(dyna),
+ m_userdata(userdata),
+ m_suspendDynamics(false)
+{
+};
+
+KX_IPhysicsController::~KX_IPhysicsController()
+{
+}
diff --git a/source/gameengine/Ketsji/KX_IPhysicsController.h b/source/gameengine/Ketsji/KX_IPhysicsController.h
new file mode 100644
index 00000000000..997317c0df5
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_IPhysicsController.h
@@ -0,0 +1,99 @@
+/**
+ * $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_IPHYSICSCONTROLLER_H
+#define __KX_IPHYSICSCONTROLLER_H
+
+#include "SG_Controller.h"
+#include "MT_Vector3.h"
+#include "MT_Point3.h"
+#include "MT_Matrix3x3.h"
+
+/**
+ Physics Controller, a special kind of Scene Graph Transformation Controller.
+ It get's callbacks from Physics in case a transformation change took place.
+ Each time the scene graph get's updated, the controller get's a chance
+ in the 'Update' method to reflect changed.
+*/
+
+class KX_IPhysicsController : public SG_Controller
+
+{
+
+protected:
+ bool m_bDyna;
+ bool m_suspendDynamics;
+ void* m_userdata;
+public:
+ KX_IPhysicsController(bool dyna,void* userdata);
+ virtual ~KX_IPhysicsController();
+
+
+ virtual void applyImpulse(const MT_Point3& attach, const MT_Vector3& impulse)=0;
+ virtual void SetObject (SG_IObject* object)=0;
+
+ virtual void RelativeTranslate(const MT_Vector3& dloc,bool local)=0;
+ virtual void RelativeRotate(const MT_Matrix3x3& drot,bool local)=0;
+ virtual void ApplyTorque(const MT_Vector3& torque,bool local)=0;
+ virtual void ApplyForce(const MT_Vector3& force,bool local)=0;
+ virtual MT_Vector3 GetLinearVelocity()=0;
+ virtual MT_Vector3 GetVelocity(const MT_Point3& pos)=0;
+ virtual void SetAngularVelocity(const MT_Vector3& ang_vel,bool local)=0;
+ virtual void SetLinearVelocity(const MT_Vector3& lin_vel,bool local)=0;
+ virtual void getOrientation(MT_Quaternion& orn)=0;
+ virtual void setOrientation(const MT_Quaternion& orn)=0;
+ virtual void setPosition(const MT_Point3& pos)=0;
+ virtual void setScaling(const MT_Vector3& scaling)=0;
+ virtual MT_Scalar GetMass()=0;
+ virtual MT_Vector3 getReactionForce()=0;
+ virtual void setRigidBody(bool rigid)=0;
+
+ virtual void SuspendDynamics()=0;
+ virtual void RestoreDynamics()=0;
+
+ virtual SG_Controller* GetReplica(class SG_Node* destnode)=0;
+
+ void SetDyna(bool isDynamic) {
+ m_bDyna = isDynamic;
+ }
+
+
+ virtual void SetSumoTransform(bool nondynaonly)=0;
+ // todo: remove next line !
+ virtual void SetSimulatedTime(double time)=0;
+
+ // call from scene graph to update
+ virtual bool Update(double time)=0;
+ void* GetUserData() { return m_userdata;}
+
+
+};
+#endif //__KX_IPHYSICSCONTROLLER_H
diff --git a/source/gameengine/Ketsji/KX_IScalarInterpolator.h b/source/gameengine/Ketsji/KX_IScalarInterpolator.h
new file mode 100644
index 00000000000..dd153f77205
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_IScalarInterpolator.h
@@ -0,0 +1,42 @@
+/**
+ * $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_ISCALARINTERPOLATOR_H
+#define KX_ISCALARINTERPOLATOR_H
+
+class KX_IScalarInterpolator {
+public:
+ virtual ~KX_IScalarInterpolator() {}
+
+ virtual float GetValue(float currentTime) const = 0;
+};
+
+#endif
diff --git a/source/gameengine/Ketsji/KX_ISceneConverter.h b/source/gameengine/Ketsji/KX_ISceneConverter.h
new file mode 100644
index 00000000000..fcb73fa8872
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_ISceneConverter.h
@@ -0,0 +1,64 @@
+/**
+ * $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_ISCENECONVERTER_H
+#define __KX_ISCENECONVERTER_H
+
+#include "STR_String.h"
+
+#include "KX_Python.h"
+
+class KX_ISceneConverter
+{
+
+public:
+ KX_ISceneConverter() {}
+ virtual ~KX_ISceneConverter () {};
+
+ /*
+ scenename: name of the scene to be converted,
+ if the scenename is empty, convert the 'default' scene (whatever this means)
+ destinationscene: pass an empty scene, everything goes into this
+ dictobj: python dictionary (for pythoncontrollers)
+ */
+ virtual void ConvertScene(const STR_String& scenename,
+ class KX_Scene* destinationscene,
+ PyObject* dictobj,
+ class SCA_IInputDevice* keyinputdev,
+ class RAS_IRenderTools* rendertools,
+ class RAS_ICanvas* canvas)=0;
+
+ virtual void SetAlwaysUseExpandFraming(bool to_what) = 0;
+
+ virtual void SetNewFileName(const STR_String& filename) = 0;
+ virtual bool TryAndLoadNewFile() = 0;
+};
+#endif //__KX_ISCENECONVERTER_H
diff --git a/source/gameengine/Ketsji/KX_ISystem.h b/source/gameengine/Ketsji/KX_ISystem.h
new file mode 100644
index 00000000000..1ab3e521418
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_ISystem.h
@@ -0,0 +1,55 @@
+/**
+* Abstract system
+*
+* $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_ISYSTEM
+#define __KX_ISYSTEM
+
+#include <vector>
+using namespace std;
+
+#include "STR_String.h"
+
+/**
+ * System Abstraction, needed only for getting some timing stuff from the host.
+ */
+class KX_ISystem
+{
+public:
+ KX_ISystem() {};
+ virtual ~KX_ISystem() {};
+
+ virtual double GetTimeInSeconds()=0;
+};
+
+#endif
diff --git a/source/gameengine/Ketsji/KX_IpoActuator.cpp b/source/gameengine/Ketsji/KX_IpoActuator.cpp
new file mode 100644
index 00000000000..1e351834822
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_IpoActuator.cpp
@@ -0,0 +1,643 @@
+/**
+ * Do Ipo 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 "KX_IpoActuator.h"
+#include "KX_GameObject.h"
+
+
+/* ------------------------------------------------------------------------- */
+/* Type strings */
+/* ------------------------------------------------------------------------- */
+
+STR_String KX_IpoActuator::S_KX_ACT_IPO_PLAY_STRING = "Play";
+STR_String KX_IpoActuator::S_KX_ACT_IPO_PINGPONG_STRING = "PingPong";
+STR_String KX_IpoActuator::S_KX_ACT_IPO_FLIPPER_STRING = "Flipper";
+STR_String KX_IpoActuator::S_KX_ACT_IPO_LOOPSTOP_STRING = "LoopStop";
+STR_String KX_IpoActuator::S_KX_ACT_IPO_LOOPEND_STRING = "LoopEnd";
+STR_String KX_IpoActuator::S_KX_ACT_IPO_KEY2KEY_STRING = "Key2key";
+STR_String KX_IpoActuator::S_KX_ACT_IPO_FROM_PROP_STRING = "FromProp";
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+/** Another poltergeist? This seems to be a very transient class... */
+class CIpoAction : public CAction
+{
+ float m_curtime;
+ bool m_resurse;
+ KX_GameObject* m_gameobj;
+ bool m_ipo_as_force;
+ bool m_force_ipo_local;
+
+public:
+ CIpoAction(KX_GameObject* gameobj,
+ float curtime,
+ bool recurse,
+ bool ipo_as_force,
+ bool force_ipo_local) :
+ m_curtime(curtime) ,
+ m_resurse(recurse),
+ m_gameobj(gameobj),
+ m_ipo_as_force(ipo_as_force),
+ m_force_ipo_local(force_ipo_local)
+ {
+ /* intentionally empty */
+ };
+
+ virtual void Execute() const
+ {
+ m_gameobj->UpdateIPO(
+ m_curtime,
+ m_resurse,
+ m_ipo_as_force,
+ m_force_ipo_local);
+ };
+
+};
+
+
+KX_IpoActuator::KX_IpoActuator(SCA_IObject* gameobj,
+ const STR_String& propname,
+ float starttime,
+ float endtime,
+ bool recurse,
+ int acttype,
+ bool ipo_as_force,
+ bool force_ipo_local,
+ PyTypeObject* T)
+ : SCA_IActuator(gameobj,T),
+ m_starttime (starttime),
+ m_endtime(endtime) ,
+ m_localtime(starttime),
+ m_recurse(recurse),
+ m_type((IpoActType)acttype) ,
+ m_direction(1),
+ m_bNegativeEvent(false),
+ m_propname(propname),
+ m_ipo_as_force(ipo_as_force),
+ m_force_ipo_local(force_ipo_local)
+{
+ // intentionally empty
+}
+
+void KX_IpoActuator::SetStart(float starttime)
+{
+ m_starttime=starttime;
+}
+
+void KX_IpoActuator::SetEnd(float endtime)
+{
+ m_endtime=endtime;
+}
+
+
+bool KX_IpoActuator::Update(double curtime,double delta_time)
+{
+ SCA_IActuator::Update(curtime,delta_time);
+ // result = true if animation has to be continued, false if animation stops
+ // maybe there are events for us in the queue !
+
+
+ bool bNegativeEvent = false;
+ int numevents = m_events.size();
+
+ for (vector<CValue*>::iterator i=m_events.end(); !(i==m_events.begin());)
+ {
+ i--;
+ if ((*i)->GetNumber() == 0.0f)
+ {
+ int ka=0;
+ bNegativeEvent = true;
+ }
+ (*i)->Release();
+ m_events.pop_back();
+ }
+
+ if (bNegativeEvent)
+ {
+ RemoveAllEvents();
+ }
+
+
+ double start_smaller_then_end = ( m_starttime < m_endtime ? 1.0 : -1.0);
+
+ double deltaframetime = start_smaller_then_end * delta_time * KX_FIXED_FRAME_PER_SEC;
+
+ bool result=true;
+
+ switch (m_type)
+ {
+
+ case KX_ACT_IPO_PLAY:
+ {
+
+ if (start_smaller_then_end > 0.0)
+ result = (m_localtime < m_endtime && !(m_localtime == m_starttime && bNegativeEvent));
+ else
+ result = (m_localtime > m_endtime && !(m_localtime == m_starttime && bNegativeEvent));
+ if (result)
+ {
+ m_localtime += m_direction * deltaframetime;
+
+ /* Perform clamping */
+ if ((m_localtime*start_smaller_then_end)>(m_endtime*start_smaller_then_end))
+ m_localtime=m_endtime;
+
+ CIpoAction ipoaction(
+ (KX_GameObject*)GetParent(),
+ m_localtime,
+ m_recurse,
+ m_ipo_as_force,
+ m_force_ipo_local);
+ GetParent()->Execute(ipoaction);
+ } else
+ {
+ m_localtime=m_starttime;
+ m_direction=1;
+ }
+ break;
+ }
+ case KX_ACT_IPO_PINGPONG:
+ {
+ result = true;
+ if (bNegativeEvent && ((m_localtime == m_starttime )|| (m_localtime == m_endtime)))
+ {
+ result = false;
+ } else
+ {
+ m_localtime += m_direction * deltaframetime;
+ }
+
+ if (m_localtime*start_smaller_then_end < m_starttime*start_smaller_then_end)
+ {
+ m_localtime = m_starttime;
+ result = false;
+ m_direction = 1;
+ }else
+ if (m_localtime*start_smaller_then_end > m_endtime*start_smaller_then_end)
+ {
+ m_localtime = m_endtime;
+ result = false;
+ m_direction = -1;
+ }
+
+ CIpoAction ipoaction(
+ (KX_GameObject*) GetParent(),
+ m_localtime,
+ m_recurse,
+ m_ipo_as_force,
+ m_force_ipo_local);
+ GetParent()->Execute(ipoaction);
+ break;
+ }
+
+ case KX_ACT_IPO_FLIPPER:
+ {
+ result = true;
+ if (numevents)
+ {
+ if (bNegativeEvent)
+ m_direction = -1;
+ else
+ m_direction = 1;
+ }
+
+ m_localtime += m_direction * deltaframetime;
+
+ if (m_localtime*start_smaller_then_end > m_endtime*start_smaller_then_end)
+ {
+ m_localtime = m_endtime;
+ } else
+ if (m_localtime*start_smaller_then_end < m_starttime*start_smaller_then_end)
+ {
+ m_localtime = m_starttime;
+ result = false;
+ }
+
+ CIpoAction ipoaction(
+ (KX_GameObject*) GetParent(),
+ m_localtime,
+ m_recurse,
+ m_ipo_as_force,
+ m_force_ipo_local);
+ GetParent()->Execute(ipoaction);
+ break;
+ }
+
+ case KX_ACT_IPO_LOOPSTOP:
+ {
+ if (numevents)
+ {
+ if (bNegativeEvent)
+ {
+ result = false;
+ m_bNegativeEvent = false;
+ numevents = 0;
+ }
+ } // fall through to loopend, and quit the ipo animation immediatly
+ }
+
+ case KX_ACT_IPO_LOOPEND:
+ {
+ if (numevents){
+ if (bNegativeEvent){
+ m_bNegativeEvent = true;
+ }
+ }
+
+ if (bNegativeEvent && m_localtime == m_starttime){
+ result = false;
+ }
+ else{
+ if (m_localtime*start_smaller_then_end < m_endtime*start_smaller_then_end){
+ m_localtime += m_direction * deltaframetime;
+ }
+ else{
+ if (!m_bNegativeEvent){
+ /* Perform wraparound */
+ float slop = m_localtime-m_endtime;
+ float length = fabs(m_starttime-m_endtime);
+ m_localtime = m_starttime + (slop - (int(slop/length)*(int(length))));
+
+ }
+ else
+ {
+ /* Perform clamping */
+ if ((m_localtime*start_smaller_then_end)>(m_endtime*start_smaller_then_end))
+ m_localtime=m_endtime;
+
+ result = false;
+ m_bNegativeEvent = false;
+ }
+ }
+ }
+ CIpoAction ipoaction(
+ (KX_GameObject*) GetParent(),
+ m_localtime,
+ m_recurse,
+ m_ipo_as_force,
+ m_force_ipo_local);
+ GetParent()->Execute(ipoaction);
+ break;
+ }
+ case KX_ACT_IPO_KEY2KEY:
+ {
+ // not implemented yet
+ result = false;
+ break;
+ }
+ case KX_ACT_IPO_FROM_PROP:
+ {
+ result = !bNegativeEvent;
+
+ CValue* propval = GetParent()->GetProperty(m_propname);
+ if (propval)
+ {
+ m_localtime = propval->GetNumber();
+ CIpoAction ipoaction(
+ (KX_GameObject*) GetParent(),
+ m_localtime,
+ m_recurse,
+ m_ipo_as_force,
+ m_force_ipo_local);
+ GetParent()->Execute(ipoaction);
+
+ } else
+ {
+ result = false;
+ }
+ break;
+ }
+
+ default:
+ {
+ result = false;
+ }
+ }
+
+ return result;
+}
+
+KX_IpoActuator::IpoActType KX_IpoActuator::string2mode(char* modename) {
+ IpoActType res = KX_ACT_IPO_NODEF;
+
+ if (modename == S_KX_ACT_IPO_PLAY_STRING) {
+ res = KX_ACT_IPO_PLAY;
+ } else if (modename == S_KX_ACT_IPO_PINGPONG_STRING) {
+ res = KX_ACT_IPO_PINGPONG;
+ } else if (modename == S_KX_ACT_IPO_FLIPPER_STRING) {
+ res = KX_ACT_IPO_FLIPPER;
+ } else if (modename == S_KX_ACT_IPO_LOOPSTOP_STRING) {
+ res = KX_ACT_IPO_LOOPSTOP;
+ } else if (modename == S_KX_ACT_IPO_LOOPEND_STRING) {
+ res = KX_ACT_IPO_LOOPEND;
+ } else if (modename == S_KX_ACT_IPO_KEY2KEY_STRING) {
+ res = KX_ACT_IPO_KEY2KEY;
+ } else if (modename == S_KX_ACT_IPO_FROM_PROP_STRING) {
+ res = KX_ACT_IPO_FROM_PROP;
+ }
+
+ return res;
+}
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject KX_IpoActuator::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "KX_IpoActuator",
+ sizeof(KX_IpoActuator),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject KX_IpoActuator::Parents[] = {
+ &KX_IpoActuator::Type,
+ &SCA_IActuator::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef KX_IpoActuator::Methods[] = {
+ {"set", (PyCFunction) KX_IpoActuator::sPySet,
+ METH_VARARGS, Set_doc},
+ {"setProperty", (PyCFunction) KX_IpoActuator::sPySetProperty,
+ METH_VARARGS, SetProperty_doc},
+ {"setStart", (PyCFunction) KX_IpoActuator::sPySetStart,
+ METH_VARARGS, SetStart_doc},
+ {"getStart", (PyCFunction) KX_IpoActuator::sPyGetStart,
+ METH_VARARGS, GetStart_doc},
+ {"setEnd", (PyCFunction) KX_IpoActuator::sPySetEnd,
+ METH_VARARGS, SetEnd_doc},
+ {"getEnd", (PyCFunction) KX_IpoActuator::sPyGetEnd,
+ METH_VARARGS, GetEnd_doc},
+ {"setIpoAsForce", (PyCFunction) KX_IpoActuator::sPySetIpoAsForce,
+ METH_VARARGS, SetIpoAsForce_doc},
+ {"getIpoAsForce", (PyCFunction) KX_IpoActuator::sPyGetIpoAsForce,
+ METH_VARARGS, GetIpoAsForce_doc},
+ {"setType", (PyCFunction) KX_IpoActuator::sPySetType,
+ METH_VARARGS, SetType_doc},
+ {"getType", (PyCFunction) KX_IpoActuator::sPyGetType,
+ METH_VARARGS, GetType_doc},
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* KX_IpoActuator::_getattr(char* attr) {
+ _getattr_up(SCA_IActuator);
+}
+
+
+
+/* set --------------------------------------------------------------------- */
+char KX_IpoActuator::Set_doc[] =
+"set(mode, startframe, endframe, force?)\n"
+"\t - mode: Play, PingPong, Flipper, LoopStop, LoopEnd or FromProp (string)\n"
+"\t - startframe: first frame to use (int)\n"
+"\t - endframe : last frame to use (int)\n"
+"\t - force? : interpret this ipo as a force? (KX_TRUE, KX_FALSE)"
+"\tSet the properties of the actuator.\n";
+PyObject* KX_IpoActuator::PySet(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ /* sets modes PLAY, PINGPONG, FLIPPER, LOOPSTOP, LOOPEND */
+ /* arg 1 = mode string, arg 2 = startframe, arg3 = stopframe, */
+ /* arg4 = force toggle */
+ char* mode;
+ int forceToggle;
+ IpoActType modenum;
+ int startFrame, stopFrame;
+ if(!PyArg_ParseTuple(args, "siii", &mode, &startFrame,
+ &stopFrame, &forceToggle)) {
+ return NULL;
+ }
+ modenum = string2mode(mode);
+
+ switch (modenum) {
+ case KX_ACT_IPO_PLAY:
+ case KX_ACT_IPO_PINGPONG:
+ case KX_ACT_IPO_FLIPPER:
+ case KX_ACT_IPO_LOOPSTOP:
+ case KX_ACT_IPO_LOOPEND:
+ m_type = modenum;
+ m_starttime = startFrame;
+ m_endtime = stopFrame;
+ m_ipo_as_force = PyArgToBool(forceToggle);
+ break;
+ default:
+ ; /* error */
+ }
+
+ Py_Return;
+}
+
+/* set property ----------------------------------------------------------- */
+char KX_IpoActuator::SetProperty_doc[] =
+"setProperty(propname)\n"
+"\t - propname: name of the property (string)\n"
+"\tSet the property to be used in FromProp mode.\n";
+PyObject* KX_IpoActuator::PySetProperty(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ /* mode is implicit here, but not supported yet... */
+ /* args: property */
+ char *propertyName;
+ if(!PyArg_ParseTuple(args, "s", &propertyName)) {
+ return NULL;
+ }
+
+ Py_Return;
+}
+
+/* 4. setStart: */
+char KX_IpoActuator::SetStart_doc[] =
+"setStart(frame)\n"
+"\t - frame: first frame to use (int)\n"
+"\tSet the frame from which the ipo starts playing.\n";
+PyObject* KX_IpoActuator::PySetStart(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ float startArg;
+ if(!PyArg_ParseTuple(args, "f", &startArg)) {
+ return NULL;
+ }
+
+ m_starttime = startArg;
+
+ Py_Return;
+}
+/* 5. getStart: */
+char KX_IpoActuator::GetStart_doc[] =
+"getStart()\n"
+"\tReturns the frame from which the ipo starts playing.\n";
+PyObject* KX_IpoActuator::PyGetStart(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ return PyFloat_FromDouble(m_starttime);
+}
+
+/* 6. setEnd: */
+char KX_IpoActuator::SetEnd_doc[] =
+"setEnd(frame)\n"
+"\t - frame: last frame to use (int)\n"
+"\tSet the frame at which the ipo stops playing.\n";
+PyObject* KX_IpoActuator::PySetEnd(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ float endArg;
+ if(!PyArg_ParseTuple(args, "f", &endArg)) {
+ return NULL;
+ }
+
+ m_endtime = endArg;
+
+ Py_Return;
+}
+/* 7. getEnd: */
+char KX_IpoActuator::GetEnd_doc[] =
+"getEnd()\n"
+"\tReturns the frame at which the ipo stops playing.\n";
+PyObject* KX_IpoActuator::PyGetEnd(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ return PyFloat_FromDouble(m_endtime);
+}
+
+/* 6. setIpoAsForce: */
+char KX_IpoActuator::SetIpoAsForce_doc[] =
+"setIpoAsForce(force?)\n"
+"\t - force? : interpret this ipo as a force? (KX_TRUE, KX_FALSE)\n"
+"\tSet whether to interpret the ipo as a force rather than a displacement.\n";
+PyObject* KX_IpoActuator::PySetIpoAsForce(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ int boolArg;
+
+ if (!PyArg_ParseTuple(args, "i", &boolArg)) {
+ return NULL;
+ }
+
+ m_ipo_as_force = PyArgToBool(boolArg);
+
+ Py_Return;
+}
+/* 7. getIpoAsForce: */
+char KX_IpoActuator::GetIpoAsForce_doc[] =
+"getIpoAsForce()\n"
+"\tReturns whether to interpret the ipo as a force rather than a displacement.\n";
+PyObject* KX_IpoActuator::PyGetIpoAsForce(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ return BoolToPyArg(m_ipo_as_force);
+}
+
+/* 8. setType: */
+char KX_IpoActuator::SetType_doc[] =
+"setType(mode)\n"
+"\t - mode: Play, PingPong, Flipper, LoopStop, LoopEnd or FromProp (string)\n"
+"\tSet the operation mode of the actuator.\n";
+PyObject* KX_IpoActuator::PySetType(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ int typeArg;
+
+ if (!PyArg_ParseTuple(args, "i", &typeArg)) {
+ return NULL;
+ }
+
+ if ( (typeArg > KX_ACT_IPO_NODEF)
+ && (typeArg < KX_ACT_IPO_KEY2KEY) ) {
+ m_type = (IpoActType) typeArg;
+ }
+
+ Py_Return;
+}
+/* 9. getType: */
+char KX_IpoActuator::GetType_doc[] =
+"getType()\n"
+"\tReturns the operation mode of the actuator.\n";
+PyObject* KX_IpoActuator::PyGetType(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ return PyInt_FromLong(m_type);
+}
+
+/* 10. setForceIpoActsLocal: */
+char KX_IpoActuator::SetForceIpoActsLocal_doc[] =
+"setForceIpoActsLocal(local?)\n"
+"\t - local? : Apply the ipo-as-force in the object's local\n"
+"\t coordinates? (KX_TRUE, KX_FALSE)\n"
+"\tSet whether to apply the force in the object's local\n"
+"\tcoordinates rather than the world global coordinates.\n";
+PyObject* KX_IpoActuator::PySetForceIpoActsLocal(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ int boolArg;
+
+ if (!PyArg_ParseTuple(args, "i", &boolArg)) {
+ return NULL;
+ }
+
+ m_force_ipo_local = PyArgToBool(boolArg);
+
+ Py_Return;
+}
+/* 11. getForceIpoActsLocal: */
+char KX_IpoActuator::GetForceIpoActsLocal_doc[] =
+"getForceIpoActsLocal()\n"
+"\tReturn whether to apply the force in the object's local\n"
+"\tcoordinates rather than the world global coordinates.\n";
+PyObject* KX_IpoActuator::PyGetForceIpoActsLocal(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ return BoolToPyArg(m_force_ipo_local);
+}
+
+
+/* eof */
diff --git a/source/gameengine/Ketsji/KX_IpoActuator.h b/source/gameengine/Ketsji/KX_IpoActuator.h
new file mode 100644
index 00000000000..134de3817b4
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_IpoActuator.h
@@ -0,0 +1,141 @@
+/**
+ * Do an object ipo
+ *
+ * $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_IPOACTUATOR
+#define __KX_IPOACTUATOR
+
+#include "SCA_IActuator.h"
+
+class KX_IpoActuator : public SCA_IActuator
+{
+ Py_Header;
+
+ bool m_bNegativeEvent;
+
+ /** Begin frame of the ipo. */
+ float m_starttime;
+
+ /** End frame of the ipo. */
+ float m_endtime;
+
+ /** Include children in the transforms? */
+ bool m_recurse;
+
+ /** Current active frame of the ipo. */
+ float m_localtime;
+
+ /** play backwards or forwards? (positive means forward). */
+ float m_direction;
+
+ /** Name of the property (only used in from_prop mode). */
+ STR_String m_propname;
+
+ /** Interpret the ipo as a force? */
+ bool m_ipo_as_force;
+
+ /** Apply a force-ipo locally? */
+ bool m_force_ipo_local;
+
+public:
+ enum IpoActType
+ {
+ KX_ACT_IPO_NODEF = 0,
+ KX_ACT_IPO_PLAY,
+ KX_ACT_IPO_PINGPONG,
+ KX_ACT_IPO_FLIPPER,
+ KX_ACT_IPO_LOOPSTOP,
+ KX_ACT_IPO_LOOPEND,
+ KX_ACT_IPO_KEY2KEY,
+ KX_ACT_IPO_FROM_PROP,
+ KX_ACT_IPO_MAX
+ };
+
+ static STR_String S_KX_ACT_IPO_PLAY_STRING;
+ static STR_String S_KX_ACT_IPO_PINGPONG_STRING;
+ static STR_String S_KX_ACT_IPO_FLIPPER_STRING;
+ static STR_String S_KX_ACT_IPO_LOOPSTOP_STRING;
+ static STR_String S_KX_ACT_IPO_LOOPEND_STRING;
+ static STR_String S_KX_ACT_IPO_KEY2KEY_STRING;
+ static STR_String S_KX_ACT_IPO_FROM_PROP_STRING;
+
+ IpoActType string2mode(char* modename);
+
+ IpoActType m_type;
+
+ KX_IpoActuator(SCA_IObject* gameobj,
+ const STR_String& propname,
+ float starttime,
+ float endtime,
+ bool recurse,
+ int acttype,
+ bool ipo_as_force,
+ bool force_ipo_local,
+ PyTypeObject* T=&Type);
+ virtual ~KX_IpoActuator() {};
+
+ virtual CValue* GetReplica() {
+ KX_IpoActuator* replica = new KX_IpoActuator(*this);//m_float,GetName());
+ replica->ProcessReplica();
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+ return replica;
+ };
+
+ void SetStart(float starttime);
+ void SetEnd(float endtime);
+ virtual bool Update(double curtime,double deltatime);
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(char *attr);
+ //KX_PYMETHOD_DOC
+ KX_PYMETHOD_DOC(KX_IpoActuator,Set);
+ KX_PYMETHOD_DOC(KX_IpoActuator,SetProperty);
+/* KX_PYMETHOD_DOC(KX_IpoActuator,SetKey2Key); */
+ KX_PYMETHOD_DOC(KX_IpoActuator,SetStart);
+ KX_PYMETHOD_DOC(KX_IpoActuator,GetStart);
+ KX_PYMETHOD_DOC(KX_IpoActuator,SetEnd);
+ KX_PYMETHOD_DOC(KX_IpoActuator,GetEnd);
+ KX_PYMETHOD_DOC(KX_IpoActuator,SetIpoAsForce);
+ KX_PYMETHOD_DOC(KX_IpoActuator,GetIpoAsForce);
+ KX_PYMETHOD_DOC(KX_IpoActuator,SetType);
+ KX_PYMETHOD_DOC(KX_IpoActuator,GetType);
+ KX_PYMETHOD_DOC(KX_IpoActuator,SetForceIpoActsLocal);
+ KX_PYMETHOD_DOC(KX_IpoActuator,GetForceIpoActsLocal);
+
+};
+
+#endif //__KX_IPOACTUATOR
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
new file mode 100644
index 00000000000..c03e4e3d964
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -0,0 +1,1250 @@
+/*
+ * $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 *****
+ * The engine ties all game modules together.
+ */
+#ifdef WIN32
+#pragma warning (disable : 4786)
+#endif //WIN32
+
+#include <iostream>
+
+#include "KX_KetsjiEngine.h"
+
+#include "ListValue.h"
+#include "IntValue.h"
+#include "VectorValue.h"
+#include "BoolValue.h"
+#include "FloatValue.h"
+
+#define KX_NUM_ITERATIONS 4
+#include "RAS_BucketManager.h"
+#include "RAS_Rect.h"
+#include "RAS_IRasterizer.h"
+#include "RAS_IRenderTools.h"
+#include "RAS_ICanvas.h"
+#include "STR_String.h"
+#include "MT_Vector3.h"
+#include "MT_Transform.h"
+#include "SCA_IInputDevice.h"
+#include "KX_Scene.h"
+#include "MT_CmMatrix4x4.h"
+#include "KX_Camera.h"
+#include "KX_PythonInit.h"
+#include "KX_PyConstraintBinding.h"
+#include "PHY_IPhysicsEnvironment.h"
+
+#include "SND_Scene.h"
+#include "SND_IAudioDevice.h"
+
+#include "NG_NetworkScene.h"
+#include "NG_NetworkDeviceInterface.h"
+
+#include "KX_WorldInfo.h"
+#include "KX_ISceneConverter.h"
+#include "KX_TimeCategoryLogger.h"
+
+#include "RAS_FramingManager.h"
+
+// If define: little test for Nzc: guarded drawing. If the canvas is
+// not valid, skip rendering this frame.
+//#define NZC_GUARDED_OUTPUT
+
+
+const char KX_KetsjiEngine::m_profileLabels[tc_numCategories][15] = {
+ "Physics:", // tc_physics
+ "Logic", // tc_logic
+ "Network:", // tc_network
+ "Scenegraph:", // tc_scenegraph
+ "Sound:", // tc_sound
+ "Rasterizer:", // tc_rasterizer
+ "Services:", // tc_services
+ "Overhead:", // tc_overhead
+ "Outside:" // tc_outside
+};
+
+
+
+
+/**
+ * Constructor of the Ketsji Engine
+ */
+KX_KetsjiEngine::KX_KetsjiEngine(KX_ISystem* system)
+: m_bInitialized(false),
+ m_activecam(0),
+ m_rasterizer(NULL)
+{
+ m_kxsystem = system;
+ m_bFixedTime = false;
+
+ // Initialize the time logger
+ m_logger = new KX_TimeCategoryLogger (25);
+
+ for (int i = tc_first; i < tc_numCategories; i++)
+ m_logger->AddCategory((KX_TimeCategory)i);
+
+ // Set up timing info display variables
+ m_show_framerate = false;
+ m_show_profile = false;
+ m_show_debug_properties = false;
+ m_propertiesPresent = false;
+
+ // Default behavior is to hide the cursor every frame.
+ m_hideCursor = false;
+
+ m_overrideFrameColor = false;
+ m_overrideFrameColorR = (float)0;
+ m_overrideFrameColorG = (float)0;
+ m_overrideFrameColorB = (float)0;
+
+ m_cameraZoom = 1.0;
+ m_drawingmode = 5; /* textured drawing mode */
+ m_overrideCam = false;
+
+ m_exitcode = KX_EXIT_REQUEST_NO_REQUEST;
+ m_exitstring = "";
+}
+
+
+
+/**
+ * Destructor of the Ketsji Engine, release all memory
+ */
+KX_KetsjiEngine::~KX_KetsjiEngine()
+{
+ if (m_logger)
+ delete m_logger;
+}
+
+
+
+void KX_KetsjiEngine::SetKeyboardDevice(SCA_IInputDevice* keyboarddevice)
+{
+ assert(keyboarddevice);
+ m_keyboarddevice = keyboarddevice;
+}
+
+
+
+void KX_KetsjiEngine::SetMouseDevice(SCA_IInputDevice* mousedevice)
+{
+ assert(mousedevice);
+ m_mousedevice = mousedevice;
+}
+
+
+
+void KX_KetsjiEngine::SetNetworkDevice(NG_NetworkDeviceInterface* networkdevice)
+{
+ assert(networkdevice);
+ m_networkdevice = networkdevice;
+}
+
+
+
+void KX_KetsjiEngine::SetAudioDevice(SND_IAudioDevice* audiodevice)
+{
+ assert(audiodevice);
+ m_audiodevice = audiodevice;
+}
+
+
+
+void KX_KetsjiEngine::SetCanvas(RAS_ICanvas* canvas)
+{
+ assert(canvas);
+ m_canvas = canvas;
+}
+
+
+
+void KX_KetsjiEngine::SetRenderTools(RAS_IRenderTools* rendertools)
+{
+ assert(rendertools);
+ m_rendertools = rendertools;
+}
+
+
+
+void KX_KetsjiEngine::SetRasterizer(RAS_IRasterizer* rasterizer)
+{
+ assert(rasterizer);
+ m_rasterizer = rasterizer;
+}
+
+
+
+void KX_KetsjiEngine::SetPythonDictionary(PyObject* pythondictionary)
+{
+ assert(pythondictionary);
+ m_pythondictionary = pythondictionary;
+}
+
+
+
+void KX_KetsjiEngine::SetSceneConverter(KX_ISceneConverter* sceneconverter)
+{
+ assert(sceneconverter);
+ m_sceneconverter = sceneconverter;
+}
+
+
+
+/**
+ * Ketsji Init(), Initializes datastructures and converts data from
+ * Blender into Ketsji native (realtime) format also sets up the
+ * graphics context
+ */
+void KX_KetsjiEngine::StartEngine()
+{
+ m_previoustime = 0.0;
+ m_missedtime = 0.0;
+ m_firstframe = true;
+
+ // for all scenes, initialize the scenegraph for the first time
+ m_lasttime = m_kxsystem->GetTimeInSeconds()*100.0;
+
+ m_bInitialized = true;
+}
+
+
+
+#define DELTALENGTH 25
+
+double KX_KetsjiEngine::CalculateAverage(double newdelta)
+{
+ if (m_deltatimes.size() < DELTALENGTH)
+ {
+ m_deltatimes.push_back(newdelta);
+ } else
+ {
+ //
+ double totaltime = 0.0;
+ double newlasttime,lasttime = newdelta;
+ double peakmin = 10000;
+ double peakmax = -10000;
+
+ for (int i=m_deltatimes.size()-1;i>=0;i--)
+ { newlasttime = m_deltatimes[i];
+ totaltime += newlasttime;
+ if (peakmin > newlasttime)
+ peakmin = newlasttime;
+ if (peakmax < newlasttime)
+ peakmax = newlasttime;
+
+ m_deltatimes[i] = lasttime;
+ lasttime = newlasttime;
+ };
+ double averagetime;
+
+ if (peakmin < peakmax)
+ {
+ averagetime = ((totaltime - peakmin) - peakmax) / (double) (m_deltatimes.size()-2);
+ } else
+ {
+ averagetime = totaltime / (double) m_deltatimes.size();
+ }
+ return averagetime;
+ }
+
+ return newdelta;
+}
+
+
+
+bool KX_KetsjiEngine::BeginFrame()
+{
+ bool result = false;
+
+ RAS_Rect vp;
+ KX_Scene* firstscene = *m_scenes.begin();
+ const RAS_FrameSettings &framesettings = firstscene->GetFramingType();
+
+ // set the area used for rendering
+ m_rasterizer->SetRenderArea();
+
+ RAS_FramingManager::ComputeViewport(framesettings, m_canvas->GetDisplayArea(), vp);
+
+ if (m_canvas->BeginDraw())
+ {
+ result = true;
+
+ m_canvas->SetViewPort(vp.GetLeft(), vp.GetBottom(), vp.GetRight(), vp.GetTop());
+ SetBackGround( firstscene->GetWorldInfo() );
+ m_rasterizer->BeginFrame( m_drawingmode , m_kxsystem->GetTimeInSeconds());
+ m_rendertools->BeginFrame( m_rasterizer);
+ }
+
+ return result;
+}
+
+
+void KX_KetsjiEngine::EndFrame()
+{
+ // Show profiling info
+ m_logger->StartLog(tc_overhead, m_kxsystem->GetTimeInSeconds(), true);
+ if (m_show_framerate || m_show_profile || (m_show_debug_properties && m_propertiesPresent))
+ {
+ RenderDebugProperties();
+ }
+ // Go to next profiling measurement, time spend after this call is shown in the next frame.
+ m_logger->NextMeasurement(m_kxsystem->GetTimeInSeconds());
+
+ m_logger->StartLog(tc_rasterizer, m_kxsystem->GetTimeInSeconds(), true);
+ m_rasterizer->EndFrame();
+ // swap backbuffer (drawing into this buffer) <-> front/visible buffer
+ m_rasterizer->SwapBuffers();
+ m_rendertools->EndFrame(m_rasterizer);
+
+ m_canvas->EndDraw();
+}
+
+
+
+void KX_KetsjiEngine::NextFrame()
+{
+ m_logger->StartLog(tc_services, m_kxsystem->GetTimeInSeconds(), true);
+
+ double deltatime = 0.02;
+ double curtime;
+
+ if (m_bFixedTime)
+ {
+ curtime = m_previoustime + deltatime;
+ }
+ else
+ {
+ curtime = m_kxsystem->GetTimeInSeconds();
+ if (m_previoustime)
+ deltatime = curtime - m_previoustime;
+
+ if (deltatime > 0.1)
+ deltatime = 0.1;
+
+ deltatime = CalculateAverage(deltatime);
+ }
+
+ m_previoustime = curtime;
+
+ KX_SceneList::iterator sceneit;
+ for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++)
+ // for each scene, call the proceed functions
+ {
+ KX_Scene* scene = *sceneit;
+
+
+
+ /* Suspension holds the physics and logic processing for an
+ * entire scene. Objects can be suspended individually, and
+ * the settings for that preceed the logic and physics
+ * update. */
+ m_logger->StartLog(tc_logic, m_kxsystem->GetTimeInSeconds(), true);
+ scene->UpdateObjectActivity();
+
+ if (!scene->IsSuspended())
+ {
+ m_logger->StartLog(tc_network, m_kxsystem->GetTimeInSeconds(), true);
+ scene->GetNetworkScene()->proceed(curtime, deltatime);
+
+ // set Python hooks for each scene
+ PHY_SetActiveEnvironment(scene->GetPhysicsEnvironment());
+ PHY_SetActiveScene(scene);
+
+ // Process sensors, and controllers
+ m_logger->StartLog(tc_logic, m_kxsystem->GetTimeInSeconds(), true);
+ scene->LogicBeginFrame(curtime,deltatime);
+
+ // Scenegraph needs to be updated again, because Logic Controllers
+ // can affect the local matrices.
+ m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
+ scene->UpdateParents(curtime);
+
+ // Process actuators
+
+ // Do some cleanup work for this logic frame
+ m_logger->StartLog(tc_logic, m_kxsystem->GetTimeInSeconds(), true);
+ scene->LogicUpdateFrame(curtime,deltatime);
+ scene->LogicEndFrame();
+
+ // Actuators can affect the scenegraph
+ m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
+ scene->UpdateParents(curtime);
+
+ // Perform physics calculations on the scene. This can involve
+ // many iterations of the physics solver.
+ m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
+ scene->GetPhysicsEnvironment()->proceed(deltatime);
+
+ // Update scenegraph after physics step. This maps physics calculations
+ // into node positions.
+ m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
+ scene->UpdateParents(curtime);
+
+ } // suspended
+
+ DoSound(scene);
+
+ m_logger->StartLog(tc_services, m_kxsystem->GetTimeInSeconds(), true);
+ }
+
+ // update system devices
+ m_logger->StartLog(tc_logic, m_kxsystem->GetTimeInSeconds(), true);
+
+ if (m_keyboarddevice)
+ m_keyboarddevice->NextFrame();
+
+ if (m_mousedevice)
+ m_mousedevice->NextFrame();
+
+ if (m_networkdevice)
+ m_networkdevice->NextFrame();
+
+ if (m_audiodevice)
+ m_audiodevice->NextFrame();
+
+ // scene management
+ ProcessScheduledScenes();
+
+ // Start logging time spend outside main loop
+ m_logger->StartLog(tc_outside, m_kxsystem->GetTimeInSeconds(), true);
+}
+
+
+
+void KX_KetsjiEngine::Render()
+{
+ KX_Scene* firstscene = *m_scenes.begin();
+ const RAS_FrameSettings &framesettings = firstscene->GetFramingType();
+
+ m_logger->StartLog(tc_rasterizer, m_kxsystem->GetTimeInSeconds(), true);
+
+ // hiding mouse cursor each frame
+ // (came back when going out of focus and then back in again)
+ if (m_hideCursor)
+ m_canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE);
+
+ // clear the entire game screen with the border color
+ // only once per frame
+ m_canvas->BeginDraw();
+ if (m_drawingmode == RAS_IRasterizer::KX_TEXTURED) {
+ m_canvas->SetViewPort(0, 0, m_canvas->GetWidth(), m_canvas->GetHeight());
+ if (m_overrideFrameColor)
+ {
+ // Do not use the framing bar color set in the Blender scenes
+ m_canvas->ClearColor(
+ m_overrideFrameColorR,
+ m_overrideFrameColorG,
+ m_overrideFrameColorB,
+ 1.0
+ );
+ }
+ else
+ {
+ // Use the framing bar color set in the Blender scenes
+ m_canvas->ClearColor(
+ framesettings.BarRed(),
+ framesettings.BarGreen(),
+ framesettings.BarBlue(),
+ 1.0
+ );
+ }
+ // clear the -whole- viewport
+ m_canvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER);
+ }
+
+ m_rasterizer->SetEye(RAS_IRasterizer::RAS_STEREO_LEFTEYE);
+
+ // BeginFrame() sets the actual drawing area. You can use a part of the window
+ if (!BeginFrame())
+ return;
+
+ KX_SceneList::iterator sceneit;
+ for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++)
+ // for each scene, call the proceed functions
+ {
+ KX_Scene* scene = *sceneit;
+
+ // pass the scene's worldsettings to the rasterizer
+ SetWorldSettings(scene->GetWorldInfo());
+
+ if (scene->IsClearingZBuffer())
+ m_rasterizer->ClearDepthBuffer();
+
+ m_rendertools->SetAuxilaryClientInfo(scene);
+
+ //Initialize scene viewport.
+ SetupRenderFrame(scene);
+
+ // do the rendering
+ RenderFrame(scene);
+ }
+
+ // only one place that checks for stereo
+ if(m_rasterizer->Stereo())
+ {
+ m_rasterizer->SetEye(RAS_IRasterizer::RAS_STEREO_RIGHTEYE);
+
+ if (!BeginFrame())
+ return;
+
+ KX_SceneList::iterator sceneit;
+ for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++)
+ // for each scene, call the proceed functions
+ {
+ KX_Scene* scene = *sceneit;
+
+ // pass the scene's worldsettings to the rasterizer
+ SetWorldSettings(scene->GetWorldInfo());
+
+ if (scene->IsClearingZBuffer())
+ m_rasterizer->ClearDepthBuffer();
+
+ //pass the scene, for picking and raycasting (shadows)
+ m_rendertools->SetAuxilaryClientInfo(scene);
+
+ //Initialize scene viewport.
+ SetupRenderFrame(scene);
+
+ // do the rendering
+ RenderFrame(scene);
+ }
+ } // if(m_rasterizer->Stereo())
+
+ EndFrame();
+}
+
+
+
+void KX_KetsjiEngine::RequestExit(int exitrequestmode)
+{
+ m_exitcode = exitrequestmode;
+}
+
+
+
+void KX_KetsjiEngine::SetNameNextGame(const STR_String& nextgame)
+{
+ m_exitstring = nextgame;
+}
+
+
+
+int KX_KetsjiEngine::GetExitCode()
+{
+ // if a gameactuator has set an exitcode or if there are no scenes left
+ if (!m_exitcode)
+ {
+ if (m_scenes.begin()==m_scenes.end())
+ m_exitcode = KX_EXIT_REQUEST_NO_SCENES_LEFT;
+ }
+
+ return m_exitcode;
+}
+
+
+
+const STR_String& KX_KetsjiEngine::GetExitString()
+{
+ return m_exitstring;
+}
+
+
+
+void KX_KetsjiEngine::DoSound(KX_Scene* scene)
+{
+ m_logger->StartLog(tc_sound, m_kxsystem->GetTimeInSeconds(), true);
+
+ KX_Camera* cam = scene->GetActiveCamera();
+ MT_Point3 listenerposition = cam->NodeGetWorldPosition();
+ MT_Vector3 listenervelocity = cam->GetLinearVelocity();
+ MT_Matrix3x3 listenerorientation = cam->NodeGetWorldOrientation();
+
+ SND_Scene* soundscene = scene->GetSoundScene();
+ soundscene->SetListenerTransform(
+ listenerposition,
+ listenervelocity,
+ listenerorientation);
+
+ soundscene->Proceed();
+}
+
+
+
+void KX_KetsjiEngine::SetBackGround(KX_WorldInfo* wi)
+{
+ if (wi->hasWorld())
+ {
+ if (m_drawingmode == RAS_IRasterizer::KX_TEXTURED)
+ {
+ m_rasterizer->SetBackColor(
+ wi->getBackColorRed(),
+ wi->getBackColorGreen(),
+ wi->getBackColorBlue(),
+ 0.0
+ );
+ }
+ }
+}
+
+
+
+void KX_KetsjiEngine::SetWorldSettings(KX_WorldInfo* wi)
+{
+ if (wi->hasWorld())
+ {
+ if (m_drawingmode == RAS_IRasterizer::KX_TEXTURED)
+ {
+ if (wi->hasMist())
+ {
+ m_rasterizer->SetFog(
+ wi->getMistStart(),
+ wi->getMistDistance(),
+ wi->getMistColorRed(),
+ wi->getMistColorGreen(),
+ wi->getMistColorBlue()
+ );
+ }
+ else
+ {
+ m_rasterizer->DisableFog();
+ }
+ }
+ }
+}
+
+
+
+void KX_KetsjiEngine::SetDrawType(int drawingmode)
+{
+ m_drawingmode = drawingmode;
+}
+
+
+
+void KX_KetsjiEngine::EnableCameraOverride(const STR_String& forscene)
+{
+ m_overrideCam = true;
+ m_overrideSceneName = forscene;
+}
+
+
+
+void KX_KetsjiEngine::SetCameraZoom(float camzoom)
+{
+ m_cameraZoom = camzoom;
+}
+
+
+
+void KX_KetsjiEngine::SetCameraOverrideUseOrtho(bool useOrtho)
+{
+ m_overrideCamUseOrtho = useOrtho;
+}
+
+
+
+void KX_KetsjiEngine::SetCameraOverrideProjectionMatrix(const MT_CmMatrix4x4& mat)
+{
+ m_overrideCamProjMat = mat;
+}
+
+
+void KX_KetsjiEngine::SetCameraOverrideViewMatrix(const MT_CmMatrix4x4& mat)
+{
+ m_overrideCamViewMat = mat;
+}
+
+
+void KX_KetsjiEngine::SetupRenderFrame(KX_Scene *scene)
+{
+ // In this function we make sure the rasterizer settings are upto
+ // date. We compute the viewport so that logic
+ // using this information is upto date.
+
+ // Note we postpone computation of the projection matrix
+ // so that we are using the latest camera position.
+
+ RAS_Rect viewport;
+
+ if (
+ m_overrideCam ||
+ (scene->GetName() != m_overrideSceneName) ||
+ m_overrideCamUseOrtho
+ ) {
+ RAS_FramingManager::ComputeViewport(
+ scene->GetFramingType(),
+ m_canvas->GetDisplayArea(),
+ viewport
+ );
+ } else {
+ viewport.SetLeft(0);
+ viewport.SetBottom(0);
+ viewport.SetRight(int(m_canvas->GetWidth()));
+ viewport.SetTop(int(m_canvas->GetHeight()));
+ }
+ // store the computed viewport in the scene
+
+ scene->SetSceneViewport(viewport);
+
+ // set the viewport for this frame and scene
+ m_canvas->SetViewPort(
+ viewport.GetLeft(),
+ viewport.GetBottom(),
+ viewport.GetRight(),
+ viewport.GetTop()
+ );
+
+}
+
+
+// update graphics
+void KX_KetsjiEngine::RenderFrame(KX_Scene* scene)
+{
+ float left, right, bottom, top, nearfrust, farfrust;
+ KX_Camera* cam = scene->GetActiveCamera();
+
+ m_rasterizer->DisplayFog();
+
+ if (m_overrideCam && (scene->GetName() == m_overrideSceneName) && m_overrideCamUseOrtho) {
+ MT_CmMatrix4x4 projmat = m_overrideCamProjMat;
+ m_rasterizer->SetProjectionMatrix(projmat);
+ } else {
+ RAS_FrameFrustum frustum;
+
+ RAS_FramingManager::ComputeFrustum(
+ scene->GetFramingType(),
+ m_canvas->GetDisplayArea(),
+ scene->GetSceneViewport(),
+ cam->GetLens(),
+ cam->GetCameraNear(),
+ cam->GetCameraFar(),
+ frustum
+ );
+
+ left = frustum.x1 * m_cameraZoom;
+ right = frustum.x2 * m_cameraZoom;
+ bottom = frustum.y1 * m_cameraZoom;
+ top = frustum.y2 * m_cameraZoom;
+ nearfrust = frustum.camnear;
+ farfrust = frustum.camfar;
+
+ MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix(
+ left, right, bottom, top, nearfrust, farfrust);
+
+ m_rasterizer->SetProjectionMatrix(projmat);
+ cam->SetProjectionMatrix(projmat);
+ }
+
+ MT_Scalar cammat[16];
+ cam->GetWorldToCamera().getValue(cammat);
+ MT_Matrix4x4 viewmat;
+ viewmat.setValue(cammat); // this _should transpose ...
+ // if finally transposed take care of correct usage
+ // in RAS_OpenGLRasterizer ! (row major vs column major)
+
+ m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldPosition(),
+ cam->GetCameraLocation(), cam->GetCameraOrientation());
+ cam->SetModelviewMatrix(viewmat);
+
+ scene->UpdateMeshTransformations();
+
+ // The following actually reschedules all vertices to be
+ // redrawn. There is a cache between the actual rescheduling
+ // and this call though. Visibility is imparted when this call
+ // runs through the individual objects.
+ scene->CalculateVisibleMeshes(m_rasterizer);
+
+ scene->RenderBuckets(cam->GetWorldToCamera(), m_rasterizer, m_rendertools);
+}
+
+
+
+void KX_KetsjiEngine::StopEngine()
+{
+ if (m_bInitialized)
+ {
+ KX_SceneList::iterator sceneit;
+ for (sceneit = m_scenes.begin();sceneit != m_scenes.end() ; sceneit++)
+ {
+ KX_Scene* scene = *sceneit;
+ delete scene;
+ }
+ m_scenes.clear();
+
+ // cleanup all the stuff
+ m_rasterizer->Exit();
+ }
+}
+
+// Scene Management is able to switch between scenes
+// and have several scene's running in parallel
+void KX_KetsjiEngine::AddScene(KX_Scene* scene)
+{
+ m_scenes.push_back(scene);
+ PostProcessScene(scene);
+ SceneListsChanged();
+}
+
+
+
+void KX_KetsjiEngine::PostProcessScene(KX_Scene* scene)
+{
+ bool override_camera = (m_overrideCam && (scene->GetName() == m_overrideSceneName));
+
+ // if there is no activecamera, or the camera is being
+ // overridden we need to construct a temporarily camera
+ if (!scene->GetActiveCamera() || override_camera)
+ {
+ KX_Camera* activecam = NULL;
+
+ RAS_CameraData camdata;
+ camdata.m_lens = 35.0f;
+ camdata.m_clipstart = 0.1f;
+ camdata.m_clipend = 100.0f;
+ activecam = new KX_Camera(scene,KX_Scene::m_callbacks,camdata);
+ activecam->SetName("__default__cam__");
+
+ // set transformation
+ if (override_camera) {
+ const MT_CmMatrix4x4& cammatdata = m_overrideCamViewMat;
+ MT_Transform trans = MT_Transform(cammatdata.getPointer());
+ MT_Transform camtrans;
+ camtrans.invert(trans);
+
+ activecam->NodeSetLocalPosition(camtrans.getOrigin());
+ activecam->NodeSetLocalOrientation(camtrans.getBasis());
+ activecam->NodeUpdateGS(0,true);
+ } else {
+ activecam->NodeSetLocalPosition(MT_Point3(0.0, 0.0, 0.0));
+ activecam->NodeSetLocalOrientation(MT_Vector3(0.0, 0.0, 0.0));
+ activecam->NodeUpdateGS(0,true);
+ }
+
+ scene->AddCamera(activecam);
+ scene->SetActiveCamera(activecam);
+ scene->GetObjectList()->Add(activecam->AddRef());
+ scene->GetRootParentList()->Add(activecam->AddRef());
+ }
+
+ scene->UpdateParents(0.0);
+}
+
+
+
+void KX_KetsjiEngine::RenderDebugProperties()
+{
+ STR_String debugtxt;
+ int xcoord = 10; // mmmm, these constants were taken from blender source
+ int ycoord = 14; // to 'mimic' behaviour
+
+ float tottime = m_logger->GetAverage();
+ if (tottime < 1e-6f) {
+ tottime = 1e-6f;
+ }
+
+ /* Framerate display */
+ if (m_show_framerate) {
+ debugtxt.Format("swap : %.3f (%.3f frames per second)", tottime, 1.0/tottime);
+ m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED,
+ debugtxt.Ptr(),
+ xcoord,
+ ycoord,
+ m_canvas->GetWidth() /* RdV, TODO ?? */,
+ m_canvas->GetHeight() /* RdV, TODO ?? */);
+ ycoord += 14;
+ }
+
+ /* Profile and framerate display */
+ if (m_show_profile)
+ {
+ for (int j = tc_first; j < tc_numCategories; j++)
+ {
+ debugtxt.Format(m_profileLabels[j]);
+ m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED,
+ debugtxt.Ptr(),
+ xcoord,ycoord,
+ m_canvas->GetWidth(),
+ m_canvas->GetHeight());
+ double time = m_logger->GetAverage((KX_TimeCategory)j);
+ debugtxt.Format("%2.2f %%", time/tottime * 100.f);
+ m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED,
+ debugtxt.Ptr(),
+ xcoord + 60 ,ycoord,
+ m_canvas->GetWidth(),
+ m_canvas->GetHeight());
+ ycoord += 14;
+ }
+ }
+
+ /* Property display*/
+ if (m_show_debug_properties && m_propertiesPresent)
+ {
+ KX_SceneList::iterator sceneit;
+ for (sceneit = m_scenes.begin();sceneit != m_scenes.end() ; sceneit++)
+ {
+ KX_Scene* scene = *sceneit;
+ /* the 'normal' debug props */
+ vector<SCA_DebugProp*>& debugproplist = scene->GetDebugProperties();
+
+ for (vector<SCA_DebugProp*>::iterator it = debugproplist.begin();
+ !(it==debugproplist.end());it++)
+ {
+ CValue* propobj = (*it)->m_obj;
+ STR_String objname = propobj->GetName();
+ STR_String propname = (*it)->m_name;
+ CValue* propval = propobj->GetProperty(propname);
+ if (propval)
+ {
+ STR_String text = propval->GetText();
+ debugtxt = objname + "." + propname + " = " + text;
+ m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED,
+ debugtxt.Ptr(),
+ xcoord,
+ ycoord,
+ m_canvas->GetWidth(),
+ m_canvas->GetHeight());
+ ycoord += 14;
+ }
+ }
+ }
+ }
+}
+
+
+KX_SceneList* KX_KetsjiEngine::CurrentScenes()
+{
+ return &m_scenes;
+}
+
+
+
+KX_Scene* KX_KetsjiEngine::FindScene(const STR_String& scenename)
+{
+ KX_SceneList::iterator sceneit = m_scenes.begin();
+
+ // bit risky :) better to split the second clause
+ while ( (sceneit != m_scenes.end())
+ && ((*sceneit)->GetName() != scenename))
+ {
+ sceneit++;
+ }
+
+ return ((sceneit == m_scenes.end()) ? NULL : *sceneit);
+}
+
+
+
+void KX_KetsjiEngine::ConvertAndAddScene(const STR_String& scenename,bool overlay)
+{
+ // only add scene when it doesn't exist!
+ if (FindScene(scenename))
+ {
+ STR_String tmpname = scenename;
+ printf("warning: scene %s already exists, not added!\n",tmpname.Ptr());
+ }
+ else
+ {
+ if (overlay)
+ {
+ m_addingOverlayScenes.insert(scenename);
+ }
+ else
+ {
+ m_addingBackgroundScenes.insert(scenename);
+ }
+ }
+}
+
+
+
+
+void KX_KetsjiEngine::RemoveScene(const STR_String& scenename)
+{
+ if (FindScene(scenename))
+ {
+ m_removingScenes.insert(scenename);
+ }
+ else
+ {
+ STR_String tmpname = scenename;
+ printf("warning: scene %s does not exist, not removed!\n",tmpname.Ptr());
+ }
+}
+
+
+
+void KX_KetsjiEngine::RemoveScheduledScenes()
+{
+ if (m_removingScenes.size())
+ {
+ set<STR_String>::iterator scenenameit;
+ for (scenenameit=m_removingScenes.begin();scenenameit != m_removingScenes.end();scenenameit++)
+ {
+ STR_String scenename = *scenenameit;
+
+ KX_SceneList::iterator sceneit;
+ for (sceneit = m_scenes.begin();sceneit != m_scenes.end() ; sceneit++)
+ {
+ KX_Scene* scene = *sceneit;
+ if (scene->GetName()==scenename)
+ {
+ delete scene;
+ m_scenes.erase(sceneit);
+ break;
+ }
+ }
+ }
+ m_removingScenes.clear();
+ }
+}
+
+
+
+KX_Scene* KX_KetsjiEngine::CreateScene(const STR_String& scenename)
+{
+
+ KX_Scene* tmpscene = new KX_Scene(m_keyboarddevice,
+ m_mousedevice,
+ m_networkdevice,
+ m_audiodevice,
+ scenename);
+
+ m_sceneconverter->ConvertScene(scenename,
+ tmpscene,
+ m_pythondictionary,
+ m_keyboarddevice,
+ m_rendertools,
+ m_canvas);
+
+ return tmpscene;
+}
+
+
+
+void KX_KetsjiEngine::AddScheduledScenes()
+{
+ set<STR_String>::iterator scenenameit;
+
+ if (m_addingOverlayScenes.size())
+ {
+ for (scenenameit = m_addingOverlayScenes.begin();
+ scenenameit != m_addingOverlayScenes.end();
+ scenenameit++)
+ {
+ STR_String scenename = *scenenameit;
+ KX_Scene* tmpscene = CreateScene(scenename);
+ m_scenes.push_back(tmpscene);
+ PostProcessScene(tmpscene);
+ }
+ m_addingOverlayScenes.clear();
+ }
+
+ if (m_addingBackgroundScenes.size())
+ {
+ for (scenenameit = m_addingBackgroundScenes.begin();
+ scenenameit != m_addingBackgroundScenes.end();
+ scenenameit++)
+ {
+ STR_String scenename = *scenenameit;
+ KX_Scene* tmpscene = CreateScene(scenename);
+ m_scenes.insert(m_scenes.begin(),tmpscene);
+ PostProcessScene(tmpscene);
+
+ }
+ m_addingBackgroundScenes.clear();
+ }
+}
+
+
+
+void KX_KetsjiEngine::ReplaceScene(const STR_String& oldscene,const STR_String& newscene)
+{
+ m_replace_scenes.insert(std::make_pair(oldscene,newscene));
+}
+
+// replace scene is not the same as removing and adding because the
+// scene must be in exact the same place (to maintain drawingorder)
+// (nzc) - should that not be done with a scene-display list? It seems
+// stupid to rely on the mem allocation order...
+void KX_KetsjiEngine::ReplaceScheduledScenes()
+{
+ if (m_replace_scenes.size())
+ {
+ set<pair<STR_String,STR_String> >::iterator scenenameit;
+
+ for (scenenameit = m_replace_scenes.begin();
+ scenenameit != m_replace_scenes.end();
+ scenenameit++)
+ {
+ STR_String oldscenename = (*scenenameit).first;
+ STR_String newscenename = (*scenenameit).second;
+ int i=0;
+ /* Scenes are not supposed to be included twice... I think */
+ KX_SceneList::iterator sceneit;
+ for (sceneit = m_scenes.begin();sceneit != m_scenes.end() ; sceneit++)
+ {
+ KX_Scene* scene = *sceneit;
+ if (scene->GetName() == oldscenename)
+ {
+ delete scene;
+ KX_Scene* tmpscene = CreateScene(newscenename);
+ m_scenes[i]=tmpscene;
+ PostProcessScene(tmpscene);
+ }
+ i++;
+ }
+ }
+ m_replace_scenes.clear();
+ }
+}
+
+
+
+void KX_KetsjiEngine::SuspendScene(const STR_String& scenename)
+{
+ KX_Scene* scene = FindScene(scenename);
+ if (scene) scene->Suspend();
+}
+
+
+
+void KX_KetsjiEngine::ResumeScene(const STR_String& scenename)
+{
+ KX_Scene* scene = FindScene(scenename);
+ if (scene) scene->Resume();
+}
+
+
+
+void KX_KetsjiEngine::SetUseFixedTime(bool bUseFixedTime)
+{
+ m_bFixedTime = bUseFixedTime;
+}
+
+
+
+bool KX_KetsjiEngine::GetUseFixedTime(void) const
+{
+ return m_bFixedTime;
+}
+
+
+
+void KX_KetsjiEngine::SetTimingDisplay(bool frameRate, bool profile, bool properties)
+{
+ m_show_framerate = frameRate;
+ m_show_profile = profile;
+ m_show_debug_properties = properties;
+}
+
+
+
+void KX_KetsjiEngine::GetTimingDisplay(bool& frameRate, bool& profile, bool& properties) const
+{
+ frameRate = m_show_framerate;
+ profile = m_show_profile;
+ properties = m_show_debug_properties;
+}
+
+
+
+void KX_KetsjiEngine::ProcessScheduledScenes(void)
+{
+ // Check whether there will be changes to the list of scenes
+ if (m_addingOverlayScenes.size() ||
+ m_addingBackgroundScenes.size() ||
+ m_replace_scenes.size() ||
+ m_removingScenes.size()) {
+
+ // Change the scene list
+ ReplaceScheduledScenes();
+ RemoveScheduledScenes();
+ AddScheduledScenes();
+
+ // Notify
+ SceneListsChanged();
+ }
+}
+
+
+
+void KX_KetsjiEngine::SceneListsChanged(void)
+{
+ m_propertiesPresent = false;
+ KX_SceneList::iterator sceneit = m_scenes.begin();
+ while ((sceneit != m_scenes.end()) && (!m_propertiesPresent))
+ {
+ KX_Scene* scene = *sceneit;
+ vector<SCA_DebugProp*>& debugproplist = scene->GetDebugProperties();
+ m_propertiesPresent = !debugproplist.empty();
+ sceneit++;
+ }
+}
+
+
+void KX_KetsjiEngine::SetHideCursor(bool hideCursor)
+{
+ m_hideCursor = hideCursor;
+}
+
+
+bool KX_KetsjiEngine::GetHideCursor(void) const
+{
+ return m_hideCursor;
+}
+
+
+void KX_KetsjiEngine::SetUseOverrideFrameColor(bool overrideFrameColor)
+{
+ m_overrideFrameColor = overrideFrameColor;
+}
+
+
+bool KX_KetsjiEngine::GetUseOverrideFrameColor(void) const
+{
+ return m_overrideFrameColor;
+}
+
+
+void KX_KetsjiEngine::SetOverrideFrameColor(float r, float g, float b)
+{
+ m_overrideFrameColorR = r;
+ m_overrideFrameColorG = g;
+ m_overrideFrameColorB = b;
+}
+
+
+void KX_KetsjiEngine::GetOverrideFrameColor(float& r, float& g, float& b) const
+{
+ r = m_overrideFrameColorR;
+ g = m_overrideFrameColorG;
+ b = m_overrideFrameColorB;
+}
+
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h
new file mode 100644
index 00000000000..4246bc28b50
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h
@@ -0,0 +1,316 @@
+/*
+ * $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_KETSJI_ENGINE
+#define __KX_KETSJI_ENGINE
+
+#include "MT_CmMatrix4x4.h"
+#include "MT_Matrix4x4.h"
+#include "STR_String.h"
+#include "KX_ISystem.h"
+#include "KX_Scene.h"
+#include "KX_Python.h"
+#include "KX_WorldInfo.h"
+#include <vector>
+#include <set>
+
+class KX_TimeCategoryLogger;
+
+#define LEFT_EYE 1
+#define RIGHT_EYE 2
+
+enum KX_ExitRequestMode
+{
+ KX_EXIT_REQUEST_NO_REQUEST = 0,
+ KX_EXIT_REQUEST_QUIT_GAME,
+ KX_EXIT_REQUEST_RESTART_GAME,
+ KX_EXIT_REQUEST_START_OTHER_GAME,
+ KX_EXIT_REQUEST_NO_SCENES_LEFT,
+ KX_EXIT_REQUEST_BLENDER_ESC,
+ KX_EXIT_REQUEST_OUTSIDE,
+ KX_EXIT_REQUEST_MAX
+};
+
+class KX_KetsjiEngine
+{
+
+private:
+ class RAS_ICanvas* m_canvas; // 2D Canvas (2D Rendering Device Context)
+ class RAS_IRasterizer* m_rasterizer; // 3D Rasterizer (3D Rendering)
+ class KX_ISystem* m_kxsystem;
+ class RAS_IRenderTools* m_rendertools;
+ class KX_ISceneConverter* m_sceneconverter;
+ class NG_NetworkDeviceInterface* m_networkdevice;
+ class SND_IAudioDevice* m_audiodevice;
+ PyObject* m_pythondictionary;
+ class SCA_IInputDevice* m_keyboarddevice;
+ class SCA_IInputDevice* m_mousedevice;
+
+ /** Lists of scenes scheduled to be removed at the end of the frame. */
+ std::set<STR_String> m_removingScenes;
+ /** Lists of overley scenes scheduled to be added at the end of the frame. */
+ std::set<STR_String> m_addingOverlayScenes;
+ /** Lists of background scenes scheduled to be added at the end of the frame. */
+ std::set<STR_String> m_addingBackgroundScenes;
+ /** Lists of scenes scheduled to be replaced at the end of the frame. */
+ std::set<std::pair<STR_String,STR_String> > m_replace_scenes;
+
+ /* The current list of scenes. */
+ KX_SceneList m_scenes;
+ /* State variable recording the presence of object debug info in the current scene list. */
+ bool m_propertiesPresent;
+
+ bool m_bInitialized;
+ int m_activecam;
+ bool m_bFixedTime;
+
+ bool m_firstframe;
+ double m_previoustime;
+ double m_missedtime;
+ double m_lasttime; // old style time
+ double m_dtime;
+ std::vector<double> m_deltatimes;
+
+ int m_exitcode;
+ STR_String m_exitstring;
+ /**
+ * Some drawing parameters, the drawing mode
+ * (wire/flat/texture), and the camera zoom
+ * factor.
+ */
+ int m_drawingmode;
+ float m_cameraZoom;
+
+ bool m_overrideCam;
+ STR_String m_overrideSceneName;
+
+ bool m_overrideCamUseOrtho;
+ MT_CmMatrix4x4 m_overrideCamProjMat;
+ MT_CmMatrix4x4 m_overrideCamViewMat;
+
+ bool m_stereo;
+ int m_curreye;
+
+ /** Categories for profiling display. */
+ typedef enum
+ {
+ tc_first = 0,
+ tc_physics = 0,
+ tc_logic,
+ tc_network,
+ tc_scenegraph,
+ tc_sound,
+ tc_rasterizer,
+ tc_services, // time spend in miscelaneous activities
+ tc_overhead, // profile info drawing overhead
+ tc_outside, // time spend outside main loop
+ tc_numCategories
+ } KX_TimeCategory;
+
+ /** Time logger. */
+ KX_TimeCategoryLogger* m_logger;
+
+ /** Labels for profiling display. */
+ static const char m_profileLabels[tc_numCategories][15];
+ /** Show the framerate on the game display? */
+ bool m_show_framerate;
+ /** Show profiling info on the game display? */
+ bool m_show_profile;
+ /** Show any debug (scene) object properties on the game display? */
+ bool m_showProperties;
+ /** Show background behind text for readability? */
+ bool m_showBackground;
+
+ bool m_show_debug_properties;
+
+ /** Hide cursor every frame? */
+ bool m_hideCursor;
+
+ /** Override framing bars color? */
+ bool m_overrideFrameColor;
+ /** Red component of framing bar color. */
+ float m_overrideFrameColorR;
+ /** Green component of framing bar color. */
+ float m_overrideFrameColorG;
+ /** Blue component of framing bar color. */
+ float m_overrideFrameColorB;
+
+ double CalculateAverage(double newdeltatime);
+
+ void SetupRenderFrame(KX_Scene *scene);
+ void RenderFrame(KX_Scene* scene);
+ void RenderDebugProperties();
+ void SetBackGround(KX_WorldInfo* worldinfo);
+ void SetWorldSettings(KX_WorldInfo* worldinfo);
+ void DoSound(KX_Scene* scene);
+
+public:
+
+ KX_KetsjiEngine(class KX_ISystem* system);
+ virtual ~KX_KetsjiEngine();
+
+ // set the devices and stuff. the client must take care of creating these
+ void SetKeyboardDevice(SCA_IInputDevice* keyboarddevice);
+ void SetMouseDevice(SCA_IInputDevice* mousedevice);
+ void SetNetworkDevice(NG_NetworkDeviceInterface* networkdevice);
+ void SetAudioDevice(SND_IAudioDevice* audiodevice);
+ void SetCanvas(RAS_ICanvas* canvas);
+ void SetRenderTools(RAS_IRenderTools* rendertools);
+ void SetRasterizer(RAS_IRasterizer* rasterizer);
+ void SetPythonDictionary(PyObject* pythondictionary);
+ void SetSceneConverter(KX_ISceneConverter* sceneconverter);
+
+ void NextFrame();
+ void Render();
+
+ void StartEngine();
+ void StopEngine();
+ void Export(const STR_String& filename);
+
+ void RequestExit(int exitrequestmode);
+ void SetNameNextGame(const STR_String& nextgame);
+ int GetExitCode();
+ const STR_String& GetExitString();
+
+ KX_SceneList* CurrentScenes();
+ KX_Scene* FindScene(const STR_String& scenename);
+ void AddScene(class KX_Scene* scene);
+ void ConvertAndAddScene(const STR_String& scenename,bool overlay);
+
+ void RemoveScene(const STR_String& scenename);
+ void ReplaceScene(const STR_String& oldscene,const STR_String& newscene);
+ void SuspendScene(const STR_String& scenename);
+ void ResumeScene(const STR_String& scenename);
+
+ void SetDrawType(int drawingtype);
+ void SetCameraZoom(float camzoom);
+
+ void EnableCameraOverride(const STR_String& forscene);
+
+ void SetCameraOverrideUseOrtho(bool useOrtho);
+ void SetCameraOverrideProjectionMatrix(const MT_CmMatrix4x4& mat);
+ void SetCameraOverrideViewMatrix(const MT_CmMatrix4x4& mat);
+
+ /**
+ * Sets display of all frames.
+ * @param bUseFixedTime New setting for display all frames.
+ */
+ void SetUseFixedTime(bool bUseFixedTime);
+
+ /**
+ * Returns display of all frames.
+ * @return Current setting for display all frames.
+ */
+ bool GetUseFixedTime(void) const;
+
+ /**
+ * Activates or deactivates timing information display.
+ * @param frameRate Display for frame rate on or off.
+ * @param profile Display for individual components on or off.
+ * @param properties Display of scene object debug properties on or off.
+ */
+ void SetTimingDisplay(bool frameRate, bool profile, bool properties);
+
+ /**
+ * Returns status of timing information display.
+ * @param frameRate Display for frame rate on or off.
+ * @param profile Display for individual components on or off.
+ * @param properties Display of scene object debug properties on or off.
+ */
+ void GetTimingDisplay(bool& frameRate, bool& profile, bool& properties) const;
+
+ /**
+ * Sets cursor hiding on every frame.
+ * @param hideCursor Turns hiding on or off.
+ */
+ void SetHideCursor(bool hideCursor);
+
+ /**
+ * Returns the current setting for cursor hiding.
+ * @return The current setting for cursor hiding.
+ */
+ bool GetHideCursor(void) const;
+
+ /**
+ * Enables/disables the use of the framing bar color of the Blender file's scenes.
+ * @param overrideFrameColor The new setting.
+ */
+ void SetUseOverrideFrameColor(bool overrideFrameColor);
+
+ /**
+ * Enables/disables the use of the framing bar color of the Blender file's scenes.
+ * @param useSceneFrameColor The new setting.
+ */
+ bool GetUseOverrideFrameColor(void) const;
+
+ /**
+ * Set the color used for framing bar color instead of the one in the Blender file's scenes.
+ * @param r Red component of the override color.
+ * @param g Green component of the override color.
+ * @param b Blue component of the override color.
+ */
+ void SetOverrideFrameColor(float r, float g, float b);
+
+ /**
+ * Returns the color used for framing bar color instead of the one in the Blender file's scenes.
+ * @param r Red component of the override color.
+ * @param g Green component of the override color.
+ * @param b Blue component of the override color.
+ */
+ void GetOverrideFrameColor(float& r, float& g, float& b) const;
+
+protected:
+ /**
+ * Processes all scheduled scene activity.
+ * At the end, if the scene lists have changed,
+ * SceneListsChanged(void) is called.
+ * @see SceneListsChanged(void).
+ */
+ void ProcessScheduledScenes(void);
+
+ /**
+ * This method is invoked when the scene lists have changed.
+ */
+ void SceneListsChanged(void);
+
+ void RemoveScheduledScenes(void);
+ void AddScheduledScenes(void);
+ void ReplaceScheduledScenes(void);
+ void PostProcessScene(class KX_Scene* scene);
+ KX_Scene* CreateScene(const STR_String& scenename);
+
+ bool BeginFrame();
+ void EndFrame();
+};
+
+#endif //__KX_KETSJI_ENGINE
+
diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp
new file mode 100644
index 00000000000..25e756ae66c
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_Light.cpp
@@ -0,0 +1,75 @@
+/**
+ * $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
+
+#pragma warning (disable : 4786)
+#endif
+
+#include "KX_Light.h"
+#include "RAS_IRenderTools.h"
+
+
+KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,
+ class RAS_IRenderTools* rendertools,
+ const RAS_LightObject& lightobj
+ )
+ :
+ KX_GameObject(sgReplicationInfo,callbacks),
+ m_rendertools(rendertools)
+{
+ m_lightobj = lightobj;
+ m_lightobj.m_worldmatrix = GetOpenGLMatrixPtr();
+ m_rendertools->AddLight(&m_lightobj);
+};
+
+
+KX_LightObject::~KX_LightObject()
+{
+
+ m_rendertools->RemoveLight(&m_lightobj);
+}
+
+
+CValue* KX_LightObject::GetReplica()
+{
+
+ KX_LightObject* replica = new KX_LightObject(*this);
+
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ ProcessReplica(replica);
+
+ replica->m_lightobj.m_worldmatrix = replica->GetOpenGLMatrixPtr();
+ m_rendertools->AddLight(&replica->m_lightobj);
+ return replica;
+}
diff --git a/source/gameengine/Ketsji/KX_Light.h b/source/gameengine/Ketsji/KX_Light.h
new file mode 100644
index 00000000000..0ee91040c84
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_Light.h
@@ -0,0 +1,50 @@
+/**
+ * $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_LIGHT
+#define __KX_LIGHT
+
+#include "RAS_LightObject.h"
+#include "KX_GameObject.h"
+
+class KX_LightObject : public KX_GameObject
+{
+ RAS_LightObject m_lightobj;
+ class RAS_IRenderTools* m_rendertools; //needed for registering and replication of lightobj
+
+public:
+ KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,class RAS_IRenderTools* rendertools,const struct RAS_LightObject& lightobj);
+ virtual ~KX_LightObject();
+ virtual CValue* GetReplica();
+ RAS_LightObject* GetLightData() { return &m_lightobj;}
+};
+
+#endif //__KX_LIGHT
diff --git a/source/gameengine/Ketsji/KX_LightIpoSGController.cpp b/source/gameengine/Ketsji/KX_LightIpoSGController.cpp
new file mode 100644
index 00000000000..3dd26947a79
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_LightIpoSGController.cpp
@@ -0,0 +1,118 @@
+/**
+ * $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 "KX_LightIpoSGController.h"
+
+#include "KX_ScalarInterpolator.h"
+#include "KX_Light.h"
+
+#include "RAS_LightObject.h"
+
+
+bool KX_LightIpoSGController::Update(double currentTime)
+{
+ if (m_modified)
+ {
+ T_InterpolatorList::iterator i;
+ for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) {
+ (*i)->Execute(m_ipotime);//currentTime);
+ }
+
+ RAS_LightObject *lightobj;
+
+ SG_Spatial* ob = (SG_Spatial*)m_pObject;
+ KX_LightObject* kxlight = (KX_LightObject*) ob->GetSGClientObject();
+ lightobj = kxlight->GetLightData();
+ //lightobj = (KX_Light*)
+
+ if (m_modify_energy) {
+ lightobj->m_energy = m_energy;
+ }
+
+ if (m_modify_color) {
+ lightobj->m_red = m_col_rgb[0];
+ lightobj->m_green = m_col_rgb[1];
+ lightobj->m_blue = m_col_rgb[2];
+ }
+
+ if (m_modify_dist) {
+ lightobj->m_distance = m_dist;
+ }
+
+ m_modified=false;
+ }
+ return false;
+}
+
+
+void KX_LightIpoSGController::AddInterpolator(KX_IInterpolator* interp)
+{
+ this->m_interpolators.push_back(interp);
+}
+
+SG_Controller* KX_LightIpoSGController::GetReplica(class SG_Node* destnode)
+{
+ KX_LightIpoSGController* iporeplica = new KX_LightIpoSGController(*this);
+ // clear object that ipo acts on
+ iporeplica->ClearObject();
+
+ // dirty hack, ask Gino for a better solution in the ipo implementation
+ // hacken en zagen, in what we call datahiding, not written for replication :(
+
+ T_InterpolatorList oldlist = m_interpolators;
+ iporeplica->m_interpolators.clear();
+
+ T_InterpolatorList::iterator i;
+ for (i = oldlist.begin(); !(i == oldlist.end()); ++i) {
+ KX_ScalarInterpolator* copyipo = new KX_ScalarInterpolator(*((KX_ScalarInterpolator*)*i));
+ iporeplica->AddInterpolator(copyipo);
+
+ MT_Scalar* scaal = ((KX_ScalarInterpolator*)*i)->GetTarget();
+ int orgbase = (int)this;
+ int orgloc = (int)scaal;
+ int offset = orgloc-orgbase;
+ int newaddrbase = (int)iporeplica + offset;
+ MT_Scalar* blaptr = (MT_Scalar*) newaddrbase;
+ copyipo->SetNewTarget((MT_Scalar*)blaptr);
+ }
+
+ return iporeplica;
+}
+
+KX_LightIpoSGController::~KX_LightIpoSGController()
+{
+
+ T_InterpolatorList::iterator i;
+ for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) {
+ delete (*i);
+ }
+
+}
diff --git a/source/gameengine/Ketsji/KX_LightIpoSGController.h b/source/gameengine/Ketsji/KX_LightIpoSGController.h
new file mode 100644
index 00000000000..2b115fcc00f
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_LightIpoSGController.h
@@ -0,0 +1,99 @@
+/**
+ * $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_LIGHTIPOSGCONTROLLER_H
+#define KX_LIGHTIPOSGCONTROLLER_H
+
+#include "SG_Controller.h"
+#include "SG_Spatial.h"
+
+#include "KX_IInterpolator.h"
+
+struct RAS_LightObject;
+
+class KX_LightIpoSGController : public SG_Controller
+{
+public:
+ MT_Scalar m_energy;
+ MT_Scalar m_col_rgb[3];
+ MT_Scalar m_dist;
+
+private:
+ T_InterpolatorList m_interpolators;
+ unsigned short m_modify_energy : 1;
+ unsigned short m_modify_color : 1;
+ unsigned short m_modify_dist : 1;
+ bool m_modified;
+
+ double m_ipotime;
+public:
+ KX_LightIpoSGController() : m_ipotime(0.0),
+ m_modify_energy(false),
+ m_modify_color(false),
+ m_modify_dist(false),
+ m_modified(true)
+ {}
+
+ virtual ~KX_LightIpoSGController();
+
+ virtual SG_Controller* GetReplica(class SG_Node* destnode);
+
+ virtual bool Update(double time);
+
+ virtual void SetSimulatedTime(double time) {
+ m_ipotime = time;
+ m_modified = true;
+ }
+
+ void SetModifyEnergy(bool modify) {
+ m_modify_energy = modify;
+ }
+
+ void SetModifyColor(bool modify) {
+ m_modify_color = modify;
+ }
+
+ void SetModifyDist(bool modify) {
+ m_modify_dist = modify;
+ }
+
+ void
+ SetOption(
+ int option,
+ int value
+ ){
+ // intentionally empty
+ };
+
+ void AddInterpolator(KX_IInterpolator* interp);
+};
+
+#endif // KX_LIGHTIPOSGCONTROLLER_H
diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp
new file mode 100644
index 00000000000..f17e5820d52
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp
@@ -0,0 +1,193 @@
+/**
+ * $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 "KX_MeshProxy.h"
+
+#include "RAS_IPolygonMaterial.h"
+#include "RAS_MeshObject.h"
+#include "KX_VertexProxy.h"
+
+
+PyTypeObject KX_MeshProxy::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "KX_MeshProxy",
+ sizeof(KX_MeshProxy),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject KX_MeshProxy::Parents[] = {
+ &KX_MeshProxy::Type,
+ &SCA_IObject::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef KX_MeshProxy::Methods[] = {
+{"getNumMaterials", (PyCFunction)KX_MeshProxy::sPyGetNumMaterials,METH_VARARGS},
+{"getMaterialName", (PyCFunction)KX_MeshProxy::sPyGetMaterialName,METH_VARARGS},
+{"getTextureName", (PyCFunction)KX_MeshProxy::sPyGetTextureName,METH_VARARGS},
+{"getVertexArrayLength", (PyCFunction)KX_MeshProxy::sPyGetVertexArrayLength,METH_VARARGS},
+{"getVertex", (PyCFunction)KX_MeshProxy::sPyGetVertex,METH_VARARGS},
+//{"getIndexArrayLength", (PyCFunction)KX_MeshProxy::sPyGetIndexArrayLength,METH_VARARGS},
+
+ {NULL,NULL} //Sentinel
+};
+
+PyObject*
+KX_MeshProxy::_getattr(char* attr)
+{
+ _getattr_up(SCA_IObject);
+}
+
+
+
+KX_MeshProxy::KX_MeshProxy(RAS_MeshObject* mesh)
+ : m_meshobj(mesh)
+{
+
+}
+
+KX_MeshProxy::~KX_MeshProxy()
+{
+
+}
+
+
+
+// stuff for cvalue related things
+CValue* KX_MeshProxy::Calc(VALUE_OPERATOR op, CValue *val) { return NULL;}
+CValue* KX_MeshProxy::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val) { return NULL;}
+
+const STR_String & KX_MeshProxy::GetText() {return m_meshobj->GetName();};
+float KX_MeshProxy::GetNumber() { return -1;}
+STR_String KX_MeshProxy::GetName() { return m_meshobj->GetName();}
+void KX_MeshProxy::SetName(STR_String name) { };
+CValue* KX_MeshProxy::GetReplica() { return NULL;}
+void KX_MeshProxy::ReplicaSetName(STR_String name) {};
+
+
+// stuff for python integration
+
+PyObject* KX_MeshProxy::PyGetNumMaterials(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ int num = m_meshobj->NumMaterials();
+ return PyInt_FromLong(num);
+}
+
+PyObject* KX_MeshProxy::PyGetMaterialName(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ int matid= 1;
+ STR_String matname;
+
+ if (PyArg_ParseTuple(args,"i",&matid))
+ {
+ matname = m_meshobj->GetMaterialName(matid);
+ }
+
+ return PyString_FromString(matname.Ptr());
+
+}
+
+
+PyObject* KX_MeshProxy::PyGetTextureName(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ int matid= 1;
+ STR_String matname;
+
+ if (PyArg_ParseTuple(args,"i",&matid))
+ {
+ matname = m_meshobj->GetTextureName(matid);
+ }
+
+ return PyString_FromString(matname.Ptr());
+
+}
+
+PyObject* KX_MeshProxy::PyGetVertexArrayLength(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ int matid= -1;
+ int length = -1;
+
+
+ if (PyArg_ParseTuple(args,"i",&matid))
+ {
+ RAS_IPolyMaterial* mat = m_meshobj->GetMaterialBucket(matid)->GetPolyMaterial();
+ if (mat)
+ {
+ length = m_meshobj->GetVertexArrayLength(mat);
+ }
+ }
+
+ return PyInt_FromLong(length);
+
+}
+
+
+PyObject* KX_MeshProxy::PyGetVertex(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ int vertexindex= 1;
+ int matindex= 1;
+ PyObject* vertexob = NULL;
+
+ if (PyArg_ParseTuple(args,"ii",&matindex,&vertexindex))
+ {
+ RAS_TexVert* vertex = m_meshobj->GetVertex(matindex,vertexindex);
+ if (vertex)
+ {
+ vertexob = new KX_VertexProxy(vertex);
+ }
+ }
+
+ return vertexob;
+
+}
diff --git a/source/gameengine/Ketsji/KX_MeshProxy.h b/source/gameengine/Ketsji/KX_MeshProxy.h
new file mode 100644
index 00000000000..a6c5b7558a2
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_MeshProxy.h
@@ -0,0 +1,66 @@
+/**
+ * $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_MESHPROXY
+#define __KX_MESHPROXY
+
+#include "SCA_IObject.h"
+
+class KX_MeshProxy : public SCA_IObject
+{
+ Py_Header;
+
+ class RAS_MeshObject* m_meshobj;
+public:
+ KX_MeshProxy(class RAS_MeshObject* mesh);
+ virtual ~KX_MeshProxy();
+
+ // stuff for cvalue related things
+ 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); // Set the name of the value
+ virtual void ReplicaSetName(STR_String name);
+ virtual CValue* GetReplica();
+
+// stuff for python integration
+ virtual PyObject* _getattr(char *attr);
+ KX_PYMETHOD(KX_MeshProxy,GetNumMaterials);
+ KX_PYMETHOD(KX_MeshProxy,GetMaterialName);
+ KX_PYMETHOD(KX_MeshProxy,GetTextureName);
+
+ // both take materialid (int)
+ KX_PYMETHOD(KX_MeshProxy,GetVertexArrayLength);
+ KX_PYMETHOD(KX_MeshProxy,GetVertex);
+};
+#endif //__KX_MESHPROXY
diff --git a/source/gameengine/Ketsji/KX_MotionState.cpp b/source/gameengine/Ketsji/KX_MotionState.cpp
new file mode 100644
index 00000000000..50b1943e5f0
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_MotionState.cpp
@@ -0,0 +1,91 @@
+/**
+ * $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 "KX_MotionState.h"
+#include "SG_Spatial.h"
+
+KX_MotionState::KX_MotionState(SG_Spatial* node) : m_node(node)
+{
+
+}
+
+KX_MotionState::~KX_MotionState()
+{
+}
+
+void KX_MotionState::getWorldPosition(float& posX,float& posY,float& posZ)
+{
+ MT_Point3 pos = m_node->GetWorldPosition();
+ posX = pos[0];
+ posY = pos[1];
+ posZ = pos[2];
+}
+
+void KX_MotionState::getWorldScaling(float& scaleX,float& scaleY,float& scaleZ)
+{
+ MT_Vector3 scale = m_node->GetWorldScaling();
+ scaleX = scale[0];
+ scaleY = scale[1];
+ scaleZ = scale[2];
+}
+
+void KX_MotionState::getWorldOrientation(float& quatIma0,float& quatIma1,float& quatIma2,float& quatReal)
+{
+ MT_Quaternion orn = m_node->GetWorldOrientation().getRotation();
+ quatIma0 = orn[0];
+ quatIma1 = orn[1];
+ quatIma2 = orn[2];
+ quatReal = orn[3];
+}
+
+void KX_MotionState::setWorldPosition(float posX,float posY,float posZ)
+{
+ m_node->SetLocalPosition(MT_Point3(posX,posY,posZ));
+
+}
+
+void KX_MotionState::setWorldOrientation(float quatIma0,float quatIma1,float quatIma2,float quatReal)
+{
+ MT_Quaternion orn;
+ orn[0] = quatIma0;
+ orn[1] = quatIma1;
+ orn[2] = quatIma2;
+ orn[3] = quatReal;
+
+ m_node->SetLocalOrientation(orn);
+}
+
+void KX_MotionState::calculateWorldTransformations()
+{
+ m_node->ComputeWorldTransforms(NULL);
+}
+
+
diff --git a/source/gameengine/Ketsji/KX_MotionState.h b/source/gameengine/Ketsji/KX_MotionState.h
new file mode 100644
index 00000000000..3d0f9bd40be
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_MotionState.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_MOTIONSTATE
+#define __KX_MOTIONSTATE
+
+#include "PHY_IMotionState.h"
+
+class KX_MotionState : public PHY_IMotionState
+{
+ class SG_Spatial* m_node;
+
+public:
+ KX_MotionState(class SG_Spatial* spatial);
+ virtual ~KX_MotionState();
+
+ virtual void getWorldPosition(float& posX,float& posY,float& posZ);
+ virtual void getWorldScaling(float& scaleX,float& scaleY,float& scaleZ);
+ virtual void getWorldOrientation(float& quatIma0,float& quatIma1,float& quatIma2,float& quatReal);
+ virtual void setWorldPosition(float posX,float posY,float posZ);
+ virtual void setWorldOrientation(float quatIma0,float quatIma1,float quatIma2,float quatReal);
+
+ virtual void calculateWorldTransformations();
+};
+
+#endif //__KX_MOTIONSTATE
diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
new file mode 100644
index 00000000000..006215b9fe8
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
@@ -0,0 +1,353 @@
+/**
+ * $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 *****
+ * KX_MouseFocusSensor determines mouse in/out/over events.
+ */
+
+#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 "MT_Point3.h"
+
+#include "KX_ClientObjectInfo.h"
+
+
+#include "RAS_FramingManager.h"
+#include "RAS_ICanvas.h"
+#include "RAS_IRasterizer.h"
+
+#include "SCA_IScene.h"
+
+#include "KX_Scene.h"
+#include "KX_Camera.h"
+
+#include "KX_MouseFocusSensor.h"
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+KX_MouseFocusSensor::KX_MouseFocusSensor(SCA_MouseManager* eventmgr,
+ int startx,
+ int starty,
+ short int mousemode,
+ bool focusmode,
+ RAS_ICanvas* canvas,
+ KX_Scene* kxscene,
+ SCA_IObject* gameobj,
+ PyTypeObject* T)
+ : SCA_MouseSensor(eventmgr, startx, starty, mousemode, gameobj, T),
+ m_focusmode(focusmode),
+ m_gp_canvas(canvas),
+ m_kxscene(kxscene)
+{
+ /* Or postpone? I think a sumo scene and kx scene go pretty much
+ * together, so it should be safe to do it here. */
+ m_mouse_over_in_previous_frame = false;
+ m_positive_event = false;
+}
+
+bool KX_MouseFocusSensor::Evaluate(CValue* event)
+{
+ bool result = false;
+ bool obHasFocus = false;
+
+// cout << "evaluate focus mouse sensor "<<endl;
+
+ if (m_focusmode) {
+ /* Focus behaviour required. Test mouse-on. The rest is
+ * equivalent to handling a key. */
+ obHasFocus = ParentObjectHasFocus();
+
+ if (!obHasFocus) {
+ if (m_mouse_over_in_previous_frame) {
+ m_positive_event = false;
+ result = true;
+ }
+ } else {
+ if (!m_mouse_over_in_previous_frame) {
+ m_positive_event = true;
+ result = true;
+ }
+ }
+ } else {
+ /* No focus behaviour required: revert to the basic mode. This
+ * mode is never used, because the converter never makes this
+ * sensor for a mouse-key event. It is here for
+ * completeness. */
+ result = SCA_MouseSensor::Evaluate(event);
+ m_positive_event = (m_val!=0);
+ }
+
+ m_mouse_over_in_previous_frame = obHasFocus;
+
+ return result;
+}
+
+bool KX_MouseFocusSensor::ParentObjectHasFocus(void)
+{
+
+ bool res = false;
+ m_hitPosition = MT_Vector3(0,0,0);
+ m_hitNormal = MT_Vector3(1,0,0);
+ MT_Point3 resultpoint;
+ MT_Vector3 resultnormal;
+
+ /* All screen handling in the gameengine is done by GL,
+ * specifically the model/view and projection parts. The viewport
+ * part is in the creator.
+ *
+ * The theory is this:
+ * WCS - world coordinates
+ * -> wcs_camcs_trafo ->
+ * camCS - camera coordinates
+ * -> camcs_clip_trafo ->
+ * clipCS - normalised device coordinates?
+ * -> normview_win_trafo
+ * winCS - window coordinates
+ *
+ * The first two transforms are respectively the model/view and
+ * the projection matrix. These are passed to the rasterizer, and
+ * we store them in the camera for easy access.
+ *
+ * For normalised device coords (xn = x/w, yn = y/w/zw) the
+ * windows coords become (lb = left bottom)
+ *
+ * xwin = [(xn + 1.0) * width]/2 + x_lb
+ * ywin = [(yn + 1.0) * height]/2 + y_lb
+ *
+ * Inverting (blender y is flipped!):
+ *
+ * xn = 2(xwin - x_lb)/width - 1.0
+ * yn = 2(ywin - y_lb)/height - 1.0
+ * = 2(height - y_blender - y_lb)/height - 1.0
+ * = 1.0 - 2(y_blender - y_lb)/height
+ *
+ * */
+
+ /* Because we don't want to worry about resize events, camera
+ * changes and all that crap, we just determine this over and
+ * over. Stop whining. We have lots of other calculations to do
+ * here as well. These reads are not the main cost. If there is no
+ * canvas, the test is irrelevant. The 1.0 makes sure the
+ * calculations don't bomb. Maybe we should explicitly guard for
+ * division by 0.0...*/
+
+ /**
+ * Get the scenes current viewport.
+ */
+
+ const RAS_Rect & viewport = m_kxscene->GetSceneViewport();
+
+ float height = float(viewport.m_y2 - viewport.m_y1 + 1);
+ float width = float(viewport.m_x2 - viewport.m_x1 + 1);
+
+ float x_lb = float(viewport.m_x1);
+ float y_lb = float(viewport.m_y1);
+
+ KX_Camera* cam = m_kxscene->GetActiveCamera();
+ /* There's some strangeness I don't fully get here... These values
+ * _should_ be wrong! */
+
+ /* old: */
+ float nearclip = 0.0;
+ float farclip = -1.0;
+
+ /* build the from and to point in normalised device coordinates
+ * Looks like normailized device coordinates are [-1,1] in x [-1,1] in y
+ * [0,-1] in z
+ *
+ * The actual z coordinates used don't have to be exact just infront and
+ * behind of the near and far clip planes.
+ */
+
+ MT_Vector4 frompoint = MT_Vector4(
+ (2 * (m_x-x_lb) / width) - 1.0,
+ 1.0 - (2 * (m_y - y_lb) / height),
+ (nearclip + 3 * farclip) / (farclip - nearclip),
+ 1.0
+ );
+ MT_Vector4 topoint = MT_Vector4(
+ (2 * (m_x-x_lb) / width) - 1.0,
+ 1.0 - (2 * (m_y-y_lb) / height),
+ (3 * nearclip + farclip) / (farclip - nearclip),
+ 1.0
+ );
+
+ /* camera to world */
+ MT_Matrix4x4 camcs_wcs_matrix;
+ cam->GetModelviewMatrix(camcs_wcs_matrix);
+ camcs_wcs_matrix.invert();
+
+ MT_Matrix4x4 clip_camcs_matrix;
+ /* badly defined, the first time round.... I wonder why... I might
+ * want to guard against floating point errors here.*/
+ cam->GetProjectionMatrix(clip_camcs_matrix);
+ clip_camcs_matrix.invert();
+
+ /* shoot-points: clip to cam to wcs . win to clip was already done.*/
+ frompoint = clip_camcs_matrix * frompoint;
+ topoint = clip_camcs_matrix * topoint;
+ frompoint = camcs_wcs_matrix * frompoint;
+ topoint = camcs_wcs_matrix * topoint;
+
+ /* from hom wcs to 3d wcs: */
+ MT_Point3 frompoint3 = MT_Point3(frompoint[0]/frompoint[3],
+ frompoint[1]/frompoint[3],
+ frompoint[2]/frompoint[3]);
+ MT_Point3 topoint3 = MT_Point3(topoint[0]/topoint[3],
+ topoint[1]/topoint[3],
+ topoint[2]/topoint[3]);
+ m_prevTargetPoint = topoint3;
+
+ /* 2. Get the object from SuMO*/
+ /* Shoot! Beware that the first argument here is an
+ * ignore-object. We don't ignore anything... */
+ KX_GameObject* thisObj = (KX_GameObject*) GetParent();
+
+
+ //SM_Object* hitSMObj = m_sumoScene->rayTest(NULL,
+ // frompoint3,
+ // topoint3,
+ // resultpoint,
+ // resultnormal);
+
+ KX_GameObject* hitKXObj = 0;
+
+ /* all this casting makes me nervous... */
+ //SM_ClientObjectInfo* client_info
+ // = ( hitSMObj ?
+ // (SM_ClientObjectInfo*) ((SM_Object*)hitSMObj)->getClientObject() :
+ // NULL);
+ //KX_GameObject* hitKXObj = ( client_info ?
+ // (KX_GameObject*)client_info->m_clientobject :
+ // NULL);
+
+
+ /* Is this me? In the ray test, there are a lot of extra checks
+ * for aliasing artefacts from self-hits. That doesn't happen
+ * here, so a simple test suffices. Or does the camera also get
+ * self-hits? (No, and the raysensor shouldn't do it either, since
+ * self-hits are excluded by setting the correct ignore-object.)
+ * Hitspots now become valid. */
+ if (hitKXObj == thisObj)
+ {
+ m_hitPosition = resultpoint;
+ m_hitNormal = resultnormal;
+ res = true;
+ }
+
+ return res;
+}
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject KX_MouseFocusSensor::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "KX_MouseFocusSensor",
+ sizeof(KX_MouseFocusSensor),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject KX_MouseFocusSensor::Parents[] = {
+ &KX_MouseFocusSensor::Type,
+ &SCA_MouseSensor::Type,
+ &SCA_ISensor::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef KX_MouseFocusSensor::Methods[] = {
+ {"getRayTarget", (PyCFunction) KX_MouseFocusSensor::sPyGetRayTarget,
+ METH_VARARGS, GetRayTarget_doc},
+ {"getRaySource", (PyCFunction) KX_MouseFocusSensor::sPyGetRaySource,
+ METH_VARARGS, GetRaySource_doc},
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* KX_MouseFocusSensor::_getattr(char* attr) {
+ _getattr_up(SCA_MouseSensor);
+}
+
+/* getRayTarget */
+char KX_MouseFocusSensor::GetRayTarget_doc[] =
+"getRayTarget()\n"
+"\tReturns the target of the ray that seeks the focus object,\n"
+"\tin worldcoordinates.";
+PyObject* KX_MouseFocusSensor::PyGetRayTarget(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ PyObject *retVal = PyList_New(3);
+
+ PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_prevTargetPoint[0]));
+ PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_prevTargetPoint[1]));
+ PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_prevTargetPoint[2]));
+
+ return retVal;
+}
+
+/* getRayTarget */
+char KX_MouseFocusSensor::GetRaySource_doc[] =
+"getRaySource()\n"
+"\tReturns the source of the ray that seeks the focus object,\n"
+"\tin worldcoordinates.";
+PyObject* KX_MouseFocusSensor::PyGetRaySource(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ PyObject *retVal = PyList_New(3);
+
+ PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_prevSourcePoint[0]));
+ PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_prevSourcePoint[1]));
+ PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_prevSourcePoint[2]));
+
+ return retVal;
+}
+
+/* eof */
+
diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.h b/source/gameengine/Ketsji/KX_MouseFocusSensor.h
new file mode 100644
index 00000000000..590f69a81b3
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.h
@@ -0,0 +1,152 @@
+/**
+ * $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 *****
+ * KX_MouseFocusSensor determines mouse in/out/over events.
+ */
+
+#ifndef __KX_MOUSEFOCUSSENSOR
+#define __KX_MOUSEFOCUSSENSOR
+
+#include "SCA_MouseSensor.h"
+/* #include "SCA_IInputDevice.h" */
+
+/**
+ * The mouse focus sensor extends the basic SCA_MouseSensor. It has
+ * been placed in KX because it needs access to the rasterizer and
+ * SuMO.
+ *
+ * - extend the valid modes?
+ * - */
+class KX_MouseFocusSensor : public SCA_MouseSensor
+{
+
+ Py_Header;
+
+ public:
+
+ KX_MouseFocusSensor(class SCA_MouseManager* keybdmgr,
+ int startx,
+ int starty,
+ short int mousemode,
+ bool focusmode,
+ RAS_ICanvas* canvas,
+ KX_Scene* kxscene,
+ SCA_IObject* gameobj,
+ PyTypeObject* T=&Type );
+
+ virtual ~KX_MouseFocusSensor() { ; };
+ virtual CValue* GetReplica() {
+ CValue* replica = new KX_MouseFocusSensor(*this);
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+ return replica;
+ };
+ /**
+ * @attention Overrides default evaluate.
+ */
+ virtual bool Evaluate(CValue* event);
+
+ virtual bool IsPositiveTrigger() {
+ bool result = m_positive_event;
+ if (m_invert) result = !result;
+ return result;
+ };
+
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+ virtual PyObject* _getattr(char *attr);
+
+ KX_PYMETHOD_DOC(KX_MouseFocusSensor,GetRayTarget);
+ KX_PYMETHOD_DOC(KX_MouseFocusSensor,GetRaySource);
+
+ /* --------------------------------------------------------------------- */
+
+ private:
+ /**
+ * The focus mode. True for handling focus, false for not handling
+ * it. */
+ bool m_focusmode;
+
+ /**
+ * Flags whether the previous test showed a mouse-over.
+ */
+ bool m_mouse_over_in_previous_frame;
+
+ /**
+ * Flags whether the previous test evaluated positive.
+ */
+ bool m_positive_event;
+
+
+ /**
+ * Tests whether the object is in mouse focus in this frame.
+ */
+ bool ParentObjectHasFocus(void);
+
+ /**
+ * (in game world coordinates) the place where the object was hit.
+ */
+ MT_Point3 m_hitPosition;
+
+ /**
+ * (in game world coordinates) the position to which to shoot the ray.
+ */
+ MT_Point3 m_prevTargetPoint;
+
+ /**
+ * (in game world coordinates) the position from which to shoot the ray.
+ */
+ MT_Point3 m_prevSourcePoint;
+
+ /**
+ * (in game world coordinates) the face normal of the vertex where
+ * the object was hit. */
+ MT_Vector3 m_hitNormal;
+
+ /**
+ * Ref to the engine, for retrieving a reference to the current
+ * scene. */
+ class KX_KetsjiEngine* m_engine;
+
+ /**
+ * The active canvas. The size of this canvas determines a part of
+ * the start position of the picking ray. */
+ RAS_ICanvas* m_gp_canvas;
+
+ /**
+ * The KX scene that holds the camera. The camera position
+ * determines a part of the start location of the picking ray. */
+ KX_Scene* m_kxscene;
+
+};
+
+#endif //__KX_MOUSESENSOR
diff --git a/source/gameengine/Ketsji/KX_NearSensor.cpp b/source/gameengine/Ketsji/KX_NearSensor.cpp
new file mode 100644
index 00000000000..0388f7cc332
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_NearSensor.cpp
@@ -0,0 +1,262 @@
+/**
+ * Sense if other objects are near
+ *
+ * $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 "KX_NearSensor.h"
+#include "SCA_LogicManager.h"
+#include "KX_GameObject.h"
+#include "KX_TouchEventManager.h"
+#include "KX_Scene.h" // needed to create a replica
+
+
+#ifdef PHYSICS_NOT_YET
+
+KX_NearSensor::KX_NearSensor(SCA_EventManager* eventmgr,
+ KX_GameObject* gameobj,
+ double margin,
+ double resetmargin,
+ bool bFindMaterial,
+ const STR_String& touchedpropname,
+ class KX_Scene* scene,
+ PyTypeObject* T)
+ :KX_TouchSensor(eventmgr,
+ gameobj,
+ bFindMaterial,
+ touchedpropname,
+ scene,
+ T),
+ m_Margin(margin),
+ m_ResetMargin(resetmargin),
+ m_sumoScene(sumoscene)
+
+{
+ m_client_info.m_type = 4;
+ m_client_info.m_clientobject = gameobj;
+ m_client_info.m_auxilary_info = NULL;
+ sumoObj->setClientObject(&m_client_info);
+}
+
+
+
+CValue* KX_NearSensor::GetReplica()
+{
+ KX_NearSensor* replica = new KX_NearSensor(*this);
+ replica->m_colliders = new CListValue();
+ replica->m_bCollision = false;
+ replica->m_bTriggered= false;
+ replica->m_hitObject = NULL;
+ replica->m_bLastTriggered = false;
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+void KX_NearSensor::ReParent(SCA_IObject* parent)
+{
+ DT_ShapeHandle shape = DT_Sphere(0.0);
+
+ // this sumoObject is not deleted by a gameobj, so delete it ourself
+ // later (memleaks)!
+
+ SM_Object* sumoObj = new SM_Object(shape,NULL,NULL,NULL);
+ sumoObj->setMargin(m_Margin);
+
+ //sumoObj->setPosition(gameobj->NodeGetWorldPosition());
+ //sumoobj->setPosition(m_sumoObj->getPosition());
+ //sumoobj->setOrientation(m_sumoObj->getOrientation());
+ //newobj->setRigidBody(this->m_sumoObj->isRigidBody());
+
+ m_sumoObj = sumoObj;
+ m_solidHandle = m_sumoObj->getObjectHandle();
+
+ double radius = m_sumoObj->getMargin();
+ sumoObj->setMargin(m_sumoObj->getMargin());
+
+ m_client_info.m_type = 4;
+ m_client_info.m_clientobject = parent;
+ m_client_info.m_auxilary_info = NULL;
+ sumoObj->setClientObject(&m_client_info);
+
+ //m_sumoScene->add(*newobj);
+
+ if (m_sumoObj)
+ {
+ DT_SetObjectResponse(m_resptable,
+ m_sumoObj->getObjectHandle(),
+ collisionResponse,
+ DT_SIMPLE_RESPONSE,
+ this);
+ }
+
+ SCA_ISensor::ReParent(parent);
+}
+
+
+
+KX_NearSensor::~KX_NearSensor()
+{
+ // for nearsensor, the sensor is the 'owner' of sumoobj
+ // for touchsensor, it's the parent
+
+ m_sumoScene->remove(*m_sumoObj);
+
+ if (m_sumoObj)
+ delete m_sumoObj;
+}
+
+
+
+bool KX_NearSensor::Evaluate(CValue* event)
+{
+ bool result = false;
+ KX_GameObject* parent = (KX_GameObject*)GetParent();
+
+ if (m_bTriggered != m_bLastTriggered)
+ {
+ m_bLastTriggered = m_bTriggered;
+ if (m_bTriggered)
+ {
+ if (m_sumoObj)
+ {
+ m_sumoObj->setMargin(m_ResetMargin);
+ }
+ } else
+ {
+ if (m_sumoObj)
+ {
+ m_sumoObj->setMargin(m_Margin);
+ }
+
+ }
+ result = true;
+ }
+
+ return result;
+}
+
+
+
+void KX_NearSensor::HandleCollision(void* obj1,void* obj2,const DT_CollData * coll_data)
+{
+ KX_TouchEventManager* toucheventmgr = (KX_TouchEventManager*)m_eventmgr;
+ KX_GameObject* parent = (KX_GameObject*)GetParent();
+
+ // need the mapping from SM_Objects to gameobjects now
+
+ SM_ClientObjectInfo* client_info =(SM_ClientObjectInfo*) (obj1 == m_sumoObj?
+ ((SM_Object*)obj2)->getClientObject() :
+ ((SM_Object*)obj1)->getClientObject());
+
+ KX_GameObject* gameobj = ( client_info ?
+ (KX_GameObject*)client_info->m_clientobject :
+ NULL);
+
+ if (gameobj && (gameobj != parent))
+ {
+ if (!m_colliders->SearchValue(gameobj))
+ m_colliders->Add(gameobj->AddRef());
+
+ // only take valid colliders
+ if (client_info->m_type == 1)
+ {
+ if ((m_touchedpropname.Length() == 0) ||
+ (gameobj->GetProperty(m_touchedpropname)))
+ {
+ m_bTriggered = true;
+ m_hitObject = gameobj;
+ }
+ }
+ } else
+ {
+
+ }
+}
+
+
+
+// python embedding
+PyTypeObject KX_NearSensor::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "KX_NearSensor",
+ sizeof(KX_NearSensor),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+
+
+PyParentObject KX_NearSensor::Parents[] = {
+ &KX_NearSensor::Type,
+ &KX_TouchSensor::Type,
+ &SCA_ISensor::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+
+
+PyMethodDef KX_NearSensor::Methods[] = {
+ {"setProperty",
+ (PyCFunction) KX_NearSensor::sPySetProperty, METH_VARARGS, SetProperty_doc},
+ {"getProperty",
+ (PyCFunction) KX_NearSensor::sPyGetProperty, METH_VARARGS, GetProperty_doc},
+ {"getHitObject",
+ (PyCFunction) KX_NearSensor::sPyGetHitObject, METH_VARARGS, GetHitObject_doc},
+ {"getHitObjectList",
+ (PyCFunction) KX_NearSensor::sPyGetHitObjectList, METH_VARARGS, GetHitObjectList_doc},
+ {NULL,NULL} //Sentinel
+};
+
+
+PyObject*
+KX_NearSensor::_getattr(char* attr)
+{
+ _getattr_up(KX_TouchSensor);
+}
+
+#endif //PHYSICS_NOT_YET
diff --git a/source/gameengine/Ketsji/KX_NearSensor.h b/source/gameengine/Ketsji/KX_NearSensor.h
new file mode 100644
index 00000000000..c87889f1ab7
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_NearSensor.h
@@ -0,0 +1,61 @@
+/**
+ * Sense if other objects are near
+ *
+ * $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_NEARSENSOR_H
+#define KX_NEARSENSOR_H
+
+#include "KX_TouchSensor.h"
+class KX_Scene;
+
+class KX_NearSensor : public KX_TouchSensor
+{
+ Py_Header;
+ double m_Margin;
+ double m_ResetMargin;
+ KX_Scene* m_scene;
+
+public:
+ KX_NearSensor(class SCA_EventManager* eventmgr,class KX_GameObject* gameobj,double margin,double resetmargin,bool bFindMaterial,const STR_String& touchedpropname,class KM_Scene* scene,PyTypeObject* T=&Type);
+ virtual ~KX_NearSensor();
+ virtual CValue* GetReplica();
+ virtual bool Evaluate(CValue* event);
+
+ virtual void ReParent(SCA_IObject* parent);
+ //virtual void HandleCollision(void* obj1,void* obj2,
+ // const DT_CollData * coll_data);
+
+ virtual PyObject* _getattr(char *attr);
+
+};
+#endif //KX_NEARSENSOR_H
diff --git a/source/gameengine/Ketsji/KX_ObColorIpoSGController.cpp b/source/gameengine/Ketsji/KX_ObColorIpoSGController.cpp
new file mode 100644
index 00000000000..d4bb714d75d
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_ObColorIpoSGController.cpp
@@ -0,0 +1,107 @@
+/**
+ * $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 "KX_ObColorIpoSGController.h"
+
+#include "KX_ScalarInterpolator.h"
+#include "KX_GameObject.h"
+
+
+bool KX_ObColorIpoSGController::Update(double currentTime)
+{
+ if (m_modified)
+ {
+ m_rgba[0]=0;
+ m_rgba[1]=0;
+ m_rgba[2]=0;
+ m_rgba[3]=0;
+
+ T_InterpolatorList::iterator i;
+ for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) {
+ (*i)->Execute(m_ipotime);
+ }
+
+
+ SG_Spatial* ob = (SG_Spatial*)m_pObject;
+ KX_GameObject* kxgameobj= (KX_GameObject*) ob->GetSGClientObject();
+
+ kxgameobj->SetObjectColor(m_rgba);
+
+
+ m_modified=false;
+ }
+ return false;
+}
+
+
+void KX_ObColorIpoSGController::AddInterpolator(KX_IInterpolator* interp)
+{
+ this->m_interpolators.push_back(interp);
+}
+
+SG_Controller* KX_ObColorIpoSGController::GetReplica(class SG_Node* destnode)
+{
+ KX_ObColorIpoSGController* iporeplica = new KX_ObColorIpoSGController(*this);
+ // clear object that ipo acts on
+ iporeplica->ClearObject();
+
+ // dirty hack, ask Gino for a better solution in the ipo implementation
+ // hacken en zagen, in what we call datahiding, not written for replication :(
+
+ T_InterpolatorList oldlist = m_interpolators;
+ iporeplica->m_interpolators.clear();
+
+ T_InterpolatorList::iterator i;
+ for (i = oldlist.begin(); !(i == oldlist.end()); ++i) {
+ KX_ScalarInterpolator* copyipo = new KX_ScalarInterpolator(*((KX_ScalarInterpolator*)*i));
+ iporeplica->AddInterpolator(copyipo);
+
+ MT_Scalar* scaal = ((KX_ScalarInterpolator*)*i)->GetTarget();
+ int orgbase = (int)this;
+ int orgloc = (int)scaal;
+ int offset = orgloc-orgbase;
+ int newaddrbase = (int)iporeplica + offset;
+ MT_Scalar* blaptr = (MT_Scalar*) newaddrbase;
+ copyipo->SetNewTarget((MT_Scalar*)blaptr);
+ }
+
+ return iporeplica;
+}
+
+KX_ObColorIpoSGController::~KX_ObColorIpoSGController()
+{
+
+ T_InterpolatorList::iterator i;
+ for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) {
+ delete (*i);
+ }
+
+}
diff --git a/source/gameengine/Ketsji/KX_ObColorIpoSGController.h b/source/gameengine/Ketsji/KX_ObColorIpoSGController.h
new file mode 100644
index 00000000000..df4d8d3bb4f
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_ObColorIpoSGController.h
@@ -0,0 +1,77 @@
+/**
+ * $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_OBCOLORIPOSGCONTROLLER_H
+#define KX_OBCOLORIPOSGCONTROLLER_H
+
+#include "SG_Controller.h"
+#include "SG_Spatial.h"
+
+#include "KX_IInterpolator.h"
+
+
+class KX_ObColorIpoSGController : public SG_Controller
+{
+public:
+ MT_Vector4 m_rgba;
+
+
+private:
+ T_InterpolatorList m_interpolators;
+ bool m_modified;
+
+ double m_ipotime;
+public:
+ KX_ObColorIpoSGController() : m_ipotime(0.0),
+
+ m_modified(true)
+ {}
+ virtual ~KX_ObColorIpoSGController();
+ virtual SG_Controller* GetReplica(class SG_Node* destnode);
+ virtual bool Update(double time);
+ virtual void SetSimulatedTime(double time) {
+ m_ipotime = time;
+ m_modified = true;
+ }
+
+ void
+ SetOption(
+ int option,
+ int value
+ ){
+ // intentionally empty
+ };
+
+
+ void AddInterpolator(KX_IInterpolator* interp);
+};
+
+#endif // KX_OBCOLORIPOSGCONTROLLER_H
diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.cpp b/source/gameengine/Ketsji/KX_ObjectActuator.cpp
new file mode 100644
index 00000000000..97e167385dc
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_ObjectActuator.cpp
@@ -0,0 +1,400 @@
+/**
+ * Do translation/rotation actions
+ *
+ * $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 "KX_ObjectActuator.h"
+#include "KX_GameObject.h"
+#include "KX_IPhysicsController.h"
+
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+
+KX_ObjectActuator::
+KX_ObjectActuator(
+ SCA_IObject* gameobj,
+ const MT_Vector3& force,
+ const MT_Vector3& torque,
+ const MT_Vector3& dloc,
+ const MT_Vector3& drot,
+ const MT_Vector3& linV,
+ const MT_Vector3& angV,
+ const KX_LocalFlags& flag,
+ PyTypeObject* T
+) :
+ SCA_IActuator(gameobj,T),
+ m_force(force),
+ m_torque(torque),
+ m_dloc(dloc),
+ m_drot(drot),
+ m_linear_velocity(linV),
+ m_angular_velocity(angV),
+ m_active_combined_velocity (false),
+ m_bitLocalFlag (flag)
+{
+}
+
+bool KX_ObjectActuator::Update(double curtime,double deltatime)
+{
+
+ bool bNegativeEvent = IsNegativeEvent();
+ RemoveAllEvents();
+
+ KX_GameObject *parent = static_cast<KX_GameObject *>(GetParent());
+
+ if (bNegativeEvent) {
+ // If we previously set the linear velocity we now have to inform
+ // the physics controller that we no longer wish to apply it and that
+ // it should reconcile the externally set velocity with it's
+ // own velocity.
+ if (m_active_combined_velocity) {
+ //if (parent->GetSumoObject()) {
+ //parent->GetPhysicsController()->ResolveCombinedVelocities(
+ // m_linear_velocity,
+ // m_angular_velocity,
+ // (m_bitLocalFlag.LinearVelocity) != 0,
+ // (m_bitLocalFlag.AngularVelocity) != 0
+ //);
+ m_active_combined_velocity = false;
+ //}
+ return false;
+ } else {
+ return false;
+ }
+
+ } else
+ if (parent)
+ {
+ /* Probably better to use some flags, so these MT_zero tests can be */
+ /* skipped. */
+ if (!MT_fuzzyZero(m_force))
+ {
+ parent->ApplyForce(m_force,(m_bitLocalFlag.Force) != 0);
+ }
+ if (!MT_fuzzyZero(m_torque))
+ {
+ parent->ApplyTorque(m_torque,(m_bitLocalFlag.Torque) != 0);
+ }
+ if (!MT_fuzzyZero(m_dloc))
+ {
+ parent->ApplyMovement(m_dloc,(m_bitLocalFlag.DLoc) != 0);
+ }
+ if (!MT_fuzzyZero(m_drot))
+ {
+ parent->ApplyRotation(m_drot,(m_bitLocalFlag.DRot) != 0);
+ }
+ if (!MT_fuzzyZero(m_linear_velocity))
+ {
+ if (m_bitLocalFlag.AddOrSetLinV) {
+ parent->addLinearVelocity(m_linear_velocity,(m_bitLocalFlag.LinearVelocity) != 0);
+ } else {
+ m_active_combined_velocity = true;
+ parent->setLinearVelocity(m_linear_velocity,(m_bitLocalFlag.LinearVelocity) != 0);
+ }
+ }
+ if (!MT_fuzzyZero(m_angular_velocity))
+ {
+ parent->setAngularVelocity(m_angular_velocity,(m_bitLocalFlag.AngularVelocity) != 0);
+ m_active_combined_velocity = true;
+ }
+
+ }
+ return true;
+}
+
+
+
+CValue* KX_ObjectActuator::GetReplica()
+{
+ KX_ObjectActuator* replica = new KX_ObjectActuator(*this);//m_float,GetName());
+ replica->ProcessReplica();
+
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+/* some 'standard' utilities... */
+bool KX_ObjectActuator::isValid(KX_ObjectActuator::KX_OBJECT_ACT_VEC_TYPE type)
+{
+ bool res = false;
+ res = (type > KX_OBJECT_ACT_NODEF) && (type < KX_OBJECT_ACT_MAX);
+ return res;
+}
+
+
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject KX_ObjectActuator::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "KX_ObjectActuator",
+ sizeof(KX_ObjectActuator),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject KX_ObjectActuator::Parents[] = {
+ &KX_ObjectActuator::Type,
+ &SCA_IActuator::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef KX_ObjectActuator::Methods[] = {
+ {"getForce", (PyCFunction) KX_ObjectActuator::sPyGetForce, METH_VARARGS},
+ {"setForce", (PyCFunction) KX_ObjectActuator::sPySetForce, METH_VARARGS},
+ {"getTorque", (PyCFunction) KX_ObjectActuator::sPyGetTorque, METH_VARARGS},
+ {"setTorque", (PyCFunction) KX_ObjectActuator::sPySetTorque, METH_VARARGS},
+ {"getDLoc", (PyCFunction) KX_ObjectActuator::sPyGetDLoc, METH_VARARGS},
+ {"setDLoc", (PyCFunction) KX_ObjectActuator::sPySetDLoc, METH_VARARGS},
+ {"getDRot", (PyCFunction) KX_ObjectActuator::sPyGetDRot, METH_VARARGS},
+ {"setDRot", (PyCFunction) KX_ObjectActuator::sPySetDRot, METH_VARARGS},
+ {"getLinearVelocity", (PyCFunction) KX_ObjectActuator::sPyGetLinearVelocity, METH_VARARGS},
+ {"setLinearVelocity", (PyCFunction) KX_ObjectActuator::sPySetLinearVelocity, METH_VARARGS},
+ {"getAngularVelocity", (PyCFunction) KX_ObjectActuator::sPyGetAngularVelocity, METH_VARARGS},
+ {"setAngularVelocity", (PyCFunction) KX_ObjectActuator::sPySetAngularVelocity, METH_VARARGS},
+
+
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* KX_ObjectActuator::_getattr(char* attr) {
+ _getattr_up(SCA_IActuator);
+};
+
+/* 1. set ------------------------------------------------------------------ */
+/* Removed! */
+
+/* 2. getForce */
+PyObject* KX_ObjectActuator::PyGetForce(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ PyObject *retVal = PyList_New(4);
+
+ PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_force[0]));
+ PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_force[1]));
+ PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_force[2]));
+ PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.Force));
+
+ return retVal;
+}
+/* 3. setForce */
+PyObject* KX_ObjectActuator::PySetForce(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ float vecArg[3];
+ int bToggle = 0;
+ if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1],
+ &vecArg[2], &bToggle)) {
+ return NULL;
+ }
+ m_force.setValue(vecArg);
+ m_bitLocalFlag.Force = PyArgToBool(bToggle);
+ Py_Return;
+}
+
+/* 4. getTorque */
+PyObject* KX_ObjectActuator::PyGetTorque(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ PyObject *retVal = PyList_New(4);
+
+ PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_torque[0]));
+ PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_torque[1]));
+ PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_torque[2]));
+ PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.Torque));
+
+ return retVal;
+}
+/* 5. setTorque */
+PyObject* KX_ObjectActuator::PySetTorque(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ float vecArg[3];
+ int bToggle = 0;
+ if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1],
+ &vecArg[2], &bToggle)) {
+ return NULL;
+ }
+ m_torque.setValue(vecArg);
+ m_bitLocalFlag.Torque = PyArgToBool(bToggle);
+ Py_Return;
+}
+
+/* 6. getDLoc */
+PyObject* KX_ObjectActuator::PyGetDLoc(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ PyObject *retVal = PyList_New(4);
+
+ PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_dloc[0]));
+ PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_dloc[1]));
+ PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_dloc[2]));
+ PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.DLoc));
+
+ return retVal;
+}
+/* 7. setDLoc */
+PyObject* KX_ObjectActuator::PySetDLoc(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ float vecArg[3];
+ int bToggle = 0;
+ if(!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1],
+ &vecArg[2], &bToggle)) {
+ return NULL;
+ }
+ m_dloc.setValue(vecArg);
+ m_bitLocalFlag.DLoc = PyArgToBool(bToggle);
+ Py_Return;
+}
+
+/* 8. getDRot */
+PyObject* KX_ObjectActuator::PyGetDRot(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ PyObject *retVal = PyList_New(4);
+
+ PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_drot[0]));
+ PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_drot[1]));
+ PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_drot[2]));
+ PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.DRot));
+
+ return retVal;
+}
+/* 9. setDRot */
+PyObject* KX_ObjectActuator::PySetDRot(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ float vecArg[3];
+ int bToggle = 0;
+ if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1],
+ &vecArg[2], &bToggle)) {
+ return NULL;
+ }
+ m_drot.setValue(vecArg);
+ m_bitLocalFlag.DRot = PyArgToBool(bToggle);
+ Py_Return;
+}
+
+/* 10. getLinearVelocity */
+PyObject* KX_ObjectActuator::PyGetLinearVelocity(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ PyObject *retVal = PyList_New(4);
+
+ PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_linear_velocity[0]));
+ PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_linear_velocity[1]));
+ PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_linear_velocity[2]));
+ PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.LinearVelocity));
+
+ return retVal;
+}
+
+/* 11. setLinearVelocity */
+PyObject* KX_ObjectActuator::PySetLinearVelocity(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ float vecArg[3];
+ int bToggle = 0;
+ if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1],
+ &vecArg[2], &bToggle)) {
+ return NULL;
+ }
+ m_linear_velocity.setValue(vecArg);
+ m_bitLocalFlag.LinearVelocity = PyArgToBool(bToggle);
+ Py_Return;
+}
+
+
+/* 12. getAngularVelocity */
+PyObject* KX_ObjectActuator::PyGetAngularVelocity(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ PyObject *retVal = PyList_New(4);
+
+ PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_angular_velocity[0]));
+ PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_angular_velocity[1]));
+ PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_angular_velocity[2]));
+ PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.AngularVelocity));
+
+ return retVal;
+}
+/* 13. setAngularVelocity */
+PyObject* KX_ObjectActuator::PySetAngularVelocity(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ float vecArg[3];
+ int bToggle = 0;
+ if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1],
+ &vecArg[2], &bToggle)) {
+ return NULL;
+ }
+ m_angular_velocity.setValue(vecArg);
+ m_bitLocalFlag.AngularVelocity = PyArgToBool(bToggle);
+ Py_Return;
+}
+
+
+
+
+/* eof */
diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.h b/source/gameengine/Ketsji/KX_ObjectActuator.h
new file mode 100644
index 00000000000..d7d780d1f3c
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_ObjectActuator.h
@@ -0,0 +1,140 @@
+/**
+ * Do translation/rotation actions
+ *
+ * $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_OBJECTACTUATOR
+#define __KX_OBJECTACTUATOR
+
+#include "SCA_IActuator.h"
+#include "MT_Vector3.h"
+
+
+//
+// Bitfield that stores the flags for each CValue derived class
+//
+struct KX_LocalFlags {
+ KX_LocalFlags() :
+ Force(false),
+ Torque(false),
+ DRot(false),
+ DLoc(false),
+ LinearVelocity(false),
+ AngularVelocity(false),
+ AddOrSetLinV(false)
+ {
+ }
+
+ unsigned short Force : 1;
+ unsigned short Torque : 1;
+ unsigned short DRot : 1;
+ unsigned short DLoc : 1;
+ unsigned short LinearVelocity : 1;
+ unsigned short AngularVelocity : 1;
+ unsigned short AddOrSetLinV : 1;
+};
+
+class KX_ObjectActuator : public SCA_IActuator
+{
+ Py_Header;
+
+ MT_Vector3 m_force;
+ MT_Vector3 m_torque;
+ MT_Vector3 m_dloc;
+ MT_Vector3 m_drot;
+ MT_Vector3 m_linear_velocity;
+ MT_Vector3 m_angular_velocity;
+ KX_LocalFlags m_bitLocalFlag;
+
+ // A hack bool -- oh no sorry everyone
+ // This bool is used to check if we have informed
+ // the physics object that we are no longer
+ // setting linear velocity.
+
+ bool m_active_combined_velocity;
+
+public:
+ enum KX_OBJECT_ACT_VEC_TYPE {
+ KX_OBJECT_ACT_NODEF = 0,
+ KX_OBJECT_ACT_FORCE,
+ KX_OBJECT_ACT_TORQUE,
+ KX_OBJECT_ACT_DLOC,
+ KX_OBJECT_ACT_DROT,
+ KX_OBJECT_ACT_LINEAR_VELOCITY,
+ KX_OBJECT_ACT_ANGULAR_VELOCITY,
+ KX_OBJECT_ACT_MAX
+ };
+
+ /**
+ * Check whether this is a valid vector mode
+ */
+ bool isValid(KX_OBJECT_ACT_VEC_TYPE type);
+
+ KX_ObjectActuator(
+ SCA_IObject* gameobj,
+ const MT_Vector3& force,
+ const MT_Vector3& torque,
+ const MT_Vector3& dloc,
+ const MT_Vector3& drot,
+ const MT_Vector3& linV,
+ const MT_Vector3& angV,
+ const KX_LocalFlags& flag,
+ PyTypeObject* T=&Type
+ );
+
+ CValue* GetReplica();
+
+ void SetForceLoc(const double force[3]) { /*m_force=force;*/ }
+ bool Update(double curtime,double deltatime);
+
+
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(char *attr);
+
+ KX_PYMETHOD(KX_ObjectActuator,GetForce);
+ KX_PYMETHOD(KX_ObjectActuator,SetForce);
+ KX_PYMETHOD(KX_ObjectActuator,GetTorque);
+ KX_PYMETHOD(KX_ObjectActuator,SetTorque);
+ KX_PYMETHOD(KX_ObjectActuator,GetDLoc);
+ KX_PYMETHOD(KX_ObjectActuator,SetDLoc);
+ KX_PYMETHOD(KX_ObjectActuator,GetDRot);
+ KX_PYMETHOD(KX_ObjectActuator,SetDRot);
+ KX_PYMETHOD(KX_ObjectActuator,GetLinearVelocity);
+ KX_PYMETHOD(KX_ObjectActuator,SetLinearVelocity);
+ KX_PYMETHOD(KX_ObjectActuator,GetAngularVelocity);
+ KX_PYMETHOD(KX_ObjectActuator,SetAngularVelocity);
+};
+#endif //__KX_OBJECTACTUATOR
diff --git a/source/gameengine/Ketsji/KX_OrientationInterpolator.cpp b/source/gameengine/Ketsji/KX_OrientationInterpolator.cpp
new file mode 100644
index 00000000000..bead946ab37
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_OrientationInterpolator.cpp
@@ -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 *****
+ */
+
+#include "KX_OrientationInterpolator.h"
+
+
+#include "MT_Matrix3x3.h"
+#include "KX_IScalarInterpolator.h"
+
+void KX_OrientationInterpolator::Execute(float currentTime) const {
+ MT_Vector3 eul(m_ipos[0]->GetValue(currentTime),
+ m_ipos[1]->GetValue(currentTime),
+ m_ipos[2]->GetValue(currentTime));
+ MT_Scalar ci = cos(eul[0]);
+ MT_Scalar cj = cos(eul[1]);
+ MT_Scalar ch = cos(eul[2]);
+ MT_Scalar si = sin(eul[0]);
+ MT_Scalar sj = sin(eul[1]);
+ MT_Scalar sh = sin(eul[2]);
+ MT_Scalar cc = ci*ch;
+ MT_Scalar cs = ci*sh;
+ MT_Scalar sc = si*ch;
+ MT_Scalar ss = si*sh;
+
+ m_target.setValue(cj*ch, sj*sc-cs, sj*cc+ss,
+ cj*sh, sj*ss+cc, sj*cs-sc,
+ -sj, cj*si, cj*ci);
+}
diff --git a/source/gameengine/Ketsji/KX_OrientationInterpolator.h b/source/gameengine/Ketsji/KX_OrientationInterpolator.h
new file mode 100644
index 00000000000..9e65e72b125
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_OrientationInterpolator.h
@@ -0,0 +1,58 @@
+/**
+ * $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_ORIENTATIONINTERPOLATOR
+#define KX_ORIENTATIONINTERPOLATOR
+
+#include "KX_IInterpolator.h"
+
+class MT_Matrix3x3;
+class KX_IScalarInterpolator;
+
+class KX_OrientationInterpolator : public KX_IInterpolator {
+public:
+ KX_OrientationInterpolator(MT_Matrix3x3& target,
+ KX_IScalarInterpolator **ipos)
+ : m_target(target)
+ {
+ m_ipos[0] = ipos[0];
+ m_ipos[1] = ipos[1];
+ m_ipos[2] = ipos[2];
+ }
+
+ virtual void Execute(float currentTime) const;
+
+private:
+ MT_Matrix3x3& m_target;
+ KX_IScalarInterpolator *m_ipos[3];
+};
+
+#endif
diff --git a/source/gameengine/Ketsji/KX_PhysicsEngineEnums.h b/source/gameengine/Ketsji/KX_PhysicsEngineEnums.h
new file mode 100644
index 00000000000..c9dd613da00
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_PhysicsEngineEnums.h
@@ -0,0 +1,44 @@
+/**
+ * $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_PHYSICSENGINEENUMS
+#define __KX_PHYSICSENGINEENUMS
+
+enum e_PhysicsEngine
+{
+ UseNone=1,
+ UseSumo,
+ UseODE,
+ UseDynamo,
+ NoSelection
+};
+
+#endif //__KX_PHYSICSENGINEENUMS
diff --git a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp
new file mode 100644
index 00000000000..b14afbdc678
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp
@@ -0,0 +1,161 @@
+/**
+ * $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 <Python.h>
+#include "KX_PhysicsObjectWrapper.h"
+#include "PHY_IPhysicsEnvironment.h"
+#include "PHY_IPhysicsController.h"
+
+KX_PhysicsObjectWrapper::KX_PhysicsObjectWrapper(
+ PHY_IPhysicsController* ctrl,
+ PHY_IPhysicsEnvironment* physenv,PyTypeObject *T)
+: m_ctrl(ctrl),m_physenv(physenv),PyObjectPlus(T)
+{
+}
+
+KX_PhysicsObjectWrapper::~KX_PhysicsObjectWrapper()
+{
+}
+
+
+PyObject* KX_PhysicsObjectWrapper::PySetPosition(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ float x,y,z;
+ if (PyArg_ParseTuple(args,"fff",&x,&y,&z))
+ {
+ m_ctrl->setPosition(x,y,z);
+ }
+ Py_INCREF(Py_None); return Py_None;
+}
+
+
+PyObject* KX_PhysicsObjectWrapper::PySetLinearVelocity(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ float x,y,z;
+ int local;
+ if (PyArg_ParseTuple(args,"fffi",&x,&y,&z,&local))
+ {
+ m_ctrl->SetLinearVelocity(x,y,z,local != 0);
+ }
+ Py_INCREF(Py_None); return Py_None;
+}
+
+PyObject* KX_PhysicsObjectWrapper::PySetAngularVelocity(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ float x,y,z;
+ int local;
+ if (PyArg_ParseTuple(args,"fffi",&x,&y,&z,&local))
+ {
+ m_ctrl->SetAngularVelocity(x,y,z,local != 0);
+ }
+ Py_INCREF(Py_None); return Py_None;
+}
+
+PyObject* KX_PhysicsObjectWrapper::PySetActive(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ int active;
+ if (PyArg_ParseTuple(args,"i",&active))
+ {
+ m_ctrl->SetActive(active!=0);
+ }
+ Py_INCREF(Py_None); return Py_None;
+}
+
+
+
+
+//python specific stuff
+PyTypeObject KX_PhysicsObjectWrapper::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "KX_PhysicsObjectWrapper",
+ sizeof(KX_PhysicsObjectWrapper),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject KX_PhysicsObjectWrapper::Parents[] = {
+ &KX_PhysicsObjectWrapper::Type,
+ NULL
+};
+
+PyObject* KX_PhysicsObjectWrapper::_getattr(char* attr)
+{
+ _getattr_up(PyObjectPlus);
+}
+
+
+int KX_PhysicsObjectWrapper::_setattr(char* attr,PyObject* pyobj)
+{
+
+ PyTypeObject* type = pyobj->ob_type;
+ int result = 1;
+
+
+ if (type == &PyInt_Type)
+ {
+ result = 0;
+ }
+ if (type == &PyString_Type)
+ {
+ result = 0;
+ }
+ if (result)
+ result = PyObjectPlus::_setattr(attr,pyobj);
+ return result;
+};
+
+
+PyMethodDef KX_PhysicsObjectWrapper::Methods[] = {
+ {"setPosition",(PyCFunction) KX_PhysicsObjectWrapper::sPySetPosition, METH_VARARGS},
+ {"setLinearVelocity",(PyCFunction) KX_PhysicsObjectWrapper::sPySetLinearVelocity, METH_VARARGS},
+ {"setAngularVelocity",(PyCFunction) KX_PhysicsObjectWrapper::sPySetAngularVelocity, METH_VARARGS},
+ {"setActive",(PyCFunction) KX_PhysicsObjectWrapper::sPySetActive, METH_VARARGS},
+ {NULL,NULL} //Sentinel
+};
diff --git a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h
new file mode 100644
index 00000000000..de384cb5932
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h
@@ -0,0 +1,58 @@
+/**
+ * $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 PHYP_PHYSICSOBJECT_WRAPPER
+#define PHYP_PHYSICSOBJECT_WRAPPER
+
+#include "Value.h"
+#include "PHY_DynamicTypes.h"
+
+class KX_PhysicsObjectWrapper : public PyObjectPlus
+{
+ Py_Header;
+
+ PyObject* _getattr(char* attr);
+ virtual int _setattr(char *attr, PyObject *value);
+public:
+ KX_PhysicsObjectWrapper(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsEnvironment* physenv,PyTypeObject *T = &Type);
+ virtual ~KX_PhysicsObjectWrapper();
+
+ KX_PYMETHOD(KX_PhysicsObjectWrapper , SetPosition);
+ KX_PYMETHOD(KX_PhysicsObjectWrapper,SetLinearVelocity);
+ KX_PYMETHOD(KX_PhysicsObjectWrapper,SetAngularVelocity);
+ KX_PYMETHOD(KX_PhysicsObjectWrapper,SetActive);
+
+private:
+ class PHY_IPhysicsController* m_ctrl;
+ PHY_IPhysicsEnvironment* m_physenv;
+};
+
+#endif //PHYP_PHYSICSOBJECT_WRAPPER
diff --git a/source/gameengine/Ketsji/KX_PhysicsPropertiesobsolete.h b/source/gameengine/Ketsji/KX_PhysicsPropertiesobsolete.h
new file mode 100644
index 00000000000..84a9133d471
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_PhysicsPropertiesobsolete.h
@@ -0,0 +1,60 @@
+/**
+ * $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_PROPSH
+#define KX_PROPSH
+
+#include <MT_Scalar.h>
+
+// Properties of dynamic objects
+struct KX_ShapeProps {
+ MT_Scalar m_mass; // Total mass
+ MT_Scalar m_inertia; // Inertia, should be a tensor some time
+ MT_Scalar m_lin_drag; // Linear drag (air, water) 0 = concrete, 1 = vacuum
+ MT_Scalar m_ang_drag; // Angular drag
+ MT_Scalar m_friction_scaling[3]; // Scaling for anisotropic friction. Component in range [0, 1]
+ bool m_do_anisotropic; // Should I do anisotropic friction?
+ bool m_do_fh; // Should the object have a linear Fh spring?
+ bool m_do_rot_fh; // Should the object have an angular Fh spring?
+};
+
+
+// Properties of collidable objects (non-ghost objects)
+struct KX_MaterialProps {
+ MT_Scalar m_restitution; // restitution of energie after a collision 0 = inelastic, 1 = elastic
+ MT_Scalar m_friction; // Coulomb friction (= ratio between the normal en maximum friction force)
+ MT_Scalar m_fh_spring; // Spring constant (both linear and angular)
+ MT_Scalar m_fh_damping; // Damping factor (linear and angular) in range [0, 1]
+ MT_Scalar m_fh_distance; // The range above the surface where Fh is active.
+ bool m_fh_normal; // Should the object slide off slopes?
+};
+
+#endif //KX_PROPSH
diff --git a/source/gameengine/Ketsji/KX_PositionInterpolator.cpp b/source/gameengine/Ketsji/KX_PositionInterpolator.cpp
new file mode 100644
index 00000000000..96af6e3ccf3
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_PositionInterpolator.cpp
@@ -0,0 +1,42 @@
+/**
+ * $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 "KX_PositionInterpolator.h"
+
+
+#include "MT_Point3.h"
+#include "KX_IScalarInterpolator.h"
+
+void KX_PositionInterpolator::Execute(float currentTime) const {
+ m_target.setValue(m_ipos[0]->GetValue(currentTime),
+ m_ipos[1]->GetValue(currentTime),
+ m_ipos[2]->GetValue(currentTime));
+}
diff --git a/source/gameengine/Ketsji/KX_PositionInterpolator.h b/source/gameengine/Ketsji/KX_PositionInterpolator.h
new file mode 100644
index 00000000000..cdc8192528a
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_PositionInterpolator.h
@@ -0,0 +1,58 @@
+/**
+ * $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_POSITIONINTERPOLATOR
+#define KX_POSITIONINTERPOLATOR
+
+#include "KX_IInterpolator.h"
+
+class MT_Point3;
+class KX_IScalarInterpolator;
+
+class KX_PositionInterpolator : public KX_IInterpolator {
+public:
+ KX_PositionInterpolator(MT_Point3& target,
+ KX_IScalarInterpolator *ipos[]) :
+ m_target(target)
+ {
+ m_ipos[0] = ipos[0];
+ m_ipos[1] = ipos[1];
+ m_ipos[2] = ipos[2];
+ }
+
+ virtual void Execute(float currentTime) const;
+
+private:
+ MT_Point3& m_target;
+ KX_IScalarInterpolator *m_ipos[3];
+};
+
+#endif
diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
new file mode 100644
index 00000000000..67a40639a13
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
@@ -0,0 +1,193 @@
+/**
+ * $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 "KX_PyConstraintBinding.h"
+#include "PHY_IPhysicsEnvironment.h"
+#include "KX_ConstraintWrapper.h"
+#include "KX_PhysicsObjectWrapper.h"
+#include "PHY_IPhysicsController.h"
+
+
+// nasty glob variable to connect scripting language
+// if there is a better way (without global), please do so!
+static PHY_IPhysicsEnvironment* g_physics_env = NULL;
+
+static char PhysicsConstraints_module_documentation[] =
+"This is the Python API for the Physics Constraints";
+
+
+static char gPySetGravity__doc__[] = "setGravity(float x,float y,float z)";
+static char gPyCreateConstraint__doc__[] = "createConstraint(ob1,ob2,float restLength,float restitution,float damping)";
+static char gPyRemoveConstraint__doc__[] = "removeConstraint(constraint id)";
+
+static PyObject* gPySetGravity(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ float x,y,z;
+ int len = PyTuple_Size(args);
+ if ((len == 3) && PyArg_ParseTuple(args,"fff",&x,&y,&z))
+ {
+ if (g_physics_env)
+ g_physics_env->setGravity(x,y,z);
+ }
+ Py_INCREF(Py_None); return Py_None;
+}
+
+
+
+
+static PyObject* gPyCreateConstraint(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ int physicsid=0,physicsid2 = 0,constrainttype=0,extrainfo=0;
+ int len = PyTuple_Size(args);
+ int success = 1;
+ float pivotX=1,pivotY=1,pivotZ=1,axisX=0,axisY=0,axisZ=1;
+ if (len == 3)
+ {
+ success = PyArg_ParseTuple(args,"iii",&physicsid,&physicsid2,&constrainttype);
+ }
+ else
+ if (len ==6)
+ {
+ success = PyArg_ParseTuple(args,"iiifff",&physicsid,&physicsid2,&constrainttype,
+ &pivotX,&pivotY,&pivotZ);
+ }
+ else if (len == 9)
+ {
+ success = PyArg_ParseTuple(args,"iiiffffff",&physicsid,&physicsid2,&constrainttype,
+ &pivotX,&pivotY,&pivotZ,&axisX,&axisY,&axisZ);
+ }
+ else if (len==4)
+ {
+ success = PyArg_ParseTuple(args,"iiii",&physicsid,&physicsid2,&constrainttype,&extrainfo);
+ pivotX=extrainfo;
+ }
+
+ if (success)
+ {
+ if (g_physics_env)
+ {
+
+ PHY_IPhysicsController* physctrl = (PHY_IPhysicsController*) physicsid;
+ PHY_IPhysicsController* physctrl2 = (PHY_IPhysicsController*) physicsid2;
+ if (physctrl) //TODO:check for existance of this pointer!
+ {
+ int constraintid = g_physics_env->createConstraint(physctrl,physctrl2,(enum PHY_ConstraintType)constrainttype,pivotX,pivotY,pivotZ,axisX,axisY,axisZ);
+
+ KX_ConstraintWrapper* wrap = new KX_ConstraintWrapper((enum PHY_ConstraintType)constrainttype,constraintid,g_physics_env);
+
+
+ return wrap;
+ }
+
+
+ }
+ }
+
+ Py_INCREF(Py_None); return Py_None;
+}
+
+
+static PyObject* gPyRemoveConstraint(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ int constraintid;
+
+ int len = PyTuple_Size(args);
+ if (PyArg_ParseTuple(args,"i",&constraintid))
+ {
+ if (g_physics_env)
+ {
+ g_physics_env->removeConstraint(constraintid);
+ }
+ }
+ Py_INCREF(Py_None); return Py_None;
+}
+
+
+
+
+
+static struct PyMethodDef physicsconstraints_methods[] = {
+ {"setGravity",(PyCFunction) gPySetGravity,
+ METH_VARARGS, gPySetGravity__doc__},
+
+ {"createConstraint",(PyCFunction) gPyCreateConstraint,
+ METH_VARARGS, gPyCreateConstraint__doc__},
+ {"removeConstraint",(PyCFunction) gPyRemoveConstraint,
+ METH_VARARGS, gPyRemoveConstraint__doc__},
+
+ //sentinel
+ { NULL, (PyCFunction) NULL, 0, NULL }
+};
+
+
+
+PyObject* initPythonConstraintBinding()
+{
+
+ PyObject* ErrorObject;
+ PyObject* m;
+ PyObject* d;
+
+ m = Py_InitModule4("PhysicsConstraints", physicsconstraints_methods,
+ PhysicsConstraints_module_documentation,
+ (PyObject*)NULL,PYTHON_API_VERSION);
+
+ // Add some symbolic constants to the module
+ d = PyModule_GetDict(m);
+ ErrorObject = PyString_FromString("PhysicsConstraints.error");
+ PyDict_SetItemString(d, "error", ErrorObject);
+
+ // XXXX Add constants here
+
+ // Check for errors
+ if (PyErr_Occurred())
+ {
+ Py_FatalError("can't initialize module PhysicsConstraints");
+ }
+
+ return d;
+}
+
+
+void KX_RemovePythonConstraintBinding()
+{
+}
+
+void PHY_SetActiveEnvironment(class PHY_IPhysicsEnvironment* env)
+{
+ g_physics_env = env;
+}
diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.h b/source/gameengine/Ketsji/KX_PyConstraintBinding.h
new file mode 100644
index 00000000000..f584649b579
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.h
@@ -0,0 +1,43 @@
+/**
+ * $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 PHY_PYTHON_CONSTRAINTBINDING
+#define PHY_PYTHON_CONSTRAINTBINDING
+
+
+#include <Python.h>
+
+
+PyObject* initPythonConstraintBinding();
+void PHY_RemovePythonConstraintBinding();
+void PHY_SetActiveEnvironment(class PHY_IPhysicsEnvironment* env);
+
+#endif //PHY_PYTHON_CONSTRAINTBINDING
diff --git a/source/gameengine/Ketsji/KX_Python.h b/source/gameengine/Ketsji/KX_Python.h
new file mode 100644
index 00000000000..705b01aa606
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_Python.h
@@ -0,0 +1,38 @@
+/**
+ * $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_PYTHON_H
+#define KX_PYTHON_H
+
+//#define USE_DL_EXPORT
+#include "Python.h"
+
+#endif // KX_PYTHON_H
diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp
new file mode 100644
index 00000000000..7b6c3a823ca
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_PythonInit.cpp
@@ -0,0 +1,832 @@
+/**
+ * $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 *****
+ * Initialize Python thingies.
+ */
+
+#ifdef WIN32
+#pragma warning (disable : 4786)
+#endif //WIN32
+
+#include "KX_PythonInit.h"
+
+#include "SCA_IInputDevice.h"
+#include "SCA_PropertySensor.h"
+#include "SCA_RandomActuator.h"
+#include "KX_ConstraintActuator.h"
+#include "KX_IpoActuator.h"
+#include "RAS_IRasterizer.h"
+#include "RAS_ICanvas.h"
+#include "MT_Vector3.h"
+#include "MT_Point3.h"
+#include "ListValue.h"
+#include "KX_Scene.h"
+#include "SND_DeviceManager.h"
+
+
+static void setSandbox(TPythonSecurityLevel level);
+
+
+// 'local' copy of canvas ptr, for window height/width python scripts
+static RAS_ICanvas* gp_Canvas = NULL;
+static KX_Scene* gp_KetsjiScene = NULL;
+static RAS_IRasterizer* gp_Rasterizer = NULL;
+
+/* Macro for building the keyboard translation */
+//#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, PyInt_FromLong(SCA_IInputDevice::KX_##name))
+#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, PyInt_FromLong(name))
+/* For the defines for types from logic bricks, we do stuff explicitly... */
+#define KX_MACRO_addTypesToDict(dict, name, name2) PyDict_SetItemString(dict, #name, PyInt_FromLong(name2))
+
+
+// temporarily python stuff, will be put in another place later !
+#include "KX_Python.h"
+#include "SCA_PythonController.h"
+// List of methods defined in the module
+
+static PyObject* ErrorObject;
+STR_String gPyGetRandomFloat_doc="getRandomFloat returns a random floating point value in the range [0..1)";
+
+static PyObject* gPyGetRandomFloat(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ return PyFloat_FromDouble(MT_random());
+}
+
+
+
+MT_Point3 GlobalConvertPythonPylist(PyObject* pylist)
+{
+ bool error=false;
+ MT_Point3 pos;
+ if (pylist->ob_type == &CListValue::Type)
+ {
+ CListValue* listval = (CListValue*) pylist;
+ if (listval->GetCount() == 3)
+ {
+ int index;
+ for (index=0;index<3;index++)
+ {
+ pos[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<3;index++)
+ {
+ pos[index] = PyFloat_AsDouble(PyList_GetItem(pylist,index));
+ }
+ }
+ else
+ {
+ error = true;
+ }
+
+ }
+ return pos;
+}
+
+
+
+MT_Point3 GlobalConvertPythonVectorArg(PyObject* args)
+{
+ MT_Point3 pos(0,0,0);
+ PyObject* pylist;
+ PyArg_ParseTuple(args,"O",&pylist);
+
+ pos = GlobalConvertPythonPylist(pylist);
+
+ return pos;
+}
+
+
+
+static PyObject* gPySetGravity(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ MT_Vector3 vec = GlobalConvertPythonVectorArg(args);
+
+ if (gp_KetsjiScene)
+ gp_KetsjiScene->SetGravity(vec);
+
+ Py_Return;
+}
+
+
+static bool usedsp = false;
+
+// this gets a pointer to an array filled with floats
+static PyObject* gPyGetSpectrum(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ SND_IAudioDevice* audiodevice = SND_DeviceManager::Instance();
+
+ PyObject* resultlist = PyList_New(512);
+
+ if (audiodevice)
+ {
+ if (!usedsp)
+ {
+ audiodevice->StartUsingDSP();
+ usedsp = true;
+ }
+
+ float* spectrum = audiodevice->GetSpectrum();
+
+ for (int index = 0; index < 512; index++)
+ {
+ PyList_SetItem(resultlist, index, PyFloat_FromDouble(spectrum[index]));
+ }
+ }
+
+ return resultlist;
+}
+
+
+
+static void gPyStartDSP(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ SND_IAudioDevice* audiodevice = SND_DeviceManager::Instance();
+
+ if (audiodevice)
+ {
+ if (!usedsp)
+ {
+ audiodevice->StartUsingDSP();
+ usedsp = true;
+ }
+ }
+}
+
+
+
+static void gPyStopDSP(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ SND_IAudioDevice* audiodevice = SND_DeviceManager::Instance();
+
+ if (audiodevice)
+ {
+ if (usedsp)
+ {
+ audiodevice->StopUsingDSP();
+ usedsp = false;
+ }
+ }
+}
+
+
+
+static struct PyMethodDef game_methods[] = {
+ {"getCurrentController",
+ (PyCFunction) SCA_PythonController::sPyGetCurrentController,
+ METH_VARARGS, SCA_PythonController::sPyGetCurrentController__doc__},
+ {"addActiveActuator",(PyCFunction) SCA_PythonController::sPyAddActiveActuator,
+ METH_VARARGS, SCA_PythonController::sPyAddActiveActuator__doc__},
+ {"getRandomFloat",(PyCFunction) gPyGetRandomFloat,
+ METH_VARARGS,gPyGetRandomFloat_doc.Ptr()},
+ {"setGravity",(PyCFunction) gPySetGravity, METH_VARARGS,"set Gravitation"},
+ {"getSpectrum",(PyCFunction) gPyGetSpectrum, METH_VARARGS,"get audio spectrum"},
+ {"stopDSP",(PyCFunction) gPyStopDSP, METH_VARARGS,"stop using the audio dsp (for performance reasons)"},
+ {NULL, (PyCFunction) NULL, 0, NULL }
+};
+
+
+static PyObject* gPyGetWindowHeight(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ int height = (gp_Canvas ? gp_Canvas->GetHeight() : 0);
+
+ PyObject* heightval = PyInt_FromLong(height);
+ return heightval;
+}
+
+
+
+static PyObject* gPyGetWindowWidth(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+
+
+ int width = (gp_Canvas ? gp_Canvas->GetWidth() : 0);
+
+ PyObject* widthval = PyInt_FromLong(width);
+ return widthval;
+}
+
+
+
+// temporarility visibility thing, will be moved to rasterizer/renderer later
+bool gUseVisibilityTemp = false;
+
+static PyObject* gPyEnableVisibility(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ int visible;
+ if (PyArg_ParseTuple(args,"i",&visible))
+ {
+ gUseVisibilityTemp = (visible != 0);
+ }
+ else
+ {
+ Py_Return;
+ }
+ Py_Return;
+}
+
+
+
+static PyObject* gPyShowMouse(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ int visible;
+ if (PyArg_ParseTuple(args,"i",&visible))
+ {
+ if (visible)
+ {
+ if (gp_Canvas)
+ gp_Canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL);
+ } else
+ {
+ if (gp_Canvas)
+ gp_Canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE);
+ }
+ }
+
+ Py_Return;
+}
+
+
+
+static PyObject* gPySetMousePosition(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ int x,y;
+ if (PyArg_ParseTuple(args,"ii",&x,&y))
+ {
+ if (gp_Canvas)
+ gp_Canvas->SetMousePosition(x,y);
+ }
+
+ Py_Return;
+}
+
+
+
+static PyObject* gPySetBackgroundColor(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+
+ MT_Vector3 vec = GlobalConvertPythonVectorArg(args);
+
+ if (gp_Canvas)
+ {
+ gp_Rasterizer->SetBackColor(vec[0],vec[1],vec[2],0.0);
+ }
+ Py_Return;
+}
+
+
+
+static PyObject* gPySetMistColor(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+
+ MT_Vector3 vec = GlobalConvertPythonVectorArg(args);
+
+ if (gp_Rasterizer)
+ {
+ gp_Rasterizer->SetFogColor(vec[0],vec[1],vec[2]);
+ }
+ Py_Return;
+}
+
+
+
+static PyObject* gPySetMistStart(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+
+ float miststart;
+ if (PyArg_ParseTuple(args,"f",&miststart))
+ {
+ if (gp_Rasterizer)
+ {
+ gp_Rasterizer->SetFogStart(miststart);
+ }
+ }
+ Py_Return;
+}
+
+
+
+static PyObject* gPySetMistEnd(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+
+ float mistend;
+ if (PyArg_ParseTuple(args,"f",&mistend))
+ {
+ if (gp_Rasterizer)
+ {
+ gp_Rasterizer->SetFogEnd(mistend);
+ }
+ }
+ Py_Return;
+}
+
+
+
+static PyObject* gPyMakeScreenshot(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ char* filename;
+ if (PyArg_ParseTuple(args,"s",&filename))
+ {
+ if (gp_Canvas)
+ {
+ gp_Canvas->MakeScreenShot(filename);
+ }
+ }
+ Py_Return;
+}
+
+
+
+STR_String gPyGetWindowHeight__doc__="getWindowHeight doc";
+STR_String gPyGetWindowWidth__doc__="getWindowWidth doc";
+STR_String gPyEnableVisibility__doc__="enableVisibility doc";
+STR_String gPyMakeScreenshot__doc__="make Screenshot doc";
+STR_String gPyShowMouse__doc__="showMouse(bool visible)";
+STR_String gPySetMousePosition__doc__="setMousePosition(int x,int y)";
+
+static struct PyMethodDef rasterizer_methods[] = {
+ {"getWindowWidth",(PyCFunction) gPyGetWindowWidth,
+ METH_VARARGS, gPyGetWindowWidth__doc__.Ptr()},
+ {"getWindowHeight",(PyCFunction) gPyGetWindowHeight,
+ METH_VARARGS, gPyGetWindowHeight__doc__.Ptr()},
+ {"makeScreenshot",(PyCFunction)gPyMakeScreenshot,
+ METH_VARARGS, gPyMakeScreenshot__doc__.Ptr()},
+ {"enableVisibility",(PyCFunction) gPyEnableVisibility,
+ METH_VARARGS, gPyEnableVisibility__doc__.Ptr()},
+ {"showMouse",(PyCFunction) gPyShowMouse,
+ METH_VARARGS, gPyShowMouse__doc__.Ptr()},
+ {"setMousePosition",(PyCFunction) gPySetMousePosition,
+ METH_VARARGS, gPySetMousePosition__doc__.Ptr()},
+ {"setBackgroundColor",(PyCFunction)gPySetBackgroundColor,METH_VARARGS,"set Background Color (rgb)"},
+ {"setMistColor",(PyCFunction)gPySetMistColor,METH_VARARGS,"set Mist Color (rgb)"},
+ {"setMistStart",(PyCFunction)gPySetMistStart,METH_VARARGS,"set Mist Start(rgb)"},
+ {"setMistEnd",(PyCFunction)gPySetMistEnd,METH_VARARGS,"set Mist End(rgb)"},
+
+ { NULL, (PyCFunction) NULL, 0, NULL }
+};
+
+
+
+// Initialization function for the module (*must* be called initGameLogic)
+
+static char GameLogic_module_documentation[] =
+"This is the Python API for the game engine of GameLogic"
+;
+
+static char Rasterizer_module_documentation[] =
+"This is the Python API for the game engine of Rasterizer"
+;
+
+
+
+PyObject* initGameLogic(KX_Scene* scene) // quick hack to get gravity hook
+{
+ PyObject* m;
+ PyObject* d;
+
+ gp_KetsjiScene = scene;
+
+ gUseVisibilityTemp=false;
+
+ // Create the module and add the functions
+ m = Py_InitModule4("GameLogic", game_methods,
+ GameLogic_module_documentation,
+ (PyObject*)NULL,PYTHON_API_VERSION);
+
+ // Add some symbolic constants to the module
+ d = PyModule_GetDict(m);
+
+ ErrorObject = PyString_FromString("GameLogic.error");
+ PyDict_SetItemString(d, "error", ErrorObject);
+
+ // XXXX Add constants here
+ /* To use logic bricks, we need some sort of constants. Here, we associate */
+ /* constants and sumbolic names. Add them to dictionary d. */
+
+ /* 1. true and false: needed for everyone */
+ KX_MACRO_addTypesToDict(d, KX_TRUE, SCA_ILogicBrick::KX_TRUE);
+ KX_MACRO_addTypesToDict(d, KX_FALSE, SCA_ILogicBrick::KX_FALSE);
+
+ /* 2. Property sensor */
+ KX_MACRO_addTypesToDict(d, KX_PROPSENSOR_EQUAL, SCA_PropertySensor::KX_PROPSENSOR_EQUAL);
+ KX_MACRO_addTypesToDict(d, KX_PROPSENSOR_NOTEQUAL, SCA_PropertySensor::KX_PROPSENSOR_NOTEQUAL);
+ KX_MACRO_addTypesToDict(d, KX_PROPSENSOR_INTERVAL, SCA_PropertySensor::KX_PROPSENSOR_INTERVAL);
+ KX_MACRO_addTypesToDict(d, KX_PROPSENSOR_CHANGED, SCA_PropertySensor::KX_PROPSENSOR_CHANGED);
+ KX_MACRO_addTypesToDict(d, KX_PROPSENSOR_EXPRESSION, SCA_PropertySensor::KX_PROPSENSOR_EXPRESSION);
+
+ /* 3. Constraint actuator */
+ KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_LOCX, KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCX);
+ KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_LOCY, KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCY);
+ KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_LOCZ, KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCZ);
+ KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_ROTX, KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTX);
+ KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_ROTY, KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTY);
+ KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_ROTZ, KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTZ);
+
+ /* 4. Ipo actuator, simple part */
+ KX_MACRO_addTypesToDict(d, KX_IPOACT_PLAY, KX_IpoActuator::KX_ACT_IPO_PLAY);
+ KX_MACRO_addTypesToDict(d, KX_IPOACT_PINGPONG, KX_IpoActuator::KX_ACT_IPO_PINGPONG);
+ KX_MACRO_addTypesToDict(d, KX_IPOACT_FLIPPER, KX_IpoActuator::KX_ACT_IPO_FLIPPER);
+ KX_MACRO_addTypesToDict(d, KX_IPOACT_LOOPSTOP, KX_IpoActuator::KX_ACT_IPO_LOOPSTOP);
+ KX_MACRO_addTypesToDict(d, KX_IPOACT_LOOPEND, KX_IpoActuator::KX_ACT_IPO_LOOPEND);
+
+ /* 5. Random distribution types */
+ KX_MACRO_addTypesToDict(d, KX_RANDOMACT_BOOL_CONST, SCA_RandomActuator::KX_RANDOMACT_BOOL_CONST);
+ KX_MACRO_addTypesToDict(d, KX_RANDOMACT_BOOL_UNIFORM, SCA_RandomActuator::KX_RANDOMACT_BOOL_UNIFORM);
+ KX_MACRO_addTypesToDict(d, KX_RANDOMACT_BOOL_BERNOUILLI, SCA_RandomActuator::KX_RANDOMACT_BOOL_BERNOUILLI);
+ KX_MACRO_addTypesToDict(d, KX_RANDOMACT_INT_CONST, SCA_RandomActuator::KX_RANDOMACT_INT_CONST);
+ KX_MACRO_addTypesToDict(d, KX_RANDOMACT_INT_UNIFORM, SCA_RandomActuator::KX_RANDOMACT_INT_UNIFORM);
+ KX_MACRO_addTypesToDict(d, KX_RANDOMACT_INT_POISSON, SCA_RandomActuator::KX_RANDOMACT_INT_POISSON);
+ KX_MACRO_addTypesToDict(d, KX_RANDOMACT_FLOAT_CONST, SCA_RandomActuator::KX_RANDOMACT_FLOAT_CONST);
+ KX_MACRO_addTypesToDict(d, KX_RANDOMACT_FLOAT_UNIFORM, SCA_RandomActuator::KX_RANDOMACT_FLOAT_UNIFORM);
+ KX_MACRO_addTypesToDict(d, KX_RANDOMACT_FLOAT_NORMAL, SCA_RandomActuator::KX_RANDOMACT_FLOAT_NORMAL);
+ KX_MACRO_addTypesToDict(d, KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL, SCA_RandomActuator::KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL);
+
+ // Check for errors
+ if (PyErr_Occurred())
+ {
+ Py_FatalError("can't initialize module GameLogic");
+ }
+
+ return d;
+}
+
+
+
+// Python Sandbox code
+// override builtin functions import() and open()
+
+
+PyObject *KXpy_open(PyObject *self, PyObject *args)
+{
+ PyErr_SetString(PyExc_RuntimeError, "Sandbox: open() function disabled!\nGame Scripts should not use this function.");
+ return NULL;
+}
+
+
+
+PyObject *KXpy_import(PyObject *self, PyObject *args)
+{
+ char *name;
+ PyObject *globals = NULL;
+ PyObject *locals = NULL;
+ PyObject *fromlist = NULL;
+ PyObject *l, *m, *n;
+
+ if (!PyArg_ParseTuple(args, "s|OOO:m_import",
+ &name, &globals, &locals, &fromlist))
+ return NULL;
+
+ /* check for builtin modules */
+ m = PyImport_AddModule("sys");
+ l = PyObject_GetAttrString(m, "builtin_module_names");
+ n = PyString_FromString(name);
+
+ if (PySequence_Contains(l, n)) {
+ return PyImport_ImportModuleEx(name, globals, locals, fromlist);
+ }
+
+ /* quick hack for GamePython modules
+ TODO: register builtin modules properly by ExtendInittab */
+ if (!strcmp(name, "GameLogic") || !strcmp(name, "GameKeys") ||
+ !strcmp(name, "Rasterizer")) {
+ return PyImport_ImportModuleEx(name, globals, locals, fromlist);
+ }
+
+ PyErr_Format(PyExc_ImportError,
+ "Import of external Module %.20s not allowed.", name);
+ return NULL;
+
+}
+
+
+
+static PyMethodDef meth_open[] = {
+ { "open", KXpy_open, METH_VARARGS,
+ "(disabled)"}
+};
+
+
+static PyMethodDef meth_import[] = {
+ { "import", KXpy_import, METH_VARARGS,
+ "our own import"}
+};
+
+
+
+//static PyObject *g_oldopen = 0;
+//static PyObject *g_oldimport = 0;
+//static int g_security = 0;
+
+
+void setSandbox(TPythonSecurityLevel level)
+{
+ PyObject *m = PyImport_AddModule("__builtin__");
+ PyObject *d = PyModule_GetDict(m);
+ PyObject *meth = PyCFunction_New(meth_open, NULL);
+
+ switch (level) {
+ case psl_Highest:
+ //if (!g_security) {
+ //g_oldopen = PyDict_GetItemString(d, "open");
+ PyDict_SetItemString(d, "open", meth);
+ meth = PyCFunction_New(meth_import, NULL);
+ PyDict_SetItemString(d, "__import__", meth);
+ //g_security = level;
+ //}
+ break;
+ /*
+ case psl_Lowest:
+ if (g_security) {
+ PyDict_SetItemString(d, "open", g_oldopen);
+ PyDict_SetItemString(d, "__import__", g_oldimport);
+ g_security = level;
+ }
+ */
+ default:
+ break;
+ }
+}
+
+
+
+PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLevel level)
+{
+ STR_String pname = progname;
+ Py_SetProgramName(pname.Ptr());
+ Py_NoSiteFlag=1;
+ Py_FrozenFlag=1;
+ Py_Initialize();
+ setSandbox(level);
+
+ PyObject* moduleobj = PyImport_AddModule("__main__");
+ return PyModule_GetDict(moduleobj);
+}
+
+
+
+void exitGamePythonScripting()
+{
+ Py_Finalize();
+}
+
+
+
+PyObject* initRasterizer(RAS_IRasterizer* rasty,RAS_ICanvas* canvas)
+{
+ gp_Canvas = canvas;
+ gp_Rasterizer = rasty;
+
+
+ PyObject* m;
+ PyObject* d;
+
+ // Create the module and add the functions
+ m = Py_InitModule4("Rasterizer", rasterizer_methods,
+ Rasterizer_module_documentation,
+ (PyObject*)NULL,PYTHON_API_VERSION);
+
+ // Add some symbolic constants to the module
+ d = PyModule_GetDict(m);
+ ErrorObject = PyString_FromString("Rasterizer.error");
+ PyDict_SetItemString(d, "error", ErrorObject);
+
+ // XXXX Add constants here
+
+ // Check for errors
+ if (PyErr_Occurred())
+ {
+ Py_FatalError("can't initialize module Rasterizer");
+ }
+
+ return d;
+}
+
+
+
+/* ------------------------------------------------------------------------- */
+/* GameKeys: symbolic constants for key mapping */
+/* ------------------------------------------------------------------------- */
+
+static char GameKeys_module_documentation[] =
+"This modules provides defines for key-codes"
+;
+
+
+
+static struct PyMethodDef gamekeys_methods[] = {
+ { NULL, (PyCFunction) NULL, 0, NULL }
+};
+
+
+
+PyObject* initGameKeys()
+{
+ PyObject* m;
+ PyObject* d;
+
+ // Create the module and add the functions
+ m = Py_InitModule4("GameKeys", gamekeys_methods,
+ GameKeys_module_documentation,
+ (PyObject*)NULL,PYTHON_API_VERSION);
+
+ // Add some symbolic constants to the module
+ d = PyModule_GetDict(m);
+
+ // XXXX Add constants here
+
+ KX_MACRO_addTypesToDict(d, AKEY, SCA_IInputDevice::KX_AKEY);
+ KX_MACRO_addTypesToDict(d, BKEY, SCA_IInputDevice::KX_BKEY);
+ KX_MACRO_addTypesToDict(d, CKEY, SCA_IInputDevice::KX_CKEY);
+ KX_MACRO_addTypesToDict(d, DKEY, SCA_IInputDevice::KX_DKEY);
+ KX_MACRO_addTypesToDict(d, EKEY, SCA_IInputDevice::KX_EKEY);
+ KX_MACRO_addTypesToDict(d, FKEY, SCA_IInputDevice::KX_FKEY);
+ KX_MACRO_addTypesToDict(d, GKEY, SCA_IInputDevice::KX_GKEY);
+ KX_MACRO_addTypesToDict(d, HKEY, SCA_IInputDevice::KX_HKEY);
+ KX_MACRO_addTypesToDict(d, IKEY, SCA_IInputDevice::KX_IKEY);
+ KX_MACRO_addTypesToDict(d, JKEY, SCA_IInputDevice::KX_JKEY);
+ KX_MACRO_addTypesToDict(d, KKEY, SCA_IInputDevice::KX_KKEY);
+ KX_MACRO_addTypesToDict(d, LKEY, SCA_IInputDevice::KX_LKEY);
+ KX_MACRO_addTypesToDict(d, MKEY, SCA_IInputDevice::KX_MKEY);
+ KX_MACRO_addTypesToDict(d, NKEY, SCA_IInputDevice::KX_NKEY);
+ KX_MACRO_addTypesToDict(d, OKEY, SCA_IInputDevice::KX_OKEY);
+ KX_MACRO_addTypesToDict(d, PKEY, SCA_IInputDevice::KX_PKEY);
+ KX_MACRO_addTypesToDict(d, QKEY, SCA_IInputDevice::KX_QKEY);
+ KX_MACRO_addTypesToDict(d, RKEY, SCA_IInputDevice::KX_RKEY);
+ KX_MACRO_addTypesToDict(d, SKEY, SCA_IInputDevice::KX_SKEY);
+ KX_MACRO_addTypesToDict(d, TKEY, SCA_IInputDevice::KX_TKEY);
+ KX_MACRO_addTypesToDict(d, UKEY, SCA_IInputDevice::KX_UKEY);
+ KX_MACRO_addTypesToDict(d, VKEY, SCA_IInputDevice::KX_VKEY);
+ KX_MACRO_addTypesToDict(d, WKEY, SCA_IInputDevice::KX_WKEY);
+ KX_MACRO_addTypesToDict(d, XKEY, SCA_IInputDevice::KX_XKEY);
+ KX_MACRO_addTypesToDict(d, YKEY, SCA_IInputDevice::KX_YKEY);
+ KX_MACRO_addTypesToDict(d, ZKEY, SCA_IInputDevice::KX_ZKEY);
+
+ KX_MACRO_addTypesToDict(d, ZEROKEY, SCA_IInputDevice::KX_ZEROKEY);
+ KX_MACRO_addTypesToDict(d, ONEKEY, SCA_IInputDevice::KX_ONEKEY);
+ KX_MACRO_addTypesToDict(d, TWOKEY, SCA_IInputDevice::KX_TWOKEY);
+ KX_MACRO_addTypesToDict(d, THREEKEY, SCA_IInputDevice::KX_THREEKEY);
+ KX_MACRO_addTypesToDict(d, FOURKEY, SCA_IInputDevice::KX_FOURKEY);
+ KX_MACRO_addTypesToDict(d, FIVEKEY, SCA_IInputDevice::KX_FIVEKEY);
+ KX_MACRO_addTypesToDict(d, SIXKEY, SCA_IInputDevice::KX_SIXKEY);
+ KX_MACRO_addTypesToDict(d, SEVENKEY, SCA_IInputDevice::KX_SEVENKEY);
+ KX_MACRO_addTypesToDict(d, EIGHTKEY, SCA_IInputDevice::KX_EIGHTKEY);
+ KX_MACRO_addTypesToDict(d, NINEKEY, SCA_IInputDevice::KX_NINEKEY);
+
+ KX_MACRO_addTypesToDict(d, CAPSLOCKKEY, SCA_IInputDevice::KX_CAPSLOCKKEY);
+
+ KX_MACRO_addTypesToDict(d, LEFTCTRLKEY, SCA_IInputDevice::KX_LEFTCTRLKEY);
+ KX_MACRO_addTypesToDict(d, LEFTALTKEY, SCA_IInputDevice::KX_LEFTALTKEY);
+ KX_MACRO_addTypesToDict(d, RIGHTALTKEY, SCA_IInputDevice::KX_RIGHTALTKEY);
+ KX_MACRO_addTypesToDict(d, RIGHTCTRLKEY, SCA_IInputDevice::KX_RIGHTCTRLKEY);
+ KX_MACRO_addTypesToDict(d, RIGHTSHIFTKEY, SCA_IInputDevice::KX_RIGHTSHIFTKEY);
+ KX_MACRO_addTypesToDict(d, LEFTSHIFTKEY, SCA_IInputDevice::KX_LEFTSHIFTKEY);
+
+ KX_MACRO_addTypesToDict(d, ESCKEY, SCA_IInputDevice::KX_ESCKEY);
+ KX_MACRO_addTypesToDict(d, TABKEY, SCA_IInputDevice::KX_TABKEY);
+ KX_MACRO_addTypesToDict(d, RETKEY, SCA_IInputDevice::KX_RETKEY);
+ KX_MACRO_addTypesToDict(d, SPACEKEY, SCA_IInputDevice::KX_SPACEKEY);
+ KX_MACRO_addTypesToDict(d, LINEFEEDKEY, SCA_IInputDevice::KX_LINEFEEDKEY);
+ KX_MACRO_addTypesToDict(d, BACKSPACEKEY, SCA_IInputDevice::KX_BACKSPACEKEY);
+ KX_MACRO_addTypesToDict(d, DELKEY, SCA_IInputDevice::KX_DELKEY);
+ KX_MACRO_addTypesToDict(d, SEMICOLONKEY, SCA_IInputDevice::KX_SEMICOLONKEY);
+ KX_MACRO_addTypesToDict(d, PERIODKEY, SCA_IInputDevice::KX_PERIODKEY);
+ KX_MACRO_addTypesToDict(d, COMMAKEY, SCA_IInputDevice::KX_COMMAKEY);
+ KX_MACRO_addTypesToDict(d, QUOTEKEY, SCA_IInputDevice::KX_QUOTEKEY);
+ KX_MACRO_addTypesToDict(d, ACCENTGRAVEKEY, SCA_IInputDevice::KX_ACCENTGRAVEKEY);
+ KX_MACRO_addTypesToDict(d, MINUSKEY, SCA_IInputDevice::KX_MINUSKEY);
+ KX_MACRO_addTypesToDict(d, SLASHKEY, SCA_IInputDevice::KX_SLASHKEY);
+ KX_MACRO_addTypesToDict(d, BACKSLASHKEY, SCA_IInputDevice::KX_BACKSLASHKEY);
+ KX_MACRO_addTypesToDict(d, EQUALKEY, SCA_IInputDevice::KX_EQUALKEY);
+ KX_MACRO_addTypesToDict(d, LEFTBRACKETKEY, SCA_IInputDevice::KX_LEFTBRACKETKEY);
+ KX_MACRO_addTypesToDict(d, RIGHTBRACKETKEY, SCA_IInputDevice::KX_RIGHTBRACKETKEY);
+
+ KX_MACRO_addTypesToDict(d, LEFTARROWKEY, SCA_IInputDevice::KX_LEFTARROWKEY);
+ KX_MACRO_addTypesToDict(d, DOWNARROWKEY, SCA_IInputDevice::KX_DOWNARROWKEY);
+ KX_MACRO_addTypesToDict(d, RIGHTARROWKEY, SCA_IInputDevice::KX_RIGHTARROWKEY);
+ KX_MACRO_addTypesToDict(d, UPARROWKEY, SCA_IInputDevice::KX_UPARROWKEY);
+
+ KX_MACRO_addTypesToDict(d, PAD2 , SCA_IInputDevice::KX_PAD2);
+ KX_MACRO_addTypesToDict(d, PAD4 , SCA_IInputDevice::KX_PAD4);
+ KX_MACRO_addTypesToDict(d, PAD6 , SCA_IInputDevice::KX_PAD6);
+ KX_MACRO_addTypesToDict(d, PAD8 , SCA_IInputDevice::KX_PAD8);
+
+ KX_MACRO_addTypesToDict(d, PAD1 , SCA_IInputDevice::KX_PAD1);
+ KX_MACRO_addTypesToDict(d, PAD3 , SCA_IInputDevice::KX_PAD3);
+ KX_MACRO_addTypesToDict(d, PAD5 , SCA_IInputDevice::KX_PAD5);
+ KX_MACRO_addTypesToDict(d, PAD7 , SCA_IInputDevice::KX_PAD7);
+ KX_MACRO_addTypesToDict(d, PAD9 , SCA_IInputDevice::KX_PAD9);
+
+ KX_MACRO_addTypesToDict(d, PADPERIOD, SCA_IInputDevice::KX_PADPERIOD);
+ KX_MACRO_addTypesToDict(d, PADSLASHKEY, SCA_IInputDevice::KX_PADSLASHKEY);
+ KX_MACRO_addTypesToDict(d, PADASTERKEY, SCA_IInputDevice::KX_PADASTERKEY);
+
+
+ KX_MACRO_addTypesToDict(d, PAD0, SCA_IInputDevice::KX_PAD0);
+ KX_MACRO_addTypesToDict(d, PADMINUS, SCA_IInputDevice::KX_PADMINUS);
+ KX_MACRO_addTypesToDict(d, PADENTER, SCA_IInputDevice::KX_PADENTER);
+ KX_MACRO_addTypesToDict(d, PADPLUSKEY, SCA_IInputDevice::KX_PADPLUSKEY);
+
+
+ KX_MACRO_addTypesToDict(d, F1KEY , SCA_IInputDevice::KX_F1KEY);
+ KX_MACRO_addTypesToDict(d, F2KEY , SCA_IInputDevice::KX_F2KEY);
+ KX_MACRO_addTypesToDict(d, F3KEY , SCA_IInputDevice::KX_F3KEY);
+ KX_MACRO_addTypesToDict(d, F4KEY , SCA_IInputDevice::KX_F4KEY);
+ KX_MACRO_addTypesToDict(d, F5KEY , SCA_IInputDevice::KX_F5KEY);
+ KX_MACRO_addTypesToDict(d, F6KEY , SCA_IInputDevice::KX_F6KEY);
+ KX_MACRO_addTypesToDict(d, F7KEY , SCA_IInputDevice::KX_F7KEY);
+ KX_MACRO_addTypesToDict(d, F8KEY , SCA_IInputDevice::KX_F8KEY);
+ KX_MACRO_addTypesToDict(d, F9KEY , SCA_IInputDevice::KX_F9KEY);
+ KX_MACRO_addTypesToDict(d, F10KEY, SCA_IInputDevice::KX_F10KEY);
+ KX_MACRO_addTypesToDict(d, F11KEY, SCA_IInputDevice::KX_F11KEY);
+ KX_MACRO_addTypesToDict(d, F12KEY, SCA_IInputDevice::KX_F12KEY);
+
+ KX_MACRO_addTypesToDict(d, PAUSEKEY, SCA_IInputDevice::KX_PAUSEKEY);
+ KX_MACRO_addTypesToDict(d, INSERTKEY, SCA_IInputDevice::KX_INSERTKEY);
+ KX_MACRO_addTypesToDict(d, HOMEKEY , SCA_IInputDevice::KX_HOMEKEY);
+ KX_MACRO_addTypesToDict(d, PAGEUPKEY, SCA_IInputDevice::KX_PAGEUPKEY);
+ KX_MACRO_addTypesToDict(d, PAGEDOWNKEY, SCA_IInputDevice::KX_PAGEDOWNKEY);
+ KX_MACRO_addTypesToDict(d, ENDKEY, SCA_IInputDevice::KX_ENDKEY);
+
+
+ // Check for errors
+ if (PyErr_Occurred())
+ {
+ Py_FatalError("can't initialize module GameKeys");
+ }
+
+ return d;
+}
+
+void PHY_SetActiveScene(class KX_Scene* scene)
+{
+ gp_KetsjiScene = scene;
+}
diff --git a/source/gameengine/Ketsji/KX_PythonInit.h b/source/gameengine/Ketsji/KX_PythonInit.h
new file mode 100644
index 00000000000..f5de003c6a6
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_PythonInit.h
@@ -0,0 +1,55 @@
+/**
+ * $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_PYTHON_INIT
+#define __KX_PYTHON_INIT
+
+#include "KX_Python.h"
+#include "STR_String.h"
+
+typedef enum {
+ psl_Lowest = 0,
+ psl_Highest
+} TPythonSecurityLevel;
+
+extern bool gUseVisibilityTemp;
+
+
+PyObject* initGameLogic(class KX_Scene* ketsjiscene);
+PyObject* initGameKeys();
+PyObject* initRasterizer(class RAS_IRasterizer* rasty,class RAS_ICanvas* canvas);
+PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLevel level);
+void exitGamePythonScripting();
+void exitGamePythonScripting();
+void PHY_SetActiveScene(class KX_Scene* scene);
+
+
+#endif //__KX_PYTHON_INIT
diff --git a/source/gameengine/Ketsji/KX_Python_dynamic.h b/source/gameengine/Ketsji/KX_Python_dynamic.h
new file mode 100644
index 00000000000..705b01aa606
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_Python_dynamic.h
@@ -0,0 +1,38 @@
+/**
+ * $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_PYTHON_H
+#define KX_PYTHON_H
+
+//#define USE_DL_EXPORT
+#include "Python.h"
+
+#endif // KX_PYTHON_H
diff --git a/source/gameengine/Ketsji/KX_Python_static.h b/source/gameengine/Ketsji/KX_Python_static.h
new file mode 100644
index 00000000000..d147794d8fe
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_Python_static.h
@@ -0,0 +1,38 @@
+/**
+ * $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_PYTHON_H
+#define KX_PYTHON_H
+
+#define USE_DL_EXPORT
+#include "Python.h"
+
+#endif // KX_PYTHON_H
diff --git a/source/gameengine/Ketsji/KX_RadarSensor.cpp b/source/gameengine/Ketsji/KX_RadarSensor.cpp
new file mode 100644
index 00000000000..27142987f4f
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_RadarSensor.cpp
@@ -0,0 +1,220 @@
+/**
+ * $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 "KX_RadarSensor.h"
+
+#include "KX_GameObject.h"
+/**
+ * RadarSensor constructor. Creates a near-sensor derived class, with a cone collision shape.
+ */
+
+#ifdef PHYSICS_NOT_YET
+
+KX_RadarSensor::KX_RadarSensor(class SCA_EventManager* eventmgr,
+ class KX_GameObject* gameobj,
+ double coneradius,
+ double coneheight,
+ int axis,
+ double margin,
+ double resetmargin,
+ bool bFindMaterial,
+ const STR_String& touchedpropname,
+ class KX_Scene* kxscene,
+ PyTypeObject* T)
+
+ : KX_NearSensor(
+ eventmgr,
+ gameobj,
+ margin,
+ resetmargin,
+ bFindMaterial,
+ touchedpropname,
+ kxscene,
+ T),
+ m_coneheight(coneheight),
+ m_coneradius(coneradius),
+ m_axis(axis)
+{
+ m_client_info.m_type = 3;
+ m_client_info.m_clientobject = gameobj;
+ m_client_info.m_auxilary_info = NULL;
+ sumoObj->setClientObject(&m_client_info);
+}
+
+
+KX_RadarSensor::~KX_RadarSensor()
+{
+
+}
+
+/**
+ * Transforms the collision object. A cone is not correctly centered
+ * for usage. */
+void KX_RadarSensor::SynchronizeTransform()
+{
+ // Getting the parent location was commented out. Why?
+ MT_Transform trans;
+ trans.setOrigin(((KX_GameObject*)GetParent())->NodeGetWorldPosition());
+ trans.setBasis(((KX_GameObject*)GetParent())->NodeGetWorldOrientation());
+ // What is the default orientation? pointing in the -y direction?
+ // is the geometry correctly converted?
+
+ // a collision cone is oriented
+ // center the cone correctly
+ // depends on the radar 'axis'
+ switch (m_axis)
+ {
+ case 0: // X Axis
+ {
+ MT_Quaternion rotquatje(MT_Vector3(0,0,1),MT_radians(90));
+ trans.rotate(rotquatje);
+ trans.translate(MT_Vector3 (0, -m_coneheight/2.0 ,0));
+ break;
+ };
+ case 1: // Y Axis
+ {
+ MT_Quaternion rotquatje(MT_Vector3(1,0,0),MT_radians(-180));
+ trans.rotate(rotquatje);
+ trans.translate(MT_Vector3 (0, -m_coneheight/2.0 ,0));
+ break;
+ };
+ case 2: // Z Axis
+ {
+ MT_Quaternion rotquatje(MT_Vector3(1,0,0),MT_radians(-90));
+ trans.rotate(rotquatje);
+ trans.translate(MT_Vector3 (0, -m_coneheight/2.0 ,0));
+ break;
+ };
+ default:
+ {
+ }
+ }
+ m_cone_origin = trans.getOrigin();
+ m_cone_target = trans(MT_Point3(0, -m_coneheight/2.0 ,0));
+
+ m_sumoObj->setPosition(trans.getOrigin());
+ m_sumoObj->setOrientation(trans.getRotation());
+ m_sumoObj->calcXform();
+}
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject KX_RadarSensor::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "KX_RadarSensor",
+ sizeof(KX_RadarSensor),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject KX_RadarSensor::Parents[] = {
+ &KX_RadarSensor::Type,
+ &KX_NearSensor::Type,
+ &KX_TouchSensor::Type,
+ &SCA_ISensor::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef KX_RadarSensor::Methods[] = {
+ {"getConeOrigin", (PyCFunction) KX_RadarSensor::sPyGetConeOrigin,
+ METH_VARARGS, GetConeOrigin_doc},
+ {"getConeTarget", (PyCFunction) KX_RadarSensor::sPyGetConeTarget,
+ METH_VARARGS, GetConeTarget_doc},
+ {"getConeHeight", (PyCFunction) KX_RadarSensor::sPyGetConeHeight,
+ METH_VARARGS, GetConeHeight_doc},
+ {NULL,NULL,NULL,NULL} //Sentinel
+};
+
+PyObject* KX_RadarSensor::_getattr(char* attr) {
+ _getattr_up(KX_TouchSensor);
+}
+
+/* getConeOrigin */
+char KX_RadarSensor::GetConeOrigin_doc[] =
+"getConeOrigin()\n"
+"\tReturns the origin of the cone with which to test. The origin\n"
+"\tis in the middle of the cone.";
+PyObject* KX_RadarSensor::PyGetConeOrigin(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ PyObject *retVal = PyList_New(3);
+
+ PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_cone_origin[0]));
+ PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_cone_origin[1]));
+ PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_cone_origin[2]));
+
+ return retVal;
+}
+
+/* getConeOrigin */
+char KX_RadarSensor::GetConeTarget_doc[] =
+"getConeTarget()\n"
+"\tReturns the center of the bottom face of the cone with which to test.\n";
+PyObject* KX_RadarSensor::PyGetConeTarget(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ PyObject *retVal = PyList_New(3);
+
+ PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_cone_target[0]));
+ PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_cone_target[1]));
+ PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_cone_target[2]));
+
+ return retVal;
+}
+
+/* getConeOrigin */
+char KX_RadarSensor::GetConeHeight_doc[] =
+"getConeHeight()\n"
+"\tReturns the height of the cone with which to test.\n";
+PyObject* KX_RadarSensor::PyGetConeHeight(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ return PyFloat_FromDouble(m_coneheight);
+}
+
+
+#endif //PHYSICS_NOT_YET
diff --git a/source/gameengine/Ketsji/KX_RadarSensor.h b/source/gameengine/Ketsji/KX_RadarSensor.h
new file mode 100644
index 00000000000..3a69c6565b2
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_RadarSensor.h
@@ -0,0 +1,93 @@
+/**
+ * $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_RADAR_SENSOR_H
+#define __KX_RADAR_SENSOR_H
+
+#include "KX_NearSensor.h"
+#include "MT_Point3.h"
+
+/**
+* Radar 'cone' sensor. Very similar to a near-sensor, but instead of a sphere, a cone is used.
+*/
+class KX_RadarSensor : public KX_NearSensor
+{
+ protected:
+ Py_Header;
+
+ MT_Scalar m_coneradius;
+
+ /**
+ * Height of the cone.
+ */
+ MT_Scalar m_coneheight;
+ int m_axis;
+
+ /**
+ * The previous position of the origin of the cone.
+ */
+ MT_Point3 m_cone_origin;
+
+ /**
+ * The previous direction of the cone (origin to bottom plane).
+ */
+ MT_Point3 m_cone_target;
+
+public:
+ KX_RadarSensor(class SCA_EventManager* eventmgr,
+ class KX_GameObject* gameobj,
+ double coneradius,
+ double coneheight,
+ int axis,
+ double margin,
+ double resetmargin,
+ class SM_Object* sumoObj,
+ bool bFindMaterial,
+ const STR_String& touchedpropname,
+ class SM_Scene* sumoscene,
+ PyTypeObject* T=&Type);
+ KX_RadarSensor();
+ virtual ~KX_RadarSensor();
+ virtual void SynchronizeTransform();
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(char *attr);
+
+ KX_PYMETHOD_DOC(KX_RadarSensor,GetConeOrigin);
+ KX_PYMETHOD_DOC(KX_RadarSensor,GetConeTarget);
+ KX_PYMETHOD_DOC(KX_RadarSensor,GetConeHeight);
+
+};
+
+#endif //__KX_RADAR_SENSOR_H
diff --git a/source/gameengine/Ketsji/KX_RayEventManager.cpp b/source/gameengine/Ketsji/KX_RayEventManager.cpp
new file mode 100644
index 00000000000..d57f97efb44
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_RayEventManager.cpp
@@ -0,0 +1,55 @@
+/**
+ * Manager for ray 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 "KX_RayEventManager.h"
+#include "SCA_LogicManager.h"
+#include "SCA_ISensor.h"
+#include <vector>
+using namespace std;
+
+#include <iostream>
+#include <stdio.h>
+
+void KX_RayEventManager::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 KX_RayEventManager::RegisterSensor(SCA_ISensor* sensor)
+{
+ m_sensors.push_back(sensor);
+};
diff --git a/source/gameengine/Ketsji/KX_RayEventManager.h b/source/gameengine/Ketsji/KX_RayEventManager.h
new file mode 100644
index 00000000000..abfbf6cb0f8
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_RayEventManager.h
@@ -0,0 +1,52 @@
+/**
+ * Manager for ray 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_RAYEVENTMGR
+#define __KX_RAYEVENTMGR
+#include "SCA_EventManager.h"
+#include <vector>
+using namespace std;
+class KX_RayEventManager : public SCA_EventManager
+{
+
+ class SCA_LogicManager* m_logicmgr;
+public:
+ KX_RayEventManager(class SCA_LogicManager* logicmgr)
+ : m_logicmgr(logicmgr),
+ SCA_EventManager(RAY_EVENTMGR)
+ {}
+ virtual void NextFrame(double curtime,double deltatime);
+ virtual void RegisterSensor(SCA_ISensor* sensor);
+};
+#endif //__KX_RAYEVENTMGR
diff --git a/source/gameengine/Ketsji/KX_RaySensor.cpp b/source/gameengine/Ketsji/KX_RaySensor.cpp
new file mode 100644
index 00000000000..eac362a0b1c
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_RaySensor.cpp
@@ -0,0 +1,381 @@
+/**
+ * Cast a ray and feel for objects
+ *
+ * $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 "KX_RaySensor.h"
+#include "SCA_EventManager.h"
+#include "SCA_RandomEventManager.h"
+#include "SCA_LogicManager.h"
+#include "SCA_IObject.h"
+#include "KX_ClientObjectInfo.h"
+#include "KX_GameObject.h"
+#include "KX_Scene.h"
+
+
+KX_RaySensor::KX_RaySensor(class SCA_EventManager* eventmgr,
+ SCA_IObject* gameobj,
+ const STR_String& propname,
+ bool bFindMaterial,
+ double distance,
+ int axis,
+ KX_Scene* ketsjiScene,
+ PyTypeObject* T)
+ : SCA_ISensor(gameobj,eventmgr, T),
+ m_propertyname(propname),
+ m_bFindMaterial(bFindMaterial),
+ m_distance(distance),
+ m_axis(axis),
+ m_ketsjiScene(ketsjiScene),
+ m_rayHit(false),
+ m_bTriggered(false),
+ m_hitObject(NULL)
+
+
+{
+
+}
+
+
+
+KX_RaySensor::~KX_RaySensor()
+{
+ /* Nothing to be done here. */
+}
+
+
+
+CValue* KX_RaySensor::GetReplica()
+{
+ CValue* replica = new KX_RaySensor(*this);
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+bool KX_RaySensor::IsPositiveTrigger()
+{
+ bool result = m_rayHit;
+
+ if (m_invert)
+ result = !result;
+
+ return result;
+}
+
+
+
+bool KX_RaySensor::Evaluate(CValue* event)
+{
+ bool result = false;
+ m_rayHit = false;
+ m_hitObject = NULL;
+ m_hitPosition = MT_Vector3(0,0,0);
+ m_hitNormal = MT_Vector3(1,0,0);
+
+ KX_GameObject* obj = (KX_GameObject*)GetParent();
+ MT_Point3 frompoint = obj->NodeGetWorldPosition();
+ MT_Matrix3x3 matje = obj->NodeGetWorldOrientation();
+ MT_Matrix3x3 invmat = matje.inverse();
+
+ MT_Vector3 todir;
+ switch (m_axis)
+ {
+ case 1: // X
+ {
+ todir[0] = invmat[0][0];
+ todir[1] = invmat[0][1];
+ todir[2] = invmat[0][2];
+ break;
+ }
+ case 0: // Y
+ {
+ todir[0] = invmat[1][0];
+ todir[1] = invmat[1][1];
+ todir[2] = invmat[1][2];
+ break;
+ }
+ case 2: // Z
+ {
+ todir[0] = invmat[2][0];
+ todir[1] = invmat[2][1];
+ todir[2] = invmat[2][2];
+ break;
+ }
+ case 3: // -X
+ {
+ todir[0] = invmat[0][0] * -1;
+ todir[1] = invmat[0][1] * -1;
+ todir[2] = invmat[0][2] * -1;
+ break;
+ }
+ case 4: // -Y
+ {
+ todir[0] = invmat[1][0] * -1;
+ todir[1] = invmat[1][1] * -1;
+ todir[2] = invmat[1][2] * -1;
+ break;
+ }
+ case 5: // -Z
+ {
+ todir[0] = invmat[2][0] * -1;
+ todir[1] = invmat[2][1] * -1;
+ todir[2] = invmat[2][2] * -1;
+ break;
+ }
+ }
+ todir.normalize();
+ m_rayDirection = todir;
+
+
+
+ MT_Point3 topoint = frompoint + (m_distance) * todir;
+ MT_Point3 resultpoint;
+ MT_Vector3 resultnormal;
+ bool ready = false;
+ /*
+ do {
+
+
+
+ SM_Object* hitObj = m_sumoScene->rayTest(obj->GetSumoObject(),
+ frompoint,
+ topoint,
+ resultpoint,
+ resultnormal);
+ if (hitObj)
+ {
+ KX_ClientObjectInfo* info = (SM_ClientObjectInfo*)hitObj->getClientObject();
+ SCA_IObject* hitgameobj = (SCA_IObject*)info->m_clientobject;
+ bool bFound = false;
+
+ if (hitgameobj == obj)
+ {
+ // false hit
+ MT_Scalar marg = obj->GetSumoObject()->getMargin() ;
+ frompoint = resultpoint + marg * todir;
+ }
+ else
+ {
+ ready = true;
+ if (m_propertyname.Length() == 0)
+ {
+ bFound = true;
+ }
+ else
+ {
+ if (m_bFindMaterial)
+ {
+ if (info->m_auxilary_info)
+ {
+ bFound = (m_propertyname== ((char*)info->m_auxilary_info));
+ }
+ }
+ else
+ {
+ if (hitgameobj->GetProperty(m_propertyname) != NULL)
+ {
+ bFound = true;
+ }
+ }
+ }
+
+ if (bFound)
+ {
+ m_rayHit = true;
+ m_hitObject = hitgameobj;
+ m_hitPosition = resultpoint;
+ m_hitNormal = resultnormal;
+
+ }
+ }
+ }
+ else
+ {
+ ready = true;
+ }
+ }
+ while (!ready);
+ */
+
+
+ /* now pass this result to some controller */
+ if (m_rayHit)
+ {
+ if (!m_bTriggered)
+ {
+ // notify logicsystem that ray is now hitting
+ result = true;
+ m_bTriggered = true;
+ }
+ else
+ {
+
+ }
+ }
+ else
+ {
+ if (m_bTriggered)
+ {
+ m_bTriggered = false;
+ // notify logicsystem that ray is not hitting anymore
+ result = true;
+ }
+ }
+
+ return result;
+}
+
+
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject KX_RaySensor::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "KX_RaySensor",
+ sizeof(KX_RaySensor),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject KX_RaySensor::Parents[] = {
+ &KX_RaySensor::Type,
+ &SCA_ISensor::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef KX_RaySensor::Methods[] = {
+ {"getHitObject",(PyCFunction) KX_RaySensor::sPyGetHitObject,METH_VARARGS, GetHitObject_doc},
+ {"getHitPosition",(PyCFunction) KX_RaySensor::sPyGetHitPosition,METH_VARARGS, GetHitPosition_doc},
+ {"getHitNormal",(PyCFunction) KX_RaySensor::sPyGetHitNormal,METH_VARARGS, GetHitNormal_doc},
+ {"getRayDirection",(PyCFunction) KX_RaySensor::sPyGetRayDirection,METH_VARARGS, GetRayDirection_doc},
+ {NULL,NULL} //Sentinel
+};
+
+char KX_RaySensor::GetHitObject_doc[] =
+"getHitObject()\n"
+"\tReturns the name of the object that was hit by this ray.\n";
+PyObject* KX_RaySensor::PyGetHitObject(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ if (m_hitObject)
+ {
+ return m_hitObject->AddRef();
+ }
+ Py_Return;
+}
+
+
+char KX_RaySensor::GetHitPosition_doc[] =
+"getHitPosition()\n"
+"\tReturns the position (in worldcoordinates) where the object was hit by this ray.\n";
+PyObject* KX_RaySensor::PyGetHitPosition(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+
+ MT_Point3 pos = m_hitPosition;
+
+ PyObject* resultlist = PyList_New(3);
+ int index;
+ for (index=0;index<3;index++)
+ {
+ PyList_SetItem(resultlist,index,PyFloat_FromDouble(pos[index]));
+ }
+ return resultlist;
+
+}
+
+char KX_RaySensor::GetRayDirection_doc[] =
+"getRayDirection()\n"
+"\tReturns the direction from the ray (in worldcoordinates) .\n";
+PyObject* KX_RaySensor::PyGetRayDirection(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+
+ MT_Vector3 dir = m_rayDirection;
+
+ PyObject* resultlist = PyList_New(3);
+ int index;
+ for (index=0;index<3;index++)
+ {
+ PyList_SetItem(resultlist,index,PyFloat_FromDouble(dir[index]));
+ }
+ return resultlist;
+
+}
+
+char KX_RaySensor::GetHitNormal_doc[] =
+"getHitNormal()\n"
+"\tReturns the normal (in worldcoordinates) of the object at the location where the object was hit by this ray.\n";
+PyObject* KX_RaySensor::PyGetHitNormal(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ MT_Vector3 pos = m_hitNormal;
+
+ PyObject* resultlist = PyList_New(3);
+ int index;
+ for (index=0;index<3;index++)
+ {
+ PyList_SetItem(resultlist,index,PyFloat_FromDouble(pos[index]));
+ }
+ return resultlist;
+
+}
+
+
+
+PyObject* KX_RaySensor::_getattr(char* attr) {
+ _getattr_up(SCA_ISensor);
+}
diff --git a/source/gameengine/Ketsji/KX_RaySensor.h b/source/gameengine/Ketsji/KX_RaySensor.h
new file mode 100644
index 00000000000..7eb16bd6d5b
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_RaySensor.h
@@ -0,0 +1,79 @@
+/**
+ * Cast a ray and feel for objects
+ *
+ * $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_RAYSENSOR_H
+#define __KX_RAYSENSOR_H
+
+#include "SCA_ISensor.h"
+#include "MT_Point3.h"
+
+class KX_RaySensor : public SCA_ISensor
+{
+ Py_Header;
+ STR_String m_propertyname;
+ bool m_bFindMaterial;
+ double m_distance;
+ class KX_Scene* m_ketsjiScene;
+ bool m_bTriggered;
+ int m_axis;
+ bool m_rayHit;
+ MT_Point3 m_hitPosition;
+ SCA_IObject* m_hitObject;
+ MT_Vector3 m_hitNormal;
+ MT_Vector3 m_rayDirection;
+
+public:
+ KX_RaySensor(class SCA_EventManager* eventmgr,
+ SCA_IObject* gameobj,
+ const STR_String& propname,
+ bool fFindMaterial,
+ double distance,
+ int axis,
+ class KX_Scene* ketsjiScene,
+ PyTypeObject* T = &Type);
+ virtual ~KX_RaySensor();
+ virtual CValue* GetReplica();
+
+ virtual bool Evaluate(CValue* event);
+ virtual bool IsPositiveTrigger();
+
+ KX_PYMETHOD_DOC(KX_RaySensor,GetHitObject);
+ KX_PYMETHOD_DOC(KX_RaySensor,GetHitPosition);
+ KX_PYMETHOD_DOC(KX_RaySensor,GetHitNormal);
+ KX_PYMETHOD_DOC(KX_RaySensor,GetRayDirection);
+
+ virtual PyObject* _getattr(char *attr);
+
+};
+#endif //__KX_RAYSENSOR_H
diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
new file mode 100644
index 00000000000..4e73f4e27ca
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
@@ -0,0 +1,335 @@
+//
+// Add an object when this actuator is triggered
+//
+// $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 *****
+// Previously existed as:
+
+// \source\gameengine\GameLogic\SCA_AddObjectActuator.cpp
+
+// Please look here for revision history.
+
+
+#include "KX_SCA_AddObjectActuator.h"
+#include "SCA_IScene.h"
+#include "KX_GameObject.h"
+#include "KX_IPhysicsController.h"
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+KX_SCA_AddObjectActuator::KX_SCA_AddObjectActuator(SCA_IObject *gameobj,
+ CValue* original,
+ int time,
+ SCA_IScene* scene,
+ const MT_Vector3& linvel,
+ bool local,
+ PyTypeObject* T)
+ :
+ SCA_IActuator(gameobj, T),
+ m_OriginalObject(original),
+ m_scene(scene),
+ m_linear_velocity(linvel),
+ m_localFlag(local)
+{
+ m_lastCreatedObject = NULL;
+ m_timeProp = time;
+}
+
+
+
+KX_SCA_AddObjectActuator::~KX_SCA_AddObjectActuator()
+{
+ if (m_lastCreatedObject)
+ m_lastCreatedObject->Release();
+}
+
+
+
+bool KX_SCA_AddObjectActuator::Update(double curtime,
+ double deltatime)
+{
+ bool result = false;
+ bool bNegativeEvent = IsNegativeEvent();
+ RemoveAllEvents();
+
+ if (bNegativeEvent) return false; // do nothing on negative events
+ if (m_OriginalObject)
+ {
+ // Add an identical object, with properties inherited from the original object
+ // Now it needs to be added to the current scene.
+ SCA_IObject* replica = m_scene->AddReplicaObject(m_OriginalObject,GetParent(),m_timeProp );
+ KX_GameObject * game_obj = static_cast<KX_GameObject *>(replica);
+ game_obj->setLinearVelocity(m_linear_velocity,m_localFlag);
+
+ //if (game_obj->GetSumoObject())
+ //{
+ // If this is object is also controlled by physics.
+ // we have to inform the physics controller that
+ // we no longer take control of the object.
+ // game_obj->GetPhysicsController()->ResolveCombinedVelocities(m_linear_velocity,
+ // MT_Vector3(0,0,0),
+ // m_localFlag,
+ // false);
+ //}
+
+ // keep a copy of the last object, to allow python scripters to change it
+ if (m_lastCreatedObject)
+ m_lastCreatedObject->Release();
+
+ m_lastCreatedObject = replica;
+ m_lastCreatedObject->AddRef();
+ }
+
+ return false;
+}
+
+
+
+SCA_IObject* KX_SCA_AddObjectActuator::GetLastCreatedObject() const
+{
+ return m_lastCreatedObject;
+}
+
+
+
+CValue* KX_SCA_AddObjectActuator::GetReplica()
+{
+ KX_SCA_AddObjectActuator* replica = new KX_SCA_AddObjectActuator(*this);
+
+ if (replica == NULL)
+ return NULL;
+
+ // this will copy properties and so on...
+ replica->ProcessReplica();
+ replica->m_lastCreatedObject=NULL;
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject KX_SCA_AddObjectActuator::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "KX_SCA_AddObjectActuator",
+ sizeof(KX_SCA_AddObjectActuator),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0,
+ __repr,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject KX_SCA_AddObjectActuator::Parents[] = {
+ &SCA_IActuator::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+PyMethodDef KX_SCA_AddObjectActuator::Methods[] = {
+ {"setObject", (PyCFunction) KX_SCA_AddObjectActuator::sPySetObject, METH_VARARGS, SetObject_doc},
+ {"setTime", (PyCFunction) KX_SCA_AddObjectActuator::sPySetTime, METH_VARARGS, SetTime_doc},
+ {"getObject", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetObject, METH_VARARGS, GetObject_doc},
+ {"getTime", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetTime, METH_VARARGS, GetTime_doc},
+ {"getLinearVelocity", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetLinearVelocity, METH_VARARGS, GetLinearVelocity_doc},
+ {"setLinearVelocity", (PyCFunction) KX_SCA_AddObjectActuator::sPySetLinearVelocity, METH_VARARGS, SetLinearVelocity_doc},
+ {"getLastCreatedObject", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetLastCreatedObject, METH_VARARGS,"getLastCreatedObject() : get the object handle to the last created object\n"},
+ {NULL,NULL} //Sentinel
+};
+
+
+PyObject* KX_SCA_AddObjectActuator::_getattr(char* attr)
+{
+ _getattr_up(SCA_IActuator);
+}
+
+/* 1. setObject */
+char KX_SCA_AddObjectActuator::SetObject_doc[] =
+"setObject(name)\n"
+"\t- name: string\n"
+"\tSets the object that will be added. There has to be an object\n"
+"\tof this name. If not, this function does nothing.\n";
+
+
+
+PyObject* KX_SCA_AddObjectActuator::PySetObject(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ char* objectname;
+
+ if (!PyArg_ParseTuple(args, "s", &objectname))
+ return NULL;
+
+ CValue* gameobj = SCA_ILogicBrick::m_sCurrentLogicManager->GetGameObjectByName(STR_String(objectname));
+
+ m_OriginalObject= (CValue*)gameobj;
+
+ Py_Return;
+}
+
+
+
+/* 2. setTime */
+char KX_SCA_AddObjectActuator::SetTime_doc[] =
+"setTime(duration)\n"
+"\t- duration: integer\n"
+"\tSets the lifetime of the object that will be added, in frames. \n"
+"\tIf the duration is negative, it is set to 0.\n";
+
+
+PyObject* KX_SCA_AddObjectActuator::PySetTime(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ int deltatime;
+
+ if (!PyArg_ParseTuple(args, "i", &deltatime))
+ return NULL;
+
+ m_timeProp = deltatime;
+ if (m_timeProp < 0) m_timeProp = 0;
+
+ Py_Return;
+}
+
+
+
+/* 3. getTime */
+char KX_SCA_AddObjectActuator::GetTime_doc[] =
+"GetTime()\n"
+"\tReturns the lifetime of the object that will be added.\n";
+
+
+PyObject* KX_SCA_AddObjectActuator::PyGetTime(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ return PyInt_FromLong(m_timeProp);
+}
+
+
+/* 4. getObject */
+char KX_SCA_AddObjectActuator::GetObject_doc[] =
+"getObject()\n"
+"\tReturns the name of the object that will be added.\n";
+
+
+
+PyObject* KX_SCA_AddObjectActuator::PyGetObject(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ return PyString_FromString(m_OriginalObject->GetName());
+}
+
+
+
+/* 5. getLinearVelocity */
+char KX_SCA_AddObjectActuator::GetLinearVelocity_doc[] =
+"GetLinearVelocity()\n"
+"\tReturns the linear velocity that will be assigned to \n"
+"\tthe created object.\n";
+
+
+
+PyObject* KX_SCA_AddObjectActuator::PyGetLinearVelocity(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ PyObject *retVal = PyList_New(3);
+
+ PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_linear_velocity[0]));
+ PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_linear_velocity[1]));
+ PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_linear_velocity[2]));
+
+ return retVal;
+}
+
+
+
+/* 6. setLinearVelocity */
+char KX_SCA_AddObjectActuator::SetLinearVelocity_doc[] =
+"setLinearVelocity(vx, vy, vz)\n"
+"\t- vx: float\n"
+"\t- vy: float\n"
+"\t- vz: float\n"
+"\tAssign this velocity to the created object. \n";
+
+
+PyObject* KX_SCA_AddObjectActuator::PySetLinearVelocity(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+
+ float vecArg[3];
+ if (!PyArg_ParseTuple(args, "fff", &vecArg[0], &vecArg[1], &vecArg[2]))
+ return NULL;
+
+ m_linear_velocity.setValue(vecArg);
+ Py_Return;
+}
+
+
+
+/* 7. GetLastCreatedObject */
+char KX_SCA_AddObjectActuator::GetLastCreatedObject_doc[] =
+"getLastCreatedObject()\n"
+"\tReturn the last created object. \n";
+
+
+PyObject* KX_SCA_AddObjectActuator::PyGetLastCreatedObject(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ SCA_IObject* result = this->GetLastCreatedObject();
+ if (result)
+ {
+ result->AddRef();
+ return result;
+ }
+ // don't return NULL to python anymore, it gives trouble in the scripts
+ Py_Return;
+}
diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
new file mode 100644
index 00000000000..9810669034c
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
@@ -0,0 +1,133 @@
+//
+// Add object to the game world on action of this actuator. A copy is made
+// of a referenced object. The copy inherits some properties from the owner
+// of this actuator.
+//
+// $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 *****
+//
+// Previously existed as:
+// \source\gameengine\GameLogic\SCA_AddObjectActuator.h
+// Please look here for revision history.
+
+#ifndef __KX_SCA_AddObjectActuator
+#define __KX_SCA_AddObjectActuator
+
+/* Actuator tree */
+#include "SCA_IActuator.h"
+#include "SCA_LogicManager.h"
+
+#include "MT_Vector3.h"
+
+class SCA_IScene;
+
+class KX_SCA_AddObjectActuator : public SCA_IActuator
+{
+ Py_Header;
+
+ /// Time field: lifetime of the new object
+ int m_timeProp;
+
+ /// Original object reference (object to replicate)
+ CValue* m_OriginalObject;
+
+ /// Object will be added to the following scene
+ SCA_IScene* m_scene;
+
+ /// Linear velocity upon creation of the object.
+ MT_Vector3 m_linear_velocity;
+
+ /// Apply the velocity locally
+ bool m_localFlag;
+
+ SCA_IObject* m_lastCreatedObject;
+
+public:
+
+ /**
+ * This class also has the default constructors
+ * available. Use with care!
+ */
+
+ KX_SCA_AddObjectActuator(
+ SCA_IObject *gameobj,
+ CValue* original,
+ int time,
+ SCA_IScene* scene,
+ const MT_Vector3& linvel,
+ bool local,
+ PyTypeObject* T=&Type
+ );
+
+ ~KX_SCA_AddObjectActuator(void);
+
+ CValue*
+ GetReplica(
+ ) ;
+
+ bool
+ Update(
+ double curtime,
+ double deltatime
+ );
+
+ PyObject*
+ _getattr(
+ char *attr
+ );
+
+ SCA_IObject*
+ GetLastCreatedObject(
+ ) const ;
+
+ /* 1. setObject */
+ KX_PYMETHOD_DOC(KX_SCA_AddObjectActuator,SetObject);
+ /* 2. setTime */
+ KX_PYMETHOD_DOC(KX_SCA_AddObjectActuator,SetTime);
+ /* 3. getTime */
+ KX_PYMETHOD_DOC(KX_SCA_AddObjectActuator,GetTime);
+ /* 4. getObject */
+ KX_PYMETHOD_DOC(KX_SCA_AddObjectActuator,GetObject);
+ /* 5. getLinearVelocity */
+ KX_PYMETHOD_DOC(KX_SCA_AddObjectActuator,GetLinearVelocity);
+ /* 6. setLinearVelocity */
+ KX_PYMETHOD_DOC(KX_SCA_AddObjectActuator,SetLinearVelocity);
+ /* 7. getLastCreatedObject */
+ KX_PYMETHOD_DOC(KX_SCA_AddObjectActuator,GetLastCreatedObject);
+
+
+}; /* end of class KX_SCA_AddObjectActuator : public KX_EditObjectActuator */
+
+#endif
+
+
+
+
+
diff --git a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp
new file mode 100644
index 00000000000..ca1c4d04084
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp
@@ -0,0 +1,137 @@
+/**
+ * $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 *****
+ */
+
+//
+
+// Remove the actuator's parent when triggered
+//
+// Previously existed as:
+// \source\gameengine\GameLogic\SCA_EndObjectActuator.cpp
+// Please look here for revision history.
+
+#include "SCA_IActuator.h"
+#include "KX_SCA_EndObjectActuator.h"
+#include "SCA_IScene.h"
+
+KX_SCA_EndObjectActuator::KX_SCA_EndObjectActuator(SCA_IObject *gameobj,
+ SCA_IScene* scene,
+ PyTypeObject* T):
+ SCA_IActuator(gameobj, T),
+ m_scene(scene)
+{
+ // intentionally empty
+} /* End of constructor */
+
+
+
+KX_SCA_EndObjectActuator::~KX_SCA_EndObjectActuator()
+{
+ // there's nothing to be done here, really....
+} /* end of destructor */
+
+
+
+bool KX_SCA_EndObjectActuator::Update(double curtime,
+ double deltatime
+ )
+{
+ bool result = false;
+ bool bNegativeEvent = IsNegativeEvent();
+ RemoveAllEvents();
+
+ if (bNegativeEvent)
+ return false; // do nothing on negative events
+ m_scene->DelayedRemoveObject(GetParent());
+
+ return false;
+}
+
+
+
+CValue* KX_SCA_EndObjectActuator::GetReplica()
+{
+ KX_SCA_EndObjectActuator* replica =
+ new KX_SCA_EndObjectActuator(*this);
+ if (replica == NULL) return NULL;
+
+ replica->ProcessReplica();
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+ return replica;
+};
+
+
+
+/* ------------------------------------------------------------------------- */
+/* Python functions : integration hooks */
+/* ------------------------------------------------------------------------- */
+
+PyTypeObject KX_SCA_EndObjectActuator::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "KX_SCA_EndObjectActuator",
+ sizeof(KX_SCA_EndObjectActuator),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+
+PyParentObject KX_SCA_EndObjectActuator::Parents[] = {
+ &KX_SCA_EndObjectActuator::Type,
+ &SCA_IActuator::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+
+
+PyMethodDef KX_SCA_EndObjectActuator::Methods[] = {
+ {NULL,NULL} //Sentinel
+};
+
+
+PyObject* KX_SCA_EndObjectActuator::_getattr(char* attr)
+{
+ _getattr_up(SCA_IActuator);
+}
+
+/* eof */
diff --git a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h
new file mode 100644
index 00000000000..39ee911b48f
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h
@@ -0,0 +1,80 @@
+//
+// Add object to the game world on action of this actuator
+//
+// $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 *****
+//
+// Previously existed as:
+// \source\gameengine\GameLogic\SCA_EndObjectActuator.h
+// Please look here for revision history.
+
+#ifndef __KX_SCA_ENDOBJECTACTUATOR
+#define __KX_SCA_ENDOBJECTACTUATOR
+
+#include "SCA_IActuator.h"
+
+class SCA_IScene;
+
+class KX_SCA_EndObjectActuator : public SCA_IActuator
+{
+ Py_Header;
+ SCA_IScene* m_scene;
+
+ public:
+ KX_SCA_EndObjectActuator(
+ SCA_IObject* gameobj,
+ SCA_IScene* scene,
+ PyTypeObject* T=&Type
+ );
+
+ ~KX_SCA_EndObjectActuator();
+
+ CValue*
+ GetReplica(
+ );
+
+ bool
+ Update(
+ double curtime,
+ double deltatime
+ );
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ PyObject*
+ _getattr(
+ char *attr
+ );
+
+}; /* end of class KX_EditObjectActuator : public SCA_PropertyActuator */
+
+#endif
diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp
new file mode 100644
index 00000000000..731ddeff80d
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp
@@ -0,0 +1,182 @@
+//
+// Replace the mesh for this actuator's parent
+//
+// $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 *****
+
+//
+// Previously existed as:
+
+// \source\gameengine\GameLogic\SCA_ReplaceMeshActuator.cpp
+
+// Please look here for revision history.
+
+
+#include "KX_SCA_ReplaceMeshActuator.h"
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+
+ PyTypeObject
+
+KX_SCA_ReplaceMeshActuator::
+
+Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "KX_SCA_ReplaceMeshActuator",
+ sizeof(KX_SCA_ReplaceMeshActuator),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0,
+ __repr,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject KX_SCA_ReplaceMeshActuator::Parents[] = {
+ &SCA_IActuator::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+
+
+PyMethodDef KX_SCA_ReplaceMeshActuator::Methods[] = {
+ {"setMesh", (PyCFunction) KX_SCA_ReplaceMeshActuator::sPySetMesh, METH_VARARGS, SetMesh_doc},
+ {NULL,NULL} //Sentinel
+};
+
+
+
+PyObject* KX_SCA_ReplaceMeshActuator::_getattr(char* attr)
+{
+ _getattr_up(SCA_IActuator);
+}
+
+
+
+/* 1. setMesh */
+char KX_SCA_ReplaceMeshActuator::SetMesh_doc[] =
+ "setMesh(name)\n"
+ "\t- name: string\n"
+ "\tSet the mesh that will be substituted for the current one.\n";
+
+PyObject* KX_SCA_ReplaceMeshActuator::PySetMesh(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ char* meshname;
+
+ if (!PyArg_ParseTuple(args, "s", &meshname))
+ {
+ return NULL;
+ }
+
+ void* mesh = SCA_ILogicBrick::m_sCurrentLogicManager->GetMeshByName(STR_String(meshname));
+
+ if (m_mesh) {
+ m_mesh= (class RAS_MeshObject*)mesh;
+ Py_Return;
+ }
+
+ return NULL;
+}
+
+
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+KX_SCA_ReplaceMeshActuator::KX_SCA_ReplaceMeshActuator(SCA_IObject *gameobj,
+ class RAS_MeshObject *mesh,
+ SCA_IScene* scene,
+ PyTypeObject* T) :
+
+ SCA_IActuator(gameobj, T),
+ m_scene(scene),
+ m_mesh(mesh)
+{
+} /* End of constructor */
+
+
+
+KX_SCA_ReplaceMeshActuator::~KX_SCA_ReplaceMeshActuator()
+{
+ // there's nothing to be done here, really....
+} /* end of destructor */
+
+
+
+bool KX_SCA_ReplaceMeshActuator::Update(double curtime,
+ double deltatime)
+{
+ bool result = false;
+ bool bNegativeEvent = IsNegativeEvent();
+ RemoveAllEvents();
+
+ if (bNegativeEvent)
+ return false; // do nothing on negative events
+
+ if (m_mesh) m_scene->ReplaceMesh(GetParent(),m_mesh);
+
+ return false;
+}
+
+
+
+CValue* KX_SCA_ReplaceMeshActuator::GetReplica()
+{
+ KX_SCA_ReplaceMeshActuator* replica =
+ new KX_SCA_ReplaceMeshActuator(*this);
+
+ if (replica == NULL)
+ return NULL;
+
+ replica->ProcessReplica();
+
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+};
+
+/* eof */
diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h
new file mode 100644
index 00000000000..ada21d06847
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h
@@ -0,0 +1,88 @@
+//
+// Add object to the game world on action of this actuator
+//
+// $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 *****
+//
+// Previously existed as:
+// \source\gameengine\GameLogic\SCA_ReplaceMeshActuator.h
+// Please look here for revision history.
+//
+
+#ifndef __KX_SCA_REPLACEMESHACTUATOR
+#define __KX_SCA_REPLACEMESHACTUATOR
+
+#include "SCA_IActuator.h"
+#include "SCA_PropertyActuator.h"
+#include "SCA_LogicManager.h"
+#include "SCA_IScene.h"
+
+#include "RAS_MeshObject.h"
+
+class KX_SCA_ReplaceMeshActuator : public SCA_IActuator
+{
+ Py_Header;
+
+ // mesh reference (mesh to replace)
+ RAS_MeshObject* m_mesh;
+ SCA_IScene* m_scene;
+
+ public:
+ KX_SCA_ReplaceMeshActuator(
+ SCA_IObject* gameobj,
+ RAS_MeshObject *mesh,
+ SCA_IScene* scene,
+ PyTypeObject* T=&Type
+ );
+
+ ~KX_SCA_ReplaceMeshActuator(
+ );
+
+ CValue*
+ GetReplica(
+ );
+
+ bool
+ Update(
+ double curtime,
+ double deltatime
+ );
+
+ PyObject*
+ _getattr(
+ char *attr
+ );
+
+ /* 1. setMesh */
+ KX_PYMETHOD_DOC(KX_SCA_ReplaceMeshActuator,SetMesh);
+
+};
+
+#endif
diff --git a/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp b/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp
new file mode 100644
index 00000000000..16529a91471
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp
@@ -0,0 +1,328 @@
+/**
+ * $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 "KX_SG_NodeRelationships.h"
+
+
+/**
+ * Implementation of classes defined in KX_SG_NodeRelationships.h
+ */
+
+/**
+ * first of all KX_NormalParentRelation
+ */
+
+ KX_NormalParentRelation *
+KX_NormalParentRelation::
+New(
+) {
+ return new KX_NormalParentRelation();
+}
+
+ void
+KX_NormalParentRelation::
+UpdateChildCoordinates(
+ SG_Spatial * child,
+ const SG_Spatial * parent
+){
+ assert(child != NULL);
+
+ // This way of accessing child coordinates is a bit cumbersome
+ // be nice to have non constant reference access to these values.
+
+ const MT_Vector3 & child_scale = child->GetLocalScale();
+ const MT_Point3 & child_pos = child->GetLocalPosition();
+ const MT_Matrix3x3 & child_rotation = child->GetLocalOrientation();
+
+ // the childs world locations which we will update.
+
+ MT_Vector3 child_w_scale;
+ MT_Point3 child_w_pos;
+ MT_Matrix3x3 child_w_rotation;
+
+ if (parent) {
+
+ const MT_Vector3 & p_world_scale = parent->GetWorldScaling();
+ const MT_Point3 & p_world_pos = parent->GetWorldPosition();
+ const MT_Matrix3x3 & p_world_rotation = parent->GetWorldOrientation();
+
+ child_w_scale = p_world_scale * child_scale;
+ child_w_rotation = p_world_rotation * child_rotation;
+
+ child_w_pos = p_world_pos + p_world_scale *
+ (p_world_rotation * child_pos);
+ } else {
+
+ child_w_scale = child_scale;
+ child_w_pos = child_pos;
+ child_w_rotation = child_rotation;
+ }
+
+ child->SetWorldScale(child_w_scale);
+ child->SetWorldPosition(child_w_pos);
+ child->SetWorldOrientation(child_w_rotation);
+}
+
+ SG_ParentRelation *
+KX_NormalParentRelation::
+NewCopy(
+){
+ return new KX_NormalParentRelation();
+}
+
+KX_NormalParentRelation::
+~KX_NormalParentRelation(
+){
+ //nothing to do
+}
+
+
+KX_NormalParentRelation::
+KX_NormalParentRelation(
+){
+ // nothing to do
+}
+
+/**
+ * Next KX_VertexParentRelation
+ */
+
+
+ KX_VertexParentRelation *
+KX_VertexParentRelation::
+New(
+){
+ return new KX_VertexParentRelation();
+}
+
+/**
+ * Method inherited from KX_ParentRelation
+ */
+
+ void
+KX_VertexParentRelation::
+UpdateChildCoordinates(
+ SG_Spatial * child,
+ const SG_Spatial * parent
+){
+
+ assert(child != NULL);
+
+ const MT_Vector3 & child_scale = child->GetLocalScale();
+ const MT_Point3 & child_pos = child->GetLocalPosition();
+ const MT_Matrix3x3 & child_rotation = child->GetLocalOrientation();
+
+ // the childs world locations which we will update.
+
+ MT_Vector3 child_w_scale;
+ MT_Point3 child_w_pos;
+ MT_Matrix3x3 child_w_rotation;
+
+ if (parent) {
+
+ // This is a vertex parent so we do not inherit orientation
+ // information.
+
+ const MT_Vector3 & p_world_scale = parent->GetWorldScaling();
+ const MT_Point3 & p_world_pos = parent->GetWorldPosition();
+ const MT_Matrix3x3 & p_world_rotation = parent->GetWorldOrientation();
+
+ child_w_scale = child_scale;
+ child_w_rotation = child_rotation;
+ child_w_pos = p_world_pos + child_pos;
+
+ } else {
+
+ child_w_scale = child_scale;
+ child_w_pos = child_pos;
+ child_w_rotation = child_rotation;
+ }
+
+ child->SetWorldScale(child_w_scale);
+ child->SetWorldPosition(child_w_pos);
+ child->SetWorldOrientation(child_w_rotation);
+}
+
+/**
+ * Method inherited from KX_ParentRelation
+ */
+
+ SG_ParentRelation *
+KX_VertexParentRelation::
+NewCopy(
+){
+ return new KX_VertexParentRelation();
+};
+
+KX_VertexParentRelation::
+~KX_VertexParentRelation(
+){
+ //nothing to do
+}
+
+
+KX_VertexParentRelation::
+KX_VertexParentRelation(
+){
+ //nothing to do
+}
+
+
+/**
+ * Slow parent relationship
+ */
+
+ KX_SlowParentRelation *
+KX_SlowParentRelation::
+New(
+ MT_Scalar relaxation
+){
+ return new KX_SlowParentRelation(relaxation);
+}
+
+/**
+ * Method inherited from KX_ParentRelation
+ */
+
+ void
+KX_SlowParentRelation::
+UpdateChildCoordinates(
+ SG_Spatial * child,
+ const SG_Spatial * parent
+){
+ assert(child != NULL);
+
+ const MT_Vector3 & child_scale = child->GetLocalScale();
+ const MT_Point3 & child_pos = child->GetLocalPosition();
+ const MT_Matrix3x3 & child_rotation = child->GetLocalOrientation();
+
+ // the childs world locations which we will update.
+
+ MT_Vector3 child_w_scale;
+ MT_Point3 child_w_pos;
+ MT_Matrix3x3 child_w_rotation;
+
+ if (parent) {
+
+ // This is a slow parent relation
+ // first compute the normal child world coordinates.
+
+ MT_Vector3 child_n_scale;
+ MT_Point3 child_n_pos;
+ MT_Matrix3x3 child_n_rotation;
+
+ const MT_Vector3 & p_world_scale = parent->GetWorldScaling();
+ const MT_Point3 & p_world_pos = parent->GetWorldPosition();
+ const MT_Matrix3x3 & p_world_rotation = parent->GetWorldOrientation();
+
+ child_n_scale = p_world_scale * child_scale;
+ child_n_rotation = p_world_rotation * child_rotation;
+
+ child_n_pos = p_world_pos + p_world_scale *
+ (p_world_rotation * child_pos);
+
+
+ if (m_initialized) {
+
+ // get the current world positions
+
+ child_w_scale = child->GetWorldScaling();
+ child_w_pos = child->GetWorldPosition();
+ child_w_rotation = child->GetWorldOrientation();
+
+ // now 'interpolate' the normal coordinates with the last
+ // world coordinates to get the new world coordinates.
+
+ // problem 1:
+ // The child world scale needs to be initialized in some way for this
+ // to make sense
+ // problem 2:
+ // This is way of doing interpolation is nonsense
+
+ int i;
+
+ MT_Scalar weight = MT_Scalar(1)/(m_relax + 1);
+ for (i=0;i <3 ;i++) {
+ child_w_scale[i] = (m_relax * child_w_scale[i] + child_n_scale[i]) * weight;
+ child_w_pos[i] = (m_relax * child_w_pos[i] + child_n_pos[i]) * weight;
+ child_w_rotation[0][i] = (m_relax * child_w_rotation[0][i] + child_n_rotation[0][i]) * weight;
+ child_w_rotation[1][i] = (m_relax * child_w_rotation[1][i] + child_n_rotation[1][i]) * weight;
+ child_w_rotation[2][i] = (m_relax * child_w_rotation[2][i] + child_n_rotation[2][i]) * weight;
+ }
+ } else {
+ child_w_scale = child_n_scale;
+ child_w_pos = child_n_pos;
+ child_w_rotation = child_n_rotation;
+ m_initialized = true;
+ }
+
+ } else {
+
+ child_w_scale = child_scale;
+ child_w_pos = child_pos;
+ child_w_rotation = child_rotation;
+ }
+
+ child->SetWorldScale(child_w_scale);
+ child->SetWorldPosition(child_w_pos);
+ child->SetWorldOrientation(child_w_rotation);
+}
+
+/**
+ * Method inherited from KX_ParentRelation
+ */
+
+ SG_ParentRelation *
+KX_SlowParentRelation::
+NewCopy(
+){
+ return new KX_SlowParentRelation(m_relax);
+}
+
+KX_SlowParentRelation::
+KX_SlowParentRelation(
+ MT_Scalar relaxation
+):
+ m_relax(relaxation),
+ m_initialized(false)
+{
+ //nothing to do
+}
+
+KX_SlowParentRelation::
+~KX_SlowParentRelation(
+){
+ //nothing to do
+}
+
+
+
+
diff --git a/source/gameengine/Ketsji/KX_SG_NodeRelationships.h b/source/gameengine/Ketsji/KX_SG_NodeRelationships.h
new file mode 100644
index 00000000000..c6c3dbaf315
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_SG_NodeRelationships.h
@@ -0,0 +1,214 @@
+/**
+ * @mainpage KX_SG_NodeRelationships
+
+ * @section
+ *
+ * This file provides common concrete implementations of
+ * SG_ParentRelation used by the game engine. These are
+ * KX_SlowParentRelation a slow parent relationship.
+ * KX_NormalParentRelation a normal parent relationship where
+ * orientation and position are inherited from the parent by
+ * the child.
+ * KX_VertexParentRelation only location information is
+ * inherited by the child.
+ *
+ * @see SG_ParentRelation for more information about this
+ * interface
+ *
+ * $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 "SG_Spatial.h"
+#include "SG_ParentRelation.h"
+
+
+class KX_NormalParentRelation : public SG_ParentRelation
+{
+
+public :
+
+ /**
+ * Allocate and construct a new KX_NormalParentRelation
+ * on the heap.
+ */
+
+ static
+ KX_NormalParentRelation *
+ New(
+ );
+
+ /**
+ * Method inherited from KX_ParentRelation
+ */
+
+ void
+ UpdateChildCoordinates(
+ SG_Spatial * child,
+ const SG_Spatial * parent
+ );
+
+ /**
+ * Method inherited from KX_ParentRelation
+ */
+
+ SG_ParentRelation *
+ NewCopy(
+ );
+
+ ~KX_NormalParentRelation(
+ );
+
+private :
+
+ KX_NormalParentRelation(
+ );
+
+};
+
+
+class KX_VertexParentRelation : public SG_ParentRelation
+{
+
+public :
+
+ /**
+ * Allocate and construct a new KX_VertexParentRelation
+ * on the heap.
+ */
+
+ static
+ KX_VertexParentRelation *
+ New(
+ );
+
+ /**
+ * Method inherited from KX_ParentRelation
+ */
+
+ void
+ UpdateChildCoordinates(
+ SG_Spatial * child,
+ const SG_Spatial * parent
+ );
+
+ /**
+ * Method inherited from KX_ParentRelation
+ */
+
+ SG_ParentRelation *
+ NewCopy(
+ );
+
+ ~KX_VertexParentRelation(
+ );
+
+private :
+
+ KX_VertexParentRelation(
+ );
+
+};
+
+
+class KX_SlowParentRelation : public SG_ParentRelation
+{
+
+public :
+
+ /**
+ * Allocate and construct a new KX_VertexParentRelation
+ * on the heap.
+ */
+
+ static
+ KX_SlowParentRelation *
+ New(
+ MT_Scalar relaxation
+ );
+
+ /**
+ * Method inherited from KX_ParentRelation
+ */
+
+ void
+ UpdateChildCoordinates(
+ SG_Spatial * child,
+ const SG_Spatial * parent
+ );
+
+ /**
+ * Method inherited from KX_ParentRelation
+ */
+
+ SG_ParentRelation *
+ NewCopy(
+ );
+
+ ~KX_SlowParentRelation(
+ );
+
+private :
+
+ KX_SlowParentRelation(
+ MT_Scalar relaxation
+ );
+
+ // the relaxation coefficient.
+
+ MT_Scalar m_relax;
+
+ /**
+ * Looks like a hack flag to me.
+ * We need to compute valid world coordinates the first
+ * time we update spatial data of the child. This is done
+ * by just doing a normal parent relation the first time
+ * UpdateChildCoordinates is called and then doing the
+ * slow parent relation
+ */
+
+ bool m_initialized;
+
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/source/gameengine/Ketsji/KX_ScalarInterpolator.cpp b/source/gameengine/Ketsji/KX_ScalarInterpolator.cpp
new file mode 100644
index 00000000000..e1c72c74a41
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_ScalarInterpolator.cpp
@@ -0,0 +1,38 @@
+/**
+ * $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 "KX_ScalarInterpolator.h"
+
+#include "KX_IScalarInterpolator.h"
+
+void KX_ScalarInterpolator::Execute(float currentTime) const {
+ *m_target = m_ipo->GetValue(currentTime);
+}
diff --git a/source/gameengine/Ketsji/KX_ScalarInterpolator.h b/source/gameengine/Ketsji/KX_ScalarInterpolator.h
new file mode 100644
index 00000000000..85c8900e8ab
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_ScalarInterpolator.h
@@ -0,0 +1,63 @@
+/**
+ * $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_SCALARINTERPOLATOR
+#define KX_SCALARINTERPOLATOR
+
+#include "MT_Scalar.h"
+#include "KX_IInterpolator.h"
+
+class KX_IScalarInterpolator;
+
+class KX_ScalarInterpolator : public KX_IInterpolator {
+public:
+ KX_ScalarInterpolator(MT_Scalar* target,
+ KX_IScalarInterpolator *ipo) :
+ m_target(target),
+ m_ipo(ipo)
+ {}
+
+ virtual ~KX_ScalarInterpolator() {}
+ virtual void Execute(float currentTime) const;
+ void SetNewTarget(MT_Scalar* newtarget)
+ {
+ m_target=newtarget;
+ }
+ MT_Scalar* GetTarget()
+ {
+ return m_target;
+ }
+private:
+ MT_Scalar* m_target;
+ KX_IScalarInterpolator *m_ipo;
+};
+
+#endif
diff --git a/source/gameengine/Ketsji/KX_ScalingInterpolator.cpp b/source/gameengine/Ketsji/KX_ScalingInterpolator.cpp
new file mode 100644
index 00000000000..87bd9455d74
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_ScalingInterpolator.cpp
@@ -0,0 +1,42 @@
+/**
+ * $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 "KX_ScalingInterpolator.h"
+
+
+#include "MT_Vector3.h"
+#include "KX_IScalarInterpolator.h"
+
+void KX_ScalingInterpolator::Execute(float currentTime) const {
+ m_target.setValue(m_ipos[0]->GetValue(currentTime),
+ m_ipos[1]->GetValue(currentTime),
+ m_ipos[2]->GetValue(currentTime));
+}
diff --git a/source/gameengine/Ketsji/KX_ScalingInterpolator.h b/source/gameengine/Ketsji/KX_ScalingInterpolator.h
new file mode 100644
index 00000000000..fd7e00d7b24
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_ScalingInterpolator.h
@@ -0,0 +1,61 @@
+/**
+ * $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_SCALINGINTERPOLATOR
+#define KX_SCALINGINTERPOLATOR
+
+#include "KX_IInterpolator.h"
+
+class MT_Vector3;
+class KX_IScalarInterpolator;
+
+class KX_ScalingInterpolator : public KX_IInterpolator {
+public:
+ KX_ScalingInterpolator(MT_Vector3& target,
+ KX_IScalarInterpolator *ipos[])
+ : m_target(target)
+ {
+ m_ipos[0] = ipos[0];
+ m_ipos[1] = ipos[1];
+ m_ipos[2] = ipos[2];
+ }
+
+ virtual void Execute(float currentTime) const;
+
+private:
+ MT_Vector3& m_target;
+ KX_IScalarInterpolator *m_ipos[3];
+};
+
+#endif
+
+
+
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
new file mode 100644
index 00000000000..508ada3a5a9
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -0,0 +1,977 @@
+/*
+ * $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 *****
+ * Ketsji scene. Holds references to all scene data.
+ */
+
+#ifdef WIN32
+#pragma warning (disable : 4786)
+#endif //WIN32
+
+#include "KX_KetsjiEngine.h"
+#include "RAS_IPolygonMaterial.h"
+#include "KX_Scene.h"
+#include "ListValue.h"
+#include "SCA_LogicManager.h"
+#include "SCA_TimeEventManager.h"
+#include "SCA_AlwaysEventManager.h"
+#include "SCA_RandomEventManager.h"
+#include "KX_RayEventManager.h"
+#include "KX_TouchEventManager.h"
+#include "SCA_KeyboardManager.h"
+#include "SCA_MouseManager.h"
+#include "SCA_PropertyEventManager.h"
+#include "KX_Camera.h"
+
+#include "RAS_MeshObject.h"
+#include "RAS_IRasterizer.h"
+#include "RAS_BucketManager.h"
+
+#include "FloatValue.h"
+#include "SCA_IController.h"
+#include "SCA_IActuator.h"
+#include "SG_Node.h"
+#include "SYS_System.h"
+#include "SG_Controller.h"
+#include "SG_IObject.h"
+
+#include "KX_SG_NodeRelationships.h"
+
+#include "KX_NetworkEventManager.h"
+#include "NG_NetworkScene.h"
+#include "PHY_IPhysicsEnvironment.h"
+#include "KX_IPhysicsController.h"
+
+
+void* KX_SceneReplicationFunc(SG_IObject* node,void* gameobj,void* scene)
+{
+ KX_GameObject* replica = ((KX_Scene*)scene)->AddNodeReplicaObject(node,(KX_GameObject*)gameobj);
+
+ return (void*)replica;
+}
+
+void* KX_SceneDestructionFunc(SG_IObject* node,void* gameobj,void* scene)
+{
+ ((KX_Scene*)scene)->RemoveNodeDestructObject(node,(KX_GameObject*)gameobj);
+
+ return NULL;
+};
+
+
+SG_Callbacks KX_Scene::m_callbacks = SG_Callbacks(KX_SceneReplicationFunc,KX_SceneDestructionFunc);
+
+// temporarily var until there is a button in the userinterface
+// (defined in KX_PythonInit.cpp)
+extern bool gUseVisibilityTemp;
+
+
+
+
+KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
+ class SCA_IInputDevice* mousedevice,
+ class NG_NetworkDeviceInterface *ndi,
+ class SND_IAudioDevice* adi,
+ const STR_String& sceneName):
+
+ m_mousemgr(NULL),
+ m_keyboardmgr(NULL),
+ m_active_camera(NULL),
+ m_ueberExecutionPriority(0),
+ m_adi(adi),
+ m_sceneName(sceneName),
+ m_networkDeviceInterface(ndi),
+ m_physicsEnvironment(0)
+{
+
+
+ m_activity_culling = false;
+ m_suspend = false;
+ m_isclearingZbuffer = true;
+ m_tempObjectList = new CListValue();
+ m_objectlist = new CListValue();
+ m_parentlist = new CListValue();
+ m_lightlist= new CListValue();
+ m_euthanasyobjects = new CListValue();
+
+ m_logicmgr = new SCA_LogicManager();
+
+ m_timemgr = new SCA_TimeEventManager(m_logicmgr);
+ m_keyboardmgr = new SCA_KeyboardManager(m_logicmgr,keyboarddevice);
+ m_mousemgr = new SCA_MouseManager(m_logicmgr,mousedevice);
+
+// m_solidScene = DT_CreateScene();
+// m_respTable = DT_CreateRespTable();
+
+ SCA_AlwaysEventManager* alwaysmgr = new SCA_AlwaysEventManager(m_logicmgr);
+ //KX_TouchEventManager* touchmgr = new KX_TouchEventManager(m_logicmgr, m_respTable, m_solidScene);
+ SCA_PropertyEventManager* propmgr = new SCA_PropertyEventManager(m_logicmgr);
+ SCA_RandomEventManager* rndmgr = new SCA_RandomEventManager(m_logicmgr);
+ KX_RayEventManager* raymgr = new KX_RayEventManager(m_logicmgr);
+
+ KX_NetworkEventManager* netmgr = new KX_NetworkEventManager(m_logicmgr, ndi);
+
+ m_logicmgr->RegisterEventManager(alwaysmgr);
+ m_logicmgr->RegisterEventManager(propmgr);
+ m_logicmgr->RegisterEventManager(m_keyboardmgr);
+ m_logicmgr->RegisterEventManager(m_mousemgr);
+ //m_logicmgr->RegisterEventManager(touchmgr);
+ m_logicmgr->RegisterEventManager(m_timemgr);
+ m_logicmgr->RegisterEventManager(rndmgr);
+ m_logicmgr->RegisterEventManager(raymgr);
+ m_logicmgr->RegisterEventManager(netmgr);
+
+ //m_sumoScene = new SM_Scene();
+ //m_sumoScene->setSecondaryRespTable(m_respTable);
+ m_soundScene = new SND_Scene(adi);
+ assert (m_networkDeviceInterface != NULL);
+ m_networkScene = new NG_NetworkScene(m_networkDeviceInterface);
+
+ m_rootnode = NULL;
+
+ m_bucketmanager=new RAS_BucketManager();
+
+ m_canvasDesignWidth = 0;
+ m_canvasDesignHeight = 0;
+}
+
+
+
+KX_Scene::~KX_Scene()
+{
+// int numobj = m_objectlist->GetCount();
+
+ //int numrootobjects = GetRootParentList()->GetCount();
+ for (int i = 0; i < GetRootParentList()->GetCount(); i++)
+ {
+ KX_GameObject* parentobj = (KX_GameObject*) GetRootParentList()->GetValue(i);
+ this->RemoveObject(parentobj);
+ }
+
+ if(m_objectlist)
+ m_objectlist->Release();
+
+ if (m_parentlist)
+ m_parentlist->Release();
+
+ if (m_lightlist)
+ m_lightlist->Release();
+
+ if (m_tempObjectList)
+ m_tempObjectList->Release();
+
+ if (m_euthanasyobjects)
+ m_euthanasyobjects->Release();
+
+ if (m_logicmgr)
+ delete m_logicmgr;
+
+ if (m_physicsEnvironment)
+ delete m_physicsEnvironment;
+
+ if (m_soundScene)
+ delete m_soundScene;
+
+ if (m_networkScene)
+ delete m_networkScene;
+
+ if (m_bucketmanager)
+ {
+ delete m_bucketmanager;
+ }
+}
+
+
+
+
+void KX_Scene::SetProjectionMatrix(MT_CmMatrix4x4& pmat)
+{
+ m_projectionmat = pmat;
+}
+
+
+
+RAS_BucketManager* KX_Scene::GetBucketManager()
+{
+ return m_bucketmanager;
+}
+
+
+
+CListValue* KX_Scene::GetObjectList()
+{
+ return m_objectlist;
+}
+
+
+
+CListValue* KX_Scene::GetRootParentList()
+{
+ return m_parentlist;
+}
+
+
+
+CListValue* KX_Scene::GetLightList()
+{
+ return m_lightlist;
+}
+
+SCA_LogicManager* KX_Scene::GetLogicManager()
+{
+ return m_logicmgr;
+}
+
+SCA_TimeEventManager* KX_Scene::GetTimeEventManager()
+{
+ return m_timemgr;
+}
+
+
+
+
+void KX_Scene::SetFramingType(RAS_FrameSettings & frame_settings)
+{
+ m_frame_settings = frame_settings;
+};
+
+/**
+ * Return a const reference to the framing
+ * type set by the above call.
+ * The contents are not guarenteed to be sensible
+ * if you don't call the above function.
+ */
+const RAS_FrameSettings& KX_Scene::GetFramingType() const
+{
+ return m_frame_settings;
+};
+
+
+
+/**
+ * Store the current scene's viewport on the
+ * game engine canvas.
+ */
+void KX_Scene::SetSceneViewport(const RAS_Rect &viewport)
+{
+ m_viewport = viewport;
+}
+
+
+
+const RAS_Rect& KX_Scene::GetSceneViewport() const
+{
+ return m_viewport;
+}
+
+
+
+void KX_Scene::SetWorldInfo(class KX_WorldInfo* worldinfo)
+{
+ m_worldinfo = worldinfo;
+}
+
+
+
+class KX_WorldInfo* KX_Scene::GetWorldInfo()
+{
+ return m_worldinfo;
+}
+
+
+
+SND_Scene* KX_Scene::GetSoundScene()
+{
+ return m_soundScene;
+}
+
+const STR_String& KX_Scene::GetName()
+{
+ return m_sceneName;
+}
+
+
+void KX_Scene::Suspend()
+{
+ m_suspend = true;
+}
+
+void KX_Scene::Resume()
+{
+ m_suspend = false;
+}
+
+void KX_Scene::SetActivityCulling(bool b)
+{
+ m_activity_culling = b;
+}
+
+bool KX_Scene::IsSuspended()
+{
+ return m_suspend;
+}
+
+bool KX_Scene::IsClearingZBuffer()
+{
+ return m_isclearingZbuffer;
+}
+
+void KX_Scene::EnableZBufferClearing(bool isclearingZbuffer)
+{
+ m_isclearingZbuffer = isclearingZbuffer;
+}
+
+void KX_Scene::RemoveNodeDestructObject(class SG_IObject* node,class CValue* gameobj)
+{
+ KX_GameObject* orgobj = (KX_GameObject*)gameobj;
+ NewRemoveObject(orgobj);
+
+ if (node)
+ delete node;
+}
+
+KX_GameObject* KX_Scene::AddNodeReplicaObject(class SG_IObject* node, class CValue* gameobj)
+{
+ KX_GameObject* orgobj = (KX_GameObject*)gameobj;
+ KX_GameObject* newobj = (KX_GameObject*)orgobj->GetReplica();
+ m_map_gameobject_to_replica.insert(orgobj, newobj);
+
+ // also register 'timers' (time properties) of the replica
+ int numprops = newobj->GetPropertyCount();
+
+ for (int i = 0; i < numprops; i++)
+ {
+ CValue* prop = newobj->GetProperty(i);
+
+ if (prop->GetProperty("timer"))
+ this->m_timemgr->AddTimeProperty(prop);
+ }
+
+ if (node)
+ {
+ newobj->SetSGNode((SG_Node*)node);
+ }
+ else
+ {
+ m_rootnode = new SG_Node(newobj,this,KX_Scene::m_callbacks);
+
+ // this fixes part of the scaling-added object bug
+ SG_Node* orgnode = orgobj->GetSGNode();
+ m_rootnode->SetLocalScale(orgnode->GetLocalScale());
+ m_rootnode->SetLocalPosition(orgnode->GetLocalPosition());
+ m_rootnode->SetLocalOrientation(orgnode->GetLocalOrientation());
+
+ // define the relationship between this node and it's parent.
+ KX_NormalParentRelation * parent_relation =
+ KX_NormalParentRelation::New();
+ m_rootnode->SetParentRelation(parent_relation);
+
+ newobj->SetSGNode(m_rootnode);
+ }
+
+ SG_IObject* replicanode = newobj->GetSGNode();
+ SG_Node* rootnode = (replicanode == m_rootnode ? NULL : m_rootnode);
+
+ replicanode->SetSGClientObject(newobj);
+
+ // this is the list of object that are send to the graphics pipeline
+ m_objectlist->Add(newobj);
+ newobj->Bucketize();
+
+ // logic cannot be replicated, until the whole hierarchy is replicated.
+ m_logicHierarchicalGameObjects.push_back(newobj);
+ //replicate controllers of this node
+ SGControllerList scenegraphcontrollers = orgobj->GetSGNode()->GetSGControllerList();
+ replicanode->RemoveAllControllers();
+ SGControllerList::iterator cit;
+ //int numcont = scenegraphcontrollers.size();
+
+ for (cit = scenegraphcontrollers.begin();!(cit==scenegraphcontrollers.end());++cit)
+ {
+ // controller replication is quite complicated
+ // only replicate ipo and physics controller for now
+
+ SG_Controller* replicacontroller = (*cit)->GetReplica((SG_Node*) replicanode);
+ if (replicacontroller)
+ {
+ replicacontroller->SetObject(replicanode);
+ replicanode->AddSGController(replicacontroller);
+ }
+ }
+
+ return newobj;
+}
+
+
+
+// before calling this method KX_Scene::ReplicateLogic(), make sure to
+// have called 'GameObject::ReParentLogic' for each object this
+// hierarchy that's because first ALL bricks must exist in the new
+// replica of the hierarchy in order to make cross-links work properly
+// !
+void KX_Scene::ReplicateLogic(KX_GameObject* newobj)
+{
+ // also relink the controller to sensors/actuators
+ SCA_ControllerList& controllers = newobj->GetControllers();
+ //SCA_SensorList& sensors = newobj->GetSensors();
+ //SCA_ActuatorList& actuators = newobj->GetActuators();
+
+ for (SCA_ControllerList::iterator itc = controllers.begin(); !(itc==controllers.end());itc++)
+ {
+ SCA_IController* cont = (*itc);
+ cont->SetUeberExecutePriority(m_ueberExecutionPriority);
+ vector<SCA_ISensor*> linkedsensors = cont->GetLinkedSensors();
+ vector<SCA_IActuator*> linkedactuators = cont->GetLinkedActuators();
+
+ // disconnect the sensors and actuators
+ cont->UnlinkAllSensors();
+ cont->UnlinkAllActuators();
+
+ // now relink each sensor
+ for (vector<SCA_ISensor*>::iterator its = linkedsensors.begin();!(its==linkedsensors.end());its++)
+ {
+ SCA_ISensor* oldsensor = (*its);
+ STR_String name = oldsensor->GetName();
+ //find this name in the list
+ SCA_ISensor* newsensor = newobj->FindSensor(name);
+
+ if (newsensor)
+ {
+ // relink this newsensor to the controller
+ m_logicmgr->RegisterToSensor(cont,newsensor);
+ }
+ else
+ {
+ // it can be linked somewhere in the hierarchy or...
+ for (vector<KX_GameObject*>::iterator git = m_logicHierarchicalGameObjects.begin();
+ !(git==m_logicHierarchicalGameObjects.end());++git)
+ {
+ newsensor = (*git)->FindSensor(name);
+ if (newsensor)
+ break;
+ }
+
+ if (newsensor)
+ {
+ // relink this newsensor to the controller somewhere else within this
+ // hierarchy
+ m_logicmgr->RegisterToSensor(cont,newsensor);
+ }
+ else
+ {
+ // must be an external sensor, so...
+ m_logicmgr->RegisterToSensor(cont,oldsensor);
+ }
+ }
+ }
+
+ // now relink each actuator
+ for (vector<SCA_IActuator*>::iterator ita = linkedactuators.begin();!(ita==linkedactuators.end());ita++)
+ {
+ SCA_IActuator* oldactuator = (*ita);
+ STR_String name = oldactuator->GetName();
+ //find this name in the list
+ SCA_IActuator* newactuator = newobj->FindActuator(name);
+ if (newactuator)
+ {
+ // relink this newsensor to the controller
+ m_logicmgr->RegisterToActuator(cont,newactuator);
+ newactuator->SetUeberExecutePriority(m_ueberExecutionPriority);
+ }
+ else
+ {
+ // it can be linked somewhere in the hierarchy or...
+ for (vector<KX_GameObject*>::iterator git = m_logicHierarchicalGameObjects.begin();
+ !(git==m_logicHierarchicalGameObjects.end());++git)
+ {
+ newactuator= (*git)->FindActuator(name);
+ if (newactuator)
+ break;
+ }
+
+ if (newactuator)
+ {
+ // relink this actuator to the controller somewhere else within this
+ // hierarchy
+ m_logicmgr->RegisterToActuator(cont,newactuator);
+ newactuator->SetUeberExecutePriority(m_ueberExecutionPriority);
+ }
+ else
+ {
+ // must be an external actuator, so...
+ m_logicmgr->RegisterToActuator(cont,oldactuator);
+ }
+ }
+ }
+ }
+}
+
+
+
+SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
+ class CValue* parentobject,
+ int lifespan)
+{
+
+ m_logicHierarchicalGameObjects.clear();
+ m_map_gameobject_to_replica.clear();
+
+ // todo: place a timebomb in the object, for temporarily objects :)
+ // lifespan of zero means 'this object lives forever'
+ KX_GameObject* originalobj = (KX_GameObject*) originalobject;
+ KX_GameObject* parentobj = (KX_GameObject*) parentobject;
+
+ m_ueberExecutionPriority++;
+
+ // lets create a replica
+ KX_GameObject* replica = (KX_GameObject*) AddNodeReplicaObject(NULL,originalobj);
+
+ if (lifespan > 0)
+ {
+ // add a timebomb to this object
+ // for now, convert between so called frames and realtime
+ m_tempObjectList->Add(replica->AddRef());
+ replica->SetProperty("::timebomb",new CFloatValue(lifespan*0.02));
+ }
+
+ // add to 'rootparent' list (this is the list of top hierarchy objects, updated each frame)
+ m_parentlist->Add(replica->AddRef());
+
+ // recurse replication into children nodes
+
+ NodeList& children = originalobj->GetSGNode()->GetSGChildren();
+
+ replica->GetSGNode()->ClearSGChildren();
+ for (NodeList::iterator childit = children.begin();!(childit==children.end());++childit)
+ {
+ SG_Node* orgnode = (*childit);
+ SG_Node* childreplicanode = orgnode->GetSGReplica();
+ replica->GetSGNode()->AddChild(childreplicanode);
+ }
+
+ // relink any pointers as necessary, sort of a temporary solution
+ vector<KX_GameObject*>::iterator git;
+ for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
+ {
+ (*git)->Relink(&m_map_gameobject_to_replica);
+ }
+
+ // now replicate logic
+ for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
+ {
+ (*git)->ReParentLogic();
+ }
+
+ // replicate crosslinks etc. between logic bricks
+ for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
+ {
+ ReplicateLogic((*git));
+ }
+
+ MT_Point3 newpos = ((KX_GameObject*) parentobject)->NodeGetWorldPosition();
+ replica->NodeSetLocalPosition(newpos);
+
+ MT_Matrix3x3 newori = ((KX_GameObject*) parentobject)->NodeGetWorldOrientation();
+ replica->NodeSetLocalOrientation(newori);
+
+ if (replica->GetPhysicsController())
+ {
+ replica->GetPhysicsController()->setPosition(newpos);
+ replica->GetPhysicsController()->setOrientation(newori.getRotation());
+ }
+
+ // here we want to set the relative scale: the rootnode's scale will override all other
+ // scalings, so lets better prepare for it
+
+ // get the rootnode's scale
+ MT_Vector3 newscale = parentobj->GetSGNode()->GetRootSGParent()->GetLocalScale();
+
+ // set the replica's relative scale with the rootnode's scale
+ replica->NodeSetRelativeScale(newscale);
+
+ replica->GetSGNode()->UpdateWorldData(0);
+
+ return replica;
+}
+
+
+
+void KX_Scene::RemoveObject(class CValue* gameobj)
+{
+ KX_GameObject* newobj = (KX_GameObject*) gameobj;
+
+ // first disconnect child from parent
+ SG_Node* node = newobj->GetSGNode();
+
+ if (node)
+ {
+ node->DisconnectFromParent();
+
+ // recursively destruct
+ node->Destruct();
+ }
+}
+
+
+
+void KX_Scene::DelayedRemoveObject(class CValue* gameobj)
+{
+ //KX_GameObject* newobj = (KX_GameObject*) gameobj;
+ if (!m_euthanasyobjects->SearchValue(gameobj))
+ {
+ m_euthanasyobjects->Add(gameobj->AddRef());
+ }
+}
+
+
+
+void KX_Scene::NewRemoveObject(class CValue* gameobj)
+{
+ KX_GameObject* newobj = (KX_GameObject*) gameobj;
+ //SM_Object* sumoObj = newobj->GetSumoObject();
+ //if (sumoObj)
+ //{
+ // this->GetSumoScene()->remove(*sumoObj);
+ //}
+ // remove all sensors/controllers/actuators from logicsystem...
+
+ SCA_SensorList& sensors = newobj->GetSensors();
+ for (SCA_SensorList::iterator its = sensors.begin();
+ !(its==sensors.end());its++)
+ {
+ m_logicmgr->RemoveSensor(*its);
+ }
+
+ SCA_ControllerList& controllers = newobj->GetControllers();
+ for (SCA_ControllerList::iterator itc = controllers.begin();
+ !(itc==controllers.end());itc++)
+ {
+ (*itc)->UnlinkAllSensors();
+ (*itc)->UnlinkAllActuators();
+ }
+
+ SCA_ActuatorList& actuators = newobj->GetActuators();
+ for (SCA_ActuatorList::iterator ita = actuators.begin();
+ !(ita==actuators.end());ita++)
+ {
+ m_logicmgr->RemoveDestroyedActuator(*ita);
+ }
+
+ // now remove the timer properties from the time manager
+ int numprops = newobj->GetPropertyCount();
+
+ for (int i = 0; i < numprops; i++)
+ {
+ CValue* propval = newobj->GetProperty(i);
+ if (propval->GetProperty("timer"))
+ {
+ m_timemgr->RemoveTimeProperty(propval);
+ }
+ }
+
+ newobj->RemoveMeshes();
+ if (m_objectlist->RemoveValue(newobj))
+ newobj->Release();
+ if (m_tempObjectList->RemoveValue(newobj))
+ newobj->Release();
+ if (m_parentlist->RemoveValue(newobj))
+ newobj->Release();
+ if (m_euthanasyobjects->RemoveValue(newobj))
+ newobj->Release();
+}
+
+
+
+void KX_Scene::ReplaceMesh(class CValue* gameobj,void* meshobj)
+{
+ KX_GameObject* newobj = (KX_GameObject*) gameobj;
+ newobj->RemoveMeshes();
+ newobj->AddMesh((RAS_MeshObject*)meshobj);
+ newobj->Bucketize();
+}
+
+
+
+MT_CmMatrix4x4& KX_Scene::GetViewMatrix()
+{
+ MT_Scalar cammat[16];
+ m_active_camera->GetWorldToCamera().getValue(cammat);
+ m_viewmat = cammat;
+ return m_viewmat;
+}
+
+
+
+MT_CmMatrix4x4& KX_Scene::GetProjectionMatrix()
+{
+ return m_projectionmat;
+}
+
+
+KX_Camera* KX_Scene::FindCamera(KX_Camera* cam)
+{
+ set<KX_Camera*>::iterator it = m_cameras.begin();
+
+ while ( (it != m_cameras.end())
+ && ((*it) != cam) ) {
+ it++;
+ }
+
+ return ((it == m_cameras.end()) ? NULL : (*it));
+}
+
+
+KX_Camera* KX_Scene::FindCamera(STR_String& name)
+{
+ set<KX_Camera*>::iterator it = m_cameras.begin();
+
+ while ( (it != m_cameras.end())
+ && ((*it)->GetName() != name) ) {
+ it++;
+ }
+
+ return ((it == m_cameras.end()) ? NULL : (*it));
+}
+
+void KX_Scene::AddCamera(KX_Camera* cam)
+{
+ m_cameras.insert(cam);
+}
+
+
+KX_Camera* KX_Scene::GetActiveCamera()
+{
+ // NULL if not defined
+ return m_active_camera;
+}
+
+
+void KX_Scene::SetActiveCamera(KX_Camera* cam)
+{
+ // only set if the cam is in the active list? Or add it otherwise?
+ if (!FindCamera(cam)){
+ AddCamera(cam);
+ if (cam) std::cout << "Added cam " << cam->GetName() << std::endl;
+ }
+
+ m_active_camera = cam;
+}
+
+
+
+void KX_Scene::UpdateMeshTransformations()
+{
+ // do this incrementally in the future
+ for (int i = 0; i < m_objectlist->GetCount(); i++)
+ {
+ KX_GameObject* gameobj = (KX_GameObject*)m_objectlist->GetValue(i);
+ gameobj->GetOpenGLMatrix();
+ gameobj->UpdateNonDynas();
+ }
+}
+
+void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty)
+{
+
+ // do this incrementally in the future
+ for (int i = 0; i < m_objectlist->GetCount(); i++)
+ {
+ KX_GameObject* gameobj = (KX_GameObject*)m_objectlist->GetValue(i);
+
+ int nummeshes = gameobj->GetMeshCount();
+
+ for (int m=0;m<nummeshes;m++)
+ {
+ // this adds the vertices to the display list
+ (gameobj->GetMesh(m))->SchedulePolygons(rasty->GetDrawingMode(),rasty);
+ // Visibility/ non-visibility are marked
+ // elsewhere now.
+ gameobj->MarkVisible();
+ }
+ }
+}
+
+// logic stuff
+void KX_Scene::LogicBeginFrame(double curtime,double deltatime)
+{
+ // have a look at temp objects ...
+ int lastobj = m_tempObjectList->GetCount() - 1;
+
+ for (int i = lastobj; i >= 0; i--)
+ {
+ CValue* objval = m_tempObjectList->GetValue(i);
+ CFloatValue* propval = (CFloatValue*) objval->GetProperty("::timebomb");
+
+ if (propval)
+ {
+ float timeleft = propval->GetNumber() - deltatime;
+
+ if (timeleft > 0)
+ {
+ propval->SetFloat(timeleft);
+ }
+ else
+ {
+ DelayedRemoveObject(objval);
+ // remove obj
+ }
+ }
+ else
+ {
+ // all object is the tempObjectList should have a clock
+ }
+ }
+ m_logicmgr->BeginFrame(curtime,deltatime);
+}
+
+
+
+void KX_Scene::LogicUpdateFrame(double curtime,double deltatime)
+{
+ m_logicmgr->UpdateFrame(curtime,deltatime);
+}
+
+
+
+void KX_Scene::LogicEndFrame()
+{
+ m_logicmgr->EndFrame();
+ int numobj = m_euthanasyobjects->GetCount();
+
+ for (int i = numobj - 1; i >= 0; i--)
+ {
+ KX_GameObject* gameobj = (KX_GameObject*)m_euthanasyobjects->GetValue(i);
+ this->RemoveObject(gameobj);
+ }
+
+ numobj = m_euthanasyobjects->GetCount();
+ if (numobj != 0)
+ {
+ // huh?
+ int ii=0;
+ }
+ // numobj is 0 we hope
+}
+
+
+
+/**
+ * UpdateParents: SceneGraph transformation update.
+ */
+void KX_Scene::UpdateParents(double curtime)
+{
+// int numrootobjects = GetRootParentList()->GetCount();
+
+ for (int i=0; i<GetRootParentList()->GetCount(); i++)
+ {
+ KX_GameObject* parentobj = (KX_GameObject*)GetRootParentList()->GetValue(i);
+ parentobj->NodeUpdateGS(curtime,true);
+ }
+}
+
+
+
+RAS_MaterialBucket* KX_Scene::FindBucket(class RAS_IPolyMaterial* polymat)
+{
+ return m_bucketmanager->RAS_BucketManagerFindBucket(polymat);
+}
+
+
+
+void KX_Scene::RenderBuckets(const MT_Transform & cameratransform,
+ class RAS_IRasterizer* rasty,
+ class RAS_IRenderTools* rendertools)
+{
+ m_bucketmanager->Renderbuckets(cameratransform,rasty,rendertools);
+}
+
+
+
+void KX_Scene::UpdateObjectActivity(void)
+{
+ if (m_activity_culling) {
+ /* determine the activity criterium and set objects accordingly */
+ int i=0;
+
+ MT_Point3 camloc = GetActiveCamera()->NodeGetWorldPosition(); //GetCameraLocation();
+
+ for (i=0;i<GetObjectList()->GetCount();i++)
+ {
+ KX_GameObject* ob = (KX_GameObject*) GetObjectList()->GetValue(i);
+
+ if (!ob->GetIgnoreActivityCulling()) {
+ /* Simple test: more than 10 away from the camera, count
+ * Manhattan distance. */
+ MT_Point3 obpos = ob->NodeGetWorldPosition();
+
+ if ( (fabs(camloc[0] - obpos[0]) > m_activity_box_radius)
+ || (fabs(camloc[1] - obpos[1]) > m_activity_box_radius)
+ || (fabs(camloc[2] - obpos[2]) > m_activity_box_radius) )
+ {
+ ob->Suspend();
+ } else {
+ ob->Resume();
+ }
+ }
+ }
+ }
+}
+
+void KX_Scene::SetActivityCullingRadius(float f)
+{
+ if (f < 0.5)
+ f = 0.5;
+ m_activity_box_radius = f;
+}
+
+NG_NetworkDeviceInterface* KX_Scene::GetNetworkDeviceInterface()
+{
+ return m_networkDeviceInterface;
+}
+
+NG_NetworkScene* KX_Scene::GetNetworkScene()
+{
+ return m_networkScene;
+}
+
+void KX_Scene::SetNetworkDeviceInterface(NG_NetworkDeviceInterface* newInterface)
+{
+ m_networkDeviceInterface = newInterface;
+}
+
+void KX_Scene::SetNetworkScene(NG_NetworkScene *newScene)
+{
+ m_networkScene = newScene;
+}
+
+
+void KX_Scene::SetGravity(const MT_Vector3& gravity)
+{
+ GetPhysicsEnvironment()->setGravity(gravity[0],gravity[1],gravity[2]);
+}
diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h
new file mode 100644
index 00000000000..818368561e6
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_Scene.h
@@ -0,0 +1,480 @@
+/**
+ * $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_SCENE_H
+#define __KX_SCENE_H
+
+
+#include "KX_PhysicsEngineEnums.h"
+
+#include "MT_CmMatrix4x4.h"
+
+#include <vector>
+#include <set>
+
+#include "GEN_Map.h"
+#include "GEN_HashedPtr.h"
+#include "SG_IObject.h"
+#include "SCA_IScene.h"
+#include "MT_Transform.h"
+#include "SND_Scene.h"
+#include "RAS_FramingManager.h"
+#include "RAS_Rect.h"
+
+/**
+ * @section Forward declarations
+ */
+struct SM_MaterialProps;
+struct SM_ShapeProps;
+
+class CListValue;
+class RAS_BucketManager;
+class KX_Camera;
+class SCA_LogicManager;
+class SCA_KeyboardManager;
+class SCA_TimeEventManager;
+class SCA_MouseManager;
+class KX_WorldInfo;
+class SND_Scene;
+class SND_IAudioDevice;
+class NG_NetworkDeviceInterface;
+class NG_NetworkScene;
+class SG_Node;
+class KX_Camera;
+class GEN_HashedPtr;
+class KX_GameObject;
+class SCA_ISystem;
+class SCA_IInputDevice;
+class RAS_BucketManager;
+class RAS_MaterialBucket;
+class RAS_IPolyMaterial;
+class RAS_IRasterizer;
+class RAS_IRenderTools;
+class CValue;
+class SG_IObject;
+
+/**
+ * The KX_Scene holds all data for an independent scene. It relates
+ * KX_Objects to the specific objects in the modules.
+ * */
+class KX_Scene : public SCA_IScene
+{
+ RAS_BucketManager* m_bucketmanager;
+ CListValue* m_tempObjectList;
+
+ /**
+ * The list of objects which have been removed during the
+ * course of one frame. They are actually destroyed in
+ * LogicEndFrame() via a call to RemoveObject().
+ */
+ CListValue* m_euthanasyobjects;
+
+ CListValue* m_objectlist;
+ CListValue* m_parentlist; // all 'root' parents
+ CListValue* m_lightlist;
+
+ /**
+ * The set of cameras for this scene
+ */
+ set<class KX_Camera*> m_cameras;
+
+ /**
+ * Various SCA managers used by the scene
+ */
+ SCA_LogicManager* m_logicmgr;
+ SCA_KeyboardManager* m_keyboardmgr;
+ SCA_MouseManager* m_mousemgr;
+ SCA_TimeEventManager* m_timemgr;
+
+ /**
+ * physics engine abstraction
+ */
+
+ e_PhysicsEngine m_physicsEngine;
+ class PHY_IPhysicsEnvironment* m_physicsEnvironment;
+
+ /**
+ * Does this scene clear the z-buffer?
+ */
+ bool m_isclearingZbuffer;
+
+ /**
+ * The name of the scene
+ */
+ STR_String m_sceneName;
+
+ /**
+ * stores the worldsettings for a scene
+ */
+ KX_WorldInfo* m_worldinfo;
+
+ /**
+ * @section Different scenes, linked to ketsji scene
+ */
+
+
+ /**
+ * Sound scenes
+ */
+ SND_Scene* m_soundScene;
+ SND_IAudioDevice* m_adi;
+
+ /**
+ * Network scene.
+ */
+ NG_NetworkDeviceInterface* m_networkDeviceInterface;
+ NG_NetworkScene* m_networkScene;
+
+ /**
+ * A temoprary variable used to parent objects together on
+ * replication. Don't get confused by the name it is not
+ * the scene's root node!
+ */
+ SG_Node* m_rootnode;
+
+ /**
+ * The active camera for the scene
+ */
+ KX_Camera* m_active_camera;
+
+ /**
+ * The projection and view matrices of this scene
+ * The projection matrix is computed externally by KX_Engine
+ * The view mat is stored as a side effect of GetViewMatrix()
+ * and is totally unnessary.
+ */
+ MT_CmMatrix4x4 m_projectionmat;
+ MT_CmMatrix4x4 m_viewmat;
+
+ /** Desired canvas width set at design time. */
+ unsigned int m_canvasDesignWidth;
+ /** Desired canvas height set at design time. */
+ unsigned int m_canvasDesignHeight;
+
+ /**
+ * Another temporary variable outstaying its welcome
+ * used in AddReplicaObject to map game objects to their
+ * replicas so pointers can be updated.
+ */
+ GEN_Map <GEN_HashedPtr, void*> m_map_gameobject_to_replica;
+
+ /**
+ * Another temporary variable outstaying its welcome
+ * used in AddReplicaObject to keep a record of all added
+ * objects. Logic can only be updated when all objects
+ * have been updated. This stores a list of the new objects.
+ */
+ std::vector<KX_GameObject*> m_logicHierarchicalGameObjects;
+
+ /**
+ * Pointer to system variable passed in in constructor
+ * only used in constructor so we do not need to keep it
+ * around in this class.
+ */
+
+ SCA_ISystem* m_kxsystem;
+
+ /**
+ * The execution priority of replicated object actuators?
+ */
+ int m_ueberExecutionPriority;
+
+ /**
+ * Activity 'bubble' settings :
+ * Suspend (freeze) the entire scene.
+ */
+ bool m_suspend;
+
+ /**
+ * Radius in Manhattan distance of the box for activity culling.
+ */
+ float m_activity_box_radius;
+
+ /**
+ * Toggle to enable or disable activity culling.
+ */
+ bool m_activity_culling;
+
+ /**
+ * The framing settings used by this scene
+ */
+
+ RAS_FrameSettings m_frame_settings;
+
+ /**
+ * This scenes viewport into the game engine
+ * canvas.Maintained externally, initially [0,0] -> [0,0]
+ */
+ RAS_Rect m_viewport;
+
+public:
+ KX_Scene(class SCA_IInputDevice* keyboarddevice,
+ class SCA_IInputDevice* mousedevice,
+ class NG_NetworkDeviceInterface* ndi,
+ class SND_IAudioDevice* adi,
+ const STR_String& scenename );
+
+ virtual
+ ~KX_Scene();
+
+ RAS_BucketManager* GetBucketManager();
+ RAS_MaterialBucket* FindBucket(RAS_IPolyMaterial* polymat);
+ void RenderBuckets(const MT_Transform& cameratransform,
+ RAS_IRasterizer* rasty,
+ RAS_IRenderTools* rendertools);
+ /**
+ * Update all transforms according to the scenegraph.
+ */
+ void UpdateParents(double curtime);
+ SCA_IObject* AddReplicaObject(CValue* gameobj,
+ CValue* locationobj,
+ int lifespan=0);
+ KX_GameObject* AddNodeReplicaObject(SG_IObject* node,
+ CValue* gameobj);
+ void RemoveNodeDestructObject(SG_IObject* node,
+ CValue* gameobj);
+ void RemoveObject(CValue* gameobj);
+ void DelayedRemoveObject(CValue* gameobj);
+ void NewRemoveObject(CValue* gameobj);
+ void ReplaceMesh(CValue* gameobj,
+ void* meshobj);
+ /**
+ * @section Logic stuff
+ * Initiate an update of the logic system.
+ */
+ void LogicBeginFrame(double curtime,
+ double deltatime);
+ void LogicUpdateFrame(double curtime,
+ double deltatime);
+
+ void
+ LogicEndFrame(
+ );
+
+ CListValue*
+ GetObjectList(
+ );
+
+ CListValue*
+ GetRootParentList(
+ );
+
+ CListValue*
+ GetLightList(
+ );
+
+ SCA_LogicManager*
+ GetLogicManager(
+ );
+
+ SCA_TimeEventManager*
+ GetTimeEventManager(
+ );
+
+
+ /** Find a camera in the scene by pointer. */
+ KX_Camera*
+ FindCamera(
+ KX_Camera*
+ );
+
+ /** Find a scene in the scene by name. */
+ KX_Camera*
+ FindCamera(
+ STR_String&
+ );
+
+ /** Add a camera to this scene. */
+ void
+ AddCamera(
+ KX_Camera*
+ );
+
+ /** Find the currently active camera. */
+ KX_Camera*
+ GetActiveCamera(
+ );
+
+ /**
+ * Set this camera to be the active camera in the scene. If the
+ * camera is not present in the camera list, it will be added
+ */
+
+ void
+ SetActiveCamera(
+ class KX_Camera*
+ );
+
+ /** Return the viewmatrix as used by the last frame. */
+ MT_CmMatrix4x4&
+ GetViewMatrix(
+ );
+
+ /**
+ * Return the projectionmatrix as used by the last frame. This is
+ * set by hand :)
+ */
+ MT_CmMatrix4x4&
+ GetProjectionMatrix(
+ );
+
+ /** Sets the projection matrix. */
+ void
+ SetProjectionMatrix(
+ MT_CmMatrix4x4& pmat
+ );
+
+ /**
+ * Activates new desired canvas width set at design time.
+ * @param width The new desired width.
+ */
+ void
+ SetCanvasDesignWidth(
+ unsigned int width
+ );
+ /**
+ * Activates new desired canvas height set at design time.
+ * @param width The new desired height.
+ */
+ void
+ SetCanvasDesignHeight(
+ unsigned int height
+ );
+ /**
+ * Returns the current desired canvas width set at design time.
+ * @return The desired width.
+ */
+ unsigned int
+ GetCanvasDesignWidth(
+ void
+ ) const;
+
+ /**
+ * Returns the current desired canvas height set at design time.
+ * @return The desired height.
+ */
+ unsigned int
+ GetCanvasDesignHeight(
+ void
+ ) const;
+
+ /**
+ * Set the framing options for this scene
+ */
+
+ void
+ SetFramingType(
+ RAS_FrameSettings & frame_settings
+ );
+
+ /**
+ * Return a const reference to the framing
+ * type set by the above call.
+ * The contents are not guarenteed to be sensible
+ * if you don't call the above function.
+ */
+
+ const
+ RAS_FrameSettings &
+ GetFramingType(
+ ) const;
+
+ /**
+ * Store the current scene's viewport on the
+ * game engine canvas.
+ */
+ void SetSceneViewport(const RAS_Rect &viewport);
+
+ /**
+ * Get the current scene's viewport on the
+ * game engine canvas. This maintained
+ * externally in KX_GameEngine
+ */
+ const RAS_Rect& GetSceneViewport() const;
+
+ /**
+ * @section Accessors to different scenes of this scene
+ */
+ void SetNetworkDeviceInterface(NG_NetworkDeviceInterface* newInterface);
+ void SetNetworkScene(NG_NetworkScene *newScene);
+ void SetWorldInfo(class KX_WorldInfo* wi);
+ KX_WorldInfo* GetWorldInfo();
+ void CalculateVisibleMeshes(RAS_IRasterizer* rasty);
+ void UpdateMeshTransformations();
+ KX_Camera* GetpCamera();
+ SND_Scene* GetSoundScene();
+ NG_NetworkDeviceInterface* GetNetworkDeviceInterface();
+ NG_NetworkScene* GetNetworkScene();
+
+ /**
+ * Replicate the logic bricks associated to this object.
+ */
+
+ void ReplicateLogic(class KX_GameObject* newobj);
+ static SG_Callbacks m_callbacks;
+
+ const STR_String& GetName();
+
+ // Suspend the entire scene.
+ void Suspend();
+
+ // Resume a suspended scene.
+ void Resume();
+
+ // Update the activity box settings for objects in this scene, if needed.
+ void UpdateObjectActivity(void);
+
+ // Enable/disable activity culling.
+ void SetActivityCulling(bool b);
+
+ // Set the radius of the activity culling box.
+ void SetActivityCullingRadius(float f);
+ bool IsSuspended();
+ bool IsClearingZBuffer();
+ void EnableZBufferClearing(bool isclearingZbuffer);
+
+ class PHY_IPhysicsEnvironment* GetPhysicsEnvironment()
+ {
+ return m_physicsEnvironment;
+ }
+
+ void SetPhysicsEnvironment(class PHY_IPhysicsEnvironment* physEnv)
+ {
+ m_physicsEnvironment = physEnv;
+ }
+
+ void SetGravity(const MT_Vector3& gravity);
+};
+
+typedef std::vector<KX_Scene*> KX_SceneList;
+
+#endif //__KX_SCENE_H
+
diff --git a/source/gameengine/Ketsji/KX_SceneActuator.cpp b/source/gameengine/Ketsji/KX_SceneActuator.cpp
new file mode 100644
index 00000000000..7cba1a6ac1e
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_SceneActuator.cpp
@@ -0,0 +1,354 @@
+/**
+* Set scene/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 "SCA_IActuator.h"
+#include "KX_SceneActuator.h"
+#include <iostream>
+#include "KX_Scene.h"
+#include "KX_Camera.h"
+#include "KX_KetsjiEngine.h"
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+KX_SceneActuator::KX_SceneActuator(SCA_IObject *gameobj,
+ int mode,
+ KX_Scene *scene,
+ KX_KetsjiEngine* ketsjiEngine,
+ const STR_String& nextSceneName,
+ KX_Camera* camera,
+ PyTypeObject* T)
+ : SCA_IActuator(gameobj, T)
+{
+ m_mode = mode;
+ m_scene = scene;
+ m_KetsjiEngine=ketsjiEngine;
+ m_camera = camera;
+ m_nextSceneName = nextSceneName;
+} /* End of constructor */
+
+
+
+KX_SceneActuator::~KX_SceneActuator()
+{
+ // there's nothing to be done here, really....
+} /* end of destructor */
+
+
+
+CValue* KX_SceneActuator::GetReplica()
+{
+ KX_SceneActuator* replica = new KX_SceneActuator(*this);
+ replica->ProcessReplica();
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+bool KX_SceneActuator::Update(double curtime,double deltatime)
+{
+ bool result = false;
+ bool bNegativeEvent = IsNegativeEvent();
+ RemoveAllEvents();
+
+ if (bNegativeEvent)
+ return false; // do nothing on negative events
+
+ switch (m_mode)
+ {
+ case KX_SCENE_RESTART:
+ {
+ m_KetsjiEngine->ReplaceScene(m_scene->GetName(),m_scene->GetName());
+ break;
+ }
+ case KX_SCENE_SET_SCENE:
+ {
+ m_KetsjiEngine->ReplaceScene(m_scene->GetName(),m_nextSceneName);
+ break;
+ }
+ case KX_SCENE_ADD_FRONT_SCENE:
+ {
+ bool overlay=true;
+ m_KetsjiEngine->ConvertAndAddScene(m_nextSceneName,overlay);
+ break;
+ }
+ case KX_SCENE_ADD_BACK_SCENE:
+ {
+ bool overlay=false;
+ m_KetsjiEngine->ConvertAndAddScene(m_nextSceneName,overlay);
+ break;
+ }
+ case KX_SCENE_REMOVE_SCENE:
+ {
+ m_KetsjiEngine->RemoveScene(m_nextSceneName);
+ break;
+ }
+ case KX_SCENE_SUSPEND:
+ {
+ m_KetsjiEngine->SuspendScene(m_nextSceneName);
+ break;
+ }
+ case KX_SCENE_RESUME:
+ {
+ m_KetsjiEngine->ResumeScene(m_nextSceneName);
+ break;
+ }
+ case KX_SCENE_SET_CAMERA:
+ if (m_camera)
+ {
+ m_scene->SetActiveCamera(m_camera);
+ }
+ break;
+ default:
+ ; /* do nothing? this is an internal error !!! */
+ }
+
+ return false;
+}
+
+
+
+/* returns a camera if the name is valid */
+KX_Camera* KX_SceneActuator::FindCamera(char *camName)
+{
+ KX_SceneList* sl = m_KetsjiEngine->CurrentScenes();
+ STR_String name = STR_String(camName);
+ KX_SceneList::iterator it = sl->begin();
+ KX_Camera* cam = NULL;
+
+ while ((it != sl->end()) && (!cam))
+ {
+ cam = (*it)->FindCamera(name);
+ it++;
+ }
+
+ return cam;
+}
+
+
+
+KX_Scene* KX_SceneActuator::FindScene(char * sceneName)
+{
+ return m_KetsjiEngine->FindScene(sceneName);
+}
+
+
+
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject KX_SceneActuator::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "KX_SceneActuator",
+ sizeof(KX_SceneActuator),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+
+
+PyParentObject KX_SceneActuator::Parents[] =
+{
+ &KX_SceneActuator::Type,
+ &SCA_IActuator::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+
+
+PyMethodDef KX_SceneActuator::Methods[] =
+{
+ {"setUseRestart", (PyCFunction) KX_SceneActuator::sPySetUseRestart, METH_VARARGS, SetUseRestart_doc},
+ {"setScene", (PyCFunction) KX_SceneActuator::sPySetScene, METH_VARARGS, SetScene_doc},
+ {"setCamera", (PyCFunction) KX_SceneActuator::sPySetCamera, METH_VARARGS, SetCamera_doc},
+ {"getUseRestart", (PyCFunction) KX_SceneActuator::sPyGetUseRestart, METH_VARARGS, GetUseRestart_doc},
+ {"getScene", (PyCFunction) KX_SceneActuator::sPyGetScene, METH_VARARGS, GetScene_doc},
+ {"getCamera", (PyCFunction) KX_SceneActuator::sPyGetCamera, METH_VARARGS, GetCamera_doc},
+ {NULL,NULL} //Sentinel
+};
+
+
+
+PyObject* KX_SceneActuator::_getattr(char* attr)
+{
+ _getattr_up(SCA_IActuator);
+}
+
+
+
+/* 2. setUseRestart--------------------------------------------------------- */
+char KX_SceneActuator::SetUseRestart_doc[] =
+"setUseRestart(flag)\n"
+"\t- flag: 0 or 1.\n"
+"\tSet flag to 1 to restart the scene.\n" ;
+PyObject* KX_SceneActuator::PySetUseRestart(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ int boolArg;
+
+ if (!PyArg_ParseTuple(args, "i", &boolArg))
+ {
+ return NULL;
+ }
+
+ if (boolArg == KX_TRUE)
+ {
+ m_restart = true;
+ }
+ else if (boolArg == KX_FALSE)
+ {
+ m_restart = false;
+ }
+ else
+ {
+ ; /* internal error */
+ }
+
+ Py_Return;
+}
+
+
+
+/* 3. getUseRestart: */
+char KX_SceneActuator::GetUseRestart_doc[] =
+"getUseRestart()\n"
+"\tReturn whether the scene will be restarted.\n" ;
+PyObject* KX_SceneActuator::PyGetUseRestart(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ return PyInt_FromLong(!(m_restart == 0));
+}
+
+
+
+/* 4. set scene------------------------------------------------------------- */
+char KX_SceneActuator::SetScene_doc[] =
+"setScene(scene)\n"
+"\t- scene: string\n"
+"\tSet the name of scene the actuator will switch to.\n" ;
+PyObject* KX_SceneActuator::PySetScene(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ /* one argument: a scene, ignore the rest */
+ char *scene_name;
+
+ if(!PyArg_ParseTuple(args, "s", &scene_name))
+ {
+ return NULL;
+ }
+
+ if (m_KetsjiEngine->FindScene(scene_name))
+ {
+ /* Scene switch is done by name. */
+ m_nextSceneName = scene_name;
+ }
+
+ Py_Return;
+}
+
+
+
+/* 5. getScene: */
+char KX_SceneActuator::GetScene_doc[] =
+"getScene()\n"
+"\tReturn the name of the scene the actuator wants to switch to.\n" ;
+PyObject* KX_SceneActuator::PyGetScene(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ return PyString_FromString(m_nextSceneName);
+}
+
+
+
+/* 6. set camera------------------------------------------------------------ */
+char KX_SceneActuator::SetCamera_doc[] =
+"setCamera(camera)\n"
+"\t- camera: string\n"
+"\tSet the camera to switch to.\n" ;
+PyObject* KX_SceneActuator::PySetCamera(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ /* one argument: a scene, ignore the rest */
+ char *camName;
+ KX_Camera *camOb;
+
+ if(!PyArg_ParseTuple(args, "s", &camName))
+ {
+ return NULL;
+ }
+
+ camOb = FindCamera(camName);
+ if (camOb) m_camera = camOb;
+
+ Py_Return;
+}
+
+
+
+/* 7. getCamera: */
+char KX_SceneActuator::GetCamera_doc[] =
+"getCamera()\n"
+"\tReturn the name of the camera to switch to.\n" ;
+PyObject* KX_SceneActuator::PyGetCamera(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ return PyString_FromString(m_camera->GetName());
+}
+/* eof */
diff --git a/source/gameengine/Ketsji/KX_SceneActuator.h b/source/gameengine/Ketsji/KX_SceneActuator.h
new file mode 100644
index 00000000000..a9f3751322e
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_SceneActuator.h
@@ -0,0 +1,115 @@
+
+//
+// Add object to the game world on action of this actuator
+//
+// $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_SCENEACTUATOR
+#define __KX_SCENEACTUATOR
+
+#include "SCA_IActuator.h"
+
+class KX_SceneActuator : public SCA_IActuator
+{
+ Py_Header;
+
+ int m_mode;
+ // (restart) has become a toggle internally... not in the interface though
+ bool m_restart;
+ // (set Scene) Scene
+ /** The current scene. */
+ class KX_Scene* m_scene;
+ class KX_KetsjiEngine* m_KetsjiEngine;
+ /** The scene to switch to. */
+ STR_String m_nextSceneName;
+
+ // (Set Camera) Object
+ class KX_Camera* m_camera;
+
+ /** Is this a valid scene? */
+ class KX_Scene* FindScene(char* sceneName);
+ /** Is this a valid camera? */
+ class KX_Camera* FindCamera(char* cameraName);
+
+ public:
+ enum SCA_SceneActuatorMode
+ {
+ KX_SCENE_NODEF = 0,
+ KX_SCENE_RESTART,
+ KX_SCENE_SET_SCENE,
+ KX_SCENE_SET_CAMERA,
+ KX_SCENE_ADD_FRONT_SCENE,
+ KX_SCENE_ADD_BACK_SCENE,
+ KX_SCENE_REMOVE_SCENE,
+ KX_SCENE_SUSPEND,
+ KX_SCENE_RESUME,
+ KX_SCENE_MAX
+ };
+
+ KX_SceneActuator(SCA_IObject* gameobj,
+ int mode,
+ KX_Scene* scene,
+ KX_KetsjiEngine* ketsjiEngine,
+ const STR_String& nextSceneName,
+ KX_Camera* camera,
+ PyTypeObject* T=&Type);
+ virtual ~KX_SceneActuator();
+
+ virtual CValue* GetReplica();
+
+ virtual bool Update(double curtime,double deltatime);
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(char *attr);
+
+ /* 1. set */
+ /* Removed */
+
+ /* 2. setUseRestart: */
+ KX_PYMETHOD_DOC(KX_SceneActuator,SetUseRestart);
+ /* 3. getUseRestart: */
+ KX_PYMETHOD_DOC(KX_SceneActuator,GetUseRestart);
+ /* 4. setScene: */
+ KX_PYMETHOD_DOC(KX_SceneActuator,SetScene);
+ /* 5. getScene: */
+ KX_PYMETHOD_DOC(KX_SceneActuator,GetScene);
+ /* 6. setCamera: */
+ KX_PYMETHOD_DOC(KX_SceneActuator,SetCamera);
+ /* 7. getCamera: */
+ KX_PYMETHOD_DOC(KX_SceneActuator,GetCamera);
+
+}; /* end of class KXSceneActuator */
+
+#endif
diff --git a/source/gameengine/Ketsji/KX_SoundActuator.cpp b/source/gameengine/Ketsji/KX_SoundActuator.cpp
new file mode 100644
index 00000000000..b36ff5f2c09
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_SoundActuator.cpp
@@ -0,0 +1,466 @@
+/**
+ * KX_SoundActuator.cpp
+ *
+ * $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 "KX_SoundActuator.h"
+#include "SND_SoundObject.h"
+#include "KX_GameObject.h"
+#include "SND_SoundObject.h"
+#include "SND_Scene.h" // needed for replication
+#include <iostream>
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+KX_SoundActuator::KX_SoundActuator(SCA_IObject* gameobj,
+ SND_SoundObject* sndobj,
+ SND_Scene* sndscene,
+ KX_SOUNDACT_TYPE type,
+ short start,
+ short end,
+ PyTypeObject* T)
+ : SCA_IActuator(gameobj,T)
+{
+ m_soundObject = sndobj;
+ m_soundScene = sndscene;
+ m_type = type;
+ m_lastEvent = true;
+ m_isplaying = false;
+ m_startFrame = start;
+ m_endFrame = end;
+ m_pino = false;
+}
+
+
+
+KX_SoundActuator::~KX_SoundActuator()
+{
+ //m_soundScene->RemoveObject(this->m_soundObject);
+ //(this->m_soundObject)->DeleteWhenFinished();
+ m_soundScene->RemoveActiveObject(m_soundObject);
+// m_soundScene->DeleteObjectWhenFinished(m_soundObject);
+ m_soundScene->DeleteObject(m_soundObject);
+}
+
+
+
+CValue* KX_SoundActuator::GetReplica()
+{
+ KX_SoundActuator* replica = new KX_SoundActuator(*this);
+ replica->ProcessReplica();
+ SND_SoundObject* soundobj = new SND_SoundObject(*m_soundObject);
+ replica->setSoundObject(soundobj);
+ m_soundScene->AddObject(soundobj);
+
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+ return replica;
+};
+
+
+
+bool KX_SoundActuator::Update(double curtime,double deltatime)
+{
+ bool result = false;
+
+ // do nothing on negative events, otherwise sounds are played twice!
+ bool bNegativeEvent = IsNegativeEvent();
+
+ RemoveAllEvents();
+
+ if (m_pino)
+ {
+ bNegativeEvent = true;
+ m_pino = false;
+ }
+
+ if (bNegativeEvent)
+ {
+ // here must be a check if it is still playing
+ m_isplaying = false;
+
+ switch (m_type)
+ {
+ case KX_SOUNDACT_PLAYSTOP:
+ case KX_SOUNDACT_LOOPSTOP:
+ case KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP:
+ {
+ m_soundScene->RemoveActiveObject(m_soundObject);
+ break;
+ }
+ case KX_SOUNDACT_PLAYEND:
+ {
+ m_soundObject->SetPlaystate(SND_MUST_STOP_WHEN_FINISHED);
+ break;
+ }
+ default:
+ // implement me !!
+ break;
+ }
+ }
+ else
+ {
+ if (m_soundObject && !m_isplaying)
+ {
+ switch (m_type)
+ {
+ case KX_SOUNDACT_LOOPBIDIRECTIONAL:
+ case KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP:
+ {
+ m_soundObject->SetLoopMode(SND_LOOP_BIDIRECTIONAL);
+ m_soundScene->AddActiveObject(m_soundObject, curtime);
+ m_isplaying = true;
+ result = true;
+ break;
+ }
+ case KX_SOUNDACT_LOOPEND:
+ case KX_SOUNDACT_LOOPSTOP:
+ {
+ m_soundObject->SetLoopMode(SND_LOOP_NORMAL);
+ m_soundScene->AddActiveObject(m_soundObject, curtime);
+ m_isplaying = true;
+ result = true;
+ break;
+ }
+ case KX_SOUNDACT_PLAYSTOP:
+ case KX_SOUNDACT_PLAYEND:
+ {
+ m_soundObject->SetLoopMode(SND_LOOP_OFF);
+ m_soundScene->AddActiveObject(m_soundObject, curtime);
+ m_isplaying = true;
+ result = true;
+ break;
+ }
+ default:
+ // implement me !!
+ break;
+ }
+ }
+ }
+
+ if (m_isplaying)
+ {
+ m_soundObject->SetPosition(((KX_GameObject*)this->GetParent())->NodeGetWorldPosition());
+ m_soundObject->SetVelocity(((KX_GameObject*)this->GetParent())->GetLinearVelocity());
+ m_soundObject->SetOrientation(((KX_GameObject*)this->GetParent())->NodeGetWorldOrientation());
+ result = true;
+ }
+ else
+ {
+ result = false;
+ }
+
+ if (result && (m_soundObject->IsLifeSpanOver(curtime)) && ((m_type == KX_SOUNDACT_PLAYEND) || (m_type == KX_SOUNDACT_PLAYSTOP)))
+ {
+ m_pino = true;
+ }
+
+ return result;
+}
+
+
+
+void KX_SoundActuator::setSoundObject(class SND_SoundObject* soundobject)
+{
+ m_soundObject = soundobject;
+}
+
+
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject KX_SoundActuator::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "KX_SoundActuator",
+ sizeof(KX_SoundActuator),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+
+
+PyParentObject KX_SoundActuator::Parents[] = {
+ &KX_SoundActuator::Type,
+ &SCA_IActuator::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+
+
+PyMethodDef KX_SoundActuator::Methods[] = {
+ {"setFilename", (PyCFunction) KX_SoundActuator::sPySetFilename, METH_VARARGS,NULL},
+ {"getFilename", (PyCFunction) KX_SoundActuator::sPyGetFilename, METH_VARARGS,NULL},
+ {"startSound",(PyCFunction) KX_SoundActuator::sPyStartSound,METH_VARARGS,NULL},
+ {"pauseSound",(PyCFunction) KX_SoundActuator::sPyPauseSound,METH_VARARGS,NULL},
+ {"stopSound",(PyCFunction) KX_SoundActuator::sPyStopSound,METH_VARARGS,NULL},
+ {"setGain",(PyCFunction) KX_SoundActuator::sPySetGain,METH_VARARGS,NULL},
+ {"getGain",(PyCFunction) KX_SoundActuator::sPyGetGain,METH_VARARGS,NULL},
+ {"setPitch",(PyCFunction) KX_SoundActuator::sPySetPitch,METH_VARARGS,NULL},
+ {"getPitch",(PyCFunction) KX_SoundActuator::sPyGetPitch,METH_VARARGS,NULL},
+ {"setRollOffFactor",(PyCFunction) KX_SoundActuator::sPySetRollOffFactor,METH_VARARGS,NULL},
+ {"getRollOffFactor",(PyCFunction) KX_SoundActuator::sPyGetRollOffFactor,METH_VARARGS,NULL},
+ {"setLooping",(PyCFunction) KX_SoundActuator::sPySetLooping,METH_VARARGS,NULL},
+ {"getLooping",(PyCFunction) KX_SoundActuator::sPyGetLooping,METH_VARARGS,NULL},
+ {"setPosition",(PyCFunction) KX_SoundActuator::sPySetPosition,METH_VARARGS,NULL},
+ {"setVelocity",(PyCFunction) KX_SoundActuator::sPySetVelocity,METH_VARARGS,NULL},
+ {"setOrientation",(PyCFunction) KX_SoundActuator::sPySetOrientation,METH_VARARGS,NULL},
+ {NULL,NULL,NULL,NULL} //Sentinel
+};
+
+
+
+PyObject* KX_SoundActuator::_getattr(char* attr)
+{
+ _getattr_up(SCA_IActuator);
+}
+
+
+
+PyObject* KX_SoundActuator::PySetFilename(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ char *soundName = NULL;
+ void *soundPointer = NULL;
+
+ if (!PyArg_ParseTuple(args, "s", &soundName))
+ return NULL;
+
+ Py_Return;
+}
+
+
+
+PyObject* KX_SoundActuator::PyGetFilename(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ STR_String objectname = m_soundObject->GetObjectName();
+ char* name = objectname.Ptr();
+
+ if (!name) {
+ Py_Return; /* internal error */
+ } else
+ return PyString_FromString(name);
+}
+
+
+
+PyObject* KX_SoundActuator::PyStartSound(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ m_soundObject->StartSound();
+ Py_Return;
+}
+
+
+
+PyObject* KX_SoundActuator::PyPauseSound(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ m_soundObject->PauseSound();
+ Py_Return;
+}
+
+
+
+PyObject* KX_SoundActuator::PyStopSound(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ m_soundObject->StopSound();
+ Py_Return;
+}
+
+
+
+PyObject* KX_SoundActuator::PySetGain(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ float gain = 1.0;
+ if (!PyArg_ParseTuple(args, "f", &gain))
+ return NULL;
+
+ m_soundObject->SetGain(gain);
+
+ Py_Return;
+}
+
+
+
+PyObject* KX_SoundActuator::PyGetGain(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ float gain = m_soundObject->GetGain();
+ PyObject* result = PyFloat_FromDouble(gain);
+
+ return result;
+}
+
+
+
+PyObject* KX_SoundActuator::PySetPitch(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ float pitch = 1.0;
+ if (!PyArg_ParseTuple(args, "f", &pitch))
+ return NULL;
+
+ m_soundObject->SetPitch(pitch);
+
+ Py_Return;
+}
+
+
+
+PyObject* KX_SoundActuator::PyGetPitch(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ float pitch = m_soundObject->GetPitch();
+ PyObject* result = PyFloat_FromDouble(pitch);
+
+ return result;
+}
+
+
+
+PyObject* KX_SoundActuator::PySetRollOffFactor(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ float rollofffactor = 1.0;
+ if (!PyArg_ParseTuple(args, "f", &rollofffactor))
+ return NULL;
+
+ m_soundObject->SetRollOffFactor(rollofffactor);
+
+ Py_Return;
+}
+
+
+
+PyObject* KX_SoundActuator::PyGetRollOffFactor(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ float rollofffactor = m_soundObject->GetRollOffFactor();
+ PyObject* result = PyFloat_FromDouble(rollofffactor);
+
+ return result;
+}
+
+
+
+PyObject* KX_SoundActuator::PySetLooping(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ bool looping = 1;
+ if (!PyArg_ParseTuple(args, "i", &looping))
+ return NULL;
+
+ m_soundObject->SetLoopMode(looping);
+
+ Py_Return;
+}
+
+
+
+PyObject* KX_SoundActuator::PyGetLooping(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int looping = m_soundObject->GetLoopMode();
+ PyObject* result = PyInt_FromLong(looping);
+
+ return result;
+}
+
+
+
+PyObject* KX_SoundActuator::PySetPosition(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ MT_Point3 pos;
+ pos[0] = 0.0;
+ pos[1] = 0.0;
+ pos[2] = 0.0;
+
+ if (!PyArg_ParseTuple(args, "fff", &pos[0], &pos[1], &pos[2]))
+ return NULL;
+
+ m_soundObject->SetPosition(pos);
+
+ Py_Return;
+}
+
+
+
+PyObject* KX_SoundActuator::PySetVelocity(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ MT_Vector3 vel;
+ vel[0] = 0.0;
+ vel[1] = 0.0;
+ vel[2] = 0.0;
+
+ if (!PyArg_ParseTuple(args, "fff", &vel[0], &vel[1], &vel[2]))
+ return NULL;
+
+ m_soundObject->SetVelocity(vel);
+
+ Py_Return;
+}
+
+
+
+PyObject* KX_SoundActuator::PySetOrientation(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ MT_Matrix3x3 ori;
+ ori[0][0] = 1.0;
+ ori[0][1] = 0.0;
+ ori[0][2] = 0.0;
+ ori[1][0] = 0.0;
+ ori[1][1] = 1.0;
+ ori[1][2] = 0.0;
+ ori[2][0] = 0.0;
+ ori[2][1] = 0.0;
+ ori[2][2] = 1.0;
+
+ if (!PyArg_ParseTuple(args, "fffffffff", &ori[0][0], &ori[0][1], &ori[0][2], &ori[1][0], &ori[1][1], &ori[1][2], &ori[2][0], &ori[2][1], &ori[2][2]))
+ return NULL;
+
+ m_soundObject->SetOrientation(ori);
+
+ Py_Return;
+}
+
+
+
diff --git a/source/gameengine/Ketsji/KX_SoundActuator.h b/source/gameengine/Ketsji/KX_SoundActuator.h
new file mode 100644
index 00000000000..1ebc3ef5250
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_SoundActuator.h
@@ -0,0 +1,106 @@
+/**
+ * KX_SoundActuator.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_SOUNDACTUATOR
+#define __KX_SOUNDACTUATOR
+
+#include "SCA_IActuator.h"
+
+class KX_SoundActuator : public SCA_IActuator
+{
+ Py_Header;
+ bool m_lastEvent;
+ bool m_isplaying;
+ /* just some handles to the audio-data... */
+ class SND_SoundObject* m_soundObject;
+ class SND_Scene* m_soundScene;
+ short m_startFrame;
+ short m_endFrame;
+ bool m_pino;
+public:
+
+ enum KX_SOUNDACT_TYPE
+ {
+ KX_SOUNDACT_NODEF = 0,
+ KX_SOUNDACT_PLAYSTOP,
+ KX_SOUNDACT_PLAYEND,
+ KX_SOUNDACT_LOOPSTOP,
+ KX_SOUNDACT_LOOPEND,
+ KX_SOUNDACT_LOOPBIDIRECTIONAL,
+ KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP,
+ KX_SOUNDACT_MAX
+ };
+
+ KX_SOUNDACT_TYPE m_type;
+
+ KX_SoundActuator(SCA_IObject* gameobj,
+ class SND_SoundObject* sndobj,
+ class SND_Scene* sndscene,
+ KX_SOUNDACT_TYPE type,
+ short start,
+ short end,
+ PyTypeObject* T=&Type);
+
+ ~KX_SoundActuator();
+
+ void setSoundObject(class SND_SoundObject* soundobject);
+ bool Update(double curtime,double deltatime);
+
+ CValue* GetReplica();
+
+ /* -------------------------------------------------------------------- */
+ /* Python interface --------------------------------------------------- */
+ /* -------------------------------------------------------------------- */
+
+ PyObject* _getattr(char *attr);
+
+ KX_PYMETHOD(KX_SoundActuator,SetFilename);
+ KX_PYMETHOD(KX_SoundActuator,GetFilename);
+ KX_PYMETHOD(KX_SoundActuator,StartSound);
+ KX_PYMETHOD(KX_SoundActuator,PauseSound);
+ KX_PYMETHOD(KX_SoundActuator,StopSound);
+ KX_PYMETHOD(KX_SoundActuator,SetGain);
+ KX_PYMETHOD(KX_SoundActuator,GetGain);
+ KX_PYMETHOD(KX_SoundActuator,SetPitch);
+ KX_PYMETHOD(KX_SoundActuator,GetPitch);
+ KX_PYMETHOD(KX_SoundActuator,SetRollOffFactor);
+ KX_PYMETHOD(KX_SoundActuator,GetRollOffFactor);
+ KX_PYMETHOD(KX_SoundActuator,SetLooping);
+ KX_PYMETHOD(KX_SoundActuator,GetLooping);
+ KX_PYMETHOD(KX_SoundActuator,SetPosition);
+ KX_PYMETHOD(KX_SoundActuator,SetVelocity);
+ KX_PYMETHOD(KX_SoundActuator,SetOrientation);
+};
+#endif //__KX_SOUNDACTUATOR
+
diff --git a/source/gameengine/Ketsji/KX_SumoPhysicsController.cpp b/source/gameengine/Ketsji/KX_SumoPhysicsController.cpp
new file mode 100644
index 00000000000..8b5b9a5d10b
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_SumoPhysicsController.cpp
@@ -0,0 +1,204 @@
+#pragma warning (disable : 4786)
+
+#include "KX_SumoPhysicsController.h"
+#include "SG_Spatial.h"
+#include "SM_Scene.h"
+#include "KX_GameObject.h"
+#include "KX_MotionState.h"
+
+
+
+void KX_SumoPhysicsController::applyImpulse(const MT_Point3& attach, const MT_Vector3& impulse)
+{
+ SumoPhysicsController::applyImpulse(attach[0],attach[1],attach[2],impulse[0],impulse[1],impulse[2]);
+}
+void KX_SumoPhysicsController::RelativeTranslate(const MT_Vector3& dloc,bool local)
+{
+ SumoPhysicsController::RelativeTranslate(dloc[0],dloc[1],dloc[2],local);
+
+}
+void KX_SumoPhysicsController::RelativeRotate(const MT_Matrix3x3& drot,bool local)
+{
+ double oldmat[12];
+ drot.getValue(oldmat);
+ float newmat[9];
+ float *m = &newmat[0];
+ double *orgm = &oldmat[0];
+
+ *m++ = *orgm++;*m++ = *orgm++;*m++ = *orgm++;orgm++;
+ *m++ = *orgm++;*m++ = *orgm++;*m++ = *orgm++;orgm++;
+ *m++ = *orgm++;*m++ = *orgm++;*m++ = *orgm++;orgm++;
+
+ SumoPhysicsController::RelativeRotate(newmat,local);
+}
+
+void KX_SumoPhysicsController::SetLinearVelocity(const MT_Vector3& lin_vel,bool local)
+{
+ SumoPhysicsController::SetLinearVelocity(lin_vel[0],lin_vel[1],lin_vel[2],local);
+
+}
+
+void KX_SumoPhysicsController::SetAngularVelocity(const MT_Vector3& ang_vel,bool local)
+{
+ SumoPhysicsController::SetAngularVelocity(ang_vel[0],ang_vel[1],ang_vel[2],local);
+}
+
+MT_Vector3 KX_SumoPhysicsController::GetVelocity(const MT_Point3& pos)
+{
+
+ float linvel[3];
+ SumoPhysicsController::GetVelocity(pos[0],pos[1],pos[2],linvel[0],linvel[1],linvel[2]);
+
+ return MT_Vector3 (linvel);
+}
+
+MT_Vector3 KX_SumoPhysicsController::GetLinearVelocity()
+{
+ return GetVelocity(MT_Point3(0,0,0));
+
+}
+void KX_SumoPhysicsController::ApplyTorque(const MT_Vector3& torque,bool local)
+{
+ SumoPhysicsController::ApplyTorque(torque[0],torque[1],torque[2],local);
+
+}
+
+void KX_SumoPhysicsController::ApplyForce(const MT_Vector3& force,bool local)
+{
+ SumoPhysicsController::ApplyForce(force[0],force[1],force[2],local);
+}
+
+bool KX_SumoPhysicsController::Update(double time)
+{
+ return SynchronizeMotionStates(time);
+
+}
+
+void KX_SumoPhysicsController::SetSimulatedTime(double time)
+{
+
+}
+
+void KX_SumoPhysicsController::SetSumoTransform(bool nondynaonly)
+{
+ SumoPhysicsController::setSumoTransform(nondynaonly);
+
+}
+
+void KX_SumoPhysicsController::SuspendDynamics()
+{
+ SumoPhysicsController::SuspendDynamics();
+}
+
+void KX_SumoPhysicsController::RestoreDynamics()
+{
+ SumoPhysicsController::RestoreDynamics();
+}
+
+SG_Controller* KX_SumoPhysicsController::GetReplica(SG_Node* destnode)
+{
+
+ PHY_IMotionState* motionstate = new KX_MotionState(destnode);
+
+ KX_SumoPhysicsController* physicsreplica = new KX_SumoPhysicsController(*this);
+
+ //parentcontroller is here be able to avoid collisions between parent/child
+
+ PHY_IPhysicsController* parentctrl = NULL;
+
+ if (destnode != destnode->GetRootSGParent())
+ {
+ KX_GameObject* clientgameobj = (KX_GameObject*) destnode->GetRootSGParent()->GetSGClientObject();
+ if (clientgameobj)
+ {
+ parentctrl = (KX_SumoPhysicsController*)clientgameobj->GetPhysicsController();
+ } else
+ {
+ // it could be a false node, try the children
+ NodeList::const_iterator childit;
+ for (
+ childit = destnode->GetSGChildren().begin();
+ childit!= destnode->GetSGChildren().end();
+ ++childit
+ ) {
+ KX_GameObject* clientgameobj = static_cast<KX_GameObject*>( (*childit)->GetSGClientObject());
+ if (clientgameobj)
+ {
+ parentctrl = (KX_SumoPhysicsController*)clientgameobj->GetPhysicsController();
+ }
+ }
+ }
+ }
+
+ physicsreplica->PostProcessReplica(motionstate,parentctrl);
+
+ return physicsreplica;
+}
+
+
+void KX_SumoPhysicsController::SetObject (SG_IObject* object)
+{
+ SG_Controller::SetObject(object);
+
+ // cheating here...
+ KX_GameObject* gameobj = (KX_GameObject*) object->GetSGClientObject();
+ gameobj->SetPhysicsController(this);
+
+
+}
+
+
+void KX_SumoPhysicsController::setOrientation(const MT_Quaternion& orn)
+{
+ SumoPhysicsController::setOrientation(
+ orn[0],orn[1],orn[2],orn[3]);
+
+}
+void KX_SumoPhysicsController::getOrientation(MT_Quaternion& orn)
+{
+
+ float quat[4];
+
+ SumoPhysicsController::getOrientation(quat[0],quat[1],quat[2],quat[3]);
+
+ orn = MT_Quaternion(quat);
+
+}
+
+void KX_SumoPhysicsController::setPosition(const MT_Point3& pos)
+{
+ SumoPhysicsController::setPosition(pos[0],pos[1],pos[2]);
+
+}
+
+void KX_SumoPhysicsController::setScaling(const MT_Vector3& scaling)
+{
+ SumoPhysicsController::setScaling(scaling[0],scaling[1],scaling[2]);
+
+}
+
+MT_Scalar KX_SumoPhysicsController::GetMass()
+{
+ return SumoPhysicsController::getMass();
+}
+
+MT_Vector3 KX_SumoPhysicsController::getReactionForce()
+{
+ float force[3];
+ SumoPhysicsController::getReactionForce(force[0],force[1],force[2]);
+ return MT_Vector3(force);
+
+}
+
+void KX_SumoPhysicsController::setRigidBody(bool rigid)
+{
+ SumoPhysicsController::setRigidBody(rigid);
+
+}
+
+
+KX_SumoPhysicsController::~KX_SumoPhysicsController()
+{
+
+
+} \ No newline at end of file
diff --git a/source/gameengine/Ketsji/KX_SumoPhysicsController.h b/source/gameengine/Ketsji/KX_SumoPhysicsController.h
new file mode 100644
index 00000000000..b1019b0c19b
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_SumoPhysicsController.h
@@ -0,0 +1,81 @@
+#ifndef __KX_SUMOPHYSICSCONTROLLER_H
+#define __KX_SUMOPHYSICSCONTROLLER_H
+
+#include "PHY_IPhysicsController.h"
+#include "SM_Object.h" // for SM_Callback
+
+/**
+ Physics Controller, a special kind of Scene Graph Transformation Controller.
+ It get's callbacks from Sumo in case a transformation change took place.
+ Each time the scene graph get's updated, the controller get's a chance
+ in the 'Update' method to reflect changed.
+*/
+
+#include "SumoPhysicsController.h"
+#include "KX_IPhysicsController.h"
+
+class KX_SumoPhysicsController : public KX_IPhysicsController,
+ public SumoPhysicsController
+
+{
+
+
+public:
+ KX_SumoPhysicsController(
+ class SM_Scene* sumoScene,
+ DT_SceneHandle solidscene,
+ class SM_Object* sumoObj,
+ class PHY_IMotionState* motionstate
+ ,bool dyna)
+ : SumoPhysicsController(sumoScene,solidscene,sumoObj,motionstate,dyna),
+ KX_IPhysicsController(dyna,NULL)
+ {
+ };
+ virtual ~KX_SumoPhysicsController();
+
+ void applyImpulse(const MT_Point3& attach, const MT_Vector3& impulse);
+ virtual void SetObject (SG_IObject* object);
+
+
+ void RelativeTranslate(const MT_Vector3& dloc,bool local);
+ void RelativeRotate(const MT_Matrix3x3& drot,bool local);
+ void ApplyTorque(const MT_Vector3& torque,bool local);
+ void ApplyForce(const MT_Vector3& force,bool local);
+ MT_Vector3 GetLinearVelocity();
+ MT_Vector3 GetVelocity(const MT_Point3& pos);
+ void SetAngularVelocity(const MT_Vector3& ang_vel,bool local);
+ void SetLinearVelocity(const MT_Vector3& lin_vel,bool local);
+
+ void SuspendDynamics();
+ void RestoreDynamics();
+ virtual void getOrientation(MT_Quaternion& orn);
+ virtual void setOrientation(const MT_Quaternion& orn);
+
+ virtual void setPosition(const MT_Point3& pos);
+ virtual void setScaling(const MT_Vector3& scaling);
+ virtual MT_Scalar GetMass();
+ virtual MT_Vector3 getReactionForce();
+ virtual void setRigidBody(bool rigid);
+
+
+ virtual SG_Controller* GetReplica(class SG_Node* destnode);
+
+
+ void SetSumoTransform(bool nondynaonly);
+ // todo: remove next line !
+ virtual void SetSimulatedTime(double time);
+
+ // call from scene graph to update
+ virtual bool Update(double time);
+
+ void
+ SetOption(
+ int option,
+ int value
+ ){
+ // intentionally empty
+ };
+
+
+};
+#endif //__KX_SUMOPHYSICSCONTROLLER_H
diff --git a/source/gameengine/Ketsji/KX_TimeCategoryLogger.cpp b/source/gameengine/Ketsji/KX_TimeCategoryLogger.cpp
new file mode 100644
index 00000000000..53a47abd77e
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_TimeCategoryLogger.cpp
@@ -0,0 +1,142 @@
+/**
+ * $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 "KX_TimeCategoryLogger.h"
+
+
+KX_TimeCategoryLogger::KX_TimeCategoryLogger(unsigned int maxNumMeasurements)
+: m_maxNumMeasurements(maxNumMeasurements)
+{
+}
+
+
+KX_TimeCategoryLogger::~KX_TimeCategoryLogger(void)
+{
+ DisposeLoggers();
+}
+
+
+void KX_TimeCategoryLogger::SetMaxNumMeasurements(unsigned int maxNumMeasurements)
+{
+ KX_TimeLoggerMap::iterator it;
+ for (it = m_loggers.begin(); it != m_loggers.end(); it++) {
+ it->second->SetMaxNumMeasurements(maxNumMeasurements);
+ }
+ m_maxNumMeasurements = maxNumMeasurements;
+}
+
+
+unsigned int KX_TimeCategoryLogger::GetMaxNumMeasurements(void) const
+{
+ return m_maxNumMeasurements;
+}
+
+
+void KX_TimeCategoryLogger::AddCategory(TimeCategory tc)
+{
+ // Only add if not already present
+ if (m_loggers.find(tc) == m_loggers.end()) {
+ KX_TimeLogger* logger = new KX_TimeLogger(m_maxNumMeasurements);
+ //assert(logger);
+ m_loggers.insert(KX_TimeLoggerMap::value_type(tc, logger));
+ }
+}
+
+
+void KX_TimeCategoryLogger::StartLog(TimeCategory tc, double now, bool endOtherCategories)
+{
+ if (endOtherCategories) {
+ KX_TimeLoggerMap::iterator it;
+ for (it = m_loggers.begin(); it != m_loggers.end(); it++) {
+ if (it->first != tc) {
+ it->second->EndLog(now);
+ }
+ }
+ }
+ //assert(m_loggers[tc] != m_loggers.end());
+ m_loggers[tc]->StartLog(now);
+}
+
+
+void KX_TimeCategoryLogger::EndLog(TimeCategory tc, double now)
+{
+ //assert(m_loggers[tc] != m_loggers.end());
+ m_loggers[tc]->EndLog(now);
+}
+
+
+void KX_TimeCategoryLogger::EndLog(double now)
+{
+ KX_TimeLoggerMap::iterator it;
+ for (it = m_loggers.begin(); it != m_loggers.end(); it++) {
+ it->second->EndLog(now);
+ }
+}
+
+
+void KX_TimeCategoryLogger::NextMeasurement(double now)
+{
+ KX_TimeLoggerMap::iterator it;
+ for (it = m_loggers.begin(); it != m_loggers.end(); it++) {
+ it->second->NextMeasurement(now);
+ }
+}
+
+
+double KX_TimeCategoryLogger::GetAverage(TimeCategory tc)
+{
+ //assert(m_loggers[tc] != m_loggers.end());
+ return m_loggers[tc]->GetAverage();
+}
+
+
+double KX_TimeCategoryLogger::GetAverage(void)
+{
+ double time = 0.;
+
+ KX_TimeLoggerMap::iterator it;
+ for (it = m_loggers.begin(); it != m_loggers.end(); it++) {
+ time += it->second->GetAverage();
+ }
+
+ return time;
+}
+
+
+void KX_TimeCategoryLogger::DisposeLoggers(void)
+{
+ KX_TimeLoggerMap::iterator it;
+ for (it = m_loggers.begin(); it != m_loggers.end(); it++) {
+ delete it->second;
+ }
+}
+
diff --git a/source/gameengine/Ketsji/KX_TimeCategoryLogger.h b/source/gameengine/Ketsji/KX_TimeCategoryLogger.h
new file mode 100644
index 00000000000..ce4c7f37c0f
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_TimeCategoryLogger.h
@@ -0,0 +1,133 @@
+/**
+ * $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_TIME_CATEGORY_LOGGER_H
+#define __KX_TIME_CATEGORY_LOGGER_H
+
+#ifdef WIN32
+#pragma warning (disable:4786) // suppress stl-MSVC debug info warning
+#endif
+
+#include <map>
+
+#include "KX_TimeLogger.h"
+
+/**
+ * Stores and manages time measurements by category.
+ * Categories can be added dynamically.
+ * Average measurements can be established for each separate category
+ * or for all categories together.
+ */
+class KX_TimeCategoryLogger {
+public:
+ typedef int TimeCategory;
+
+ /**
+ * Constructor.
+ * @param maxNumMesasurements Maximum number of measurements stored (> 1).
+ */
+ KX_TimeCategoryLogger(unsigned int maxNumMeasurements = 10);
+
+ /**
+ * Destructor.
+ */
+ virtual ~KX_TimeCategoryLogger(void);
+
+ /**
+ * Changes the maximum number of measurements that can be stored.
+ */
+ virtual void SetMaxNumMeasurements(unsigned int maxNumMeasurements);
+
+ /**
+ * Changes the maximum number of measurements that can be stored.
+ */
+ virtual unsigned int GetMaxNumMeasurements(void) const;
+
+ /**
+ * Adds a category.
+ * @param category The new category.
+ */
+ virtual void AddCategory(TimeCategory tc);
+
+ /**
+ * Starts logging in current measurement for the given category.
+ * @param tc The category to log to.
+ * @param now The current time.
+ * @param endOtherCategories Whether to stop logging to other categories.
+ */
+ virtual void StartLog(TimeCategory tc, double now, bool endOtherCategories = true);
+
+ /**
+ * End logging in current measurement for the given category.
+ * @param tc The category to log to.
+ * @param now The current time.
+ */
+ virtual void EndLog(TimeCategory tc, double now);
+
+ /**
+ * End logging in current measurement for all categories.
+ * @param now The current time.
+ */
+ virtual void EndLog(double now);
+
+ /**
+ * Logs time in next measurement.
+ * @param now The current time.
+ */
+ virtual void NextMeasurement(double now);
+
+ /**
+ * Returns average of all but the current measurement time.
+ * @return The average of all but the current measurement.
+ */
+ virtual double GetAverage(TimeCategory tc);
+
+ /**
+ * Returns average for grand total.
+ */
+ virtual double GetAverage(void);
+
+protected:
+ /**
+ * Disposes loggers.
+ */
+ virtual void DisposeLoggers(void);
+
+ /** Storage for the loggers. */
+ typedef std::map<TimeCategory, KX_TimeLogger*> KX_TimeLoggerMap;
+ KX_TimeLoggerMap m_loggers;
+ /** Maximum number of measurements. */
+ unsigned int m_maxNumMeasurements;
+
+};
+
+#endif // __KX_TIME_CATEGORY_LOGGER_H
diff --git a/source/gameengine/Ketsji/KX_TimeLogger.cpp b/source/gameengine/Ketsji/KX_TimeLogger.cpp
new file mode 100644
index 00000000000..e2114e8d8d7
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_TimeLogger.cpp
@@ -0,0 +1,117 @@
+/**
+ * $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 "KX_TimeLogger.h"
+
+
+
+KX_TimeLogger::KX_TimeLogger(unsigned int maxNumMeasurements)
+: m_maxNumMeasurements(maxNumMeasurements), m_logging(false), m_logStart(0)
+{
+}
+
+
+KX_TimeLogger::~KX_TimeLogger(void)
+{
+}
+
+
+void KX_TimeLogger::SetMaxNumMeasurements(unsigned int maxNumMeasurements)
+{
+ if ((m_maxNumMeasurements != maxNumMeasurements) && maxNumMeasurements) {
+ // Actual removing is done in NextMeasurement()
+ m_maxNumMeasurements = maxNumMeasurements;
+ }
+}
+
+
+unsigned int KX_TimeLogger::GetMaxNumMeasurements(void) const
+{
+ return m_maxNumMeasurements;
+}
+
+
+void KX_TimeLogger::StartLog(double now)
+{
+ if (!m_logging) {
+ m_logging = true;
+ m_logStart = now;
+ }
+}
+
+
+void KX_TimeLogger::EndLog(double now)
+{
+ if (m_logging) {
+ m_logging = false;
+ double time = now - m_logStart;
+ if (m_measurements.size() > 0) {
+ m_measurements[0] += time;
+ }
+ }
+}
+
+
+void KX_TimeLogger::NextMeasurement(double now)
+{
+ // End logging to current measurement
+ EndLog(now);
+
+ // Add a new measurement at the front
+ double m = 0.;
+ m_measurements.push_front(m);
+
+ // Remove measurement if we grow beyond the maximum size
+ if ((m_measurements.size()) > m_maxNumMeasurements) {
+ while (m_measurements.size() > m_maxNumMeasurements) {
+ m_measurements.pop_back();
+ }
+ }
+}
+
+
+
+double KX_TimeLogger::GetAverage(void) const
+{
+ double avg = 0.;
+
+ unsigned int numMeasurements = m_measurements.size();
+ if (numMeasurements > 1) {
+ for (int i = 1; i < numMeasurements; i++) {
+ avg += m_measurements[i];
+ }
+ avg /= (float)numMeasurements - 1;
+ }
+
+ return avg;
+}
+
diff --git a/source/gameengine/Ketsji/KX_TimeLogger.h b/source/gameengine/Ketsji/KX_TimeLogger.h
new file mode 100644
index 00000000000..a802ed1a93a
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_TimeLogger.h
@@ -0,0 +1,107 @@
+/**
+ * $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_TIME_LOGGER_H
+#define __KX_TIME_LOGGER_H
+
+#ifdef WIN32
+#pragma warning (disable:4786) // suppress stl-MSVC debug info warning
+#endif
+
+
+#include <deque>
+
+/**
+ * Stores and manages time measurements.
+ */
+class KX_TimeLogger {
+public:
+ /**
+ * Constructor.
+ * @param maxNumMesasurements Maximum number of measurements stored (>1).
+ */
+ KX_TimeLogger(unsigned int maxNumMeasurements = 10);
+
+ /**
+ * Destructor.
+ */
+ virtual ~KX_TimeLogger(void);
+
+ /**
+ * Changes the maximum number of measurements that can be stored.
+ */
+ virtual void SetMaxNumMeasurements(unsigned int maxNumMeasurements);
+
+ /**
+ * Changes the maximum number of measurements that can be stored.
+ */
+ virtual unsigned int GetMaxNumMeasurements(void) const;
+
+ /**
+ * Starts logging in current measurement.
+ * @param now The current time.
+ */
+ virtual void StartLog(double now);
+
+ /**
+ * End logging in current measurement.
+ * @param now The current time.
+ */
+ virtual void EndLog(double now);
+
+ /**
+ * Logs time in next measurement.
+ * @param now The current time.
+ */
+ virtual void NextMeasurement(double now);
+
+ /**
+ * Returns average of all but the current measurement.
+ * @return The average of all but the current measurement.
+ */
+ virtual double GetAverage(void) const;
+
+protected:
+ /** Storage for the measurements. */
+ std::deque<double> m_measurements;
+
+ /** Maximum number of measurements. */
+ unsigned int m_maxNumMeasurements;
+
+ /** Time at start of logging. */
+ double m_logStart;
+
+ /** State of logging. */
+ bool m_logging;
+};
+
+#endif // __KX_TIME_LOGGER_H
diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.cpp b/source/gameengine/Ketsji/KX_TouchEventManager.cpp
new file mode 100644
index 00000000000..d9848398900
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_TouchEventManager.cpp
@@ -0,0 +1,117 @@
+/**
+ * $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 "KX_TouchEventManager.h"
+
+#include "SCA_ISensor.h"
+#include "KX_TouchSensor.h"
+#include "KX_GameObject.h"
+
+#ifdef PHYSICS_NOT_YET
+
+KX_TouchEventManager::KX_TouchEventManager(class SCA_LogicManager* logicmgr,
+ DT_RespTableHandle resphandle,
+ DT_SceneHandle scenehandle)
+ : SCA_EventManager(TOUCH_EVENTMGR),
+ m_resphandle(resphandle),
+ m_scenehandle(scenehandle),
+ m_logicmgr(logicmgr) {}
+
+void KX_TouchEventManager::RegisterSensor(SCA_ISensor* sensor)
+{
+
+
+ KX_TouchSensor* touchsensor = static_cast<KX_TouchSensor*>(sensor);
+ m_sensors.push_back(touchsensor);
+
+ touchsensor->RegisterSumo();//this,m_resphandle);
+
+ //KX_GameObject* gameobj = ((KX_GameObject*)sensor->GetParent());
+// SM_Object* smobj = touchsensor->GetSumoObject();//gameobj->GetSumoObject();
+// if (smobj)
+// {
+// smobj->calcXform();
+// DT_AddObject(m_scenehandle,
+// smobj->getObjectHandle());
+// }
+}
+
+
+
+void KX_TouchEventManager::EndFrame()
+{
+ vector<SCA_ISensor*>::iterator it;
+ for ( it = m_sensors.begin();
+ !(it==m_sensors.end());it++)
+ {
+ ((KX_TouchSensor*)*it)->EndFrame();
+
+ }
+}
+
+
+
+void KX_TouchEventManager::NextFrame(double curtime,double deltatime)
+{
+ if (m_sensors.size() > 0)
+ {
+ vector<SCA_ISensor*>::iterator it;
+
+ for (it = m_sensors.begin();!(it==m_sensors.end());it++)
+ ((KX_TouchSensor*)*it)->SynchronizeTransform();
+
+ if (DT_Test(m_scenehandle,m_resphandle))
+ int i = 0;
+
+ for (it = m_sensors.begin();!(it==m_sensors.end());it++)
+ (*it)->Activate(m_logicmgr,NULL);
+ }
+}
+
+
+
+void KX_TouchEventManager::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();
+ //SM_Object* smobj = ((KX_TouchSensor*)*i)->GetSumoObject();
+ //DT_RemoveObject(m_scenehandle,
+ // smobj->getObjectHandle());
+ }
+ // remove the sensor forever :)
+ SCA_EventManager::RemoveSensor(sensor);
+}
+
+#endif
diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.h b/source/gameengine/Ketsji/KX_TouchEventManager.h
new file mode 100644
index 00000000000..4575814986f
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_TouchEventManager.h
@@ -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 *****
+ */
+#ifndef __KX_TOUCHEVENTMANAGER
+#define __KX_TOUCHEVENTMANAGER
+
+#include "SCA_EventManager.h"
+#include "KX_TouchSensor.h"
+#include "KX_GameObject.h"
+
+#include <vector>
+using namespace std;
+
+
+class KX_TouchEventManager : public SCA_EventManager
+{
+ class SCA_LogicManager* m_logicmgr;
+
+public:
+ KX_TouchEventManager(class SCA_LogicManager* logicmgr);
+ virtual void NextFrame(double curtime,double deltatime);
+ virtual void EndFrame();
+ virtual void RemoveSensor(class SCA_ISensor* sensor);
+ virtual void RegisterSensor(SCA_ISensor* sensor);
+ SCA_LogicManager* GetLogicManager() { return m_logicmgr;}
+};
+
+#endif //__KX_TOUCHEVENTMANAGER
+
+
+
+
+
+
+
+
+
+
+
diff --git a/source/gameengine/Ketsji/KX_TouchSensor.cpp b/source/gameengine/Ketsji/KX_TouchSensor.cpp
new file mode 100644
index 00000000000..daf344999fc
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_TouchSensor.cpp
@@ -0,0 +1,393 @@
+/**
+ * Senses touch and collision 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 "KX_TouchSensor.h"
+#include "SCA_EventManager.h"
+#include "SCA_LogicManager.h"
+#include "KX_GameObject.h"
+#include "KX_TouchEventManager.h"
+#include <iostream>
+
+#ifdef PHYSICS_NOT_YET
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+void KX_TouchSensor::SynchronizeTransform()
+{
+
+ if (m_sumoObj)
+ {
+ m_sumoObj->setPosition(((KX_GameObject*)GetParent())->NodeGetWorldPosition());
+ m_sumoObj->setOrientation(
+ ((KX_GameObject*)GetParent())->NodeGetWorldOrientation().getRotation()
+ );
+ m_sumoObj->calcXform();
+ }
+
+}
+
+
+void KX_TouchSensor::EndFrame() {
+ m_colliders->ReleaseAndRemoveAll();
+ m_bTriggered = false;
+}
+
+bool KX_TouchSensor::Evaluate(CValue* event)
+{
+ bool result = false;
+
+ if (m_bTriggered != m_bLastTriggered)
+ {
+ m_bLastTriggered = m_bTriggered;
+ if (!m_bTriggered)
+ m_hitObject = NULL;
+ result = true;
+ }
+
+ return result;
+}
+
+KX_TouchSensor::KX_TouchSensor(SCA_EventManager* eventmgr,KX_GameObject* gameobj,SM_Object* sumoObj,bool bFindMaterial,const STR_String& touchedpropname,PyTypeObject* T)
+:SCA_ISensor(gameobj,eventmgr,T),
+m_touchedpropname(touchedpropname),
+m_bFindMaterial(bFindMaterial),
+m_sumoObj(sumoObj),
+m_bCollision(false),
+m_bTriggered(false),
+m_bLastTriggered(false)
+{
+ m_eventmgr = eventmgr;
+ KX_TouchEventManager* touchmgr = (KX_TouchEventManager*) eventmgr;
+
+ m_resptable = touchmgr->GetResponseTable();
+
+ m_solidHandle = m_sumoObj->getObjectHandle();
+
+ m_hitObject = NULL;
+ m_colliders = new CListValue();
+}
+
+
+KX_TouchSensor::~KX_TouchSensor()
+{
+ DT_ClearObjectResponse(m_resptable,m_solidHandle);
+ m_colliders->Release();
+}
+
+void KX_TouchSensor::ReParent(SCA_IObject* parent)
+{
+
+ m_sumoObj = ((KX_GameObject*)parent)->GetSumoObject();
+ m_solidHandle = m_sumoObj->getObjectHandle();
+
+ m_client_info.m_clientobject = NULL;//parent;
+ m_client_info.m_auxilary_info = NULL;
+ SCA_ISensor::ReParent(parent);
+}
+
+
+void KX_TouchSensor::RegisterSumo()
+{
+
+ if (m_sumoObj)
+ {
+ // collision
+ DT_SetObjectResponse(
+ m_resptable,
+ m_solidHandle,
+ collisionResponse,
+ DT_SIMPLE_RESPONSE,
+ this);
+
+ }
+
+}
+
+void KX_TouchSensor::HandleCollision(void* obj1,void* obj2,const DT_CollData * coll_data)
+{
+ KX_TouchEventManager* toucheventmgr = (KX_TouchEventManager*)m_eventmgr;
+ KX_GameObject* parent = (KX_GameObject*)GetParent();
+
+ // need the mapping from SM_Objects to gameobjects now
+
+ SM_ClientObjectInfo* client_info =(SM_ClientObjectInfo*) (obj1 == m_sumoObj?
+ ((SM_Object*)obj2)->getClientObject() :
+ ((SM_Object*)obj1)->getClientObject());
+
+
+ KX_GameObject* gameobj = ( client_info ?
+ (KX_GameObject*)client_info->m_clientobject :
+ NULL);
+
+ if (gameobj && (gameobj != parent))
+ {
+ if (!m_colliders->SearchValue(gameobj))
+ m_colliders->Add(gameobj->AddRef());
+
+ bool found = m_touchedpropname.IsEmpty();
+ if (!found)
+ {
+ if (m_bFindMaterial)
+ {
+ if (client_info->m_auxilary_info)
+ {
+ found = (m_touchedpropname == ((char*)client_info->m_auxilary_info));
+ }
+
+ if (found)
+ {
+ int i=0;
+ }
+
+ } else
+ {
+ found = (gameobj->GetProperty(m_touchedpropname) != NULL);
+ }
+ }
+ if (found)
+ {
+ m_bTriggered = true;
+ m_hitObject = gameobj;
+ }
+
+ }
+
+}
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject KX_TouchSensor::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "KX_TouchSensor",
+ sizeof(KX_TouchSensor),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject KX_TouchSensor::Parents[] = {
+ &KX_TouchSensor::Type,
+ &SCA_ISensor::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef KX_TouchSensor::Methods[] = {
+ {"setProperty",
+ (PyCFunction) KX_TouchSensor::sPySetProperty, METH_VARARGS, SetProperty_doc},
+ {"getProperty",
+ (PyCFunction) KX_TouchSensor::sPyGetProperty, METH_VARARGS, GetProperty_doc},
+ {"getHitObject",
+ (PyCFunction) KX_TouchSensor::sPyGetHitObject, METH_VARARGS, GetHitObject_doc},
+ {"getHitObjectList",
+ (PyCFunction) KX_TouchSensor::sPyGetHitObjectList, METH_VARARGS, GetHitObjectList_doc},
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* KX_TouchSensor::_getattr(char* attr) {
+ _getattr_up(SCA_ISensor);
+}
+
+/* Python API */
+
+/* 1. setProperty */
+char KX_TouchSensor::SetProperty_doc[] =
+"setProperty(name)\n"
+"\t- name: string\n"
+"\tSet the property or material to collide with. Use\n"
+"\tsetTouchMaterial() to switch between properties and\n"
+"\tmaterials.";
+PyObject* KX_TouchSensor::PySetProperty(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ char *nameArg;
+ if (!PyArg_ParseTuple(args, "s", &nameArg)) {
+ return NULL;
+ }
+
+ CValue* prop = GetParent()->FindIdentifier(nameArg);
+
+ if (!prop->IsError()) {
+ m_touchedpropname = nameArg;
+ prop->Release();
+ } else {
+ ; /* not found ... */
+ }
+
+ Py_Return;
+}
+/* 2. getProperty */
+char KX_TouchSensor::GetProperty_doc[] =
+"getProperty(name)\n"
+"\tReturns the property or material to collide with. Use\n"
+"\tgetTouchMaterial() to find out whether this sensor\n"
+"\tlooks for properties or materials.";
+PyObject* KX_TouchSensor::PyGetProperty(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ return PyString_FromString(m_touchedpropname);
+}
+
+char KX_TouchSensor::GetHitObject_doc[] =
+"getHitObject()\n"
+;
+PyObject* KX_TouchSensor::PyGetHitObject(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ /* to do: do Py_IncRef if the object is already known in Python */
+ /* otherwise, this leaks memory */
+ if (m_hitObject)
+ {
+ return m_hitObject->AddRef();
+ }
+ Py_Return;
+}
+
+char KX_TouchSensor::GetHitObjectList_doc[] =
+"getHitObjectList()\n"
+"\tReturn a list of the objects this object collided with,\n"
+"\tbut only those matching the property/material condition.\n";
+PyObject* KX_TouchSensor::PyGetHitObjectList(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+
+ /* to do: do Py_IncRef if the object is already known in Python */
+ /* otherwise, this leaks memory */
+
+ if ( m_touchedpropname.IsEmpty() ) {
+ return m_colliders->AddRef();
+ } else {
+ CListValue* newList = new CListValue();
+ int i = 0;
+ while (i < m_colliders->GetCount()) {
+ if (m_bFindMaterial) {
+ /* need to associate the CValues from the list to material
+ * names. The collider list _should_ contains only
+ * KX_GameObjects. I am loathe to cast them, though... The
+ * material name must be retrieved from Sumo. To a Sumo
+ * object, a client-info block is attached. This block
+ * contains the material name.
+ * - this also doesn't work (obviously) for multi-materials...
+ */
+ KX_GameObject* gameob = (KX_GameObject*) m_colliders->GetValue(i);
+ SM_Object* smob = (SM_Object*) gameob->GetSumoObject();
+
+ if (smob) {
+ SM_ClientObjectInfo* cl_inf = (SM_ClientObjectInfo*) smob->getClientObject();
+
+ if (m_touchedpropname == ((char*)cl_inf->m_auxilary_info)) {
+ newList->Add(m_colliders->GetValue(i)->AddRef());
+ }
+ }
+
+ } else {
+ CValue* val = m_colliders->GetValue(i)->FindIdentifier(m_touchedpropname);
+ if (!val->IsError()) {
+ newList->Add(m_colliders->GetValue(i)->AddRef());
+ val->Release();
+ }
+ }
+
+ i++;
+ }
+ return newList->AddRef();
+ }
+
+}
+
+/* 5. getTouchMaterial */
+char KX_TouchSensor::GetTouchMaterial_doc[] =
+"getTouchMaterial()\n"
+"\tReturns KX_TRUE if this sensor looks for a specific material,\n"
+"\tKX_FALSE if it looks for a specific property.\n" ;
+PyObject* KX_TouchSensor::PyGetTouchMaterial(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ int retval = 0;
+
+ if (m_bFindMaterial) {
+ retval = KX_TRUE;
+ } else {
+ retval = KX_FALSE;
+ }
+
+ return PyInt_FromLong(retval);
+}
+
+/* 6. setTouchMaterial */
+char KX_TouchSensor::SetTouchMaterial_doc[] =
+"setTouchMaterial(flag)\n"
+"\t- flag: KX_TRUE or KX_FALSE.\n"
+"\tSet flag to KX_TRUE to switch on positive pulse mode,\n"
+"\tKX_FALSE to switch off positive pulse mode.\n" ;
+PyObject* KX_TouchSensor::PySetTouchMaterial(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int pulseArg = 0;
+
+ if(!PyArg_ParseTuple(args, "i", &pulseArg)) {
+ return NULL;
+ }
+
+ if (pulseArg == KX_TRUE) {
+ m_bFindMaterial = true;
+ } else if (pulseArg == KX_FALSE){
+ m_bFindMaterial = false;
+ } else {
+ ; /* internal error */
+ }
+
+ Py_Return;
+}
+
+#endif //#ifdef PHYSICS_NOT_YET
+
+/* eof */
diff --git a/source/gameengine/Ketsji/KX_TouchSensor.h b/source/gameengine/Ketsji/KX_TouchSensor.h
new file mode 100644
index 00000000000..123f7041968
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_TouchSensor.h
@@ -0,0 +1,146 @@
+/**
+ * Senses touch and collision 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_TOUCHSENSOR
+#define __KX_TOUCHSENSOR
+
+#include "SCA_ISensor.h"
+#include "ListValue.h"
+
+#include "KX_ClientObjectInfo.h"
+
+class KX_TouchSensor : public SCA_ISensor
+{
+protected:
+ Py_Header;
+
+ /**
+ * The sensor should only look for objects with this property.
+ */
+ STR_String m_touchedpropname;
+ bool m_bFindMaterial;
+ class SCA_EventManager* m_eventmgr;
+
+ //class SM_Object* m_sumoObj;
+ //DT_ObjectHandle m_solidHandle;
+ //SM_ClientObjectInfo m_client_info;
+ //DT_RespTableHandle m_resptable;
+
+
+ bool m_bCollision;
+ bool m_bTriggered;
+ bool m_bLastTriggered;
+ SCA_IObject* m_hitObject;
+ class CListValue* m_colliders;
+
+public:
+ KX_TouchSensor(class SCA_EventManager* eventmgr,
+ class KX_GameObject* gameobj,
+ class SM_Object* sumoObj,
+ bool fFindMaterial,
+ const STR_String& touchedpropname,
+ PyTypeObject* T=&Type) ;
+ virtual ~KX_TouchSensor();
+
+ virtual CValue* GetReplica() {
+ KX_TouchSensor* replica = new KX_TouchSensor(*this);
+ replica->m_colliders = new CListValue();
+ replica->m_bCollision = false;
+ replica->m_bTriggered= false;
+ replica->m_hitObject = NULL;
+ replica->m_bLastTriggered = false;
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+ return replica;
+ };
+ virtual void SynchronizeTransform();
+ virtual bool Evaluate(CValue* event);
+ virtual void ReParent(SCA_IObject* parent);
+
+/* static void collisionResponse(void *client_data,
+ void *object1,
+ void *object2,
+ const DT_CollData *coll_data) {
+ class KX_TouchSensor* sensor = (class KX_TouchSensor*) client_data;
+ sensor->HandleCollision(object1,object2,coll_data);
+ }
+
+
+
+ void RegisterSumo();
+
+ virtual void HandleCollision(void* obj1,void* obj2,
+ const DT_CollData * coll_data);
+
+
+ // SM_Object* GetSumoObject() { return m_sumoObj; };
+
+ */
+
+ virtual bool IsPositiveTrigger() {
+ bool result = m_bTriggered;
+ if (m_invert) result = !result;
+ return result;
+ }
+
+
+ void EndFrame();
+
+ // todo: put some info for collision maybe
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(char *attr);
+
+ /* 1. setProperty */
+ KX_PYMETHOD_DOC(KX_TouchSensor,SetProperty);
+ /* 2. getProperty */
+ KX_PYMETHOD_DOC(KX_TouchSensor,GetProperty);
+ /* 3. getHitObject */
+ KX_PYMETHOD_DOC(KX_TouchSensor,GetHitObject);
+ /* 4. getHitObject */
+ KX_PYMETHOD_DOC(KX_TouchSensor,GetHitObjectList);
+ /* 5. getTouchMaterial */
+ KX_PYMETHOD_DOC(KX_TouchSensor,GetTouchMaterial);
+ /* 6. setTouchMaterial */
+ KX_PYMETHOD_DOC(KX_TouchSensor,SetTouchMaterial);
+
+};
+
+#endif //__KX_TOUCHSENSOR
+
+
+
diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.cpp b/source/gameengine/Ketsji/KX_TrackToActuator.cpp
new file mode 100644
index 00000000000..647ffb447aa
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_TrackToActuator.cpp
@@ -0,0 +1,487 @@
+//
+// Replace the mesh for this actuator's parent
+//
+// $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 *****
+
+// todo: not all trackflags / upflags are implemented/tested !
+// m_trackflag is used to determine the forward tracking direction
+// m_upflag for the up direction
+// normal situation is +y for forward, +z for up
+
+#include "MT_Scalar.h"
+#include "SCA_IActuator.h"
+#include "KX_TrackToActuator.h"
+#include "SCA_IScene.h"
+#include "SCA_LogicManager.h"
+#include <math.h>
+#include <iostream>
+#include "KX_GameObject.h"
+
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+
+
+KX_TrackToActuator::KX_TrackToActuator(SCA_IObject *gameobj,
+ SCA_IObject *ob,
+ int time,
+ bool allow3D,
+ int trackflag,
+ int upflag,
+ PyTypeObject* T)
+ :
+ SCA_IActuator(gameobj, T)
+{
+ m_time = time;
+ m_allow3D = allow3D;
+ m_object = ob;
+ m_trackflag = trackflag;
+ m_upflag = upflag;
+} /* End of constructor */
+
+
+
+/* old function from Blender */
+MT_Matrix3x3 EulToMat3(float *eul)
+{
+ MT_Matrix3x3 mat;
+ float ci, cj, ch, si, sj, sh, cc, cs, sc, ss;
+
+ ci = cos(eul[0]);
+ cj = cos(eul[1]);
+ ch = cos(eul[2]);
+ si = sin(eul[0]);
+ sj = sin(eul[1]);
+ sh = sin(eul[2]);
+ cc = ci*ch;
+ cs = ci*sh;
+ sc = si*ch;
+ ss = si*sh;
+
+ mat[0][0] = cj*ch;
+ mat[1][0] = sj*sc-cs;
+ mat[2][0] = sj*cc+ss;
+ mat[0][1] = cj*sh;
+ mat[1][1] = sj*ss+cc;
+ mat[2][1] = sj*cs-sc;
+ mat[0][2] = -sj;
+ mat[1][2] = cj*si;
+ mat[2][2] = cj*ci;
+
+ return mat;
+}
+
+
+
+/* old function from Blender */
+void Mat3ToEul(MT_Matrix3x3 mat, float *eul)
+{
+ MT_Scalar cy;
+
+ cy = sqrt(mat[0][0]*mat[0][0] + mat[0][1]*mat[0][1]);
+
+ if (cy > 16.0*FLT_EPSILON) {
+ eul[0] = atan2(mat[1][2], mat[2][2]);
+ eul[1] = atan2(-mat[0][2], cy);
+ eul[2] = atan2(mat[0][1], mat[0][0]);
+ } else {
+ eul[0] = atan2(-mat[2][1], mat[1][1]);
+ eul[1] = atan2(-mat[0][2], cy);
+ eul[2] = 0.0;
+ }
+}
+
+
+
+/* old function from Blender */
+void compatible_eulFast(float *eul, float *oldrot)
+{
+ float dx, dy, dz;
+
+ /* verschillen van ong 360 graden corrigeren */
+
+ dx= eul[0] - oldrot[0];
+ dy= eul[1] - oldrot[1];
+ dz= eul[2] - oldrot[2];
+
+ if( fabs(dx) > 5.1) {
+ if(dx > 0.0) eul[0] -= MT_2_PI; else eul[0]+= MT_2_PI;
+ }
+ if( fabs(dy) > 5.1) {
+ if(dy > 0.0) eul[1] -= MT_2_PI; else eul[1]+= MT_2_PI;
+ }
+ if( fabs(dz) > 5.1 ) {
+ if(dz > 0.0) eul[2] -= MT_2_PI; else eul[2]+= MT_2_PI;
+ }
+}
+
+
+
+MT_Matrix3x3 matrix3x3_interpol(MT_Matrix3x3 oldmat, MT_Matrix3x3 mat, int m_time)
+{
+ float eul[3], oldeul[3];
+
+ Mat3ToEul(oldmat, oldeul);
+ Mat3ToEul(mat, eul);
+ compatible_eulFast(eul, oldeul);
+
+ eul[0]= (m_time*oldeul[0] + eul[0])/(1.0+m_time);
+ eul[1]= (m_time*oldeul[1] + eul[1])/(1.0+m_time);
+ eul[2]= (m_time*oldeul[2] + eul[2])/(1.0+m_time);
+
+ return EulToMat3(eul);
+}
+
+
+
+KX_TrackToActuator::~KX_TrackToActuator()
+{
+ // there's nothing to be done here, really....
+} /* end of destructor */
+
+
+
+bool KX_TrackToActuator::Update(double curtime,double deltatime)
+{
+ bool result = false;
+ bool bNegativeEvent = IsNegativeEvent();
+ RemoveAllEvents();
+
+ if (bNegativeEvent)
+ {
+ // do nothing on negative events
+ }
+ else if (m_object)
+ {
+ KX_GameObject* curobj = (KX_GameObject*) GetParent();
+ MT_Vector3 dir = ((KX_GameObject*)m_object)->NodeGetWorldPosition() - curobj->NodeGetWorldPosition();
+ dir.normalize();
+ MT_Vector3 up(0,0,1);
+
+
+#ifdef DSADSA
+ switch (m_upflag)
+ {
+ case 0:
+ {
+ up = MT_Vector3(1.0,0,0);
+ break;
+ }
+ case 1:
+ {
+ up = MT_Vector3(0,1.0,0);
+ break;
+ }
+ case 2:
+ default:
+ {
+ up = MT_Vector3(0,0,1.0);
+ }
+ }
+#endif
+ if (m_allow3D)
+ {
+ up = (up - up.dot(dir) * dir).normalized();
+
+ }
+ else
+ {
+ dir = (dir - up.dot(dir)*up).normalized();
+ }
+
+ MT_Vector3 left;
+ MT_Matrix3x3 mat;
+
+ switch (m_trackflag)
+ {
+ case 0: // TRACK X
+ {
+ // (1.0 , 0.0 , 0.0 ) x direction is forward, z (0.0 , 0.0 , 1.0 ) up
+ left = dir.normalized();
+ dir = (left.cross(up)).normalized();
+ mat.setValue (
+ left[0], dir[0],up[0],
+ left[1], dir[1],up[1],
+ left[2], dir[2],up[2]
+ );
+
+ break;
+ };
+ case 1: // TRACK Y
+ {
+ // (0.0 , 1.0 , 0.0 ) y direction is forward, z (0.0 , 0.0 , 1.0 ) up
+ left = (dir.cross(up)).normalized();
+ mat.setValue (
+ left[0], dir[0],up[0],
+ left[1], dir[1],up[1],
+ left[2], dir[2],up[2]
+ );
+
+ break;
+ }
+
+ case 2: // track Z
+ {
+ left = up.normalized();
+ up = dir.normalized();
+ dir = left;
+ left = (dir.cross(up)).normalized();
+ mat.setValue (
+ left[0], dir[0],up[0],
+ left[1], dir[1],up[1],
+ left[2], dir[2],up[2]
+ );
+ break;
+ }
+
+ case 3: // TRACK -X
+ {
+ // (1.0 , 0.0 , 0.0 ) x direction is forward, z (0.0 , 0.0 , 1.0 ) up
+ left = -dir.normalized();
+ dir = -(left.cross(up)).normalized();
+ mat.setValue (
+ left[0], dir[0],up[0],
+ left[1], dir[1],up[1],
+ left[2], dir[2],up[2]
+ );
+
+ break;
+ };
+ case 4: // TRACK -Y
+ {
+ // (0.0 , -1.0 , 0.0 ) -y direction is forward, z (0.0 , 0.0 , 1.0 ) up
+ left = (-dir.cross(up)).normalized();
+ mat.setValue (
+ left[0], -dir[0],up[0],
+ left[1], -dir[1],up[1],
+ left[2], -dir[2],up[2]
+ );
+ break;
+ }
+ case 5: // track -Z
+ {
+ left = up.normalized();
+ up = -dir.normalized();
+ dir = left;
+ left = (dir.cross(up)).normalized();
+ mat.setValue (
+ left[0], dir[0],up[0],
+ left[1], dir[1],up[1],
+ left[2], dir[2],up[2]
+ );
+
+ break;
+ }
+
+ default:
+ {
+ // (1.0 , 0.0 , 0.0 ) -x direction is forward, z (0.0 , 0.0 , 1.0 ) up
+ left = -dir.normalized();
+ dir = -(left.cross(up)).normalized();
+ mat.setValue (
+ left[0], dir[0],up[0],
+ left[1], dir[1],up[1],
+ left[2], dir[2],up[2]
+ );
+ }
+ }
+
+ MT_Matrix3x3 oldmat;
+ oldmat= curobj->NodeGetWorldOrientation();
+
+ /* erwin should rewrite this! */
+ mat= matrix3x3_interpol(oldmat, mat, m_time);
+
+ curobj->NodeSetLocalOrientation(mat);
+
+ //cout << "\n TrackTo!";
+ result = true;
+ }
+
+ return result;
+}
+
+
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject KX_TrackToActuator::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "KX_TrackToActuator",
+ sizeof(KX_TrackToActuator),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+
+
+PyParentObject KX_TrackToActuator::Parents[] = {
+ &KX_TrackToActuator::Type,
+ &SCA_IActuator::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+
+
+PyMethodDef KX_TrackToActuator::Methods[] = {
+ {"setObject", (PyCFunction) KX_TrackToActuator::sPySetObject, METH_VARARGS, SetObject_doc},
+ {"getObject", (PyCFunction) KX_TrackToActuator::sPyGetObject, METH_VARARGS, GetObject_doc},
+ {"setTime", (PyCFunction) KX_TrackToActuator::sPySetTime, METH_VARARGS, SetTime_doc},
+ {"getTime", (PyCFunction) KX_TrackToActuator::sPyGetTime, METH_VARARGS, GetTime_doc},
+ {"setUse3D", (PyCFunction) KX_TrackToActuator::sPySetUse3D, METH_VARARGS, SetUse3D_doc},
+ {"getUse3D", (PyCFunction) KX_TrackToActuator::sPyGetUse3D, METH_VARARGS, GetUse3D_doc},
+ {NULL,NULL} //Sentinel
+};
+
+
+
+PyObject* KX_TrackToActuator::_getattr(char* attr)
+{
+ _getattr_up(SCA_IActuator);
+}
+
+
+
+/* 1. setObject */
+char KX_TrackToActuator::SetObject_doc[] =
+"setObject(object)\n"
+"\t- object: string\n"
+"\tSet the object to track with the parent of this actuator.\n";
+PyObject* KX_TrackToActuator::PySetObject(PyObject* self, PyObject* args, PyObject* kwds) {
+ char* nameArg;
+
+ if (!PyArg_ParseTuple(args, "s", &nameArg)) {
+ return NULL;
+ }
+ CValue* gameobj = SCA_ILogicBrick::m_sCurrentLogicManager->GetGameObjectByName(STR_String(nameArg));
+
+ m_object= (SCA_IObject*)gameobj;
+
+ Py_Return;
+}
+
+
+
+/* 2. getObject */
+char KX_TrackToActuator::GetObject_doc[] =
+"getObject()\n"
+"\tReturns the object to track with the parent of this actuator.\n";
+PyObject* KX_TrackToActuator::PyGetObject(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return PyString_FromString(m_object->GetName());
+}
+
+
+
+/* 3. setTime */
+char KX_TrackToActuator::SetTime_doc[] =
+"setTime(time)\n"
+"\t- time: integer\n"
+"\tSet the time in frames with which to delay the tracking motion.\n";
+PyObject* KX_TrackToActuator::PySetTime(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int timeArg;
+
+ if (!PyArg_ParseTuple(args, "i", &timeArg))
+ {
+ return NULL;
+ }
+
+ m_time= timeArg;
+
+ Py_Return;
+}
+
+
+
+/* 4.getTime */
+char KX_TrackToActuator::GetTime_doc[] =
+"getTime()\n"
+"\t- time: integer\n"
+"\tReturn the time in frames with which the tracking motion is delayed.\n";
+PyObject* KX_TrackToActuator::PyGetTime(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return PyInt_FromLong(m_time);
+}
+
+
+
+/* 5. getUse3D */
+char KX_TrackToActuator::GetUse3D_doc[] =
+"getUse3D()\n"
+"\tReturns 1 if the motion is allowed to extend in the z-direction.\n";
+PyObject* KX_TrackToActuator::PyGetUse3D(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return PyInt_FromLong(!(m_allow3D == 0));
+}
+
+
+
+/* 6. setUse3D */
+char KX_TrackToActuator::SetUse3D_doc[] =
+"setUse3D(value)\n"
+"\t- value: 0 or 1\n"
+"\tSet to 1 to allow the tracking motion to extend in the z-direction,\n"
+"\tset to 0 to lock the tracking motion to the x-y plane.\n";
+PyObject* KX_TrackToActuator::PySetUse3D(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int boolArg;
+
+ if (!PyArg_ParseTuple(args, "i", &boolArg)) {
+ return NULL;
+ }
+
+ m_allow3D = !(boolArg == 0);
+
+ Py_Return;
+}
+
+/* eof */
diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.h b/source/gameengine/Ketsji/KX_TrackToActuator.h
new file mode 100644
index 00000000000..cbb9892706e
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_TrackToActuator.h
@@ -0,0 +1,85 @@
+//
+// Add object to the game world on action of this actuator
+//
+// $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_TrackToActuator
+#define __KX_TrackToActuator
+
+#include "SCA_IActuator.h"
+#include "SCA_IObject.h"
+
+class KX_TrackToActuator : public SCA_IActuator
+{
+ Py_Header;
+ // Object reference. Actually, we use the object's 'life'
+ SCA_IObject* m_object;
+ // 3d toggle
+ bool m_allow3D;
+ // time field
+ int m_time;
+ int m_trackTime;
+ int m_trackflag;
+ int m_upflag;
+ public:
+ KX_TrackToActuator(SCA_IObject* gameobj, SCA_IObject *ob, int time,
+ bool threedee,int trackflag,int upflag, PyTypeObject* T=&Type);
+ virtual ~KX_TrackToActuator();
+ virtual CValue* GetReplica() {
+ KX_TrackToActuator* replica = new KX_TrackToActuator(*this);
+ replica->ProcessReplica();
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+ return replica;
+ };
+
+ virtual bool Update(double curtime,double deltatime);
+
+ /* Python part */
+ virtual PyObject* _getattr(char *attr);
+
+ /* 1. setObject */
+ KX_PYMETHOD_DOC(KX_TrackToActuator,SetObject);
+ /* 2. getObject */
+ KX_PYMETHOD_DOC(KX_TrackToActuator,GetObject);
+ /* 3. setTime */
+ KX_PYMETHOD_DOC(KX_TrackToActuator,SetTime);
+ /* 4. getTime */
+ KX_PYMETHOD_DOC(KX_TrackToActuator,GetTime);
+ /* 5. getUse3D */
+ KX_PYMETHOD_DOC(KX_TrackToActuator,GetUse3D);
+ /* 6. setUse3D */
+ KX_PYMETHOD_DOC(KX_TrackToActuator,SetUse3D);
+
+}; /* end of class KX_TrackToActuator : public KX_EditObjectActuator */
+
+#endif
diff --git a/source/gameengine/Ketsji/KX_VertexProxy.cpp b/source/gameengine/Ketsji/KX_VertexProxy.cpp
new file mode 100644
index 00000000000..2f61ef7a630
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_VertexProxy.cpp
@@ -0,0 +1,217 @@
+/**
+ * $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 "KX_VertexProxy.h"
+
+#include "RAS_TexVert.h"
+
+
+PyTypeObject KX_VertexProxy::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "KX_VertexProxy",
+ sizeof(KX_VertexProxy),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject KX_VertexProxy::Parents[] = {
+ &KX_VertexProxy::Type,
+ &SCA_IObject::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef KX_VertexProxy::Methods[] = {
+{"getXYZ", (PyCFunction)KX_VertexProxy::sPyGetXYZ,METH_VARARGS},
+{"setXYZ", (PyCFunction)KX_VertexProxy::sPySetXYZ,METH_VARARGS},
+{"getUV", (PyCFunction)KX_VertexProxy::sPyGetUV,METH_VARARGS},
+{"setUV", (PyCFunction)KX_VertexProxy::sPySetUV,METH_VARARGS},
+{"getRGBA", (PyCFunction)KX_VertexProxy::sPyGetRGBA,METH_VARARGS},
+{"setRGBA", (PyCFunction)KX_VertexProxy::sPySetRGBA,METH_VARARGS},
+{"getNormal", (PyCFunction)KX_VertexProxy::sPyGetNormal,METH_VARARGS},
+{"setNormal", (PyCFunction)KX_VertexProxy::sPySetNormal,METH_VARARGS},
+ {NULL,NULL} //Sentinel
+};
+
+PyObject*
+KX_VertexProxy::_getattr(char* attr)
+{
+ _getattr_up(SCA_IObject);
+}
+
+
+
+KX_VertexProxy::KX_VertexProxy(RAS_TexVert* vertex)
+:m_vertex(vertex)
+{
+
+}
+
+KX_VertexProxy::~KX_VertexProxy()
+{
+
+}
+
+
+
+// stuff for cvalue related things
+CValue* KX_VertexProxy::Calc(VALUE_OPERATOR op, CValue *val) { return NULL;}
+CValue* KX_VertexProxy::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val) { return NULL;}
+STR_String sVertexName="vertex";
+const STR_String & KX_VertexProxy::GetText() {return sVertexName;};
+float KX_VertexProxy::GetNumber() { return -1;}
+STR_String KX_VertexProxy::GetName() { return sVertexName;}
+void KX_VertexProxy::SetName(STR_String name) { };
+CValue* KX_VertexProxy::GetReplica() { return NULL;}
+void KX_VertexProxy::ReplicaSetName(STR_String name) {};
+
+
+// stuff for python integration
+
+PyObject* KX_VertexProxy::PyGetXYZ(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+
+ MT_Point3 pos = m_vertex->getLocalXYZ();
+
+ PyObject* resultlist = PyList_New(3);
+ int index;
+ for (index=0;index<3;index++)
+ {
+ PyList_SetItem(resultlist,index,PyFloat_FromDouble(pos[index]));
+ }
+
+ return resultlist;
+
+}
+
+PyObject* KX_VertexProxy::PySetXYZ(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+
+ MT_Point3 pos = ConvertPythonVectorArg(args);
+ m_vertex->SetXYZ(pos);
+
+
+ Py_Return;
+}
+
+PyObject* KX_VertexProxy::PyGetNormal(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+
+ const short* shortnormal = m_vertex->getNormal();
+ MT_Vector3 normal(shortnormal[0],shortnormal[1],shortnormal[2]);
+ normal.normalize();
+
+ PyObject* resultlist = PyList_New(3);
+ int index;
+ for (index=0;index<3;index++)
+ {
+ PyList_SetItem(resultlist,index,PyFloat_FromDouble(normal[index]));
+ }
+
+ return resultlist;
+
+}
+
+PyObject* KX_VertexProxy::PySetNormal(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ MT_Point3 normal = ConvertPythonVectorArg(args);
+ m_vertex->SetNormal(normal);
+ Py_Return;
+}
+
+
+PyObject* KX_VertexProxy::PyGetRGBA(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ int rgba = m_vertex->getRGBA();
+ return PyInt_FromLong(rgba);
+}
+
+PyObject* KX_VertexProxy::PySetRGBA(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ int rgba;
+ if (PyArg_ParseTuple(args,"i",&rgba))
+ {
+ m_vertex->SetRGBA(rgba);
+ }
+ Py_Return;
+}
+
+
+PyObject* KX_VertexProxy::PyGetUV(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ MT_Vector2 uv = m_vertex->getUV1();
+ PyObject* resultlist = PyList_New(2);
+ int index;
+ for (index=0;index<2;index++)
+ {
+ PyList_SetItem(resultlist,index,PyFloat_FromDouble(uv[index]));
+ }
+
+ return resultlist;
+
+}
+
+PyObject* KX_VertexProxy::PySetUV(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ MT_Point3 uv = ConvertPythonVectorArg(args);
+ m_vertex->SetUV(MT_Point2(uv[0],uv[1]));
+ Py_Return;
+}
+
+
+
diff --git a/source/gameengine/Ketsji/KX_VertexProxy.h b/source/gameengine/Ketsji/KX_VertexProxy.h
new file mode 100644
index 00000000000..f23a2d6941c
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_VertexProxy.h
@@ -0,0 +1,70 @@
+/**
+ * $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_VERTEXPROXY
+#define __KX_VERTEXPROXY
+
+#include "SCA_IObject.h"
+
+class KX_VertexProxy : public SCA_IObject
+{
+ Py_Header;
+
+ class RAS_TexVert* m_vertex;
+public:
+ KX_VertexProxy(class RAS_TexVert* vertex);
+ virtual ~KX_VertexProxy();
+
+ // stuff for cvalue related things
+ CValue* Calc(VALUE_OPERATOR op, CValue *val) ;
+ CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val);
+ const STR_String & GetText();
+ float GetNumber();
+ STR_String GetName();
+ void SetName(STR_String name); // Set the name of the value
+ void ReplicaSetName(STR_String name);
+ CValue* GetReplica();
+
+
+// stuff for python integration
+ virtual PyObject* _getattr(char *attr);
+
+ KX_PYMETHOD(KX_VertexProxy,GetXYZ);
+ KX_PYMETHOD(KX_VertexProxy,SetXYZ);
+ KX_PYMETHOD(KX_VertexProxy,GetUV);
+ KX_PYMETHOD(KX_VertexProxy,SetUV);
+ KX_PYMETHOD(KX_VertexProxy,GetRGBA);
+ KX_PYMETHOD(KX_VertexProxy,SetRGBA);
+ KX_PYMETHOD(KX_VertexProxy,GetNormal);
+ KX_PYMETHOD(KX_VertexProxy,SetNormal);
+
+};
+#endif //__KX_VERTEXPROXY
diff --git a/source/gameengine/Ketsji/KX_VisibilityActuator.cpp b/source/gameengine/Ketsji/KX_VisibilityActuator.cpp
new file mode 100644
index 00000000000..c39775f4391
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_VisibilityActuator.cpp
@@ -0,0 +1,161 @@
+/*
+ * $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 *****
+ * Actuator to toggle visibility/invisibility of objects
+ */
+
+#include "KX_VisibilityActuator.h"
+#include "KX_GameObject.h"
+
+KX_VisibilityActuator::KX_VisibilityActuator(
+ SCA_IObject* gameobj,
+ bool visible,
+ PyTypeObject* T
+ )
+ : SCA_IActuator(gameobj,T),
+ m_visible(visible)
+{
+ // intentionally empty
+}
+
+KX_VisibilityActuator::~KX_VisibilityActuator(
+ void
+ )
+{
+ // intentionally empty
+}
+
+CValue*
+KX_VisibilityActuator::GetReplica(
+ void
+ )
+{
+ KX_VisibilityActuator* replica = new KX_VisibilityActuator(*this);
+ replica->ProcessReplica();
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+ return replica;
+}
+
+bool
+KX_VisibilityActuator::Update(
+ double curtime,
+ double deltatime
+ )
+{
+ bool bNegativeEvent = IsNegativeEvent();
+
+ RemoveAllEvents();
+ if (bNegativeEvent) return false;
+
+ KX_GameObject *obj = (KX_GameObject*) GetParent();
+
+ obj->SetVisible(m_visible);
+ obj->MarkVisible();
+
+ return true;
+}
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject
+KX_VisibilityActuator::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "KX_VisibilityActuator",
+ sizeof(KX_VisibilityActuator),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject
+KX_VisibilityActuator::Parents[] = {
+ &KX_VisibilityActuator::Type,
+ &SCA_IActuator::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef
+KX_VisibilityActuator::Methods[] = {
+ {"set", (PyCFunction) KX_VisibilityActuator::sPySetVisible,
+ METH_VARARGS, SetVisible_doc},
+ {NULL,NULL} //Sentinel
+};
+
+PyObject*
+KX_VisibilityActuator::_getattr(
+ char* attr
+ )
+{
+ _getattr_up(SCA_IActuator);
+};
+
+
+
+/* set visibility ---------------------------------------------------------- */
+char
+KX_VisibilityActuator::SetVisible_doc[] =
+"setVisible(visible?)\n"
+"\t - visible? : Make the object visible? (KX_TRUE, KX_FALSE)"
+"\tSet the properties of the actuator.\n";
+PyObject*
+
+KX_VisibilityActuator::PySetVisible(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ int vis;
+
+ if(!PyArg_ParseTuple(args, "i", &vis)) {
+ return NULL;
+ }
+
+ m_visible = PyArgToBool(vis);
+
+ Py_Return;
+}
+
+
diff --git a/source/gameengine/Ketsji/KX_VisibilityActuator.h b/source/gameengine/Ketsji/KX_VisibilityActuator.h
new file mode 100644
index 00000000000..1c079eee967
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_VisibilityActuator.h
@@ -0,0 +1,80 @@
+/*
+ * $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 *****
+ * Actuator to toggle visibility/invisibility of objects
+ */
+
+#ifndef __KX_VISIBILITYACTUATOR
+#define __KX_VISIBILITYACTUATOR
+
+#include "SCA_IActuator.h"
+
+class KX_VisibilityActuator : public SCA_IActuator
+{
+ Py_Header;
+
+ /** Make visible? */
+ bool m_visible;
+
+ public:
+
+ KX_VisibilityActuator(
+ SCA_IObject* gameobj,
+ bool visible,
+ PyTypeObject* T=&Type
+ );
+
+ virtual
+ ~KX_VisibilityActuator(
+ void
+ );
+
+ virtual CValue*
+ GetReplica(
+ void
+ );
+
+ virtual bool
+ Update(
+ double curtime,
+ double deltatime
+ );
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(char *attr);
+ //KX_PYMETHOD_DOC
+ KX_PYMETHOD_DOC(KX_VisibilityActuator,SetVisible);
+
+};
+
+#endif
diff --git a/source/gameengine/Ketsji/KX_WorldInfo.cpp b/source/gameengine/Ketsji/KX_WorldInfo.cpp
new file mode 100644
index 00000000000..4c1884572e5
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_WorldInfo.cpp
@@ -0,0 +1,38 @@
+/**
+ * $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 "KX_WorldInfo.h"
+
+
+KX_WorldInfo::~KX_WorldInfo()
+{
+}
+
diff --git a/source/gameengine/Ketsji/KX_WorldInfo.h b/source/gameengine/Ketsji/KX_WorldInfo.h
new file mode 100644
index 00000000000..7bcf4bb1589
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_WorldInfo.h
@@ -0,0 +1,65 @@
+/**
+ * $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_WORLDINFO_H
+#define __KX_WORLDINFO_H
+
+#include "MT_Scalar.h"
+
+
+class MT_CmMatrix4x4;
+
+
+class KX_WorldInfo
+{
+public:
+ KX_WorldInfo(){}
+ virtual ~KX_WorldInfo();
+
+ virtual bool hasWorld()=0;
+ virtual bool hasMist()=0;
+ virtual float getBackColorRed()=0;
+ virtual float getBackColorGreen()=0;
+ virtual float getBackColorBlue()=0;
+ virtual float getMistStart()=0;
+ virtual float getMistDistance()=0;
+ virtual float getMistColorRed()=0;
+ virtual float getMistColorGreen()=0;
+ virtual float getMistColorBlue()=0;
+
+ virtual void setMistStart(float)=0;
+ virtual void setMistDistance(float)=0;
+ virtual void setMistColorRed(float)=0;
+ virtual void setMistColorGreen(float)=0;
+ virtual void setMistColorBlue(float)=0;
+};
+
+#endif //__KX_WORLDINFO_H
diff --git a/source/gameengine/Ketsji/KX_WorldIpoController.cpp b/source/gameengine/Ketsji/KX_WorldIpoController.cpp
new file mode 100644
index 00000000000..c4907a29a7a
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_WorldIpoController.cpp
@@ -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 *****
+ */
+
+#include "KX_WorldIpoController.h"
+
+#include "KX_ScalarInterpolator.h"
+#include "KX_WorldInfo.h"
+
+bool KX_WorldIpoController::Update(double currentTime)
+{
+ if (m_modified)
+ {
+ T_InterpolatorList::iterator i;
+ for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) {
+ (*i)->Execute(m_ipotime);//currentTime);
+ }
+
+ KX_WorldInfo *world;
+
+ if (m_modify_mist_start) {
+ world->setMistStart(m_mist_start);
+ }
+
+ if (m_modify_mist_color) {
+ world->setMistColorRed(m_mist_rgb[0]);
+ world->setMistColorGreen(m_mist_rgb[1]);
+ world->setMistColorBlue(m_mist_rgb[2]);
+ }
+
+ if (m_modify_mist_dist) {
+ world->setMistDistance(m_mist_dist);
+ }
+
+ m_modified=false;
+ }
+ return false;
+}
+
+
+void KX_WorldIpoController::AddInterpolator(KX_IInterpolator* interp)
+{
+ this->m_interpolators.push_back(interp);
+}
+
+
+SG_Controller* KX_WorldIpoController::GetReplica(class SG_Node* destnode)
+{
+ KX_WorldIpoController* iporeplica = new KX_WorldIpoController(*this);
+ // clear object that ipo acts on
+ iporeplica->ClearObject();
+
+ // dirty hack, ask Gino for a better solution in the ipo implementation
+ // hacken en zagen, in what we call datahiding, not written for replication :(
+
+ T_InterpolatorList oldlist = m_interpolators;
+ iporeplica->m_interpolators.clear();
+
+ T_InterpolatorList::iterator i;
+ for (i = oldlist.begin(); !(i == oldlist.end()); ++i) {
+ KX_ScalarInterpolator* copyipo = new KX_ScalarInterpolator(*((KX_ScalarInterpolator*)*i));
+ iporeplica->AddInterpolator(copyipo);
+
+ MT_Scalar* scaal = ((KX_ScalarInterpolator*)*i)->GetTarget();
+ int orgbase = (int)this;
+ int orgloc = (int)scaal;
+ int offset = orgloc-orgbase;
+ int newaddrbase = (int)iporeplica + offset;
+ MT_Scalar* blaptr = (MT_Scalar*) newaddrbase;
+ copyipo->SetNewTarget((MT_Scalar*)blaptr);
+ }
+
+ return iporeplica;
+}
+
+KX_WorldIpoController::~KX_WorldIpoController()
+{
+
+ T_InterpolatorList::iterator i;
+ for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) {
+ delete (*i);
+ }
+
+}
diff --git a/source/gameengine/Ketsji/KX_WorldIpoController.h b/source/gameengine/Ketsji/KX_WorldIpoController.h
new file mode 100644
index 00000000000..36b457adfda
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_WorldIpoController.h
@@ -0,0 +1,99 @@
+/**
+ * $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_WORLDIPOCONTROLLER_H
+#define KX_WORLDIPOCONTROLLER_H
+
+#include "SG_Controller.h"
+#include "SG_Spatial.h"
+
+#include "KX_IInterpolator.h"
+
+class KX_WorldIpoController : public SG_Controller
+{
+public:
+ MT_Scalar m_mist_rgb[3];
+ MT_Scalar m_mist_start;
+ MT_Scalar m_mist_dist;
+
+private:
+ T_InterpolatorList m_interpolators;
+ unsigned short m_modify_mist_color : 1;
+ unsigned short m_modify_mist_start : 1;
+ unsigned short m_modify_mist_dist : 1;
+ bool m_modified;
+
+ double m_ipotime;
+
+public:
+ KX_WorldIpoController() : m_ipotime(0.0),
+ m_modify_mist_color(false),
+ m_modify_mist_start(false),
+ m_modify_mist_dist(false),
+ m_modified(true)
+ {}
+
+ virtual ~KX_WorldIpoController();
+
+ virtual SG_Controller* GetReplica(class SG_Node* destnode);
+
+ virtual bool Update(double time);
+
+ virtual void SetSimulatedTime(double time) {
+ m_ipotime = time;
+ m_modified = true;
+ }
+
+ void SetModifyMistStart(bool modify) {
+ m_modify_mist_start = modify;
+ }
+
+ void SetModifyMistColor(bool modify) {
+ m_modify_mist_color = modify;
+ }
+
+ void SetModifyMistDist(bool modify) {
+ m_modify_mist_dist = modify;
+ }
+
+ void
+ SetOption(
+ int option,
+ int value
+ ){
+ // intentionally empty
+ };
+
+ void AddInterpolator(KX_IInterpolator* interp);
+};
+
+#endif // KX_LIGHTIPOSGCONTROLLER_H
+
diff --git a/source/gameengine/Ketsji/Makefile b/source/gameengine/Ketsji/Makefile
new file mode 100644
index 00000000000..4e0ee06fe1a
--- /dev/null
+++ b/source/gameengine/Ketsji/Makefile
@@ -0,0 +1,60 @@
+#
+# $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 = ketsji
+DIR = $(OCGDIR)/gameengine/$(LIBNAME)
+
+include nan_compile.mk
+
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+CPPFLAGS += $(OGL_CPPFLAGS)
+CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
+CPPFLAGS += -I$(NAN_STRING)/include
+CPPFLAGS += -I$(NAN_FUZZICS)/include -I$(NAN_SUMO)/include -I$(NAN_MOTO)/include
+CPPFLAGS += -I../Rasterizer -I../GameLogic -I../SceneGraph
+CPPFLAGS += -I../BlenderRoutines -I../SoundSystem -I../Expressions
+CPPFLAGS += -I../../kernel/gen_system
+CPPFLAGS += -I../Network -IKXNetwork
+CPPFLAGS += -I../Physics/common
+CPPFLAGS += -I../Physics/Dummy
+CPPFLAGS += -I../Physics/Sumo
+CPPFLAGS += -I.
+
+###########################
+
+SOURCEDIR = source/gameengine/Ketsji
+DIRS = KXNetwork
+
+include nan_subdirs.mk
+
diff --git a/source/gameengine/Makefile b/source/gameengine/Makefile
new file mode 100644
index 00000000000..3111f3afbdd
--- /dev/null
+++ b/source/gameengine/Makefile
@@ -0,0 +1,43 @@
+#
+# $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 *****
+#
+# Bounces make to subdirectories.
+
+include nan_definitions.mk
+
+SOURCEDIR = source/gameengine
+DIR = $(OCGDIR)/gameengine
+DIRS = BlenderRoutines
+DIRS += Converter
+DIRS += Expressions GameLogic Ketsji Rasterizer SceneGraph
+DIRS += SoundSystem Network GamePlayer Physics
+
+include nan_subdirs.mk
diff --git a/source/gameengine/Network/LoopBackNetwork/Makefile b/source/gameengine/Network/LoopBackNetwork/Makefile
new file mode 100644
index 00000000000..19fe362b8f7
--- /dev/null
+++ b/source/gameengine/Network/LoopBackNetwork/Makefile
@@ -0,0 +1,44 @@
+#
+# $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 = LoopBackNetwork
+DIR = $(OCGDIR)/gameengine/Network/$(LIBNAME)
+
+include nan_compile.mk
+
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+CPPFLAGS += -I$(NAN_STRING)/include
+CPPFLAGS += -I..
+CPPFLAGS += -I../../../kernel/gen_system
+
diff --git a/source/gameengine/Network/LoopBackNetwork/NG_LoopBackNetworkDeviceInterface.cpp b/source/gameengine/Network/LoopBackNetwork/NG_LoopBackNetworkDeviceInterface.cpp
new file mode 100644
index 00000000000..9d4069bcac6
--- /dev/null
+++ b/source/gameengine/Network/LoopBackNetwork/NG_LoopBackNetworkDeviceInterface.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 *****
+ * LoopbackNetworkDeviceInterface derived from NG_NetworkDeviceInterface
+ */
+
+#include "NG_LoopBackNetworkDeviceInterface.h"
+#include "NG_NetworkMessage.h"
+
+// temporary debugging printf's
+#ifdef NAN_NET_DEBUG
+ #include <stdio.h>
+#endif
+
+NG_LoopBackNetworkDeviceInterface::NG_LoopBackNetworkDeviceInterface()
+{
+ m_currentQueue=0;
+ Online(); // LoopBackdevices are 'online' immediately
+}
+
+NG_LoopBackNetworkDeviceInterface::~NG_LoopBackNetworkDeviceInterface()
+{
+}
+
+// perhaps this should go to the shared/common implementation too
+void NG_LoopBackNetworkDeviceInterface::NextFrame()
+{
+ // Release reference to the messages while emptying the queue
+ while (m_messages[m_currentQueue].size() > 0) {
+ // Should do assert(m_events[0]);
+ m_messages[m_currentQueue][0]->Release();
+ m_messages[m_currentQueue].pop_front();
+ }
+ //m_messages[m_currentQueue].clear();
+
+ m_currentQueue=1-m_currentQueue;
+}
+
+STR_String NG_LoopBackNetworkDeviceInterface::GetNetworkVersion()
+{
+ return LOOPBACK_NETWORK_VERSION;
+}
+
+void NG_LoopBackNetworkDeviceInterface::SendNetworkMessage(NG_NetworkMessage* nwmsg)
+{
+#ifdef NAN_NET_DEBUG
+ printf("NG_LBNDI::SendNetworkMessage '%s'->'%s' '%s' '%s'\n",
+ nwmsg->GetDestinationName().ReadPtr(),
+ nwmsg->GetSenderName().ReadPtr(),
+ nwmsg->GetSubject().ReadPtr(),
+ nwmsg->GetMessageText().ReadPtr());
+#endif
+ int backqueue = 1-m_currentQueue;
+
+ nwmsg->AddRef();
+ m_messages[backqueue].push_back(nwmsg);
+}
+
+vector<NG_NetworkMessage*> NG_LoopBackNetworkDeviceInterface::RetrieveNetworkMessages()
+{
+ vector<NG_NetworkMessage*> messages;
+
+ std::deque<NG_NetworkMessage*>::iterator mesit=m_messages[m_currentQueue].begin();
+ for (; !(mesit == m_messages[m_currentQueue].end());mesit++)
+ {
+
+ // We don't increase the reference count for these messages. We
+ // are passing a vector of messages in the interface and not
+ // explicitily storing the messgaes for long term usage
+
+ messages.push_back(*mesit);
+
+#ifdef NAN_NET_DEBUG
+ printf("NG_LBNDI::RetrieveNetworkMessages '%s'->'%s' '%s' '%s'\n",
+ (*mesit)->GetDestinationName().ReadPtr(),
+ (*mesit)->GetSenderName().ReadPtr(),
+ (*mesit)->GetSubject().ReadPtr(),
+ (*mesit)->GetMessageText().ReadPtr());
+#endif
+ }
+ return messages;
+}
+
diff --git a/source/gameengine/Network/LoopBackNetwork/NG_LoopBackNetworkDeviceInterface.h b/source/gameengine/Network/LoopBackNetwork/NG_LoopBackNetworkDeviceInterface.h
new file mode 100644
index 00000000000..ad87b232794
--- /dev/null
+++ b/source/gameengine/Network/LoopBackNetwork/NG_LoopBackNetworkDeviceInterface.h
@@ -0,0 +1,68 @@
+/*
+ * $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 *****
+ * LoopbackNetworkDeviceInterface derived from NG_NetworkDeviceInterface
+ */
+#ifndef NG_LOOPBACKNETWORKDEVICEINTERFACE_H
+#define NG_LOOPBACKNETWORKDEVICEINTERFACE_H
+
+#include <deque>
+#include "NG_NetworkDeviceInterface.h"
+
+class NG_LoopBackNetworkDeviceInterface : public NG_NetworkDeviceInterface
+{
+ enum {
+ LOOPBACK_NETWORK_VERSION=28022001
+ };
+
+ std::deque<NG_NetworkMessage*> m_messages[2];
+ int m_currentQueue;
+
+public:
+ NG_LoopBackNetworkDeviceInterface();
+ virtual ~NG_LoopBackNetworkDeviceInterface();
+
+ /**
+ * Clear message buffer
+ */
+ virtual void NextFrame();
+
+ bool Connect(char *address, unsigned int port, char *password,
+ unsigned int localport, unsigned int timeout) {
+ return true;}
+ bool Disconnect(void) {return true;}
+
+ virtual void SendNetworkMessage(class NG_NetworkMessage* msg);
+ virtual vector<NG_NetworkMessage*> RetrieveNetworkMessages();
+
+ STR_String GetNetworkVersion();
+};
+
+#endif //NG_LOOPBACKNETWORKDEVICEINTERFACE_H
diff --git a/source/gameengine/Network/Makefile b/source/gameengine/Network/Makefile
new file mode 100644
index 00000000000..3c5ed35e539
--- /dev/null
+++ b/source/gameengine/Network/Makefile
@@ -0,0 +1,50 @@
+#
+# $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 = Network
+DIR = $(OCGDIR)/gameengine/$(LIBNAME)
+
+include nan_compile.mk
+
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+CPPFLAGS += -I$(NAN_STRING)/include
+CPPFLAGS += -I../GameLogic
+CPPFLAGS += -I../../kernel/gen_system
+
+##############
+
+DIRS = LoopBackNetwork
+SOURCEDIR = source/gameengine/Network
+
+include nan_subdirs.mk
diff --git a/source/gameengine/Network/NG_NetworkDeviceInterface.h b/source/gameengine/Network/NG_NetworkDeviceInterface.h
new file mode 100644
index 00000000000..f6f8b0e8631
--- /dev/null
+++ b/source/gameengine/Network/NG_NetworkDeviceInterface.h
@@ -0,0 +1,85 @@
+/*
+ * $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 *****
+ * NetworkGameengine_NetworkDeviceInterface
+ * Functions like (de)initialize network, get library version
+ * To be derived by loopback and network libraries
+ */
+#ifndef NG_NETWORKDEVICEINTERFACE_H
+#define NG_NETWORKDEVICEINTERFACE_H
+
+#include "NG_NetworkMessage.h"
+
+#include <vector>
+
+class NG_NetworkDeviceInterface
+{
+private:
+ // candidates for shared/common implementation class
+ bool m_online;
+public:
+ NG_NetworkDeviceInterface() {};
+ virtual ~NG_NetworkDeviceInterface() {};
+
+ virtual void NextFrame()=0;
+
+ /**
+ * Mark network connection online
+ */
+ void Online(void) { m_online = true; }
+ /**
+ * Mark network connection offline
+ */
+ void Offline(void) { m_online = false; }
+ /**
+ * Is the network connection established ?
+ */
+ bool IsOnline(void) { return m_online; }
+
+ virtual bool Connect(char *address, unsigned int port, char *password,
+ unsigned int localport, unsigned int timeout)=0;
+ virtual bool Disconnect(void)=0;
+
+ virtual void SendNetworkMessage(NG_NetworkMessage* msg)=0;
+ /**
+ * read NG_NetworkMessage from library buffer, may be
+ * irrelevant for loopbackdevices
+ */
+
+ virtual std::vector<NG_NetworkMessage*> RetrieveNetworkMessages()=0;
+
+ /**
+ * number of messages in device hash for this frame
+ */
+
+ virtual STR_String GetNetworkVersion(void)=0;
+};
+
+#endif //NG_NETWORKDEVICEINTERFACE_H
diff --git a/source/gameengine/Network/NG_NetworkMessage.cpp b/source/gameengine/Network/NG_NetworkMessage.cpp
new file mode 100644
index 00000000000..d000dd4b4cc
--- /dev/null
+++ b/source/gameengine/Network/NG_NetworkMessage.cpp
@@ -0,0 +1,55 @@
+/*
+ * $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 *****
+ * generic Network Message implementation
+ */
+#include "NG_NetworkMessage.h"
+#include <assert.h>
+
+int NG_NetworkMessage::s_nextID = 3; // just some number to start with
+
+NG_NetworkMessage::NG_NetworkMessage(
+ const STR_String& to,
+ const STR_String& from,
+ const STR_String& subject,
+ const STR_String& body) :
+ m_uniqueMessageID(s_nextID++),
+ m_refcount(1),
+ m_to(to),
+ m_from(from),
+ m_subject(subject),
+ m_message(body)
+{
+}
+
+NG_NetworkMessage::~NG_NetworkMessage()
+{
+ assert(m_refcount==0);
+}
diff --git a/source/gameengine/Network/NG_NetworkMessage.h b/source/gameengine/Network/NG_NetworkMessage.h
new file mode 100644
index 00000000000..72abb3e4a71
--- /dev/null
+++ b/source/gameengine/Network/NG_NetworkMessage.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 *****
+ * NetworkGame_NetworkMessage generic Network Message class
+ */
+#ifndef NG_NETWORKMESSAGE_H
+#define NG_NETWORKMESSAGE_H
+
+#include "STR_HashedString.h"
+
+class NG_NetworkMessage
+{
+ static int s_nextID;
+ int m_uniqueMessageID; // intern counting MessageID
+ unsigned int m_ClientId;
+ int m_refcount;
+
+ STR_String m_to; // receiver
+ STR_String m_from; // sender
+ STR_String m_subject; // empty or propName
+ STR_String m_message; // message or propValue
+
+protected:
+ ~NG_NetworkMessage();
+
+public:
+ NG_NetworkMessage(
+ const STR_String& to,
+ const STR_String& from,
+ const STR_String& subject,
+ const STR_String& body);
+
+ void AddRef() {
+ m_refcount++;
+ }
+
+ // This is not nice code you should'nt need to resort to
+ // delete this.
+ void Release()
+ {
+ if (! --m_refcount)
+ {
+ delete this;
+ }
+ }
+
+ /**
+ * set the content of this message
+ */
+ void SetMessageText(const STR_String& msgtext) {
+ m_message = msgtext;
+ }
+
+ /**
+ * get the (read-only) To part of this message
+ */
+ const STR_String& GetDestinationName() { return m_to;};
+
+ /**
+ * get the (read-only) From part of this message
+ */
+ const STR_String& GetSenderName() { return m_from;};
+
+ /**
+ * get the (read-only) Subject part of this message
+ */
+ const STR_String& GetSubject() { return m_subject;};
+
+ /**
+ * get the (read-only) Body part of this message
+ */
+ const STR_String& GetMessageText() {
+//cout << "GetMessageText " << m_message << "\n";
+ return m_message;
+ }
+ const STR_String& GetMessageText() const {
+//cout << "GetMessageText " << m_message << "\n";
+ return m_message;
+ }
+
+ /**
+ * Set the NetworkMessage sender identifier
+ */
+ void SetSender(unsigned int ClientId) {
+ m_ClientId = ClientId;
+ }
+
+ /**
+ * Get the NetworkMessage sender identifier
+ */
+ unsigned int GetSender(void) {
+ return m_ClientId;
+ }
+
+ /**
+ * get the unique Network Message ID
+ */
+ int GetMessageID() {
+ return m_uniqueMessageID;
+ }
+};
+
+#endif //NG_NETWORKMESSAGE_H
diff --git a/source/gameengine/Network/NG_NetworkObject.cpp b/source/gameengine/Network/NG_NetworkObject.cpp
new file mode 100644
index 00000000000..54db7c4f4b8
--- /dev/null
+++ b/source/gameengine/Network/NG_NetworkObject.cpp
@@ -0,0 +1,46 @@
+/*
+ * $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 *****
+ * NetworkGame_NetworkObject generic Network Object implementation
+ */
+#include "NG_NetworkObject.h"
+
+NG_NetworkObject::NG_NetworkObject()
+{
+}
+
+NG_NetworkObject::~NG_NetworkObject()
+{
+}
+
+const STR_String& NG_NetworkObject::GetName()
+{
+ return m_name;
+}
diff --git a/source/gameengine/Network/NG_NetworkObject.h b/source/gameengine/Network/NG_NetworkObject.h
new file mode 100644
index 00000000000..d276ab6a25a
--- /dev/null
+++ b/source/gameengine/Network/NG_NetworkObject.h
@@ -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 *****
+ * NetworkGame_NetworkObject generic Network Object class
+ */
+#ifndef NG_NETWORKOBJECT_H
+#define NG_NETWORKOBJECT_H
+
+#include "STR_String.h"
+
+class NG_NetworkObject
+{
+ STR_String m_name;
+public:
+ NG_NetworkObject();
+ ~NG_NetworkObject();
+ const STR_String& GetName();
+};
+
+#endif //NG_NETWORKOBJECT_H
diff --git a/source/gameengine/Network/NG_NetworkScene.cpp b/source/gameengine/Network/NG_NetworkScene.cpp
new file mode 100644
index 00000000000..30bc1aac122
--- /dev/null
+++ b/source/gameengine/Network/NG_NetworkScene.cpp
@@ -0,0 +1,271 @@
+/**
+ * $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 *****
+ * NetworkSceneManagement generic implementation
+ */
+#include <stdio.h>
+#include <assert.h>
+#include <algorithm>
+
+#include "NG_NetworkScene.h"
+#include "NG_NetworkDeviceInterface.h"
+#include "NG_NetworkMessage.h"
+#include "NG_NetworkObject.h"
+
+NG_NetworkScene::NG_NetworkScene(NG_NetworkDeviceInterface* nic)
+{
+ m_networkdevice = nic;
+}
+
+NG_NetworkScene::~NG_NetworkScene()
+{
+ ClearAllMessageMaps();
+}
+
+/**
+ * progress one frame, handle all network traffic
+ */
+void NG_NetworkScene::proceed(double curtime, double deltatime)
+{
+ if (!m_networkdevice) return;
+ if (!m_networkdevice->IsOnline()) return;
+
+ ClearAllMessageMaps();
+
+ // read all NetworkMessages from the device
+ vector<NG_NetworkMessage*> messages =
+ m_networkdevice->RetrieveNetworkMessages();
+
+ vector<NG_NetworkMessage*>::iterator mesit = messages.begin();
+ for (; !(mesit == messages.end()); mesit++) {
+ NG_NetworkMessage* message = (*mesit);
+ vector<NG_NetworkMessage*>* tmplist=NULL;
+
+ vector<NG_NetworkMessage*>** tmplistptr =
+ m_messagesByDestinationName[message->GetDestinationName()];
+ // if there is already a vector of messages, append, else create
+ // a new vector and insert into map
+ if (!tmplistptr) {
+ tmplist = new vector<NG_NetworkMessage*>;
+ m_messagesByDestinationName.insert(message->GetDestinationName(),
+ tmplist);
+ } else {
+ tmplist = *tmplistptr;
+ }
+ message->AddRef();
+ tmplist->push_back(message);
+ tmplist = NULL;
+
+ tmplistptr = m_messagesBySenderName[message->GetSenderName()];
+ // if there is already a vector of messages, append, else create
+ // a new vector and insert into map
+ if (!tmplistptr) {
+ tmplist = new vector<NG_NetworkMessage*>;
+ m_messagesBySenderName.insert(message->GetSenderName(), tmplist);
+ } else {
+ tmplist = *tmplistptr;
+ }
+ message->AddRef();
+ tmplist->push_back(message);
+ tmplist = NULL;
+
+ tmplistptr = m_messagesBySubject[message->GetSubject()];
+ // if there is already a vector of messages, append, else create
+ // a new vector and insert into map
+ if (!tmplistptr) {
+ tmplist = new vector<NG_NetworkMessage*>;
+ m_messagesBySubject.insert(message->GetSubject(), tmplist);
+ } else {
+ tmplist = *tmplistptr;
+ }
+ message->AddRef();
+ tmplist->push_back(message);
+ tmplist = NULL;
+ }
+}
+
+/**
+ * add a network object to the network scene
+ */
+void NG_NetworkScene::AddObject(NG_NetworkObject* object)
+{
+ if (! m_networkdevice->IsOnline()) return;
+
+ STR_String name = object->GetName();
+ m_networkObjects.insert(name, object);
+}
+
+/**
+ * remove a network object from the network scene
+ */
+void NG_NetworkScene::RemoveObject(NG_NetworkObject* object)
+{
+ if (! m_networkdevice->IsOnline()) return;
+
+ STR_String name = object->GetName();
+ m_networkObjects.remove(name);
+}
+
+/**
+ * remove all network scene objects at once
+ */
+void NG_NetworkScene::RemoveAllObjects()
+{
+ m_networkObjects.clear();
+}
+
+/**
+ * get a single network object given its name
+ */
+NG_NetworkObject* NG_NetworkScene::FindNetworkObject(const STR_String& objname) {
+ NG_NetworkObject *nwobj = NULL;
+ if (! m_networkdevice->IsOnline()) return nwobj;
+
+ NG_NetworkObject **nwobjptr = m_networkObjects[objname];
+ if (nwobjptr) {
+ nwobj = *nwobjptr;
+ }
+
+ return nwobj;
+}
+
+bool NG_NetworkScene::ConstraintsAreValid(
+ const STR_String& from,
+ const STR_String& subject,
+ NG_NetworkMessage* message)
+{
+ vector<NG_NetworkMessage*>** fromlistptr = m_messagesBySenderName[from];
+ vector<NG_NetworkMessage*>** subjectlistptr = m_messagesBySubject[subject];
+
+ vector<NG_NetworkMessage*>* fromlist = (fromlistptr ? *fromlistptr : NULL);
+ vector<NG_NetworkMessage*>* subjectlist = (subjectlistptr ? *subjectlistptr : NULL);
+
+ return (
+ ( from.IsEmpty() || (!fromlist ? false : (!(std::find(fromlist->begin(), fromlist->end(), message) == fromlist->end())))
+ ) &&
+ ( subject.IsEmpty() || (!subjectlist ? false : (!(std::find(subjectlist->begin(), subjectlist->end(), message) == subjectlist->end())))
+ ));
+}
+
+vector<NG_NetworkMessage*> NG_NetworkScene::FindMessages(
+ const STR_String& to,
+ const STR_String& from,
+ const STR_String& subject,
+ bool spamallowed)
+{
+ vector<NG_NetworkMessage*> foundmessages;
+ bool notfound = false;
+
+ // broad phase
+ notfound = ((to.IsEmpty() || spamallowed) ? notfound : m_messagesByDestinationName[to] == NULL);
+ if (!notfound)
+ notfound = (from.IsEmpty() ? notfound : m_messagesBySenderName[from] == NULL);
+ if (!notfound)
+ notfound = (subject.IsEmpty() ? notfound : m_messagesBySubject[subject] == NULL);
+ if (notfound) {
+ // it's definately NOT in the scene, so stop looking
+ } else { // narrow phase
+ // possibly it's there, but maybe not (false hit)
+ if (to.IsEmpty()) {
+ // take all messages, and check other fields
+ assert("objectnames that are empty are not valid, so make it a hobby project :)\n");
+ } else {
+ //todo: find intersection of messages (that are in other 2 maps)
+ vector<NG_NetworkMessage*>** tolistptr = m_messagesByDestinationName[to];
+ if (tolistptr) {
+ vector<NG_NetworkMessage*>* tolist = *tolistptr;
+ vector<NG_NetworkMessage*>::iterator listit;
+ for (listit=tolist->begin();!(listit==tolist->end());listit++) {
+ NG_NetworkMessage* message = *listit;
+ if (ConstraintsAreValid(from, subject, message)) {
+ message->AddRef();
+ foundmessages.push_back(message);
+ }
+ }
+ }
+ // TODO find intersection of messages (that are in other 2 maps)
+ if (spamallowed) {
+ tolistptr = m_messagesByDestinationName[""];
+ if (tolistptr) {
+ vector<NG_NetworkMessage*>* tolist = *tolistptr;
+ vector<NG_NetworkMessage*>::iterator listit;
+ for (listit=tolist->begin();!(listit==tolist->end());listit++) {
+ NG_NetworkMessage* message = *listit;
+ if (ConstraintsAreValid(from, subject, message)) {
+ message->AddRef();
+ foundmessages.push_back(message);
+ }
+ }
+ }
+ }
+ }
+ }
+ return foundmessages;
+}
+
+void NG_NetworkScene::SendMessage(
+ const STR_String& to,
+ const STR_String& from,
+ const STR_String& subject,
+ const STR_String& message)
+{
+ NG_NetworkMessage* msg = new NG_NetworkMessage(to, from, subject, message);
+ m_networkdevice->SendNetworkMessage(msg);
+ msg->Release();
+}
+
+void NG_NetworkScene::ClearAllMessageMaps(void)
+{
+ ClearMessageMap(m_messagesByDestinationName);
+ ClearMessageMap(m_messagesBySenderName);
+ ClearMessageMap(m_messagesBySubject);
+}
+
+void NG_NetworkScene::ClearMessageMap(TMessageMap& map)
+{
+ // Release the messages in the map
+ for (int i = 0; i < map.size(); i++) {
+ vector<NG_NetworkMessage*>* msglist;
+ msglist = *(map.at(i));
+
+ // Iterate through the current vector and release all it's messages
+ vector<NG_NetworkMessage*>::iterator msgit;
+ for (msgit = msglist->begin(); msgit != msglist->end(); msgit++) {
+ (*msgit)->Release();
+ }
+
+ // Delete the actual vector
+ delete (msglist);
+ }
+
+ // Empty the map
+ map.clear();
+}
+
diff --git a/source/gameengine/Network/NG_NetworkScene.h b/source/gameengine/Network/NG_NetworkScene.h
new file mode 100644
index 00000000000..487934205ec
--- /dev/null
+++ b/source/gameengine/Network/NG_NetworkScene.h
@@ -0,0 +1,102 @@
+/*
+ * $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 *****
+ * NetworkSceneManagement generic class
+ */
+#ifndef __NG_NETWORKSCENE_H
+#define __NG_NETWORKSCENE_H
+
+#include "GEN_Map.h"
+#include "STR_HashedString.h"
+#include <vector>
+class NG_NetworkDeviceInterface;
+
+class NG_NetworkScene
+{
+ class NG_NetworkDeviceInterface *m_networkdevice;
+ GEN_Map<STR_HashedString, class NG_NetworkObject *> m_networkObjects;
+
+ // GEN_Maps used as a 'Bloom' filter
+ typedef GEN_Map<STR_HashedString, std::vector<class NG_NetworkMessage*>* > TMessageMap;
+ TMessageMap m_messagesByDestinationName;
+ TMessageMap m_messagesBySenderName;
+ TMessageMap m_messagesBySubject;
+
+public:
+ NG_NetworkScene(NG_NetworkDeviceInterface *nic);
+ ~NG_NetworkScene();
+
+ /**
+ * progress one frame, handle all network traffic
+ */
+ void proceed(double curtime, double deltatime);
+
+ /**
+ * add a networkobject to the scene
+ */
+ void AddObject(NG_NetworkObject* object);
+
+ /**
+ * remove a networkobject to the scene
+ */
+ void RemoveObject(NG_NetworkObject* object);
+
+ /**
+ * remove all objects at once
+ */
+ void RemoveAllObjects();
+
+ /**
+ * send a message (ascii text) over the network
+ */
+ void SendMessage(const STR_String& to,const STR_String& from,const STR_String& subject,const STR_String& message);
+
+ /**
+ * find an object by name
+ */
+ NG_NetworkObject* FindNetworkObject(const STR_String& objname);
+
+ bool ConstraintsAreValid(const STR_String& from,const STR_String& subject,class NG_NetworkMessage* message);
+ vector<NG_NetworkMessage*> FindMessages(const STR_String& to,const STR_String& from,const STR_String& subject,bool spamallowed);
+
+protected:
+ /**
+ * Releases messages in message map members.
+ */
+ void ClearAllMessageMaps(void);
+
+ /**
+ * Releases messages for the given message map.
+ * @param map Message map with messages.
+ */
+ void ClearMessageMap(TMessageMap& map);
+};
+
+#endif //__NG_NETWORKSCENE_H
diff --git a/source/gameengine/Network/TerraplayNetwork/Makefile b/source/gameengine/Network/TerraplayNetwork/Makefile
new file mode 100644
index 00000000000..6fad0e0ca43
--- /dev/null
+++ b/source/gameengine/Network/TerraplayNetwork/Makefile
@@ -0,0 +1,45 @@
+#
+# $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 = TerraPlayNetwork
+DIR = $(OCGDIR)/gameengine/Network/$(LIBNAME)
+
+include nan_compile.mk
+
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+CPPFLAGS += -I$(NAN_STRING)/include
+CPPFLAGS += -I$(LCGDIR)/terraplay/include
+CPPFLAGS += -I../../../kernel/gen_system
+CPPFLAGS += -I..
+
diff --git a/source/gameengine/Network/TerraplayNetwork/NG_TerraplayNetworkDeviceInterface.cpp b/source/gameengine/Network/TerraplayNetwork/NG_TerraplayNetworkDeviceInterface.cpp
new file mode 100644
index 00000000000..55710e0f8ad
--- /dev/null
+++ b/source/gameengine/Network/TerraplayNetwork/NG_TerraplayNetworkDeviceInterface.cpp
@@ -0,0 +1,192 @@
+/*
+ * $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 *****
+ * TerraplayNetworkDeviceInterface derived from NG_NetworkDeviceInterface
+ */
+
+#include "NG_TerraplayNetworkDeviceInterface.h"
+#include "NG_NetworkMessage.h"
+
+//---- relocate these
+void NG_TerraplayNetworkDeviceInterface::interface_error(char *str, GASResult error) {
+ GASRString err_str = GAS->ErrorTranslate(error);
+ if (err_str.result == GASOK)
+ printf("%s: %s\n",str,err_str.ptr);
+ else
+ printf("%s: UNKNOWN (Error code %d)", error);
+}
+//---- END relocate these
+
+NG_TerraplayNetworkDeviceInterface::NG_TerraplayNetworkDeviceInterface()
+{
+ group_id = GASCLIENTIDNULL;
+ group_id_request_valid = false;
+ this->Offline();
+
+ if ((GAS = new GASInterface()) == NULL) {
+ // terror
+ printf("ERROR GAS Common Network Interface NOT created\n");
+ // do something useful
+ } else {
+ printf("GAS Common Network Interface created\n");
+ }
+}
+
+NG_TerraplayNetworkDeviceInterface::~NG_TerraplayNetworkDeviceInterface()
+{
+ if (GAS != NULL) {
+ delete GAS;
+ printf("GAS Common Network Interface deleted\n");
+ }
+}
+
+bool NG_TerraplayNetworkDeviceInterface::Connect(char *GAS_address,
+ unsigned int GAS_port, char *GAS_password, unsigned int localport,
+ unsigned int timeout)
+{
+ GASResult result;
+ printf("Establishing connection to GAS...\n");
+ result = GAS->ConnectionRequest(GAS_address, GAS_port,
+ GAS_password,localport, timeout);
+ if (result == GASOK) {
+ this->Online();
+ GASRClientId client_id = GAS->Connected();
+ if (client_id.result != GASOK) {
+ printf("... connected, but no client ID\n");
+ return false;
+ } else {
+ printf("Connected with client ID %d\n",
+ client_id.clientid);
+ return true;
+ }
+ } else {
+ interface_error("Connection", result);
+ return false;
+ }
+}
+
+bool NG_TerraplayNetworkDeviceInterface::Disconnect(void)
+{
+ int i = 0;
+ printf("Disconnecting...\n");
+ if (! this->IsOnline()) {
+ printf("ehh... /me was not connected\n");
+ return false;
+ }
+
+ GASRRequestId req = GAS->ConnectionClose();
+ if (req.result != GASWAITING) {
+ interface_error("ConnectionClose",req.result);
+ this->~NG_TerraplayNetworkDeviceInterface();
+ }
+ this->Offline();
+// dit is erg fout :( ik wil helemaal geen ~NG_ hier
+
+ while (true) {
+ GASRMessage gas_message;
+ GASResult result = GAS->GasActivity(GASBLOCK, 100);
+ if (++i>5000) {
+ printf("\nGiving up on waiting for connection close\n");
+ this->~NG_TerraplayNetworkDeviceInterface();
+ }
+ switch (result) {
+ case GASCONNECTIONOK:
+ break;
+ case GASGASMESSAGE:
+ gas_message = GAS->GasMessageGetNext();
+ if (gas_message.type == GASRCONNECTIONCLOSE) {
+ if (gas_message.result == GASOK ||
+ gas_message.result == GASALREADYDONE) {
+ return true;
+ } else {
+ interface_error("GasMessageGetNext",
+ gas_message.result);
+ return false;
+ }
+ }
+ // no break ...
+ default:
+ interface_error("GasActivity",result);
+ }
+ }
+ return true;
+}
+
+STR_String NG_TerraplayNetworkDeviceInterface::GetNetworkVersion()
+{
+ GASRString version = GAS->Version();
+ if (version.result != GASOK) {
+ interface_error("GetNetworkVersion", version.result);
+ return NULL;
+ } else {
+ return version.ptr;
+ }
+}
+
+int NG_TerraplayNetworkDeviceInterface::mytest() {
+ return (3);
+}
+
+void NG_TerraplayNetworkDeviceInterface::SendNetworkMessage(NG_NetworkMessage* nwmsg)
+{
+ GASPayload payload;
+ GASResult result;
+ STR_String mystring;
+
+ if (group_id == GASCLIENTIDNULL) {
+ printf("Oops, no group to send to yet\n");
+ return;
+ }
+
+ mystring = nwmsg->GetMessageText().ReadPtr();
+ payload.ptr = (void *) mystring.Ptr();
+ payload.size = mystring.Length() + 1;
+
+ result = GAS->ClientMessageSend(group_id, payload, GASBESTEFFORT);
+
+ switch (result) {
+ case GASOK:
+ break;
+ default:
+ interface_error("ClientMessageSend",result);
+ }
+ // NOTE. You shall NOT free the payload with PayloadFree().
+ // This is your own payload, allocated and freed by yourself
+ // anyway you want.
+}
+
+vector <NG_NetworkMessage*> NG_TerraplayNetworkDeviceInterface::RetrieveNetworkMessages()
+{
+
+ vector <NG_NetworkMessage*> messages;
+ //todo: spend your expensive time here!
+
+ return messages;
+}
diff --git a/source/gameengine/Network/TerraplayNetwork/NG_TerraplayNetworkDeviceInterface.h b/source/gameengine/Network/TerraplayNetwork/NG_TerraplayNetworkDeviceInterface.h
new file mode 100644
index 00000000000..b430b72d985
--- /dev/null
+++ b/source/gameengine/Network/TerraplayNetwork/NG_TerraplayNetworkDeviceInterface.h
@@ -0,0 +1,70 @@
+/*
+ * $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 *****
+ * TerraplayNetworkDeviceInterface derived from NG_NetworkDeviceInterface
+ */
+#ifndef NG_TERRAPLAYNETWORKDEVICEINTERFACE_H
+#define NG_TERRAPLAYNETWORKDEVICEINTERFACE_H
+
+#include <deque>
+
+#include "GASInterface.h"
+
+#include "NG_NetworkDeviceInterface.h"
+
+class NG_TerraplayNetworkDeviceInterface : public NG_NetworkDeviceInterface
+{
+ std::deque<NG_NetworkMessage*> m_messages;
+
+ // Terraplay GAS stuff
+ GASInterface *GAS;
+ GASClientId group_id;
+ GASRequestId group_id_request;
+ int group_id_request_valid;
+
+ void interface_error(char *str, GASResult error);
+public:
+ NG_TerraplayNetworkDeviceInterface();
+ ~NG_TerraplayNetworkDeviceInterface();
+
+ bool Connect(char *GAS_address, unsigned int GAS_port,
+ char *GAS_password, unsigned int localport,
+ unsigned int timeout);
+ bool Disconnect(void);
+
+ void SendNetworkMessage(NG_NetworkMessage* nwmsg);
+ vector<NG_NetworkMessage*> RetrieveNetworkMessages(void);
+
+ STR_String GetNetworkVersion(void);
+
+ int mytest(void);
+};
+
+#endif //NG_TERRAPLAYNETWORKDEVICEINTERFACE_H
diff --git a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp
new file mode 100644
index 00000000000..bc88ae7012d
--- /dev/null
+++ b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp
@@ -0,0 +1,91 @@
+/**
+ * $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 "DummyPhysicsEnvironment.h"
+#include "PHY_IMotionState.h"
+
+
+
+DummyPhysicsEnvironment::DummyPhysicsEnvironment()
+{
+ // create physicsengine data
+}
+
+
+
+DummyPhysicsEnvironment::~DummyPhysicsEnvironment()
+{
+ //destroy physicsengine data
+}
+
+void DummyPhysicsEnvironment::proceed(double timeStep)
+{
+ //step physics simulation, typically perform
+
+ //collision detection
+ //solve constraints
+ //integrate solution
+
+}
+
+void DummyPhysicsEnvironment::setGravity(float x,float y,float z)
+{
+}
+
+
+
+
+
+
+
+int DummyPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsController* ctrl2,PHY_ConstraintType type,
+ float pivotX,float pivotY,float pivotZ,float axisX,float axisY,float axisZ)
+{
+
+ int constraintid = 0;
+ return constraintid;
+
+}
+
+void DummyPhysicsEnvironment::removeConstraint(int constraintid)
+{
+ if (constraintid)
+ {
+ }
+}
+
+PHY_IPhysicsController* DummyPhysicsEnvironment::rayTest(void* ignoreClient,float fromX,float fromY,float fromZ, float toX,float toY,float toZ,
+ float& hitX,float& hitY,float& hitZ,float& normalX,float& normalY,float& normalZ)
+{
+ //collision detection / raytesting
+ return NULL;
+}
+
diff --git a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h
new file mode 100644
index 00000000000..874b747849d
--- /dev/null
+++ b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h
@@ -0,0 +1,70 @@
+/**
+ * $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 _DUMMYPHYSICSENVIRONMENT
+#define _DUMMYPHYSICSENVIRONMENT
+
+
+#include "PHY_IPhysicsEnvironment.h"
+
+/**
+* DummyPhysicsEnvironment is an empty placeholder
+* Alternatives are ODE,Sumo and Dynamo PhysicsEnvironments
+* Use DummyPhysicsEnvironment as a base to integrate your own physics engine
+* Physics Environment takes care of stepping the simulation and is a container for physics entities (rigidbodies,constraints, materials etc.)
+*
+* A derived class may be able to 'construct' entities by loading and/or converting
+*/
+class DummyPhysicsEnvironment : public PHY_IPhysicsEnvironment
+{
+
+public:
+ DummyPhysicsEnvironment ();
+ virtual ~DummyPhysicsEnvironment ();
+// Perform an integration step of duration 'timeStep'.
+ virtual void proceed (double timeStep);
+ virtual void setGravity(float x,float y,float z);
+
+ virtual int createConstraint(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsController* ctrl2,PHY_ConstraintType type,
+ float pivotX,float pivotY,float pivotZ,
+ float axisX,float axisY,float axisZ);
+
+ virtual void removeConstraint(int constraintid);
+ virtual PHY_IPhysicsController* rayTest(void* ignoreClient, float fromX,float fromY,float fromZ, float toX,float toY,float toZ,
+ float& hitX,float& hitY,float& hitZ,float& normalX,float& normalY,float& normalZ);
+
+
+};
+
+#endif //_DUMMYPHYSICSENVIRONMENT
+
+
+
diff --git a/source/gameengine/Physics/Dummy/Makefile b/source/gameengine/Physics/Dummy/Makefile
new file mode 100644
index 00000000000..4ef37cf97ce
--- /dev/null
+++ b/source/gameengine/Physics/Dummy/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 = dummy
+DIR = $(OCGDIR)/gameengine/blphys/$(LIBNAME)
+
+include nan_compile.mk
+
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+CPPFLAGS += -I$(OPENGL_HEADERS)
+CPPFLAGS += -I$(NAN_STRING)/include
+CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
+CPPFLAGS += -I$(NAN_FUZZICS)/include -I$(NAN_SUMO)/include -I$(NAN_MOTO)/include
+CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
+CPPFLAGS += -I../../Physics/common
+CPPFLAGS += -I../../Physics/Dummy
diff --git a/source/gameengine/Physics/Makefile b/source/gameengine/Physics/Makefile
new file mode 100644
index 00000000000..c04ccb175aa
--- /dev/null
+++ b/source/gameengine/Physics/Makefile
@@ -0,0 +1,40 @@
+#
+# $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 *****
+#
+# Bounces make to subdirectories.
+
+include nan_definitions.mk
+
+SOURCEDIR = source/gameengine/Physics
+DIR = $(OCGDIR)/gameengine/blphys
+DIRS = common Sumo Dummy
+
+include nan_subdirs.mk
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/Makefile b/source/gameengine/Physics/Sumo/Fuzzics/Makefile
new file mode 100644
index 00000000000..d721a416862
--- /dev/null
+++ b/source/gameengine/Physics/Sumo/Fuzzics/Makefile
@@ -0,0 +1,9 @@
+#
+# $Id$
+# Copyright (C) 2001 NaN Technologies B.V.
+# Bounce make to subdirectories.
+
+SOURCEDIR = source/sumo/Fuzzics
+DIRS = src
+
+include nan_subdirs.mk
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Callback.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Callback.h
new file mode 100644
index 00000000000..a43ddbec483
--- /dev/null
+++ b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Callback.h
@@ -0,0 +1,10 @@
+#ifndef SM_CALLBACK_H
+#define SM_CALLBACK_H
+
+class SM_Callback {
+public:
+ virtual void do_me() = 0;
+};
+
+#endif
+
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_ClientObjectInfo.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_ClientObjectInfo.h
new file mode 100644
index 00000000000..2063892e671
--- /dev/null
+++ b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_ClientObjectInfo.h
@@ -0,0 +1,15 @@
+#ifndef __SM_CLIENTOBJECT_INFO_H
+#define __SM_CLIENTOBJECT_INFO_H
+
+/**
+ * Client Type and Additional Info. This structure can be use instead of a bare void* pointer, for safeness, and additional info for callbacks
+ */
+
+struct SM_ClientObjectInfo
+{
+ int m_type;
+ void* m_clientobject;
+ void* m_auxilary_info;
+};
+
+#endif //__SM_CLIENTOBJECT_INFO_H
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_FhObject.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_FhObject.h
new file mode 100644
index 00000000000..4aac43f6712
--- /dev/null
+++ b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_FhObject.h
@@ -0,0 +1,36 @@
+#ifndef SM_FHOBJECT_H
+#define SM_FHOBJECT_H
+
+#include "SM_Object.h"
+
+class SM_FhObject : public SM_Object {
+public:
+ SM_FhObject() {}
+ SM_FhObject(const MT_Vector3& ray, SM_Object *client_object) :
+ SM_Object(DT_Ray(ray[0], ray[1], ray[2]), 0, 0, 0),
+ m_ray(ray),
+ m_ray_direction(ray.normalized()),
+ m_client_object(client_object) {}
+
+ const MT_Vector3& getRay() const { return m_ray; }
+ MT_Point3 getSpot() const { return m_pos + m_ray; }
+ const MT_Vector3& getRayDirection() const { return m_ray_direction; }
+ SM_Object *getClientObject() const { return m_client_object; }
+
+ static void ray_hit(void *client_data,
+ void *object1,
+ void *object2,
+ const DT_CollData *coll_data);
+
+private:
+ MT_Vector3 m_ray;
+ MT_Vector3 m_ray_direction;
+ SM_Object *m_client_object;
+};
+
+#endif
+
+
+
+
+
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_MotionState.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_MotionState.h
new file mode 100644
index 00000000000..9c6a9ddaec2
--- /dev/null
+++ b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_MotionState.h
@@ -0,0 +1,36 @@
+#ifndef SM_MOTIONSTATE_H
+#define SM_MOTIONSTATE_H
+
+#include "MT_Transform.h"
+
+class SM_MotionState {
+public:
+ SM_MotionState() :
+ m_pos(0.0, 0.0, 0.0),
+ m_orn(0.0, 0.0, 0.0, 1.0),
+ m_lin_vel(0.0, 0.0, 0.0),
+ m_ang_vel(0.0, 0.0, 0.0)
+ {}
+
+ void setPosition(const MT_Point3& pos) { m_pos = pos; }
+ void setOrientation(const MT_Quaternion& orn) { m_orn = orn; }
+ void setLinearVelocity(const MT_Vector3& lin_vel) { m_lin_vel = lin_vel; }
+ void setAngularVelocity(const MT_Vector3& ang_vel) { m_ang_vel = ang_vel; }
+
+ const MT_Point3& getPosition() const { return m_pos; }
+ const MT_Quaternion& getOrientation() const { return m_orn; }
+ const MT_Vector3& getLinearVelocity() const { return m_lin_vel; }
+ const MT_Vector3& getAngularVelocity() const { return m_ang_vel; }
+
+ virtual MT_Transform getTransform() const {
+ return MT_Transform(m_pos, m_orn);
+ }
+
+protected:
+ MT_Point3 m_pos;
+ MT_Quaternion m_orn;
+ MT_Vector3 m_lin_vel;
+ MT_Vector3 m_ang_vel;
+};
+
+#endif
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h
new file mode 100644
index 00000000000..670da6e71db
--- /dev/null
+++ b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h
@@ -0,0 +1,280 @@
+#ifndef SM_OBJECT_H
+#define SM_OBJECT_H
+
+#include <vector>
+
+#include "solid.h"
+
+#include "SM_Callback.h"
+#include "SM_MotionState.h"
+#include <stdio.h>
+
+
+class SM_FhObject;
+
+
+// Properties of dynamic objects
+struct SM_ShapeProps {
+ MT_Scalar m_mass; // Total mass
+ MT_Scalar m_inertia; // Inertia, should be a tensor some time
+ MT_Scalar m_lin_drag; // Linear drag (air, water) 0 = concrete, 1 = vacuum
+ MT_Scalar m_ang_drag; // Angular drag
+ MT_Scalar m_friction_scaling[3]; // Scaling for anisotropic friction. Component in range [0, 1]
+ bool m_do_anisotropic; // Should I do anisotropic friction?
+ bool m_do_fh; // Should the object have a linear Fh spring?
+ bool m_do_rot_fh; // Should the object have an angular Fh spring?
+};
+
+
+// Properties of collidable objects (non-ghost objects)
+struct SM_MaterialProps {
+ MT_Scalar m_restitution; // restitution of energie after a collision 0 = inelastic, 1 = elastic
+ MT_Scalar m_friction; // Coulomb friction (= ratio between the normal en maximum friction force)
+ MT_Scalar m_fh_spring; // Spring constant (both linear and angular)
+ MT_Scalar m_fh_damping; // Damping factor (linear and angular) in range [0, 1]
+ MT_Scalar m_fh_distance; // The range above the surface where Fh is active.
+ bool m_fh_normal; // Should the object slide off slopes?
+};
+
+
+class SM_Object : public SM_MotionState {
+public:
+ SM_Object() ;
+ SM_Object(
+ DT_ShapeHandle shape,
+ const SM_MaterialProps *materialProps,
+ const SM_ShapeProps *shapeProps,
+ SM_Object *dynamicParent
+ );
+
+ virtual ~SM_Object();
+
+ bool isDynamic() const;
+
+ /* nzc experimental. There seem to be two places where kinematics
+ * are evaluated: proceedKinematic (called from SM_Scene) and
+ * proceed() in this object. I'll just try and bunge these out for
+ * now. */
+
+ void suspend(void);
+ void resume(void);
+
+ void suspendDynamics();
+
+ void restoreDynamics();
+
+ bool isGhost() const;
+
+ void suspendMaterial();
+
+ void restoreMaterial();
+
+ SM_FhObject *getFhObject() const;
+
+ void registerCallback(SM_Callback& callback);
+
+ void calcXform();
+ void notifyClient();
+
+ // Save the current state information for use in the
+ // velocity computation in the next frame.
+
+ void proceedKinematic(MT_Scalar timeStep);
+
+ void saveReactionForce(MT_Scalar timeStep) ;
+
+ void clearForce() ;
+
+ void clearMomentum() ;
+
+ void setMargin(MT_Scalar margin) ;
+
+ MT_Scalar getMargin() const ;
+
+ const SM_MaterialProps *getMaterialProps() const ;
+
+ const SM_ShapeProps *getShapeProps() const ;
+
+ void setPosition(const MT_Point3& pos);
+ void setOrientation(const MT_Quaternion& orn);
+ void setScaling(const MT_Vector3& scaling);
+
+
+ /**
+ * set an external velocity. This velocity complements
+ * the physics velocity. So setting it does not override the
+ * physics velocity. It is your responsibility to clear
+ * this external velocity. This velocity is not subject to
+ * friction or damping.
+ */
+
+
+ void setExternalLinearVelocity(const MT_Vector3& lin_vel) ;
+ void addExternalLinearVelocity(const MT_Vector3& lin_vel) ;
+
+ /** Override the physics velocity */
+
+ void addLinearVelocity(const MT_Vector3& lin_vel);
+ void setLinearVelocity(const MT_Vector3& lin_vel);
+
+ /**
+ * Set an external angular velocity. This velocity complemetns
+ * the physics angular velocity so does not override it. It is
+ * your responsibility to clear this velocity. This velocity
+ * is not subject to friction or damping.
+ */
+
+ void setExternalAngularVelocity(const MT_Vector3& ang_vel) ;
+ void addExternalAngularVelocity(const MT_Vector3& ang_vel);
+
+ /** Override the physics angular velocity */
+
+ void addAngularVelocity(const MT_Vector3& ang_vel);
+ void setAngularVelocity(const MT_Vector3& ang_vel);
+
+ /** Clear the external velocities */
+
+ void clearCombinedVelocities();
+
+ /**
+ * Tell the physics system to combine the external velocity
+ * with the physics velocity.
+ */
+
+ void resolveCombinedVelocities(
+ const MT_Vector3 & lin_vel,
+ const MT_Vector3 & ang_vel
+ ) ;
+
+
+
+ MT_Scalar getInvMass() const;
+
+ MT_Scalar getInvInertia() const ;
+
+ void applyForceField(const MT_Vector3& accel) ;
+
+ void applyCenterForce(const MT_Vector3& force) ;
+
+ void applyTorque(const MT_Vector3& torque) ;
+
+ void applyImpulse(const MT_Point3& attach, const MT_Vector3& impulse) ;
+
+ void applyCenterImpulse(const MT_Vector3& impulse);
+
+ void applyAngularImpulse(const MT_Vector3& impulse);
+
+ MT_Point3 getWorldCoord(const MT_Point3& local) const;
+
+ MT_Vector3 getVelocity(const MT_Point3& local) const;
+
+
+ const MT_Vector3& getReactionForce() const ;
+
+ void getMatrix(double *m) const ;
+
+ const double *getMatrix() const ;
+
+ // Still need this???
+ const MT_Transform& getScaledTransform() const;
+
+ DT_ObjectHandle getObjectHandle() const ;
+ DT_ShapeHandle getShapeHandle() const ;
+
+ void setClientObject(void *clientobj) ;
+ void *getClientObject() ;
+
+ SM_Object *getDynamicParent() ;
+
+ void integrateForces(MT_Scalar timeStep);
+ void integrateMomentum(MT_Scalar timeSteo);
+
+ void setRigidBody(bool is_rigid_body) ;
+
+ bool isRigidBody() const ;
+
+
+ // This is the callback for handling collisions of dynamic objects
+ static
+ void
+ boing(
+ void *client_data,
+ void *object1,
+ void *object2,
+ const DT_CollData *coll_data
+ );
+
+private:
+
+ // return the actual linear_velocity of this object this
+ // is the addition of m_combined_lin_vel and m_lin_vel.
+
+ const
+ MT_Vector3
+ actualLinVelocity(
+ ) const ;
+
+ const
+ MT_Vector3
+ actualAngVelocity(
+ ) const ;
+
+ typedef std::vector<SM_Callback *> T_CallbackList;
+
+
+ T_CallbackList m_callbackList; // Each object can have multiple callbacks from the client (=game engine)
+ SM_Object *m_dynamicParent; // Collisions between parent and children are ignored
+
+ // as the collision callback now has only information
+ // on an SM_Object, there must be a way that the SM_Object client
+ // can identify it's clientdata after a collision
+ void *m_client_object;
+
+ DT_ShapeHandle m_shape; // Shape for collision detection
+
+ // Material and shape properties are not owned by this class.
+
+ const SM_MaterialProps *m_materialProps;
+ const SM_MaterialProps *m_materialPropsBackup; // Backup in case the object temporarily becomes a ghost.
+ const SM_ShapeProps *m_shapeProps;
+ const SM_ShapeProps *m_shapePropsBackup; // Backup in case the object's dynamics is temporarily suspended
+ DT_ObjectHandle m_object; // A handle to the corresponding object in SOLID.
+ MT_Scalar m_margin; // Offset for the object's shape (also for collision detection)
+ MT_Vector3 m_scaling; // Non-uniform scaling of the object's shape
+
+ double m_ogl_matrix[16]; // An OpenGL-type 4x4 matrix
+ MT_Transform m_xform; // The object's local coordinate system
+ MT_Transform m_prev_xform; // The object's local coordinate system in the previous frame
+ SM_MotionState m_prev_state; // The object's motion state in the previous frame
+ MT_Scalar m_timeStep; // The duration of the last frame
+
+ MT_Vector3 m_reaction_impulse; // The accumulated impulse resulting from collisions
+ MT_Vector3 m_reaction_force; // The reaction force derived from the reaction impulse
+
+ unsigned int m_kinematic : 1; // Have I been displaced (translated, rotated, scaled) in this frame?
+ unsigned int m_prev_kinematic : 1; // Have I been displaced (translated, rotated, scaled) in the previous frame?
+ unsigned int m_is_rigid_body : 1; // Should friction give me a change in angular momentum?
+
+ MT_Vector3 m_lin_mom; // Linear momentum (linear velocity times mass)
+ MT_Vector3 m_ang_mom; // Angular momentum (angualr velocity times inertia)
+ MT_Vector3 m_force; // Force on center of mass (afffects linear momentum)
+ MT_Vector3 m_torque; // Torque around center of mass (affects angualr momentum)
+
+ // Here are the values of externally set linear and angular
+ // velocity. These are updated from the outside
+ // (actuators and python) each frame and combined with the
+ // physics values. At the end of each frame (at the end of a
+ // call to proceed) they are set to zero. This allows the
+ // outside world to contribute to the velocity of an object
+ // but still have it react to physics.
+
+ MT_Vector3 m_combined_lin_vel;
+ MT_Vector3 m_combined_ang_vel;
+
+ // The force and torque are the accumulated forces and torques applied by the client (game logic, python).
+
+ SM_FhObject *m_fh_object; // The ray object used for Fh
+ bool m_suspended; // Is this object frozen?
+};
+
+#endif
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Props.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Props.h
new file mode 100644
index 00000000000..0b2efacac2a
--- /dev/null
+++ b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Props.h
@@ -0,0 +1,60 @@
+/**
+ * $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 SM_PROPSH
+#define SM_PROPSH
+
+#include <MT_Scalar.h>
+
+// Properties of dynamic objects
+struct SM_ShapeProps {
+ MT_Scalar m_mass; // Total mass
+ MT_Scalar m_inertia; // Inertia, should be a tensor some time
+ MT_Scalar m_lin_drag; // Linear drag (air, water) 0 = concrete, 1 = vacuum
+ MT_Scalar m_ang_drag; // Angular drag
+ MT_Scalar m_friction_scaling[3]; // Scaling for anisotropic friction. Component in range [0, 1]
+ bool m_do_anisotropic; // Should I do anisotropic friction?
+ bool m_do_fh; // Should the object have a linear Fh spring?
+ bool m_do_rot_fh; // Should the object have an angular Fh spring?
+};
+
+
+// Properties of collidable objects (non-ghost objects)
+struct SM_MaterialProps {
+ MT_Scalar m_restitution; // restitution of energie after a collision 0 = inelastic, 1 = elastic
+ MT_Scalar m_friction; // Coulomb friction (= ratio between the normal en maximum friction force)
+ MT_Scalar m_fh_spring; // Spring constant (both linear and angular)
+ MT_Scalar m_fh_damping; // Damping factor (linear and angular) in range [0, 1]
+ MT_Scalar m_fh_distance; // The range above the surface where Fh is active.
+ bool m_fh_normal; // Should the object slide off slopes?
+};
+
+#endif //SM_PROPSH
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h
new file mode 100644
index 00000000000..761e6c7c449
--- /dev/null
+++ b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h
@@ -0,0 +1,129 @@
+/**
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * The physics scene.
+ */
+
+#ifndef SM_SCENE_H
+#define SM_SCENE_H
+
+#pragma warning (disable : 4786)
+
+#include <vector>
+#include <set>
+#include <utility> //needed for pair
+
+#include "solid.h"
+
+#include "MT_Vector3.h"
+#include "MT_Point3.h"
+
+class SM_Object;
+
+class SM_Scene {
+public:
+ SM_Scene() :
+ m_scene(DT_CreateScene()),
+ m_respTable(DT_CreateRespTable()),
+ m_secondaryRespTable(0),
+ m_forceField(0.0, 0.0, 0.0)
+ {}
+
+ ~SM_Scene() {
+ DT_DeleteRespTable(m_respTable);
+ DT_DeleteScene(m_scene);
+ }
+
+ DT_RespTableHandle getRespTableHandle() const {
+ return m_respTable;
+ }
+
+ const MT_Vector3& getForceField() const {
+ return m_forceField;
+ }
+
+ MT_Vector3& getForceField() {
+ return m_forceField;
+ }
+
+ void setForceField(const MT_Vector3& forceField) {
+ m_forceField = forceField;
+ }
+
+ void add(SM_Object& object);
+ void remove(SM_Object& object);
+
+ void addPair(SM_Object *obj1, SM_Object *obj2) {
+ m_pairList.insert(std::make_pair(obj1, obj2));
+ }
+
+ void clearPairs() {
+ m_pairList.clear();
+ }
+
+ void setSecondaryRespTable(DT_RespTableHandle secondaryRespTable) {
+ m_secondaryRespTable = secondaryRespTable;
+ }
+
+
+ // Perform an integration step of duration 'timeStep'.
+ // 'subSampling' is the maximum duration of a substep, i.e.,
+ // The maximum time interval between two collision checks.
+ // 'subSampling' can be used to control aliasing effects
+ // (fast moving objects traversing through walls and such).
+ void proceed(MT_Scalar timeStep, MT_Scalar subSampling);
+
+ /**
+ * Test whether any objects lie on the line defined by from and
+ * to. The search returns the first such bject starting at from,
+ * or NULL if there was none.
+ * @returns A reference to the object, or NULL if there was none.
+ * @param ignore_client Do not look for collisions with this
+ * object. This can be useful to avoid self-hits if
+ * starting from the location of an object.
+ * @param from The start point, in world coordinates, of the search.
+ * @param to The end point, in world coordinates, of the search.
+ * @param result A store to return the point where intersection
+ * took place (if there was an intersection).
+ * @param normal A store to return the normal of the hit object on
+ * the location of the intersection, if it took place.
+ */
+ SM_Object *rayTest(void *ignore_client,
+ const MT_Point3& from, const MT_Point3& to,
+ MT_Point3& result, MT_Vector3& normal) const;
+
+private:
+
+ // Clear the user set velocities.
+ void clearObjectCombinedVelocities();
+
+ /** internal type */
+ typedef std::vector<SM_Object *> T_ObjectList;
+ /** internal type */
+ typedef std::set<std::pair<SM_Object *, SM_Object *> > T_PairList;
+
+ /** Handle to the scene in SOLID */
+ DT_SceneHandle m_scene;
+ /** Following response table contains the callbacks for the dynmics */
+ DT_RespTableHandle m_respTable;
+ /**
+ * Following response table contains callbacks for the client (=
+ * game engine) */
+ DT_RespTableHandle m_secondaryRespTable; // Handle
+
+ /** The acceleration from the force field */
+ MT_Vector3 m_forceField;
+
+ /**
+ * The list of objects that receive motion updates and do
+ * collision tests. */
+ T_ObjectList m_objectList;
+
+ /**
+ * A list with pairs of objects that collided the previous
+ * timestep. The list is built during the proceed(). During that
+ * time, it is not valid. */
+ T_PairList m_pairList;
+};
+
+#endif
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/sample/Makefile b/source/gameengine/Physics/Sumo/Fuzzics/sample/Makefile
new file mode 100644
index 00000000000..672dff39028
--- /dev/null
+++ b/source/gameengine/Physics/Sumo/Fuzzics/sample/Makefile
@@ -0,0 +1,25 @@
+#
+# $Id$
+# Copyright (C) 2001 NaN Technologies B.V.
+
+DIR = $(OCGDIR)/sumo
+ALLTARGETS = $(OBJS) $(DIR)/$(DEBUG_DIR)particle $(DIR)/$(DEBUG_DIR)particle0
+
+include nan_compile.mk
+
+CPPFLAGS = -I../../include -I../include -I$(NAN_MOTO)/include
+CPPFLAGS += -I$(OPENGL_HEADERS)
+
+clean::
+ @$(RM) $(DIR)/particle $(DIR)/particle0
+ @$(RM) $(DIR)/debug/particle $(DIR)/debug/particle0
+
+LDFLAGS = -L$(DIR) -L/usr/X11R6/lib
+OGL_LDLIBS = -lglut -lGLU -lGL -pthread
+LDLIBS = -lfuzzics -lsolid $(NAN_MOTO)/lib/libmoto.a $(OGL_LDLIBS)
+
+$(DIR)/$(DEBUG_DIR)particle: particle.o $(DIR)/$(DEBUG_DIR)libfuzzics.a $(DIR)/$(DEBUG_DIR)libsolid.a
+ $(CCC) $(CCFLAGS) $(CPPFLAGS) $(LDFLAGS) $< -o $@ $(LDLIBS)
+
+$(DIR)/$(DEBUG_DIR)particle0: particle0.o $(DIR)/$(DEBUG_DIR)libfuzzics.a $(DIR)/$(DEBUG_DIR)libsolid.a
+ $(CCC) $(CCFLAGS) $(CPPFLAGS) $(LDFLAGS) $< -o $@ $(LDLIBS)
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/sample/particle.cpp b/source/gameengine/Physics/Sumo/Fuzzics/sample/particle.cpp
new file mode 100644
index 00000000000..e8e78d89a4e
--- /dev/null
+++ b/source/gameengine/Physics/Sumo/Fuzzics/sample/particle.cpp
@@ -0,0 +1,705 @@
+//#define FAKE_IT
+#define USE_COMPLEX
+#define QUADS
+
+#include <algorithm>
+#include <new>
+#include <GL/glut.h>
+
+#include "MT_MinMax.h"
+#include "MT_Point3.h"
+#include "MT_Vector3.h"
+#include "MT_Quaternion.h"
+#include "MT_Matrix3x3.h"
+#include "MT_Transform.h"
+
+#include "SM_Object.h"
+#include "SM_FhObject.h"
+#include "SM_Scene.h"
+
+#include "solid.h"
+
+const MT_Scalar bowl_curv = 0.10;
+const MT_Scalar timeStep = 0.02;
+const MT_Scalar ground_margin = 0.0;
+const MT_Scalar sphere_radius = 0.5;
+
+const MT_Vector3 gravity(0, -9.8, 0);
+
+static MT_Scalar DISTANCE = 5;
+
+static MT_Scalar ele = 0, azi = 0;
+static MT_Point3 eye(0, 0, DISTANCE);
+static MT_Point3 center(0, 0, 0);
+
+inline double irnd() { return 2 * MT_random() - 1; }
+
+static const double SCALE_BOTTOM = 0.5;
+static const double SCALE_FACTOR = 2.0;
+
+SM_ShapeProps g_shapeProps = {
+ 1.0, // mass
+ 1.0, // inertia
+ 0.1, // linear drag
+ 0.1, // angular drag
+ { 1.0, 0.0, 0.0 }, // anisotropic friction
+ false, // do anisotropic friction?
+ true, // do fh?
+ true // do rot fh?
+};
+
+SM_MaterialProps g_materialProps = {
+ 0.7, // restitution
+ 0.0, // friction
+ 10.0, // Fh spring constant
+ 1.0, // Fh damping
+ 0.5, // Fh distance
+ true // Fh leveling
+};
+
+
+void toggleIdle();
+
+
+void newRandom();
+
+void coordSystem() {
+ glDisable(GL_LIGHTING);
+ glBegin(GL_LINES);
+ glColor3f(1, 0, 0);
+ glVertex3d(0, 0, 0);
+ glVertex3d(10, 0, 0);
+ glColor3f(0, 1, 0);
+ glVertex3d(0, 0, 0);
+ glVertex3d(0, 10, 0);
+ glColor3f(0, 0, 1);
+ glVertex3d(0, 0, 0);
+ glVertex3d(0, 0, 10);
+ glEnd();
+ glEnable(GL_LIGHTING);
+}
+
+
+void display_bbox(const MT_Point3& min, const MT_Point3& max) {
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_LIGHTING);
+ glColor3f(0, 1, 1);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ glBegin(GL_QUAD_STRIP);
+ glVertex3d(min[0], min[1], min[2]);
+ glVertex3d(min[0], min[1], max[2]);
+ glVertex3d(max[0], min[1], min[2]);
+ glVertex3d(max[0], min[1], max[2]);
+ glVertex3d(max[0], max[1], min[2]);
+ glVertex3d(max[0], max[1], max[2]);
+ glVertex3d(min[0], max[1], min[2]);
+ glVertex3d(min[0], max[1], max[2]);
+ glVertex3d(min[0], min[1], min[2]);
+ glVertex3d(min[0], min[1], max[2]);
+ glEnd();
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_DEPTH_TEST);
+}
+
+
+
+
+class GLShape {
+public:
+ virtual void paint(GLdouble *m) const = 0;
+};
+
+
+class GLSphere : public GLShape {
+ MT_Scalar radius;
+public:
+ GLSphere(MT_Scalar r) : radius(r) {}
+
+ void paint(GLdouble *m) const {
+ glPushMatrix();
+ glLoadMatrixd(m);
+ coordSystem();
+ glutSolidSphere(radius, 20, 20);
+ glPopMatrix();
+ }
+};
+
+
+class GLBox : public GLShape {
+ MT_Vector3 extent;
+public:
+ GLBox(MT_Scalar x, MT_Scalar y, MT_Scalar z) :
+ extent(x, y, z) {}
+
+ void paint(GLdouble *m) const {
+ glPushMatrix();
+ glLoadMatrixd(m);
+ coordSystem();
+ glPushMatrix();
+ glScaled(extent[0], extent[1], extent[2]);
+ glutSolidCube(1.0);
+ glPopMatrix();
+ glPopMatrix();
+ }
+};
+
+
+class GLCone : public GLShape {
+ MT_Scalar bottomRadius;
+ MT_Scalar height;
+ mutable GLuint displayList;
+
+public:
+ GLCone(MT_Scalar r, MT_Scalar h) :
+ bottomRadius(r),
+ height(h),
+ displayList(0) {}
+
+ void paint(GLdouble *m) const {
+ glPushMatrix();
+ glLoadMatrixd(m);
+ coordSystem();
+ if (displayList) glCallList(displayList);
+ else {
+ GLUquadricObj *quadObj = gluNewQuadric();
+ displayList = glGenLists(1);
+ glNewList(displayList, GL_COMPILE_AND_EXECUTE);
+ glPushMatrix();
+ glRotatef(-90.0, 1.0, 0.0, 0.0);
+ glTranslatef(0.0, 0.0, -1.0);
+ gluQuadricDrawStyle(quadObj, (GLenum)GLU_FILL);
+ gluQuadricNormals(quadObj, (GLenum)GLU_SMOOTH);
+ gluCylinder(quadObj, bottomRadius, 0, height, 15, 10);
+ glPopMatrix();
+ glEndList();
+ }
+ glPopMatrix();
+ }
+};
+
+class GLCylinder : public GLShape {
+ MT_Scalar radius;
+ MT_Scalar height;
+ mutable GLuint displayList;
+
+public:
+ GLCylinder(MT_Scalar r, MT_Scalar h) :
+ radius(r),
+ height(h),
+ displayList(0) {}
+
+ void paint(GLdouble *m) const {
+ glPushMatrix();
+ glLoadMatrixd(m);
+ coordSystem();
+ if (displayList) glCallList(displayList);
+ else {
+ GLUquadricObj *quadObj = gluNewQuadric();
+ displayList = glGenLists(1);
+ glNewList(displayList, GL_COMPILE_AND_EXECUTE);
+ glPushMatrix();
+ glRotatef(-90.0, 1.0, 0.0, 0.0);
+ glTranslatef(0.0, 0.0, -1.0);
+ gluQuadricDrawStyle(quadObj, (GLenum)GLU_FILL);
+ gluQuadricNormals(quadObj, (GLenum)GLU_SMOOTH);
+ gluCylinder(quadObj, radius, radius, height, 15, 10);
+ glPopMatrix ();
+ glEndList();
+ }
+ glPopMatrix();
+ }
+};
+
+class Object;
+
+class Callback : public SM_Callback {
+public:
+ Callback(Object& object) : m_object(object) {}
+
+ virtual void do_me();
+
+private:
+ Object& m_object;
+};
+
+
+class Object {
+public:
+ Object(GLShape *gl_shape, SM_Object& object) :
+ m_gl_shape(gl_shape),
+ m_object(object),
+ m_callback(*this)
+ {
+ m_object.registerCallback(m_callback);
+ }
+
+ ~Object() {}
+
+ void paint() {
+ if (m_gl_shape) {
+ m_gl_shape->paint(m);
+ // display_bbox(m_bbox.lower(), m_bbox.upper());
+ }
+ }
+
+ void print_reaction_force() const {
+ std::cout << m_object.getReactionForce() << std::endl;
+ }
+
+ MT_Vector3 getAhead() {
+ return MT_Vector3(&m[4]);
+ }
+
+ MT_Vector3 getUp() {
+ return MT_Vector3(&m[8]);
+ }
+
+ void clearMomentum() {
+ m_object.clearMomentum();
+ }
+
+ void setMargin(MT_Scalar margin) {
+ m_object.setMargin(margin);
+ }
+
+ void setScaling(const MT_Vector3& scaling) {
+ m_object.setScaling(scaling);
+ }
+
+ const MT_Point3& getPosition() {
+ return m_object.getPosition();
+ }
+
+ void setPosition(const MT_Point3& pos) {
+ m_object.setPosition(pos);
+ }
+
+ void setOrientation(const MT_Quaternion& orn) {
+ m_object.setOrientation(orn);
+ }
+
+ void applyCenterForce(const MT_Vector3& force) {
+ m_object.applyCenterForce(force);
+ }
+
+ void applyTorque(const MT_Vector3& torque) {
+ m_object.applyTorque(torque);
+ }
+
+ MT_Point3 getWorldCoord(const MT_Point3& local) const {
+ return m_object.getWorldCoord(local);
+ }
+
+ MT_Vector3 getLinearVelocity() const {
+ return m_object.getLinearVelocity();
+ }
+
+ MT_Vector3 getAngularVelocity() const {
+ return m_object.getAngularVelocity();
+ }
+
+ void setMatrix() {
+ m_object.calcXform();
+ m_object.getMatrix(m);
+ }
+
+ const double *getMatrix() {
+ m_object.calcXform();
+ return m_object.getMatrix();
+ }
+
+private:
+ GLShape *m_gl_shape;
+ SM_Object& m_object;
+ DT_Scalar m[16];
+ Callback m_callback;
+};
+
+
+
+const MT_Scalar SPACE_SIZE = 2;
+
+static GLSphere gl_sphere(sphere_radius);
+static GLBox gl_ground(50.0, 0.0, 50.0);
+
+
+
+#ifdef USE_COMPLEX
+
+const int GRID_SCALE = 10;
+const MT_Scalar GRID_UNIT = 25.0 / GRID_SCALE;
+
+DT_ShapeHandle createComplex() {
+ DT_ShapeHandle shape = DT_NewComplexShape();
+ for (int i0 = -GRID_SCALE; i0 != GRID_SCALE; ++i0) {
+ for (int j0 = -GRID_SCALE; j0 != GRID_SCALE; ++j0) {
+ int i1 = i0 + 1;
+ int j1 = j0 + 1;
+#ifdef QUADS
+ DT_Begin();
+ DT_Vertex(GRID_UNIT * i0, bowl_curv * i0*i0, GRID_UNIT * j0);
+ DT_Vertex(GRID_UNIT * i0, bowl_curv * i0*i0, GRID_UNIT * j1);
+ DT_Vertex(GRID_UNIT * i1, bowl_curv * i1*i1, GRID_UNIT * j1);
+ DT_Vertex(GRID_UNIT * i1, bowl_curv * i1*i1, GRID_UNIT * j0);
+ DT_End();
+#else
+ DT_Begin();
+ DT_Vertex(GRID_UNIT * i0, 0, GRID_UNIT * j0);
+ DT_Vertex(GRID_UNIT * i0, 0, GRID_UNIT * j1);
+ DT_Vertex(GRID_UNIT * i1, 0, GRID_UNIT * j1);
+ DT_End();
+
+ DT_Begin();
+ DT_Vertex(GRID_UNIT * i0, 0, GRID_UNIT * j1);
+ DT_Vertex(GRID_UNIT * i1, 0, GRID_UNIT * j1);
+ DT_Vertex(GRID_UNIT * i1, 0, GRID_UNIT * j0);
+ DT_End();
+#endif
+
+ }
+ }
+ DT_EndComplexShape();
+ return shape;
+}
+
+
+static DT_ShapeHandle ground_shape = createComplex();
+
+#else
+
+static DT_ShapeHandle ground_shape = DT_Box(50, 0, 50);
+
+#endif
+
+static SM_Object sm_ground(ground_shape, &g_materialProps, 0, 0);
+static Object ground(&gl_ground, sm_ground);
+
+static SM_Object sm_sphere(DT_Sphere(0.0), &g_materialProps, &g_shapeProps, 0);
+static Object object(&gl_sphere, sm_sphere);
+
+
+static SM_Scene g_scene;
+
+
+bool g_hit = false;
+MT_Point3 g_spot;
+MT_Vector3 g_normal;
+
+
+void Callback::do_me()
+{
+ m_object.setMatrix();
+ m_object.print_reaction_force();
+}
+
+void myinit(void) {
+
+ GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
+ GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
+ GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
+
+ /* light_position is NOT default value */
+ GLfloat light_position0[] = { 1.0, 1.0, 1.0, 0.0 };
+ GLfloat light_position1[] = { -1.0, -1.0, -1.0, 0.0 };
+
+ glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
+ glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
+ glLightfv(GL_LIGHT0, GL_POSITION, light_position0);
+
+ glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient);
+ glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
+ glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular);
+ glLightfv(GL_LIGHT1, GL_POSITION, light_position1);
+
+
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+ glEnable(GL_LIGHT1);
+
+ glShadeModel(GL_SMOOTH);
+
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LESS);
+
+ // glEnable(GL_CULL_FACE);
+ // glCullFace(GL_BACK);
+
+ ground.setPosition(MT_Point3(0, -10, 0));
+ ground.setOrientation(MT_Quaternion(0, 0, 0, 1));
+ ground.setMatrix();
+ center.setValue(0.0, 0.0, 0.0);
+ sm_ground.setMargin(ground_margin);
+
+ g_scene.setForceField(gravity);
+ g_scene.add(sm_ground);
+
+ object.setMargin(sphere_radius);
+
+ g_scene.add(sm_sphere);
+
+
+ newRandom();
+}
+
+
+//MT_Point3 cp1, cp2;
+//bool intersection;
+
+void display(void) {
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ ground.paint();
+ object.paint();
+
+ if (g_hit) {
+ glDisable(GL_LIGHTING);
+ glColor3f(1, 0, 0);
+
+ glPointSize(5);
+ glBegin(GL_POINTS);
+ glVertex3d(g_spot[0], g_spot[1], g_spot[2]);
+ glEnd();
+ glPointSize(1);
+
+ glColor3f(1, 1, 0);
+ glBegin(GL_LINES);
+ glVertex3d(g_spot[0], g_spot[1], g_spot[2]);
+ glVertex3d(g_spot[0] + g_normal[0],
+ g_spot[1] + g_normal[1],
+ g_spot[2] + g_normal[2]);
+ glEnd();
+ glEnable(GL_LIGHTING);
+ }
+
+
+
+#ifdef COLLISION
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_LIGHTING);
+ glColor3f(1, 1, 0);
+ if (intersection) {
+ glPointSize(5);
+ glBegin(GL_POINTS);
+ glVertex3d(cp1[0], cp1[1], cp1[2]);
+ glEnd();
+ glPointSize(1);
+ }
+ else {
+ glBegin(GL_LINES);
+ glVertex3d(cp1[0], cp1[1], cp1[2]);
+ glVertex3d(cp2[0], cp2[1], cp2[2]);
+ glEnd();
+ }
+ glEnable(GL_LIGHTING);
+ glEnable(GL_DEPTH_TEST);
+#endif
+
+ glFlush();
+ glutSwapBuffers();
+}
+
+
+
+
+
+void newRandom() {
+ object.setPosition(MT_Point3(0, 0, 0));
+ object.setOrientation(MT_Quaternion::random());
+ object.clearMomentum();
+ object.setMatrix();
+
+ display();
+}
+
+void moveAndDisplay() {
+ g_scene.proceed(timeStep, 0.01);
+
+ display();
+ g_hit = false;
+}
+
+
+void turn_left() {
+ object.applyTorque(5.0 * object.getUp());
+}
+
+void turn_right() {
+ object.applyTorque(-5.0 * object.getUp());
+}
+
+void forward() {
+ object.applyCenterForce(10.0 * object.getAhead());
+}
+
+void backward() {
+ object.applyCenterForce(-10.0 * object.getAhead());
+}
+
+void jump() {
+ object.applyCenterForce(MT_Vector3(0.0, 200.0, 0.0));
+}
+
+
+void toggleIdle() {
+ static bool idle = true;
+ if (idle) {
+ glutIdleFunc(moveAndDisplay);
+ idle = false;
+ }
+ else {
+ glutIdleFunc(NULL);
+ idle = true;
+ }
+}
+
+
+void setCamera() {
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 200.0);
+ MT_Scalar rele = MT_radians(ele);
+ MT_Scalar razi = MT_radians(azi);
+ eye.setValue(DISTANCE * sin(razi) * cos(rele),
+ DISTANCE * sin(rele),
+ DISTANCE * cos(razi) * cos(rele));
+ gluLookAt(eye[0], eye[1], eye[2],
+ center[0], center[1], center[2],
+ 0, 1, 0);
+ glMatrixMode(GL_MODELVIEW);
+ display();
+}
+
+const MT_Scalar STEPSIZE = 5;
+
+void stepLeft() { azi -= STEPSIZE; if (azi < 0) azi += 360; setCamera(); }
+void stepRight() { azi += STEPSIZE; if (azi >= 360) azi -= 360; setCamera(); }
+void stepFront() { ele += STEPSIZE; if (azi >= 360) azi -= 360; setCamera(); }
+void stepBack() { ele -= STEPSIZE; if (azi < 0) azi += 360; setCamera(); }
+void zoomIn() { DISTANCE -= 1; setCamera(); }
+void zoomOut() { DISTANCE += 1; setCamera(); }
+
+
+void myReshape(int w, int h) {
+ glViewport(0, 0, w, h);
+ setCamera();
+}
+
+void myKeyboard(unsigned char key, int x, int y)
+{
+ switch (key)
+ {
+ case 'w': forward(); break;
+ case 's': backward(); break;
+ case 'a': turn_left(); break;
+ case 'd': turn_right(); break;
+ case 'e': jump(); break;
+ case 'l' : stepLeft(); break;
+ case 'r' : stepRight(); break;
+ case 'f' : stepFront(); break;
+ case 'b' : stepBack(); break;
+ case 'z' : zoomIn(); break;
+ case 'x' : zoomOut(); break;
+ case 'i' : toggleIdle(); break;
+ case ' ' : newRandom(); break;
+ default:
+// std::cout << "unused key : " << key << std::endl;
+ break;
+ }
+}
+
+void mySpecial(int key, int x, int y)
+{
+ switch (key)
+ {
+ case GLUT_KEY_LEFT : stepLeft(); break;
+ case GLUT_KEY_RIGHT : stepRight(); break;
+ case GLUT_KEY_UP : stepFront(); break;
+ case GLUT_KEY_DOWN : stepBack(); break;
+ case GLUT_KEY_PAGE_UP : zoomIn(); break;
+ case GLUT_KEY_PAGE_DOWN : zoomOut(); break;
+ case GLUT_KEY_HOME : toggleIdle(); break;
+ default:
+// std::cout << "unused (special) key : " << key << std::endl;
+ break;
+ }
+}
+
+void goodbye( void)
+{
+ g_scene.remove(sm_ground);
+ g_scene.remove(sm_sphere);
+
+ std::cout << "goodbye ..." << std::endl;
+ exit(0);
+}
+
+void menu(int choice)
+{
+
+ static int fullScreen = 0;
+ static int px, py, sx, sy;
+
+ switch(choice) {
+ case 1:
+ if (fullScreen == 1) {
+ glutPositionWindow(px,py);
+ glutReshapeWindow(sx,sy);
+ glutChangeToMenuEntry(1,"Full Screen",1);
+ fullScreen = 0;
+ } else {
+ px=glutGet((GLenum)GLUT_WINDOW_X);
+ py=glutGet((GLenum)GLUT_WINDOW_Y);
+ sx=glutGet((GLenum)GLUT_WINDOW_WIDTH);
+ sy=glutGet((GLenum)GLUT_WINDOW_HEIGHT);
+ glutFullScreen();
+ glutChangeToMenuEntry(1,"Close Full Screen",1);
+ fullScreen = 1;
+ }
+ break;
+ case 2:
+ toggleIdle();
+ break;
+ case 3:
+ goodbye();
+ break;
+ default:
+ break;
+ }
+}
+
+void createMenu()
+{
+ glutCreateMenu(menu);
+ glutAddMenuEntry("Full Screen", 1);
+ glutAddMenuEntry("Toggle Idle (Start/Stop)", 2);
+ glutAddMenuEntry("Quit", 3);
+ glutAttachMenu(GLUT_RIGHT_BUTTON);
+}
+
+int main(int argc, char **argv) {
+ glutInit(&argc, argv);
+ glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
+ glutInitWindowPosition(0, 0);
+ glutInitWindowSize(500, 500);
+ glutCreateWindow("Physics demo");
+
+ myinit();
+ glutKeyboardFunc(myKeyboard);
+ glutSpecialFunc(mySpecial);
+ glutReshapeFunc(myReshape);
+ createMenu();
+ glutIdleFunc(NULL);
+
+ glutDisplayFunc(display);
+ glutMainLoop();
+ return 0;
+}
+
+
+
+
+
+
+
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/sample/particle0.cpp b/source/gameengine/Physics/Sumo/Fuzzics/sample/particle0.cpp
new file mode 100644
index 00000000000..1c03621f530
--- /dev/null
+++ b/source/gameengine/Physics/Sumo/Fuzzics/sample/particle0.cpp
@@ -0,0 +1,691 @@
+//#define FAKE_IT
+#define USE_COMPLEX
+#define QUADS
+
+#include <algorithm>
+#include <new>
+#include <GL/glut.h>
+
+#include "MT_MinMax.h"
+#include "MT_Point3.h"
+#include "MT_Vector3.h"
+#include "MT_Quaternion.h"
+#include "MT_Matrix3x3.h"
+#include "MT_Transform.h"
+
+#include "SM_Object.h"
+#include "SM_Scene.h"
+
+#include "solid.h"
+
+const MT_Scalar bowl_curv = 0.10;
+const MT_Scalar timeStep = 0.04;
+const MT_Scalar ground_margin = 0.0;
+const MT_Scalar sphere_radius = 0.5;
+
+const MT_Vector3 gravity(0, -9.8, 0);
+
+static MT_Scalar DISTANCE = 5;
+
+static MT_Scalar ele = 0, azi = 0;
+static MT_Point3 eye(0, 0, DISTANCE);
+static MT_Point3 center(0, 0, 0);
+
+inline double irnd() { return 2 * MT_random() - 1; }
+
+static const double SCALE_BOTTOM = 0.5;
+static const double SCALE_FACTOR = 2.0;
+
+SM_ShapeProps g_shapeProps = {
+ 1.0, // mass
+ 1.0, // inertia
+ 0.9, // linear drag
+ 0.9 // angular drag
+};
+
+SM_MaterialProps g_materialProps = {
+ 0.7, // restitution
+ 0.0, // friction
+ 0.0, // spring constant
+ 0.0 // damping
+};
+
+
+void toggleIdle();
+
+
+void newRandom();
+
+void coordSystem() {
+ glDisable(GL_LIGHTING);
+ glBegin(GL_LINES);
+ glColor3f(1, 0, 0);
+ glVertex3d(0, 0, 0);
+ glVertex3d(10, 0, 0);
+ glColor3f(0, 1, 0);
+ glVertex3d(0, 0, 0);
+ glVertex3d(0, 10, 0);
+ glColor3f(0, 0, 1);
+ glVertex3d(0, 0, 0);
+ glVertex3d(0, 0, 10);
+ glEnd();
+ glEnable(GL_LIGHTING);
+}
+
+
+void display_bbox(const MT_Point3& min, const MT_Point3& max) {
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_LIGHTING);
+ glColor3f(0, 1, 1);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ glBegin(GL_QUAD_STRIP);
+ glVertex3d(min[0], min[1], min[2]);
+ glVertex3d(min[0], min[1], max[2]);
+ glVertex3d(max[0], min[1], min[2]);
+ glVertex3d(max[0], min[1], max[2]);
+ glVertex3d(max[0], max[1], min[2]);
+ glVertex3d(max[0], max[1], max[2]);
+ glVertex3d(min[0], max[1], min[2]);
+ glVertex3d(min[0], max[1], max[2]);
+ glVertex3d(min[0], min[1], min[2]);
+ glVertex3d(min[0], min[1], max[2]);
+ glEnd();
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_DEPTH_TEST);
+}
+
+
+
+
+class GLShape {
+public:
+ virtual void paint(GLdouble *m) const = 0;
+};
+
+
+class GLSphere : public GLShape {
+ MT_Scalar radius;
+public:
+ GLSphere(MT_Scalar r) : radius(r) {}
+
+ void paint(GLdouble *m) const {
+ glPushMatrix();
+ glLoadMatrixd(m);
+ coordSystem();
+ glutSolidSphere(radius, 20, 20);
+ glPopMatrix();
+ }
+};
+
+
+class GLBox : public GLShape {
+ MT_Vector3 extent;
+public:
+ GLBox(MT_Scalar x, MT_Scalar y, MT_Scalar z) :
+ extent(x, y, z) {}
+
+ void paint(GLdouble *m) const {
+ glPushMatrix();
+ glLoadMatrixd(m);
+ coordSystem();
+ glPushMatrix();
+ glScaled(extent[0], extent[1], extent[2]);
+ glutSolidCube(1.0);
+ glPopMatrix();
+ glPopMatrix();
+ }
+};
+
+
+class GLCone : public GLShape {
+ MT_Scalar bottomRadius;
+ MT_Scalar height;
+ mutable GLuint displayList;
+
+public:
+ GLCone(MT_Scalar r, MT_Scalar h) :
+ bottomRadius(r),
+ height(h),
+ displayList(0) {}
+
+ void paint(GLdouble *m) const {
+ glPushMatrix();
+ glLoadMatrixd(m);
+ coordSystem();
+ if (displayList) glCallList(displayList);
+ else {
+ GLUquadricObj *quadObj = gluNewQuadric();
+ displayList = glGenLists(1);
+ glNewList(displayList, GL_COMPILE_AND_EXECUTE);
+ glPushMatrix();
+ glRotatef(-90.0, 1.0, 0.0, 0.0);
+ glTranslatef(0.0, 0.0, -1.0);
+ gluQuadricDrawStyle(quadObj, (GLenum)GLU_FILL);
+ gluQuadricNormals(quadObj, (GLenum)GLU_SMOOTH);
+ gluCylinder(quadObj, bottomRadius, 0, height, 15, 10);
+ glPopMatrix();
+ glEndList();
+ }
+ glPopMatrix();
+ }
+};
+
+class GLCylinder : public GLShape {
+ MT_Scalar radius;
+ MT_Scalar height;
+ mutable GLuint displayList;
+
+public:
+ GLCylinder(MT_Scalar r, MT_Scalar h) :
+ radius(r),
+ height(h),
+ displayList(0) {}
+
+ void paint(GLdouble *m) const {
+ glPushMatrix();
+ glLoadMatrixd(m);
+ coordSystem();
+ if (displayList) glCallList(displayList);
+ else {
+ GLUquadricObj *quadObj = gluNewQuadric();
+ displayList = glGenLists(1);
+ glNewList(displayList, GL_COMPILE_AND_EXECUTE);
+ glPushMatrix();
+ glRotatef(-90.0, 1.0, 0.0, 0.0);
+ glTranslatef(0.0, 0.0, -1.0);
+ gluQuadricDrawStyle(quadObj, (GLenum)GLU_FILL);
+ gluQuadricNormals(quadObj, (GLenum)GLU_SMOOTH);
+ gluCylinder(quadObj, radius, radius, height, 15, 10);
+ glPopMatrix ();
+ glEndList();
+ }
+ glPopMatrix();
+ }
+};
+
+class Object;
+
+class Callback : public SM_Callback {
+public:
+ Callback(Object& object) : m_object(object) {}
+
+ virtual void do_me();
+
+private:
+ Object& m_object;
+};
+
+
+class Object {
+public:
+ Object(GLShape *gl_shape, SM_Object& object) :
+ m_gl_shape(gl_shape),
+ m_object(object),
+ m_callback(*this)
+ {
+ m_object.registerCallback(m_callback);
+ }
+
+ ~Object() {}
+
+ void paint() {
+ m_gl_shape->paint(m);
+ // display_bbox(m_bbox.lower(), m_bbox.upper());
+ }
+
+ MT_Vector3 getAhead() {
+ return MT_Vector3(-m[8], -m[9], -m[10]);
+ }
+
+ void clearMomentum() {
+ m_object.clearMomentum();
+ }
+
+ void setMargin(MT_Scalar margin) {
+ m_object.setMargin(margin);
+ }
+
+ void setScaling(const MT_Vector3& scaling) {
+ m_object.setScaling(scaling);
+ }
+
+ void setPosition(const MT_Point3& pos) {
+ m_object.setPosition(pos);
+ }
+
+ void setOrientation(const MT_Quaternion& orn) {
+ m_object.setOrientation(orn);
+ }
+
+ void applyCenterForce(const MT_Vector3& force) {
+ m_object.applyCenterForce(force);
+ }
+
+ void applyTorque(const MT_Vector3& torque) {
+ m_object.applyTorque(torque);
+ }
+
+ MT_Point3 getWorldCoord(const MT_Point3& local) const {
+ return m_object.getWorldCoord(local);
+ }
+
+ MT_Vector3 getLinearVelocity() const {
+ return m_object.getLinearVelocity();
+ }
+
+ void setMatrix() {
+ m_object.getMatrix(m);
+ }
+
+private:
+ GLShape *m_gl_shape;
+ SM_Object& m_object;
+ DT_Scalar m[16];
+ Callback m_callback;
+};
+
+
+void Callback::do_me()
+{
+ m_object.setMatrix();
+}
+
+
+const MT_Scalar SPACE_SIZE = 2;
+
+static GLSphere gl_sphere(sphere_radius);
+static GLBox gl_ground(50.0, 0.0, 50.0);
+
+
+
+#ifdef USE_COMPLEX
+
+const int GRID_SCALE = 10;
+const MT_Scalar GRID_UNIT = 25.0 / GRID_SCALE;
+
+DT_ShapeHandle createComplex() {
+ DT_ShapeHandle shape = DT_NewComplexShape();
+ for (int i0 = -GRID_SCALE; i0 != GRID_SCALE; ++i0) {
+ for (int j0 = -GRID_SCALE; j0 != GRID_SCALE; ++j0) {
+ int i1 = i0 + 1;
+ int j1 = j0 + 1;
+#ifdef QUADS
+ DT_Begin();
+ DT_Vertex(GRID_UNIT * i0, bowl_curv * i0*i0, GRID_UNIT * j0);
+ DT_Vertex(GRID_UNIT * i0, bowl_curv * i0*i0, GRID_UNIT * j1);
+ DT_Vertex(GRID_UNIT * i1, bowl_curv * i1*i1, GRID_UNIT * j1);
+ DT_Vertex(GRID_UNIT * i1, bowl_curv * i1*i1, GRID_UNIT * j0);
+ DT_End();
+#else
+ DT_Begin();
+ DT_Vertex(GRID_UNIT * i0, 0, GRID_UNIT * j0);
+ DT_Vertex(GRID_UNIT * i0, 0, GRID_UNIT * j1);
+ DT_Vertex(GRID_UNIT * i1, 0, GRID_UNIT * j1);
+ DT_End();
+
+ DT_Begin();
+ DT_Vertex(GRID_UNIT * i0, 0, GRID_UNIT * j1);
+ DT_Vertex(GRID_UNIT * i1, 0, GRID_UNIT * j1);
+ DT_Vertex(GRID_UNIT * i1, 0, GRID_UNIT * j0);
+ DT_End();
+#endif
+
+ }
+ }
+ DT_EndComplexShape();
+ return shape;
+}
+
+
+static DT_ShapeHandle ground_shape = createComplex();
+
+#else
+
+static DT_ShapeHandle ground_shape = DT_Box(50, 0, 50);
+
+#endif
+
+static SM_Object sm_ground(ground_shape, &g_materialProps, 0, 0);
+static Object ground(&gl_ground, sm_ground);
+
+static SM_Object sm_sphere(DT_Sphere(0.0), &g_materialProps, &g_shapeProps, 0);
+static Object object(&gl_sphere, sm_sphere);
+
+
+static SM_Object sm_ray(DT_Ray(0.0, -1.0, 0.0), 0, 0, 0);
+
+static SM_Scene g_scene;
+
+
+void myinit(void) {
+
+ GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
+ GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
+ GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
+
+ /* light_position is NOT default value */
+ GLfloat light_position0[] = { 1.0, 1.0, 1.0, 0.0 };
+ GLfloat light_position1[] = { -1.0, -1.0, -1.0, 0.0 };
+
+ glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
+ glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
+ glLightfv(GL_LIGHT0, GL_POSITION, light_position0);
+
+ glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient);
+ glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
+ glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular);
+ glLightfv(GL_LIGHT1, GL_POSITION, light_position1);
+
+
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+ glEnable(GL_LIGHT1);
+
+ glShadeModel(GL_SMOOTH);
+
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LESS);
+
+ // glEnable(GL_CULL_FACE);
+ // glCullFace(GL_BACK);
+
+ g_scene.setForceField(gravity);
+ g_scene.add(sm_ground);
+ sm_ground.setMargin(ground_margin);
+
+ new(&object) Object(&gl_sphere, sm_sphere);
+
+
+ object.setMargin(sphere_radius);
+
+ g_scene.add(sm_sphere);
+
+ ground.setPosition(MT_Point3(0, -10, 0));
+ ground.setOrientation(MT_Quaternion(0, 0, 0, 1));
+ ground.setMatrix();
+ center.setValue(0.0, 0.0, 0.0);
+
+ newRandom();
+}
+
+
+//MT_Point3 cp1, cp2;
+//bool intersection;
+
+bool g_hit = false;
+MT_Point3 g_spot;
+MT_Vector3 g_normal;
+
+
+void display(void) {
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ ground.paint();
+ object.paint();
+
+ if (g_hit) {
+ glPointSize(5);
+ glBegin(GL_POINTS);
+ glVertex3d(g_spot[0], g_spot[1], g_spot[2]);
+ glEnd();
+ glPointSize(1);
+ }
+
+
+
+#ifdef COLLISION
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_LIGHTING);
+ glColor3f(1, 1, 0);
+ if (intersection) {
+ glPointSize(5);
+ glBegin(GL_POINTS);
+ glVertex3d(cp1[0], cp1[1], cp1[2]);
+ glEnd();
+ glPointSize(1);
+ }
+ else {
+ glBegin(GL_LINES);
+ glVertex3d(cp1[0], cp1[1], cp1[2]);
+ glVertex3d(cp2[0], cp2[1], cp2[2]);
+ glEnd();
+ }
+ glEnable(GL_LIGHTING);
+ glEnable(GL_DEPTH_TEST);
+#endif
+
+ glFlush();
+ glutSwapBuffers();
+}
+
+
+
+
+
+void newRandom() {
+ object.setPosition(MT_Point3(0, 0, 0));
+ object.clearMomentum();
+ object.setMatrix();
+
+ display();
+}
+
+void moveAndDisplay() {
+ g_scene.proceed(timeStep, 0.01);
+
+ MT_Vector3 normal(0, 1, 0);
+
+ MT_Point3 from = object.getWorldCoord(MT_Point3(0, 0, 0));
+ MT_Point3 to = from - normal * 10.0;
+
+ g_hit = DT_ObjectRayTest(sm_ground.getObjectHandle(),
+ from.getValue(),
+ to.getValue(), g_spot.getValue(),
+ g_normal.getValue());
+
+ // Scrap
+#define DO_FH
+#ifdef DO_FH
+ MT_Scalar dist = MT_distance(from, g_spot);
+ if (dist < 5.0) {
+ MT_Vector3 lin_vel = object.getLinearVelocity();
+ MT_Scalar lin_vel_normal = lin_vel.dot(normal);
+
+ MT_Scalar spring_extent = dist + lin_vel_normal * (timeStep * 0.5);
+
+ MT_Scalar f_spring = (5.0 - spring_extent) * 3.0;
+ object.applyCenterForce(normal * f_spring);
+ object.applyCenterForce(-lin_vel_normal * normal);
+ }
+
+#endif
+
+
+ display();
+}
+
+
+void turn_left() {
+ object.applyTorque(MT_Vector3(0.0, 10.0, 0.0));
+}
+
+void turn_right() {
+ object.applyTorque(MT_Vector3(0.0, -10.0, 0.0));
+}
+
+void forward() {
+ object.applyCenterForce(20.0 * object.getAhead());
+}
+
+void backward() {
+ object.applyCenterForce(-20.0 * object.getAhead());
+}
+
+void jump() {
+ object.applyCenterForce(MT_Vector3(0.0, 200.0, 0.0));
+}
+
+
+void toggleIdle() {
+ static bool idle = true;
+ if (idle) {
+ glutIdleFunc(moveAndDisplay);
+ idle = false;
+ }
+ else {
+ glutIdleFunc(NULL);
+ idle = true;
+ }
+}
+
+
+void setCamera() {
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 200.0);
+ MT_Scalar rele = MT_radians(ele);
+ MT_Scalar razi = MT_radians(azi);
+ eye.setValue(DISTANCE * sin(razi) * cos(rele),
+ DISTANCE * sin(rele),
+ DISTANCE * cos(razi) * cos(rele));
+ gluLookAt(eye[0], eye[1], eye[2],
+ center[0], center[1], center[2],
+ 0, 1, 0);
+ glMatrixMode(GL_MODELVIEW);
+ display();
+}
+
+const MT_Scalar STEPSIZE = 5;
+
+void stepLeft() { azi -= STEPSIZE; if (azi < 0) azi += 360; setCamera(); }
+void stepRight() { azi += STEPSIZE; if (azi >= 360) azi -= 360; setCamera(); }
+void stepFront() { ele += STEPSIZE; if (azi >= 360) azi -= 360; setCamera(); }
+void stepBack() { ele -= STEPSIZE; if (azi < 0) azi += 360; setCamera(); }
+void zoomIn() { DISTANCE -= 1; setCamera(); }
+void zoomOut() { DISTANCE += 1; setCamera(); }
+
+
+void myReshape(int w, int h) {
+ glViewport(0, 0, w, h);
+ setCamera();
+}
+
+void myKeyboard(unsigned char key, int x, int y)
+{
+ switch (key)
+ {
+ case 'w': forward(); break;
+ case 's': backward(); break;
+ case 'a': turn_left(); break;
+ case 'd': turn_right(); break;
+ case 'e': jump(); break;
+ case 'l' : stepLeft(); break;
+ case 'r' : stepRight(); break;
+ case 'f' : stepFront(); break;
+ case 'b' : stepBack(); break;
+ case 'z' : zoomIn(); break;
+ case 'x' : zoomOut(); break;
+ case 'i' : toggleIdle(); break;
+ case ' ' : newRandom(); break;
+ default:
+// std::cout << "unused key : " << key << std::endl;
+ break;
+ }
+}
+
+void mySpecial(int key, int x, int y)
+{
+ switch (key)
+ {
+ case GLUT_KEY_LEFT : stepLeft(); break;
+ case GLUT_KEY_RIGHT : stepRight(); break;
+ case GLUT_KEY_UP : stepFront(); break;
+ case GLUT_KEY_DOWN : stepBack(); break;
+ case GLUT_KEY_PAGE_UP : zoomIn(); break;
+ case GLUT_KEY_PAGE_DOWN : zoomOut(); break;
+ case GLUT_KEY_HOME : toggleIdle(); break;
+ default:
+// std::cout << "unused (special) key : " << key << std::endl;
+ break;
+ }
+}
+
+void goodbye( void)
+{
+ g_scene.remove(sm_ground);
+ g_scene.remove(sm_sphere);
+
+ std::cout << "goodbye ..." << std::endl;
+ exit(0);
+}
+
+void menu(int choice)
+{
+
+ static int fullScreen = 0;
+ static int px, py, sx, sy;
+
+ switch(choice) {
+ case 1:
+ if (fullScreen == 1) {
+ glutPositionWindow(px,py);
+ glutReshapeWindow(sx,sy);
+ glutChangeToMenuEntry(1,"Full Screen",1);
+ fullScreen = 0;
+ } else {
+ px=glutGet((GLenum)GLUT_WINDOW_X);
+ py=glutGet((GLenum)GLUT_WINDOW_Y);
+ sx=glutGet((GLenum)GLUT_WINDOW_WIDTH);
+ sy=glutGet((GLenum)GLUT_WINDOW_HEIGHT);
+ glutFullScreen();
+ glutChangeToMenuEntry(1,"Close Full Screen",1);
+ fullScreen = 1;
+ }
+ break;
+ case 2:
+ toggleIdle();
+ break;
+ case 3:
+ goodbye();
+ break;
+ default:
+ break;
+ }
+}
+
+void createMenu()
+{
+ glutCreateMenu(menu);
+ glutAddMenuEntry("Full Screen", 1);
+ glutAddMenuEntry("Toggle Idle (Start/Stop)", 2);
+ glutAddMenuEntry("Quit", 3);
+ glutAttachMenu(GLUT_RIGHT_BUTTON);
+}
+
+int main(int argc, char **argv) {
+ glutInit(&argc, argv);
+ glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
+ glutInitWindowPosition(0, 0);
+ glutInitWindowSize(500, 500);
+ glutCreateWindow("Physics demo");
+
+ myinit();
+ glutKeyboardFunc(myKeyboard);
+ glutSpecialFunc(mySpecial);
+ glutReshapeFunc(myReshape);
+ createMenu();
+ glutIdleFunc(NULL);
+
+ glutDisplayFunc(display);
+ glutMainLoop();
+ return 0;
+}
+
+
+
+
+
+
+
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/src/Makefile b/source/gameengine/Physics/Sumo/Fuzzics/src/Makefile
new file mode 100644
index 00000000000..5e3b35f6cf4
--- /dev/null
+++ b/source/gameengine/Physics/Sumo/Fuzzics/src/Makefile
@@ -0,0 +1,13 @@
+#
+# $Id$
+# Copyright (C) 2001 NaN Technologies B.V.
+
+LIBNAME = fuzzics
+DIR = $(OCGDIR)/sumo
+
+include nan_compile.mk
+
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+CPPFLAGS += -I../include -I$(NAN_MOTO)/include -I../../include
+
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_FhObject.cpp b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_FhObject.cpp
new file mode 100644
index 00000000000..f8be49aa126
--- /dev/null
+++ b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_FhObject.cpp
@@ -0,0 +1,115 @@
+#include "SM_FhObject.h"
+#include "MT_MinMax.h"
+
+void SM_FhObject::ray_hit(void *client_data,
+ void *client_object1,
+ void *client_object2,
+ const DT_CollData *coll_data) {
+
+ SM_Object *hit_object = (SM_Object *)client_object1;
+ const SM_MaterialProps *matProps = hit_object->getMaterialProps();
+
+ if ((matProps == 0) || (matProps->m_fh_distance < MT_EPSILON)) {
+ return;
+ }
+
+ SM_FhObject *fh_object = (SM_FhObject *)client_object2;
+ SM_Object *cl_object = fh_object->getClientObject();
+
+ if (hit_object == cl_object) {
+ // Shot myself in the foot...
+ return;
+ }
+
+ const SM_ShapeProps *shapeProps = cl_object->getShapeProps();
+
+ // Exit if the client object is not dynamic.
+ if (shapeProps == 0) {
+ return;
+ }
+
+ MT_Point3 lspot;
+ MT_Vector3 normal;
+
+ if (DT_ObjectRayTest(hit_object->getObjectHandle(),
+ fh_object->getPosition().getValue(),
+ fh_object->getSpot().getValue(),
+ lspot.getValue(), normal.getValue())) {
+
+ const MT_Vector3& ray_dir = fh_object->getRayDirection();
+ MT_Scalar dist = MT_distance(fh_object->getPosition(),
+ hit_object->getWorldCoord(lspot)) -
+ cl_object->getMargin();
+
+ normal.normalize();
+
+ if (dist < matProps->m_fh_distance) {
+
+ if (shapeProps->m_do_fh) {
+ MT_Vector3 rel_vel = cl_object->getLinearVelocity() - hit_object->getVelocity(lspot);
+ MT_Scalar rel_vel_ray = ray_dir.dot(rel_vel);
+ MT_Scalar spring_extent = 1.0 - dist / matProps->m_fh_distance;
+
+ MT_Scalar i_spring = spring_extent * matProps->m_fh_spring;
+ MT_Scalar i_damp = rel_vel_ray * matProps->m_fh_damping;
+
+ cl_object->addLinearVelocity(-(i_spring + i_damp) * ray_dir);
+ if (matProps->m_fh_normal) {
+ cl_object->addLinearVelocity(
+ (i_spring + i_damp) *
+ (normal - normal.dot(ray_dir) * ray_dir));
+ }
+
+ MT_Vector3 lateral = rel_vel - rel_vel_ray * ray_dir;
+ const SM_ShapeProps *shapeProps = cl_object->getShapeProps();
+
+ if (shapeProps->m_do_anisotropic) {
+ MT_Matrix3x3 lcs(cl_object->getOrientation());
+ MT_Vector3 loc_lateral = lateral * lcs;
+ const MT_Vector3& friction_scaling =
+ shapeProps->m_friction_scaling;
+
+ loc_lateral.scale(friction_scaling[0],
+ friction_scaling[1],
+ friction_scaling[2]);
+ lateral = lcs * loc_lateral;
+ }
+
+
+ MT_Scalar rel_vel_lateral = lateral.length();
+
+ if (rel_vel_lateral > MT_EPSILON) {
+ MT_Scalar friction_factor = matProps->m_friction;
+ MT_Scalar max_friction = friction_factor * MT_max(0.0, i_spring);
+
+ MT_Scalar rel_mom_lateral = rel_vel_lateral /
+ cl_object->getInvMass();
+
+ MT_Vector3 friction =
+ (rel_mom_lateral > max_friction) ?
+ -lateral * (max_friction / rel_vel_lateral) :
+ -lateral;
+
+ cl_object->applyCenterImpulse(friction);
+ }
+ }
+
+ if (shapeProps->m_do_rot_fh) {
+ const double *ogl_mat = cl_object->getMatrix();
+ MT_Vector3 up(&ogl_mat[8]);
+ MT_Vector3 t_spring = up.cross(normal) * matProps->m_fh_spring;
+ MT_Vector3 ang_vel = cl_object->getAngularVelocity();
+
+ // only rotations that tilt relative to the normal are damped
+ ang_vel -= ang_vel.dot(normal) * normal;
+
+ MT_Vector3 t_damp = ang_vel * matProps->m_fh_damping;
+
+ cl_object->addAngularVelocity(t_spring - t_damp);
+ }
+ }
+ }
+}
+
+
+
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp
new file mode 100644
index 00000000000..655590c2086
--- /dev/null
+++ b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp
@@ -0,0 +1,953 @@
+/**
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * The basic physics object.
+ */
+
+#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 "SM_Object.h"
+#include "SM_Scene.h"
+#include "SM_FhObject.h"
+
+#include "MT_MinMax.h"
+
+
+// Tweak parameters
+static MT_Scalar ImpulseThreshold = 0.5;
+
+SM_Object::SM_Object(
+ DT_ShapeHandle shape,
+ const SM_MaterialProps *materialProps,
+ const SM_ShapeProps *shapeProps,
+ SM_Object *dynamicParent
+) :
+ m_shape(shape),
+ m_materialProps(materialProps),
+ m_materialPropsBackup(0),
+ m_shapeProps(shapeProps),
+ m_shapePropsBackup(0),
+ m_dynamicParent(dynamicParent),
+ m_object(DT_CreateObject(this, shape)),
+ m_margin(0.0),
+ m_scaling(1.0, 1.0, 1.0),
+ m_reaction_impulse(0.0, 0.0, 0.0),
+ m_reaction_force(0.0, 0.0, 0.0),
+ m_kinematic(false),
+ m_prev_kinematic(false),
+ m_is_rigid_body(false),
+ m_lin_mom(0.0, 0.0, 0.0),
+ m_ang_mom(0.0, 0.0, 0.0),
+ m_force(0.0, 0.0, 0.0),
+ m_torque(0.0, 0.0, 0.0),
+ m_client_object(0),
+ m_fh_object(0),
+
+ m_combined_lin_vel (0.0, 0.0, 0.0),
+ m_combined_ang_vel (0.0, 0.0, 0.0)
+{
+ m_xform.setIdentity();
+ m_xform.getValue(m_ogl_matrix);
+ if (shapeProps &&
+ (shapeProps->m_do_fh || shapeProps->m_do_rot_fh)) {
+ MT_Vector3 ray(0.0, 0.0, -10.0);
+ m_fh_object = new SM_FhObject(ray, this);
+ }
+ m_suspended = false;
+}
+
+
+ void
+SM_Object::
+integrateForces(
+ MT_Scalar timeStep
+){
+ if (!m_suspended) {
+ m_prev_state = *this;
+ m_prev_state.setLinearVelocity(actualLinVelocity());
+ m_prev_state.setAngularVelocity(actualAngVelocity());
+ if (isDynamic()) {
+ // Integrate momentum (forward Euler)
+ m_lin_mom += m_force * timeStep;
+ m_ang_mom += m_torque * timeStep;
+ // Drain momentum because of air/water resistance
+ m_lin_mom *= pow(m_shapeProps->m_lin_drag, timeStep);
+ m_ang_mom *= pow(m_shapeProps->m_ang_drag, timeStep);
+ // Set velocities according momentum
+ m_lin_vel = m_lin_mom / m_shapeProps->m_mass;
+ m_ang_vel = m_ang_mom / m_shapeProps->m_inertia;
+ }
+ }
+
+};
+
+ void
+SM_Object::
+integrateMomentum(
+ MT_Scalar timeStep
+){
+ // Integrate position and orientation
+
+ // only do it for objects with linear and/or angular velocity
+ // else clients with hierarchies may get into trouble
+ if (!actualLinVelocity().fuzzyZero() || !actualAngVelocity().fuzzyZero())
+ {
+
+ // those MIDPOINT and BACKWARD integration methods are
+ // in this form not ok with some testfiles !
+ // For a release build please use forward euler unless completely tested
+[
+//#define MIDPOINT
+//#define BACKWARD
+#ifdef MIDPOINT
+// Midpoint rule
+ m_pos += (m_prev_state.getLinearVelocity() + actualLinVelocity()) * (timeStep * 0.5);
+ m_orn += (m_prev_state.getAngularVelocity() * m_prev_state.getOrientation() + actualAngVelocity() * m_orn) * (timeStep * 0.25);
+#elif defined BACKWARD
+// Backward Euler
+ m_pos += actualLinVelocity() * timeStep;
+ m_orn += actualAngVelocity() * m_orn * (timeStep * 0.5);
+#else
+// Forward Euler
+
+ m_pos += m_prev_state.getLinearVelocity() * timeStep;
+ m_orn += m_prev_state.getAngularVelocity() * m_orn * (timeStep * 0.5);
+#endif
+ m_orn.normalize(); // I might not be necessary to do this every call
+
+ calcXform();
+ notifyClient();
+
+ }
+}
+
+
+void SM_Object::boing(
+ void *client_data,
+ void *object1,
+ void *object2,
+ const DT_CollData *coll_data
+){
+ SM_Scene *scene = (SM_Scene *)client_data;
+ SM_Object *obj1 = (SM_Object *)object1;
+ SM_Object *obj2 = (SM_Object *)object2;
+
+ scene->addPair(obj1, obj2); // Record this collision for client callbacks
+
+
+ // If one of the objects is a ghost then ignore it for the dynamics
+ if (obj1->isGhost() || obj2->isGhost()) {
+ return;
+ }
+
+
+ if (!obj2->isDynamic()) {
+ std::swap(obj1, obj2);
+ }
+
+ if (!obj2->isDynamic()) {
+ return;
+ }
+
+ // obj1 points to a dynamic object
+
+
+ // This distinction between dynamic and non-dynamic objects should not be
+ // necessary. Non-dynamic objects are assumed to have infinite mass.
+
+ if (obj1->isDynamic()) {
+ // normal to the contact plane
+ MT_Vector3 normal = obj2->m_pos - obj1->m_pos;
+ MT_Scalar dist = normal.length();
+
+ if (MT_EPSILON < dist && dist <= obj1->getMargin() + obj2->getMargin())
+ {
+ normal /= dist;
+ // relative velocity of the contact points
+ MT_Vector3 rel_vel = obj2->actualLinVelocity() - obj1->actualLinVelocity();
+ // relative velocity projected onto the normal
+ MT_Scalar rel_vel_normal = normal.dot(rel_vel);
+
+ // if the objects are approaching eachother...
+ if (rel_vel_normal < 0.0) {
+ MT_Scalar restitution;
+ // ...and the approaching velocity is large enough...
+ if (-rel_vel_normal > ImpulseThreshold) {
+ // ...this must be a true collision.
+ restitution =
+ MT_min(obj1->getMaterialProps()->m_restitution,
+ obj2->getMaterialProps()->m_restitution);
+ }
+ else {
+ // otherwise, it is a resting contact, and thus the
+ // relative velocity must be made zero
+ restitution = 0.0;
+ // We also need to interfere with the positions of the
+ // objects, otherwise they might drift into eachother.
+ MT_Vector3 penalty = normal *
+ (0.5 * (obj1->getMargin() + obj2->getMargin() - dist));
+ obj1->m_pos -= penalty;
+ obj2->m_pos += penalty;
+ }
+
+ // Compute the impulse necessary to yield the desired relative velocity...
+ MT_Scalar impulse = -(1.0 + restitution) * rel_vel_normal /
+ (obj1->getInvMass() + obj2->getInvMass());
+
+ // ... and apply it.
+ obj1->applyCenterImpulse(-impulse * normal);
+ obj2->applyCenterImpulse( impulse * normal);
+ }
+ }
+ }
+ else {
+ // Same again but now obj1 is non-dynamic
+
+ // Compute the point on obj1 closest to obj2 (= sphere with radius = 0)
+ MT_Point3 local1, local2;
+ MT_Scalar dist = DT_GetClosestPair(obj1->m_object, obj2->m_object,
+ local1.getValue(), local2.getValue());
+
+ // local1 is th point closest to obj2
+ // local2 is the local origin of obj2
+
+ if (MT_EPSILON < dist && dist <= obj2->getMargin()) {
+ MT_Point3 world1 = obj1->getWorldCoord(local1);
+ MT_Point3 world2 = obj2->getWorldCoord(local2);
+ MT_Vector3 vel1 = obj1->getVelocity(local1) + obj1->m_combined_lin_vel;
+ MT_Vector3 vel2 = obj2->getVelocity(local2) + obj2->m_combined_lin_vel;
+
+ // the normal to the contact plane
+ MT_Vector3 normal = world2 - world1;
+ normal /= dist;
+
+ // wr2 points from obj2's origin to the global contact point
+ // wr2 is only needed for rigid bodies (objects for which the
+ // friction can change the angular momentum).
+ // vel2 is adapted to denote the velocity of the contact point
+ MT_Vector3 wr2;
+ if (obj2->isRigidBody()) {
+ wr2 = -obj2->getMargin() * normal;
+ vel2 += obj2->actualAngVelocity().cross(wr2);
+ }
+
+
+ // This should look familiar....
+ MT_Vector3 rel_vel = vel2 - vel1;
+ MT_Scalar rel_vel_normal = normal.dot(rel_vel);
+
+ if (rel_vel_normal < 0.0) {
+ MT_Scalar restitution;
+ if (-rel_vel_normal > ImpulseThreshold) {
+ restitution =
+ MT_min(obj1->getMaterialProps()->m_restitution,
+ obj2->getMaterialProps()->m_restitution);
+ }
+ else {
+ restitution = 0.0;
+ // We fix drift by moving obj2 only, since obj1 was
+ // non-dynamic.
+ obj2->m_pos += normal * (obj2->getMargin() - dist);
+
+ }
+
+ MT_Scalar impulse = -(1.0 + restitution) * rel_vel_normal /
+ (obj1->getInvMass() + obj2->getInvMass());
+
+
+ obj2->applyCenterImpulse( impulse * normal);
+
+// The friction part starts here!!!!!!!!
+
+ // Compute the lateral component of the relative velocity
+ // lateral actually points in the opposite direction, i.e.,
+ // into the direction of the friction force.
+
+#if 1
+ // test - only do friction on the physics part of the
+ // velocity.
+ vel1 -= obj1->m_combined_lin_vel;
+ vel2 -= obj2->m_combined_lin_vel;
+
+ // This should look familiar....
+ rel_vel = vel2 - vel1;
+ rel_vel_normal = normal.dot(rel_vel);
+#endif
+
+ MT_Vector3 lateral = normal * rel_vel_normal - rel_vel;
+
+ const SM_ShapeProps *shapeProps = obj2->getShapeProps();
+
+ if (shapeProps->m_do_anisotropic) {
+
+ // For anisotropic friction we scale the lateral component,
+ // rather than compute a direction-dependent fricition
+ // factor. For this the lateral component is transformed to
+ // local coordinates.
+
+ MT_Matrix3x3 lcs(obj2->m_orn);
+ // We cannot use m_xform.getBasis() for the matrix, since
+ // it might contain a non-uniform scaling.
+ // OPT: it's a bit daft to compute the matrix since the
+ // quaternion itself can be used to do the transformation.
+
+ MT_Vector3 loc_lateral = lateral * lcs;
+ // lcs is orthogonal so lcs.inversed() == lcs.transposed(),
+ // and lcs.transposed() * lateral == lateral * lcs.
+
+ const MT_Vector3& friction_scaling =
+ shapeProps->m_friction_scaling;
+
+ // Scale the local lateral...
+ loc_lateral.scale(friction_scaling[0],
+ friction_scaling[1],
+ friction_scaling[2]);
+ // ... and transform it back to global coordinates
+ lateral = lcs * loc_lateral;
+ }
+
+ // A tiny Coulomb friction primer:
+ // The Coulomb friction law states that the magnitude of the
+ // maximum possible friction force depends linearly on the
+ // magnitude of the normal force.
+ //
+ // F_max_friction = friction_factor * F_normal
+ //
+ // (NB: independent of the contact area!!)
+ //
+ // The friction factor depends on the material.
+ // We use impulses rather than forces but let us not be
+ // bothered by this.
+
+
+ MT_Scalar rel_vel_lateral = lateral.length();
+
+ if (rel_vel_lateral > MT_EPSILON) {
+ lateral /= rel_vel_lateral;
+
+ MT_Scalar friction_factor =
+ MT_min(obj1->getMaterialProps()->m_friction,
+ obj2->getMaterialProps()->m_friction);
+
+ // Compute the maximum friction impulse
+
+ MT_Scalar max_friction =
+ friction_factor * MT_max(0.0, impulse);
+
+ // I guess the GEN_max is not necessary, so let's check it
+
+ assert(impulse >= 0.0);
+
+ // Here's the trick. We compute the impulse to make the
+ // lateral velocity zero. (Make the objects stick together
+ // at the contact point. If this impulse is larger than
+ // the maximum possible friction impulse, then shrink its
+ // magnitude to the maximum friction.
+
+ if (obj2->isRigidBody()) {
+
+ // For rigid bodies we take the inertia into account,
+ // since the friciton impulse is going to change the
+ // angular momentum as well.
+ MT_Scalar impulse_lateral = rel_vel_lateral /
+ (obj1->getInvMass() + obj2->getInvMass() +
+ ((obj2->getInvInertia() * wr2.cross(lateral)).cross(wr2)).dot(lateral));
+ MT_Scalar friction = MT_min(impulse_lateral, max_friction);
+ obj2->applyImpulse(world2 + wr2, friction * lateral);
+ }
+ else {
+ MT_Scalar impulse_lateral = rel_vel_lateral /
+ (obj1->getInvMass() + obj2->getInvMass());
+
+ MT_Scalar friction = MT_min(impulse_lateral, max_friction);
+ obj2->applyCenterImpulse( friction * lateral);
+ }
+ }
+
+ obj2->calcXform();
+ obj2->notifyClient();
+ }
+ }
+ }
+}
+
+
+
+SM_Object::SM_Object(
+) {
+ // warning no initialization of variables done by moto.
+}
+
+SM_Object::
+~SM_Object() {
+ delete m_fh_object;
+ DT_DeleteObject(m_object);
+}
+
+ bool
+SM_Object::
+isDynamic(
+) const {
+ return m_shapeProps != 0;
+}
+
+/* nzc experimental. There seem to be two places where kinematics
+ * are evaluated: proceedKinematic (called from SM_Scene) and
+ * proceed() in this object. I'll just try and bunge these out for
+ * now. */
+ void
+SM_Object::
+suspend(
+){
+ if (!m_suspended) {
+ m_suspended = true;
+ suspendDynamics();
+ }
+}
+
+ void
+SM_Object::
+resume(
+) {
+ if (m_suspended) {
+ m_suspended = false;
+ restoreDynamics();
+ }
+}
+
+ void
+SM_Object::
+suspendDynamics(
+) {
+ if (m_shapeProps) {
+ m_shapePropsBackup = m_shapeProps;
+ m_shapeProps = 0;
+ }
+}
+
+ void
+SM_Object::
+restoreDynamics(
+) {
+ if (m_shapePropsBackup) {
+ m_shapeProps = m_shapePropsBackup;
+ m_shapePropsBackup = 0;
+ }
+}
+
+ bool
+SM_Object::
+isGhost(
+) const {
+ return m_materialProps == 0;
+}
+
+ void
+SM_Object::
+suspendMaterial(
+) {
+ if (m_materialProps) {
+ m_materialPropsBackup = m_materialProps;
+ m_materialProps = 0;
+ }
+}
+
+ void
+SM_Object::
+restoreMaterial(
+) {
+ if (m_materialPropsBackup) {
+ m_materialProps = m_materialPropsBackup;
+ m_materialPropsBackup = 0;
+ }
+}
+
+ SM_FhObject *
+SM_Object::
+getFhObject(
+) const {
+ return m_fh_object;
+}
+
+ void
+SM_Object::
+registerCallback(
+ SM_Callback& callback
+) {
+ m_callbackList.push_back(&callback);
+}
+
+// Set the local coordinate system according to the current state
+ void
+SM_Object::
+calcXform() {
+ m_xform.setOrigin(m_pos);
+ m_xform.setBasis(MT_Matrix3x3(m_orn, m_scaling));
+ m_xform.getValue(m_ogl_matrix);
+ DT_SetMatrixd(m_object, m_ogl_matrix);
+ if (m_fh_object) {
+ m_fh_object->setPosition(m_pos);
+ m_fh_object->calcXform();
+ }
+}
+
+// Call callbacks to notify the client of a change of placement
+ void
+SM_Object::
+notifyClient() {
+ T_CallbackList::iterator i;
+ for (i = m_callbackList.begin(); i != m_callbackList.end(); ++i) {
+ (*i)->do_me();
+ }
+}
+
+
+// Save the current state information for use in the velocity computation in the next frame.
+ void
+SM_Object::
+proceedKinematic(
+ MT_Scalar timeStep
+) {
+ /* nzc: need to bunge this for the logic bubbling as well? */
+ if (!m_suspended) {
+ m_prev_kinematic = m_kinematic;
+ if (m_kinematic) {
+ m_prev_xform = m_xform;
+ m_timeStep = timeStep;
+ calcXform();
+ m_kinematic = false;
+ }
+ }
+}
+
+ void
+SM_Object::
+saveReactionForce(
+ MT_Scalar timeStep
+) {
+ if (isDynamic()) {
+ m_reaction_force = m_reaction_impulse / timeStep;
+ m_reaction_impulse.setValue(0.0, 0.0, 0.0);
+ }
+}
+
+ void
+SM_Object::
+clearForce(
+) {
+ m_force.setValue(0.0, 0.0, 0.0);
+ m_torque.setValue(0.0, 0.0, 0.0);
+}
+
+ void
+SM_Object::
+clearMomentum(
+) {
+ m_lin_mom.setValue(0.0, 0.0, 0.0);
+ m_ang_mom.setValue(0.0, 0.0, 0.0);
+}
+
+ void
+SM_Object::
+setMargin(
+ MT_Scalar margin
+) {
+ m_margin = margin;
+ DT_SetMargin(m_object, margin);
+}
+
+ MT_Scalar
+SM_Object::
+getMargin(
+) const {
+ return m_margin;
+}
+
+const
+ SM_MaterialProps *
+SM_Object::
+getMaterialProps(
+) const {
+ return m_materialProps;
+}
+
+const
+ SM_ShapeProps *
+SM_Object::
+getShapeProps(
+) const {
+ return m_shapeProps;
+}
+
+ void
+SM_Object::
+setPosition(
+ const MT_Point3& pos
+){
+ m_kinematic = true;
+ m_pos = pos;
+}
+
+ void
+SM_Object::
+setOrientation(
+ const MT_Quaternion& orn
+){
+ assert(!orn.fuzzyZero());
+ m_kinematic = true;
+ m_orn = orn;
+}
+
+ void
+SM_Object::
+setScaling(
+ const MT_Vector3& scaling
+){
+ m_kinematic = true;
+ m_scaling = scaling;
+}
+
+/**
+ * Functions to handle linear velocity
+ */
+
+ void
+SM_Object::
+setExternalLinearVelocity(
+ const MT_Vector3& lin_vel
+) {
+ m_combined_lin_vel=lin_vel;
+}
+
+ void
+SM_Object::
+addExternalLinearVelocity(
+ const MT_Vector3& lin_vel
+) {
+ m_combined_lin_vel+=lin_vel;
+}
+
+ void
+SM_Object::
+addLinearVelocity(
+ const MT_Vector3& lin_vel
+){
+ m_lin_vel += lin_vel;
+ if (m_shapeProps) {
+ m_lin_mom = m_lin_vel * m_shapeProps->m_mass;
+ }
+}
+
+ void
+SM_Object::
+setLinearVelocity(
+ const MT_Vector3& lin_vel
+){
+ m_lin_vel = lin_vel;
+ if (m_shapeProps) {
+ m_lin_mom = m_lin_vel * m_shapeProps->m_mass;
+ }
+}
+
+/**
+ * Functions to handle angular velocity
+ */
+
+ void
+SM_Object::
+setExternalAngularVelocity(
+ const MT_Vector3& ang_vel
+) {
+ m_combined_ang_vel = ang_vel;
+}
+
+ void
+SM_Object::
+addExternalAngularVelocity(
+ const MT_Vector3& ang_vel
+) {
+ m_combined_ang_vel += ang_vel;
+}
+
+ void
+SM_Object::
+setAngularVelocity(
+ const MT_Vector3& ang_vel
+) {
+ m_ang_vel = ang_vel;
+ if (m_shapeProps) {
+ m_ang_mom = m_ang_vel * m_shapeProps->m_inertia;
+ }
+}
+
+ void
+SM_Object::
+addAngularVelocity(
+ const MT_Vector3& ang_vel
+) {
+ m_ang_vel += ang_vel;
+ if (m_shapeProps) {
+ m_ang_mom = m_ang_vel * m_shapeProps->m_inertia;
+ }
+}
+
+
+ void
+SM_Object::
+clearCombinedVelocities(
+) {
+ m_combined_lin_vel = MT_Vector3(0,0,0);
+ m_combined_ang_vel = MT_Vector3(0,0,0);
+}
+
+ void
+SM_Object::
+resolveCombinedVelocities(
+ const MT_Vector3 & lin_vel,
+ const MT_Vector3 & ang_vel
+) {
+
+ // Different behaviours for dynamic and non-dynamic
+ // objects. For non-dynamic we just set the velocity to
+ // zero. For dynmic the physics velocity has to be
+ // taken into account. We must make an arbitrary decision
+ // on how to resolve the 2 velocities. Choices are
+ // Add the physics velocity to the linear velocity. Objects
+ // will just keep on moving in the direction they were
+ // last set in - untill external forces affect them.
+ // Set the combinbed linear and physics velocity to zero.
+ // Set the physics velocity in the direction of the set velocity
+ // zero.
+ if (isDynamic()) {
+
+#if 1
+ m_lin_vel += lin_vel;
+ m_ang_vel += ang_vel;
+#else
+
+ //compute the component of the physics velocity in the
+ // direction of the set velocity and set it to zero.
+ MT_Vector3 lin_vel_norm = lin_vel.normalized();
+
+ m_lin_vel -= (m_lin_vel.dot(lin_vel_norm) * lin_vel_norm);
+#endif
+ m_lin_mom = m_lin_vel * m_shapeProps->m_mass;
+ m_ang_mom = m_ang_vel * m_shapeProps->m_inertia;
+ clearCombinedVelocities();
+
+ }
+
+}
+
+
+ MT_Scalar
+SM_Object::
+getInvMass(
+) const {
+ return m_shapeProps ? 1.0 / m_shapeProps->m_mass : 0.0;
+ // OPT: cache the result of this division rather than compute it each call
+}
+
+ MT_Scalar
+SM_Object::
+getInvInertia(
+) const {
+ return m_shapeProps ? 1.0 / m_shapeProps->m_inertia : 0.0;
+ // OPT: cache the result of this division rather than compute it each call
+}
+
+ void
+SM_Object::
+applyForceField(
+ const MT_Vector3& accel
+) {
+ if (m_shapeProps) {
+ m_force += m_shapeProps->m_mass * accel; // F = m * a
+ }
+}
+
+ void
+SM_Object::
+applyCenterForce(
+ const MT_Vector3& force
+) {
+ m_force += force;
+}
+
+ void
+SM_Object::
+applyTorque(
+ const MT_Vector3& torque
+) {
+ m_torque += torque;
+}
+
+ void
+SM_Object::
+applyImpulse(
+ const MT_Point3& attach, const MT_Vector3& impulse
+) {
+ applyCenterImpulse(impulse); // Change in linear momentum
+ applyAngularImpulse((attach - m_pos).cross(impulse)); // Change in angular momentump
+}
+
+ void
+SM_Object::
+applyCenterImpulse(
+ const MT_Vector3& impulse
+) {
+ if (m_shapeProps) {
+ m_lin_mom += impulse;
+ m_reaction_impulse += impulse;
+ m_lin_vel = m_lin_mom / m_shapeProps->m_mass;
+
+ // The linear velocity is immedialtely updated since otherwise
+ // simultaneous collisions will get a double impulse.
+ }
+}
+
+ void
+SM_Object::
+applyAngularImpulse(
+ const MT_Vector3& impulse
+) {
+ if (m_shapeProps) {
+ m_ang_mom += impulse;
+ m_ang_vel = m_ang_mom / m_shapeProps->m_inertia;
+ }
+}
+
+ MT_Point3
+SM_Object::
+getWorldCoord(
+ const MT_Point3& local
+) const {
+ return m_xform(local);
+}
+
+ MT_Vector3
+SM_Object::
+getVelocity(
+ const MT_Point3& local
+) const {
+ // For displaced objects the velocity is faked using the previous state.
+ // Dynamic objects get their own velocity, not the faked velocity.
+ // (Dynamic objects shouldn't be displaced in the first place!!)
+
+ return m_prev_kinematic && !isDynamic() ?
+ (m_xform(local) - m_prev_xform(local)) / m_timeStep :
+ m_lin_vel + m_ang_vel.cross(m_xform.getBasis() * local);
+
+ // NB: m_xform.getBasis() * local == m_xform(local) - m_xform.getOrigin()
+
+}
+
+
+const
+ MT_Vector3&
+SM_Object::
+getReactionForce(
+) const {
+ return m_reaction_force;
+}
+
+ void
+SM_Object::
+getMatrix(
+ double *m
+) const {
+ std::copy(&m_ogl_matrix[0], &m_ogl_matrix[16], &m[0]);
+}
+
+const
+ double *
+SM_Object::
+getMatrix(
+) const {
+ return m_ogl_matrix;
+}
+
+// Still need this???
+const
+ MT_Transform&
+SM_Object::
+getScaledTransform(
+) const {
+ return m_xform;
+}
+
+ DT_ObjectHandle
+SM_Object::
+getObjectHandle(
+) const {
+ return m_object;
+}
+
+ DT_ShapeHandle
+SM_Object::
+getShapeHandle(
+) const {
+ return m_shape;
+}
+
+ void
+SM_Object::
+setClientObject(
+ void *clientobj
+) {
+ m_client_object = clientobj;
+}
+
+ void *
+SM_Object::
+getClientObject(
+){
+ return m_client_object;
+}
+
+ SM_Object *
+SM_Object::
+getDynamicParent(
+) {
+ return m_dynamicParent;
+}
+
+ void
+SM_Object::
+setRigidBody(
+ bool is_rigid_body
+) {
+ m_is_rigid_body = is_rigid_body;
+}
+
+ bool
+SM_Object::
+isRigidBody(
+) const {
+ return m_is_rigid_body;
+}
+
+const
+ MT_Vector3
+SM_Object::
+actualLinVelocity(
+) const {
+ return m_combined_lin_vel + m_lin_vel;
+};
+
+const
+ MT_Vector3
+SM_Object::
+actualAngVelocity(
+) const {
+ return m_combined_ang_vel + m_ang_vel;
+};
+
+
+
+
+
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp
new file mode 100644
index 00000000000..e3eb7e5c5ea
--- /dev/null
+++ b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp
@@ -0,0 +1,179 @@
+/**
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * The physics scene.
+ */
+
+#ifdef WIN32
+#pragma warning(disable : 4786) // shut off 255 char limit debug template warning
+#endif
+
+#include "SM_Scene.h"
+#include "SM_Object.h"
+#include "SM_FhObject.h"
+
+#include <algorithm>
+
+void SM_Scene::add(SM_Object& object) {
+ object.calcXform();
+ m_objectList.push_back(&object);
+ DT_AddObject(m_scene, object.getObjectHandle());
+ if (object.isDynamic()) {
+ DT_SetObjectResponse(m_respTable, object.getObjectHandle(),
+ SM_Object::boing, DT_SIMPLE_RESPONSE, this);
+ }
+
+ if (object.getDynamicParent()) {
+ DT_SetPairResponse(m_respTable, object.getObjectHandle(),
+ object.getDynamicParent()->getObjectHandle(),
+ 0, DT_NO_RESPONSE, 0);
+ }
+ SM_FhObject *fh_object = object.getFhObject();
+
+ if (fh_object) {
+ DT_AddObject(m_scene, fh_object->getObjectHandle());
+ DT_SetObjectResponse(m_respTable, fh_object->getObjectHandle(),
+ SM_FhObject::ray_hit, DT_SIMPLE_RESPONSE, this);
+ }
+}
+
+void SM_Scene::remove(SM_Object& object) {
+ T_ObjectList::iterator i =
+ std::find(m_objectList.begin(), m_objectList.end(), &object);
+ if (!(i == m_objectList.end()))
+ {
+ std::swap(*i, m_objectList.back());
+ m_objectList.pop_back();
+ DT_RemoveObject(m_scene, object.getObjectHandle());
+ if (object.isDynamic()) {
+ DT_ClearObjectResponse(m_respTable, object.getObjectHandle());
+ }
+
+ if (object.getDynamicParent()) {
+ DT_ClearPairResponse(m_respTable, object.getObjectHandle(),
+ object.getDynamicParent()->getObjectHandle());
+ }
+
+ SM_FhObject *fh_object = object.getFhObject();
+
+ if (fh_object) {
+ DT_RemoveObject(m_scene, fh_object->getObjectHandle());
+ DT_ClearObjectResponse(m_respTable,
+ fh_object->getObjectHandle());
+ }
+ }
+ else {
+ // tried to remove an object that is not in the scene
+ //assert(false);
+ }
+}
+
+void SM_Scene::proceed(MT_Scalar timeStep, MT_Scalar subSampling) {
+ // Don't waste time...but it's OK to spill a little.
+ if (timeStep < 0.001)
+ return;
+
+ // Divide the timeStep into a number of subsamples of size roughly
+ // equal to subSampling (might be a little smaller).
+ int num_samples = (int)ceil(timeStep / subSampling);
+
+
+ MT_Scalar subStep = timeStep / num_samples;
+ T_ObjectList::iterator i;
+
+ // Apply a forcefield (such as gravity)
+ for (i = m_objectList.begin(); i != m_objectList.end(); ++i) {
+ (*i)->applyForceField(m_forceField);
+ }
+
+ // Do the integration steps per object.
+ int step;
+ for (step = 0; step != num_samples; ++step) {
+
+ for (i = m_objectList.begin(); i != m_objectList.end(); ++i) {
+ (*i)->integrateForces(subStep);
+ }
+
+ // And second we update the object positions by performing
+ // an integration step for each object
+ for (i = m_objectList.begin(); i != m_objectList.end(); ++i) {
+ (*i)->integrateMomentum(subStep);
+ }
+#if 0
+ // I changed the order of the next 2 statements.
+ // Originally objects were first integrated with a call
+ // to proceed(). However if external objects were
+ // directly manipulating the velocities etc of physics
+ // objects then the physics environment would not be able
+ // to react before object positions were updated. --- Laurence.
+
+ // So now first we let the physics scene respond to
+ // new forces, velocities set externally.
+#endif
+ // The collsion and friction impulses are computed here.
+ DT_Test(m_scene, m_respTable);
+
+ }
+
+
+ // clear the user set velocities.
+#if 0
+ clearObjectCombinedVelocities();
+#endif
+ // Finish this timestep by saving al state information for the next
+ // timestep and clearing the accumulated forces.
+
+ for (i = m_objectList.begin(); i != m_objectList.end(); ++i) {
+ (*i)->proceedKinematic(timeStep);
+ (*i)->saveReactionForce(timeStep);
+ (*i)->clearForce();
+ }
+
+ // For each pair of object that collided, call the corresponding callback.
+ // Additional collisions of a pair within the same time step are ignored.
+
+ if (m_secondaryRespTable) {
+ T_PairList::iterator p;
+ for (p = m_pairList.begin(); p != m_pairList.end(); ++p) {
+ DT_CallResponse(m_secondaryRespTable,
+ (*p).first->getObjectHandle(),
+ (*p).second->getObjectHandle(),
+ 0);
+ }
+ }
+
+ clearPairs();
+}
+
+SM_Object *SM_Scene::rayTest(void *ignore_client,
+ const MT_Point3& from, const MT_Point3& to,
+ MT_Point3& result, MT_Vector3& normal) const {
+ MT_Point3 local;
+
+ SM_Object *hit_object = (SM_Object *)
+ DT_RayTest(m_scene, ignore_client, from.getValue(), to.getValue(),
+ local.getValue(), normal.getValue());
+
+ if (hit_object) {
+ result = hit_object->getWorldCoord(local);
+ }
+
+ return hit_object;
+}
+
+void SM_Scene::clearObjectCombinedVelocities() {
+
+ T_ObjectList::iterator i;
+
+ for (i = m_objectList.begin(); i != m_objectList.end(); ++i) {
+
+ (*i)->clearCombinedVelocities();
+
+ }
+
+}
+
+
+
+
+
diff --git a/source/gameengine/Physics/Sumo/Makefile b/source/gameengine/Physics/Sumo/Makefile
new file mode 100644
index 00000000000..3e5aca1d577
--- /dev/null
+++ b/source/gameengine/Physics/Sumo/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 = sumo
+DIR = $(OCGDIR)/gameengine/blphys/$(LIBNAME)
+
+include nan_compile.mk
+
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+CPPFLAGS += -I$(OPENGL_HEADERS)
+CPPFLAGS += -I$(NAN_STRING)/include
+CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
+CPPFLAGS += -I$(NAN_FUZZICS)/include -I$(NAN_SUMO)/include -I$(NAN_MOTO)/include
+CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
+CPPFLAGS += -I../../Physics/common
+CPPFLAGS += -I../../Physics/Dummy
diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsController.cpp b/source/gameengine/Physics/Sumo/SumoPhysicsController.cpp
new file mode 100644
index 00000000000..2b2c5b81856
--- /dev/null
+++ b/source/gameengine/Physics/Sumo/SumoPhysicsController.cpp
@@ -0,0 +1,462 @@
+/**
+ * $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 "SumoPhysicsController.h"
+#include "PHY_IMotionState.h"
+#include "SM_Object.h"
+#include "MT_Quaternion.h"
+
+
+SumoPhysicsController::SumoPhysicsController(
+ class SM_Scene* sumoScene,
+ DT_SceneHandle solidscene,
+ class SM_Object* sumoObj,
+ class PHY_IMotionState* motionstate,
+
+ bool dyna)
+ :
+ m_sumoScene(sumoScene),
+ m_solidscene(solidscene),
+ m_sumoObj(sumoObj) ,
+ m_bFirstTime(true),
+ m_MotionState(motionstate),
+ m_bDyna(dyna)
+{
+ if (m_sumoObj)
+ {
+ m_sumoObj->setClientObject(this);
+ //if it is a dyna, register for a callback
+ m_sumoObj->registerCallback(*this);
+ }
+};
+
+
+
+SumoPhysicsController::~SumoPhysicsController()
+{
+ if (m_sumoObj)
+ {
+ m_sumoScene->remove(*m_sumoObj);
+
+
+ DT_ObjectHandle objhandle = (DT_ObjectHandle) m_sumoObj->getObjectHandle();
+ if (objhandle)
+ {
+ DT_RemoveObject(m_solidscene,objhandle);
+ }
+ delete m_sumoObj;
+ }
+}
+
+float SumoPhysicsController::getMass()
+{
+ if (m_sumoObj)
+ {
+ const SM_ShapeProps *shapeprops = m_sumoObj->getShapeProps();
+ return shapeprops->m_mass;
+ }
+ return 0.f;
+}
+
+bool SumoPhysicsController::SynchronizeMotionStates(float time)
+{
+
+ if (m_bFirstTime)
+ {
+ setSumoTransform(false);
+ m_bFirstTime = false;
+ }
+
+ if (!m_bDyna)
+ {
+ if (m_sumoObj)
+ {
+ MT_Point3 pos;
+ GetWorldPosition(pos);
+
+ m_sumoObj->setPosition(pos);
+ if (m_bDyna)
+ {
+ m_sumoObj->setScaling(MT_Vector3(1,1,1));
+ } else
+ {
+ MT_Vector3 scaling;
+ GetWorldScaling(scaling);
+ m_sumoObj->setScaling(scaling);
+ }
+ MT_Matrix3x3 orn;
+ GetWorldOrientation(orn);
+ m_sumoObj->setOrientation(orn.getRotation());
+ m_sumoObj->calcXform();
+ }
+ }
+ return false; // physics object are not part of
+ // hierarchy, or ignore it ??
+}
+
+
+
+
+void SumoPhysicsController::GetWorldOrientation(MT_Matrix3x3& mat)
+{
+ float orn[4];
+ m_MotionState->getWorldOrientation(orn[0],orn[1],orn[2],orn[3]);
+ MT_Quaternion quat(orn);
+ mat.setRotation(quat);
+
+}
+
+void SumoPhysicsController::GetWorldPosition(MT_Point3& pos)
+{
+ float worldpos[3];
+ m_MotionState->getWorldPosition(worldpos[0],worldpos[1],worldpos[2]);
+ pos[0]=worldpos[0];
+ pos[1]=worldpos[1];
+ pos[2]=worldpos[2];
+}
+
+void SumoPhysicsController::GetWorldScaling(MT_Vector3& scale)
+{
+ float worldscale[3];
+ m_MotionState->getWorldScaling(worldscale[0],worldscale[1],worldscale[2]);
+ scale[0]=worldscale[0];
+ scale[1]=worldscale[1];
+ scale[2]=worldscale[2];
+}
+
+
+ // kinematic methods
+void SumoPhysicsController::RelativeTranslate(float dlocX,float dlocY,float dlocZ,bool local)
+{
+
+
+ if (m_sumoObj)
+ {
+ MT_Matrix3x3 mat;
+ GetWorldOrientation(mat);
+ MT_Vector3 dloc(dlocX,dlocY,dlocZ);
+
+ MT_Point3 newpos = m_sumoObj->getPosition();
+ newpos += (local ? mat * dloc : dloc);
+ m_sumoObj->setPosition(newpos);
+ }
+
+}
+void SumoPhysicsController::RelativeRotate(const float drot[9],bool local)
+{
+
+ if (m_sumoObj )
+ {
+ MT_Matrix3x3 drotmat(drot);
+ MT_Matrix3x3 currentOrn;
+ GetWorldOrientation(currentOrn);
+
+ m_sumoObj->setOrientation(m_sumoObj->getOrientation()*(local ?
+ drotmat.getRotation() : (currentOrn.inverse() * drotmat * currentOrn)).getRotation());
+ }
+
+}
+void SumoPhysicsController::setOrientation(float quatImag0,float quatImag1,float quatImag2,float quatReal)
+{
+ float orn [4]={quatImag0,quatImag1,quatImag2,quatReal};
+ MT_Quaternion quat(orn);
+ m_sumoObj->setOrientation(orn);
+}
+
+void SumoPhysicsController::getOrientation(float &quatImag0,float &quatImag1,float &quatImag2,float &quatReal)
+{
+ const MT_Quaternion& q = m_sumoObj->getOrientation();
+ quatImag0 = q[0];
+ quatImag1 = q[1];
+ quatImag2 = q[2];
+ quatReal = q[3];
+}
+
+void SumoPhysicsController::setPosition(float posX,float posY,float posZ)
+{
+ m_sumoObj->setPosition(MT_Point3(posX,posY,posZ));
+}
+void SumoPhysicsController::setScaling(float scaleX,float scaleY,float scaleZ)
+{
+ m_sumoObj->setScaling(MT_Vector3(scaleX,scaleY,scaleZ));
+}
+
+ // physics methods
+void SumoPhysicsController::ApplyTorque(float torqueX,float torqueY,float torqueZ,bool local)
+{
+ if (m_sumoObj)
+ {
+ MT_Vector3 torque(torqueX,torqueY,torqueZ);
+
+ MT_Matrix3x3 orn;
+ GetWorldOrientation(orn);
+ m_sumoObj->applyTorque(local ?
+ orn * torque :
+ torque);
+ }
+
+}
+
+void SumoPhysicsController::ApplyForce(float forceX,float forceY,float forceZ,bool local)
+{
+ if (m_sumoObj)
+ {
+ MT_Vector3 force(forceX,forceY,forceZ);
+
+ MT_Matrix3x3 orn;
+ GetWorldOrientation(orn);
+
+ m_sumoObj->applyCenterForce(local ?
+ orn * force :
+ force);
+
+ }
+
+}
+
+void SumoPhysicsController::SetAngularVelocity(float ang_velX,float ang_velY,float ang_velZ,bool local)
+{
+ if (m_sumoObj)
+ {
+ MT_Vector3 ang_vel(ang_velX,ang_velY,ang_velZ);
+
+ MT_Matrix3x3 orn;
+ GetWorldOrientation(orn);
+
+ m_sumoObj->setAngularVelocity(local ?
+ orn * ang_vel :
+ ang_vel);
+
+ }
+}
+
+void SumoPhysicsController::SetLinearVelocity(float lin_velX,float lin_velY,float lin_velZ,bool local)
+{
+ if (m_sumoObj )
+ {
+ MT_Matrix3x3 orn;
+ GetWorldOrientation(orn);
+
+ MT_Vector3 lin_vel(lin_velX,lin_velY,lin_velZ);
+ m_sumoObj->setLinearVelocity(local ?
+ orn * lin_vel :
+ lin_vel);
+ }
+}
+
+void SumoPhysicsController::applyImpulse(float attachX,float attachY,float attachZ, float impulseX,float impulseY,float impulseZ)
+{
+ if (m_sumoObj)
+ {
+ MT_Point3 attach(attachX,attachY,attachZ);
+ MT_Vector3 impulse(impulseX,impulseY,impulseZ);
+ m_sumoObj->applyImpulse(attach,impulse);
+ }
+
+}
+
+void SumoPhysicsController::SuspendDynamics()
+{
+ m_suspendDynamics=true;
+
+ if (m_sumoObj)
+ {
+ m_sumoObj->suspendDynamics();
+ m_sumoObj->setLinearVelocity(MT_Vector3(0,0,0));
+ m_sumoObj->setAngularVelocity(MT_Vector3(0,0,0));
+ m_sumoObj->calcXform();
+ }
+}
+
+void SumoPhysicsController::RestoreDynamics()
+{
+ m_suspendDynamics=false;
+
+ if (m_sumoObj)
+ {
+ m_sumoObj->restoreDynamics();
+ }
+
+
+}
+
+
+ /**
+ reading out information from physics
+ */
+void SumoPhysicsController::GetLinearVelocity(float& linvX,float& linvY,float& linvZ)
+{
+ if (m_sumoObj)
+ {
+ // get velocity from the physics object (m_sumoObj)
+ const MT_Vector3& vel = m_sumoObj->getLinearVelocity();
+ linvX = vel[0];
+ linvY = vel[1];
+ linvZ = vel[2];
+ }
+ else
+ {
+ linvX = 0.f;
+ linvY = 0.f;
+ linvZ = 0.f;
+ }
+}
+ /**
+ GetVelocity parameters are in geometric coordinates (Origin is not center of mass!).
+ */
+void SumoPhysicsController::GetVelocity(const float posX,const float posY,const float posZ,float& linvX,float& linvY,float& linvZ)
+{
+ if (m_sumoObj)
+ {
+ MT_Point3 pos(posX,posY,posZ);
+ // get velocity from the physics object (m_sumoObj)
+ const MT_Vector3& vel = m_sumoObj->getVelocity(pos);
+ linvX = vel[0];
+ linvY = vel[1];
+ linvZ = vel[2];
+ }
+ else
+ {
+ linvX = 0.f;
+ linvY = 0.f;
+ linvZ = 0.f;
+
+ }
+}
+
+
+void SumoPhysicsController::getReactionForce(float& forceX,float& forceY,float& forceZ)
+{
+ const MT_Vector3& force = m_sumoObj->getReactionForce();
+ forceX = force[0];
+ forceY = force[1];
+ forceZ = force[2];
+
+
+}
+void SumoPhysicsController::setRigidBody(bool rigid)
+{
+ m_sumoObj->setRigidBody(rigid);
+}
+
+
+void SumoPhysicsController::PostProcessReplica(class PHY_IMotionState* motionstate,class PHY_IPhysicsController* parentctrl)
+{
+ m_MotionState = motionstate;
+
+ SM_Object* dynaparent=0;
+ SumoPhysicsController* sumoparentctrl = (SumoPhysicsController* )parentctrl;
+
+ if (sumoparentctrl)
+ {
+ dynaparent = sumoparentctrl->GetSumoObject();
+ }
+
+ SM_Object* orgsumoobject = m_sumoObj;
+
+
+ m_sumoObj = new SM_Object(
+ orgsumoobject->getShapeHandle(),
+ orgsumoobject->getMaterialProps(),
+ orgsumoobject->getShapeProps(),
+ dynaparent);
+
+ m_sumoObj->setRigidBody(orgsumoobject->isRigidBody());
+
+ double radius = orgsumoobject->getMargin();
+ m_sumoObj->setMargin(orgsumoobject->getMargin());
+ m_sumoObj->setPosition(orgsumoobject->getPosition());
+ m_sumoObj->setOrientation(orgsumoobject->getOrientation());
+ m_sumoScene->add(* (m_sumoObj));
+
+ if (m_sumoObj)
+ {
+ m_sumoObj->setClientObject(this);
+ //if it is a dyna, register for a callback
+ m_sumoObj->registerCallback(*this);
+ }
+
+
+ DT_AddObject(m_solidscene,m_sumoObj->getObjectHandle());
+
+}
+
+void SumoPhysicsController::SetSimulatedTime(float time)
+{
+}
+
+
+void SumoPhysicsController::WriteMotionStateToDynamics(bool nondynaonly)
+{
+
+}
+// this is the actual callback from sumo, and the position/orientation
+//is written to the scenegraph, using the motionstate abstraction
+
+void SumoPhysicsController::do_me()
+{
+
+ const MT_Point3& pos = m_sumoObj->getPosition();
+ const MT_Quaternion& orn = m_sumoObj->getOrientation();
+
+ m_MotionState->setWorldPosition(pos[0],pos[1],pos[2]);
+ m_MotionState->setWorldOrientation(orn[0],orn[1],orn[2],orn[3]);
+
+}
+
+
+void SumoPhysicsController::setSumoTransform(bool nondynaonly)
+{
+ if (!nondynaonly || !m_bDyna)
+ {
+ if (m_sumoObj)
+ {
+ MT_Point3 pos;
+ GetWorldPosition(pos);
+
+ m_sumoObj->setPosition(pos);
+ if (m_bDyna)
+ {
+ m_sumoObj->setScaling(MT_Vector3(1,1,1));
+ } else
+ {
+ MT_Vector3 scale;
+ GetWorldScaling(scale);
+ m_sumoObj->setScaling(scale);
+ }
+ MT_Matrix3x3 orn;
+ GetWorldOrientation(orn);
+ m_sumoObj->setOrientation(orn.getRotation());
+ m_sumoObj->calcXform();
+ }
+ }
+}
diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsController.h b/source/gameengine/Physics/Sumo/SumoPhysicsController.h
new file mode 100644
index 00000000000..d78c21dbd1b
--- /dev/null
+++ b/source/gameengine/Physics/Sumo/SumoPhysicsController.h
@@ -0,0 +1,171 @@
+/**
+ * $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 __SUMO_PHYSICSCONTROLLER_H
+#define __SUMO_PHYSICSCONTROLLER_H
+
+
+#include "PHY_IPhysicsController.h"
+#include "SM_Scene.h"
+#include "SM_Callback.h"
+
+
+/**
+ Sumo Physics Controller, a special kind of a PhysicsController.
+ A Physics Controller is a special kind of Scene Graph Transformation Controller.
+ Each time the scene graph get's updated, the controller get's a chance
+ in the 'Update' method to reflect changes.
+*/
+
+class SumoPhysicsController : public PHY_IPhysicsController , public SM_Callback
+
+
+{
+
+ class SM_Object* m_sumoObj;
+ class SM_Scene* m_sumoScene; // needed for replication
+ DT_SceneHandle m_solidscene;
+ bool m_bFirstTime;
+ bool m_bDyna;
+
+ float m_friction;
+ float m_restitution;
+
+
+ bool m_suspendDynamics;
+
+public:
+ SumoPhysicsController(
+ class SM_Scene* sumoScene,
+ DT_SceneHandle solidscene,
+ class SM_Object* sumoObj,
+ class PHY_IMotionState* motionstate,
+ bool dyna);
+
+ virtual ~SumoPhysicsController();
+
+ // kinematic methods
+ virtual void RelativeTranslate(float dlocX,float dlocY,float dlocZ,bool local);
+ virtual void RelativeRotate(const float drot[9],bool local);
+ virtual void getOrientation(float &quatImag0,float &quatImag1,float &quatImag2,float &quatReal);
+ virtual void setOrientation(float quatImag0,float quatImag1,float quatImag2,float quatReal);
+ virtual void setPosition(float posX,float posY,float posZ);
+ virtual void setScaling(float scaleX,float scaleY,float scaleZ);
+
+ // physics methods
+ virtual void ApplyTorque(float torqueX,float torqueY,float torqueZ,bool local);
+ virtual void ApplyForce(float forceX,float forceY,float forceZ,bool local);
+ virtual void SetAngularVelocity(float ang_velX,float ang_velY,float ang_velZ,bool local);
+ virtual void SetLinearVelocity(float lin_velX,float lin_velY,float lin_velZ,bool local);
+ virtual void applyImpulse(float attachX,float attachY,float attachZ, float impulseX,float impulseY,float impulseZ);
+ virtual void SetActive(bool active){};
+ virtual void SuspendDynamics();
+ virtual void RestoreDynamics();
+
+
+ /**
+ reading out information from physics
+ */
+ virtual void GetLinearVelocity(float& linvX,float& linvY,float& linvZ);
+ /**
+ GetVelocity parameters are in geometric coordinates (Origin is not center of mass!).
+ */
+ virtual void GetVelocity(const float posX,const float posY,const float posZ,float& linvX,float& linvY,float& linvZ);
+ virtual float getMass();
+ virtual void getReactionForce(float& forceX,float& forceY,float& forceZ);
+ virtual void setRigidBody(bool rigid);
+
+
+ virtual void PostProcessReplica(class PHY_IMotionState* motionstate,class PHY_IPhysicsController* parentctrl);
+
+ // todo: remove next line !
+ virtual void SetSimulatedTime(float time);
+
+
+ virtual void WriteDynamicsToMotionState() {};
+ virtual void WriteMotionStateToDynamics(bool nondynaonly);
+
+ /**
+ call from Scene Graph Node to 'update'.
+ */
+ virtual bool SynchronizeMotionStates(float time);
+
+ // clientinfo for raycasts for example
+ virtual void* getClientInfo() { return m_clientInfo;}
+ virtual void setClientInfo(void* clientinfo) {m_clientInfo = clientinfo;};
+ void* m_clientInfo;
+
+
+ float getFriction() { return m_friction;}
+ float getRestitution() { return m_restitution;}
+
+ // sumo callback
+ virtual void do_me();
+
+ class SM_Object* GetSumoObject ()
+ {
+ return m_sumoObj;
+ };
+
+ void GetWorldOrientation(class MT_Matrix3x3& mat);
+ void GetWorldPosition(MT_Point3& pos);
+ void GetWorldScaling(MT_Vector3& scale);
+
+
+// void SetSumoObject(class SM_Object* sumoObj) {
+// m_sumoObj = sumoObj;
+// }
+// void SetSumoScene(class SM_Scene* sumoScene) {
+// m_sumoScene = sumoScene;
+// }
+
+ void setSumoTransform(bool nondynaonly);
+
+
+private:
+
+ bool m_firstTime;
+ bool m_bFullRigidBody;
+ bool m_bPhantom; // special flag for objects that are not affected by physics 'resolver'
+
+ // data to calculate fake velocities for kinematic objects (non-dynas)
+ bool m_bKinematic;
+ bool m_bPrevKinematic;
+
+ float m_lastTime;
+
+ class PHY_IMotionState* m_MotionState;
+
+};
+
+#endif //__SUMO_PHYSICSCONTROLLER_H
+
+
diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp
new file mode 100644
index 00000000000..05b88fcb06b
--- /dev/null
+++ b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp
@@ -0,0 +1,103 @@
+/**
+ * $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 "SumoPhysicsEnvironment.h"
+#include "PHY_IMotionState.h"
+#include "SumoPhysicsController.h"
+#include "SM_Scene.h"
+
+
+const MT_Scalar UpperBoundForFuzzicsIntegrator = 0.01;
+// At least 100Hz (isn't this CPU hungry ?)
+
+
+SumoPhysicsEnvironment::SumoPhysicsEnvironment()
+{
+ // seperate collision scene for events
+ m_solidScene = DT_CreateScene();
+ m_respTable = DT_CreateRespTable();
+
+ m_sumoScene = new SM_Scene();
+ m_sumoScene->setSecondaryRespTable(m_respTable);
+
+}
+
+
+
+SumoPhysicsEnvironment::~SumoPhysicsEnvironment()
+{
+ delete m_sumoScene;
+
+ DT_DeleteScene(m_solidScene);
+ DT_DeleteRespTable(m_respTable);
+}
+
+void SumoPhysicsEnvironment::proceed(double timeStep)
+{
+ m_sumoScene->proceed(timeStep,UpperBoundForFuzzicsIntegrator);
+}
+
+void SumoPhysicsEnvironment::setGravity(float x,float y,float z)
+{
+ m_sumoScene->setForceField(MT_Vector3(x,y,z));
+
+}
+
+
+
+
+
+int SumoPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsController* ctrl2,PHY_ConstraintType type,
+ float pivotX,float pivotY,float pivotZ,float axisX,float axisY,float axisZ)
+{
+
+ int constraintid = 0;
+ return constraintid;
+
+}
+
+void SumoPhysicsEnvironment::removeConstraint(int constraintid)
+{
+ if (constraintid)
+ {
+ }
+}
+
+PHY_IPhysicsController* SumoPhysicsEnvironment::rayTest(void* ignoreClient, float fromX,float fromY,float fromZ, float toX,float toY,float toZ,
+ float& hitX,float& hitY,float& hitZ,float& normalX,float& normalY,float& normalZ)
+{
+ //collision detection / raytesting
+ //m_sumoScene->rayTest(ignoreclient,from,to,result,normal);
+
+ return NULL;
+}
+
+
diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h
new file mode 100644
index 00000000000..0e28b855833
--- /dev/null
+++ b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h
@@ -0,0 +1,88 @@
+/**
+ * $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 _SUMOPhysicsEnvironment
+#define _SUMOPhysicsEnvironment
+
+
+#include "PHY_IPhysicsEnvironment.h"
+
+#include "solid.h"
+
+/**
+* Physics Environment takes care of stepping the simulation and is a container for physics entities (rigidbodies,constraints, materials etc.)
+* A derived class may be able to 'construct' entities by loading and/or converting
+*/
+class SumoPhysicsEnvironment : public PHY_IPhysicsEnvironment
+{
+
+ class SM_Scene* m_sumoScene;
+
+ DT_SceneHandle m_solidScene;
+ DT_RespTableHandle m_respTable;
+
+public:
+ SumoPhysicsEnvironment();
+ virtual ~SumoPhysicsEnvironment();
+// Perform an integration step of duration 'timeStep'.
+ virtual void proceed(double timeStep);
+ virtual void setGravity(float x,float y,float z);
+ virtual int createConstraint(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsController* ctrl2,PHY_ConstraintType type,
+ float pivotX,float pivotY,float pivotZ,
+ float axisX,float axisY,float axisZ);
+
+ virtual void removeConstraint(int constraintid);
+ virtual PHY_IPhysicsController* rayTest(void* ignoreClient,float fromX,float fromY,float fromZ, float toX,float toY,float toZ,
+ float& hitX,float& hitY,float& hitZ,float& normalX,float& normalY,float& normalZ);
+
+
+ // sumo specific
+ SM_Scene* GetSumoScene()
+ {
+ return m_sumoScene;
+ }
+
+ DT_SceneHandle GetSolidScene()
+ {
+ return m_solidScene;
+ }
+
+private:
+
+
+
+
+};
+
+#endif //_SUMOPhysicsEnvironment
+
+
+
diff --git a/source/gameengine/Physics/Sumo/convert.txt b/source/gameengine/Physics/Sumo/convert.txt
new file mode 100644
index 00000000000..81f8f602cde
--- /dev/null
+++ b/source/gameengine/Physics/Sumo/convert.txt
@@ -0,0 +1,35 @@
+static DT_ShapeHandle CreateShapeFromMesh(RAS_MeshObject* meshobj)
+{
+ DT_ShapeHandle shape = DT_NewComplexShape();
+ int numpolys = meshobj->NumPolygons();
+ int numvalidpolys = 0;
+
+ for (int p=0; p<numpolys; p++)
+ {
+ RAS_Polygon* poly = meshobj->GetPolygon(p);
+
+ // only add polygons that have the collisionflag set
+ if (poly->IsCollider())
+ {
+ DT_Begin();
+ for (int v=0; v<poly->VertexCount(); v++) {
+ MT_Point3 pt = meshobj->GetVertex(poly->GetVertexIndexBase().m_vtxarray,
+ poly->GetVertexIndexBase().m_indexarray[v],
+ poly->GetMaterial()->GetPolyMaterial())->xyz();
+ DT_Vertex(pt[0],pt[1],pt[2]);
+ }
+ DT_End();
+
+ numvalidpolys++;
+ }
+ }
+
+ DT_EndComplexShape();
+
+ if (numvalidpolys==0) {
+ delete shape;
+ return NULL;
+ } else {
+ return shape;
+ }
+}
diff --git a/source/gameengine/Physics/Sumo/include/interpolator.h b/source/gameengine/Physics/Sumo/include/interpolator.h
new file mode 100644
index 00000000000..055c242edc7
--- /dev/null
+++ b/source/gameengine/Physics/Sumo/include/interpolator.h
@@ -0,0 +1,27 @@
+#ifndef INTERPOLATOR_H
+#define INTERPOLATOR_H
+
+#include "solid_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+DT_DECLARE_HANDLE(IP_IpoHandle);
+
+typedef struct IP_ControlPoint {
+ DT_Scalar m_key;
+ DT_Scalar m_keyValue;
+} IP_ControlPoint;
+
+IP_IpoHandle IP_CreateLinear(const IP_ControlPoint *cpoints, int num_cpoints);
+
+void IP_DeleteInterpolator(IP_IpoHandle ipo);
+
+DT_Scalar IP_GetValue(IP_IpoHandle ipo, DT_Scalar key);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/source/gameengine/Physics/Sumo/include/solid.h b/source/gameengine/Physics/Sumo/include/solid.h
new file mode 100644
index 00000000000..985014a2a46
--- /dev/null
+++ b/source/gameengine/Physics/Sumo/include/solid.h
@@ -0,0 +1,195 @@
+#ifndef SOLID_H
+#define SOLID_H
+
+#include "solid_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+DT_DECLARE_HANDLE(DT_ObjectHandle);
+DT_DECLARE_HANDLE(DT_SceneHandle);
+DT_DECLARE_HANDLE(DT_ShapeHandle);
+DT_DECLARE_HANDLE(DT_RespTableHandle);
+
+typedef enum DT_ScalarType {
+ DT_FLOAT,
+ DT_DOUBLE
+} DT_ScalarType;
+
+typedef enum DT_ResponseType {
+ DT_NO_RESPONSE,
+ DT_SIMPLE_RESPONSE,
+ DT_WITNESSED_RESPONSE,
+ DT_DEPTH_RESPONSE,
+} DT_ResponseType;
+
+typedef struct DT_CollData {
+ DT_Vector3 point1;
+ DT_Vector3 point2;
+ DT_Vector3 normal;
+} DT_CollData;
+
+typedef void (*DT_ResponseCallback)(
+ void *client_data,
+ void *client_object1,
+ void *client_object2,
+ const DT_CollData *coll_data);
+
+/* Shape definition, similar to OpenGL */
+
+extern DT_ShapeHandle DT_Box(DT_Scalar x, DT_Scalar y, DT_Scalar z);
+extern DT_ShapeHandle DT_Cone(DT_Scalar radius, DT_Scalar height);
+extern DT_ShapeHandle DT_Cylinder(DT_Scalar radius, DT_Scalar height);
+extern DT_ShapeHandle DT_Sphere(DT_Scalar radius);
+extern DT_ShapeHandle DT_Ray(DT_Scalar x, DT_Scalar y, DT_Scalar z);
+
+extern DT_ShapeHandle DT_NewComplexShape();
+extern void DT_EndComplexShape();
+
+extern DT_ShapeHandle DT_NewPolyhedron();
+extern void DT_EndPolyhedron();
+
+extern void DT_Begin();
+extern void DT_End();
+
+extern void DT_Vertex(DT_Scalar x, DT_Scalar y, DT_Scalar z);
+
+/* Vertex arrays maintained by the client application can be accessed directly
+ by SUMO. For instance, you have a vertex struct in the client of the form:
+
+ struct Vertex {
+ float xyz[3];
+ float uv[2];
+ float normal[3];
+ };
+
+ And maintain vertex arrays e.g. as
+
+ struct Vertex vertices[328];
+
+ Within a Polyhedron or a ComplexShape you can use this data by specifying
+
+ DT_VertexBase(vertices, DT_FLOAT, sizeof(struct Vertex));
+
+ and refer to vertices in the array using
+
+ DT_VertexIndex(10);
+
+ or
+
+ DT_Index indices[5] = { 6, 4, 8, 1, 3 };
+ DT_VertexIndices(5, indices);
+
+ or even
+
+ DT_VertexRange(8, 4);
+
+ for the range 8, 9, 10, 11.
+*/
+
+
+extern void DT_SetVertexBase(const void *base, DT_ScalarType type,
+ DT_Size stride);
+extern void DT_VertexIndex(DT_Index index);
+extern void DT_VertexIndices(DT_Count count, const DT_Index *indices);
+extern void DT_VertexRange(DT_Index first, DT_Count count);
+
+
+/* currently not implemented */
+extern void DT_ChangeVertexBase(DT_ShapeHandle shape, const void *base);
+
+extern void DT_DeleteShape(DT_ShapeHandle shape);
+
+/* Scene */
+
+extern DT_SceneHandle DT_CreateScene();
+extern void DT_DeleteScene(DT_SceneHandle scene);
+
+extern void DT_AddObject(DT_SceneHandle scene, DT_ObjectHandle object);
+extern void DT_RemoveObject(DT_SceneHandle scene, DT_ObjectHandle object);
+
+
+
+/* Object */
+
+extern DT_ObjectHandle DT_CreateObject(
+ void *client_object, /* pointer to object in client memory */
+ DT_ShapeHandle shape /* the shape or geometry of the object */
+ );
+
+extern void DT_DeleteObject(DT_ObjectHandle object);
+
+extern void DT_SetScaling(DT_ObjectHandle object, const DT_Vector3 scaling);
+extern void DT_SetPosition(DT_ObjectHandle object, const DT_Vector3 position);
+extern void DT_SetOrientation(DT_ObjectHandle object, const DT_Quaternion orientation);
+
+extern void DT_SetMargin(DT_ObjectHandle object, DT_Scalar margin);
+
+extern void DT_SetMatrixf(DT_ObjectHandle object, const float *m);
+extern void DT_GetMatrixf(DT_ObjectHandle object, float *m);
+
+extern void DT_SetMatrixd(DT_ObjectHandle object, const double *m);
+extern void DT_GetMatrixd(DT_ObjectHandle object, double *m);
+
+extern void DT_GetWorldCoord(DT_ObjectHandle object,
+ const DT_Vector3 local,
+ DT_Vector3 world);
+
+extern DT_Scalar DT_GetClosestPair(DT_ObjectHandle object1, DT_ObjectHandle object2,
+ DT_Vector3 point1, DT_Vector3 point2);
+
+
+/* Response, see SOLID user manual */
+
+extern DT_RespTableHandle DT_CreateRespTable();
+extern void DT_DeleteRespTable(DT_RespTableHandle respTable);
+
+extern void DT_CallResponse(DT_RespTableHandle respTable,
+ DT_ObjectHandle object1,
+ DT_ObjectHandle object2,
+ const DT_CollData *coll_data);
+
+extern void DT_SetDefaultResponse(DT_RespTableHandle respTable,
+ DT_ResponseCallback response,
+ DT_ResponseType type,
+ void *client_data);
+
+extern void DT_ClearDefaultResponse(DT_RespTableHandle respTable);
+
+extern void DT_SetObjectResponse(DT_RespTableHandle respTable,
+ DT_ObjectHandle object,
+ DT_ResponseCallback response,
+ DT_ResponseType type, void *client_data);
+extern void DT_ClearObjectResponse(DT_RespTableHandle respTable,
+ DT_ObjectHandle object);
+
+extern void DT_SetPairResponse(DT_RespTableHandle respTable,
+ DT_ObjectHandle object1,
+ DT_ObjectHandle object2,
+ DT_ResponseCallback response,
+ DT_ResponseType type,
+ void *client_data);
+extern void DT_ClearPairResponse(DT_RespTableHandle respTable,
+ DT_ObjectHandle object1,
+ DT_ObjectHandle object2);
+
+
+
+/* Perform a collision test for a given scene, using a response table */
+
+extern DT_Count DT_Test(DT_SceneHandle scene, DT_RespTableHandle respTable);
+
+extern void *DT_RayTest(DT_SceneHandle scene, void *ignore_client,
+ const DT_Vector3 from, const DT_Vector3 to,
+ DT_Vector3 spot, DT_Vector3 normal);
+
+extern int DT_ObjectRayTest(DT_ObjectHandle object,
+ const DT_Vector3 from, const DT_Vector3 to,
+ DT_Vector3 spot, DT_Vector3 normal);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/source/gameengine/Physics/Sumo/include/solid_broadphase.h b/source/gameengine/Physics/Sumo/include/solid_broadphase.h
new file mode 100644
index 00000000000..d5d05e8a243
--- /dev/null
+++ b/source/gameengine/Physics/Sumo/include/solid_broadphase.h
@@ -0,0 +1,38 @@
+#ifndef SOLID_BROADPHASE_H
+#define SOLID_BROADPHASE_H
+
+#include "solid_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+DT_DECLARE_HANDLE(BP_SceneHandle);
+DT_DECLARE_HANDLE(BP_ProxyHandle);
+
+typedef void (*BP_Callback)(void *client_data,
+ void *object1,
+ void *object2);
+
+extern BP_SceneHandle BP_CreateScene(void *client_data,
+ BP_Callback beginOverlap,
+ BP_Callback endOverlap);
+
+extern void BP_DeleteScene(BP_SceneHandle scene);
+
+extern BP_ProxyHandle BP_CreateProxy(BP_SceneHandle scene, void *object,
+ const DT_Vector3 lower,
+ const DT_Vector3 upper);
+
+extern void BP_DeleteProxy(BP_SceneHandle scene,
+ BP_ProxyHandle proxy);
+
+extern void BP_SetBBox(BP_ProxyHandle proxy,
+ const DT_Vector3 lower,
+ const DT_Vector3 upper);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/source/gameengine/Physics/Sumo/include/solid_types.h b/source/gameengine/Physics/Sumo/include/solid_types.h
new file mode 100644
index 00000000000..537bbcb5826
--- /dev/null
+++ b/source/gameengine/Physics/Sumo/include/solid_types.h
@@ -0,0 +1,14 @@
+#ifndef SOLID_TYPES_H
+#define SOLID_TYPES_H
+
+#define DT_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
+
+typedef double DT_Scalar;
+typedef unsigned int DT_Count;
+typedef unsigned int DT_Index;
+typedef unsigned int DT_Size;
+
+typedef DT_Scalar DT_Vector3[3];
+typedef DT_Scalar DT_Quaternion[4];
+
+#endif
diff --git a/source/gameengine/Physics/common/Makefile b/source/gameengine/Physics/common/Makefile
new file mode 100644
index 00000000000..3783d959e14
--- /dev/null
+++ b/source/gameengine/Physics/common/Makefile
@@ -0,0 +1,59 @@
+#
+# $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 = common
+DIR = $(OCGDIR)/gameengine/blphys/$(LIBNAME)
+
+include nan_compile.mk
+
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+CPPFLAGS += -I$(OPENGL_HEADERS)
+CPPFLAGS += -I$(NAN_STRING)/include
+CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
+CPPFLAGS += -I$(NAN_FUZZICS)/include -I$(NAN_SUMO)/include -I$(NAN_MOTO)/include
+CPPFLAGS += -I../../blender
+# these two needed because of blenkernel
+CPPFLAGS += -I../../blender/makesdna
+CPPFLAGS += -I../../blender/include
+CPPFLAGS += -I../../blender/blenlib
+CPPFLAGS += -I../../blender/blenkernel
+CPPFLAGS += -I../../blender/render/extern/include
+CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
+CPPFLAGS += -I../Expressions -I../Rasterizer -I../GameLogic -I../SoundSystem
+CPPFLAGS += -I../Ketsji -I../BlenderRoutines -I../SceneGraph
+CPPFLAGS += -I../../kernel/gen_system
+CPPFLAGS += -I../Rasterizer/RAS_OpenGLRasterizer
+CPPFLAGS += -I../Network -I../Ketsji/KXNetwork
+CPPFLAGS += -I../Physics
+CPPFLAGS += -I../Physics/Dummy
diff --git a/source/gameengine/Physics/common/PHY_DynamicTypes.h b/source/gameengine/Physics/common/PHY_DynamicTypes.h
new file mode 100644
index 00000000000..4b10a29e1e7
--- /dev/null
+++ b/source/gameengine/Physics/common/PHY_DynamicTypes.h
@@ -0,0 +1,68 @@
+/**
+ * $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 __PHY_DYNAMIC_TYPES
+#define __PHY_DYNAMIC_TYPES
+
+/// PHY_ScalarType enumerates possible scalar types.
+/// See the PHY_IMeshInterface for its use
+typedef enum PHY_ScalarType {
+ PHY_FLOAT,
+ PHY_DOUBLE,
+ PHY_INTEGER,
+ PHY_SHORT,
+ PHY_FIXEDPOINT88
+} PHY_ScalarType;
+
+/// PHY_PhysicsType enumerates all possible Physics Entities.
+/// It is mainly used to create/add Physics Objects
+
+typedef enum PHY_PhysicsType {
+ PHY_CONVEX_RIGIDBODY=16386,
+ PHY_CONCAVE_RIGIDBODY=16399,
+ PHY_CONVEX_FIXEDBODY=16388,//'collision object'
+ PHY_CONCAVE_FIXEDBODY=16401,
+ PHY_CONVEX_KINEMATICBODY=16387,//
+ PHY_CONCAVE_KINEMATICBODY=16400,
+ PHY_CONVEX_PHANTOMBODY=16398,
+ PHY_CONCAVE_PHANTOMBODY=16402
+} PHY_PhysicsType;
+
+/// PHY_ConstraintType enumerates all supported Constraint Types
+typedef enum PHY_ConstraintType {
+ PHY_POINT2POINT_CONSTRAINT=1,
+ PHY_LINEHINGE_CONSTRAINT,
+
+} PHY_ConstraintType;
+
+typedef float PHY_Vector3[3];
+
+#endif //__PHY_DYNAMIC_TYPES
diff --git a/source/gameengine/Physics/common/PHY_IMotionState.cpp b/source/gameengine/Physics/common/PHY_IMotionState.cpp
new file mode 100644
index 00000000000..106f453424d
--- /dev/null
+++ b/source/gameengine/Physics/common/PHY_IMotionState.cpp
@@ -0,0 +1,37 @@
+/**
+ * $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 "PHY_IMotionState.h"
+
+PHY_IMotionState::~PHY_IMotionState()
+{
+
+}
diff --git a/source/gameengine/Physics/common/PHY_IMotionState.h b/source/gameengine/Physics/common/PHY_IMotionState.h
new file mode 100644
index 00000000000..6dd97427b59
--- /dev/null
+++ b/source/gameengine/Physics/common/PHY_IMotionState.h
@@ -0,0 +1,57 @@
+/**
+ * $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 PHY__MOTIONSTATE_H
+#define PHY__MOTIONSTATE_H
+
+
+/**
+ PHY_IMotionState is the Interface to explicitly synchronize the world transformation.
+ Default implementations for mayor graphics libraries like OpenGL and DirectX can be provided.
+*/
+class PHY_IMotionState
+
+{
+ public:
+
+ virtual ~PHY_IMotionState();
+
+ virtual void getWorldPosition(float& posX,float& posY,float& posZ)=0;
+ virtual void getWorldScaling(float& scaleX,float& scaleY,float& scaleZ)=0;
+ virtual void getWorldOrientation(float& quatIma0,float& quatIma1,float& quatIma2,float& quatReal)=0;
+
+ virtual void setWorldPosition(float posX,float posY,float posZ)=0;
+ virtual void setWorldOrientation(float quatIma0,float quatIma1,float quatIma2,float quatReal)=0;
+
+ virtual void calculateWorldTransformations()=0;
+};
+
+#endif //PHY__MOTIONSTATE_H
diff --git a/source/gameengine/Physics/common/PHY_IPhysicsController.cpp b/source/gameengine/Physics/common/PHY_IPhysicsController.cpp
new file mode 100644
index 00000000000..ec0f7b9df3e
--- /dev/null
+++ b/source/gameengine/Physics/common/PHY_IPhysicsController.cpp
@@ -0,0 +1,39 @@
+/**
+ * $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 "PHY_IPhysicsController.h"
+
+
+PHY_IPhysicsController::~PHY_IPhysicsController()
+{
+
+}
+
diff --git a/source/gameengine/Physics/common/PHY_IPhysicsController.h b/source/gameengine/Physics/common/PHY_IPhysicsController.h
new file mode 100644
index 00000000000..e8309c0ca40
--- /dev/null
+++ b/source/gameengine/Physics/common/PHY_IPhysicsController.h
@@ -0,0 +1,89 @@
+/**
+ * $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 PHY_IPHYSICSCONTROLLER_H
+#define PHY_IPHYSICSCONTROLLER_H
+
+/**
+ PHY_IPhysicsController is the abstract simplified Interface to a physical object.
+ It contains the IMotionState and IDeformableMesh Interfaces.
+*/
+
+
+class PHY_IPhysicsController
+{
+
+ public:
+
+ virtual ~PHY_IPhysicsController();
+ /**
+ SynchronizeMotionStates ynchronizes dynas, kinematic and deformable entities (and do 'late binding')
+ */
+ virtual bool SynchronizeMotionStates(float time)=0;
+ /**
+ WriteMotionStateToDynamics ynchronizes dynas, kinematic and deformable entities (and do 'late binding')
+ */
+
+ virtual void WriteMotionStateToDynamics(bool nondynaonly)=0;
+ virtual void WriteDynamicsToMotionState()=0;
+ // controller replication
+ virtual void PostProcessReplica(class PHY_IMotionState* motionstate,class PHY_IPhysicsController* parentctrl)=0;
+
+ // kinematic methods
+ virtual void RelativeTranslate(float dlocX,float dlocY,float dlocZ,bool local)=0;
+ virtual void RelativeRotate(const float drot[9],bool local)=0;
+ virtual void getOrientation(float &quatImag0,float &quatImag1,float &quatImag2,float &quatReal)=0;
+ virtual void setOrientation(float quatImag0,float quatImag1,float quatImag2,float quatReal)=0;
+ virtual void setPosition(float posX,float posY,float posZ)=0;
+ virtual void setScaling(float scaleX,float scaleY,float scaleZ)=0;
+
+ // physics methods
+ virtual void ApplyTorque(float torqueX,float torqueY,float torqueZ,bool local)=0;
+ virtual void ApplyForce(float forceX,float forceY,float forceZ,bool local)=0;
+ virtual void SetAngularVelocity(float ang_velX,float ang_velY,float ang_velZ,bool local)=0;
+ virtual void SetLinearVelocity(float lin_velX,float lin_velY,float lin_velZ,bool local)=0;
+ virtual void applyImpulse(float attachX,float attachY,float attachZ, float impulseX,float impulseY,float impulseZ)=0;
+ virtual void SetActive(bool active)=0;
+
+ // reading out information from physics
+ virtual void GetLinearVelocity(float& linvX,float& linvY,float& linvZ)=0;
+ virtual void GetVelocity(const float posX,const float posY,const float posZ,float& linvX,float& linvY,float& linvZ)=0;
+ virtual void getReactionForce(float& forceX,float& forceY,float& forceZ)=0;
+
+ // dyna's that are rigidbody are free in orientation, dyna's with non-rigidbody are restricted
+ virtual void setRigidBody(bool rigid)=0;
+
+ // clientinfo for raycasts for example
+ virtual void* getClientInfo()=0;
+ virtual void setClientInfo(void* clientinfo)=0;
+};
+
+#endif //PHY_IPHYSICSCONTROLLER_H
diff --git a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.cpp b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.cpp
new file mode 100644
index 00000000000..7c0660976fb
--- /dev/null
+++ b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.cpp
@@ -0,0 +1,45 @@
+/**
+ * $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 "PHY_IPhysicsEnvironment.h"
+
+/**
+* Physics Environment takes care of stepping the simulation and is a container for physics entities (rigidbodies,constraints, materials etc.)
+* A derived class may be able to 'construct' entities by loading and/or converting
+*/
+
+
+
+PHY_IPhysicsEnvironment::~PHY_IPhysicsEnvironment()
+{
+
+}
diff --git a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
new file mode 100644
index 00000000000..5867e27ce42
--- /dev/null
+++ b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
@@ -0,0 +1,60 @@
+/**
+ * $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 _IPHYSICSENVIRONMENT
+#define _IPHYSICSENVIRONMENT
+
+#include <vector>
+#include "PHY_DynamicTypes.h"
+
+
+/**
+* Physics Environment takes care of stepping the simulation and is a container for physics entities (rigidbodies,constraints, materials etc.)
+* A derived class may be able to 'construct' entities by loading and/or converting
+*/
+class PHY_IPhysicsEnvironment
+{
+ public:
+ virtual ~PHY_IPhysicsEnvironment();
+ /// Perform an integration step of duration 'timeStep'.
+ virtual void proceed(double timeStep)=0;
+ virtual void setGravity(float x,float y,float z)=0;
+
+ virtual int createConstraint(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsController* ctrl2,PHY_ConstraintType type,
+ float pivotX,float pivotY,float pivotZ,
+ float axisX,float axisY,float axisZ)=0;
+ virtual void removeConstraint(int constraintid)=0;
+
+ virtual PHY_IPhysicsController* rayTest(void* ignoreClient, float fromX,float fromY,float fromZ, float toX,float toY,float toZ,
+ float& hitX,float& hitY,float& hitZ,float& normalX,float& normalY,float& normalZ)=0;
+};
+
+#endif //_IPHYSICSENVIRONMENT
diff --git a/source/gameengine/Physics/common/PHY_Pro.h b/source/gameengine/Physics/common/PHY_Pro.h
new file mode 100644
index 00000000000..58f3badaff6
--- /dev/null
+++ b/source/gameengine/Physics/common/PHY_Pro.h
@@ -0,0 +1,60 @@
+/**
+ * $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 PHY_PROPSH
+#define PHY_PROPSH
+
+#include <MT_Scalar.h>
+
+// Properties of dynamic objects
+struct PHY_ShapeProps {
+ MT_Scalar m_mass; // Total mass
+ MT_Scalar m_inertia; // Inertia, should be a tensor some time
+ MT_Scalar m_lin_drag; // Linear drag (air, water) 0 = concrete, 1 = vacuum
+ MT_Scalar m_ang_drag; // Angular drag
+ MT_Scalar m_friction_scaling[3]; // Scaling for anisotropic friction. Component in range [0, 1]
+ bool m_do_anisotropic; // Should I do anisotropic friction?
+ bool m_do_fh; // Should the object have a linear Fh spring?
+ bool m_do_rot_fh; // Should the object have an angular Fh spring?
+};
+
+
+// Properties of collidable objects (non-ghost objects)
+struct PHY_MaterialProps {
+ MT_Scalar m_restitution; // restitution of energie after a collision 0 = inelastic, 1 = elastic
+ MT_Scalar m_friction; // Coulomb friction (= ratio between the normal en maximum friction force)
+ MT_Scalar m_fh_spring; // Spring constant (both linear and angular)
+ MT_Scalar m_fh_damping; // Damping factor (linear and angular) in range [0, 1]
+ MT_Scalar m_fh_distance; // The range above the surface where Fh is active.
+ bool m_fh_normal; // Should the object slide off slopes?
+};
+
+#endif //PHY_PROPSH
diff --git a/source/gameengine/Rasterizer/Makefile b/source/gameengine/Rasterizer/Makefile
new file mode 100644
index 00000000000..6a1421ae90b
--- /dev/null
+++ b/source/gameengine/Rasterizer/Makefile
@@ -0,0 +1,51 @@
+#
+# $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 = rasterizer
+DIR = $(OCGDIR)/gameengine/$(LIBNAME)
+
+include nan_compile.mk
+
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+CPPFLAGS += -I$(OPENGL_HEADERS)
+CPPFLAGS += -I$(NAN_STRING)/include
+CPPFLAGS += -I$(NAN_MOTO)/include
+CPPFLAGS += -I../../kernel/gen_system
+
+###############
+
+SOURCEDIR = source/gameengine/Rasterizer
+DIRS = RAS_OpenGLRasterizer
+
+include nan_subdirs.mk
diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.cpp b/source/gameengine/Rasterizer/RAS_BucketManager.cpp
new file mode 100644
index 00000000000..39ec523cfa2
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_BucketManager.cpp
@@ -0,0 +1,156 @@
+/**
+ * $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
+// don't show these anoying STL warnings
+#pragma warning (disable:4786)
+#endif
+
+#include "GEN_Map.h"
+#include "RAS_MaterialBucket.h"
+#include "STR_HashedString.h"
+#include "RAS_MeshObject.h"
+#define KX_NUM_MATERIALBUCKETS 100
+#include "RAS_IRasterizer.h"
+#include "RAS_IRenderTools.h"
+
+#include "RAS_BucketManager.h"
+
+
+RAS_BucketManager::RAS_BucketManager()
+{
+
+}
+
+RAS_BucketManager::~RAS_BucketManager()
+{
+ RAS_BucketManagerClearAll();
+}
+
+
+void RAS_BucketManager::Renderbuckets(
+ const MT_Transform& cameratrans, RAS_IRasterizer* rasty, RAS_IRenderTools* rendertools)
+{
+ int numbuckets = m_MaterialBuckets.size();
+
+ //default_gl_light();
+
+ int i;
+
+ rasty->EnableTextures(false);
+ rasty->SetDepthMask(RAS_IRasterizer::KX_DEPTHMASK_ENABLED);
+
+ // beginning each frame, clear (texture/material) caching information
+ rasty->ClearCachingInfo();
+
+ RAS_MaterialBucket::StartFrame();
+
+ for (i=0;i<numbuckets;i++)
+ {
+ RAS_MaterialBucket** bucketptr = m_MaterialBuckets.at(i);
+ if (bucketptr)
+ {
+ (*bucketptr)->ClearScheduledPolygons();
+ }
+ }
+
+ vector<RAS_MaterialBucket*> alphabuckets;
+
+ // if no visibility method is define, everything is drawn
+
+ for (i=0;i<numbuckets;i++)
+ {
+ RAS_MaterialBucket** bucketptr = m_MaterialBuckets.at(i);
+ if (bucketptr)
+ {
+ if (!(*bucketptr)->IsTransparant())
+ {
+ (*bucketptr)->Render(cameratrans,rasty,rendertools);
+ } else
+ {
+ alphabuckets.push_back(*bucketptr);
+ }
+ }
+ }
+
+ rasty->SetDepthMask(RAS_IRasterizer::KX_DEPTHMASK_DISABLED);
+
+ int numalphabuckets = alphabuckets.size();
+ for (vector<RAS_MaterialBucket*>::const_iterator it=alphabuckets.begin();
+ !(it==alphabuckets.end());it++)
+ {
+ (*it)->Render(cameratrans,rasty,rendertools);
+ }
+
+ alphabuckets.clear();
+
+
+ RAS_MaterialBucket::EndFrame();
+
+ rasty->SetDepthMask(RAS_IRasterizer::KX_DEPTHMASK_ENABLED);
+}
+
+RAS_MaterialBucket* RAS_BucketManager::RAS_BucketManagerFindBucket(RAS_IPolyMaterial * material)
+{
+
+ RAS_MaterialBucket** bucketptr = m_MaterialBuckets[*material];
+ RAS_MaterialBucket* bucket=NULL;
+ if (!bucketptr)
+ {
+ bucket = new RAS_MaterialBucket(material);
+ m_MaterialBuckets.insert(*material,bucket);
+
+ } else
+ {
+ bucket = *bucketptr;
+ }
+
+ return bucket;
+}
+
+void RAS_BucketManager::RAS_BucketManagerClearAll()
+{
+
+ int numbuckets = m_MaterialBuckets.size();
+ for (int i=0;i<numbuckets;i++)
+ {
+ RAS_MaterialBucket** bucketptr = m_MaterialBuckets.at(i);
+ if (bucketptr)
+ {
+ delete (*bucketptr);
+ *bucketptr=NULL;
+
+ }
+ }
+ m_MaterialBuckets.clear();
+
+}
diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.h b/source/gameengine/Rasterizer/RAS_BucketManager.h
new file mode 100644
index 00000000000..72427473fc1
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_BucketManager.h
@@ -0,0 +1,63 @@
+/**
+ * $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 *****
+ */
+// this will be put in a class later on
+
+#ifndef __RAS_BUCKETMANAGER
+#define __RAS_BUCKETMANAGER
+
+#include "MT_Transform.h"
+#include "RAS_MaterialBucket.h"
+#include "GEN_Map.h"
+
+class RAS_BucketManager
+{
+
+ GEN_Map<class RAS_IPolyMaterial,class RAS_MaterialBucket*> m_MaterialBuckets;
+
+public:
+ RAS_BucketManager();
+ virtual ~RAS_BucketManager();
+
+ void Renderbuckets(const MT_Transform & cameratrans,
+ RAS_IRasterizer* rasty,
+ class RAS_IRenderTools* rendertools);
+
+ RAS_MaterialBucket* RAS_BucketManagerFindBucket(RAS_IPolyMaterial * material);
+
+
+private:
+ void RAS_BucketManagerClearAll();
+
+};
+
+#endif //__RAS_BUCKETMANAGER
+
diff --git a/source/gameengine/Rasterizer/RAS_CameraData.h b/source/gameengine/Rasterizer/RAS_CameraData.h
new file mode 100644
index 00000000000..5c9b1dd0e88
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_CameraData.h
@@ -0,0 +1,42 @@
+/**
+ * $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 __RAS_CAMERADATA_H
+#define __RAS_CAMERADATA_H
+
+struct RAS_CameraData
+{
+ float m_lens;
+ float m_clipstart;
+ float m_clipend;
+};
+
+#endif //__RAS_CAMERADATA_H
diff --git a/source/gameengine/Rasterizer/RAS_Deformer.h b/source/gameengine/Rasterizer/RAS_Deformer.h
new file mode 100644
index 00000000000..9aeb85c5740
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_Deformer.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 RAS_DEFORMER
+#define RAS_DEFORMER
+
+#ifdef WIN32
+#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
+#endif //WIN32
+
+#include "GEN_Map.h"
+
+class RAS_Deformer
+{
+public:
+ RAS_Deformer(){};
+ virtual ~RAS_Deformer(){};
+ virtual void Relink(GEN_Map<class GEN_HashedPtr, void*>*map)=0;
+ virtual bool Apply(class RAS_IPolyMaterial *polymat)=0;
+ virtual void Update(void)=0;
+ virtual RAS_Deformer *GetReplica()=0;
+protected:
+ class RAS_MeshObject *m_pMesh;
+};
+
+#endif
+
diff --git a/source/gameengine/Rasterizer/RAS_FramingManager.cpp b/source/gameengine/Rasterizer/RAS_FramingManager.cpp
new file mode 100644
index 00000000000..af0499bd348
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_FramingManager.cpp
@@ -0,0 +1,234 @@
+/**
+ * $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 "RAS_FramingManager.h"
+
+#include "RAS_Rect.h"
+
+ void
+RAS_FramingManager::
+ComputeDefaultFrustum(
+ const float camnear,
+ const float camfar,
+ const float lens,
+ const float design_aspect_ratio,
+ RAS_FrameFrustum & frustum
+){
+
+ /*
+ * Magic Blender calculation.
+ * Blender does not give a Field of View as lens but a size
+ * at 16 units away from the lens.
+ */
+ float halfSize = 16.f * camnear / lens;
+ float sizeX;
+ float sizeY;
+
+ if (design_aspect_ratio > 1.f) {
+ // halfsize defines the width
+ sizeX = halfSize;
+ sizeY = halfSize/design_aspect_ratio;
+ } else {
+ // halfsize defines the height
+ sizeX = halfSize * design_aspect_ratio;
+ sizeY = halfSize;
+ }
+
+ frustum.x2 = sizeX;
+ frustum.x1 = -frustum.x2;
+ frustum.y2 = sizeY;
+ frustum.y1 = -frustum.y2;
+ frustum.camnear = camnear;
+ frustum.camfar = camfar;
+}
+
+ void
+RAS_FramingManager::
+ComputeBestFitViewRect(
+ const RAS_Rect &availableViewport,
+ const float design_aspect_ratio,
+ RAS_Rect &viewport
+){
+ // try and honour the aspect ratio when setting the
+ // drawable area. If we don't do this we are liable
+ // to get a lot of distortion in the rendered image.
+
+ int width = availableViewport.GetWidth();
+ int height = availableViewport.GetHeight();
+ float window_aspect = float(width)/float(height);
+
+ if (window_aspect < design_aspect_ratio) {
+ int v_height = (int)(width / design_aspect_ratio);
+ int left_over = (height - v_height) / 2;
+
+ viewport.SetLeft(availableViewport.GetLeft());
+ viewport.SetBottom(availableViewport.GetBottom() + left_over);
+ viewport.SetRight(availableViewport.GetLeft() + width);
+ viewport.SetTop(availableViewport.GetBottom() + left_over + v_height);
+
+ } else {
+ int v_width = (int)(height * design_aspect_ratio);
+ int left_over = (width - v_width) / 2;
+
+ viewport.SetLeft(availableViewport.GetLeft() + left_over);
+ viewport.SetBottom(availableViewport.GetBottom());
+ viewport.SetRight(availableViewport.GetLeft() + v_width + left_over);
+ viewport.SetTop(availableViewport.GetBottom() + height);
+ }
+}
+
+ void
+RAS_FramingManager::
+ComputeViewport(
+ const RAS_FrameSettings &settings,
+ const RAS_Rect &availableViewport,
+ RAS_Rect &viewport
+){
+
+ RAS_FrameSettings::RAS_FrameType type = settings.FrameType();
+ const int winx = availableViewport.GetWidth();
+ const int winy = availableViewport.GetHeight();
+
+ const float design_width = float(settings.DesignAspectWidth());
+ const float design_height = float(settings.DesignAspectHeight());
+
+ float design_aspect_ratio = float(1);
+
+ if (design_height == float(0)) {
+ // well this is ill defined
+ // lets just scale the thing
+
+ type = RAS_FrameSettings::e_frame_scale;
+ } else {
+ design_aspect_ratio = design_width/design_height;
+ }
+
+ switch (type) {
+
+ case RAS_FrameSettings::e_frame_scale :
+ case RAS_FrameSettings::e_frame_extend:
+ {
+ viewport.SetLeft(availableViewport.GetLeft());
+ viewport.SetBottom(availableViewport.GetBottom());
+ viewport.SetRight(availableViewport.GetLeft() + int(winx));
+ viewport.SetTop(availableViewport.GetBottom() + int(winy));
+
+ break;
+ }
+
+ case RAS_FrameSettings::e_frame_bars:
+ {
+ ComputeBestFitViewRect(
+ availableViewport,
+ design_aspect_ratio,
+ viewport
+ );
+
+ break;
+ }
+ default :
+ break;
+ }
+}
+
+ void
+RAS_FramingManager::
+ComputeFrustum(
+ const RAS_FrameSettings &settings,
+ const RAS_Rect &availableViewport,
+ const RAS_Rect &viewport,
+ const float lens,
+ const float camnear,
+ const float camfar,
+ RAS_FrameFrustum &frustum
+){
+
+ const int winx = availableViewport.GetWidth();
+ const int winy = availableViewport.GetHeight();
+
+ RAS_FrameSettings::RAS_FrameType type = settings.FrameType();
+
+ const float design_width = float(settings.DesignAspectWidth());
+ const float design_height = float(settings.DesignAspectHeight());
+
+ float design_aspect_ratio = float(1);
+
+ if (design_height == float(0)) {
+ // well this is ill defined
+ // lets just scale the thing
+
+ type = RAS_FrameSettings::e_frame_scale;
+ } else {
+ design_aspect_ratio = design_width/design_height;
+ }
+
+ ComputeDefaultFrustum(
+ camnear,
+ camfar,
+ lens,
+ design_aspect_ratio,
+ frustum
+ );
+
+ switch (type) {
+
+ case RAS_FrameSettings::e_frame_extend:
+ {
+ RAS_Rect vt;
+ ComputeBestFitViewRect(
+ availableViewport,
+ design_aspect_ratio,
+ vt
+ );
+
+ // now scale the calculated frustum by the difference
+ // between vt and the viewport in each axis.
+ // These are always > 1
+
+ float x_scale = float(viewport.GetWidth())/float(vt.GetWidth());
+ float y_scale = float(viewport.GetHeight())/float(vt.GetHeight());
+
+ frustum.x1 *= x_scale;
+ frustum.x2 *= x_scale;
+ frustum.y1 *= y_scale;
+ frustum.y2 *= y_scale;
+
+ break;
+ }
+ case RAS_FrameSettings::e_frame_scale :
+ case RAS_FrameSettings::e_frame_bars:
+ default :
+ break;
+ }
+}
+
+
+
diff --git a/source/gameengine/Rasterizer/RAS_FramingManager.h b/source/gameengine/Rasterizer/RAS_FramingManager.h
new file mode 100644
index 00000000000..581c6b56fc9
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_FramingManager.h
@@ -0,0 +1,255 @@
+/**
+ * $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 RAS_FRAMINGMANAGER_H
+#define RAS_FRAMINGMANAGER_H
+
+class RAS_Rect;
+
+/**
+ * @section RAS_FrameSettings
+ * This is a value type describing the framing used
+ * by a particular scene in the game engine.
+ * Each KX_Scene contains a RAS_FrameSetting describing
+ * how the frustum and viewport are to be modified
+ * depending on the canvas size.
+ *
+ * e_frame_scale means that the viewport is set to the current
+ * canvas size. If the view frustum aspect ratio is different
+ * to the canvas aspect this will lead to stretching.
+ *
+ * e_frame_extend means that the best fit viewport will be
+ * computed based upon the design aspect ratio
+ * and the view frustum will be adjusted so that
+ * more of the scene is visible.
+ *
+ * e_frame_bars means that the best fit viewport will be
+ * be computed based upon the design aspect ratio.
+ */
+
+class RAS_FrameSettings
+{
+public :
+
+ /**
+ * enum defining the policy to use
+ * in each axis.
+ */
+ enum RAS_FrameType {
+ e_frame_scale,
+ e_frame_extend,
+ e_frame_bars
+ };
+
+ /**
+ * Contructor
+ */
+
+ RAS_FrameSettings(
+ RAS_FrameType frame_type,
+ float bar_r,
+ float bar_g,
+ float bar_b,
+ unsigned int design_aspect_width,
+ unsigned int design_aspect_height
+ ):
+ m_frame_type(frame_type),
+ m_bar_r(bar_r),
+ m_bar_g(bar_g),
+ m_bar_b(bar_b),
+ m_design_aspect_width(design_aspect_width),
+ m_design_aspect_height(design_aspect_height)
+ {
+ };
+
+ RAS_FrameSettings(
+ ):
+ m_frame_type(e_frame_scale),
+ m_bar_r(0),
+ m_bar_g(0),
+ m_bar_b(0),
+ m_design_aspect_width(1),
+ m_design_aspect_height(1)
+ {
+ };
+
+ /**
+ * Accessors
+ */
+
+ const
+ RAS_FrameType &
+ FrameType(
+ ) const {
+ return m_frame_type;
+ };
+
+ float
+ BarRed(
+ ) const {
+ return m_bar_r;
+ };
+
+ float
+ BarGreen(
+ ) const {
+ return m_bar_g;
+ };
+
+ float
+ BarBlue(
+ ) const {
+ return m_bar_b;
+ };
+
+ unsigned int
+ DesignAspectWidth(
+ ) const {
+ return m_design_aspect_width;
+ };
+
+ unsigned int
+ DesignAspectHeight(
+ ) const {
+ return m_design_aspect_height;
+ };
+
+private :
+
+ /**
+ * private to force use of public constructor
+ */
+
+ RAS_FrameSettings(
+ const RAS_FrameSettings &
+ );
+
+ RAS_FrameType m_frame_type;
+ float m_bar_r;
+ float m_bar_g;
+ float m_bar_b;
+ unsigned int m_design_aspect_width;
+ unsigned int m_design_aspect_height;
+};
+
+struct RAS_FrameFrustum
+{
+ float camnear,camfar;
+ float x1,y1;
+ float x2,y2;
+};
+
+
+/**
+ * @section RAS_FramingManager
+ * This class helps to compute a view frustum
+ * and a viewport rectangle given the
+ * above settings and a description of the
+ * current canvas dimensions.
+ *
+ * You do not have to instantiate this class
+ * directly, it only contains static helper functions
+ */
+
+class RAS_FramingManager
+{
+public :
+
+ /**
+ * Compute a viewport given
+ * a RAS_FrameSettings and a description of the
+ * canvas.
+ */
+
+ static
+ void
+ ComputeViewport(
+ const RAS_FrameSettings &settings,
+ const RAS_Rect &availableViewport,
+ RAS_Rect &viewport
+ );
+
+
+ /**
+ * compute a frustrum given a valid viewport,
+ * RAS_FrameSettings, canvas description
+ * and camera description
+ */
+
+ static
+ void
+ ComputeFrustum(
+ const RAS_FrameSettings &settings,
+ const RAS_Rect &availableViewport,
+ const RAS_Rect &viewport,
+ const float lens,
+ const float camnear,
+ const float camfar,
+ RAS_FrameFrustum &frustum
+ );
+
+
+private :
+
+ static
+ void
+ ComputeDefaultFrustum(
+ const float camnear,
+ const float camfar,
+ const float lens,
+ const float design_aspect_ratio,
+ RAS_FrameFrustum & frustum
+ );
+
+ static
+ void
+ ComputeBestFitViewRect(
+ const RAS_Rect &availableViewport,
+ const float design_aspect_ratio,
+ RAS_Rect &viewport
+ );
+
+
+
+ /**
+ * Private constructor - this class is not meant
+ * for instanciation.
+ */
+
+ RAS_FramingManager(
+ );
+
+ RAS_FramingManager(
+ const RAS_FramingManager &
+ );
+};
+
+#endif
diff --git a/source/gameengine/Rasterizer/RAS_ICanvas.h b/source/gameengine/Rasterizer/RAS_ICanvas.h
new file mode 100644
index 00000000000..8060313b4be
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_ICanvas.h
@@ -0,0 +1,172 @@
+/**
+ * $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 __RAS_ICANVAS
+#define __RAS_ICANVAS
+
+/**
+ * 2D rendering device context. The connection from 3d rendercontext to 2d surface.
+ */
+
+class RAS_Rect;
+
+
+class RAS_ICanvas
+{
+public:
+ enum BufferType {
+ COLOR_BUFFER=1,
+ DEPTH_BUFFER=2
+ };
+
+ enum RAS_MouseState
+ {
+ MOUSE_INVISIBLE=1,
+ MOUSE_WAIT,
+ MOUSE_NORMAL
+ };
+
+ virtual
+ ~RAS_ICanvas(
+ ) {
+ };
+
+ virtual
+ void
+ Init(
+ ) = 0;
+
+ virtual
+ void
+ BeginFrame(
+ )=0;
+
+ virtual
+ void
+ EndFrame(
+ )=0;
+
+ /**
+ * Initializes the canvas for drawing. Drawing to the canvas is
+ * only allowed between BeginDraw() and EndDraw().
+ *
+ * @retval false Acquiring the canvas failed.
+ * @retval true Acquiring the canvas succeeded.
+ *
+ */
+
+ virtual
+ bool
+ BeginDraw(
+ )=0;
+
+ /**
+ * Unitializes the canvas for drawing.
+ */
+
+ virtual
+ void
+ EndDraw(
+ )=0;
+
+
+ /// probably needs some arguments for PS2 in future
+ virtual
+ void
+ SwapBuffers(
+ )=0;
+
+ virtual
+ void
+ ClearBuffer(
+ int type
+ )=0;
+
+ virtual
+ void
+ ClearColor(
+ float r,
+ float g,
+ float b,
+ float a
+ )=0;
+
+ virtual
+ int
+ GetWidth(
+ ) const = 0;
+
+ virtual
+ int
+ GetHeight(
+ ) const = 0;
+
+ virtual
+ const RAS_Rect &
+ GetDisplayArea(
+ ) const = 0;
+
+ virtual
+ RAS_Rect &
+ GetDisplayArea(
+ ) = 0;
+
+ /**
+ * Set the visible vieport
+ */
+
+ virtual
+ void
+ SetViewPort(
+ int x1, int y1,
+ int x2, int y2
+ ) = 0;
+
+ virtual
+ void
+ SetMouseState(
+ RAS_MouseState mousestate
+ )=0;
+
+ virtual
+ void
+ SetMousePosition(
+ int x,
+ int y
+ )=0;
+
+ virtual
+ void
+ MakeScreenShot(
+ const char* filename
+ )=0;
+};
+#endif //__RAS_ICANVAS
diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
new file mode 100644
index 00000000000..7e1017b5c39
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
@@ -0,0 +1,125 @@
+/**
+ * $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 "RAS_IPolygonMaterial.h"
+
+
+RAS_IPolyMaterial::RAS_IPolyMaterial(const STR_String& texname,
+ bool ba,
+ const STR_String& matname,
+ int tile,
+ int tilexrep,
+ int tileyrep,
+ int mode,
+ int transparant,
+ int lightlayer,
+ bool bIsTriangle,
+ void* clientobject=NULL) :
+
+ m_texturename(texname),
+ m_materialname(matname),
+ m_tile(tile),
+ m_tilexrep(tilexrep),
+ m_tileyrep(tileyrep),
+ m_drawingmode (mode),
+ m_transparant(transparant),
+ m_lightlayer(lightlayer),
+ m_bIsTriangle(bIsTriangle)
+{
+ m_shininess = 35.0;
+ m_specular = MT_Vector3(0.5,0.5,0.5);
+ m_specularity = 1.0;
+ m_diffuse = MT_Vector3(0.5,0.5,0.5);
+}
+
+
+bool RAS_IPolyMaterial::Equals(const RAS_IPolyMaterial& lhs) const
+{
+ return (
+ this->m_texturename == lhs.m_texturename &&
+ this->m_tile == lhs.m_tile &&
+ this->m_tilexrep == lhs.m_tilexrep &&
+ this->m_tileyrep == lhs.m_tileyrep &&
+ this->m_transparant == lhs.m_transparant &&
+ this->m_drawingmode == lhs.m_drawingmode &&
+ this->m_bIsTriangle == lhs.m_bIsTriangle &&
+ this->m_lightlayer == lhs.m_lightlayer &&
+ this->m_materialname == lhs.m_materialname
+ );
+}
+
+
+
+int RAS_IPolyMaterial::GetLightLayer()
+{
+ return m_lightlayer;
+}
+
+
+
+bool RAS_IPolyMaterial::IsTransparant()
+{
+ return (m_transparant != 0);
+}
+
+
+
+bool RAS_IPolyMaterial::UsesTriangles()
+{
+ return m_bIsTriangle;
+}
+
+
+
+unsigned int RAS_IPolyMaterial::hash() const
+{
+ return m_texturename.hash();
+}
+
+
+
+int RAS_IPolyMaterial::GetDrawingMode()
+{
+ return m_drawingmode;
+}
+
+
+
+const STR_String& RAS_IPolyMaterial::GetMaterialName() const
+{
+ return m_materialname;
+}
+
+
+const STR_String& RAS_IPolyMaterial::GetTextureName() const
+{
+ return m_texturename;
+}
diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
new file mode 100644
index 00000000000..dd5fadab008
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
@@ -0,0 +1,123 @@
+/**
+ * $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 __RAS_IPOLYGONMATERIAL
+#define __RAS_IPOLYGONMATERIAL
+
+#include "STR_HashedString.h"
+
+
+/**
+ * Polygon Material on which the material buckets are sorted
+ *
+ */
+#include "MT_Vector3.h"
+#include "STR_HashedString.h"
+
+class RAS_IRasterizer;
+
+class RAS_IPolyMaterial
+{
+ //todo: remove these variables from this interface/protocol class
+protected:
+ STR_HashedString m_texturename;
+ STR_String m_materialname; //also needed for touchsensor
+ int m_tile;
+ int m_tilexrep,m_tileyrep;
+ int m_drawingmode; // tface->mode
+ int m_transparant;
+ int m_lightlayer;
+ bool m_bIsTriangle;
+
+public:
+
+ MT_Vector3 m_diffuse;
+ float m_shininess;
+ MT_Vector3 m_specular;
+ float m_specularity;
+
+ /** Used to store caching information for materials. */
+ typedef void* TCachingInfo;
+
+ // care! these are taken from blender polygonflags, see file DNA_mesh_types.h for #define TF_BILLBOARD etc.
+ enum MaterialFlags
+ {
+ BILLBOARD_SCREENALIGNED = 256,
+ BILLBOARD_AXISALIGNED = 4096,
+ SHADOW =8192
+ };
+
+ RAS_IPolyMaterial(const STR_String& texname,
+ bool ba,
+ const STR_String& matname,
+ int tile,
+ int tilexrep,
+ int tileyrep,
+ int mode,
+ int transparant,
+ int lightlayer,
+ bool bIsTriangle,
+ void* clientobject);
+ virtual ~RAS_IPolyMaterial() {};
+
+ /**
+ * Returns the caching information for this material,
+ * This can be used to speed up the rasterizing process.
+ * @return The caching information.
+ */
+ virtual TCachingInfo GetCachingInfo(void) const { return 0; }
+
+ /**
+ * Activates the material in the rasterizer.
+ * On entry, the cachingInfo contains info about the last activated material.
+ * On exit, the cachingInfo should contain updated info about this material.
+ * @param rasty The rasterizer in which the material should be active.
+ * @param cachingInfo The information about the material used to speed up rasterizing.
+ */
+ virtual void Activate(RAS_IRasterizer* rasty, TCachingInfo& cachingInfo) const {}
+
+ bool Equals(const RAS_IPolyMaterial& lhs) const;
+ int GetLightLayer();
+ bool IsTransparant();
+ bool UsesTriangles();
+ unsigned int hash() const;
+ int GetDrawingMode();
+ const STR_String& GetMaterialName() const;
+ const STR_String& GetTextureName() const;
+};
+
+inline bool operator ==( const RAS_IPolyMaterial & rhs,const RAS_IPolyMaterial & lhs)
+{
+ return ( rhs.Equals(lhs));
+}
+
+
+#endif //__RAS_IPOLYGONMATERIAL
diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h
new file mode 100644
index 00000000000..d3a2a74887c
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h
@@ -0,0 +1,191 @@
+/**
+ * $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 __RAS_IRASTERIZER
+#define __RAS_IRASTERIZER
+
+#ifdef WIN32
+#pragma warning (disable:4786)
+#endif
+
+#include "MT_CmMatrix4x4.h"
+#include "MT_Matrix4x4.h"
+
+class RAS_ICanvas;
+class RAS_IPolyMaterial;
+#include "RAS_MaterialBucket.h"
+
+/**
+ * 3D rendering device context interface.
+ */
+
+class RAS_IRasterizer
+{
+
+public:
+
+ RAS_IRasterizer(RAS_ICanvas* canv){};
+ virtual ~RAS_IRasterizer(){};
+ enum {
+ RAS_RENDER_3DPOLYGON_TEXT = 16384
+ };
+ enum {
+ KX_BOUNDINGBOX = 1,
+ KX_WIREFRAME,
+ KX_SOLID,
+ KX_SHADED,
+ KX_TEXTURED
+ };
+
+ enum {
+ KX_DEPTHMASK_ENABLED =1,
+ KX_DEPTHMASK_DISABLED,
+ };
+
+ enum {
+ RAS_STEREO_NOSTEREO = 1,
+ RAS_STEREO_QUADBUFFERED,
+ RAS_STEREO_ABOVEBELOW,
+ RAS_STEREO_INTERLACED,
+ };
+ enum {
+ RAS_STEREO_LEFTEYE = 1,
+ RAS_STEREO_RIGHTEYE,
+ };
+
+ virtual void SetDepthMask(int depthmask)=0;
+ virtual void SetMaterial(const RAS_IPolyMaterial& mat)=0;
+ virtual bool Init()=0;
+ virtual void Exit()=0;
+ virtual bool BeginFrame(int drawingmode, double time)=0;
+ virtual void ClearDepthBuffer()=0;
+ virtual void ClearCachingInfo(void)=0;
+ virtual void EndFrame()=0;
+ virtual void SetRenderArea()=0;
+
+ virtual void SetStereoMode(const int stereomode)=0;
+ virtual bool Stereo()=0;
+ virtual void SetEye(const int eye)=0;
+ virtual void SetEyeSeparation(const float eyeseparation)=0;
+ virtual void SetFocalLength(const float focallength)=0;
+
+ virtual void SwapBuffers()=0;
+ virtual void IndexPrimitives( const vecVertexArray& vertexarrays,
+ const vecIndexArrays & indexarrays,
+ int mode,
+ class RAS_IPolyMaterial* polymat,
+ class RAS_IRenderTools* rendertools,
+ bool useObjectColor,
+ const MT_Vector4& rgbacolor)=0;
+ virtual void IndexPrimitives_Ex( const vecVertexArray& vertexarrays,
+ const vecIndexArrays & indexarrays,
+ int mode,
+ class RAS_IPolyMaterial* polymat,
+ class RAS_IRenderTools* rendertools,
+ bool useObjectColor,
+ const MT_Vector4& rgbacolor)=0;
+ virtual void IndexPrimitives_3DText( const vecVertexArray& vertexarrays,
+ const vecIndexArrays & indexarrays,
+ int mode,
+ class RAS_IPolyMaterial* polymat,
+ class RAS_IRenderTools* rendertools,
+ bool useObjectColor,
+ const MT_Vector4& rgbacolor)=0;
+
+ virtual void SetProjectionMatrix(MT_CmMatrix4x4 & mat)=0;
+ /* This one should become our final version, methinks. */
+ /**
+ * Set the projection matrix for the rasterizer. This projects
+ * from camera coordinates to window coordinates.
+ * @param mat The projection matrix.
+ */
+ virtual void SetProjectionMatrix(MT_Matrix4x4 & mat)=0;
+ virtual void SetViewMatrix(const MT_Matrix4x4 & mat,
+ const MT_Vector3& campos,
+ const MT_Point3 &camLoc,
+ const MT_Quaternion &camOrientQuat)=0;
+ virtual const MT_Point3& GetCameraPosition()=0;
+ virtual void LoadViewMatrix()=0;
+
+ virtual void SetFog(float start,
+ float dist,
+ float r,
+ float g,
+ float b)=0;
+
+ virtual void SetFogColor(float r,
+ float g,
+ float b)=0;
+
+ virtual void SetFogStart(float start)=0;
+ virtual void SetFogEnd(float end)=0;
+
+ virtual void DisplayFog()=0;
+ virtual void DisableFog()=0;
+
+ virtual void SetBackColor(float red,
+ float green,
+ float blue,
+ float alpha)=0;
+
+ virtual void SetDrawingMode(int drawingmode)=0;
+ virtual int GetDrawingMode()=0;
+
+ virtual void EnableTextures(bool enable)=0;
+
+ virtual void SetCullFace(bool enable)=0;
+
+ virtual double GetTime()=0;
+
+ virtual MT_Matrix4x4 GetFrustumMatrix(
+ float left,
+ float right,
+ float bottom,
+ float top,
+ float frustnear,
+ float frustfar
+ )=0;
+
+ virtual void SetSpecularity(float specX,
+ float specY,
+ float specZ,
+ float specval)=0;
+
+ virtual void SetShinyness(float shiny)=0;
+ virtual void SetDiffuse(float difX,
+ float difY,
+ float difZ,
+ float diffuse)=0;
+
+};
+
+#endif //__RAS_IRASTERIZER
+
diff --git a/source/gameengine/Rasterizer/RAS_IRenderTools.cpp b/source/gameengine/Rasterizer/RAS_IRenderTools.cpp
new file mode 100644
index 00000000000..d52ba72af40
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_IRenderTools.cpp
@@ -0,0 +1,76 @@
+/**
+ * $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 "RAS_IRenderTools.h"
+
+
+
+void RAS_IRenderTools::SetViewMat(const MT_Transform& trans)
+{
+ trans.getValue(m_viewmat);
+}
+
+
+
+void RAS_IRenderTools::SetClientObject(void* obj)
+{
+ if (m_clientobject != obj)
+ {
+ m_clientobject = obj;
+ m_modified = true;
+ }
+}
+
+
+
+void RAS_IRenderTools::SetAuxilaryClientInfo(void* inf)
+{
+ m_auxilaryClientInfo = inf;
+}
+
+
+
+void RAS_IRenderTools::AddLight(struct RAS_LightObject* lightobject)
+{
+ m_lights.push_back(lightobject);
+}
+
+
+
+void RAS_IRenderTools::RemoveLight(struct RAS_LightObject* lightobject)
+{
+ std::vector<struct RAS_LightObject*>::iterator lit =
+ std::find(m_lights.begin(),m_lights.end(),lightobject);
+
+ if (!(lit==m_lights.end()))
+ m_lights.erase(lit);
+
+}
diff --git a/source/gameengine/Rasterizer/RAS_IRenderTools.h b/source/gameengine/Rasterizer/RAS_IRenderTools.h
new file mode 100644
index 00000000000..ac9033c7186
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_IRenderTools.h
@@ -0,0 +1,196 @@
+/**
+ * $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 __RAS_IRENDERTOOLS
+#define __RAS_IRENDERTOOLS
+
+#include "MT_Transform.h"
+#include "RAS_IRasterizer.h"
+
+
+#include <vector>
+#include <algorithm>
+
+class RAS_IPolyMaterial;
+struct RAS_LightObject;
+
+class RAS_IRenderTools
+{
+
+protected:
+ float m_viewmat[16];
+ void* m_clientobject;
+ void* m_auxilaryClientInfo;
+
+ bool m_modified;
+
+ std::vector<struct RAS_LightObject*> m_lights;
+
+
+public:
+ enum RAS_TEXT_RENDER_MODE {
+ RAS_TEXT_RENDER_NODEF = 0,
+ RAS_TEXT_NORMAL,
+ RAS_TEXT_PADDED,
+ RAS_TEXT_MAX,
+ };
+
+ RAS_IRenderTools(
+ ) :
+ m_modified(true),
+ m_clientobject(NULL)
+ {
+ };
+
+ virtual
+ ~RAS_IRenderTools(
+ ) {};
+
+ virtual
+ void
+ BeginFrame(
+ RAS_IRasterizer* rasty
+ )=0;
+
+ virtual
+ void
+ EndFrame(
+ RAS_IRasterizer* rasty
+ )=0;
+
+ // the following function was formerly called 'Render'
+ // by it doesn't render anymore
+ // It only sets the transform for the rasterizer
+ // so must be renamed to 'applyTransform' or something
+
+ virtual
+ void
+ applyTransform(
+ class RAS_IRasterizer* rasty,
+ double* oglmatrix,
+ int drawingmode
+ )=0;
+
+ /**
+ * Renders 2D text string.
+ * @param mode The type of text
+ * @param text The string to render.
+ * @param xco Position on the screen (origin in lower left corner).
+ * @param yco Position on the screen (origin in lower left corner).
+ * @param width Width of the canvas to draw to.
+ * @param height Height of the canvas to draw to.
+ */
+ virtual
+ void
+ RenderText2D(
+ RAS_TEXT_RENDER_MODE mode,
+ const char* text,
+ int xco,
+ int yco,
+ int width,
+ int height
+ ) = 0;
+
+ // 3d text, mapped on polygon
+ virtual
+ void
+ RenderText(
+ int mode,
+ RAS_IPolyMaterial* polymat,
+ float v1[3],
+ float v2[3],
+ float v3[3],
+ float v4[3]
+ )=0;
+
+ virtual
+ void
+ SetViewMat(
+ const MT_Transform& trans
+ );
+
+ virtual
+ int
+ ProcessLighting(
+ int layer
+ )=0;
+
+ void
+ SetClientObject(
+ void* obj
+ );
+
+ void
+ SetAuxilaryClientInfo(
+ void* inf
+ );
+
+ virtual
+ void
+ PushMatrix(
+ )=0;
+
+ virtual
+ void
+ PopMatrix(
+ )=0;
+
+ virtual
+ void
+ AddLight(
+ struct RAS_LightObject* lightobject
+ );
+
+ virtual
+ void
+ RemoveLight(
+ struct RAS_LightObject* lightobject
+ );
+
+ virtual
+ class RAS_IPolyMaterial*
+ CreateBlenderPolyMaterial(
+ const STR_String &texname,
+ bool ba,
+ const STR_String& matname,
+ int tile,
+ int tilexrep,
+ int tileyrep,
+ int mode,
+ int transparant,
+ int lightlayer,
+ bool bIsTriangle,
+ void* clientobject,
+ void* tface
+ )=0;
+};
+
+#endif //__RAS_IRENDERTOOLS
diff --git a/source/gameengine/Rasterizer/RAS_LightObject.h b/source/gameengine/Rasterizer/RAS_LightObject.h
new file mode 100644
index 00000000000..cd2014ba678
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_LightObject.h
@@ -0,0 +1,63 @@
+/**
+ * $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 __RAS_LIGHTOBJECT_H
+#define __RAS_LIGHTOBJECT_H
+
+#include "MT_CmMatrix4x4.h"
+
+struct RAS_LightObject
+{
+ enum LightType{
+ LIGHT_SPOT,
+ LIGHT_SUN,
+ LIGHT_NORMAL
+ };
+ bool m_modified;
+ int m_layer;
+
+ float m_energy;
+ float m_distance;
+
+ float m_red;
+ float m_green;
+ float m_blue;
+
+ float m_att1;
+ float m_spotsize;
+ float m_spotblend;
+
+ LightType m_type;
+ MT_CmMatrix4x4* m_worldmatrix;
+
+};
+
+#endif //__RAS_LIGHTOBJECT_H
diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
new file mode 100644
index 00000000000..ecb621c0d9d
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
@@ -0,0 +1,248 @@
+/**
+ * $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 "RAS_MaterialBucket.h"
+
+#ifdef WIN32
+#pragma warning (disable:4786)
+#include <windows.h>
+#endif // WIN32
+
+#include "RAS_Polygon.h"
+#include "RAS_TexVert.h"
+#include "RAS_IRasterizer.h"
+#include "RAS_IRenderTools.h"
+#include "RAS_MeshObject.h"
+#include "RAS_Deformer.h" // __NLA
+
+
+
+KX_VertexIndex::KX_VertexIndex(int size)
+{
+ m_size = size;
+}
+
+
+
+void KX_VertexIndex::SetIndex(short loc,short index)
+{
+ m_indexarray[loc]=index;
+}
+
+
+
+
+bool KX_MeshSlot::Less(const KX_MeshSlot& lhs) const
+{
+ bool result = ((m_mesh < lhs.m_mesh ) ||
+ ((m_mesh == lhs.m_mesh)&&(m_OpenGLMatrix < lhs.m_OpenGLMatrix)));
+
+ return result;
+}
+
+
+
+RAS_MaterialBucket::RAS_MaterialBucket(RAS_IPolyMaterial* mat)
+ :m_bModified(true)
+{
+ m_bScheduled=true;
+ m_material = mat;
+}
+
+
+
+void RAS_MaterialBucket::SchedulePolygons(int drawingmode)
+{
+ m_bScheduled = true;
+}
+
+
+
+void RAS_MaterialBucket::ClearScheduledPolygons()
+{
+ m_bScheduled = false;
+}
+
+
+
+RAS_IPolyMaterial* RAS_MaterialBucket::GetPolyMaterial()
+{
+ return m_material;
+}
+
+
+
+void RAS_MaterialBucket::SetMeshSlot(KX_MeshSlot& ms)
+{
+ m_meshSlots.insert(ms);
+}
+
+
+
+void RAS_MaterialBucket::RemoveMeshSlot(KX_MeshSlot& ms)
+{
+ T_MeshSlotList::iterator it = m_meshSlots.find(ms);
+
+ if (!(it == m_meshSlots.end()))
+ m_meshSlots.erase(it);
+
+}
+
+
+
+void RAS_MaterialBucket::MarkVisibleMeshSlot(KX_MeshSlot& ms,
+ bool visible,
+ bool color,
+ const MT_Vector4& rgbavec)
+{
+ T_MeshSlotList::iterator it = m_meshSlots.find(ms);
+
+ assert (!(it == m_meshSlots.end()));
+ (*it).m_bVisible = visible;
+ (*it).m_bObjectColor = color;
+ (*it).m_RGBAcolor= rgbavec;
+}
+
+
+
+bool RAS_MaterialBucket::IsTransparant()
+{
+ return (m_material->IsTransparant());
+}
+
+
+
+void RAS_MaterialBucket::StartFrame()
+{
+}
+
+
+
+void RAS_MaterialBucket::EndFrame()
+{
+}
+
+
+
+void RAS_MaterialBucket::Render(const MT_Transform& cameratrans,
+ RAS_IRasterizer* rasty,
+ RAS_IRenderTools* rendertools)
+{
+
+ if (m_meshSlots.begin()== m_meshSlots.end())
+ return;
+
+ rendertools->SetViewMat(cameratrans);
+
+ rasty->SetMaterial(*m_material);
+
+ if (m_meshSlots.size() >0)
+ {
+
+ rendertools->SetClientObject((*m_meshSlots.begin()).m_clientObj);
+ }
+
+ bool dolights = m_material->GetDrawingMode()&16;
+
+ if ((rasty->GetDrawingMode() <= RAS_IRasterizer::KX_SOLID) || !dolights)
+ {
+ bool bUseLights = rendertools->ProcessLighting(-1);
+ }
+ else
+ {
+ bool bUseLights = rendertools->ProcessLighting(m_material->GetLightLayer());
+ }
+
+ int drawmode = (rasty->GetDrawingMode() < RAS_IRasterizer::KX_SOLID ?
+ 1: (m_material->UsesTriangles() ? 0 : 2));
+
+ for (T_MeshSlotList::const_iterator it = m_meshSlots.begin();
+ ! (it == m_meshSlots.end());it++)
+ {
+ if ((*it).m_bVisible)
+ {
+ rendertools->SetClientObject((*it).m_clientObj);
+
+ /* __NLA Do the deformation */
+ if ((*it).m_pDeformer)
+ (*it).m_pDeformer->Apply(m_material);
+ /* End __NLA */
+
+ rendertools->PushMatrix();
+ rendertools->applyTransform(rasty,(*it).m_OpenGLMatrix,m_material->GetDrawingMode());
+
+ // Use the text-specific IndexPrimitives for text faces
+ if (m_material->GetDrawingMode() & RAS_IRasterizer::RAS_RENDER_3DPOLYGON_TEXT)
+ {
+ rasty->IndexPrimitives_3DText(
+ (*it).m_mesh->GetVertexCache(m_material),
+ (*it).m_mesh->GetIndexCache(m_material),
+ drawmode,
+ m_material,
+ rendertools, // needed for textprinting on polys
+ (*it).m_bObjectColor,
+ (*it).m_RGBAcolor);
+
+ }
+ // Use the (slower) IndexPrimitives_Ex which can recalc face normals & such
+ // for deformed objects - eventually should be extended to recalc ALL normals
+ else if ((*it).m_pDeformer){
+ rasty->IndexPrimitives_Ex(
+ (*it).m_mesh->GetVertexCache(m_material),
+ (*it).m_mesh->GetIndexCache(m_material),
+ drawmode,
+ m_material,
+ rendertools, // needed for textprinting on polys
+ (*it).m_bObjectColor,
+ (*it).m_RGBAcolor
+ );
+ }
+ // Use the normal IndexPrimitives
+ else
+ {
+ rasty->IndexPrimitives(
+ (*it).m_mesh->GetVertexCache(m_material),
+ (*it).m_mesh->GetIndexCache(m_material),
+ drawmode,
+ m_material,
+ rendertools, // needed for textprinting on polys
+ (*it).m_bObjectColor,
+ (*it).m_RGBAcolor
+ );
+ }
+
+ rendertools->PopMatrix();
+ }
+ }
+}
+
+
diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.h b/source/gameengine/Rasterizer/RAS_MaterialBucket.h
new file mode 100644
index 00000000000..06b1261c532
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.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 *****
+ */
+#ifndef __RAS_MATERIALBUCKET
+#define __RAS_MATERIALBUCKET
+
+#include "RAS_TexVert.h"
+#include "GEN_Map.h"
+#include "STR_HashedString.h"
+
+#include "MT_Transform.h"
+#include "RAS_IPolygonMaterial.h"
+#include "RAS_Deformer.h" // __NLA
+#include <vector>
+#include <map>
+#include <set>
+using namespace std;
+
+typedef vector< vector<class RAS_TexVert>* > vecVertexArray;
+typedef vector<unsigned int> KX_IndexArray;
+typedef vector< KX_IndexArray* > vecIndexArrays;
+
+typedef vector<RAS_TexVert> KX_VertexArray;
+
+
+
+struct KX_VertexIndex {
+public:
+ KX_VertexIndex(int size);
+ void SetIndex(short loc,short index);
+ short m_vtxarray;
+ short m_indexarray[4];
+ short m_size;
+};
+
+
+
+class KX_MeshSlot
+{
+public:
+ void* m_clientObj;
+ RAS_Deformer* m_pDeformer; // __NLA
+ double* m_OpenGLMatrix;
+ class RAS_MeshObject* m_mesh;
+ mutable bool m_bVisible; // for visibility
+ mutable bool m_bObjectColor;
+ mutable MT_Vector4 m_RGBAcolor;
+
+ KX_MeshSlot() :m_bVisible(true), m_pDeformer(NULL) {}
+ // KX_MeshSlot() :m_bVisible(true) {}
+
+ bool Less(const KX_MeshSlot& lhs) const;
+};
+
+
+inline bool operator <( const KX_MeshSlot& rhs,const KX_MeshSlot& lhs)
+{
+ return ( rhs.Less(lhs));
+}
+
+
+class RAS_MaterialBucket
+{
+ typedef std::set<KX_MeshSlot> T_MeshSlotList;
+
+ T_MeshSlotList m_meshSlots;
+ bool m_bScheduled;
+ bool m_bModified;
+ RAS_IPolyMaterial* m_material;
+ double* m_pOGLMatrix;
+
+public:
+ RAS_MaterialBucket(RAS_IPolyMaterial* mat);
+ virtual ~RAS_MaterialBucket() {}
+
+ void Render(const MT_Transform& cameratrans,
+ class RAS_IRasterizer* rasty,
+ class RAS_IRenderTools* rendertools);
+
+ void SchedulePolygons(int drawingmode);
+ void ClearScheduledPolygons();
+
+ RAS_IPolyMaterial* GetPolyMaterial();
+ bool IsTransparant();
+
+ static void StartFrame();
+ static void EndFrame();
+
+ void SetMeshSlot(KX_MeshSlot& ms);
+ void RemoveMeshSlot(KX_MeshSlot& ms);
+ void MarkVisibleMeshSlot(KX_MeshSlot& ms,
+ bool visible,
+ bool color,
+ const MT_Vector4& rgbavec);
+};
+
+
+#endif //__KX_BUCKET
diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
new file mode 100644
index 00000000000..3c78b7cf991
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
@@ -0,0 +1,635 @@
+/**
+ * $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 "RAS_MeshObject.h"
+
+#include "RAS_IRasterizer.h"
+#include "MT_MinMax.h"
+
+STR_String RAS_MeshObject::s_emptyname = "";
+
+
+
+KX_ArrayOptimizer::~KX_ArrayOptimizer()
+{
+ int i = 0;
+
+ for (vector<KX_VertexArray*>::iterator itv = m_VertexArrayCache1.begin();
+ !(itv == m_VertexArrayCache1.end());itv++)
+ {
+ delete (*itv);
+ }
+
+ for (vector<KX_IndexArray*>::iterator iti = m_IndexArrayCache1.begin();
+ !(iti == m_IndexArrayCache1.end());iti++)
+ {
+ delete (*iti);
+ }
+
+ m_TriangleArrayCount.clear();
+ m_VertexArrayCache1.clear();
+ m_IndexArrayCache1.clear();
+
+
+}
+
+
+
+RAS_MeshObject::RAS_MeshObject(int lightlayer)
+ : m_bModified(true),
+ m_lightlayer(lightlayer)
+{
+}
+
+
+
+RAS_MeshObject::~RAS_MeshObject()
+{
+ for (vector<RAS_Polygon*>::iterator it=m_Polygons.begin();!(it==m_Polygons.end());it++)
+ {
+ delete (*it);
+ }
+
+ ClearArrayData();
+}
+
+
+
+int RAS_MeshObject::GetLightLayer()
+{
+ return m_lightlayer;
+}
+
+
+
+int RAS_MeshObject::NumMaterials()
+{
+ return m_materials.size();
+}
+
+
+
+const STR_String& RAS_MeshObject::GetMaterialName(int matid)
+{
+ if (m_materials.size() > 0 && (matid < m_materials.size()))
+ {
+ BucketMaterialSet::iterator it = m_materials.begin();
+
+ for (int i = 1; i < m_materials.size(); i++)
+ {
+ it++;
+ }
+ return (*it)->GetPolyMaterial()->GetMaterialName();
+ }
+
+ return s_emptyname;
+}
+
+
+
+RAS_MaterialBucket* RAS_MeshObject::GetMaterialBucket(int matid)
+{
+ RAS_MaterialBucket* bucket = NULL;
+
+ if (m_materials.size() > 0 && (matid < m_materials.size()))
+ {
+ BucketMaterialSet::iterator it = m_materials.begin();
+ int i = matid;
+ while (i > 0)
+ {
+ i--;
+ it++;
+ }
+ bucket = *it;
+ }
+
+ return bucket;
+}
+
+
+
+int RAS_MeshObject::NumPolygons()
+{
+ return m_Polygons.size();
+}
+
+
+
+RAS_Polygon* RAS_MeshObject::GetPolygon(int num)
+{
+ return m_Polygons[num];
+}
+
+
+
+set<RAS_MaterialBucket*>::iterator RAS_MeshObject::GetFirstMaterial()
+{
+ return m_materials.begin();
+}
+
+
+
+set<RAS_MaterialBucket*>::iterator RAS_MeshObject::GetLastMaterial()
+{
+ return m_materials.end();
+}
+
+
+
+void RAS_MeshObject::SetName(STR_String name)
+{
+ m_name = name;
+}
+
+
+
+const STR_String& RAS_MeshObject::GetName()
+{
+ return m_name;
+}
+
+
+
+const STR_String& RAS_MeshObject::GetTextureName(int matid)
+{
+ if (m_materials.size() > 0 && (matid < m_materials.size()))
+ {
+ BucketMaterialSet::iterator it = m_materials.begin();
+ for (int i = 1; i < m_materials.size(); i++)
+ {
+ it++;
+ }
+
+ return (*it)->GetPolyMaterial()->GetTextureName();
+ }
+
+ return s_emptyname;
+}
+
+
+
+void RAS_MeshObject::AddPolygon(RAS_Polygon* poly)
+{
+ m_Polygons.push_back(poly);
+}
+
+
+
+void RAS_MeshObject::DebugColor(unsigned int abgr)
+{
+/*
+ int numpolys = NumPolygons();
+ for (int i=0;i<numpolys;i++)
+ {
+ RAS_Polygon* poly = m_polygons[i];
+ for (int v=0;v<poly->VertexCount();v++)
+ {
+ RAS_TexVert* vtx = poly->GetVertex(v);
+ vtx->setDebugRGBA(abgr);
+ }
+ }
+ */
+
+ m_debugcolor = abgr;
+}
+
+
+
+void RAS_MeshObject::SchedulePoly(const KX_VertexIndex& idx,
+ int numverts,
+ RAS_IPolyMaterial* mat)
+{
+ //int indexpos = m_IndexArrayCount[idx.m_vtxarray];
+ int indexidx = 0;
+ //m_IndexArrayCount[idx.m_vtxarray] = indexpos + 3;
+
+ KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);
+ ao->m_IndexArrayCache1[idx.m_vtxarray]->push_back(idx.m_indexarray[0]);
+ ao->m_IndexArrayCache1[idx.m_vtxarray]->push_back(idx.m_indexarray[1]);
+ ao->m_IndexArrayCache1[idx.m_vtxarray]->push_back(idx.m_indexarray[2]);
+ if (!mat->UsesTriangles()) //if (!m_bUseTriangles)
+ {
+ //m_IndexArrayCount[idx.m_vtxarray] = indexpos+4;
+ ao->m_IndexArrayCache1[idx.m_vtxarray]->push_back(idx.m_indexarray[3]);
+ }
+}
+
+
+
+void RAS_MeshObject::ScheduleWireframePoly(const KX_VertexIndex& idx,
+ int numverts,
+ int edgecode,
+ RAS_IPolyMaterial* mat)
+{
+ //int indexpos = m_IndexArrayCount[idx.m_vtxarray];
+ int edgetrace = 1<<(numverts-1);
+ bool drawedge = (edgecode & edgetrace)!=0;
+ edgetrace = 1;
+ int prevvert = idx.m_indexarray[numverts-1];
+ KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);
+
+ for (int v = 0; v < numverts; v++)
+ {
+ unsigned int curvert = idx.m_indexarray[v];
+ if (drawedge)
+ {
+ ao->m_IndexArrayCache1[idx.m_vtxarray]->push_back(prevvert);
+ ao->m_IndexArrayCache1[idx.m_vtxarray]->push_back(curvert);
+ }
+ prevvert = curvert;
+ drawedge = (edgecode & edgetrace)!=0;
+ edgetrace*=2;
+ }
+ //m_IndexArrayCount[idx.m_vtxarray] = indexpos;
+}
+
+int RAS_MeshObject::FindOrAddVertex(int vtxarray,
+ const MT_Point3& xyz,
+ const MT_Point2& uv,
+ const unsigned int rgbacolor,
+ const MT_Vector3& normal,
+ RAS_IPolyMaterial* mat,
+ int orgindex)
+{
+ short newnormal[3];
+
+ newnormal[0]=(short)((normal[0])*32767.0);
+ newnormal[1]=(short)((normal[1])*32767.0);
+ newnormal[2]=(short)((normal[2])*32767.0);
+
+ KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]);
+
+ int numverts = ao->m_VertexArrayCache1[vtxarray]->size();//m_VertexArrayCount[vtxarray];
+
+#define KX_FIND_SHARED_VERTICES
+#ifdef KX_FIND_SHARED_VERTICES
+
+ std::vector<RAS_MatArrayIndex>::iterator it = m_xyz_index_to_vertex_index_mapping[orgindex].begin();
+ int index=-1;
+ while (index < 0 && !(it == m_xyz_index_to_vertex_index_mapping[orgindex].end()))
+ {
+ if ((*it).m_arrayindex1 == ao->m_index1 &&
+ ((*it).m_array == vtxarray) &&
+ (RAS_IPolyMaterial*) (*it).m_matid == mat
+ )
+ {
+ return (*it).m_index;
+ }
+ it++;
+ }
+
+ if (index >= 0)
+ return index;
+#endif // KX_FIND_SHARED_VERTICES
+
+ // no vertex found, add one
+ ao->m_VertexArrayCache1[vtxarray]->push_back(RAS_TexVert (xyz,uv,rgbacolor,newnormal, 0));
+ // printf("(%f,%f,%f) ",xyz[0],xyz[1],xyz[2]);
+ RAS_MatArrayIndex idx;
+ idx.m_arrayindex1 = ao->m_index1;
+ idx.m_array = vtxarray;
+ idx.m_index = numverts;
+ idx.m_matid = (int) mat;
+ m_xyz_index_to_vertex_index_mapping[orgindex].push_back(idx);
+
+ return numverts;
+}
+
+
+
+const vecVertexArray& RAS_MeshObject::GetVertexCache (RAS_IPolyMaterial* mat)
+{
+ KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]);
+
+ return ao->m_VertexArrayCache1;
+}
+
+
+
+int RAS_MeshObject::GetVertexArrayLength(RAS_IPolyMaterial* mat)
+{
+ int len = 0;
+
+ const vecVertexArray & vertexvec = GetVertexCache(mat);
+ vector<KX_VertexArray*>::const_iterator it = vertexvec.begin();
+
+ for (; it != vertexvec.end(); it++)
+ {
+ len += (*it)->size();
+ }
+
+ return len;
+}
+
+
+
+RAS_TexVert* RAS_MeshObject::GetVertex(int matid,
+ int index)
+{
+ RAS_TexVert* vertex = NULL;
+
+ RAS_MaterialBucket* bucket = GetMaterialBucket(matid);
+ if (bucket)
+ {
+ RAS_IPolyMaterial* mat = bucket->GetPolyMaterial();
+ if (mat)
+ {
+ const vecVertexArray & vertexvec = GetVertexCache(mat);
+ vector<KX_VertexArray*>::const_iterator it = vertexvec.begin();
+
+ for (int len = 0; it != vertexvec.end(); it++)
+ {
+ if (index < len + (*it)->size())
+ {
+ vertex = &(*(*it))[index-len];
+ break;
+ }
+ else
+ {
+ len += (*it)->size();
+ }
+ }
+ }
+ }
+
+ return vertex;
+}
+
+
+
+const vecIndexArrays& RAS_MeshObject::GetIndexCache (RAS_IPolyMaterial* mat)
+{
+ KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]);
+
+ return ao->m_IndexArrayCache1;
+}
+
+
+
+KX_ArrayOptimizer* RAS_MeshObject::GetArrayOptimizer(RAS_IPolyMaterial* polymat)
+{
+ KX_ArrayOptimizer** aop = (m_matVertexArrayS[*polymat]);
+
+ if (aop)
+ return *aop;
+
+ int numelements = m_matVertexArrayS.size();
+ m_sortedMaterials.push_back(polymat);
+
+ KX_ArrayOptimizer* ao = new KX_ArrayOptimizer(numelements);
+ m_matVertexArrayS.insert(*polymat,ao);
+
+ return ao;
+}
+
+
+
+void RAS_MeshObject::Bucketize(double* oglmatrix,
+ void* clientobj,
+ bool useObjectColor,
+ const MT_Vector4& rgbavec)
+{
+ KX_MeshSlot ms;
+ ms.m_clientObj = clientobj;
+ ms.m_mesh = this;
+ ms.m_OpenGLMatrix = oglmatrix;
+ ms.m_bObjectColor = useObjectColor;
+ ms.m_RGBAcolor = rgbavec;
+
+ int i=0;
+ for (BucketMaterialSet::iterator it = m_materials.begin();it!=m_materials.end();it++)
+ {
+ RAS_MaterialBucket* bucket = *it;
+ bucket->SchedulePolygons(0);
+ KX_ArrayOptimizer* oa = GetArrayOptimizer(bucket->GetPolyMaterial());
+ bucket->SetMeshSlot(ms);
+ }
+
+}
+
+
+
+void RAS_MeshObject::MarkVisible(double* oglmatrix,
+ void* clientobj,
+ bool visible,
+ bool useObjectColor,
+ const MT_Vector4& rgbavec)
+{
+ KX_MeshSlot ms;
+ ms.m_clientObj = clientobj;
+ ms.m_mesh = this;
+ ms.m_OpenGLMatrix = oglmatrix;
+ ms.m_RGBAcolor = rgbavec;
+ ms.m_bObjectColor= useObjectColor;
+
+ for (BucketMaterialSet::iterator it = m_materials.begin();it!=m_materials.end();it++)
+ {
+ RAS_MaterialBucket* bucket = *it;
+ bucket->SchedulePolygons(0);
+ KX_ArrayOptimizer* oa = GetArrayOptimizer(bucket->GetPolyMaterial());
+ bucket->MarkVisibleMeshSlot(ms,visible,useObjectColor,rgbavec);
+ }
+}
+
+
+
+void RAS_MeshObject::RemoveFromBuckets(double* oglmatrix,
+ void* clientobj)
+{
+ KX_MeshSlot ms;
+ ms.m_clientObj = clientobj;
+ ms.m_mesh = this;
+ ms.m_OpenGLMatrix = oglmatrix;
+
+ for (BucketMaterialSet::iterator it = m_materials.begin();it!=m_materials.end();it++)
+ {
+ RAS_MaterialBucket* bucket = *it;
+ RAS_IPolyMaterial* polymat = bucket->GetPolyMaterial();
+ bucket->SchedulePolygons(0);
+ //KX_ArrayOptimizer* oa = GetArrayOptimizer(polymat);
+ bucket->RemoveMeshSlot(ms);
+ }
+
+}
+
+
+
+/*
+ * RAS_MeshObject::GetVertex returns the vertex located somewhere in the vertexpool
+ * it is the clients responsibility to make sure the array and index are valid
+ */
+RAS_TexVert* RAS_MeshObject::GetVertex(short array,
+ short index,
+ RAS_IPolyMaterial* polymat)
+{
+ KX_ArrayOptimizer* ao = GetArrayOptimizer(polymat);//*(m_matVertexArrays[*polymat]);
+ return &((*(ao->m_VertexArrayCache1)[array])[index]);
+}
+
+
+
+void RAS_MeshObject::ClearArrayData()
+{
+ for (int i=0;i<m_matVertexArrayS.size();i++)
+ { KX_ArrayOptimizer** ao = m_matVertexArrayS.at(i);
+ if (ao)
+ delete *ao;
+ }
+}
+
+
+
+/**
+ * RAS_MeshObject::CreateNewVertices creates vertices within sorted pools of vertices that share same material
+*/
+int RAS_MeshObject::FindVertexArray(int numverts,
+ RAS_IPolyMaterial* polymat)
+{
+ bool found=false;
+ int array=-1;
+
+ KX_ArrayOptimizer* ao = GetArrayOptimizer(polymat);
+
+ for (int i=0;i<ao->m_VertexArrayCache1.size();i++)
+ {
+ if ( (ao->m_TriangleArrayCount[i] + (numverts-2)) < BUCKET_MAX_TRIANGLES)
+ {
+ if((ao->m_VertexArrayCache1[i]->size()+numverts < BUCKET_MAX_INDICES))
+ {
+ array = i;
+ ao->m_TriangleArrayCount[array]+=numverts-2;
+ break;
+ }
+ }
+ else
+ {
+ int i=0;
+ }
+ }
+
+ if (array == -1)
+ {
+ array = ao->m_VertexArrayCache1.size();
+ vector<RAS_TexVert>* va = new vector<RAS_TexVert>;
+ ao->m_VertexArrayCache1.push_back(va);
+ KX_IndexArray *ia = new KX_IndexArray();
+ ao->m_IndexArrayCache1.push_back(ia);
+ ao->m_TriangleArrayCount.push_back(numverts-2);
+ }
+
+ return array;
+}
+
+
+
+
+//void RAS_MeshObject::Transform(const MT_Transform& trans)
+//{
+ //m_trans.translate(MT_Vector3(0,0,1));//.operator *=(trans);
+
+// for (int i=0;i<m_Polygons.size();i++)
+// {
+// m_Polygons[i]->Transform(trans);
+// }
+//}
+
+
+/*
+void RAS_MeshObject::RelativeTransform(const MT_Vector3& vec)
+{
+ for (int i=0;i<m_Polygons.size();i++)
+ {
+ m_Polygons[i]->RelativeTransform(vec);
+ }
+}
+*/
+
+
+
+void RAS_MeshObject::UpdateMaterialList()
+{
+ m_materials.clear();
+ int numpolys = m_Polygons.size();
+ // for all polygons, find out which material they use, and add it to the set of materials
+ for (int i=0;i<numpolys;i++)
+ {
+ m_materials.insert(m_Polygons[i]->GetMaterial());
+ }
+ int nummaterials = m_materials.size();
+
+}
+
+
+
+void RAS_MeshObject::SchedulePolygons(int drawingmode,RAS_IRasterizer* rasty)
+{
+ int nummaterials = m_materials.size();
+ int i;
+
+ if (m_bModified)
+ {
+ for (BucketMaterialSet::iterator it = m_materials.begin();it!=m_materials.end();it++)
+ {
+ RAS_MaterialBucket* bucket = *it;
+
+ bucket->SchedulePolygons(drawingmode);
+ }
+
+ int numpolys = m_Polygons.size();
+
+ if ((rasty->GetDrawingMode() > RAS_IRasterizer::KX_BOUNDINGBOX) &&
+ (rasty->GetDrawingMode() < RAS_IRasterizer::KX_SOLID))
+ {
+ for (i=0;i<numpolys;i++)
+ {
+ RAS_Polygon* poly = m_Polygons[i];
+ if (poly->IsVisible())
+ ScheduleWireframePoly(poly->GetVertexIndexBase(),poly->VertexCount(),poly->GetEdgeCode()
+ ,poly->GetMaterial()->GetPolyMaterial());
+
+ }
+ }
+ else
+ {
+ for (i=0;i<numpolys;i++)
+ {
+ RAS_Polygon* poly = m_Polygons[i];
+ if (poly->IsVisible())
+ {
+ SchedulePoly(poly->GetVertexIndexBase(),poly->VertexCount(),poly->GetMaterial()->GetPolyMaterial());
+ }
+ }
+ }
+
+ m_bModified = false;
+ }
+ // }
+}
diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h
new file mode 100644
index 00000000000..95a2858d7bf
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_MeshObject.h
@@ -0,0 +1,230 @@
+/**
+ * $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 __RAS_MESHOBJECT
+#define __RAS_MESHOBJECT
+
+
+#ifdef WIN32
+// disable the STL warnings ("debug information length > 255")
+#pragma warning (disable:4786)
+#endif
+
+#include <vector>
+#include <set>
+
+#include "RAS_Polygon.h"
+#include "MT_Transform.h"
+
+#include "GEN_HashedPtr.h"
+
+class KX_ArrayOptimizer
+{
+public:
+ KX_ArrayOptimizer(int index)
+ : m_index1(index)
+ {};
+ virtual ~KX_ArrayOptimizer();
+
+ vector<KX_VertexArray*> m_VertexArrayCache1;
+ vector<int> m_TriangleArrayCount;
+ vector<KX_IndexArray*> m_IndexArrayCache1;
+
+ /**
+ order in which they are stored into the mesh
+ */
+ int m_index1;
+};
+
+struct RAS_TriangleIndex
+{
+public:
+ int m_index[3];
+ bool m_collider;
+};
+
+class RAS_MatArrayIndex
+{
+public:
+
+ int m_arrayindex1;
+ int m_matid;
+ int m_array;
+ int m_index;
+
+ inline bool Less(const RAS_MatArrayIndex& lhs) const {
+ bool result =
+ ( (m_matid < lhs.m_matid) ||
+ ((m_matid == lhs.m_matid)&&(m_array < lhs.m_array)) ||
+ ((m_matid == lhs.m_matid) && (m_array == lhs.m_array) &&
+ (m_index < lhs.m_index))
+
+ );
+ return result;
+
+ }
+
+
+};
+inline bool operator <( const RAS_MatArrayIndex& rhs,const RAS_MatArrayIndex& lhs)
+{
+ return ( rhs.Less(lhs));
+}
+
+
+class RAS_MeshObject
+{
+
+ enum { BUCKET_MAX_INDICES = 2048 };//2048};//8192};
+ enum { BUCKET_MAX_TRIANGLES = 1024 };
+
+ // GEN_Map<class RAS_IPolyMaterial,KX_ArrayOptimizer*> m_matVertexArrayS;
+ //vector<class RAS_IPolyMaterial*,KX_ArrayOptimizer> m_vertexArrays;
+ virtual KX_ArrayOptimizer* GetArrayOptimizer(RAS_IPolyMaterial* polymat);
+ //vector<RAS_Polygon*> m_polygons;
+
+ unsigned int m_debugcolor;
+ bool m_bModified;
+ int m_lightlayer;
+
+ vector<class RAS_Polygon*> m_Polygons;
+ STR_String m_name;
+ static STR_String s_emptyname;
+
+protected:
+ GEN_Map<class RAS_IPolyMaterial,KX_ArrayOptimizer*> m_matVertexArrayS;
+ typedef set<class RAS_MaterialBucket*> BucketMaterialSet;
+
+ BucketMaterialSet m_materials;
+public:
+ // for now, meshes need to be in a certain layer (to avoid sorting on lights in realtime)
+ RAS_MeshObject(int lightlayer);
+ virtual ~RAS_MeshObject();
+
+ vector<RAS_IPolyMaterial*> m_sortedMaterials;
+ vector<vector<RAS_MatArrayIndex> > m_xyz_index_to_vertex_index_mapping;
+ vector<RAS_TriangleIndex > m_triangle_indices;
+
+ int GetLightLayer();
+ int NumMaterials();
+ const STR_String& GetMaterialName(int matid);
+ RAS_MaterialBucket* GetMaterialBucket(int matid);
+ const STR_String& GetTextureName(int matid);
+ virtual void AddPolygon(RAS_Polygon* poly);
+ void UpdateMaterialList();
+
+ int NumPolygons();
+ RAS_Polygon* GetPolygon(int num);
+
+ virtual void Bucketize(
+ double* oglmatrix,
+ void* clientobj,
+ bool useObjectColor,
+ const MT_Vector4& rgbavec
+ );
+
+ void RemoveFromBuckets(
+ double* oglmatrix,
+ void* clientobj
+ );
+
+ void MarkVisible(
+ double* oglmatrix,
+ void* clientobj,
+ bool visible,
+ bool useObjectColor,
+ const MT_Vector4& rgbavec
+ );
+
+ void DebugColor(unsigned int abgr);
+
+ void SchedulePolygons(
+ int drawingmode,
+ class RAS_IRasterizer* rasty
+ );
+
+ void ClearArrayData();
+
+ set<RAS_MaterialBucket*>::iterator GetFirstMaterial();
+ set<RAS_MaterialBucket*>::iterator GetLastMaterial();
+
+ virtual RAS_TexVert* GetVertex(
+ short array,
+ short index,
+ RAS_IPolyMaterial* polymat
+ );
+
+ virtual int FindVertexArray(
+ int numverts,
+ RAS_IPolyMaterial* polymat
+ );
+
+ void SchedulePoly(
+ const KX_VertexIndex& idx,
+ int numverts,
+ RAS_IPolyMaterial* mat
+ );
+
+ void ScheduleWireframePoly(
+ const KX_VertexIndex& idx,
+ int numverts,
+ int edgecode,
+ RAS_IPolyMaterial* mat
+ );
+
+ // find (and share) or add vertices
+ // for some speedup, only the last 20 added vertices are searched for equality
+
+ virtual int FindOrAddVertex(
+ int vtxarray,
+ const MT_Point3& xyz,
+ const MT_Point2& uv,
+ const unsigned int rgbacolor,
+ const MT_Vector3& normal,
+ RAS_IPolyMaterial* mat,
+ int orgindex
+ );
+
+ const vecVertexArray& GetVertexCache (RAS_IPolyMaterial* mat);
+
+ int GetVertexArrayLength(RAS_IPolyMaterial* mat);
+
+ RAS_TexVert* GetVertex(
+ int matid,
+ int index
+ );
+
+ const vecIndexArrays& GetIndexCache (RAS_IPolyMaterial* mat);
+ void SetName(STR_String name);
+ const STR_String& GetName();
+};
+
+#endif //__RAS_MESHOBJECT
diff --git a/source/gameengine/Rasterizer/RAS_ObjectColor.h b/source/gameengine/Rasterizer/RAS_ObjectColor.h
new file mode 100644
index 00000000000..217ca9c8343
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_ObjectColor.h
@@ -0,0 +1,41 @@
+/**
+ * $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 __RAS_OBJECTCOLOR_H
+#define __RAS_OBJECTCOLOR_H
+
+struct RAS_ObjectColor {
+ float m_red;
+ float m_green;
+ float m_blue;
+};
+
+#endif //__RAS_OBJECTCOLOR_H
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/Makefile b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/Makefile
new file mode 100644
index 00000000000..c03aab3422e
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/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 *****
+#
+# Bounce make to subdirectories.
+#
+
+LIBNAME = OpenGLrasterizer
+DIR = $(OCGDIR)/gameengine/$(LIBNAME)
+
+include nan_compile.mk
+
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+CPPFLAGS += -I$(OPENGL_HEADERS)
+CPPFLAGS += -I$(NAN_STRING)/include
+CPPFLAGS += -I$(NAN_MOTO)/include
+CPPFLAGS += -I../../../kernel/gen_system
+CPPFLAGS += -I..
+
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_CheckVertexArrays.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_CheckVertexArrays.cpp
new file mode 100644
index 00000000000..ff57e7ab102
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_CheckVertexArrays.cpp
@@ -0,0 +1,61 @@
+/**
+ * $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 "RAS_CheckVertexArrays.h"
+
+#ifdef WIN32
+#include <windows.h>
+#endif // WIN32
+#include "GL/gl.h"
+
+#include "STR_String.h"
+
+
+bool RAS_SystemSupportsVertexArrays() {
+
+ bool result = false;
+
+ char* ext = (char*) glGetString(GL_EXTENSIONS);
+ STR_String extensions;
+
+ if (ext)
+ extensions = STR_String(ext);
+
+#ifdef WIN32
+ if (extensions.Find("GL_EXT_compiled_vertex_array") >= 0)
+ {
+ result=true;
+ }
+#endif //WIN32
+
+ return result;
+
+}
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_CheckVertexArrays.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_CheckVertexArrays.h
new file mode 100644
index 00000000000..f9edafb7d2e
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_CheckVertexArrays.h
@@ -0,0 +1,37 @@
+/**
+ * $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 __RAS_CHECKVERTEXARRAYS
+#define __RAS_CHECKVERTEXARRAYS
+
+bool RAS_SystemSupportsVertexArrays();
+
+#endif //__RAS_CHECKVERTEXARRAYS
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
new file mode 100644
index 00000000000..32b5852137b
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
@@ -0,0 +1,1226 @@
+#include "RAS_OpenGLRasterizer.h"
+
+#ifdef WIN32
+#include <windows.h>
+#endif // WIN32
+#include "GL/gl.h"
+
+#include "RAS_Rect.h"
+#include "RAS_TexVert.h"
+#include "MT_CmMatrix4x4.h"
+#include "RAS_IRenderTools.h" // rendering text
+
+
+RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
+ :RAS_IRasterizer(canvas),
+ m_2DCanvas(canvas),
+ m_fogenabled(false),
+ m_materialCachingInfo(0),
+ m_noOfScanlines(32)
+{
+ m_viewmatrix.Identity();
+ m_stereomode = RAS_STEREO_NOSTEREO;
+}
+
+
+
+RAS_OpenGLRasterizer::~RAS_OpenGLRasterizer()
+{
+}
+
+
+
+void Myinit_gl_stuff(void)
+{
+ float mat_specular[] = { 0.5, 0.5, 0.5, 1.0 };
+ float mat_shininess[] = { 35.0 };
+/* float one= 1.0; */
+ int a, x, y;
+ GLubyte pat[32*32];
+ const GLubyte *patc= pat;
+
+ glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_specular);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
+
+
+#if defined(__FreeBSD) || defined(__linux__)
+ glDisable(GL_DITHER); /* op sgi/sun hardware && 12 bits */
+#endif
+
+ /* no local viewer, looks ugly in ortho mode */
+ /* glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, &one); */
+
+ glDepthFunc(GL_LEQUAL);
+ /* scaling matrices */
+ glEnable(GL_NORMALIZE);
+
+ glShadeModel(GL_FLAT);
+
+ glDisable(GL_ALPHA_TEST);
+ glDisable(GL_BLEND);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_FOG);
+ glDisable(GL_LIGHTING);
+ glDisable(GL_LOGIC_OP);
+ glDisable(GL_STENCIL_TEST);
+ glDisable(GL_TEXTURE_1D);
+ glDisable(GL_TEXTURE_2D);
+
+ glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
+ glPixelTransferi(GL_RED_SCALE, 1);
+ glPixelTransferi(GL_RED_BIAS, 0);
+ glPixelTransferi(GL_GREEN_SCALE, 1);
+ glPixelTransferi(GL_GREEN_BIAS, 0);
+ glPixelTransferi(GL_BLUE_SCALE, 1);
+ glPixelTransferi(GL_BLUE_BIAS, 0);
+ glPixelTransferi(GL_ALPHA_SCALE, 1);
+ glPixelTransferi(GL_ALPHA_BIAS, 0);
+
+ a = 0;
+ for(x=0; x<32; x++)
+ {
+ for(y=0; y<4; y++)
+ {
+ if( (x) & 1) pat[a++]= 0x88;
+ else pat[a++]= 0x22;
+ }
+ }
+
+ glPolygonStipple(patc);
+}
+
+
+
+bool RAS_OpenGLRasterizer::Init()
+{
+
+ Myinit_gl_stuff();
+
+ m_redback = 0.4375;
+ m_greenback = 0.4375;
+ m_blueback = 0.4375;
+ m_alphaback = 0.0;
+
+ // enable both vertexcolor AND lighting color
+ glEnable(GL_COLOR_MATERIAL);
+
+ glClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glShadeModel(GL_SMOOTH);
+
+ return true;
+}
+
+
+
+void RAS_OpenGLRasterizer::SetBackColor(float red,
+ float green,
+ float blue,
+ float alpha)
+{
+ m_redback = red;
+ m_greenback = green;
+ m_blueback = blue;
+ m_alphaback = alpha;
+}
+
+
+
+void RAS_OpenGLRasterizer::SetFogColor(float r,
+ float g,
+ float b)
+{
+ m_fogr = r;
+ m_fogg = g;
+ m_fogb = b;
+ m_fogenabled = true;
+}
+
+
+
+void RAS_OpenGLRasterizer::SetFogStart(float start)
+{
+ m_fogstart = start;
+ m_fogenabled = true;
+}
+
+
+
+void RAS_OpenGLRasterizer::SetFogEnd(float fogend)
+{
+ m_fogdist = fogend;
+ m_fogenabled = true;
+}
+
+
+
+void RAS_OpenGLRasterizer::SetFog(float start,
+ float dist,
+ float r,
+ float g,
+ float b)
+{
+ m_fogstart = start;
+ m_fogdist = dist;
+ m_fogr = r;
+ m_fogg = g;
+ m_fogb = b;
+ m_fogenabled = true;
+}
+
+
+
+void RAS_OpenGLRasterizer::DisableFog()
+{
+ m_fogenabled = false;
+}
+
+
+
+void RAS_OpenGLRasterizer::DisplayFog()
+{
+ if ((m_drawingmode >= KX_SOLID) && m_fogenabled)
+ {
+ float params[5];
+ glFogi(GL_FOG_MODE, GL_LINEAR);
+ glFogf(GL_FOG_DENSITY, 0.1f);
+ glFogf(GL_FOG_START, m_fogstart);
+ glFogf(GL_FOG_END, m_fogstart + m_fogdist);
+ params[0]= m_fogr;
+ params[1]= m_fogg;
+ params[2]= m_fogb;
+ params[3]= 0.0;
+ glFogfv(GL_FOG_COLOR, params);
+ glEnable(GL_FOG);
+ }
+ else
+ {
+ glDisable(GL_FOG);
+ }
+}
+
+
+
+void RAS_OpenGLRasterizer::SetMaterial(const RAS_IPolyMaterial& mat)
+{
+ if (mat.GetCachingInfo() != m_materialCachingInfo)
+ {
+ mat.Activate(this, m_materialCachingInfo);
+ }
+}
+
+
+
+void RAS_OpenGLRasterizer::Exit()
+{
+
+ glEnable(GL_CULL_FACE);
+ glEnable(GL_DEPTH_TEST);
+ glClearDepth(1.0);
+ glClearColor(m_redback, m_greenback, m_blueback, m_alphaback);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glDepthMask (GL_TRUE);
+ glDepthFunc(GL_LEQUAL);
+ glBlendFunc(GL_ONE, GL_ZERO);
+
+ glDisable(GL_LIGHTING);
+
+ EndFrame();
+}
+
+
+
+bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time)
+{
+ m_time = time;
+ m_drawingmode = drawingmode;
+
+ m_2DCanvas->ClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
+ m_2DCanvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER);
+
+ // Blender camera routine destroys the settings
+ if (m_drawingmode < KX_SOLID)
+ {
+ glDisable (GL_CULL_FACE);
+ glDisable (GL_DEPTH_TEST);
+ }
+ else
+ {
+ glEnable(GL_DEPTH_TEST);
+ glEnable (GL_CULL_FACE);
+ }
+
+ glShadeModel(GL_SMOOTH);
+
+ m_2DCanvas->BeginFrame();
+
+ return true;
+}
+
+
+
+void RAS_OpenGLRasterizer::SetDrawingMode(int drawingmode)
+{
+ m_drawingmode = drawingmode;
+
+ switch (m_drawingmode)
+ {
+ case KX_BOUNDINGBOX:
+ {
+ }
+ case KX_WIREFRAME:
+ {
+ glDisable (GL_CULL_FACE);
+ break;
+ }
+ case KX_TEXTURED:
+ {
+ }
+ case KX_SHADED:
+ {
+ }
+ case KX_SOLID:
+ {
+ }
+ default:
+ {
+ }
+ }
+}
+
+
+
+int RAS_OpenGLRasterizer::GetDrawingMode()
+{
+ return m_drawingmode;
+}
+
+
+
+void RAS_OpenGLRasterizer::SetDepthMask(int depthmask)
+{
+ switch (depthmask)
+ {
+ case KX_DEPTHMASK_ENABLED:
+ {
+ glDepthMask(GL_TRUE);
+ break;
+ };
+ case KX_DEPTHMASK_DISABLED:
+ {
+ glDepthMask(GL_FALSE);
+ break;
+ };
+ default:
+ {
+ //printf("someone made a mistake, RAS_OpenGLRasterizer::SetDepthMask(int depthmask)\n");
+ exit(0);
+ }
+ }
+}
+
+
+
+void RAS_OpenGLRasterizer::ClearDepthBuffer()
+{
+ m_2DCanvas->ClearBuffer(RAS_ICanvas::DEPTH_BUFFER);
+}
+
+
+void RAS_OpenGLRasterizer::ClearCachingInfo(void)
+{
+ m_materialCachingInfo = 0;
+}
+
+
+void RAS_OpenGLRasterizer::EndFrame()
+{
+ m_2DCanvas->EndFrame();
+}
+
+
+void RAS_OpenGLRasterizer::SetRenderArea()
+{
+ // only above/below stereo method needs viewport adjustment
+ if(m_stereomode == RAS_STEREO_ABOVEBELOW)
+ {
+ switch(m_curreye)
+ {
+ case RAS_STEREO_LEFTEYE:
+ // upper half of window
+ m_2DCanvas->GetDisplayArea().SetLeft(0);
+ m_2DCanvas->GetDisplayArea().SetBottom(m_2DCanvas->GetHeight() -
+ int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2);
+
+ m_2DCanvas->GetDisplayArea().SetRight(int(m_2DCanvas->GetWidth()));
+ m_2DCanvas->GetDisplayArea().SetTop(int(m_2DCanvas->GetHeight()));
+ break;
+ case RAS_STEREO_RIGHTEYE:
+ // lower half of window
+ m_2DCanvas->GetDisplayArea().SetLeft(0);
+ m_2DCanvas->GetDisplayArea().SetBottom(0);
+ m_2DCanvas->GetDisplayArea().SetRight(int(m_2DCanvas->GetWidth()));
+ m_2DCanvas->GetDisplayArea().SetTop(int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2);
+ break;
+ }
+ }
+ else
+ {
+ // every available pixel
+ m_2DCanvas->GetDisplayArea().SetLeft(0);
+ m_2DCanvas->GetDisplayArea().SetBottom(0);
+ m_2DCanvas->GetDisplayArea().SetRight(int(m_2DCanvas->GetWidth()));
+ m_2DCanvas->GetDisplayArea().SetTop(int(m_2DCanvas->GetHeight()));
+ }
+}
+
+
+void RAS_OpenGLRasterizer::SetStereoMode(const int stereomode)
+{
+ m_stereomode = stereomode;
+}
+
+
+
+bool RAS_OpenGLRasterizer::Stereo()
+{
+ if(m_stereomode == RAS_STEREO_NOSTEREO)
+ return false;
+ else
+ return true;
+}
+
+
+void RAS_OpenGLRasterizer::SetEye(int eye)
+{
+ m_curreye = eye;
+ if(m_stereomode == RAS_STEREO_QUADBUFFERED) {
+ if(m_curreye == RAS_STEREO_LEFTEYE)
+ glDrawBuffer(GL_BACK_LEFT);
+ else
+ glDrawBuffer(GL_BACK_RIGHT);
+ }
+}
+
+
+void RAS_OpenGLRasterizer::SetEyeSeparation(float eyeseparation)
+{
+ m_eyeseparation = eyeseparation;
+}
+
+
+void RAS_OpenGLRasterizer::SetFocalLength(float focallength)
+{
+ m_focallength = focallength;
+}
+
+
+void RAS_OpenGLRasterizer::SwapBuffers()
+{
+ m_2DCanvas->SwapBuffers();
+}
+
+
+
+void RAS_OpenGLRasterizer::IndexPrimitives(const vecVertexArray & vertexarrays,
+ const vecIndexArrays & indexarrays,
+ int mode,
+ class RAS_IPolyMaterial* polymat,
+ class RAS_IRenderTools* rendertools,
+ bool useObjectColor,
+ const MT_Vector4& rgbacolor
+ )
+{
+ static const GLsizei vtxstride = sizeof(RAS_TexVert);
+ GLenum drawmode;
+ switch (mode)
+ {
+ case 0:
+ drawmode = GL_TRIANGLES;
+ break;
+ case 1:
+ drawmode = GL_LINES;
+ break;
+ case 2:
+ drawmode = GL_QUADS;
+ break;
+ default:
+ drawmode = GL_LINES;
+ break;
+ }
+
+ const RAS_TexVert* vertexarray ;
+ int numindices,vt;
+
+ for (vt=0;vt<vertexarrays.size();vt++)
+ {
+ vertexarray = &((*vertexarrays[vt]) [0]);
+ const KX_IndexArray & indexarray = (*indexarrays[vt]);
+ numindices = indexarray.size();
+
+ int numverts = vertexarrays[vt]->size();
+
+ if (!numindices)
+ break;
+
+ int vindex=0;
+ switch (mode)
+ {
+ case 1:
+ {
+ glBegin(GL_LINES);
+ vindex=0;
+ for (int i=0;i<numindices;i+=2)
+ {
+ glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
+ glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
+ }
+ glEnd();
+ }
+ break;
+ case 2:
+ {
+ glBegin(GL_QUADS);
+ vindex=0;
+ if (useObjectColor)
+ {
+ for (int i=0;i<numindices;i+=4)
+ {
+
+ glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
+
+ glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
+ glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
+ glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ vindex++;
+
+ glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
+ glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
+ glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ vindex++;
+
+ glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
+ glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
+ glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ vindex++;
+
+ glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
+ glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
+ glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ vindex++;
+ }
+ }
+ else
+ {
+ for (int i=0;i<numindices;i+=4)
+ {
+ char *cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
+ // This looks curiously endian unsafe to me.
+ // However it depends on the way the colors are packed into
+ // the m_rgba field of RAS_TexVert
+
+ glColor4ub(cp[0], cp[1], cp[2], cp[3]);
+ glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
+ glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
+ glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ vindex++;
+
+ cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
+ glColor4ub(cp[0], cp[1], cp[2], cp[3]);
+ glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
+ glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
+ glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ vindex++;
+
+ cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
+ glColor4ub(cp[0], cp[1], cp[2], cp[3]);
+ glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
+ glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
+ glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ vindex++;
+
+ cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
+ glColor4ub(cp[0], cp[1], cp[2], cp[3]);
+ glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
+ glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
+ glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ vindex++;
+ }
+ }
+ glEnd();
+ break;
+ }
+ case 0:
+ {
+ glBegin(GL_TRIANGLES);
+ vindex=0;
+ if (useObjectColor)
+ {
+ for (int i=0;i<numindices;i+=3)
+ {
+
+ glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
+
+ glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
+ glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
+ glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ vindex++;
+
+ glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
+ glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
+ glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ vindex++;
+
+ glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
+ glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
+ glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ vindex++;
+ }
+ }
+ else
+ {
+ for (int i=0;i<numindices;i+=3)
+ {
+
+ char *cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
+ glColor4ub(cp[0], cp[1], cp[2], cp[3]);
+ glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
+ glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
+ glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ vindex++;
+
+ cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
+ glColor4ub(cp[0], cp[1], cp[2], cp[3]);
+ glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
+ glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
+ glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ vindex++;
+
+ cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
+ glColor4ub(cp[0], cp[1], cp[2], cp[3]);
+ glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
+ glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
+ glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ vindex++;
+ }
+ }
+ glEnd();
+ break;
+ }
+ default:
+ {
+ }
+
+ } // switch
+ } // for each vertexarray
+
+}
+
+void RAS_OpenGLRasterizer::IndexPrimitives_Ex(const vecVertexArray & vertexarrays,
+ const vecIndexArrays & indexarrays,
+ int mode,
+ class RAS_IPolyMaterial* polymat,
+ class RAS_IRenderTools* rendertools,
+ bool useObjectColor,
+ const MT_Vector4& rgbacolor
+ )
+{
+ bool recalc;
+ static const GLsizei vtxstride = sizeof(RAS_TexVert);
+ GLenum drawmode;
+ switch (mode)
+ {
+ case 0:
+ drawmode = GL_TRIANGLES;
+ break;
+ case 1:
+ drawmode = GL_LINES;
+ break;
+ case 2:
+ drawmode = GL_QUADS;
+ break;
+ default:
+ drawmode = GL_LINES;
+ break;
+ }
+
+ const RAS_TexVert* vertexarray ;
+ int numindices,vt;
+
+ for (vt=0;vt<vertexarrays.size();vt++)
+ {
+ vertexarray = &((*vertexarrays[vt]) [0]);
+ const KX_IndexArray & indexarray = (*indexarrays[vt]);
+ numindices = indexarray.size();
+
+ int numverts = vertexarrays[vt]->size();
+
+ if (!numindices)
+ break;
+
+ int vindex=0;
+ switch (mode)
+ {
+ case 1:
+ {
+ glBegin(GL_LINES);
+ vindex=0;
+ for (int i=0;i<numindices;i+=2)
+ {
+ glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
+ glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
+ }
+ glEnd();
+ }
+ break;
+ case 2:
+ {
+ glBegin(GL_QUADS);
+ vindex=0;
+ if (useObjectColor)
+ {
+ for (int i=0;i<numindices;i+=4)
+ {
+ MT_Point3 mv1, mv2, mv3, mv4, fnor;
+ /* Calc a new face normal */
+
+ if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
+ recalc= true;
+ else
+ recalc=false;
+
+ if (recalc){
+ mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
+ mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
+ mv4 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
+
+ fnor = (((mv2-mv1).cross(mv3-mv2))+((mv4-mv3).cross(mv1-mv4))).safe_normalized();
+
+ glNormal3f(fnor[0], fnor[1], fnor[2]);
+ }
+
+ glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
+
+ if (!recalc)
+ glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
+ glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
+ glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ vindex++;
+
+ if (!recalc)
+ glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
+ glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
+ glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ vindex++;
+
+ if (!recalc)
+ glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
+ glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
+ glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ vindex++;
+
+ if (!recalc)
+ glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
+ glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
+ glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ vindex++;
+ }
+ }
+ else
+ {
+ for (int i=0;i<numindices;i+=4)
+ {
+ char *cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
+ // This looks curiously endian unsafe to me.
+ // However it depends on the way the colors are packed into
+ // the m_rgba field of RAS_TexVert
+ MT_Point3 mv1, mv2, mv3, mv4, fnor;
+ /* Calc a new face normal */
+
+ if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
+ recalc= true;
+ else
+ recalc=false;
+
+
+ if (recalc){
+ mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
+ mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
+ mv4 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
+
+ fnor = (((mv2-mv1).cross(mv3-mv2))+((mv4-mv3).cross(mv1-mv4))).safe_normalized();
+
+ glNormal3f(fnor[0], fnor[1], fnor[2]);
+ }
+
+ glColor4ub(cp[0], cp[1], cp[2], cp[3]);
+ if (!recalc)
+ glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
+ glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
+ glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ vindex++;
+
+ cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
+ glColor4ub(cp[0], cp[1], cp[2], cp[3]);
+ if (!recalc)
+ glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
+ glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
+ glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ vindex++;
+
+ cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
+ glColor4ub(cp[0], cp[1], cp[2], cp[3]);
+ if (!recalc)
+ glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
+ glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
+ glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ vindex++;
+
+ cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
+ glColor4ub(cp[0], cp[1], cp[2], cp[3]);
+ if (!recalc)
+ glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
+ glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
+ glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ vindex++;
+ }
+ }
+ glEnd();
+ break;
+ }
+ case 0:
+ {
+ glBegin(GL_TRIANGLES);
+ vindex=0;
+ if (useObjectColor)
+ {
+ for (int i=0;i<numindices;i+=3)
+ {
+ MT_Point3 mv1, mv2, mv3, fnor;
+ /* Calc a new face normal */
+
+ if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
+ recalc= true;
+ else
+ recalc=false;
+
+ if (recalc){
+ mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
+ mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
+
+ fnor = ((mv2-mv1).cross(mv3-mv2)).safe_normalized();
+ glNormal3f(fnor[0], fnor[1], fnor[2]);
+ }
+
+ glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
+
+ if (!recalc)
+ glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
+ glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
+ glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ vindex++;
+
+ if (!recalc)
+ glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
+ glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
+ glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ vindex++;
+
+ if (!recalc)
+ glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
+ glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
+ glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ vindex++;
+ }
+ }
+ else
+ {
+ for (int i=0;i<numindices;i+=3)
+ {
+ MT_Point3 mv1, mv2, mv3, fnor;
+ /* Calc a new face normal */
+
+ if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
+ recalc= true;
+ else
+ recalc=false;
+
+
+ if (recalc){
+ mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
+ mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
+
+ fnor = ((mv2-mv1).cross(mv3-mv2)).safe_normalized();
+ glNormal3f(fnor[0], fnor[1], fnor[2]);
+ }
+
+ char *cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
+ glColor4ub(cp[0], cp[1], cp[2], cp[3]);
+ if (!recalc)
+ glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
+ glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
+ glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ vindex++;
+
+ cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
+ glColor4ub(cp[0], cp[1], cp[2], cp[3]);
+ if (!recalc)
+ glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
+ glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
+ glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ vindex++;
+
+ cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
+ glColor4ub(cp[0], cp[1], cp[2], cp[3]);
+ if (!recalc)
+ glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
+ glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
+ glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
+ vindex++;
+ }
+ }
+ glEnd();
+ break;
+ }
+ default:
+ {
+ }
+
+ } // switch
+ } // for each vertexarray
+
+}
+
+
+
+void RAS_OpenGLRasterizer::IndexPrimitives_3DText(const vecVertexArray & vertexarrays,
+ const vecIndexArrays & indexarrays,
+ int mode,
+ class RAS_IPolyMaterial* polymat,
+ class RAS_IRenderTools* rendertools,
+ bool useObjectColor,
+ const MT_Vector4& rgbacolor
+ )
+{
+ unsigned char* mypointer=NULL;
+ static const GLsizei vtxstride = sizeof(RAS_TexVert);
+ GLenum drawmode;
+ switch (mode)
+ {
+ case 0:
+ drawmode = GL_TRIANGLES;
+ break;
+ case 1:
+ drawmode = GL_LINES;
+ break;
+ case 2:
+ drawmode = GL_QUADS;
+ break;
+ default:
+ drawmode = GL_LINES;
+ break;
+ }
+
+ const RAS_TexVert* vertexarray ;
+
+ int numindices ;
+ int vt;
+
+ if (useObjectColor)
+ {
+ glDisableClientState(GL_COLOR_ARRAY);
+ glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
+ }
+ else
+ {
+ glEnableClientState(GL_COLOR_ARRAY);
+ }
+
+ for (vt=0;vt<vertexarrays.size();vt++)
+ {
+ vertexarray = &((*vertexarrays[vt]) [0]);
+ const KX_IndexArray & indexarray = (*indexarrays[vt]);
+ numindices = indexarray.size();
+
+ int numverts = vertexarrays[vt]->size();
+
+ if (!numindices)
+ break;
+
+ int vindex=0;
+ switch (mode)
+ {
+ case 1:
+ {
+ glBegin(GL_LINES);
+ vindex=0;
+ for (int i=0;i<numindices;i+=2)
+ {
+ glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
+ glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
+ }
+ glEnd();
+ }
+ break;
+ case 2:
+ {
+ vindex=0;
+ for (int i=0;i<numindices;i+=4)
+ {
+ float v1[3],v2[3],v3[3],v4[3];
+
+ char *cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
+ v1[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
+ v1[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
+ v1[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
+ vindex++;
+
+ cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
+ v2[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
+ v2[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
+ v2[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
+ vindex++;
+
+ cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
+ v3[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
+ v3[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
+ v3[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
+ vindex++;
+
+ cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
+ v4[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
+ v4[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
+ v4[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
+
+ vindex++;
+
+ rendertools->RenderText(polymat->GetDrawingMode(),polymat,v1,v2,v3,v4);
+ ClearCachingInfo();
+ }
+ break;
+ }
+ case 0:
+ {
+ glBegin(GL_TRIANGLES);
+ vindex=0;
+ for (int i=0;i<numindices;i+=3)
+ {
+ float v1[3],v2[3],v3[3];
+
+ v1[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
+ v1[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
+ v1[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
+ vindex++;
+
+ v2[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
+ v2[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
+ v2[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
+ vindex++;
+
+ v3[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
+ v3[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
+ v3[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
+ vindex++;
+
+ rendertools->RenderText(polymat->GetDrawingMode(),polymat,v1,v2,v3,NULL);
+ ClearCachingInfo();
+ }
+ glEnd();
+ break;
+ }
+ default:
+ {
+ }
+ } //switch
+ } //for each vertexarray
+}
+
+
+
+void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat)
+{
+ glMatrixMode(GL_PROJECTION);
+ double* matrix = &mat(0,0);
+ glLoadMatrixd(matrix);
+}
+
+
+void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_Matrix4x4 & mat)
+{
+ glMatrixMode(GL_PROJECTION);
+ double matrix[16];
+ /* Get into argument. Looks a bit dodgy, but it's ok. */
+ mat.getValue(matrix);
+ /* Internally, MT_Matrix4x4 uses doubles (MT_Scalar). */
+ glLoadMatrixd(matrix);
+}
+
+MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix(
+ float left,
+ float right,
+ float bottom,
+ float top,
+ float frustnear,
+ float frustfar
+){
+ MT_Matrix4x4 result;
+ double mat[16];
+
+ // correction for stereo
+ if(m_stereomode != RAS_STEREO_NOSTEREO)
+ {
+ float near_div_focallength;
+ // next 2 params should be specified on command line and in Blender publisher
+ m_focallength = 1.5 * right; // derived from example
+ m_eyeseparation = 0.18 * right; // just a guess...
+
+ near_div_focallength = frustnear / m_focallength;
+ switch(m_curreye)
+ {
+ case RAS_STEREO_LEFTEYE:
+ left += 0.5 * m_eyeseparation * near_div_focallength;
+ right += 0.5 * m_eyeseparation * near_div_focallength;
+ break;
+ case RAS_STEREO_RIGHTEYE:
+ left -= 0.5 * m_eyeseparation * near_div_focallength;
+ right -= 0.5 * m_eyeseparation * near_div_focallength;
+ break;
+ }
+ // leave bottom, top, bottom and top untouched
+ }
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(left, right, bottom, top, frustnear, frustfar);
+ glGetDoublev(GL_PROJECTION_MATRIX, mat);
+ result.setValue(mat);
+
+ return result;
+}
+
+
+// next arguments probably contain redundant info, for later...
+void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat, const MT_Vector3& campos,
+ const MT_Point3 &camLoc, const MT_Quaternion &camOrientQuat)
+{
+ MT_Matrix4x4 viewMat = mat;
+
+ // correction for stereo
+ if(m_stereomode != RAS_STEREO_NOSTEREO)
+ {
+ MT_Matrix3x3 camOrientMat3x3(camOrientQuat);
+ MT_Vector3 unitViewDir(0.0, -1.0, 0.0); // minus y direction, Blender convention
+ MT_Vector3 unitViewupVec(0.0, 0.0, 1.0);
+ MT_Vector3 viewDir, viewupVec;
+ MT_Vector3 eyeline;
+
+ // actual viewDir
+ viewDir = camOrientMat3x3 * unitViewDir; // this is the moto convention, vector on right hand side
+ // actual viewup vec
+ viewupVec = camOrientMat3x3 * unitViewupVec;
+
+ // vector between eyes
+ eyeline = viewDir.cross(viewupVec);
+
+ switch(m_curreye)
+ {
+ case RAS_STEREO_LEFTEYE:
+ {
+ // translate to left by half the eye distance
+ MT_Transform transform;
+ transform.setIdentity();
+ transform.translate(-(eyeline * m_eyeseparation / 2.0));
+ viewMat *= transform;
+ }
+ break;
+ case RAS_STEREO_RIGHTEYE:
+ {
+ // translate to right by half the eye distance
+ MT_Transform transform;
+ transform.setIdentity();
+ transform.translate(eyeline * m_eyeseparation / 2.0);
+ viewMat *= transform;
+ }
+ break;
+ }
+ }
+
+ // convert row major matrix 'viewMat' to column major for OpenGL
+ MT_Scalar cammat[16];
+ viewMat.getValue(cammat);
+ MT_CmMatrix4x4 viewCmmat = cammat;
+
+ glMatrixMode(GL_MODELVIEW);
+ m_viewmatrix = viewCmmat;
+ glLoadMatrixd(&m_viewmatrix(0,0));
+ m_campos = campos;
+}
+
+
+const MT_Point3& RAS_OpenGLRasterizer::GetCameraPosition()
+{
+ return m_campos;
+}
+
+
+
+void RAS_OpenGLRasterizer::LoadViewMatrix()
+{
+ glLoadMatrixd(&m_viewmatrix(0,0));
+}
+
+
+
+void RAS_OpenGLRasterizer::EnableTextures(bool enable)
+{
+}
+
+
+
+void RAS_OpenGLRasterizer::SetCullFace(bool enable)
+{
+ if (enable)
+ glEnable(GL_CULL_FACE);
+ else
+ glDisable(GL_CULL_FACE);
+}
+
+
+
+void RAS_OpenGLRasterizer::SetSpecularity(float specX,
+ float specY,
+ float specZ,
+ float specval)
+{
+ GLfloat mat_specular[] = {specX, specY, specZ, specval};
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
+}
+
+
+
+void RAS_OpenGLRasterizer::SetShinyness(float shiny)
+{
+ GLfloat mat_shininess[] = { shiny };
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
+}
+
+
+
+void RAS_OpenGLRasterizer::SetDiffuse(float difX,float difY,float difZ,float diffuse)
+{
+ GLfloat mat_diffuse [] = {difX, difY,difZ, diffuse};
+ glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
+}
+
+double RAS_OpenGLRasterizer::GetTime()
+{
+ return m_time;
+}
+
+
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
new file mode 100644
index 00000000000..9bbb19e8aa5
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
@@ -0,0 +1,226 @@
+/**
+ * $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 __RAS_OPENGLRASTERIZER
+#define __RAS_OPENGLRASTERIZER
+
+#ifdef WIN32
+#pragma warning (disable:4786)
+#endif
+
+#include "MT_CmMatrix4x4.h"
+#include <vector>
+using namespace std;
+
+
+#include "RAS_IRasterizer.h"
+#include "RAS_MaterialBucket.h"
+#include "RAS_ICanvas.h"
+
+/**
+ * 3D rendering device context.
+ */
+class RAS_OpenGLRasterizer : public RAS_IRasterizer
+{
+
+ RAS_ICanvas* m_2DCanvas;
+
+ // fogging vars
+ bool m_fogenabled;
+ float m_fogstart;
+ float m_fogdist;
+ float m_fogr;
+ float m_fogg;
+ float m_fogb;
+
+ float m_redback;
+ float m_greenback;
+ float m_blueback;
+ float m_alphaback;
+
+ bool m_bEXT_compiled_vertex_array;
+
+ double m_time;
+ MT_CmMatrix4x4 m_viewmatrix;
+ MT_Point3 m_campos;
+
+ int m_stereomode;
+ int m_curreye;
+ float m_eyeseparation;
+ float m_focallength;
+ int m_noOfScanlines;
+
+protected:
+ int m_drawingmode;
+ /** Stores the caching information for the last material activated. */
+ RAS_IPolyMaterial::TCachingInfo m_materialCachingInfo;
+
+public:
+ double GetTime();
+ RAS_OpenGLRasterizer(RAS_ICanvas* canv);
+ virtual ~RAS_OpenGLRasterizer();
+
+
+
+ enum
+ {
+ KX_BOUNDINGBOX = 1,
+ KX_WIREFRAME,
+ KX_SOLID,
+ KX_SHADED,
+ KX_TEXTURED
+ };
+
+ enum
+ {
+ KX_DEPTHMASK_ENABLED =1,
+ KX_DEPTHMASK_DISABLED,
+ };
+ virtual void SetDepthMask(int depthmask);
+
+ virtual void SetMaterial(const RAS_IPolyMaterial& mat);
+ virtual bool Init();
+ virtual void Exit();
+ virtual bool BeginFrame(int drawingmode, double time);
+ virtual void ClearDepthBuffer();
+ virtual void ClearCachingInfo(void);
+ virtual void EndFrame();
+ virtual void SetRenderArea();
+
+ virtual void SetStereoMode(const int stereomode);
+ virtual bool Stereo();
+ virtual void SetEye(const int eye);
+ virtual void SetEyeSeparation(const float eyeseparation);
+ virtual void SetFocalLength(const float focallength);
+
+ virtual void SwapBuffers();
+ virtual void IndexPrimitives(
+ const vecVertexArray& vertexarrays,
+ const vecIndexArrays & indexarrays,
+ int mode,
+ class RAS_IPolyMaterial* polymat,
+ class RAS_IRenderTools* rendertools,
+ bool useObjectColor,
+ const MT_Vector4& rgbacolor
+ );
+
+ virtual void IndexPrimitives_Ex(
+ const vecVertexArray& vertexarrays,
+ const vecIndexArrays & indexarrays,
+ int mode,
+ class RAS_IPolyMaterial* polymat,
+ class RAS_IRenderTools* rendertools,
+ bool useObjectColor,
+ const MT_Vector4& rgbacolor
+ );
+
+ virtual void IndexPrimitives_3DText(
+ const vecVertexArray& vertexarrays,
+ const vecIndexArrays & indexarrays,
+ int mode,
+ class RAS_IPolyMaterial* polymat,
+ class RAS_IRenderTools* rendertools,
+ bool useObjectColor,
+ const MT_Vector4& rgbacolor
+ );
+
+ virtual void SetProjectionMatrix(MT_CmMatrix4x4 & mat);
+ virtual void SetProjectionMatrix(MT_Matrix4x4 & mat);
+ virtual void SetViewMatrix(
+ const MT_Matrix4x4 & mat,
+ const MT_Vector3& campos,
+ const MT_Point3 &camLoc,
+ const MT_Quaternion &camOrientQuat
+ );
+
+ virtual const MT_Point3& GetCameraPosition();
+ virtual void LoadViewMatrix();
+
+ virtual void SetFog(
+ float start,
+ float dist,
+ float r,
+ float g,
+ float b
+ );
+
+ virtual void SetFogColor(
+ float r,
+ float g,
+ float b
+ );
+
+ virtual void SetFogStart(float fogstart);
+ virtual void SetFogEnd(float fogend);
+
+ void DisableFog();
+ virtual void DisplayFog();
+
+ virtual void SetBackColor(
+ float red,
+ float green,
+ float blue,
+ float alpha
+ );
+
+ virtual void SetDrawingMode(int drawingmode);
+ virtual int GetDrawingMode();
+
+ virtual void EnableTextures(bool enable);
+ virtual void SetCullFace(bool enable);
+
+ virtual MT_Matrix4x4 GetFrustumMatrix(
+ float left,
+ float right,
+ float bottom,
+ float top,
+ float frustnear,
+ float frustfar
+ );
+
+ virtual void SetSpecularity(
+ float specX,
+ float specY,
+ float specZ,
+ float specval
+ );
+
+ virtual void SetShinyness(float shiny);
+ virtual void SetDiffuse(
+ float difX,
+ float difY,
+ float difZ,
+ float diffuse
+ );
+
+};
+
+#endif //__RAS_OPENGLRASTERIZER
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp
new file mode 100644
index 00000000000..fe582a3d2ee
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp
@@ -0,0 +1,215 @@
+#ifdef WIN32
+
+
+#include "RAS_VAOpenGLRasterizer.h"
+
+
+#include <windows.h>
+#include "GL/gl.h"
+
+typedef void (APIENTRY *GLLOCKARRAYSEXTPTR)(GLint first,GLsizei count);
+typedef void (APIENTRY *GLUNLOCKARRAYSEXTPTR)(void);
+void APIENTRY RAS_lockfunc(GLint first,GLsizei count) {};
+void APIENTRY RAS_unlockfunc() {};
+GLLOCKARRAYSEXTPTR glLockArraysEXT=RAS_lockfunc;
+GLUNLOCKARRAYSEXTPTR glUnlockArraysEXT=RAS_unlockfunc;
+
+
+
+
+#include "STR_String.h"
+#include "RAS_TexVert.h"
+#include "MT_CmMatrix4x4.h"
+#include "RAS_IRenderTools.h" // rendering text
+
+
+RAS_VAOpenGLRasterizer::RAS_VAOpenGLRasterizer(RAS_ICanvas* canvas)
+:RAS_OpenGLRasterizer(canvas)
+{
+ int i = 0;
+}
+
+
+
+RAS_VAOpenGLRasterizer::~RAS_VAOpenGLRasterizer()
+{
+}
+
+
+
+bool RAS_VAOpenGLRasterizer::Init()
+{
+
+ bool result = RAS_OpenGLRasterizer::Init();
+
+ if (result)
+ {
+ // if possible, add extensions to other platforms too, if this
+ // rasterizer becomes messy just derive one for each platform
+ // (ie. KX_Win32Rasterizer, KX_LinuxRasterizer etc.)
+
+ glUnlockArraysEXT = reinterpret_cast<GLUNLOCKARRAYSEXTPTR>(wglGetProcAddress("glUnlockArraysEXT"));
+ if (!glUnlockArraysEXT)
+ result = false;
+
+ glLockArraysEXT = reinterpret_cast<GLLOCKARRAYSEXTPTR>(wglGetProcAddress("glLockArraysEXT"));
+ if (!glLockArraysEXT)
+ result=false;
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glDisableClientState(GL_NORMAL_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ }
+
+ return result;
+}
+
+
+
+void RAS_VAOpenGLRasterizer::SetDrawingMode(int drawingmode)
+{
+ m_drawingmode = drawingmode;
+
+ switch (m_drawingmode)
+ {
+ case KX_BOUNDINGBOX:
+ {
+ }
+ case KX_WIREFRAME:
+ {
+ glDisable (GL_CULL_FACE);
+ break;
+ }
+ case KX_TEXTURED:
+ {
+ }
+ case KX_SHADED:
+ {
+ glEnableClientState(GL_COLOR_ARRAY);
+ }
+ case KX_SOLID:
+ {
+ break;
+ }
+ default:
+ {
+ }
+ }
+}
+
+
+
+void RAS_VAOpenGLRasterizer::Exit()
+{
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+ glDisableClientState(GL_NORMAL_ARRAY);
+ glDisable(GL_COLOR_MATERIAL);
+
+ RAS_OpenGLRasterizer::Exit();
+}
+
+
+
+void RAS_VAOpenGLRasterizer::IndexPrimitives( const vecVertexArray& vertexarrays,
+ const vecIndexArrays & indexarrays,
+ int mode,
+ class RAS_IPolyMaterial* polymat,
+ class RAS_IRenderTools* rendertools,
+ bool useObjectColor,
+ const MT_Vector4& rgbacolor)
+{
+ unsigned char* mypointer=NULL;
+ static const GLsizei vtxstride = sizeof(RAS_TexVert);
+ GLenum drawmode;
+ switch (mode)
+ {
+ case 0:
+ {
+ drawmode = GL_TRIANGLES;
+ break;
+ }
+ case 2:
+ {
+ drawmode = GL_QUADS;
+ break;
+ }
+ case 1: //lines
+ {
+ }
+ default:
+ {
+ drawmode = GL_LINES;
+ break;
+ }
+ }
+ const RAS_TexVert* vertexarray;
+ int numindices,vt;
+ if (drawmode != GL_LINES)
+ {
+ if (useObjectColor)
+ {
+ glDisableClientState(GL_COLOR_ARRAY);
+ glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
+ } else
+ {
+ glColor4d(0,0,0,1.0);
+ glEnableClientState(GL_COLOR_ARRAY);
+ }
+ }
+ else
+ {
+ glColor3d(0,0,0);
+ }
+ // use glDrawElements to draw each vertexarray
+ for (vt=0;vt<vertexarrays.size();vt++)
+ {
+ vertexarray = &((*vertexarrays[vt]) [0]);
+ const KX_IndexArray & indexarray = (*indexarrays[vt]);
+ numindices = indexarray.size();
+ int numverts = vertexarrays[vt]->size();
+
+ if (!numindices)
+ break;
+
+ mypointer = (unsigned char*)(vertexarray);
+ glVertexPointer(3,GL_FLOAT,vtxstride,mypointer);
+ mypointer+= 3*sizeof(float);
+ glTexCoordPointer(2,GL_FLOAT,vtxstride,mypointer);
+ mypointer+= 2*sizeof(float);
+ glColorPointer(4,GL_UNSIGNED_BYTE,vtxstride,mypointer);
+ mypointer += sizeof(int);
+ glNormalPointer(GL_SHORT,vtxstride,mypointer);
+ glLockArraysEXT(0,numverts);
+ // here the actual drawing takes places
+ glDrawElements(drawmode,numindices,GL_UNSIGNED_INT,&(indexarray[0]));
+ glUnlockArraysEXT();
+ }
+}
+
+
+void RAS_VAOpenGLRasterizer::EnableTextures(bool enable)
+{
+ if (enable)
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ else
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+}
+
+bool RAS_VAOpenGLRasterizer::Stereo()
+{
+/*
+ if(m_stereomode == RAS_STEREO_NOSTEREO)
+ return false;
+ else
+ return true;
+*/
+ return false;
+}
+
+
+#endif //WIN32
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h
new file mode 100644
index 00000000000..f2500e02dde
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.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_VERTEXARRAYOPENGLRASTERIZER
+#define __KX_VERTEXARRAYOPENGLRASTERIZER
+
+#include "RAS_OpenGLRasterizer.h"
+
+class RAS_VAOpenGLRasterizer : public RAS_OpenGLRasterizer
+{
+public:
+ RAS_VAOpenGLRasterizer(RAS_ICanvas* canvas);
+ virtual ~RAS_VAOpenGLRasterizer();
+
+ virtual bool Init();
+ virtual void Exit();
+
+ virtual bool Stereo();
+ virtual void SetDrawingMode(int drawingmode);
+
+ virtual void IndexPrimitives( const vecVertexArray& vertexarrays,
+ const vecIndexArrays & indexarrays,
+ int mode,
+ class RAS_IPolyMaterial* polymat,
+ class RAS_IRenderTools* rendertools,
+ bool useObjectColor,
+ const MT_Vector4& rgbacolor);
+
+
+ virtual void EnableTextures(bool enable);
+
+};
+
+#endif //__KX_VERTEXARRAYOPENGLRASTERIZER
diff --git a/source/gameengine/Rasterizer/RAS_Polygon.cpp b/source/gameengine/Rasterizer/RAS_Polygon.cpp
new file mode 100644
index 00000000000..c495ef9679d
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_Polygon.cpp
@@ -0,0 +1,142 @@
+/**
+ * $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
+
+#pragma warning (disable:4786)
+#endif
+
+#include "RAS_Polygon.h"
+
+/*
+RAS_TexVert* RAS_Polygon::GetVertex(int index)
+{
+ if (m_bucket)
+ return m_bucket->GetVertex(m_vertexindexbase.m_vtxarray, m_vertexindexbase.m_indexarray[index]);
+ else
+ return NULL;
+}
+*/
+
+/*void RAS_Polygon::Bucketize(double* oglmatrix)
+{
+ //Transform(trans);
+ if (m_bucket)
+ m_bucket->AddPolygon(this,oglmatrix);
+}
+*/
+
+RAS_Polygon::RAS_Polygon(RAS_MaterialBucket* bucket,
+ bool visible,
+ int numverts,
+ int vtxarrayindex)
+ :m_bucket(bucket),
+ m_vertexindexbase(numverts),
+ m_numverts(numverts),
+ m_edgecode(0)
+{
+ int size = sizeof(RAS_Polygon);
+ m_vertexindexbase.m_vtxarray = vtxarrayindex ;//m_bucket->FindVertexArray(numverts);
+ m_polyFlags.Visible = visible;
+}
+
+
+
+int RAS_Polygon::VertexCount()
+{
+ return m_numverts;
+}
+
+
+
+void RAS_Polygon::SetVertex(int i,
+ int vertexindex ) //const MT_Point3& xyz,const MT_Point2& uv,const unsigned int rgbacolor,const MT_Vector3& normal)
+{
+ m_vertexindexbase.SetIndex(i,vertexindex); //m_bucket->FindOrAddVertex(m_vertexindexbase.m_vtxarray,
+ //xyz,uv,rgbacolor,normal));
+}
+
+
+
+const KX_VertexIndex& RAS_Polygon::GetIndexBase()
+{
+ return m_vertexindexbase;
+}
+
+
+
+void RAS_Polygon::SetVisibleWireframeEdges(int edgecode)
+{
+ m_edgecode = edgecode;
+}
+
+
+
+// each bit is for a visible edge, starting with bit 1 for the first edge, bit 2 for second etc.
+int RAS_Polygon::GetEdgeCode()
+{
+ return m_edgecode;
+}
+
+
+
+bool RAS_Polygon::IsVisible()
+{
+ return m_polyFlags.Visible;
+}
+
+
+
+bool RAS_Polygon::IsCollider()
+{
+ return m_polyFlags.Collider;
+}
+
+
+
+void RAS_Polygon::SetCollider(bool col)
+{
+ m_polyFlags.Collider = col;
+}
+
+
+
+KX_VertexIndex& RAS_Polygon::GetVertexIndexBase()
+{
+ return m_vertexindexbase;
+}
+
+
+
+RAS_MaterialBucket* RAS_Polygon::GetMaterial()
+{
+ return m_bucket;
+}
diff --git a/source/gameengine/Rasterizer/RAS_Polygon.h b/source/gameengine/Rasterizer/RAS_Polygon.h
new file mode 100644
index 00000000000..d5b6123e153
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_Polygon.h
@@ -0,0 +1,92 @@
+/**
+ * $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 __RAS_POLYGON
+#define __RAS_POLYGON
+
+#include "RAS_TexVert.h"
+//#include "KX_BoundingVolumes.h"
+#include "RAS_MaterialBucket.h"
+
+#include <vector>
+using namespace std;
+
+
+//
+// Bitfield that stores the flags for each CValue derived class
+//
+struct PolygonFlags {
+ PolygonFlags() :
+ Visible(true),
+ Collider(true)
+ {
+ }
+ unsigned char Visible : 1;
+ unsigned char Collider : 1;
+ //int Visible : 1;
+ //int Collider : 1;
+};
+
+class RAS_Polygon
+{
+ RAS_MaterialBucket* m_bucket;
+ KX_VertexIndex m_vertexindexbase;
+ int m_numverts;
+ int m_edgecode;
+ PolygonFlags m_polyFlags;
+
+
+public:
+ RAS_Polygon(RAS_MaterialBucket* bucket,
+ bool visible,
+ int numverts,
+ int vtxarrayindex) ;
+ virtual ~RAS_Polygon() {};
+
+// RAS_TexVert* GetVertex(int index);
+ int VertexCount();
+ void SetVertex(int i,int vertexindex); //const MT_Point3& xyz,const MT_Point2& uv,const unsigned int rgbacolor,const MT_Vector3& normal)
+
+ const KX_VertexIndex& GetIndexBase();
+
+ void SetVisibleWireframeEdges(int edgecode);
+ // each bit is for a visible edge, starting with bit 1 for the first edge, bit 2 for second etc.
+ int GetEdgeCode();
+
+ bool IsVisible();
+ bool IsCollider();
+ void SetCollider(bool col);
+
+ KX_VertexIndex& GetVertexIndexBase();
+ RAS_MaterialBucket* GetMaterial();
+
+};
+#endif
diff --git a/source/gameengine/Rasterizer/RAS_Rect.h b/source/gameengine/Rasterizer/RAS_Rect.h
new file mode 100644
index 00000000000..448a5ec73c1
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_Rect.h
@@ -0,0 +1,99 @@
+/**
+ * $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 _RAS_RECT
+#define _RAS_RECT
+
+
+/**
+ * @section interface class.
+ * RAS_Rect just encodes a simple rectangle.
+ * Should be part of a generic library
+ */
+
+class RAS_Rect
+{
+public: // todo: make a decent class, and make private
+ int m_x1, m_y1;
+ int m_x2, m_y2;
+
+public:
+ RAS_Rect() : m_x1(0), m_y1(0), m_x2(0), m_y2(0) {}
+ int GetWidth(
+ ) const {
+ return m_x2 - m_x1;
+ }
+ int GetHeight(
+ ) const {
+ return m_y2 - m_y1;
+ }
+ int GetLeft(
+ ) const {
+ return m_x1;
+ }
+ int GetRight(
+ ) const {
+ return m_x2;
+ }
+ int GetBottom(
+ ) const {
+ return m_y1;
+ }
+ int GetTop(
+ ) const {
+ return m_y2;
+ }
+
+ void SetLeft(
+ int x1)
+ {
+ m_x1 = x1;
+ }
+ void SetBottom(
+ int y1)
+ {
+ m_y1 = y1;
+ }
+ void SetRight(
+ int x2)
+ {
+ m_x2 = x2;
+ }
+ void SetTop(
+ int y2)
+ {
+ m_y2 = y2;
+ }
+};
+
+
+#endif // _RAS_RECT
diff --git a/source/gameengine/Rasterizer/RAS_TexMatrix.h b/source/gameengine/Rasterizer/RAS_TexMatrix.h
new file mode 100644
index 00000000000..c4d02c49154
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_TexMatrix.h
@@ -0,0 +1,45 @@
+/**
+ * $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 __RASTEXMATRIX
+#define __RASTEXMATRIX
+
+#include "MT_Matrix3x3.h"
+#include "MT_Point3.h"
+#include "MT_Point2.h"
+
+
+
+#include "RAS_TexVert.h"
+
+void RAS_CalcTexMatrix(RAS_TexVert p[3],MT_Point3& origin,MT_Vector3& udir,MT_Vector3& vdir);
+
+#endif //__RASTEXMATRIX
diff --git a/source/gameengine/Rasterizer/RAS_TexVert.cpp b/source/gameengine/Rasterizer/RAS_TexVert.cpp
new file mode 100644
index 00000000000..20a4f0d2570
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_TexVert.cpp
@@ -0,0 +1,152 @@
+/**
+ * $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 "RAS_TexVert.h"
+
+
+RAS_TexVert::RAS_TexVert(const MT_Point3& xyz,
+ const MT_Point2& uv,
+ const unsigned int rgba,
+ const short *normal,
+ const short flag)
+{
+ xyz.getValue(m_localxyz);
+ uv.getValue(m_uv1);
+ SetRGBA(rgba);
+ m_normal[0] = normal[0];
+ m_normal[1] = normal[1];
+ m_normal[2] = normal[2];
+ m_flag = flag;
+}
+
+
+
+const float* RAS_TexVert::getUV1 () const
+{
+ return m_uv1;
+}
+
+
+
+const MT_Point3& RAS_TexVert::xyz()
+{
+ g_pt3.setValue(m_localxyz);
+ return g_pt3;
+}
+
+void RAS_TexVert::SetXYZ(const MT_Point3& xyz)
+{
+ xyz.getValue(m_localxyz);
+}
+
+
+
+void RAS_TexVert::SetUV(const MT_Point2& uv)
+{
+ uv.getValue(m_uv1);
+}
+
+
+
+void RAS_TexVert::SetRGBA(const unsigned int rgba)
+{
+ m_rgba = rgba;
+}
+
+
+void RAS_TexVert::SetFlag(const short flag)
+{
+ m_flag = flag;
+}
+void RAS_TexVert::SetNormal(const MT_Vector3& normal)
+{
+ m_normal[0] = short(normal.x()*32767.0);
+ m_normal[1] = short(normal.y()*32767.0);
+ m_normal[2] = short(normal.z()*32767.0);
+}
+
+
+
+// leave multiline for debugging
+const short* RAS_TexVert::getNormal() const
+{
+ return m_normal;
+}
+
+
+
+const float* RAS_TexVert::getLocalXYZ() const
+{
+ return m_localxyz;
+}
+
+
+
+const unsigned int& RAS_TexVert::getRGBA() const
+{
+ return m_rgba;
+}
+
+
+
+// compare two vertices, and return TRUE if both are almost identical (they can be shared)
+bool RAS_TexVert::closeTo(const RAS_TexVert* other)
+{
+ return ((MT_Vector3(m_localxyz) - MT_Vector3(other->m_localxyz)).fuzzyZero() &&
+ (MT_Vector2(m_uv1) - MT_Vector2(other->m_uv1)).fuzzyZero() &&
+ m_normal[0] == other->m_normal[0] &&
+ m_normal[1] == other->m_normal[1] &&
+ m_normal[2] == other->m_normal[2] &&
+ m_flag == other->m_flag &&
+ m_rgba == other->m_rgba) ;
+
+}
+
+
+
+bool RAS_TexVert::closeTo(const MT_Point3& otherxyz,
+ const MT_Point2& otheruv,
+ const unsigned int otherrgba,
+ short othernormal[3]) const
+{
+ return ((MT_Vector3(m_localxyz) - otherxyz).fuzzyZero() &&
+ (MT_Vector2(m_uv1) - otheruv).fuzzyZero() &&
+ m_normal[0] == othernormal[0] &&
+ m_normal[1] == othernormal[1] &&
+ m_normal[2] == othernormal[2] &&
+ m_rgba == otherrgba) ;
+}
+
+
+short RAS_TexVert::getFlag() const
+{
+ return m_flag;
+}
diff --git a/source/gameengine/Rasterizer/RAS_TexVert.h b/source/gameengine/Rasterizer/RAS_TexVert.h
new file mode 100644
index 00000000000..ebbd35fb91c
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_TexVert.h
@@ -0,0 +1,98 @@
+/**
+ * $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 __RAS_TEXVERT
+#define __RAS_TEXVERT
+
+
+#include "MT_Point3.h"
+#include "MT_Point2.h"
+#include "MT_Transform.h"
+
+
+static MT_Point3 g_pt3;
+static MT_Point2 g_pt2;
+
+#define TV_CALCFACENORMAL 0x0001
+
+class RAS_TexVert
+{
+
+ float m_localxyz[3]; // 3*4=12 = 24
+ float m_uv1[2]; // 2*4=8 = 24 + 16 = 40
+ unsigned int m_rgba; //4 = 40 + 4 = 44
+ short m_normal[3]; //3*2=6 = 50
+ short m_flag; //32 bytes total size, fits nice = 52 = not fit nice
+
+
+public:
+ short getFlag() const;
+ RAS_TexVert()// :m_xyz(0,0,0),m_uv(0,0),m_rgba(0)
+ {}
+ RAS_TexVert(const MT_Point3& xyz,
+ const MT_Point2& uv,
+ const unsigned int rgba,
+ const short *normal,
+ const short flag);
+ ~RAS_TexVert() {};
+
+ // leave multiline for debugging
+ const float* getUV1 () const;
+
+ //const float* getUV1 () const {
+ // return m_uv1;
+ //};
+
+ const MT_Point3& xyz();
+
+ void SetXYZ(const MT_Point3& xyz);
+ void SetUV(const MT_Point2& uv);
+ void SetRGBA(const unsigned int rgba);
+ void SetNormal(const MT_Vector3& normal);
+ void SetFlag(const short flag);
+ // leave multiline for debugging
+ const short* getNormal() const;
+ //const float* getLocalXYZ() const {
+ // return m_localxyz;
+ //};
+
+ const float* getLocalXYZ() const;
+ const unsigned int& getRGBA() const;
+ // compare two vertices, and return TRUE if both are almost identical (they can be shared)
+ bool closeTo(const RAS_TexVert* other);
+
+ bool closeTo(const MT_Point3& otherxyz,
+ const MT_Point2& otheruv,
+ const unsigned int otherrgba,
+ short othernormal[3]) const;
+};
+
+#endif //__RAS_TEXVERT
diff --git a/source/gameengine/Rasterizer/RAS_texmatrix.cpp b/source/gameengine/Rasterizer/RAS_texmatrix.cpp
new file mode 100644
index 00000000000..515f05b8303
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_texmatrix.cpp
@@ -0,0 +1,133 @@
+/**
+ * $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 "RAS_TexMatrix.h"
+
+
+void RAS_CalcTexMatrix(RAS_TexVert p[3],MT_Point3& origin,MT_Vector3& udir,MT_Vector3& vdir)
+{
+// precondition: 3 vertices are non-colinear
+
+ MT_Vector3 vec1 = p[1].xyz()-p[0].xyz();
+ MT_Vector3 vec2 = p[2].xyz()-p[0].xyz();
+ MT_Vector3 normal = vec1.cross(vec2);
+ normal.normalize();
+
+ // determine which coordinate we drop, ie. max coordinate in the normal
+
+
+ int ZCOORD = normal.closestAxis();
+ int XCOORD = (ZCOORD+1)%3;
+ int YCOORD = (ZCOORD+2)%3;
+
+ // ax+by+cz+d=0
+ MT_Scalar d = -p[0].xyz().dot(normal);
+
+
+ MT_Matrix3x3 mat3( p[0].getUV1()[0],p[0].getUV1()[1], 1,
+ p[1].getUV1()[0],p[1].getUV1()[1], 1,
+ p[2].getUV1()[0],p[2].getUV1()[1], 1);
+
+
+ MT_Matrix3x3 mat3inv = mat3.inverse();
+
+ MT_Vector3 p123x(p[0].xyz()[XCOORD],p[1].xyz()[XCOORD],p[2].xyz()[XCOORD]);
+ MT_Vector3 resultx = mat3inv*p123x;
+ MT_Vector3 p123y(p[0].xyz()[YCOORD],p[1].xyz()[YCOORD],p[2].xyz()[YCOORD]);
+ MT_Vector3 resulty = mat3inv*p123y;
+
+ // normal[ZCOORD] is not zero, because it's chosen to be maximal (absolute), and normal has length 1,
+ // so at least on of the coords is <> 0
+
+ //droppedvalue udir.dot(normal) =0
+ MT_Scalar droppedu = -(resultx.x()*normal[XCOORD]+resulty.x()*normal[YCOORD])/normal[ZCOORD];
+ udir[XCOORD] = resultx.x();
+ udir[YCOORD] = resulty.x();
+ udir[ZCOORD] = droppedu;
+ MT_Scalar droppedv = -(resultx.y()*normal[XCOORD]+resulty.y()*normal[YCOORD])/normal[ZCOORD];
+ vdir[XCOORD] = resultx.y();
+ vdir[YCOORD] = resulty.y();
+ vdir[ZCOORD] = droppedv;
+ // droppedvalue b = -(ax+cz+d)/y;
+ MT_Scalar droppedvalue = -((resultx.z()*normal[XCOORD] + resulty.z()*normal[YCOORD]+d))/normal[ZCOORD];
+ origin[XCOORD] = resultx.z();
+ origin[YCOORD] = resulty.z();
+ origin[ZCOORD] = droppedvalue;
+
+
+}
+
+#ifdef _TEXOWNMAIN
+
+int main()
+{
+
+ MT_Point2 puv0={0,0};
+ MT_Point3 pxyz0 (0,0,128);
+
+ MT_Scalar puv1[2]={1,0};
+ MT_Point3 pxyz1(128,0,128);
+
+ MT_Scalar puv2[2]={1,1};
+ MT_Point3 pxyz2(128,0,0);
+
+ RAS_TexVert p0(pxyz0,puv0);
+ RAS_TexVert p1(pxyz1,puv1);
+ RAS_TexVert p2(pxyz2,puv2);
+
+ RAS_TexVert vertices[3] =
+ {
+ p0,
+ p1,
+ p2
+ };
+
+ MT_Vector3 udir,vdir;
+ MT_Point3 origin;
+ CalcTexMatrix(vertices,origin,udir,vdir);
+
+ MT_Point3 testpoint(128,32,64);
+
+ MT_Scalar lenu = udir.length2();
+ MT_Scalar lenv = vdir.length2();
+
+ MT_Scalar testu=((pxyz2-origin).dot(udir))/lenu;
+ MT_Scalar testv=((pxyz2-origin).dot(vdir))/lenv;
+
+
+
+
+ return 0;
+}
+
+#endif // _TEXOWNMAIN
diff --git a/source/gameengine/SceneGraph/Makefile b/source/gameengine/SceneGraph/Makefile
new file mode 100644
index 00000000000..bc184c8faba
--- /dev/null
+++ b/source/gameengine/SceneGraph/Makefile
@@ -0,0 +1,41 @@
+#
+# $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 = scenegraph
+DIR = $(OCGDIR)/gameengine/$(LIBNAME)
+
+include nan_compile.mk
+
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+CPPFLAGS += -I$(NAN_MOTO)/include
diff --git a/source/gameengine/SceneGraph/SG_Controller.cpp b/source/gameengine/SceneGraph/SG_Controller.cpp
new file mode 100644
index 00000000000..4a5735bb4c0
--- /dev/null
+++ b/source/gameengine/SceneGraph/SG_Controller.cpp
@@ -0,0 +1,49 @@
+/**
+ * $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 "SG_Controller.h"
+
+
+ void
+SG_Controller::
+SetObject(SG_IObject* obj)
+{
+ m_pObject = obj; // no checks yet ?
+}
+
+ void
+SG_Controller::
+ClearObject(
+){
+ m_pObject = NULL;
+}
+
+
diff --git a/source/gameengine/SceneGraph/SG_Controller.h b/source/gameengine/SceneGraph/SG_Controller.h
new file mode 100644
index 00000000000..9753af45a99
--- /dev/null
+++ b/source/gameengine/SceneGraph/SG_Controller.h
@@ -0,0 +1,116 @@
+/**
+ * Implementationclass to derive controllers from
+ *
+ * $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 __SG_CONTROLLER_H
+#define __SG_CONTROLLER_H
+
+
+#include "SG_IObject.h"
+class SG_Controller
+{
+public:
+ SG_Controller(
+ ) :
+ m_pObject(NULL) {
+ }
+
+ virtual
+ ~SG_Controller(
+ ) {};
+
+ virtual
+ bool
+ Update(
+ double time
+ )=0;
+
+ virtual
+ void
+ SetObject (
+ SG_IObject* object
+ );
+
+ void
+ ClearObject(
+ );
+
+ virtual
+ void
+ SetSimulatedTime(
+ double time
+ )=0;
+
+ virtual
+ SG_Controller*
+ GetReplica(
+ class SG_Node* destnode
+ )=0;
+
+ /**
+ * Hacky way of passing options to specific controllers
+ * @param option An integer identifying the option.
+ * @param value The value of this option.
+ * @attention This has been placed here to give sca-elements
+ * @attention some control over the controllers. This is
+ * @attention necessary because the identity of the controller
+ * @attention is lost on the way here.
+ */
+ virtual
+ void
+ SetOption(
+ int option,
+ int value
+ )=0;
+
+ /**
+ * Option-identifiers: SG_CONTR_<controller-type>_<option>.
+ * Options only apply to a specific controller type. The
+ * semantics are defined by whoever uses the setting.
+ */
+ enum SG_Controller_option {
+ SG_CONTR_NODEF = 0,
+ SG_CONTR_IPO_IPO_AS_FORCE,
+ SG_CONTR_IPO_FORCES_ACT_LOCAL,
+ SG_CONTR_CAMIPO_LENS,
+ SG_CONTR_CAMIPO_CLIPEND,
+ SG_CONTR_CAMIPO_CLIPSTART,
+ SG_CONTR_MAX
+ };
+
+protected:
+ SG_IObject* m_pObject;
+
+};
+
+#endif //__SG_CONTROLLER_H
diff --git a/source/gameengine/SceneGraph/SG_IObject.cpp b/source/gameengine/SceneGraph/SG_IObject.cpp
new file mode 100644
index 00000000000..2561bd0c672
--- /dev/null
+++ b/source/gameengine/SceneGraph/SG_IObject.cpp
@@ -0,0 +1,153 @@
+/**
+ * $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 "SG_IObject.h"
+
+#include "SG_Controller.h"
+
+SG_IObject::
+SG_IObject(
+ void* clientobj,
+ void* clientinfo,
+ SG_Callbacks callbacks
+):
+ m_SGclientObject(clientobj),
+ m_SGclientInfo(clientinfo),
+ m_callbacks(callbacks)
+{
+ //nothing to do
+}
+
+SG_IObject::
+SG_IObject(
+ const SG_IObject &other
+) :
+ m_SGclientObject(other.m_SGclientObject),
+ m_SGclientInfo(other.m_SGclientInfo),
+ m_callbacks(other.m_callbacks)
+{
+ //nothing to do
+}
+
+ void
+SG_IObject::
+AddSGController(
+ SG_Controller* cont
+){
+ m_SGcontrollers.push_back(cont);
+}
+
+ void
+SG_IObject::
+RemoveAllControllers(
+) {
+ m_SGcontrollers.clear();
+}
+
+/// Needed for replication
+ SGControllerList&
+SG_IObject::
+GetSGControllerList(
+){
+ return m_SGcontrollers;
+}
+
+ void*
+SG_IObject::
+GetSGClientObject(
+){
+ return m_SGclientObject;
+}
+
+const
+ void*
+SG_IObject::
+GetSGClientObject(
+) const {
+ return m_SGclientObject;
+}
+
+ void
+SG_IObject::
+SetSGClientObject(
+ void* clientObject
+){
+ m_SGclientObject = clientObject;
+}
+
+
+ void
+SG_IObject::
+ActivateReplicationCallback(
+ SG_IObject *replica
+){
+ if (m_callbacks.m_replicafunc)
+ {
+ // Call client provided replication func
+ m_callbacks.m_replicafunc(replica,m_SGclientObject,m_SGclientInfo);
+ }
+};
+
+ void
+SG_IObject::
+ActivateDestructionCallback(
+){
+ if (m_callbacks.m_destructionfunc)
+ {
+ // Call client provided destruction function on this!
+ m_callbacks.m_destructionfunc(this,m_SGclientObject,m_SGclientInfo);
+ }
+}
+
+ void
+SG_IObject::
+SetControllerTime(
+ double time
+){
+ SGControllerList::iterator contit;
+
+ for (contit = m_SGcontrollers.begin();contit!=m_SGcontrollers.end();++contit)
+ {
+ (*contit)->SetSimulatedTime(time);
+ }
+}
+
+
+SG_IObject::
+~SG_IObject()
+{
+ SGControllerList::iterator contit;
+
+ for (contit = m_SGcontrollers.begin();contit!=m_SGcontrollers.end();++contit)
+ {
+ delete (*contit);
+ }
+}
diff --git a/source/gameengine/SceneGraph/SG_IObject.h b/source/gameengine/SceneGraph/SG_IObject.h
new file mode 100644
index 00000000000..f9066a9b340
--- /dev/null
+++ b/source/gameengine/SceneGraph/SG_IObject.h
@@ -0,0 +1,220 @@
+/**
+ * $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 __SG_IOBJECT
+#define __SG_IOBJECT
+/**
+base object that can be part of the scenegraph.
+*/
+#include <vector>
+
+
+class SG_Controller;
+class SG_IObject;
+
+typedef std::vector<SG_Controller*> SGControllerList;
+
+typedef void* (*SG_ReplicationNewCallback)(
+ SG_IObject* sgobject,
+ void* clientobj,
+ void* clientinfo
+);
+
+typedef void* (*SG_DestructionNewCallback)(
+ SG_IObject* sgobject,
+ void* clientobj,
+ void* clientinfo
+);
+
+
+/**
+ * SG_Callbacks hold 2 call backs to the outside world.
+ * The first is meant to be called when objects are replicated.
+ * And allows the outside world to syncronise external objects
+ * with replicated nodes and their children.
+ * The second is called when a node is detroyed and again
+ * is their for synconisation purposes
+ * These callbacks may both be NULL.
+ * The efficacy of this approach has not been proved some
+ * alternatives might be to perform all replication and destruction
+ * externally.
+ * To define a class interface rather than a simple function
+ * call back so that replication information can be transmitted from
+ * parent->child.
+ */
+struct SG_Callbacks
+{
+ SG_Callbacks(
+ ):
+ m_replicafunc(NULL),
+ m_destructionfunc(NULL)
+ {
+ };
+
+ SG_Callbacks(
+ SG_ReplicationNewCallback repfunc,
+ SG_DestructionNewCallback destructfunc
+ ):
+ m_replicafunc(repfunc),
+ m_destructionfunc(destructfunc)
+ {
+ };
+
+ SG_ReplicationNewCallback m_replicafunc;
+ SG_DestructionNewCallback m_destructionfunc;
+};
+
+class SG_IObject
+{
+private :
+
+ void* m_SGclientObject;
+ void* m_SGclientInfo;
+ SG_Callbacks m_callbacks;
+ SGControllerList m_SGcontrollers;
+
+public:
+
+
+ virtual ~SG_IObject();
+
+
+ /**
+ * Add a pointer to a controller allocated on the heap, to
+ * this node. This memory for this controller becomes the
+ * responsibility of this class. It will be deleted when
+ * this object is deleted.
+ */
+
+ void
+ AddSGController(
+ SG_Controller* cont
+ );
+
+ /**
+ * Clear the array of pointers to controllers associated with
+ * this node. This does not delete the controllers themselves!
+ * This should be used very carefully to avoid memory
+ * leaks.
+ */
+
+ void
+ RemoveAllControllers(
+ );
+
+ /// Needed for replication
+
+ /**
+ * Return a reference to this node's controller list.
+ * Whilst we don't wish to expose full control of the container
+ * to the user we do allow them to call non_const methods
+ * on pointers in the container. C++ topic: how to do this in
+ * using STL?
+ */
+
+ SGControllerList&
+ GetSGControllerList(
+ );
+
+
+ /**
+ * Get the client object associated with this
+ * node. This interface allows you to associate
+ * arbitray external objects with this node. They are
+ * passed to the callback functions when they are
+ * activated so you can syncronise these external objects
+ * upon replication and destruction
+ * This may be NULL.
+ */
+
+ void*
+ GetSGClientObject(
+ );
+
+ const
+ void*
+ GetSGClientObject(
+ ) const ;
+
+
+ /**
+ * Set the client object for this node. This is just a
+ * pointer to an object allocated that should exist for
+ * the duration of the lifetime of this object, or untill
+ * this function is called again.
+ */
+
+ void
+ SetSGClientObject(
+ void* clientObject
+ );
+
+ /**
+ * Set the current simulation time for this node.
+ * The implementation of this function runs through
+ * the nodes list of controllers and calls their SetSimulatedTime methods
+ */
+
+ void
+ SetControllerTime(
+ double time
+ );
+
+ virtual
+ void
+ Destruct(
+ ) = 0;
+
+protected :
+
+ void
+ ActivateReplicationCallback(
+ SG_IObject *replica
+ );
+
+ void
+ ActivateDestructionCallback(
+ );
+
+ SG_IObject(
+ void* clientobj,
+ void* clientinfo,
+ SG_Callbacks callbacks
+ );
+
+ SG_IObject(
+ const SG_IObject &other
+ );
+
+
+};
+
+#endif //__SG_IOBJECT
diff --git a/source/gameengine/SceneGraph/SG_Node.cpp b/source/gameengine/SceneGraph/SG_Node.cpp
new file mode 100644
index 00000000000..d40cdca0c76
--- /dev/null
+++ b/source/gameengine/SceneGraph/SG_Node.cpp
@@ -0,0 +1,231 @@
+/**
+ * $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 "SG_Node.h"
+
+#include "SG_ParentRelation.h"
+
+#include <algorithm>
+
+using namespace std;
+
+
+SG_Node::SG_Node(
+ void* clientobj,
+ void* clientinfo,
+ SG_Callbacks callbacks
+
+)
+ : SG_Spatial(clientobj,clientinfo,callbacks),
+ m_SGparent(NULL)
+{
+}
+
+SG_Node::SG_Node(
+ const SG_Node & other
+) :
+ SG_Spatial(other),
+ m_SGparent(other.m_SGparent),
+ m_children(other.m_children)
+{
+ // nothing to do
+}
+
+SG_Node::~SG_Node()
+{
+}
+
+
+SG_Node* SG_Node::GetSGReplica()
+{
+ SG_Node* replica = new SG_Node(*this);
+ if (replica == NULL) return NULL;
+
+ ProcessSGReplica(replica);
+
+ return replica;
+}
+
+ void
+SG_Node::
+ProcessSGReplica(
+ SG_Node* replica
+){
+ // Apply the replication call back function.
+ ActivateReplicationCallback(replica);
+
+ // clear the replica node of it's parent.
+ static_cast<SG_Node*>(replica)->m_SGparent = NULL;
+
+ if (m_children.begin() != m_children.end())
+ {
+ // if this node has children, the replica has too, so clear and clone children
+ replica->ClearSGChildren();
+
+ NodeList::iterator childit;
+ for (childit = m_children.begin();childit!=m_children.end();++childit)
+ {
+ replica->AddChild((*childit)->GetSGReplica());
+ }
+ }
+}
+
+
+ void
+SG_Node::
+Destruct()
+{
+ // Not entirely sure what Destruct() expects to happen.
+ // I think it probably means just to call the DestructionCallback
+ // in the right order on all the children - rather than free any memory
+
+ // We'll delete m_parent_relation now anyway.
+
+ delete(m_parent_relation);
+ m_parent_relation = NULL;
+
+ if (m_children.begin() != m_children.end())
+ {
+ NodeList::iterator childit;
+ for (childit = m_children.begin();childit!=m_children.end();++childit)
+ {
+ // call the SG_Node destruct method on each of our children }-)
+ (*childit)->Destruct();
+ }
+ }
+
+ ActivateDestructionCallback();
+}
+
+
+ SG_Node*
+SG_Node::
+GetSGParent(
+) const {
+ return m_SGparent;
+}
+
+ void
+SG_Node::
+SetSGParent(
+ SG_Node* parent
+){
+ m_SGparent = parent;
+}
+
+const
+ SG_Node*
+SG_Node::
+GetRootSGParent(
+) const {
+ return (m_SGparent ? (const SG_Node*) m_SGparent->GetRootSGParent() : (const SG_Node*) this);
+}
+
+
+ void
+SG_Node::
+DisconnectFromParent(
+){
+ if (m_SGparent)
+ {
+ m_SGparent->RemoveChild(this);
+ m_SGparent = NULL;
+ }
+
+}
+
+
+
+void SG_Node::AddChild(SG_Node* child)
+{
+ m_children.push_back(child);
+ child->SetSGParent(this); // this way ?
+}
+
+void SG_Node::RemoveChild(SG_Node* child)
+{
+ NodeList::iterator childfound = find(m_children.begin(),m_children.end(),child);
+
+ if (childfound != m_children.end())
+ {
+ m_children.erase(childfound);
+ }
+}
+
+
+
+void SG_Node::UpdateWorldData(double time)
+{
+ UpdateSpatialData(GetSGParent(),time);
+
+ // update children's worlddata
+ for (NodeList::iterator it = m_children.begin();it!=m_children.end();++it)
+ {
+ (*it)->UpdateWorldData(time);
+ }
+}
+
+
+NodeList& SG_Node::GetSGChildren()
+{
+ return this->m_children;
+}
+
+
+const NodeList& SG_Node::GetSGChildren() const
+{
+ return this->m_children;
+}
+
+
+void SG_Node::ClearSGChildren()
+{
+ m_children.clear();
+}
+
+
+
+void SG_Node::SetSimulatedTime(double time,bool recurse)
+{
+
+ // update the controllers of this node.
+ SetControllerTime(time);
+
+ // update children's simulate time.
+ if (recurse)
+ {
+ for (NodeList::iterator it = m_children.begin();it!=m_children.end();++it)
+ {
+ (*it)->SetSimulatedTime(time,recurse);
+ }
+ }
+}
+
diff --git a/source/gameengine/SceneGraph/SG_Node.h b/source/gameengine/SceneGraph/SG_Node.h
new file mode 100644
index 00000000000..a42afefcf1e
--- /dev/null
+++ b/source/gameengine/SceneGraph/SG_Node.h
@@ -0,0 +1,208 @@
+/**
+ * $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 __SG_NODE_H
+#define __SG_NODE_H
+
+#include "SG_Spatial.h"
+
+#include <vector>
+
+typedef std::vector<SG_Node*> NodeList;
+
+class SG_Node : public SG_Spatial
+{
+
+public:
+
+ SG_Node(
+ void* clientobj,
+ void* clientinfo,
+ SG_Callbacks callbacks
+ );
+
+ SG_Node(
+ const SG_Node & other
+ );
+
+ virtual ~SG_Node();
+
+
+ /**
+ * Add a child to this object. This also informs the child of
+ * it's parent.
+ * This just stores a pointer to the child and does not
+ * make a deep copy.
+ */
+
+ void
+ AddChild(
+ SG_Node* child
+ );
+
+ /**
+ * Remove a child node from this object. This just removes the child
+ * pointer from the list of children - it does not destroy the child.
+ * This does not inform the child that this node is no longer it's parent.
+ * If the node was not a child of this object no action is performed.
+ */
+
+ void
+ RemoveChild(
+ SG_Node* child
+ );
+
+ /**
+ * Get the current list of children. Do not use this interface for
+ * adding or removing children please use the methods of this class for
+ * that.
+ * @return a reference to the list of children of this node.
+ */
+
+ NodeList&
+ GetSGChildren(
+ );
+
+ /**
+ * Get the current list of children.
+ * @return a const reference to the current list of children of this node.
+ */
+
+ const
+ NodeList&
+ GetSGChildren(
+ ) const;
+
+ /**
+ * Clear the list of children associated with this node
+ */
+
+ void
+ ClearSGChildren(
+ );
+
+ /**
+ * return the parent of this node if it exists.
+ */
+
+ SG_Node*
+ GetSGParent(
+ ) const ;
+
+
+ /**
+ * Set the parent of this node.
+ */
+
+ void
+ SetSGParent(
+ SG_Node* parent
+ );
+
+ /**
+ * Return the top node in this node's Scene graph hierarchy
+ */
+
+ const
+ SG_Node*
+ GetRootSGParent(
+ ) const;
+
+ /**
+ * Disconnect this node from it's parent
+ */
+
+ void
+ DisconnectFromParent(
+ );
+
+ /**
+ * Tell this node to treat it's parent as a vertex parent.
+ */
+
+ void
+ SetVertexParent(
+ bool isvertexparent
+ ) ;
+
+
+ /**
+ * Update the spatial data of this node. Iterate through
+ * the children of this node and update their world data.
+ */
+
+ void
+ UpdateWorldData(
+ double time
+ );
+
+ /**
+ * Update the simulation time of this node. Iterate through
+ * the children nodes and update their simulated time.
+ */
+
+ void
+ SetSimulatedTime(
+ double time,
+ bool resurse
+ );
+
+ /**
+ * Node replication functions.
+ */
+
+ SG_Node*
+ GetSGReplica(
+ );
+
+ void
+ Destruct(
+ );
+
+private:
+
+ void
+ ProcessSGReplica(
+ SG_Node* replica
+ );
+
+ /**
+ * The list of children of this node.
+ */
+ NodeList m_children;
+
+ /**
+ * The parent of this node may be NULL
+ */
+ SG_Node* m_SGparent;
+
+};
+#endif //__SG_NODE_H
diff --git a/source/gameengine/SceneGraph/SG_ParentRelation.h b/source/gameengine/SceneGraph/SG_ParentRelation.h
new file mode 100644
index 00000000000..5df8efe7027
--- /dev/null
+++ b/source/gameengine/SceneGraph/SG_ParentRelation.h
@@ -0,0 +1,116 @@
+/**
+ * @mainpage SG_ParentRelation
+
+ * @section
+ *
+ * This is an abstract interface class to the Scene Graph library.
+ * It allows you to specify how child nodes react to parent nodes.
+ * Normally a child will use it's parent's transforms to compute
+ * it's own global transforms. How this is performed depends on
+ * the type of relation. For example if the parent is a vertex
+ * parent to this child then the child should not inherit any
+ * rotation information from the parent. Or if the parent is a
+ * 'slow parent' to this child then the child should react
+ * slowly to changes in the parent's position. The exact relation
+ * is left for you to implement by filling out this interface
+ * with concrete examples.
+ *
+ * There is exactly one SG_ParentRelation per SG_Node. Subclasses
+ * should not be value types and should be allocated on the heap.
+ *
+ * $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 __SG_ParentRelation_h
+#define __SG_ParentRelation_h
+
+class SG_Spatial;
+
+class SG_ParentRelation {
+
+public :
+
+ /**
+ * Update the childs local and global coordinates
+ * based upon the parents global coordinates.
+ * You must also handle the case when this node has no
+ * parent (parent == NULL). Usually you should just
+ * copy the local coordinates of the child to the
+ * world coordinates.
+ */
+
+ virtual
+ void
+ UpdateChildCoordinates(
+ SG_Spatial * child,
+ const SG_Spatial * parent
+ ) = 0;
+
+ virtual
+ ~SG_ParentRelation(
+ ){
+ };
+
+ /**
+ * You must provide a way of duplicating an
+ * instance of an SG_ParentRelation. This should
+ * return a pointer to a new duplicate allocated
+ * on the heap. Responsibilty for deleting the
+ * duplicate resides with the caller of this method.
+ */
+
+ virtual
+ SG_ParentRelation *
+ NewCopy(
+ ) = 0;
+
+protected :
+
+ /**
+ * Protected constructors
+ * this class is not meant to be instantiated.
+ */
+
+ SG_ParentRelation(
+ ) {
+ };
+
+ /**
+ * Copy construction should not be implemented
+ */
+
+ SG_ParentRelation(
+ const SG_ParentRelation &
+ );
+};
+
+#endif
diff --git a/source/gameengine/SceneGraph/SG_Spatial.cpp b/source/gameengine/SceneGraph/SG_Spatial.cpp
new file mode 100644
index 00000000000..96370f28ef3
--- /dev/null
+++ b/source/gameengine/SceneGraph/SG_Spatial.cpp
@@ -0,0 +1,283 @@
+/**
+ * $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 "SG_Node.h"
+#include "SG_Spatial.h"
+#include "SG_Controller.h"
+#include "SG_ParentRelation.h"
+
+SG_Spatial::
+SG_Spatial(
+ void* clientobj,
+ void* clientinfo,
+ SG_Callbacks callbacks
+):
+
+ SG_IObject(clientobj,clientinfo,callbacks),
+ m_localPosition(MT_Point3(0,0,0)),
+ m_localScaling(MT_Vector3(1.f,1.f,1.f)),
+ m_localRotation(1,0,0,0,1,0,0,0,1),
+ m_parent_relation (NULL),
+
+ m_worldPosition(MT_Point3(0,0,0)),
+ m_worldScaling(MT_Vector3(1.f,1.f,1.f)),
+ m_worldRotation(0,0,0,0,0,0,0,0,0)
+
+{
+}
+
+SG_Spatial::
+SG_Spatial(
+ const SG_Spatial& other
+) :
+ SG_IObject(other),
+ m_localPosition(other.m_localPosition),
+ m_localScaling(other.m_localScaling),
+ m_localRotation(other.m_localRotation),
+ m_parent_relation(NULL),
+ m_worldPosition(other.m_worldPosition),
+ m_worldScaling(other.m_worldScaling),
+ m_worldRotation(other.m_worldRotation)
+{
+ // duplicate the parent relation for this object
+ m_parent_relation = other.m_parent_relation->NewCopy();
+}
+
+SG_Spatial::
+~SG_Spatial()
+{
+ delete (m_parent_relation);
+}
+
+ void
+SG_Spatial::
+SetParentRelation(
+ SG_ParentRelation *relation
+){
+ delete (m_parent_relation);
+ m_parent_relation = relation;
+}
+
+
+/**
+ * Update Spatial Data.
+ * Calculates WorldTransform., (either doing itsself or using the linked SGControllers)
+ */
+
+
+ void
+SG_Spatial::
+UpdateSpatialData(
+ const SG_Spatial *parent,
+ double time
+){
+
+ bool bComputesWorldTransform = false;
+
+ // update spatial controllers
+
+ SGControllerList::iterator cit = GetSGControllerList().begin();
+ SGControllerList::const_iterator c_end = GetSGControllerList().end();
+
+ for (;cit!=c_end;++cit)
+ {
+ bComputesWorldTransform = bComputesWorldTransform || (*cit)->Update(time);
+ }
+
+ // If none of the objects updated our values then we ask the
+ // parent_relation object owned by this class to update
+ // our world coordinates.
+
+ if (!bComputesWorldTransform)
+ {
+ ComputeWorldTransforms(parent);
+ }
+}
+
+void SG_Spatial::ComputeWorldTransforms(const SG_Spatial *parent)
+{
+ m_parent_relation->UpdateChildCoordinates(this,parent);
+}
+
+
+/**
+ * Position and translation methods
+ */
+
+
+ void
+SG_Spatial::
+RelativeTranslate(
+ const MT_Vector3& trans,
+ const SG_Spatial *parent,
+ bool local
+){
+ if (local) {
+ m_localPosition += m_localRotation * trans;
+ } else {
+ if (parent) {
+ m_localPosition += trans * parent->GetWorldOrientation();
+ } else {
+ m_localPosition += trans;
+ }
+ }
+}
+
+ void
+SG_Spatial::
+SetLocalPosition(
+ const MT_Point3& trans
+){
+ m_localPosition = trans;
+}
+
+ void
+SG_Spatial::
+SetWorldPosition(
+ const MT_Point3& trans
+) {
+ m_worldPosition = trans;
+}
+
+/**
+ * Scaling methods.
+ */
+
+ void
+SG_Spatial::
+RelativeScale(
+ const MT_Vector3& scale
+){
+ m_localScaling = m_localScaling * scale;
+}
+
+ void
+SG_Spatial::
+SetLocalScale(
+ const MT_Vector3& scale
+){
+ m_localScaling = scale;
+}
+
+
+ void
+SG_Spatial::
+SetWorldScale(
+ const MT_Vector3& scale
+){
+ m_worldScaling = scale;
+}
+
+/**
+ * Orientation and rotation methods.
+ */
+
+
+ void
+SG_Spatial::
+RelativeRotate(
+ const MT_Matrix3x3& rot,
+ bool local
+){
+ m_localRotation = m_localRotation * (
+ local ?
+ rot
+ :
+ (GetWorldOrientation().inverse() * rot * GetWorldOrientation()));
+}
+
+ void
+SG_Spatial::
+SetLocalOrientation(const MT_Matrix3x3& rot)
+{
+ m_localRotation = rot;
+}
+
+
+
+ void
+SG_Spatial::
+SetWorldOrientation(
+ const MT_Matrix3x3& rot
+) {
+ m_worldRotation = rot;
+}
+
+const
+ MT_Point3&
+SG_Spatial::
+GetLocalPosition(
+) const {
+ return m_localPosition;
+}
+
+const
+ MT_Matrix3x3&
+SG_Spatial::
+GetLocalOrientation(
+) const {
+ return m_localRotation;
+}
+
+const
+ MT_Vector3&
+SG_Spatial::
+GetLocalScale(
+) const{
+ return m_localScaling;
+}
+
+
+const
+ MT_Point3&
+SG_Spatial::
+GetWorldPosition(
+) const {
+ return m_worldPosition;
+}
+
+const
+ MT_Matrix3x3&
+SG_Spatial::
+GetWorldOrientation(
+) const {
+ return m_worldRotation;
+}
+
+const
+ MT_Vector3&
+SG_Spatial::
+GetWorldScaling(
+) const {
+ return m_worldScaling;
+}
+
diff --git a/source/gameengine/SceneGraph/SG_Spatial.h b/source/gameengine/SceneGraph/SG_Spatial.h
new file mode 100644
index 00000000000..ff54c4055be
--- /dev/null
+++ b/source/gameengine/SceneGraph/SG_Spatial.h
@@ -0,0 +1,205 @@
+/**
+ * $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 __SG_SPATIAL_H
+#define __SG_SPATIAL_H
+
+#include <MT_Vector3.h>
+#include <MT_Point3.h>
+#include <MT_Matrix3x3.h> // or Quaternion later ?
+
+#include "SG_IObject.h"
+
+class SG_Node;
+class SG_ParentRelation;
+
+class SG_Spatial : public SG_IObject
+{
+
+protected:
+ MT_Point3 m_localPosition;
+ MT_Matrix3x3 m_localRotation;
+ MT_Vector3 m_localScaling;
+
+ MT_Point3 m_worldPosition;
+ MT_Matrix3x3 m_worldRotation;
+ MT_Vector3 m_worldScaling;
+
+ SG_ParentRelation * m_parent_relation;
+
+public:
+
+ /**
+ * Define the realtionship this node has with it's parent
+ * node. You should pass an unshared instance of an SG_ParentRelation
+ * allocated on the heap to this method. Ownership of this
+ * instance is assumed by this class.
+ * You may call this function several times in the lifetime
+ * of a node to change the relationship dynamically.
+ * You must call this method before the first call to UpdateSpatialData().
+ * An assertion willl be fired at run-time in debug if this is not
+ * the case.
+ * The relation is activated only if no controllers of this object
+ * updated the coordinates of the child.
+ */
+
+ void
+ SetParentRelation(
+ SG_ParentRelation *relation
+ );
+
+
+ /**
+ * Apply a translation relative to the current position.
+ * if local then the translation is assumed to be in the
+ * local coordinates of this object. If not then the translation
+ * is assumed to be in global coordinates. In this case
+ * you must provide a pointer to the parent of this object if it
+ * exists otherwise if there is no parent set it to NULL
+ */
+
+ void
+ RelativeTranslate(
+ const MT_Vector3& trans,
+ const SG_Spatial *parent,
+ bool local
+ );
+
+ void
+ SetLocalPosition(
+ const MT_Point3& trans
+ );
+
+ void
+ SetWorldPosition(
+ const MT_Point3& trans
+ );
+
+ void
+ RelativeRotate(
+ const MT_Matrix3x3& rot,
+ bool local
+ );
+
+ void
+ SetLocalOrientation(
+ const MT_Matrix3x3& rot
+ );
+
+ void
+ SetWorldOrientation(
+ const MT_Matrix3x3& rot
+ );
+
+ void
+ RelativeScale(
+ const MT_Vector3& scale
+ );
+
+ void
+ SetLocalScale(
+ const MT_Vector3& scale
+ );
+
+ void
+ SetWorldScale(
+ const MT_Vector3& scale
+ );
+
+ const
+ MT_Point3&
+ GetLocalPosition(
+ ) const ;
+
+ const
+ MT_Matrix3x3&
+ GetLocalOrientation(
+ ) const ;
+
+ const
+ MT_Vector3&
+ GetLocalScale(
+ ) const;
+
+ const
+ MT_Point3&
+ GetWorldPosition(
+ ) const ;
+
+ const
+ MT_Matrix3x3&
+ GetWorldOrientation(
+ ) const ;
+
+ const
+ MT_Vector3&
+ GetWorldScaling(
+ ) const ;
+
+
+ void ComputeWorldTransforms( const SG_Spatial *parent);
+
+
+protected:
+ friend SG_Controller;
+
+ /**
+ * Protected constructor this class is not
+ * designed for direct instantiation
+ */
+
+ SG_Spatial(
+ void* clientobj,
+ void* clientinfo,
+ SG_Callbacks callbacks
+ );
+
+ SG_Spatial(
+ const SG_Spatial& other
+ );
+
+
+ virtual ~SG_Spatial();
+
+ /**
+ * Update the world coordinates of this spatial node. This also informs
+ * any controllers to update this object.
+ */
+
+ void
+ UpdateSpatialData(
+ const SG_Spatial *parent,
+ double time
+ );
+
+};
+#endif //__SG_SPATIAL_H