Commits

Alberto Torres committed 422659e

Improved and simplified input system.

Comments (0)

Files changed (16)

 set(PYGAMEKIT_SRC
     blendfile.pxi
     engine.pxi
-    event.pxi
+    sensor.pxi
     gamekit.pyx
     gameobject.pxd
     gameobject.pxi
     if(PYTHON_LIBRARIES)
     else()
         set(PYTHON_INCLUDE_PATH /home/julio/.wine/drive_c/Python27/include)
-        set(PYTHON_LIBRARIES /home/julio/.wine/drive_c/Python27/libs)
+        set(PYTHON_LIBRARIES -L/home/julio/.wine/drive_c/Python27/libs -lpython27)
     endif()
 endif()
 
 find_program(CYTHON_EXECUTABLE cython)
 
-# Figure out installation path
-execute_process(COMMAND
-  ${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"
-  OUTPUT_VARIABLE PYTHON_SITE_PACKAGES OUTPUT_STRIP_TRAILING_WHITESPACE)
+# # Figure out installation path
+# execute_process(COMMAND
+#   ${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"
+#   OUTPUT_VARIABLE PYTHON_SITE_PACKAGES OUTPUT_STRIP_TRAILING_WHITESPACE)
 
-# How to Cython the .pyx file
+# Cython integratin into gdb
+if (CMAKE_BUILD_TYPE MATCHES "Deb")
+    set(CYTHON_DEBUG --gdb)
+endif()
+
 add_custom_command(
   DEPENDS ${PYGAMEKIT_SRC}
   OUTPUT gamekit.cpp mathutils.cpp
-  COMMAND ${CYTHON_EXECUTABLE} --cplus --fast-fail -o gamekit.cpp
+  COMMAND ${CYTHON_EXECUTABLE} ${CYTHON_DEBUG} --cplus --fast-fail -o gamekit.cpp
          "${CMAKE_CURRENT_SOURCE_DIR}/gamekit.pyx"
-  COMMAND ${CYTHON_EXECUTABLE} --cplus --fast-fail -o mathutils.cpp
+  COMMAND ${CYTHON_EXECUTABLE} ${CYTHON_DEBUG} --cplus --fast-fail -o mathutils.cpp
          "${CMAKE_CURRENT_SOURCE_DIR}/mathutils.pyx"
 
 )
 endif()
 include_directories(${PYTHON_INCLUDE_PATH} ${OGREKIT_INCLUDE} .)
 
-IF( CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" )
-  SET_TARGET_PROPERTIES(cython_gamekit PROPERTIES COMPILE_FLAGS "-fPIC")
-ENDIF( CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" )
 
-# Install the extension
-install(TARGETS cython_gamekit
-  DESTINATION ${PYTHON_SITE_PACKAGES})
-
-
         if filename:
             self.load(filename, options, scene, group)
 
-    def load(self, filename, options = ONLY_ACTIVE_SCENE, scene = "", group = ""):
+    def load(self, filename, options = ONLY_ACTIVE_SCENE, scene = "", group = "", seek = 0):
         
         #cdef glBlendLoader* bl = gkBlendLoaderGS()
         self.bfile = loadFile(gkUtils_getFile(to_stdstring(filename)), options, to_stdstring(scene), to_stdstring(group))
     void* gkTextManager_getByName "gkTextManager::getSingleton().getByName"(const_std_string& name)
     bool gkTextManager_exists "gkTextManager::getSingleton().exists"(const_std_string& name)
     
-cdef Event tick_callback = Event()
+cdef Sensor tick_callback = Sensor()
 cdef bool initialized = False
 
 cdef class Engine:
     cdef gkEngine *eng
     #cdef gkHUDManager* mgr
+    
+    tickSensor = TickSensor()
 
-    def __init__(self, bfile=None, cfgfile=None, initialize=True):
+    def __init__(self, bfile=None, cfgfile=None, initialize=True, seek=0):
         
         global initialized
         
             #self.mgr = new gkHUDManager()
 
             if bfile:
-                self.loadBlend(bfile)
+                self.loadBlend(bfile, seek)
                 
             self.eng.initializeStepLoop()
             initialized = True
             return False
         return self.eng.stepOneFrame()
     
-    def loadBlend(self, bfile):
+    def loadBlend(self, bfile, seek=0):
         cdef gkScene* scn
         
         b = BlendFile()
-        b.load(bfile,IGNORE_CACHE_FILE)
+        b.load(bfile,IGNORE_CACHE_FILE,seek=seek)
         
         scn = self.eng.getActiveScene()
         
             
             scn.createInstance()
             
-        
-    property onTick:
-        
-        def __get__(self):
-            return tick_callback
-            
-        def __set__(self, f):
-            global tick_callback
-            del(tick_callback[:])
-            tick_callback += f
-            
     def run(self):
         while self.stepOneFrame():
             pass
+
+cdef class TickSensor(Sensor):
+    
+    def __init__(self):
+        self.callback_list = tick_callback
+        
+    def __nonzero__(self):
+        return True
             
 cdef void evaluate_tick_callbacks() except *:
-    tick_callback.execute()
+    cdef TickSensor t = tick_callback.next_non_empty()
+    while t!=None:
+        t.execute()
+        t = t.next_non_empty()
         
 def _evaluate_all_callbacks():
     evaluate_input_callbacks()

event.pxi

-
-from libcpp cimport bool
-from prerequisites cimport *
-
-cdef class EventData(object):
-    
-    cdef int _key
-    cdef gkVector2 *_rel
-    cdef std_string *_prop
-    
-    def __init__(self):
-        self._rel = new gkVector2()
-        self._prop = new std_string()
-        #TODO: is this being freed?
-    
-    @property
-    def keycode(self):
-        return self._key
-    
-    @property
-    def keyname(self):
-        return KEYS[self._key]
-        
-    @property
-    def pos(self):
-        cdef gkVector2 v = getMouse().getPosition()
-        return v.x, v.y
-        
-    @property
-    def rel(self):
-        return self._rel.x, self._rel.y
-        
-
-cdef class Event(list):
-    
-    cdef Event _next
-    cdef bool is_in_callback_list
-    cdef EventData data
-    cdef bool prevstate
-    cdef void *misc, *misc2
-    cdef object sens
-    
-    def __init__(self):
-        self.data = EventData()
-        
-    def __add__(self, f):
-        if isinstance(f, Event):
-            raise TypeError("Use boolean operations to combine events.")
-        elif hasattr(f,'__iter__'):
-            if [x for x in f if not hasattr(x,'__call__')]:
-                raise TypeError("'%s' object is not callable or a list of callables." % f.__class__.__name__)
-            self.extend(f)
-        elif hasattr(f,'__call__'):
-            self.append(f)
-        else:
-            raise TypeError("'%s' object is not callable or a list of callables." % f.__class__.__name__)
-        return self
-        
-    def __iadd__(self, f):
-        if type(f)==Event:
-            self.__add__(f[:])
-        return self.__add__(f)
-        # TODO: move the code of __add__ to __iadd__ and
-        #       make __add__ return a list
-        
-    #as decorator
-    def __call__(self, f):
-        self.__add__(f)
-        return f
-    
-    cdef execute(self):
-        for f in self:
-            f(self.sens)
-    
-    # return next, removing empty callbacks.
-    cdef Event next_non_empty(self):
-        cdef Event n
-        n = self._next
-        while not n and n!=None:
-            n.is_in_callback_list = False
-            n = self._next = n._next
-        return n
-        
-    # add itself to list, if not already
-    cdef Event check_add_to_list(self, Event callback_list):
-        if not self.is_in_callback_list:
-            self._next = callback_list._next
-            callback_list._next = self
-            
-            
 
 include "prerequisites.pxi"
-include "event.pxi"
+include "sensor.pxi"
 include "gameobject.pxi"
 include "scene.pxi"
 include "engine.pxi"
 include "blendfile.pxi"
 include "input.pxi"
-print     GK_PLATFORM,  GK_PLATFORM_ANDROID,    GK_PLATFORM_LINUX
 import sys
 
 #gkLogger_enable(to_stdstring("AppCppDemo.log"), GK_CPP_VERBOSE_LOG)
 
 cdef gkUserDefs *prefs = new gkUserDefs()
 #prefs.rendersystem = OGRE_RS_GL
-prefs.winsize.x = 800
-prefs.winsize.y = 800
+prefs.winsize.x = 1280
+prefs.winsize.y = 720
 #prefs.fullscreen = True
-prefs.wintitle = to_stdstring("OgreKit Python Testbed")
+prefs.wintitle = to_stdstring("Pixelements Python Gamekit.")
 #prefs.verbose = GK_CPP_VERBOSE_LOG
 #prefs.fsaa = True
 #prefs.debugPhysics = True
-prefs.debugFps = True
+#prefs.debugFps = True
 prefs.grabInput = False
 #prefs.useBulletDbvt = False
 prefs.enableshadows = 0
         gkAnimationPlayer*     getAnimationPlayer(const_std_string name)
         
         void playAnimation(gkAnimationPlayer* act, Real blend)#, int mode = AK_ACT_END, int priority = 0)
+        void stopAnimation(gkAnimationPlayer* act)
         
         gkAnimations& getAnimations()
     
 
 OBJECT_TYPES = 'NULL', 'CAMERA', 'LIGHT', 'ENTITY', 'OBJECT', 'SKELETON', 'PARTICLES'
 
-cdef Event collision_callbacks = Event()
+cdef CollisionSensor collision_callbacks = CollisionSensor()
 
 cdef gkGameObject* cloneRecursiveImpl(gkGameObject* ob, int lifespan=0, bool instance=True):
     
 
         (<gkGameObject*>self._p).applyForce(v, TRANSFORM_WORLD)
 
+    def suspendDynamics(self):
+        (<gkGameObject*>self._p).getPhysicsController().suspend(True)
+
+    def resumeDynamics(self):
+        (<gkGameObject*>self._p).getPhysicsController().suspend(False)
 
     @property
     def animations(self):
     
     cdef gkGameObject *ob
     
-    def play(self):
-        self.ob.playAnimation(<gkAnimationPlayer*>self._p,1.0)
+    def play(self, blend = 1.0):
+        self.ob.playAnimation(<gkAnimationPlayer*>self._p, blend)
+        
+    def stop(self, blend = 1.0):
+        self.ob.stopAnimation(<gkAnimationPlayer*>self._p)
+        
+    property weight:
+        def __get__(self):
+            return (<gkAnimationPlayer*>self._p).getWeight()
+        def __set__(self,  v):
+            (<gkAnimationPlayer*>self._p).setWeight(v)
+            
+    property length:
+        def __get__(self):
+            return (<gkAnimationPlayer*>self._p).getLength()
+        #def __set__(self,  v):
+            #(<gkAnimationPlayer*>self._p).setLength(v)
+            
+    property speed_factor:
+        def __get__(self):
+            return (<gkAnimationPlayer*>self._p).getSpeedFactor()
+        def __set__(self, v):
+            (<gkAnimationPlayer*>self._p).setSpeedFactor(v)
+    
 
 cdef class AnimationList(pywrap):
         
         return (<gkGameObject*>self._p).getAnimations().size()
         
 
-cdef class CollisionSensor:
+cdef class CollisionSensor(Sensor):
     
     cdef gkPhysicsController *pc
     cdef std_string *prop
-    cdef Event _collide
     cdef gkGameObjectArray *objlist
     
     cdef _init(self, gkGameObject *ob, prop):
         self.prop = new std_string(prop) #is this freed?
-        self._collide = Event()
-        self._collide.data._prop = self.prop
-        self._collide.sens=self
-        self.pc = self._collide.misc = ob.getPhysicsController()
-        self.objlist = self._collide.misc2 = new gkGameObjectArray()
+        self.pc = ob.getPhysicsController()
+        self.objlist = new gkGameObjectArray()
+        self.callback_list = collision_callbacks
         return self
     
     def __nonzero__(self):
         return self.pc.sensorCollides(self.prop[0], to_stdstring(""), False, False, self.objlist)
-
-    property onCollision:
-        
-        def __get__(self):
-            self._collide.check_add_to_list(collision_callbacks)
-            return self._collide
-            
-        def __set__(self, func):
-            self._collide.check_add_to_list(collision_callbacks)
-            del(self._collide[:])
-            self._collide += func
             
     property hitObjects:
         
         else: return "<CollisionSensor>"
         
 cdef void evaluate_collision_callbacks() except *:
-    cdef gkPhysicsController *pc
     cdef bool s
+    cdef CollisionSensor e
     
-    e = collision_callbacks
+    e = collision_callbacks.next_non_empty()
     while e != None:
-        pc = <gkPhysicsController*>e.misc
-        if pc:
-            s = pc.sensorCollides(e.data._prop[0], to_stdstring(""), False, False, <gkGameObjectArray*>e.misc2)
+        if e.pc:
+            s = e.pc.sensorCollides(e.prop[0], to_stdstring(""), False, False, <gkGameObjectArray*>e.objlist)
             if not e.prevstate and s:
                 e.execute()
             e.prevstate = s
         Quaternion& div "operator/"(Quaternion)
         Vector3 mul "operator*"(Vector3)
         Real *ptr()
+    Quaternion quat_nlerp "Ogre::Quaternion::nlerp"(Real fT, Quaternion &rkP, Quaternion &rkQ, bool shortestPath)
+    Quaternion quat_Slerp "Ogre::Quaternion::Slerp"(Real fT, Quaternion &rkP, Quaternion &rkQ, bool shortestPath)
+    Quaternion quat_SlerpExtraSpins "Ogre::Quaternion::SlerpExtraSpins"(Real fT, Quaternion &rkP, Quaternion &rkQ, int iExtraSpins)
         
     cppclass Matrix3:
         Vector3 mCol0
 class WrongInputError(BaseException):
     pass
 
-cdef Event press_callbacks = Event()
-cdef Event release_callbacks = Event()
-cdef Event mouse_move_callbacks = Event()
-cdef Event mbpress_callbacks = Event()
-cdef Event mbrelease_callbacks = Event()
+cdef Sensor key_callbacks = Sensor()
+cdef Sensor mouse_move_callbacks = Sensor()
+cdef Sensor mousebutton_callbacks = Sensor()
 cdef int previous_keys[256] #TODO: use KC_MAX
 cdef int previous_mb[3]
 cdef gkVector2 prev_mouse
 prev_mouse.x = -1
 
-cdef class Key:
+cdef class Key(Sensor):
     
     cdef int *key
-    cdef Event _press, _release
+    cdef int keynum
     
     def __init__(self, keyname):
         cdef int keycode
         except ValueError:
             raise WrongInputError('Key name not in '+str(KEYS))
         self.key = getKeyboard().keys + keycode
-        self._press = Event()
-        self._press.data._key = keycode
-        self._release = Event()
-        self._release.data._key = keycode
+        self.keynum = keycode
+        self.callback_list = key_callbacks
         
     def __nonzero__(self):
         return self.key[0] == 1
-        
-    property onPress:
-        
-        def __get__(self):
-            self._press.check_add_to_list(press_callbacks)
-            return self._press
-            
-        def __set__(self, func):
-            self._press.check_add_to_list(press_callbacks)
-            del(self._press[:])
-            self._press += func
-            
-    property onRelease:
-        
-        def __get__(self):
-            self._release.check_add_to_list(release_callbacks)
-            return self._release
-            
-        def __set__(self, func):
-            self._release.check_add_to_list(release_callbacks)
-            del(self._release[:])
-            self._release += func
 
     def __str__(self):
         if self.but[0] == 1: return "<Key Pressed>"
         else: return "<Key>"
 
-cdef class MouseButton:
+cdef class MouseButton(Sensor):
     
     cdef int *but
-    cdef Event _press, _release
+    cdef int butnum
     
     def __init__(self, button):
         if not 1<=button<=3:
             raise WrongInputError('Button must be between 1 and 3.')
         
         self.but = &getMouse().buttons[button-1]
-        self._press = Event()
-        self._press.data._key = button
-        self._release = Event()
-        self._release.data._key = button
+        self.butnum = button
+        self.callback_list = mousebutton_callbacks
     
     def __nonzero__(self):
         return self.but[0] == 1
 
-    property onPress:
-        
-        def __get__(self):
-            self._press.check_add_to_list(mbpress_callbacks)
-            return self._press
-            
-        def __set__(self, func):
-            self._press.check_add_to_list(mbpress_callbacks)
-            del(self._press[:])
-            self._press += func
-            
-    property onRelease:
-        
-        def __get__(self):
-            self._release.check_add_to_list(mbrelease_callbacks)
-            return self._release
-            
-        def __set__(self, func):
-            self._release.check_add_to_list(mbrelease_callbacks)
-            del(self._release[:])
-            self._release += func
-
     def __str__(self):
         if self.but[0] == 1: return "<MouseButton Pressed>"
         else: return "<MouseButton>"
 cdef class Keyboard:
     
     cdef gkKeyboard *keybd
-    cdef Key prueba
     
     def __init__(self):
         self.keybd = getKeyboard()
     def getKey(self, code):
         return self.keybd.keys[code] == 1
         
-cdef class Mouse:
+cdef class MouseMotion(Sensor):
     
     cdef gkMouse *mouse
-    cdef Event _move
+    cdef int butnum
     
-    def __init__(self):
+    def __init__(self, butnum=-1):
         self.mouse = getMouse()
-        self._move = Event()
-        self._move.data._key = -1
+        self.butnum = butnum
+        self.callback_list = mouse_move_callbacks
         
     @property
     def position(self):
         
     def mouseMoved(self):
         return self.mouse.mouseMoved()
-
-    property onMouseMove:
-        
-        def __get__(self):
-            self._move.check_add_to_list(mouse_move_callbacks)
-            return self._move
-            
-        def __set__(self, func):
-            self._move.check_add_to_list(mouse_move_callbacks)
-            del(self._move[:])
-            self._move += func
            
 cdef class Accelerometer:
     cdef Vector v
     global prev_mouse
     cdef int k, *keys = getKeyboard().keys
     cdef gkVector2 pos = getMouse().getPosition(), rel
-    cdef Event e
-    cdef int *mousebuttons = getMouse().buttons
+    cdef Sensor e
+    cdef int *mousebuttons = getMouse().buttons, b
     
-    e = press_callbacks
+    e = key_callbacks.next_non_empty()
     while e != None:
-        k = e.data._key
-        if keys[k] == 1 and previous_keys[k] != 1:
-            e.execute()
-        e = e.next_non_empty()
-
-    e = release_callbacks
-    while e != None:
-        k = e.data._key
-        if keys[k] != 1 and previous_keys[k] == 1:
+        k = (<Key>e).keynum
+        if keys[k] != previous_keys[k]:
             e.execute()
         e = e.next_non_empty()
 
         rel.y = pos.y - prev_mouse.y
         
     if not rel.isZeroLength():
-        e = mouse_move_callbacks
+        e = mouse_move_callbacks.next_non_empty()
+        print 1
         while e != None:
-            if e.data._key==-1 or mousebuttons[e.data._key]:
-                e.data._rel[0] = rel
+            print 2
+            b = (<MouseMotion>e).butnum
+            if 1 or b==-1 or mousebuttons[b]:
+                print 3
                 e.execute()
             e = e.next_non_empty()
     
     prev_mouse = pos
     
-    e = mbpress_callbacks
+    e = mousebutton_callbacks.next_non_empty()
     while e != None:
-        k = e.data._key-1
-        if mousebuttons[k] == 1 and previous_mb[k] != 1:
-            e.execute()
-        e = e.next_non_empty()
-
-    e = mbrelease_callbacks
-    while e != None:
-        k = e.data._key-1
-        if mousebuttons[k] == 1 and previous_mb[k] != 1:
+        k = (<MouseButton>e).butnum
+        if mousebuttons[k] != previous_mb[k]:
             e.execute()
         e = e.next_non_empty()
         
         self.q.x=-(self.q.x)
         self.q.y=-(self.q.y)
         self.q.z=-(self.q.z)
+        
+    def lerp(self, Quaternion other, factor):
+        cdef Quaternion q = Quaternion()
+        q.q.assign(gkmath.quat_nlerp(factor, self.q[0], other.q[0], False))
+        
+    def slerp(self, Quaternion other, factor):
+        cdef Quaternion q = Quaternion()
+        q.q.assign(gkmath.quat_Slerp(factor, self.q[0], other.q[0], False))
+        
     def lerp(Vector self, other, factor):
         factor = max(0.0,min(factor,1.0))
         invf = 1.0-factor
-        return Vector(self.x*invf + other[0]*asfasdf,
-                      self.y*invf + other[1]*asfasdf,
-                      self.z*invf + other[2]*asfasdf)
+        return Vector(self.x*invf + other[0]*factor,
+                      self.y*invf + other[1]*factor,
+                      self.z*invf + other[2]*factor)
         
     #cdef assignv(Vector self, gkmath.Vector3 v):
     #    memcpy((<gkmath.Vector3*>self.v).ptr(),v.ptr(),sizeof(Real)*3)
         self.q.x=-(self.q.x)
         self.q.y=-(self.q.y)
         self.q.z=-(self.q.z)
+        
+    def lerp(self, Quaternion other, factor):
+        cdef Quaternion q = Quaternion()
+        q.q.assign(gkmath.Quaternion_nlerp(factor, (<Quaternion>self).q[0], other.q[0], False))
+        
+    def slerp(self, Quaternion other, factor):
+        cdef Quaternion q = Quaternion()
+        q.q.assign(gkmath.Quaternion_Slerp(factor, (<Quaternion>self).q[0], other.q[0], False))
+        
+
+from gameobject cimport *
+cimport gkmath
+
+cdef extern from "OgreSceneManager.h":
+    cdef cppclass Ogre_SceneManager "Ogre::SceneManager":
+        void setShadowTextureSelfShadow(bool)
+        void setShadowCasterRenderBackFaces(bool)
+        void setShadowTextureSize(int)
+        void setShadowFarDistance(Real)
+
+cdef enum UPDATE_FLAGS:
+    UF_NONE                 = 0
+    UF_PHYSICS              = 1 << 0
+    UF_LOGIC_BRICKS = 1 << 1
+    UF_NODE_TREES   = 1 << 2
+    UF_ANIMATIONS   = 1 << 3
+    UF_SOUNDS               = 1 << 4
+    UF_DBVT                 = 1 << 5
+    UF_DEBUG                = 1 << 6
+    UF_ALL                  = 0xFFFFFFFF
+                
+cdef extern from "gkScene.h":
+    
+    cdef cppclass gkScene:
+        
+        gkCamera*     getMainCamera()
+        bool          hasDefaultCamera()
+        bool          hasCameras()
+        #gkCameraSet&  getCameras(void)
+        void setMainCamera(gkCamera*)
+        
+        void update(Real tickRate)
+        void beginFrame()
+        void setHorizonColor(gkColor&)
+        void setAmbientColor(gkColor&)
+        void setGravity(gkmath.Vector3)
+        
+        void createInstance()
+        
+        void addObject(gkGameObject* obj)
+        void removeObject(gkGameObject* obj)
+        void destroyObject(gkGameObject* obj)
+        
+        gkGameObject* cloneObject(gkGameObject* obj, int lifeSpan, bool instantiate)
+        
+        gkGameObject* getObject(const_std_string& name)
+        gkGameObjectHashMap getObjects()
+        
+        Ogre_SceneManager* getManager()
+        
+        gkDynamicsWorld* getDynamicsWorld()
+
+        int getUpdateFlags()
+        void setUpdateFlags(int)
+        
+#cdef extern from "gkDynamicsWorld.h":
+    #cppclass gkDynamicsWorld:
+        #btDynamicsWorld* getBulletWorld()
+        
+    #cppclass btDynamicsWorld:
+        #pass
     
 
 cdef class Scene(pywrap):
+
+    cdef public TickSensor tickSensor
+    
+    def __init__(self):
+        self.tickSensor = TickSensor()
     
     def setGravity(self,g):
         (<gkScene *>self._p).setGravity(Vector(g).v[0])
+
+from scene cimport *
+from gameobject cimport *
+    
+cdef enum:
+        OBJ_CAMERA  = 1 << 0
+        OBJ_LIGHT   = 1 << 1
+        OBJ_ENTITY  = 1 << 2
+        OBJ_OBJECT  = 1 << 3
+        OBJ_SKELETON = 1 << 4
+
+cdef extern from "gkSceneManager.h":
+    
+    cdef gkScene* createEmptyScene "gkSceneManager::getSingleton().createEmptyScene"(
+                                    const_std_string& sceneName, const_std_string& cameraName = "", const_std_string& group="")
+    cdef gkScene* copyObjects "gkSceneManager::getSingleton().copyObjects"(gkScene* fromScene, gkScene* toScene, int exceptObjectTypes)
+    
+    
+
+cdef class Scene(pywrap):
+
+    cdef public TickSensor tickSensor = None
+    
+    def __init__(self):
+        self.tickSensor = TickSensor()
+    
+    def setGravity(self,g):
+        (<gkScene *>self._p).setGravity(Vector(g).v[0])
+    
+    def getMainCamera(self):
+        
+        return Camera().P((<gkScene *>self._p).getMainCamera())
+    
+    #TODO: make sure you pass one of the correct types
+    
+    def setMainCamera(self, GameObject cam):
+        (<gkScene *>self._p).setMainCamera(<gkCamera *>cam._p)
+        
+    def addObject(self, GameObject ob):
+        (<gkScene *>self._p).addObject(<gkGameObject *>ob._p)
+        
+    def removeObject(self, GameObject ob):
+        (<gkScene *>self._p).removeObject(<gkGameObject *>ob._p)
+        
+    def destroyObject(self, GameObject ob):
+        (<gkScene *>self._p).destroyObject(<gkGameObject *>ob._p)
+        
+    def cloneObject(self, GameObject ob, lifeSpan=0, instantiate=False):
+        cdef gkGameObject* o = <gkGameObject *>ob._p
+        o = (<gkScene *>self._p).cloneObject(o, lifeSpan, instantiate)
+        return GameObject().P(o)
+
+    @property
+    def objects(self):
+        return GameObjectList().P(self._p)
+        
+    def suspendDynamics(Scene self):
+        (<gkScene *>self._p).setUpdateFlags((<gkScene *>self._p).getUpdateFlags()&~UF_PHYSICS)
+        
+    def resumeDynamics(Scene self):
+        (<gkScene *>self._p).setUpdateFlags((<gkScene *>self._p).getUpdateFlags()|UF_PHYSICS)
+        
+    def setShadowTextureSelfShadow(self,b):
+        (<gkScene *>self._p).getManager().setShadowTextureSelfShadow(b)
+        
+    def setShadowCasterRenderBackFaces(self,b):
+        (<gkScene *>self._p).getManager().setShadowCasterRenderBackFaces(b)
+        
+    def setShadowTextureSize(self,size):
+        (<gkScene *>self._p).getManager().setShadowTextureSize(size)
+        
+    def setShadowFarDistance(self,d):
+        (<gkScene *>self._p).getManager().setShadowFarDistance(d)
+        
+    
+    #def __init__(self, sceneName = "", cameraName = "", group = ""):
+        
+        #self.scn = create(to_stdstring(sceneName), to_stdstring(cameraName), to_stdstring(group))
+        #self.scn.setHorizonColor(gkColor(0.2,0.2,0.2))
+        #self.scn.setAmbientColor(gkColor(0.5,0.5,0.5))
+        
+    #cdef __init__(self, gkScene* scn):
+        #self.scn = scn
+        #self.objects = GameObjectList()
+        #self.objects.scn = scn
+        #self.objects.hashmap = scn.getObjects()
+        
   PySys_SetArgvEx(argc, argv, 0);
 
   PyRun_SimpleString(
-    "SELFBINSIZE=0                \n"
     "import gamekit, sys\n"
     "print sys.argv\n"
-    "bname = sys.argv[0].rstrip('.EXE').rstrip('.exe')+'.blend'\n"
-    "nextiscfg = False\n"
+    "bname = sys.argv[0]\n"
+    "ext = bname.split('.')[-1].lower()\n"
+    "if ext in ('exe', 'bin', 'bin32', 'bin64'):\n"
+    "    bname = bname[:-len(ext)-1]\n"
+    "bname += '.blend'\n"
+    "p = ''\n"
     "cfgfile = None\n"
     "for a in sys.argv[1:]:\n"
-    "    if nextiscfg:\n"
-    "        cfgfile, nextiscfg = a, False\n"
-    "    elif a=='-c':\n"
-    "        nextiscfg = True\n"
-    "    elif a.startswith('-c'):\n"
-    "        cfgfile = a[2:]\n"
+    "    if p:\n"
+    "        if p=='-c':\n"
+    "            cfgfile = a\n"
+    "        elif p=='--pythonpath':\n"
+    "            sys.path.append(a)\n"
+    "        elif p=='--':\n"
+    "            bname = a\n"
+    "        else:\n"
+    "            print('Unrecognized option %s'%p)\n"
+    "        p = ''\n"
     "    else:\n"
-    "        bname = a\n"
+    "        if a.startswith('-'):\n"
+    "            p = a\n"
+    "        else:\n"
+    "            bname = a\n"
     "e = gamekit.Engine(bname,cfgfile)\n"
-    "if gamekit.hasTextBlock('init.py'):\n"
+    "try:\n"
     "    import init\n"
+    "except ImportError:\n"
+    "    print('Error: Can\\'t import init.py')\n"
     "e.run()\n"
   );
 
Binary file modified.