summary refs log tree commit diff stats
path: root/tests/manyloc/keineschweine/dependencies
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2013-04-13 21:55:02 +0200
committerAraq <rumpf_a@web.de>2013-04-13 21:55:02 +0200
commit75b508032b9da285f30d4ec7f2af4c63075b8611 (patch)
tree79476c0e8b7c70ee373bde21a2ea0a62d84520f8 /tests/manyloc/keineschweine/dependencies
parent4f09794be9fb9b96728078712f01e990e0021929 (diff)
downloadNim-75b508032b9da285f30d4ec7f2af4c63075b8611.tar.gz
added manyloc test suite; --path now relative to project dir if not absolute
Diffstat (limited to 'tests/manyloc/keineschweine/dependencies')
-rw-r--r--tests/manyloc/keineschweine/dependencies/chipmunk/chipmunk.nim1516
-rw-r--r--tests/manyloc/keineschweine/dependencies/enet/enet.nim614
-rw-r--r--tests/manyloc/keineschweine/dependencies/enet/testclient.nim49
-rw-r--r--tests/manyloc/keineschweine/dependencies/enet/testserver.nim45
-rw-r--r--tests/manyloc/keineschweine/dependencies/genpacket/genpacket.nim295
-rw-r--r--tests/manyloc/keineschweine/dependencies/genpacket/genpacket_enet.nim296
-rw-r--r--tests/manyloc/keineschweine/dependencies/genpacket/macro_dsl.nim73
-rw-r--r--tests/manyloc/keineschweine/dependencies/genpacket/streams_enh.nim47
-rw-r--r--tests/manyloc/keineschweine/dependencies/nake/nake.nim83
-rw-r--r--tests/manyloc/keineschweine/dependencies/nake/nakefile.nim23
-rw-r--r--tests/manyloc/keineschweine/dependencies/sfml/README.md13
-rw-r--r--tests/manyloc/keineschweine/dependencies/sfml/sfml.nim1115
-rw-r--r--tests/manyloc/keineschweine/dependencies/sfml/sfml_audio.nim899
-rw-r--r--tests/manyloc/keineschweine/dependencies/sfml/sfml_colors.nim15
-rw-r--r--tests/manyloc/keineschweine/dependencies/sfml/sfml_vector.nim2
15 files changed, 5085 insertions, 0 deletions
diff --git a/tests/manyloc/keineschweine/dependencies/chipmunk/chipmunk.nim b/tests/manyloc/keineschweine/dependencies/chipmunk/chipmunk.nim
new file mode 100644
index 000000000..8226b0b04
--- /dev/null
+++ b/tests/manyloc/keineschweine/dependencies/chipmunk/chipmunk.nim
@@ -0,0 +1,1516 @@
+# Copyright (c) 2007 Scott Lembcke
+#  
+#  Permission is hereby granted, free of charge, to any person obtaining a copy
+#  of this software and associated documentation files (the "Software"), to deal
+#  in the Software without restriction, including without limitation the rights
+#  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+#  copies of the Software, and to permit persons to whom the Software is
+#  furnished to do so, subject to the following conditions:
+#  
+#  The above copyright notice and this permission notice shall be included in
+#  all copies or substantial portions of the Software.
+#  
+#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+#  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+#  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+#  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+#  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+#  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+#  SOFTWARE.
+# 
+when defined(Linux):
+  const Lib = "libchipmunk.so.6.1.1"
+else:
+  {.error: "Platform unsupported".}
+when defined(MoreNimrod):
+  {.hint: "MoreNimrod defined; some Chipmunk functions replaced in Nimrod".}
+{.deadCodeElim: on.}
+from math import sqrt, sin, cos, arctan2
+when defined(CpUseFloat):
+  {.hint: "CpUseFloat defined; using float32 as float".}
+  type CpFloat* = cfloat
+else:
+  type CpFloat* = cdouble
+const 
+  CP_BUFFER_BYTES* = (32 * 1024)  
+  CP_MAX_CONTACTS_PER_ARBITER* = 4
+  CpInfinity*: CpFloat = 1.0/0
+{.pragma: pf, pure, final.}
+type 
+  Bool32* = cint  #replace one day with cint-compatible bool
+  CpDataPointer* = pointer
+  TVector* {.final, pure.} = object
+    x*, y*: CpFloat
+  TTimestamp* = cuint
+  TBodyVelocityFunc* = proc(body: PBody, gravity: TVector,
+                            damping: CpFloat; dt: CpFloat){.cdecl.}
+  TBodyPositionFunc* = proc(body: PBody; dt: CpFloat){.cdecl.}
+  TComponentNode*{.pf.} = object 
+    root*: PBody
+    next*: PBody
+    idleTime*: CpFloat
+  
+  THashValue = cuint  # uintptr_t 
+  TCollisionType* = cuint #uintptr_t
+  TGroup * = cuint #uintptr_t
+  TLayers* = cuint
+  PArray = ptr TArray
+  TArray{.pure,final.} = object
+  PHashSet = ptr THashSet
+  THashSet{.pf.} = object
+  PContact* = ptr TContact
+  TContact*{.pure,final.} = object
+  PArbiter* = ptr TArbiter
+  TArbiter*{.pf.} = object 
+    e*: CpFloat
+    u*: CpFloat 
+    surface_vr*: TVector
+    a*: PShape
+    b*: PShape
+    body_a*: PBody
+    body_b*: PBody
+    thread_a*: TArbiterThread
+    thread_b*: TArbiterThread
+    numContacts*: cint
+    contacts*: PContact
+    stamp*: TTimestamp
+    handler*: PCollisionHandler
+    swappedColl*: bool32
+    state*: TArbiterState
+  PCollisionHandler* = ptr TCollisionHandler
+  TCollisionHandler*{.pf.} = object 
+    a*: TCollisionType
+    b*: TCollisionType
+    begin*: TCollisionBeginFunc
+    preSolve*: TCollisionPreSolveFunc
+    postSolve*: TCollisionPostSolveFunc
+    separate*: TCollisionSeparateFunc
+    data*: pointer
+  TArbiterState*{.size: sizeof(cint).} = enum 
+    ArbiterStateFirstColl,    # Arbiter is active and its not the first collision.
+    ArbiterStateNormal,       # Collision has been explicitly ignored.
+                              # Either by returning false from a begin collision handler or calling cpArbiterIgnore().
+    ArbiterStateIgnore,       # Collison is no longer active. A space will cache an arbiter for up to cpSpace.collisionPersistence more steps.
+    ArbiterStateCached
+  TArbiterThread*{.pf.} = object 
+    next*: PArbiter        # Links to next and previous arbiters in the contact graph.
+    prev*: PArbiter
+  
+  TContactPoint*{.pf.} = object 
+    point*: TVector    #/ The position of the contact point.
+    normal*: TVector   #/ The normal of the contact point.
+    dist*: CpFloat     #/ The depth of the contact point.
+  #/ A struct that wraps up the important collision data for an arbiter.
+  PContactPointSet* = ptr TContactPointSet
+  TContactPointSet*{.pf.} = object 
+    count*: cint              #/ The number of contact points in the set.
+    points*: array[0..CP_MAX_CONTACTS_PER_ARBITER - 1, TContactPoint] #/ The array of contact points.
+  
+  #/ Collision begin event function callback type.
+  #/ Returning false from a begin callback causes the collision to be ignored until
+  #/ the the separate callback is called when the objects stop colliding.
+  TCollisionBeginFunc* = proc (arb: PArbiter; space: PSpace; data: pointer): Bool{.
+      cdecl.}
+  #/ Collision pre-solve event function callback type.
+  #/ Returning false from a pre-step callback causes the collision to be ignored until the next step.
+  TCollisionPreSolveFunc* = proc (arb: PArbiter; space: PSpace; 
+                                  data: pointer): bool {.cdecl.}
+  #/ Collision post-solve event function callback type.
+  TCollisionPostSolveFunc* = proc (arb: PArbiter; space: PSpace; 
+                                   data: pointer){.cdecl.}
+  #/ Collision separate event function callback type.
+  TCollisionSeparateFunc* = proc (arb: PArbiter; space: PSpace; 
+                                  data: pointer){.cdecl.}
+  
+  #/ Chipmunk's axis-aligned 2D bounding box type. (left, bottom, right, top)
+  PBB* = ptr TBB
+  TBB* {.pf.} = object 
+    l*, b*, r*, t*: CpFloat
+  
+  #/ Spatial index bounding box callback function type.
+  #/ The spatial index calls this function and passes you a pointer to an object you added
+  #/ when it needs to get the bounding box associated with that object.
+  TSpatialIndexBBFunc* = proc (obj: pointer): TBB{.cdecl.}
+  #/ Spatial index/object iterator callback function type.
+  TSpatialIndexIteratorFunc* = proc (obj: pointer; data: pointer){.cdecl.}
+  #/ Spatial query callback function type. 
+  TSpatialIndexQueryFunc* = proc (obj1: pointer; obj2: pointer; data: pointer){.
+      cdecl.}
+  #/ Spatial segment query callback function type.
+  TSpatialIndexSegmentQueryFunc* = proc (obj1: pointer; obj2: pointer; 
+      data: pointer): CpFloat {.cdecl.}
+  #/ private
+  PSpatialIndex = ptr TSpatialIndex
+  TSpatialIndex{.pf.} = object 
+    klass: PSpatialIndexClass
+    bbfunc: TSpatialIndexBBFunc
+    staticIndex: PSpatialIndex
+    dynamicIndex: PSpatialIndex
+
+  TSpatialIndexDestroyImpl* = proc (index: PSpatialIndex){.cdecl.}
+  TSpatialIndexCountImpl* = proc (index: PSpatialIndex): cint{.cdecl.}
+  TSpatialIndexEachImpl* = proc (index: PSpatialIndex; 
+                                 func: TSpatialIndexIteratorFunc; data: pointer){.
+      cdecl.}
+  TSpatialIndexContainsImpl* = proc (index: PSpatialIndex; obj: pointer; 
+                                     hashid: THashValue): Bool32 {.cdecl.}
+  TSpatialIndexInsertImpl* = proc (index: PSpatialIndex; obj: pointer; 
+                                   hashid: THashValue){.cdecl.}
+  TSpatialIndexRemoveImpl* = proc (index: PSpatialIndex; obj: pointer; 
+                                   hashid: THashValue){.cdecl.}
+  TSpatialIndexReindexImpl* = proc (index: PSpatialIndex){.cdecl.}
+  TSpatialIndexReindexObjectImpl* = proc (index: PSpatialIndex; 
+      obj: pointer; hashid: THashValue){.cdecl.}
+  TSpatialIndexReindexQueryImpl* = proc (index: PSpatialIndex; 
+      func: TSpatialIndexQueryFunc; data: pointer){.cdecl.}
+  TSpatialIndexPointQueryImpl* = proc (index: PSpatialIndex; point: TVector; 
+                                       func: TSpatialIndexQueryFunc; 
+                                       data: pointer){.cdecl.}
+  TSpatialIndexSegmentQueryImpl* = proc (index: PSpatialIndex; obj: pointer; 
+      a: TVector; b: TVector; t_exit: CpFloat; func: TSpatialIndexSegmentQueryFunc; 
+      data: pointer){.cdecl.}
+  TSpatialIndexQueryImpl* = proc (index: PSpatialIndex; obj: pointer; 
+                                  bb: TBB; func: TSpatialIndexQueryFunc; 
+                                  data: pointer){.cdecl.}
+  PSpatialIndexClass* = ptr TSpatialIndexClass
+  TSpatialIndexClass*{.pf.} = object 
+    destroy*: TSpatialIndexDestroyImpl
+    count*: TSpatialIndexCountImpl
+    each*: TSpatialIndexEachImpl
+    contains*: TSpatialIndexContainsImpl
+    insert*: TSpatialIndexInsertImpl
+    remove*: TSpatialIndexRemoveImpl
+    reindex*: TSpatialIndexReindexImpl
+    reindexObject*: TSpatialIndexReindexObjectImpl
+    reindexQuery*: TSpatialIndexReindexQueryImpl
+    pointQuery*: TSpatialIndexPointQueryImpl
+    segmentQuery*: TSpatialIndexSegmentQueryImpl
+    query*: TSpatialIndexQueryImpl
+  
+  PSpaceHash* = ptr TSpaceHash
+  TSpaceHash* {.pf.} = object
+  PBBTree* = ptr TBBTree
+  TBBTree* {.pf.} = object
+  PSweep1D* = ptr TSweep1D
+  TSweep1D* {.pf.} = object
+  
+  #/ Bounding box tree velocity callback function.
+  #/ This function should return an estimate for the object's velocity.
+  TBBTreeVelocityFunc* = proc (obj: pointer): TVector {.cdecl.}
+  
+  PContactBufferHeader* = ptr TContentBufferHeader
+  TContentBufferHeader* {.pf.} = object
+  TSpaceArbiterApplyImpulseFunc* = proc (arb: PArbiter){.cdecl.}
+  
+  PSpace* = ptr TSpace
+  TSpace* {.pf.} = object
+    iterations*: cint 
+    gravity*: TVector
+    damping*: CpFloat
+    idleSpeedThreshold*: CpFloat 
+    sleepTimeThreshold*: CpFloat 
+    collisionSlop*: CpFloat 
+    collisionBias*: CpFloat
+    collisionPersistence*: TTimestamp        
+    enableContactGraph*: cint ##BOOL
+    data*: pointer
+    staticBody*: PBody
+    stamp: TTimestamp
+    currDT: CpFloat
+    bodies: PArray
+    rousedBodies: PArray
+    sleepingComponents: PArray
+    staticShapes: PSpatialIndex
+    activeShapes: PSpatialIndex
+    arbiters: PArray
+    contactBuffersHead: PContactBufferHeader
+    cachedArbiters: PHashSet
+    pooledArbiters: PArray
+    constraints: PArray
+    allocatedBuffers: PArray
+    locked: cint
+    collisionHandlers: PHashSet
+    defaultHandler: TCollisionHandler
+    postStepCallbacks: PHashSet
+    arbiterApplyImpulse: TSpaceArbiterApplyImpulseFunc
+    staticBody2: TBody  #_staticBody 
+  PBody* = ptr TBody
+  TBody*{.pf.} = object 
+    velocityFunc*: TBodyVelocityFunc 
+    positionFunc*: TBodyPositionFunc                                       
+    m*: CpFloat           
+    mInv*: CpFloat       
+    i*: CpFloat           
+    iInv*: CpFloat       
+    p*: TVector            
+    v*: TVector            
+    f*: TVector 
+    a*: CpFloat 
+    w*: CpFloat 
+    t*: CpFloat 
+    rot*: TVector 
+    data*: pointer
+    vLimit*: CpFloat   
+    wLimit*: CpFloat
+    vBias*: TVector
+    wBias*: CpFloat
+    space*: PSpace
+    shapeList*: PShape
+    arbiterList*: PArbiter
+    constraintList*: PConstraint
+    node*: TComponentNode
+  #/ Body/shape iterator callback function type. 
+  TBodyShapeIteratorFunc* = proc (body: PBody; shape: PShape; 
+                                   data: pointer) {.cdecl.}
+  #/ Body/constraint iterator callback function type. 
+  TBodyConstraintIteratorFunc* = proc (body: PBody; 
+                                        constraint: PConstraint; 
+                                        data: pointer) {.cdecl.}
+  #/ Body/arbiter iterator callback function type. 
+  TBodyArbiterIteratorFunc* = proc (body: PBody; arbiter: PArbiter; 
+                                     data: pointer) {.cdecl.}
+  
+  PNearestPointQueryInfo* = ptr TNearestPointQueryInfo
+  #/ Nearest point query info struct.
+  TNearestPointQueryInfo*{.pf.} = object
+    shape: PShape  #/ The nearest shape, NULL if no shape was within range.
+    p: TVector     #/ The closest point on the shape's surface. (in world space coordinates)
+    d: CpFloat      #/ The distance to the point. The distance is negative if the point is inside the shape.
+  
+  PSegmentQueryInfo* = ptr TSegmentQueryInfo
+  #/ Segment query info struct.
+  TSegmentQueryInfo*{.pf.} = object 
+    shape*: PShape         #/ The shape that was hit, NULL if no collision occured.
+    t*: CpFloat            #/ The normalized distance along the query segment in the range [0, 1].
+    n*: TVector            #/ The normal of the surface hit.
+  TShapeType*{.size: sizeof(cint).} = enum 
+    CP_CIRCLE_SHAPE, CP_SEGMENT_SHAPE, CP_POLY_SHAPE, CP_NUM_SHAPES
+  TShapeCacheDataImpl* = proc (shape: PShape; p: TVector; rot: TVector): TBB{.cdecl.}
+  TShapeDestroyImpl* = proc (shape: PShape){.cdecl.}
+  TShapePointQueryImpl* = proc (shape: PShape; p: TVector): bool32 {.cdecl.}
+  TShapeSegmentQueryImpl* = proc (shape: PShape; a: TVector; b: TVector; 
+                                  info: PSegmentQueryInfo){.cdecl.}
+  PShapeClass* = ptr TShapeClass
+  TShapeClass*{.pf.} = object 
+    kind*: TShapeType
+    cacheData*: TShapeCacheDataImpl
+    destroy*: TShapeDestroyImpl
+    pointQuery*: TShapePointQueryImpl
+    segmentQuery*: TShapeSegmentQueryImpl
+  PShape* = ptr TShape
+  TShape*{.pf.} = object 
+    klass: PShapeClass   #/ PRIVATE
+    body*: PBody           #/ The rigid body this collision shape is attached to.
+    bb*: TBB               #/ The current bounding box of the shape.   
+    sensor*: Bool32        #/ Sensor flag.
+                           #/ Sensor shapes call collision callbacks but don't produce collisions.  
+    e*: CpFloat            #/ Coefficient of restitution. (elasticity)
+    u*: CpFloat            #/ Coefficient of friction.
+    surface_v*: TVector    #/ Surface velocity used when solving for friction.
+    data*: pointer        #/ User definable data pointer. Generally this points to your the game object class so you can access it when given a cpShape reference in a callback.
+    collision_type*: TCollisionType #/ Collision type of this shape used when picking collision handlers.
+    group*: TGroup      #/ Group of this shape. Shapes in the same group don't collide.
+    layers*: TLayers   #/ Layer bitmask for this shape. Shapes only collide if the bitwise and of their layers is non-zero.
+    space: PSpace        #PRIVATE
+    next: PShape         #PRIVATE
+    prev: PShape         #PRIVATE
+    hashid: THashValue  #PRIVATE
+  PCircleShape* = ptr TCircleShape
+  TCircleShape*{.pf.} = object
+    shape: PShape
+    c, tc: TVector
+    r: CpFloat
+  PPolyShape* = ptr TPolyShape
+  TPolyShape*{.pf.} = object
+    shape: PShape
+    numVerts: cint
+    verts, tVerts: TVector
+    planes, tPlanes: PSplittingPlane
+  PSegmentShape* = ptr TSegmentShape
+  TSegmentShape*{.pf.} = object
+    shape: PShape
+    a, b, n: TVector
+    ta, tb, tn: TVector
+    r: CpFloat
+    aTangent, bTangent: TVector
+  PSplittingPlane* = ptr TSplittingPlane
+  TSplittingPlane*{.pf.} = object
+    n: TVector
+    d: CpFloat
+  
+  #/ Post Step callback function type.
+  TPostStepFunc* = proc (space: PSpace; obj: pointer; data: pointer){.cdecl.}
+  #/ Point query callback function type.
+  TSpacePointQueryFunc* = proc (shape: PShape; data: pointer){.cdecl.}
+  #/ Segment query callback function type.
+  TSpaceSegmentQueryFunc* = proc (shape: PShape; t: CpFloat; n: TVector; 
+                                  data: pointer){.cdecl.}
+  #/ Rectangle Query callback function type.
+  TSpaceBBQueryFunc* = proc (shape: PShape; data: pointer){.cdecl.}
+  #/ Shape query callback function type.
+  TSpaceShapeQueryFunc* = proc (shape: PShape; points: PContactPointSet; 
+                                data: pointer){.cdecl.}
+  #/ Space/body iterator callback function type.
+  TSpaceBodyIteratorFunc* = proc (body: PBody; data: pointer){.cdecl.}
+  #/ Space/body iterator callback function type.
+  TSpaceShapeIteratorFunc* = proc (shape: PShape; data: pointer){.cdecl.}
+  #/ Space/constraint iterator callback function type.
+  TSpaceConstraintIteratorFunc* = proc (constraint: PConstraint; 
+                                        data: pointer){.cdecl.}
+  #/ Opaque cpConstraint struct.
+  PConstraint* = ptr TConstraint
+  TConstraint*{.pf.} = object 
+    klass: PConstraintClass #/PRIVATE
+    a*: PBody            #/ The first body connected to this constraint.
+    b*: PBody              #/ The second body connected to this constraint.
+    space: PSpace         #/PRIVATE
+    next_a: PConstraint  #/PRIVATE
+    next_b: PConstraint #/PRIVATE
+    maxForce*: CpFloat  #/ The maximum force that this constraint is allowed to use. Defaults to infinity.
+    errorBias*: CpFloat #/ The rate at which joint error is corrected. Defaults to pow(1.0 - 0.1, 60.0) meaning that it will correct 10% of the error every 1/60th of a second.
+    maxBias*: CpFloat    #/ The maximum rate at which joint error is corrected. Defaults to infinity.       
+    preSolve*: TConstraintPreSolveFunc  #/ Function called before the solver runs. Animate your joint anchors, update your motor torque, etc.
+    postSolve*: TConstraintPostSolveFunc #/ Function called after the solver runs. Use the applied impulse to perform effects like breakable joints.
+    data*: CpDataPointer  # User definable data pointer. Generally this points to your the game object class so you can access it when given a cpConstraint reference in a callback.
+  TConstraintPreStepImpl = proc (constraint: PConstraint; dt: CpFloat){.cdecl.}
+  TConstraintApplyCachedImpulseImpl = proc (constraint: PConstraint; dt_coef: CpFloat){.cdecl.}
+  TConstraintApplyImpulseImpl = proc (constraint: PConstraint){.cdecl.}
+  TConstraintGetImpulseImpl = proc (constraint: PConstraint): CpFloat{.cdecl.}
+  PConstraintClass = ptr TConstraintClass
+  TConstraintClass{.pf.} = object 
+    preStep*: TConstraintPreStepImpl
+    applyCachedImpulse*: TConstraintApplyCachedImpulseImpl
+    applyImpulse*: TConstraintApplyImpulseImpl
+    getImpulse*: TConstraintGetImpulseImpl
+  #/ Callback function type that gets called before solving a joint.
+  TConstraintPreSolveFunc* = proc (constraint: PConstraint; space: PSpace){.
+    cdecl.}
+  #/ Callback function type that gets called after solving a joint.
+  TConstraintPostSolveFunc* = proc (constraint: PConstraint; space: PSpace){.
+    cdecl.}
+
+##cp property emulators
+template defGetter(otype: typedesc, memberType: typedesc, memberName: expr, procName: expr): stmt {.immediate.} =
+  proc `get procName`*(obj: otype): memberType {.cdecl.} =
+    return obj.memberName
+template defSetter(otype: typedesc, memberType: typedesc, memberName: expr, procName: expr): stmt {.immediate.} =
+  proc `set procName`*(obj: otype, value: memberType) {.cdecl.} =
+    obj.memberName = value
+template defProp(otype: typedesc, memberType: typedesc, memberName: expr, procName: expr): stmt {.immediate.} =
+  defGetter(otype, memberType, memberName, procName)
+  defSetter(otype, memberType, memberName, procName)
+
+
+##cpspace.h
+proc allocSpace*(): PSpace {.
+  importc: "cpSpaceAlloc", dynlib: Lib.}
+proc Init*(space: PSpace): PSpace {.
+  importc: "cpSpaceInit", dynlib: Lib.}
+proc newSpace*(): PSpace {.
+  importc: "cpSpaceNew", dynlib: Lib.}
+proc destroy*(space: PSpace) {.
+  importc: "cpSpaceDestroy", dynlib: Lib.}
+proc free*(space: PSpace) {.
+  importc: "cpSpaceFree", dynlib: Lib.}
+
+defProp(PSpace, cint, iterations, Iterations)
+defProp(PSpace, TVector, gravity, Gravity)
+defProp(PSpace, CpFloat, damping, Damping)
+defProp(PSpace, CpFloat, idleSpeedThreshold, IdleSpeedThreshold)
+defProp(PSpace, CpFloat, sleepTimeThreshold, SleepTimeThreshold)
+defProp(PSpace, CpFloat, collisionSlop, CollisionSlop)
+defProp(PSpace, CpFloat, collisionBias, CollisionBias)
+defProp(PSpace, TTimestamp, collisionPersistence, CollisionPersistence)
+defProp(PSpace, Bool32, enableContactGraph, EnableContactGraph)
+defProp(PSpace, pointer, data, UserData)
+defGetter(PSpace, PBody, staticBody, StaticBody)
+defGetter(PSpace, CpFloat, currDt, CurrentTimeStep)
+
+
+#/ returns true from inside a callback and objects cannot be added/removed.
+proc isLocked*(space: PSpace): Bool{.inline.} = 
+  result = space.locked.bool
+
+#/ Set a default collision handler for this space.
+#/ The default collision handler is invoked for each colliding pair of shapes
+#/ that isn't explicitly handled by a specific collision handler.
+#/ You can pass NULL for any function you don't want to implement.
+proc setDefaultCollisionHandler*(space: PSpace; begin: TCollisionBeginFunc; 
+                                  preSolve: TCollisionPreSolveFunc; 
+                                  postSolve: TCollisionPostSolveFunc; 
+                                  separate: TCollisionSeparateFunc; 
+                                  data: pointer){.
+  cdecl, importc: "cpSpaceSetDefaultCollisionHandler", dynlib: Lib.}
+#/ Set a collision handler to be used whenever the two shapes with the given collision types collide.
+#/ You can pass NULL for any function you don't want to implement.
+proc addCollisionHandler*(space: PSpace; a, b: TCollisionType; 
+                           begin: TCollisionBeginFunc; 
+                           preSolve: TCollisionPreSolveFunc; 
+                           postSolve: TCollisionPostSolveFunc; 
+                           separate: TCollisionSeparateFunc; data: pointer){.
+  cdecl, importc: "cpSpaceAddCollisionHandler", dynlib: Lib.}
+#/ Unset a collision handler.
+proc removeCollisionHandler*(space: PSpace; a: TCollisionType; 
+                                  b: TCollisionType){.
+  cdecl, importc: "cpSpaceRemoveCollisionHandler", dynlib: Lib.}
+#/ Add a collision shape to the simulation.
+#/ If the shape is attached to a static body, it will be added as a static shape.
+proc addShape*(space: PSpace; shape: PShape): PShape{.
+  cdecl, importc: "cpSpaceAddShape", dynlib: Lib.}
+#/ Explicity add a shape as a static shape to the simulation.
+proc addStaticShape*(space: PSpace; shape: PShape): PShape{.
+  cdecl, importc: "cpSpaceAddStaticShape", dynlib: Lib.}
+#/ Add a rigid body to the simulation.
+proc addBody*(space: PSpace; body: PBody): PBody{.
+  cdecl, importc: "cpSpaceAddBody", dynlib: Lib.}
+#/ Add a constraint to the simulation.
+proc addConstraint*(space: PSpace; constraint: PConstraint): PConstraint{.
+    cdecl, importc: "cpSpaceAddConstraint", dynlib: Lib.}
+#/ Remove a collision shape from the simulation.
+proc removeShape*(space: PSpace; shape: PShape){.
+  cdecl, importc: "cpSpaceRemoveShape", dynlib: Lib.}
+#/ Remove a collision shape added using cpSpaceAddStaticShape() from the simulation.
+proc removeStaticShape*(space: PSpace; shape: PShape){.
+  cdecl, importc: "cpSpaceRemoveStaticShape", dynlib: Lib.}
+#/ Remove a rigid body from the simulation.
+proc removeBody*(space: PSpace; body: PBody){.
+  cdecl, importc: "cpSpaceRemoveBody", dynlib: Lib.}
+#/ Remove a constraint from the simulation.
+proc RemoveConstraint*(space: PSpace; constraint: PConstraint){.
+  cdecl, importc: "cpSpaceRemoveConstraint", dynlib: Lib.}
+#/ Test if a collision shape has been added to the space.
+proc containsShape*(space: PSpace; shape: PShape): Bool{.
+  cdecl, importc: "cpSpaceContainsShape", dynlib: Lib.}
+#/ Test if a rigid body has been added to the space.
+proc containsBody*(space: PSpace; body: PBody): Bool{.
+  cdecl, importc: "cpSpaceContainsBody", dynlib: Lib.}
+#/ Test if a constraint has been added to the space.
+
+proc containsConstraint*(space: PSpace; constraint: PConstraint): Bool{.
+  cdecl, importc: "cpSpaceContainsConstraint", dynlib: Lib.}
+#/ Schedule a post-step callback to be called when cpSpaceStep() finishes.
+#/ @c obj is used a key, you can only register one callback per unique value for @c obj
+proc addPostStepCallback*(space: PSpace; func: TPostStepFunc; 
+                               obj: pointer; data: pointer){.
+  cdecl, importc: "cpSpaceAddPostStepCallback", dynlib: Lib.}
+                                        
+#/ Query the space at a point and call @c func for each shape found.
+proc pointQuery*(space: PSpace; point: TVector; layers: TLayers; 
+                      group: TGroup; func: TSpacePointQueryFunc; data: pointer){.
+  cdecl, importc: "cpSpacePointQuery", dynlib: Lib.}
+
+#/ Query the space at a point and return the first shape found. Returns NULL if no shapes were found.
+proc pointQueryFirst*(space: PSpace; point: TVector; layers: TLayers; 
+                       group: TGroup): PShape{.
+  cdecl, importc: "cpSpacePointQueryFirst", dynlib: Lib.}
+
+#/ Perform a directed line segment query (like a raycast) against the space calling @c func for each shape intersected.
+proc segmentQuery*(space: PSpace; start: TVector; to: TVector; 
+                    layers: TLayers; group: TGroup; 
+                    func: TSpaceSegmentQueryFunc; data: pointer){.
+  cdecl, importc: "cpSpaceSegmentQuery", dynlib: Lib.}
+#/ Perform a directed line segment query (like a raycast) against the space and return the first shape hit. Returns NULL if no shapes were hit.
+proc segmentQueryFirst*(space: PSpace; start: TVector; to: TVector; 
+                         layers: TLayers; group: TGroup; 
+                         res: PSegmentQueryInfo): PShape{.
+  cdecl, importc: "cpSpaceSegmentQueryFirst", dynlib: Lib.}
+
+#/ Perform a fast rectangle query on the space calling @c func for each shape found.
+#/ Only the shape's bounding boxes are checked for overlap, not their full shape.
+proc BBQuery*(space: PSpace; bb: TBB; layers: TLayers; group: TGroup; 
+                   func: TSpaceBBQueryFunc; data: pointer){.
+  cdecl, importc: "cpSpaceBBQuery", dynlib: Lib.}
+
+#/ Query a space for any shapes overlapping the given shape and call @c func for each shape found.
+proc shapeQuery*(space: PSpace; shape: PShape; func: TSpaceShapeQueryFunc; data: pointer): Bool {.
+  cdecl, importc: "cpSpaceShapeQuery", dynlib: Lib.}
+#/ Call cpBodyActivate() for any shape that is overlaps the given shape.
+proc activateShapesTouchingShape*(space: PSpace; shape: PShape){.
+    cdecl, importc: "cpSpaceActivateShapesTouchingShape", dynlib: Lib.}
+
+#/ Call @c func for each body in the space.
+proc eachBody*(space: PSpace; func: TSpaceBodyIteratorFunc; data: pointer){.
+  cdecl, importc: "cpSpaceEachBody", dynlib: Lib.}
+
+#/ Call @c func for each shape in the space.
+proc eachShape*(space: PSpace; func: TSpaceShapeIteratorFunc; 
+                     data: pointer){.
+  cdecl, importc: "cpSpaceEachShape", dynlib: Lib.}
+#/ Call @c func for each shape in the space.
+proc eachConstraint*(space: PSpace; func: TSpaceConstraintIteratorFunc; 
+                          data: pointer){.
+  cdecl, importc: "cpSpaceEachConstraint", dynlib: Lib.}
+#/ Update the collision detection info for the static shapes in the space.
+proc reindexStatic*(space: PSpace){.
+  cdecl, importc: "cpSpaceReindexStatic", dynlib: Lib.}
+#/ Update the collision detection data for a specific shape in the space.
+proc reindexShape*(space: PSpace; shape: PShape){.
+  cdecl, importc: "cpSpaceReindexShape", dynlib: Lib.}
+#/ Update the collision detection data for all shapes attached to a body.
+proc reindexShapesForBody*(space: PSpace; body: PBody){.
+  cdecl, importc: "cpSpaceReindexShapesForBody", dynlib: Lib.}
+#/ Switch the space to use a spatial has as it's spatial index.
+proc SpaceUseSpatialHash*(space: PSpace; dim: CpFloat; count: cint){.
+  cdecl, importc: "cpSpaceUseSpatialHash", dynlib: Lib.}
+#/ Step the space forward in time by @c dt.
+proc step*(space: PSpace; dt: CpFloat) {.
+  cdecl, importc: "cpSpaceStep", dynlib: Lib.}
+
+
+#/ Convenience constructor for cpVect structs.
+proc vector*(x, y: CpFloat): TVector {.inline.} =
+  result.x = x
+  result.y = y
+proc newVector*(x, y: CpFloat): TVector {.inline.} =
+  return vector(x, y)
+#let VectorZero* = newVector(0.0, 0.0)
+var VectorZero* = newVector(0.0, 0.0)
+
+#/ Vector dot product.
+proc dot*(v1, v2: TVector): CpFloat {.inline.} = 
+  result = v1.x * v2.x + v1.y * v2.y
+
+#/ Returns the length of v.
+#proc len*(v: TVector): CpFloat {.
+#  cdecl, importc: "cpvlength", dynlib: Lib.}
+proc len*(v: TVector): CpFloat {.inline.} =
+  result = v.dot(v).sqrt
+#/ Spherical linearly interpolate between v1 and v2.
+proc slerp*(v1, v2: TVector; t: CpFloat): TVector {.
+  cdecl, importc: "cpvslerp", dynlib: Lib.}
+#/ Spherical linearly interpolate between v1 towards v2 by no more than angle a radians
+proc slerpconst*(v1, v2: TVector; a: CpFloat): TVector {.
+  cdecl, importc: "cpvslerpconst", dynlib: Lib.}
+#/ Returns the unit length vector for the given angle (in radians).
+#proc vectorForAngle*(a: CpFloat): TVector {.
+#  cdecl, importc: "cpvforangle", dynlib: Lib.}
+proc vectorForAngle*(a: CpFloat): TVector {.inline.} =
+  result = newVector(math.cos(a), math.sin(a))
+#/ Returns the angular direction v is pointing in (in radians).
+proc toAngle*(v: TVector): CpFloat {.inline.} =
+  result = math.arctan2(v.y, v.x)
+#/	Returns a string representation of v. Intended mostly for debugging purposes and not production use.
+#/	@attention The string points to a static local and is reset every time the function is called.
+#/	If you want to print more than one vector you will have to split up your printing onto separate lines.
+proc `$`*(v: TVector): cstring {.cdecl, importc: "cpvstr", dynlib: Lib.}
+
+
+#/ Check if two vectors are equal. (Be careful when comparing floating point numbers!)
+proc `==`*(v1, v2: TVector): bool {.inline.} =
+  result = v1.x == v2.x and v1.y == v2.y
+
+#/ Add two vectors
+proc `+`*(v1, v2: TVector): TVector {.inline.} =
+  result = newVector(v1.x + v2.x, v1.y + v2.y)
+proc `+=`*(v1: var TVector; v2: TVector) =
+  v1.x = v1.x + v2.x
+  v1.y = v1.y + v2.y
+
+#/ Subtract two vectors.
+proc `-`*(v1, v2: TVector): TVector {.inline.} =
+  result = newVector(v1.x - v2.x, v1.y - v2.y)
+proc `-=`*(v1: var TVector; v2: TVector) =
+  v1.x = v1.x - v2.x
+  v1.y = v1.y - v2.y
+
+#/ Negate a vector.
+proc `-`*(v: TVector): TVector {.inline.} = 
+  result = newVector(- v.x, - v.y)
+
+#/ Scalar multiplication.
+proc `*`*(v: TVector, s: CpFloat): TVector {.inline.} =
+  result.x = v.x * s
+  result.y = v.y * s
+proc `*=`*(v: var TVector; s: CpFloat) =
+  v.x = v.x * s
+  v.y = v.y * s
+
+#/ 2D vector cross product analog.
+#/ The cross product of 2D vectors results in a 3D vector with only a z component.
+#/ This function returns the magnitude of the z value.
+proc cross*(v1, v2: TVector): CpFloat {.inline.} = 
+  result = v1.x * v2.y - v1.y * v2.x
+
+#/ Returns a perpendicular vector. (90 degree rotation)
+proc perp*(v: TVector): TVector {.inline.} = 
+  result = newVector(- v.y, v.x)
+
+#/ Returns a perpendicular vector. (-90 degree rotation)
+proc rperp*(v: TVector): TVector {.inline.} = 
+  result = newVector(v.y, - v.x)
+
+#/ Returns the vector projection of v1 onto v2.
+proc project*(v1,v2: TVector): TVector {.inline.} = 
+  result = v2 * (v1.dot(v2) / v2.dot(v2))
+
+#/ Uses complex number multiplication to rotate v1 by v2. Scaling will occur if v1 is not a unit vector.
+
+proc rotate*(v1, v2: TVector): TVector {.inline.} = 
+  result = newVector(v1.x * v2.x - v1.y * v2.y, v1.x * v2.y + v1.y * v2.x)
+#/ Inverse of cpvrotate().
+proc unrotate*(v1, v2: TVector): TVector {.inline.} = 
+  result = newVector(v1.x * v2.x + v1.y * v2.y, v1.y * v2.x - v1.x * v2.y)
+#/ Returns the squared length of v. Faster than cpvlength() when you only need to compare lengths.
+proc lenSq*(v: TVector): CpFloat {.inline.} = 
+  result = v.dot(v)
+#/ Linearly interpolate between v1 and v2.
+proc lerp*(v1, v2: TVector; t: CpFloat): TVector {.inline.} = 
+  result = (v1 * (1.0 - t)) + (v2 * t)
+#/ Returns a normalized copy of v.
+proc normalize*(v: TVector): TVector {.inline.} = 
+  result = v * (1.0 / v.len)
+#/ Returns a normalized copy of v or cpvzero if v was already cpvzero. Protects against divide by zero errors.
+proc normalizeSafe*(v: TVector): TVector {.inline.} = 
+  result = if v.x == 0.0 and v.y == 0.0: VectorZero else: v.normalize
+#/ Clamp v to length len.
+proc clamp*(v: TVector; len: CpFloat): TVector {.inline.} = 
+  result = if v.dot(v) > len * len: v.normalize * len else: v
+#/ Linearly interpolate between v1 towards v2 by distance d.
+proc lerpconst*(v1, v2: TVector; d: CpFloat): TVector {.inline.} = 
+  result = v1 + clamp(v2 - v1, d)             #vadd(v1 + vclamp(vsub(v2, v1), d))
+#/ Returns the distance between v1 and v2.
+proc dist*(v1, v2: TVector): CpFloat {.inline.} = 
+  result = (v1 - v2).len #vlength(vsub(v1, v2))
+#/ Returns the squared distance between v1 and v2. Faster than cpvdist() when you only need to compare distances.
+proc distsq*(v1, v2: TVector): CpFloat {.inline.} = 
+  result = (v1 - v2).lenSq  #vlengthsq(vsub(v1, v2))
+#/ Returns true if the distance between v1 and v2 is less than dist.
+proc near*(v1, v2: TVector; dist: CpFloat): Bool{.inline.} = 
+  result = v1.distSq(v2) < dist * dist
+
+
+
+##cpBody.h
+proc allocBody*(): PBody {.importc: "cpBodyAlloc", dynlib: Lib.}
+proc init*(body: PBody; m: CpFloat; i: CpFloat): PBody {.
+  importc: "cpBodyInit", dynlib: Lib.}
+proc newBody*(m: CpFloat; i: CpFloat): PBody {.
+  importc: "cpBodyNew", dynlib: Lib.}
+
+proc initStaticBody*(body: PBody): PBody{.
+  importc: "cpBodyInitStatic", dynlib: Lib.}
+#/ Allocate and initialize a static cpBody.
+proc newStatic*(): PBody{.importc: "cpBodyNewStatic", dynlib: Lib.}
+#/ Destroy a cpBody.
+proc destroy*(body: PBody){.importc: "cpBodyDestroy", dynlib: Lib.}
+#/ Destroy and free a cpBody.
+proc free*(body: PBody){.importc: "cpBodyFree", dynlib: Lib.}
+
+#/ Wake up a sleeping or idle body.
+proc activate*(body: PBody){.importc: "cpBodyActivate", dynlib: Lib.}
+#/ Wake up any sleeping or idle bodies touching a static body.
+proc activateStatic*(body: PBody; filter: PShape){.
+    importc: "cpBodyActivateStatic", dynlib: Lib.}
+#/ Force a body to fall asleep immediately.
+proc Sleep*(body: PBody){.importc: "cpBodySleep", dynlib: Lib.}
+#/ Force a body to fall asleep immediately along with other bodies in a group.
+proc SleepWithGroup*(body: PBody; group: PBody){.
+    importc: "cpBodySleepWithGroup", dynlib: Lib.}
+#/ Returns true if the body is sleeping.
+proc isSleeping*(body: PBody): Bool {.inline.} = 
+  return body.node.root != nil
+#/ Returns true if the body is static.
+proc isStatic*(body: PBody): bool {.inline.} = 
+  return body.node.idleTime == CpInfinity
+#/ Returns true if the body has not been added to a space.
+proc isRogue*(body: PBody): Bool {.inline.} = 
+  return body.space == nil
+
+# #define CP_DefineBodyStructGetter(type, member, name) \
+# static inline type cpBodyGet##name(const cpBody *body){return body->member;}
+# #define CP_DefineBodyStructSetter(type, member, name) \
+# static inline void cpBodySet##name(cpBody *body, const type value){ \
+# 	cpBodyActivate(body); \
+# 	cpBodyAssertSane(body); \
+# 	body->member = value; \
+# }
+# #define CP_DefineBodyStructProperty(type, member, name) \
+# CP_DefineBodyStructGetter(type, member, name) \
+# CP_DefineBodyStructSetter(type, member, name)
+
+defGetter(PBody, CpFloat, m, Mass)
+#/ Set the mass of a body.
+when defined(MoreNimrod):
+  defSetter(PBody, CpFloat, m, Mass)
+else:
+  proc setMass*(body: PBody; m: CpFloat){.
+    cdecl, importc: "cpBodySetMass", dynlib: Lib.}
+
+#/ Get the moment of a body.
+defGetter(PBody, CpFloat, i, Moment)
+#/ Set the moment of a body.
+when defined(MoreNimrod):
+  defSetter(PBody, CpFloat, i, Moment)
+else: 
+  proc SetMoment*(body: PBody; i: CpFloat) {.
+    cdecl, importc: "cpBodySetMoment", dynlib: Lib.}
+
+#/ Get the position of a body.
+defGetter(PBody, TVector, p, Pos)
+#/ Set the position of a body.
+when defined(MoreNimrod):
+  defSetter(PBody, TVector, p, Pos)
+else:
+  proc setPos*(body: PBody; pos: TVector) {.
+    cdecl, importc: "cpBodySetPos", dynlib: Lib.}
+
+defProp(PBody, TVector, v, Vel)
+defProp(PBody, TVector, f, Force)
+
+#/ Get the angle of a body.
+defGetter(PBody, CpFloat, a, Angle)
+#/ Set the angle of a body.
+proc setAngle*(body: PBody; a: CpFloat){.
+  cdecl, importc: "cpBodySetAngle", dynlib: Lib.}
+
+defProp(PBody, CpFloat, w, AngVel)
+defProp(PBody, CpFloat, t, Torque)
+defGetter(PBody, TVector, rot, Rot)
+defProp(PBody, CpFloat, v_limit, VelLimit)
+defProp(PBody, CpFloat, w_limit, AngVelLimit)
+defProp(PBody, pointer, data, UserData)
+
+#/ Default Integration functions.
+proc UpdateVelocity*(body: PBody; gravity: TVector; damping: CpFloat; dt: CpFloat){.
+  cdecl, importc: "cpBodyUpdateVelocity", dynlib: Lib.}
+proc UpdatePosition*(body: PBody; dt: CpFloat){.
+  cdecl, importc: "cpBodyUpdatePosition", dynlib: Lib.}
+#/ Convert body relative/local coordinates to absolute/world coordinates.
+proc Local2World*(body: PBody; v: TVector): TVector{.inline.} = 
+  result = body.p + v.rotate(body.rot) ##return cpvadd(body.p, cpvrotate(v, body.rot))
+#/ Convert body absolute/world coordinates to  relative/local coordinates.
+proc world2Local*(body: PBody; v: TVector): TVector{.inline.} = 
+  result = (v - body.p).unrotate(body.rot)
+#/ Set the forces and torque or a body to zero.
+proc resetForces*(body: PBody){.
+  cdecl, importc: "cpBodyResetForces", dynlib: Lib.}
+#/ Apply an force (in world coordinates) to the body at a point relative to the center of gravity (also in world coordinates).
+proc applyForce*(body: PBody; f, r: TVector){.
+  cdecl, importc: "cpBodyApplyForce", dynlib: Lib.}
+#/ Apply an impulse (in world coordinates) to the body at a point relative to the center of gravity (also in world coordinates).
+proc applyImpulse*(body: PBody; j, r: TVector){.
+  cdecl, importc: "cpBodyApplyImpulse", dynlib: Lib.}
+#/ Get the velocity on a body (in world units) at a point on the body in world coordinates.
+
+proc getVelAtWorldPoint*(body: PBody; point: TVector): TVector{.
+  cdecl, importc: "cpBodyGetVelAtWorldPoint", dynlib: Lib.}
+#/ Get the velocity on a body (in world units) at a point on the body in local coordinates.
+proc getVelAtLocalPoint*(body: PBody; point: TVector): TVector{.
+  cdecl, importc: "cpBodyGetVelAtLocalPoint", dynlib: Lib.}
+#/ Get the kinetic energy of a body.
+# static inline CpFloat cpBodyKineticEnergy(const cpBody *body)
+# {
+# 	// Need to do some fudging to avoid NaNs
+# 	cpFloat vsq = cpvdot(body->v, body->v);
+# 	cpFloat wsq = body->w*body->w;
+# 	return (vsq ? vsq*body->m : 0.0f) + (wsq ? wsq*body->i : 0.0f);
+# }
+proc kineticEnergy*(body: PBOdy): CpFloat =
+  result = (body.v.dot(body.v) * body.m) + (body.w * body.w * body.i)
+
+#/ Call @c func once for each shape attached to @c body and added to the space.
+proc eachShape*(body: PBody; func: TBodyShapeIteratorFunc; 
+                      data: pointer){.
+  cdecl, importc: "cpBodyEachShape", dynlib: Lib.}
+#/ Call @c func once for each constraint attached to @c body and added to the space.
+proc eachConstraint*(body: PBody; func: TBodyConstraintIteratorFunc; 
+                           data: pointer) {.
+  cdecl, importc: "cpBodyEachConstraint", dynlib: Lib.}
+#/ Call @c func once for each arbiter that is currently active on the body.
+proc eachArbiter*(body: PBody; func: TBodyArbiterIteratorFunc; 
+                        data: pointer){.
+  cdecl, importc: "cpBodyEachArbiter", dynlib: Lib.}
+#/ Allocate a spatial hash.
+proc SpaceHashAlloc*(): PSpaceHash{.
+  cdecl, importc: "cpSpaceHashAlloc", dynlib: Lib.}
+#/ Initialize a spatial hash. 
+proc SpaceHashInit*(hash: PSpaceHash; celldim: CpFloat; numcells: cint; 
+                    bbfunc: TSpatialIndexBBFunc; staticIndex: PSpatialIndex): PSpatialIndex{.
+  cdecl, importc: "cpSpaceHashInit", dynlib: Lib.}
+#/ Allocate and initialize a spatial hash.
+proc SpaceHashNew*(celldim: CpFloat; cells: cint; bbfunc: TSpatialIndexBBFunc; 
+                   staticIndex: PSpatialIndex): PSpatialIndex{.
+  cdecl, importc: "cpSpaceHashNew", dynlib: Lib.}
+#/ Change the cell dimensions and table size of the spatial hash to tune it.
+#/ The cell dimensions should roughly match the average size of your objects
+#/ and the table size should be ~10 larger than the number of objects inserted.
+#/ Some trial and error is required to find the optimum numbers for efficiency.
+proc SpaceHashResize*(hash: PSpaceHash; celldim: CpFloat; numcells: cint){.
+  cdecl, importc: "cpSpaceHashResize", dynlib: Lib.}
+#MARK: AABB Tree
+
+
+#/ Allocate a bounding box tree.
+proc BBTreeAlloc*(): PBBTree{.cdecl, importc: "cpBBTreeAlloc", dynlib: Lib.}
+#/ Initialize a bounding box tree.
+proc BBTreeInit*(tree: PBBTree; bbfunc: TSpatialIndexBBFunc; 
+                 staticIndex: ptr TSpatialIndex): ptr TSpatialIndex{.cdecl, 
+    importc: "cpBBTreeInit", dynlib: Lib.}
+#/ Allocate and initialize a bounding box tree.
+proc BBTreeNew*(bbfunc: TSpatialIndexBBFunc; staticIndex: PSpatialIndex): PSpatialIndex{.
+    cdecl, importc: "cpBBTreeNew", dynlib: Lib.}
+#/ Perform a static top down optimization of the tree.
+proc BBTreeOptimize*(index: PSpatialIndex){.
+  cdecl, importc: "cpBBTreeOptimize", dynlib: Lib.}
+#/ Set the velocity function for the bounding box tree to enable temporal coherence.
+
+proc BBTreeSetVelocityFunc*(index: PSpatialIndex; func: TBBTreeVelocityFunc){.
+    cdecl, importc: "cpBBTreeSetVelocityFunc", dynlib: Lib.}
+#MARK: Single Axis Sweep
+
+
+#/ Allocate a 1D sort and sweep broadphase.
+
+proc Sweep1DAlloc*(): ptr TSweep1D{.cdecl, importc: "cpSweep1DAlloc", 
+                                    dynlib: Lib.}
+#/ Initialize a 1D sort and sweep broadphase.
+
+proc Sweep1DInit*(sweep: ptr TSweep1D; bbfunc: TSpatialIndexBBFunc; 
+                  staticIndex: ptr TSpatialIndex): ptr TSpatialIndex{.cdecl, 
+    importc: "cpSweep1DInit", dynlib: Lib.}
+#/ Allocate and initialize a 1D sort and sweep broadphase.
+
+proc Sweep1DNew*(bbfunc: TSpatialIndexBBFunc; staticIndex: ptr TSpatialIndex): ptr TSpatialIndex{.
+    cdecl, importc: "cpSweep1DNew", dynlib: Lib.}
+
+
+
+defProp(PArbiter, CpFloat, e, Elasticity)
+defProp(PArbiter, CpFloat, u, Friction)
+defProp(PArbiter, TVector, surface_vr, SurfaceVelocity)
+
+#/ Calculate the total impulse that was applied by this 
+#/ This function should only be called from a post-solve, post-step or cpBodyEachArbiter callback.
+proc totalImpulse*(obj: PArbiter): TVector {.cdecl, importc: "cpArbiterTotalImpulse", dynlib: Lib.}
+
+#/ Calculate the total impulse including the friction that was applied by this arbiter.
+#/ This function should only be called from a post-solve, post-step or cpBodyEachArbiter callback.
+proc totalImpulseWithFriction*(obj: PArbiter): TVector {.cdecl, importc: "cpArbiterTotalImpulseWithFriction", dynlib: Lib.}
+
+#/ Calculate the amount of energy lost in a collision including static, but not dynamic friction.
+#/ This function should only be called from a post-solve, post-step or cpBodyEachArbiter callback.
+proc totalKE*(obj: PArbiter): CpFloat {.cdecl, importc: "cpArbiterTotalKE", dynlib: Lib.}
+
+
+#/ Causes a collision pair to be ignored as if you returned false from a begin callback.
+#/ If called from a pre-step callback, you will still need to return false
+#/ if you want it to be ignored in the current step.
+proc ignore*(arb: PArbiter) {.cdecl, importc: "cpArbiterIgnore", dynlib: Lib.}
+
+#/ Return the colliding shapes involved for this arbiter.
+#/ The order of their cpSpace.collision_type values will match
+#/ the order set when the collision handler was registered.
+proc getShapes*(arb: PArbiter, a, b: var PShape) {.inline.} =
+  if arb.swappedColl.bool:
+    a = arb.b
+    b = arb.a
+  else:
+    a = arb.a
+    b = arb.b
+
+#/ A macro shortcut for defining and retrieving the shapes from an arbiter.
+#define CP_ARBITER_GET_SHAPES(arb, a, b) cpShape *a, *b; cpArbiterGetShapes(arb, &a, &b);
+template getShapes*(arb: PArbiter, name1, name2: expr): stmt {.immediate.} =
+  var name1, name2: PShape
+  getShapes(arb, name1, name2)
+
+
+#/ Return the colliding bodies involved for this arbiter.
+#/ The order of the cpSpace.collision_type the bodies are associated with values will match
+#/ the order set when the collision handler was registered.
+#proc getBodies*(arb: PArbiter, a, b: var PBody) {.inline.} = 
+#  getShapes(arb, shape1, shape2)
+#  a = shape1.body
+#  b = shape2.body
+
+#/ A macro shortcut for defining and retrieving the bodies from an arbiter.
+#define CP_ARBITER_GET_BODIES(arb, a, b) cpBody *a, *b; cpArbiterGetBodies(arb, &a, &b);
+template getBodies*(arb: PArbiter, name1, name2: expr): stmt {.immediate.} =
+  var name1, name2: PBOdy
+  getBodies(arb, name1, name2)
+
+proc isFirstContact*(arb: PArbiter): bool {.inline.} =
+  result = arb.state == ArbiterStateFirstColl
+
+proc getCount*(arb: PArbiter): cint {.inline.} =
+  result = arb.numContacts
+
+#/ Return a contact set from an arbiter.
+proc getContactPointSet*(arb: PArbiter): TContactPointSet {.
+  cdecl, importc: "cpArbiterGetContactPointSet", dynlib: Lib.}
+#/ Get the normal of the @c ith contact point.
+proc getNormal*(arb: PArbiter; i: cint): TVector {.
+  cdecl, importc: "cpArbiterGetNormal", dynlib: Lib.}
+#/ Get the position of the @c ith contact point.
+proc getPoint*(arb: PArbiter; i: cint): TVector {.
+  cdecl, importc: "cpArbiterGetPoint", dynlib: Lib.}
+#/ Get the depth of the @c ith contact point.
+proc getDepth*(arb: PArbiter; i: cint): CpFloat {.
+  cdecl, importc: "cpArbiterGetDepth", dynlib: Lib.}
+
+##Shapes
+template defShapeSetter(memberType: typedesc, memberName: expr, procName: expr, activates: bool): stmt {.immediate.} =
+  proc `set procName`*(obj: PShape, value: memberType) {.cdecl.} =
+    if activates and obj.body != nil: obj.body.activate()
+    obj.memberName = value
+template defShapeProp(memberType: typedesc, memberName: expr, procName: expr, activates: bool): stmt {.immediate.} =
+  defGetter(PShape, memberType, memberName, procName)
+  defShapeSetter(memberType, memberName, procName, activates)
+
+#/ Destroy a shape.
+proc destroy*(shape: PShape) {.
+  cdecl, importc: "cpShapeDestroy", dynlib: Lib.}
+#/ Destroy and Free a shape.
+proc free*(shape: PShape){.
+  cdecl, importc: "cpShapeFree", dynlib: Lib.}
+#/ Update, cache and return the bounding box of a shape based on the body it's attached to.
+proc cacheBB*(shape: PShape): TBB{.
+  cdecl, importc: "cpShapeCacheBB", dynlib: Lib.}
+#/ Update, cache and return the bounding box of a shape with an explicit transformation.
+proc update*(shape: PShape; pos: TVector; rot: TVector): TBB {.
+  cdecl, importc: "cpShapeUpdate", dynlib: Lib.}
+#/ Test if a point lies within a shape.
+proc pointQuery*(shape: PShape; p: TVector): Bool32 {.
+  cdecl, importc: "cpShapePointQuery", dynlib: Lib.}
+
+#/ Perform a nearest point query. It finds the closest point on the surface of shape to a specific point.
+#/ The value returned is the distance between the points. A negative distance means the point is inside the shape.
+proc nearestPointQuery*(shape: PShape; p: TVector; res: PNearestPointQueryInfo): CpFloat {.
+  cdecl, importc: "cpShapeNearestPointQuery", dynlib: Lib.}
+#/ Perform a segment query against a shape. @c info must be a pointer to a valid cpSegmentQueryInfo structure.
+proc segmentQuery*(shape: PShape, a, b: TVector, info: PSegmentQueryInfo): bool {.
+  cdecl, importc: "cpShapeSegmentQuery", dynlib: Lib.}
+
+#/ Get the hit point for a segment query.
+## Possibly change; info to PSegmentQueryInfo 
+proc queryHitPoint*(start, to: TVector, info: TSegmentQueryInfo): TVector {.inline.} =
+  result = start.lerp(to, info.t)
+
+#/ Get the hit distance for a segment query.
+proc queryHitDist*(start, to: TVector, info: TSegmentQueryInfo): CpFloat {.inline.} =
+  result = start.dist(to) * info.t
+
+defGetter(PShape, PSpace, space, Space)
+
+defGetter(PShape, PBody, body, Body)
+proc setBody*(shape: PShape, value: PBody) {.
+  cdecl, importc: "cpShapeSetBody", dynlib: Lib.}
+
+
+defGetter(PShape, TBB, bb, BB)
+defShapeProp(Bool32, sensor, Sensor, true)
+defShapeProp(CpFloat, e, Elasticity, false)
+defShapeProp(CpFloat, u, Friction, true)
+defShapeProp(TVector, surface_v, SurfaceVelocity, true)
+defShapeProp(pointer, data, UserData, false)
+defShapeProp(TCollisionType, collision_type, CollisionType, true)
+defShapeProp(TGroup, group, Group, true)
+defShapeProp(TLayers, layers, Layers, true)
+
+#/ When initializing a shape, it's hash value comes from a counter.
+#/ Because the hash value may affect iteration order, you can reset the shape ID counter
+#/ when recreating a space. This will make the simulation be deterministic.
+proc resetShapeIdCounter*(): void {.cdecl, importc: "cpResetShapeIdCounter", dynlib: Lib.}
+#/ Allocate a circle shape.
+proc CircleShapeAlloc*(): PCircleShape {.cdecl, importc: "cpCircleShapeAlloc", dynlib: Lib.}
+#/ Initialize a circle shape.
+proc init*(circle: PCircleShape, body: PBody, radius: CpFloat, offset: TVector): PCircleShape {.
+  cdecl, importc: "cpCircleShapeInit", dynlib: Lib.}
+#/ Allocate and initialize a circle shape.
+proc newCircleShape*(body: PBody, radius: CpFloat, offset: TVector): PShape {.
+  cdecl, importc: "cpCircleShapeNew", dynlib: Lib.}
+
+proc getCircleOffset*(shape: PShape): TVector {.
+  cdecl, importc: "cpCircleShapeGetOffset", dynlib: Lib.}
+proc getCircleRadius*(shape: PShape): CpFloat {.
+  cdecl, importc: "cpCircleShapeGetRadius", dynlib: Lib.}
+
+
+#/ Allocate a polygon shape.
+proc allocPolyShape*(): PPolyShape {.
+  cdecl, importc: "cpPolyShapeAlloc", dynlib: Lib.}
+#/ Initialize a polygon shape.
+#/ A convex hull will be created from the vertexes.
+proc init*(poly: PPolyShape; body: PBody, numVerts: cint;
+            verts: ptr TVector; offset: TVector): PPolyShape {.
+  cdecl, importc: "cpPolyShapeInit", dynlib: Lib.}
+#/ Allocate and initialize a polygon shape.
+#/ A convex hull will be created from the vertexes.
+proc newPolyShape*(body: PBody; numVerts: cint; verts: ptr TVector; 
+                    offset: TVector): PShape {.
+  cdecl, importc: "cpPolyShapeNew", dynlib: Lib.}
+#/ Initialize a box shaped polygon shape.
+proc init*(poly: PPolyShape; body: PBody; width, height: CpFloat): PPolyShape {.
+  cdecl, importc: "cpBoxShapeInit", dynlib: Lib.}
+#/ Initialize an offset box shaped polygon shape.
+proc init*(poly: PPolyShape; body: PBody; box: TBB): PPolyShape {.
+  cdecl, importc: "cpBoxShapeInit2", dynlib: Lib.}
+#/ Allocate and initialize a box shaped polygon shape.
+proc newBoxShape*(body: PBody; width, height: CpFloat): PShape {.
+  cdecl, importc: "cpBoxShapeNew", dynlib: Lib.}
+#/ Allocate and initialize an offset box shaped polygon shape.
+proc newBoxShape*(body: PBody; box: TBB): PShape {.
+  cdecl, importc: "cpBoxShapeNew2", dynlib: Lib.}
+
+#/ Check that a set of vertexes is convex and has a clockwise winding.
+#/ NOTE: Due to floating point precision issues, hulls created with cpQuickHull() are not guaranteed to validate!
+proc validatePoly*(verts: ptr TVector; numVerts: cint): bool {.
+  cdecl, importc: "cpPolyValidate", dynlib: Lib.}
+#/ Get the number of verts in a polygon shape.
+proc getNumVerts*(shape: PShape): cint {.
+  cdecl, importc: "cpPolyShapeGetNumVerts", dynlib: Lib.}
+#/ Get the @c ith vertex of a polygon shape.
+proc getVert*(shape: PShape; index: cint): TVector {.
+  cdecl, importc: "cpPolyShapeGetVert", dynlib: Lib.}
+
+#/ Allocate a segment shape.
+proc allocSegmentShape*(): PSegmentShape {.
+  cdecl, importc: "cpSegmentShapeAlloc", dynlib: Lib.}
+#/ Initialize a segment shape.
+proc init*(seg: PSegmentShape, body: PBody, a, b: TVector, radius: CpFloat): PSegmentShape {.
+  cdecl, importc: "cpSegmentShapeInit", dynlib: Lib.}
+#/ Allocate and initialize a segment shape.
+proc newSegmentShape*(body: PBody, a, b: TVector, radius: CpFloat): PShape {.
+  cdecl, importc: "cpSegmentShapeNew", dynlib: Lib.}
+
+proc setSegmentNeighbors*(shape: PShape, prev, next: TVector) {.
+  cdecl, importc: "cpSegmentShapeSetNeighbors", dynlib: Lib.}
+proc getSegmentA*(shape: PShape): TVector {.
+  cdecl, importc: "cpSegmentShapeGetA", dynlib: Lib.}
+proc getSegmentB*(shape: PShape): TVector {.
+  cdecl, importc: "cpSegmentShapeGetB", dynlib: Lib.}
+proc getSegmentNormal*(shape: PShape): TVector {.
+  cdecl, importc: "cpSegmentShapeGetNormal", dynlib: Lib.}
+proc getSegmentRadius*(shape: PShape): CpFloat {.
+  cdecl, importc: "cpSegmentShapeGetRadius", dynlib: Lib.}
+
+
+#/ Version string.
+#var VersionString*{.importc: "cpVersionString", dynlib: Lib.}: cstring
+#/ Calculate the moment of inertia for a circle.
+#/ @c r1 and @c r2 are the inner and outer diameters. A solid circle has an inner diameter of 0.
+when defined(MoreNimrod):
+  proc momentForCircle*(m, r1, r2: CpFloat; offset: TVector): CpFloat {.cdecl.} =
+    result = m * (0.5 * (r1 * r1 + r2 * r2) + lenSq(offset))
+else:
+  proc momentForCircle*(m, r1, r2: CpFloat; offset: TVector): CpFloat {.
+    cdecl, importc: "cpMomentForCircle", dynlib: Lib.}
+
+#/ Calculate area of a hollow circle.
+#/ @c r1 and @c r2 are the inner and outer diameters. A solid circle has an inner diameter of 0.
+proc AreaForCircle*(r1: CpFloat; r2: CpFloat): CpFloat {.
+  cdecl, importc: "cpAreaForCircle", dynlib: Lib.}
+#/ Calculate the moment of inertia for a line segment.
+#/ Beveling radius is not supported.
+proc MomentForSegment*(m: CpFloat; a, b: TVector): CpFloat {.
+  cdecl, importc: "cpMomentForSegment", dynlib: Lib.}
+#/ Calculate the area of a fattened (capsule shaped) line segment.
+proc AreaForSegment*(a, b: TVector; r: CpFloat): CpFloat {.
+  cdecl, importc: "cpAreaForSegment", dynlib: Lib.}
+#/ Calculate the moment of inertia for a solid polygon shape assuming it's center of gravity is at it's centroid. The offset is added to each vertex.
+proc MomentForPoly*(m: CpFloat; numVerts: cint; verts: ptr TVector; offset: TVector): CpFloat {.
+  cdecl, importc: "cpMomentForPoly", dynlib: Lib.}
+#/ Calculate the signed area of a polygon. A Clockwise winding gives positive area.
+#/ This is probably backwards from what you expect, but matches Chipmunk's the winding for poly shapes.
+proc AreaForPoly*(numVerts: cint; verts: ptr TVector): CpFloat {.
+  cdecl, importc: "cpAreaForPoly", dynlib: Lib.}
+#/ Calculate the natural centroid of a polygon.
+proc CentroidForPoly*(numVerts: cint; verts: ptr TVector): TVector {.
+  cdecl, importc: "cpCentroidForPoly", dynlib: Lib.}
+#/ Center the polygon on the origin. (Subtracts the centroid of the polygon from each vertex)
+proc RecenterPoly*(numVerts: cint; verts: ptr TVector) {.
+  cdecl, importc: "cpRecenterPoly", dynlib: Lib.}
+#/ Calculate the moment of inertia for a solid box.
+proc MomentForBox*(m, width, height: CpFloat): CpFloat {.
+  cdecl, importc: "cpMomentForBox", dynlib: Lib.}
+#/ Calculate the moment of inertia for a solid box.
+proc MomentForBox2*(m: CpFloat; box: TBB): CpFloat {.
+  cdecl, importc: "cpMomentForBox2", dynlib: Lib.}
+
+
+
+##constraints
+type 
+  #TODO: all these are private
+  #TODO: defConstraintProp()
+  PPinJoint = ptr TPinJoint
+  TPinJoint{.pf.} = object 
+    constraint: PConstraint
+    anchr1: TVector
+    anchr2: TVector
+    dist: CpFloat
+    r1: TVector
+    r2: TVector
+    n: TVector
+    nMass: CpFloat
+    jnAcc: CpFloat
+    jnMax: CpFloat
+    bias: CpFloat
+  PSlideJoint = ptr TSlideJoint
+  TSlideJoint{.pf.} = object 
+    constraint: PConstraint
+    anchr1: TVector
+    anchr2: TVector
+    min: CpFloat
+    max: CpFloat
+    r1: TVector
+    r2: TVector
+    n: TVector
+    nMass: CpFloat
+    jnAcc: CpFloat
+    jnMax: CpFloat
+    bias: CpFloat
+  PPivotJoint = ptr TPivotJoint
+  TPivotJoint{.pf.} = object 
+    constraint: PConstraint
+    anchr1: TVector
+    anchr2: TVector
+    r1: TVector
+    r2: TVector
+    k1: TVector
+    k2: TVector
+    jAcc: TVector
+    jMaxLen: CpFloat
+    bias: TVector
+  PGrooveJoint = ptr TGrooveJoint
+  TGrooveJoint{.pf.} = object 
+    constraint: PConstraint
+    grv_n: TVector
+    grv_a: TVector
+    grv_b: TVector
+    anchr2: TVector
+    grv_tn: TVector
+    clamp: CpFloat
+    r1: TVector
+    r2: TVector
+    k1: TVector
+    k2: TVector
+    jAcc: TVector
+    jMaxLen: CpFloat
+    bias: TVector
+  PDampedSpring = ptr TDampedSpring
+  TDampedSpring{.pf.} = object 
+    constraint: PConstraint
+    anchr1: TVector
+    anchr2: TVector
+    restLength: CpFloat
+    stiffness: CpFloat
+    damping: CpFloat
+    springForceFunc: TDampedSpringForceFunc
+    target_vrn: CpFloat
+    v_coef: CpFloat
+    r1: TVector
+    r2: TVector
+    nMass: CpFloat
+    n: TVector
+  PDampedRotarySpring = ptr TDampedRotarySpring
+  TDampedRotarySpring{.pf.} = object 
+    constraint: PConstraint
+    restAngle: CpFloat
+    stiffness: CpFloat
+    damping: CpFloat
+    springTorqueFunc: TDampedRotarySpringTorqueFunc
+    target_wrn: CpFloat
+    w_coef: CpFloat
+    iSum: CpFloat
+  PRotaryLimitJoint = ptr TRotaryLimitJoint
+  TRotaryLimitJoint{.pf.} = object 
+    constraint: PConstraint
+    min: CpFloat
+    max: CpFloat
+    iSum: CpFloat
+    bias: CpFloat
+    jAcc: CpFloat
+    jMax: CpFloat
+  PRatchetJoint = ptr TRatchetJoint
+  TRatchetJoint{.pf.} = object 
+    constraint: PConstraint
+    angle: CpFloat
+    phase: CpFloat
+    ratchet: CpFloat
+    iSum: CpFloat
+    bias: CpFloat
+    jAcc: CpFloat
+    jMax: CpFloat
+  PGearJoint = ptr TGearJoint
+  TGearJoint{.pf.} = object 
+    constraint: PConstraint
+    phase: CpFloat
+    ratio: CpFloat
+    ratio_inv: CpFloat
+    iSum: CpFloat
+    bias: CpFloat
+    jAcc: CpFloat
+    jMax: CpFloat
+  PSimpleMotor = ptr TSimpleMotor
+  TSimpleMotor{.pf.} = object 
+    constraint: PConstraint
+    rate: CpFloat
+    iSum: CpFloat
+    jAcc: CpFloat
+    jMax: CpFloat
+  TDampedSpringForceFunc* = proc (spring: PConstraint; dist: CpFloat): CpFloat{.
+    cdecl.}
+  TDampedRotarySpringTorqueFunc* = proc (spring: PConstraint; 
+      relativeAngle: CpFloat): CpFloat {.cdecl.}
+#/ Destroy a constraint.
+proc destroy*(constraint: PConstraint){.
+  cdecl, importc: "cpConstraintDestroy", dynlib: Lib.}
+#/ Destroy and free a constraint.111
+proc free*(constraint: PConstraint){.
+  cdecl, importc: "cpConstraintFree", dynlib: Lib.}
+
+#/ @private
+proc activateBodies(constraint: PConstraint) {.inline.} = 
+  if not constraint.a.isNil: constraint.a.activate()
+  if not constraint.b.isNil: constraint.b.activate()
+
+# /// @private
+# #define CP_DefineConstraintStructGetter(type, member, name) \
+# static inline type cpConstraint##Get##name(const cpConstraint *constraint){return constraint->member;}
+# /// @private
+# #define CP_DefineConstraintStructSetter(type, member, name) \
+# static inline void cpConstraint##Set##name(cpConstraint *constraint, type value){ \
+# 	cpConstraintActivateBodies(constraint); \
+# 	constraint->member = value; \
+# }
+template defConstraintSetter(memberType: typedesc, member: expr, name: expr): stmt {.immediate.} =
+  proc `set name`*(constraint: PConstraint, value: memberType) {.cdecl.} =
+    activateBodies(constraint)
+    constraint.member = value
+template defConstraintProp(memberType: typedesc, member: expr, name: expr): stmt {.immediate.} =
+  defGetter(PConstraint, memberType, member, name)
+  defConstraintSetter(memberType, member, name)
+# CP_DefineConstraintStructGetter(cpSpace*, CP_PRIVATE(space), Space)
+defGetter(PConstraint, PSpace, space, Space)
+defGetter(PConstraint, PBody, a, A)
+defGetter(PConstraint, PBody, a, B)
+defGetter(PConstraint, CpFloat, maxForce, MaxForce)
+defGetter(PConstraint, CpFloat, errorBias, ErrorBias)
+defGetter(PConstraint, CpFloat, maxBias, MaxBias)
+defGetter(PConstraint, TConstraintPreSolveFunc, preSolve, PreSolveFunc)
+defGetter(PConstraint, TConstraintPostSolveFunc, postSolve, PostSolveFunc)
+defGetter(PConstraint, CpDataPointer, data, UserData)
+# Get the last impulse applied by this constraint.
+proc getImpulse*(constraint: PConstraint): CpFloat {.inline.} = 
+  return constraint.klass.getImpulse(constraint)
+
+# #define cpConstraintCheckCast(constraint, struct) \
+# 	cpAssertHard(constraint->CP_PRIVATE(klass) == struct##GetClass(), "Constraint is not a "#struct)
+# #define CP_DefineConstraintGetter(struct, type, member, name) \
+# static inline type struct##Get##name(const cpConstraint *constraint){ \
+# 	cpConstraintCheckCast(constraint, struct); \
+# 	return ((struct *)constraint)->member; \
+# }
+# #define CP_DefineConstraintSetter(struct, type, member, name) \
+# static inline void struct##Set##name(cpConstraint *constraint, type value){ \
+# 	cpConstraintCheckCast(constraint, struct); \
+# 	cpConstraintActivateBodies(constraint); \
+# 	((struct *)constraint)->member = value; \
+# }
+template constraintCheckCast(constraint: PConstraint, ctype: expr): stmt {.immediate.} =
+  assert(constraint.klass == `ctype getClass`(), "Constraint is the wrong class")
+template defCGetter(ctype: expr, memberType: typedesc, member: expr, name: expr): stmt {.immediate.} = 
+  proc `get ctype name`*(constraint: PConstraint): memberType {.cdecl.} =
+    constraintCheckCast(constraint, ctype)
+    result = cast[`P ctype`](constraint).member
+template defCSetter(ctype: expr, memberType: typedesc, member: expr, name: expr): stmt {.immediate.} =
+  proc `set ctype name`*(constraint: PConstraint, value: memberType) {.cdecl.} =
+    constraintCheckCast(constraint, ctype)
+    activateBodies(constraint)
+    cast[`P ctype`](constraint).member = value
+template defCProp(ctype: expr, memberType: typedesc, member: expr, name: expr): stmt {.immediate.} =
+  defCGetter(ctype, memberType, member, name)
+  defCSetter(ctype, memberType, member, name)
+
+proc PinJointGetClass*(): PConstraintClass{.
+  cdecl, importc: "cpPinJointGetClass", dynlib: Lib.}
+#/ @private
+
+#/ Allocate a pin joint.
+proc AllocPinJoint*(): PPinJoint{.
+  cdecl, importc: "cpPinJointAlloc", dynlib: Lib.}
+#/ Initialize a pin joint.
+proc PinJointInit*(joint: PPinJoint; a: PBody; b: PBody; anchr1: TVector; 
+                   anchr2: TVector): PPinJoint{.
+  cdecl, importc: "cpPinJointInit", dynlib: Lib.}
+#/ Allocate and initialize a pin joint.
+proc newPinJoint*(a: PBody; b: PBody; anchr1: TVector; anchr2: TVector): PConstraint{.
+  cdecl, importc: "cpPinJointNew", dynlib: Lib.}
+# CP_DefineConstraintProperty(cpPinJoint, cpVect, anchr1, Anchr1)
+defCProp(PinJoint, TVector, anchr1, Anchr1)
+defCProp(PinJoint, TVector, anchr2, Anchr2)
+defCProp(PinJoint, CpFloat, dist, Dist)
+
+proc SlideJointGetClass*(): PConstraintClass{.
+  cdecl, importc: "cpSlideJointGetClass", dynlib: Lib.}
+#/ Allocate a slide joint.
+proc AllocSlideJoint*(): PSlideJoint{.
+  cdecl, importc: "cpSlideJointAlloc", dynlib: Lib.}
+#/ Initialize a slide joint.
+proc init*(joint: PSlideJoint; a, b: PBody; anchr1, anchr2: TVector;
+            min, max: CpFloat): PSlideJoint{.
+  cdecl, importc: "cpSlideJointInit", dynlib: Lib.}
+#/ Allocate and initialize a slide joint.
+proc newSlideJoint*(a, b: PBody; anchr1, anchr2: TVector; min, max: CpFloat): PConstraint{.
+  cdecl, importc: "cpSlideJointNew", dynlib: Lib.}
+
+defCProp(SlideJoint, TVector, anchr1, Anchr1)
+defCProp(SlideJoint, TVector, anchr2, Anchr2)
+defCProp(SlideJoint, CpFloat, min, Min)
+defCProp(SlideJoint, CpFloat, max, Max)
+
+proc pivotJointGetClass*(): PConstraintClass {.
+  cdecl, importc: "cpPivotJointGetClass", dynlib: Lib.}
+
+#/ Allocate a pivot joint
+proc allocPivotJoint*(): PPivotJoint{.
+  cdecl, importc: "cpPivotJointAlloc", dynlib: Lib.}
+#/ Initialize a pivot joint.
+proc init*(joint: PPivotJoint; a, b: PBody; anchr1, anchr2: TVector): PPivotJoint{.
+  cdecl, importc: "cpPivotJointInit", dynlib: Lib.}
+#/ Allocate and initialize a pivot joint.
+proc newPivotJoint*(a, b: PBody; pivot: TVector): PConstraint{.
+  cdecl, importc: "cpPivotJointNew", dynlib: Lib.}
+#/ Allocate and initialize a pivot joint with specific anchors.
+proc newPivotJoint*(a, b: PBody; anchr1, anchr2: TVector): PConstraint{.
+  cdecl, importc: "cpPivotJointNew2", dynlib: Lib.}
+
+defCProp(PivotJoint, TVector, anchr1, Anchr1)
+defCProp(PivotJoint, TVector, anchr2, Anchr2)
+
+
+proc GrooveJointGetClass*(): PConstraintClass{.
+  cdecl, importc: "cpGrooveJointGetClass", dynlib: Lib.}
+#/ Allocate a groove joint.
+proc GrooveJointAlloc*(): ptr TGrooveJoint{.
+  cdecl, importc: "cpGrooveJointAlloc", dynlib: Lib.}
+#/ Initialize a groove joint.
+proc Init*(joint: PGrooveJoint; a, b: PBody; groove_a, groove_b, anchr2: TVector): PGrooveJoint{.
+  cdecl, importc: "cpGrooveJointInit", dynlib: Lib.}
+#/ Allocate and initialize a groove joint.
+proc newGrooveJoint*(a, b: PBody; groove_a, groove_b, anchr2: TVector): PConstraint{.
+  cdecl, importc: "cpGrooveJointNew", dynlib: Lib.}
+
+defCGetter(GrooveJoint, TVector, grv_a, GrooveA)
+defCGetter(GrooveJoint, TVector, grv_b, GrooveB)
+# /// Set endpoint a of a groove joint's groove
+proc SetGrooveA*(constraint: PConstraint, value: TVector) {.
+  cdecl, importc: "cpGrooveJointSetGrooveA", dynlib: Lib.}
+# /// Set endpoint b of a groove joint's groove
+proc SetGrooveB*(constraint: PConstraint, value: TVector) {.
+  cdecl, importc: "cpGrooveJointSetGrooveB", dynlib: Lib.}
+defCProp(GrooveJoint, TVector, anchr2, Anchr2)
+
+proc DampedSpringGetClass*(): PConstraintClass{.
+  cdecl, importc: "cpDampedSpringGetClass", dynlib: Lib.}
+#/ Allocate a damped spring.
+proc AllocDampedSpring*(): PDampedSpring{.
+  cdecl, importc: "cpDampedSpringAlloc", dynlib: Lib.}
+#/ Initialize a damped spring.
+proc init*(joint: PDampedSpring; a, b: PBody; anchr1, anchr2: TVector;
+            restLength, stiffness, damping: CpFloat): PDampedSpring{.
+  cdecl, importc: "cpDampedSpringInit", dynlib: Lib.}
+#/ Allocate and initialize a damped spring.
+proc newDampedSpring*(a, b: PBody; anchr1, anchr2: TVector; 
+                      restLength, stiffness, damping: CpFloat): PConstraint{.
+  cdecl, importc: "cpDampedSpringNew", dynlib: Lib.}
+
+# CP_DefineConstraintProperty(cpDampedSpring, cpVect, anchr1, Anchr1)
+defCProp(DampedSpring, TVector, anchr1, Anchr1)
+defCProp(DampedSpring, TVector, anchr2, Anchr2)
+defCProp(DampedSpring, CpFloat, restLength, RestLength)
+defCProp(DampedSpring, CpFloat, stiffness, Stiffness)
+defCProp(DampedSpring, CpFloat, damping, Damping)
+defCProp(DampedSpring, TDampedSpringForceFunc, springForceFunc, SpringForceFunc)
+
+
+proc DampedRotarySpringGetClass*(): PConstraintClass{.
+  cdecl, importc: "cpDampedRotarySpringGetClass", dynlib: Lib.}
+
+#/ Allocate a damped rotary spring.
+proc DampedRotarySpringAlloc*(): PDampedRotarySpring{.
+  cdecl, importc: "cpDampedRotarySpringAlloc", dynlib: Lib.}
+#/ Initialize a damped rotary spring.
+proc init*(joint: PDampedRotarySpring; a, b: PBody; 
+            restAngle, stiffness, damping: CpFloat): PDampedRotarySpring{.
+  cdecl, importc: "cpDampedRotarySpringInit", dynlib: Lib.}
+#/ Allocate and initialize a damped rotary spring.
+proc DampedRotarySpringNew*(a, b: PBody; restAngle, stiffness, damping: CpFloat): PConstraint{.
+  cdecl, importc: "cpDampedRotarySpringNew", dynlib: Lib.}
+
+defCProp(DampedRotarySpring, CpFloat, restAngle, RestAngle)
+defCProp(DampedRotarySpring, CpFloat, stiffness, Stiffness)
+defCProp(DampedRotarySpring, CpFloat, damping, Damping)
+defCProp(DampedRotarySpring, TDampedRotarySpringTorqueFunc, springTorqueFunc, SpringTorqueFunc)
+
+
+proc RotaryLimitJointGetClass*(): PConstraintClass{.
+  cdecl, importc: "cpRotaryLimitJointGetClass", dynlib: Lib.}
+#/ Allocate a damped rotary limit joint.
+proc allocRotaryLimitJoint*(): PRotaryLimitJoint{.
+  cdecl, importc: "cpRotaryLimitJointAlloc", dynlib: Lib.}
+#/ Initialize a damped rotary limit joint.
+proc init*(joint: PRotaryLimitJoint; a, b: PBody; min, max: CpFloat): PRotaryLimitJoint{.
+  cdecl, importc: "cpRotaryLimitJointInit", dynlib: Lib.}
+#/ Allocate and initialize a damped rotary limit joint.
+proc newRotaryLimitJoint*(a, b: PBody; min, max: CpFloat): PConstraint{.
+  cdecl, importc: "cpRotaryLimitJointNew", dynlib: Lib.}
+
+defCProp(RotaryLimitJoint, CpFloat, min, Min)
+defCProp(RotaryLimitJoint, CpFloat, max, Max)
+
+
+proc RatchetJointGetClass*(): PConstraintClass{.
+  cdecl, importc: "cpRatchetJointGetClass", dynlib: Lib.}
+#/ Allocate a ratchet joint.
+proc AllocRatchetJoint*(): PRatchetJoint{.
+  cdecl, importc: "cpRatchetJointAlloc", dynlib: Lib.}
+#/ Initialize a ratched joint.
+proc init*(joint: PRatchetJoint; a, b: PBody; phase, ratchet: CpFloat): PRatchetJoint{.
+  cdecl, importc: "cpRatchetJointInit", dynlib: Lib.}
+#/ Allocate and initialize a ratchet joint.
+proc NewRatchetJoint*(a, b: PBody; phase, ratchet: CpFloat): PConstraint{.
+  cdecl, importc: "cpRatchetJointNew", dynlib: Lib.}
+
+defCProp(RatchetJoint, CpFloat, angle, Angle)
+defCProp(RatchetJoint, CpFloat, phase, Phase)
+defCProp(RatchetJoint, CpFloat, ratchet, Ratchet)
+
+
+proc GearJointGetClass*(): PConstraintClass{.cdecl, 
+    importc: "cpGearJointGetClass", dynlib: Lib.}
+#/ Allocate a gear joint.
+proc AllocGearJoint*(): PGearJoint{.
+  cdecl, importc: "cpGearJointAlloc", dynlib: Lib.}
+#/ Initialize a gear joint.
+proc init*(joint: PGearJoint; a, b: PBody, phase, ratio: CpFloat): PGearJoint{.
+  cdecl, importc: "cpGearJointInit", dynlib: Lib.}
+#/ Allocate and initialize a gear joint.
+proc NewGearJoint*(a, b: PBody; phase, ratio: CpFloat): PConstraint{.
+  cdecl, importc: "cpGearJointNew", dynlib: Lib.}
+
+defCProp(GearJoint, CpFloat, phase, Phase)
+defCGetter(GearJoint, CpFloat, ratio, Ratio)
+#/ Set the ratio of a gear joint.
+proc GearJointSetRatio*(constraint: PConstraint; value: CpFloat){.
+  cdecl, importc: "cpGearJointSetRatio", dynlib: Lib.}
+
+
+proc SimpleMotorGetClass*(): PConstraintClass{.
+  cdecl, importc: "cpSimpleMotorGetClass", dynlib: Lib.}
+#/ Allocate a simple motor.
+proc AllocSimpleMotor*(): PSimpleMotor{.
+  cdecl, importc: "cpSimpleMotorAlloc", dynlib: Lib.}
+#/ initialize a simple motor.
+proc init*(joint: PSimpleMotor; a, b: PBody; 
+                      rate: CpFloat): PSimpleMotor{.
+  cdecl, importc: "cpSimpleMotorInit", dynlib: Lib.}
+#/ Allocate and initialize a simple motor.
+proc newSimpleMotor*(a, b: PBody; rate: CpFloat): PConstraint{.
+  cdecl, importc: "cpSimpleMotorNew", dynlib: Lib.}
+
+defCProp(SimpleMotor, CpFloat, rate, Rate)
+
+
+
diff --git a/tests/manyloc/keineschweine/dependencies/enet/enet.nim b/tests/manyloc/keineschweine/dependencies/enet/enet.nim
new file mode 100644
index 000000000..ad43c69b7
--- /dev/null
+++ b/tests/manyloc/keineschweine/dependencies/enet/enet.nim
@@ -0,0 +1,614 @@
+discard """Copyright (c) 2002-2012 Lee Salzman
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of 
+this software and associated documentation files (the "Software"), to deal in 
+the Software without restriction, including without limitation the rights to 
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all 
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""
+when defined(Linux):
+  const Lib = "libenet.so.1(|.0.3)"
+else:
+  {.error: "Your platform has not been accounted for."}
+{.deadCodeElim: ON.}
+const 
+  ENET_VERSION_MAJOR* = 1
+  ENET_VERSION_MINOR* = 3
+  ENET_VERSION_PATCH* = 3
+template ENET_VERSION_CREATE(major, minor, patch: expr): expr = 
+  (((major) shl 16) or ((minor) shl 8) or (patch))
+
+const 
+  ENET_VERSION* = ENET_VERSION_CREATE(ENET_VERSION_MAJOR, ENET_VERSION_MINOR, 
+                                      ENET_VERSION_PATCH)
+type 
+  TVersion* = cuint
+  TSocketType*{.size: sizeof(cint).} = enum 
+    ENET_SOCKET_TYPE_STREAM = 1, ENET_SOCKET_TYPE_DATAGRAM = 2
+  TSocketWait*{.size: sizeof(cint).} = enum 
+    ENET_SOCKET_WAIT_NONE = 0, ENET_SOCKET_WAIT_SEND = (1 shl 0), 
+    ENET_SOCKET_WAIT_RECEIVE = (1 shl 1)
+  TSocketOption*{.size: sizeof(cint).} = enum 
+    ENET_SOCKOPT_NONBLOCK = 1, ENET_SOCKOPT_BROADCAST = 2, 
+    ENET_SOCKOPT_RCVBUF = 3, ENET_SOCKOPT_SNDBUF = 4, 
+    ENET_SOCKOPT_REUSEADDR = 5
+const 
+  ENET_HOST_ANY* = 0
+  ENET_HOST_BROADCAST* = 0xFFFFFFFF
+  ENET_PORT_ANY* = 0
+  
+  ENET_PROTOCOL_MINIMUM_MTU* = 576
+  ENET_PROTOCOL_MAXIMUM_MTU* = 4096
+  ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS* = 32
+  ENET_PROTOCOL_MINIMUM_WINDOW_SIZE* = 4096
+  ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE* = 32768
+  ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT* = 1
+  ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT* = 255
+  ENET_PROTOCOL_MAXIMUM_PEER_ID* = 0x00000FFF
+type
+  PAddress* = ptr TAddress
+  TAddress*{.pure, final.} = object 
+    host*: cuint
+    port*: cushort
+  
+  TPacketFlag*{.size: sizeof(cint).} = enum 
+    FlagReliable = (1 shl 0), 
+    FlagUnsequenced = (1 shl 1), 
+    NoAllocate = (1 shl 2), 
+    UnreliableFragment = (1 shl 3)
+  
+  TENetListNode*{.pure, final.} = object 
+      next*: ptr T_ENetListNode
+      previous*: ptr T_ENetListNode
+
+  PENetListIterator* = ptr TENetListNode
+  TENetList*{.pure, final.} = object 
+    sentinel*: TENetListNode
+  
+  T_ENetPacket*{.pure, final.} = object 
+  TPacketFreeCallback* = proc (a2: ptr T_ENetPacket){.cdecl.}
+  
+  PPacket* = ptr TPacket
+  TPacket*{.pure, final.} = object 
+    referenceCount: csize
+    flags*: cint
+    data*: cstring#ptr cuchar
+    dataLength*: csize
+    freeCallback*: TPacketFreeCallback
+
+  PAcknowledgement* = ptr TAcknowledgement
+  TAcknowledgement*{.pure, final.} = object 
+    acknowledgementList*: TEnetListNode
+    sentTime*: cuint
+    command*: TEnetProtocol
+
+  POutgoingCommand* = ptr TOutgoingCommand
+  TOutgoingCommand*{.pure, final.} = object 
+    outgoingCommandList*: TEnetListNode
+    reliableSequenceNumber*: cushort
+    unreliableSequenceNumber*: cushort
+    sentTime*: cuint
+    roundTripTimeout*: cuint
+    roundTripTimeoutLimit*: cuint
+    fragmentOffset*: cuint
+    fragmentLength*: cushort
+    sendAttempts*: cushort
+    command*: TEnetProtocol
+    packet*: PPacket
+
+  PIncomingCommand* = ptr TIncomingCommand
+  TIncomingCommand*{.pure, final.} = object 
+    incomingCommandList*: TEnetListNode
+    reliableSequenceNumber*: cushort
+    unreliableSequenceNumber*: cushort
+    command*: TEnetProtocol
+    fragmentCount*: cuint
+    fragmentsRemaining*: cuint
+    fragments*: ptr cuint
+    packet*: ptr TPacket
+
+  TPeerState*{.size: sizeof(cint).} = enum 
+    ENET_PEER_STATE_DISCONNECTED = 0, ENET_PEER_STATE_CONNECTING = 1, 
+    ENET_PEER_STATE_ACKNOWLEDGING_CONNECT = 2, 
+    ENET_PEER_STATE_CONNECTION_PENDING = 3, 
+    ENET_PEER_STATE_CONNECTION_SUCCEEDED = 4, ENET_PEER_STATE_CONNECTED = 5, 
+    ENET_PEER_STATE_DISCONNECT_LATER = 6, ENET_PEER_STATE_DISCONNECTING = 7, 
+    ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT = 8, ENET_PEER_STATE_ZOMBIE = 9
+  
+  TENetProtocolCommand*{.size: sizeof(cint).} = enum 
+    ENET_PROTOCOL_COMMAND_NONE = 0, ENET_PROTOCOL_COMMAND_ACKNOWLEDGE = 1, 
+    ENET_PROTOCOL_COMMAND_CONNECT = 2, 
+    ENET_PROTOCOL_COMMAND_VERIFY_CONNECT = 3, 
+    ENET_PROTOCOL_COMMAND_DISCONNECT = 4, ENET_PROTOCOL_COMMAND_PING = 5, 
+    ENET_PROTOCOL_COMMAND_SEND_RELIABLE = 6, 
+    ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE = 7, 
+    ENET_PROTOCOL_COMMAND_SEND_FRAGMENT = 8, 
+    ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED = 9, 
+    ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT = 10, 
+    ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE = 11, 
+    ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT = 12, 
+    ENET_PROTOCOL_COMMAND_COUNT = 13, ENET_PROTOCOL_COMMAND_MASK = 0x0000000F
+  TENetProtocolFlag*{.size: sizeof(cint).} = enum 
+    ENET_PROTOCOL_HEADER_SESSION_SHIFT = 12,
+    ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED = (1 shl 6), 
+    ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE = (1 shl 7), 
+    ENET_PROTOCOL_HEADER_SESSION_MASK = (3 shl 12), 
+    ENET_PROTOCOL_HEADER_FLAG_COMPRESSED = (1 shl 14), 
+    ENET_PROTOCOL_HEADER_FLAG_SENT_TIME = (1 shl 15),
+    ENET_PROTOCOL_HEADER_FLAG_MASK = ENET_PROTOCOL_HEADER_FLAG_COMPRESSED.cint or
+        ENET_PROTOCOL_HEADER_FLAG_SENT_TIME.cint
+  
+  TENetProtocolHeader*{.pure, final.} = object 
+    peerID*: cushort
+    sentTime*: cushort
+
+  TENetProtocolCommandHeader*{.pure, final.} = object 
+    command*: cuchar
+    channelID*: cuchar
+    reliableSequenceNumber*: cushort
+
+  TENetProtocolAcknowledge*{.pure, final.} = object 
+    header*: TENetProtocolCommandHeader
+    receivedReliableSequenceNumber*: cushort
+    receivedSentTime*: cushort
+
+  TENetProtocolConnect*{.pure, final.} = object 
+    header*: TENetProtocolCommandHeader
+    outgoingPeerID*: cushort
+    incomingSessionID*: cuchar
+    outgoingSessionID*: cuchar
+    mtu*: cuint
+    windowSize*: cuint
+    channelCount*: cuint
+    incomingBandwidth*: cuint
+    outgoingBandwidth*: cuint
+    packetThrottleInterval*: cuint
+    packetThrottleAcceleration*: cuint
+    packetThrottleDeceleration*: cuint
+    connectID*: cuint
+    data*: cuint
+
+  TENetProtocolVerifyConnect*{.pure, final.} = object 
+    header*: TENetProtocolCommandHeader
+    outgoingPeerID*: cushort
+    incomingSessionID*: cuchar
+    outgoingSessionID*: cuchar
+    mtu*: cuint
+    windowSize*: cuint
+    channelCount*: cuint
+    incomingBandwidth*: cuint
+    outgoingBandwidth*: cuint
+    packetThrottleInterval*: cuint
+    packetThrottleAcceleration*: cuint
+    packetThrottleDeceleration*: cuint
+    connectID*: cuint
+
+  TENetProtocolBandwidthLimit*{.pure, final.} = object 
+    header*: TENetProtocolCommandHeader
+    incomingBandwidth*: cuint
+    outgoingBandwidth*: cuint
+
+  TENetProtocolThrottleConfigure*{.pure, final.} = object 
+    header*: TENetProtocolCommandHeader
+    packetThrottleInterval*: cuint
+    packetThrottleAcceleration*: cuint
+    packetThrottleDeceleration*: cuint
+
+  TENetProtocolDisconnect*{.pure, final.} = object 
+    header*: TENetProtocolCommandHeader
+    data*: cuint
+
+  TENetProtocolPing*{.pure, final.} = object 
+    header*: TENetProtocolCommandHeader
+
+  TENetProtocolSendReliable*{.pure, final.} = object 
+    header*: TENetProtocolCommandHeader
+    dataLength*: cushort
+
+  TENetProtocolSendUnreliable*{.pure, final.} = object 
+    header*: TENetProtocolCommandHeader
+    unreliableSequenceNumber*: cushort
+    dataLength*: cushort
+
+  TENetProtocolSendUnsequenced*{.pure, final.} = object 
+    header*: TENetProtocolCommandHeader
+    unsequencedGroup*: cushort
+    dataLength*: cushort
+
+  TENetProtocolSendFragment*{.pure, final.} = object 
+    header*: TENetProtocolCommandHeader
+    startSequenceNumber*: cushort
+    dataLength*: cushort
+    fragmentCount*: cuint
+    fragmentNumber*: cuint
+    totalLength*: cuint
+    fragmentOffset*: cuint
+  
+  ## this is incomplete; need helper templates or something
+  ## ENetProtocol
+  TENetProtocol*{.pure, final.} = object 
+    header*: TENetProtocolCommandHeader
+const 
+  ENET_BUFFER_MAXIMUM* = (1 + 2 * ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS)
+  ENET_HOST_RECEIVE_BUFFER_SIZE          = 256 * 1024
+  ENET_HOST_SEND_BUFFER_SIZE             = 256 * 1024
+  ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL  = 1000
+  ENET_HOST_DEFAULT_MTU                  = 1400
+
+  ENET_PEER_DEFAULT_ROUND_TRIP_TIME      = 500
+  ENET_PEER_DEFAULT_PACKET_THROTTLE      = 32
+  ENET_PEER_PACKET_THROTTLE_SCALE        = 32
+  ENET_PEER_PACKET_THROTTLE_COUNTER      = 7
+  ENET_PEER_PACKET_THROTTLE_ACCELERATION = 2
+  ENET_PEER_PACKET_THROTTLE_DECELERATION = 2
+  ENET_PEER_PACKET_THROTTLE_INTERVAL     = 5000
+  ENET_PEER_PACKET_LOSS_SCALE            = (1 shl 16)
+  ENET_PEER_PACKET_LOSS_INTERVAL         = 10000
+  ENET_PEER_WINDOW_SIZE_SCALE            = 64 * 1024
+  ENET_PEER_TIMEOUT_LIMIT                = 32
+  ENET_PEER_TIMEOUT_MINIMUM              = 5000
+  ENET_PEER_TIMEOUT_MAXIMUM              = 30000
+  ENET_PEER_PING_INTERVAL                = 500
+  ENET_PEER_UNSEQUENCED_WINDOWS          = 64
+  ENET_PEER_UNSEQUENCED_WINDOW_SIZE      = 1024
+  ENET_PEER_FREE_UNSEQUENCED_WINDOWS     = 32
+  ENET_PEER_RELIABLE_WINDOWS             = 16
+  ENET_PEER_RELIABLE_WINDOW_SIZE         = 0x1000
+  ENET_PEER_FREE_RELIABLE_WINDOWS        = 8
+
+when defined(Linux):
+  import posix
+  const
+    ENET_SOCKET_NULL*: cint = -1
+  type 
+    TENetSocket* = cint
+    PEnetBuffer* = ptr object
+    TENetBuffer*{.pure, final.} = object 
+      data*: pointer
+      dataLength*: csize
+    TENetSocketSet* = Tfd_set
+  ## see if these are different on win32, if not then get rid of these
+  template ENET_HOST_TO_NET_16*(value: expr): expr = 
+    (htons(value))
+  template ENET_HOST_TO_NET_32*(value: expr): expr = 
+    (htonl(value))
+  template ENET_NET_TO_HOST_16*(value: expr): expr = 
+    (ntohs(value))
+  template ENET_NET_TO_HOST_32*(value: expr): expr = 
+    (ntohl(value))
+
+  template ENET_SOCKETSET_EMPTY*(sockset: expr): expr = 
+    FD_ZERO(addr((sockset)))
+  template ENET_SOCKETSET_ADD*(sockset, socket: expr): expr = 
+    FD_SET(socket, addr((sockset)))
+  template ENET_SOCKETSET_REMOVE*(sockset, socket: expr): expr = 
+    FD_CLEAR(socket, addr((sockset)))
+  template ENET_SOCKETSET_CHECK*(sockset, socket: expr): expr = 
+    FD_ISSET(socket, addr((sockset)))
+
+when defined(Windows):
+  ## put the content of win32.h in here
+
+
+type 
+  PChannel* = ptr TChannel
+  TChannel*{.pure, final.} = object 
+    outgoingReliableSequenceNumber*: cushort
+    outgoingUnreliableSequenceNumber*: cushort
+    usedReliableWindows*: cushort
+    reliableWindows*: array[0..ENET_PEER_RELIABLE_WINDOWS - 1, cushort]
+    incomingReliableSequenceNumber*: cushort
+    incomingUnreliableSequenceNumber*: cushort
+    incomingReliableCommands*: TENetList
+    incomingUnreliableCommands*: TENetList
+
+  PPeer* = ptr TPeer
+  TPeer*{.pure, final.} = object 
+    dispatchList*: TEnetListNode
+    host*: ptr THost
+    outgoingPeerID*: cushort
+    incomingPeerID*: cushort
+    connectID*: cuint
+    outgoingSessionID*: cuchar
+    incomingSessionID*: cuchar
+    address*: TAddress
+    data*: pointer
+    state*: TPeerState
+    channels*: PChannel
+    channelCount*: csize
+    incomingBandwidth*: cuint
+    outgoingBandwidth*: cuint
+    incomingBandwidthThrottleEpoch*: cuint
+    outgoingBandwidthThrottleEpoch*: cuint
+    incomingDataTotal*: cuint
+    outgoingDataTotal*: cuint
+    lastSendTime*: cuint
+    lastReceiveTime*: cuint
+    nextTimeout*: cuint
+    earliestTimeout*: cuint
+    packetLossEpoch*: cuint
+    packetsSent*: cuint
+    packetsLost*: cuint
+    packetLoss*: cuint
+    packetLossVariance*: cuint
+    packetThrottle*: cuint
+    packetThrottleLimit*: cuint
+    packetThrottleCounter*: cuint
+    packetThrottleEpoch*: cuint
+    packetThrottleAcceleration*: cuint
+    packetThrottleDeceleration*: cuint
+    packetThrottleInterval*: cuint
+    lastRoundTripTime*: cuint
+    lowestRoundTripTime*: cuint
+    lastRoundTripTimeVariance*: cuint
+    highestRoundTripTimeVariance*: cuint
+    roundTripTime*: cuint
+    roundTripTimeVariance*: cuint
+    mtu*: cuint
+    windowSize*: cuint
+    reliableDataInTransit*: cuint
+    outgoingReliableSequenceNumber*: cushort
+    acknowledgements*: TENetList
+    sentReliableCommands*: TENetList
+    sentUnreliableCommands*: TENetList
+    outgoingReliableCommands*: TENetList
+    outgoingUnreliableCommands*: TENetList
+    dispatchedCommands*: TENetList
+    needsDispatch*: cint
+    incomingUnsequencedGroup*: cushort
+    outgoingUnsequencedGroup*: cushort
+    unsequencedWindow*: array[0..ENET_PEER_UNSEQUENCED_WINDOW_SIZE div 32 - 1, 
+                              cuint]
+    eventData*: cuint
+
+  PCompressor* = ptr TCompressor
+  TCompressor*{.pure, final.} = object 
+    context*: pointer
+    compress*: proc (context: pointer; inBuffers: ptr TEnetBuffer; 
+                     inBufferCount: csize; inLimit: csize; 
+                     outData: ptr cuchar; outLimit: csize): csize{.cdecl.}
+    decompress*: proc (context: pointer; inData: ptr cuchar; inLimit: csize; 
+                       outData: ptr cuchar; outLimit: csize): csize{.cdecl.}
+    destroy*: proc (context: pointer){.cdecl.}
+
+  TChecksumCallback* = proc (buffers: ptr TEnetBuffer; bufferCount: csize): cuint{.
+      cdecl.}
+  
+  PHost* = ptr THost
+  THost*{.pure, final.} = object 
+    socket*: TEnetSocket
+    address*: TAddress
+    incomingBandwidth*: cuint
+    outgoingBandwidth*: cuint
+    bandwidthThrottleEpoch*: cuint
+    mtu*: cuint
+    randomSeed*: cuint
+    recalculateBandwidthLimits*: cint
+    peers*: ptr TPeer
+    peerCount*: csize
+    channelLimit*: csize
+    serviceTime*: cuint
+    dispatchQueue*: TEnetList
+    continueSending*: cint
+    packetSize*: csize
+    headerFlags*: cushort
+    commands*: array[0..ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS - 1, 
+                     TEnetProtocol]
+    commandCount*: csize
+    buffers*: array[0..ENET_BUFFER_MAXIMUM - 1, TEnetBuffer]
+    bufferCount*: csize
+    checksum*: TChecksumCallback
+    compressor*: TCompressor
+    packetData*: array[0..ENET_PROTOCOL_MAXIMUM_MTU - 1, 
+                       array[0..2 - 1, cuchar]]
+    receivedAddress*: TAddress
+    receivedData*: ptr cuchar
+    receivedDataLength*: csize
+    totalSentData*: cuint
+    totalSentPackets*: cuint
+    totalReceivedData*: cuint
+    totalReceivedPackets*: cuint
+  
+  TEventType*{.size: sizeof(cint).} = enum 
+    EvtNone = 0, EvtConnect = 1, 
+    EvtDisconnect = 2, EvtReceive = 3
+  PEvent* = ptr TEvent
+  TEvent*{.pure, final.} = object 
+    kind*: TEventType
+    peer*: ptr TPeer
+    channelID*: cuchar
+    data*: cuint
+    packet*: ptr TPacket
+
+  TENetCallbacks*{.pure, final.} = object 
+    malloc*: proc (size: csize): pointer{.cdecl.}
+    free*: proc (memory: pointer){.cdecl.}
+    no_memory*: proc (){.cdecl.}
+
+{.push callConv:cdecl.}
+proc enet_malloc*(a2: csize): pointer{.
+  importc: "enet_malloc", dynlib: Lib.}
+proc enet_free*(a2: pointer){.
+  importc: "enet_free", dynlib: Lib.}
+
+proc enetInit*(): cint{.
+  importc: "enet_initialize", dynlib: Lib.}
+proc enetInit*(version: TVersion; inits: ptr TENetCallbacks): cint{.
+  importc: "enet_initialize_with_callbacks", dynlib: Lib.}
+proc enetDeinit*(){.
+  importc: "enet_deinitialize", dynlib: Lib.}
+proc enet_time_get*(): cuint{.
+  importc: "enet_time_get", dynlib: Lib.}
+proc enet_time_set*(a2: cuint){.
+  importc: "enet_time_set", dynlib: Lib.}
+
+#enet docs are pretty lacking, i'm not sure what the names of these arguments should be
+proc createSocket*(kind: TSocketType): TEnetSocket{.
+  importc: "enet_socket_create", dynlib: Lib.}
+proc bindTo*(socket: TEnetSocket; address: var TAddress): cint{.
+  importc: "enet_socket_bind", dynlib: Lib.}
+proc bindTo*(socket: TEnetSocket; address: ptr TAddress): cint{.
+  importc: "enet_socket_bind", dynlib: Lib.}
+proc listen*(socket: TEnetSocket; a3: cint): cint{.
+  importc: "enet_socket_listen", dynlib: Lib.}
+proc accept*(socket: TEnetSocket; address: var TAddress): TEnetSocket{.
+  importc: "enet_socket_accept", dynlib: Lib.}
+proc accept*(socket: TEnetSocket; address: ptr TAddress): TEnetSocket{.
+  importc: "enet_socket_accept", dynlib: Lib.}
+proc connect*(socket: TEnetSocket; address: var TAddress): cint{.
+  importc: "enet_socket_connect", dynlib: Lib.}
+proc connect*(socket: TEnetSocket; address: ptr TAddress): cint{.
+  importc: "enet_socket_connect", dynlib: Lib.}
+proc send*(socket: TEnetSocket; address: var TAddress; buffer: ptr TEnetBuffer; size: csize): cint{.
+  importc: "enet_socket_send", dynlib: Lib.}
+proc send*(socket: TEnetSocket; address: ptr TAddress; buffer: ptr TEnetBuffer; size: csize): cint{.
+  importc: "enet_socket_send", dynlib: Lib.}
+proc receive*(socket: TEnetSocket; address: var TAddress; 
+               buffer: ptr TEnetBuffer; size: csize): cint{.
+  importc: "enet_socket_receive", dynlib: Lib.}
+proc receive*(socket: TEnetSocket; address: ptr TAddress; 
+               buffer: ptr TEnetBuffer; size: csize): cint{.
+  importc: "enet_socket_receive", dynlib: Lib.}
+proc wait*(socket: TEnetSocket; a3: ptr cuint; a4: cuint): cint{.
+  importc: "enet_socket_wait", dynlib: Lib.}
+proc setOption*(socket: TEnetSocket; a3: TSocketOption; a4: cint): cint{.
+  importc: "enet_socket_set_option", dynlib: Lib.}
+proc destroy*(socket: TEnetSocket){.
+  importc: "enet_socket_destroy", dynlib: Lib.}
+proc select*(socket: TEnetSocket; a3: ptr TENetSocketSet; 
+              a4: ptr TENetSocketSet; a5: cuint): cint{.
+  importc: "enet_socketset_select", dynlib: Lib.}
+
+proc setHost*(address: PAddress; hostName: cstring): cint{.
+  importc: "enet_address_set_host", dynlib: Lib.}
+proc setHost*(address: var TAddress; hostName: cstring): cint{.
+  importc: "enet_address_set_host", dynlib: Lib.}
+proc getHostIP*(address: var TAddress; hostName: cstring; nameLength: csize): cint{.
+  importc: "enet_address_get_host_ip", dynlib: Lib.}
+proc getHost*(address: var TAddress; hostName: cstring; nameLength: csize): cint{.
+  importc: "enet_address_get_host", dynlib: Lib.}
+
+## Call the above two funcs but trim the result string
+proc getHostIP*(address: var TAddress; hostName: var string; nameLength: csize): cint{.inline.} =
+  hostName.setLen nameLength
+  result = getHostIP(address, cstring(hostName), nameLength)
+  if result == 0:
+    hostName.setLen(len(cstring(hostName)))
+proc getHost*(address: var TAddress; hostName: var string; nameLength: csize): cint{.inline.} =
+  hostName.setLen nameLength
+  result = getHost(address, cstring(hostName), nameLength)
+  if result == 0:
+    hostName.setLen(len(cstring(hostName)))
+
+proc createPacket*(data: pointer; len: csize; flag: TPacketFlag): PPacket{.
+  importc: "enet_packet_create", dynlib: Lib.}
+proc destroy*(packet: PPacket){.
+  importc: "enet_packet_destroy", dynlib: Lib.}
+proc resize*(packet: PPacket; dataLength: csize): cint{.
+  importc: "enet_packet_resize", dynlib: Lib.}
+
+proc crc32*(buffers: ptr TEnetBuffer; bufferCount: csize): cuint{.
+  importc: "enet_crc32", dynlib: Lib.}
+
+proc createHost*(address: ptr TAddress; maxConnections, maxChannels: csize; downSpeed, upSpeed: cuint): PHost{.
+  importc: "enet_host_create", dynlib: Lib.}
+proc createHost*(address: var TAddress; maxConnections, maxChannels: csize; downSpeed, upSpeed: cuint): PHost{.
+  importc: "enet_host_create", dynlib: Lib.}
+proc destroy*(host: PHost){.
+  importc: "enet_host_destroy", dynlib: Lib.}
+proc connect*(host: PHost; address: ptr TAddress; channelCount: csize; data: cuint): PPeer{.
+  importc: "enet_host_connect", dynlib: Lib.}
+proc connect*(host: PHost; address: var TAddress; channelCount: csize; data: cuint): PPeer{.
+  importc: "enet_host_connect", dynlib: Lib.}
+
+proc checkEvents*(host: PHost; event: var TEvent): cint{.
+  importc: "enet_host_check_events", dynlib: Lib.}
+proc checkEvents*(host: PHost; event: ptr TEvent): cint{.
+  importc: "enet_host_check_events", dynlib: Lib.}
+proc hostService*(host: PHost; event: var TEvent; timeout: cuint): cint{.
+  importc: "enet_host_service", dynlib: Lib.}
+proc hostService*(host: PHost; event: ptr TEvent; timeout: cuint): cint{.
+  importc: "enet_host_service", dynlib: Lib.}
+proc flush*(host: PHost){.
+  importc: "enet_host_flush", dynlib: Lib.}
+proc broadcast*(host: PHost; channelID: cuchar; packet: PPacket){.
+  importc: "enet_host_broadcast", dynlib: Lib.}
+proc compress*(host: PHost; compressor: PCompressor){.
+  importc: "enet_host_compress", dynlib: Lib.}
+proc compressWithRangeCoder*(host: PHost): cint{.
+  importc: "enet_host_compress_with_range_coder", dynlib: Lib.}
+proc channelLimit*(host: PHost; channelLimit: csize){.
+  importc: "enet_host_channel_limit", dynlib: Lib.}
+proc bandwidthLimit*(host: PHost; incoming, outgoing: cuint){.
+  importc: "enet_host_bandwidth_limit", dynlib: Lib.}
+proc bandwidthThrottle*(host: PHost){.
+  importc: "enet_host_bandwidth_throttle", dynlib: Lib.}
+
+
+proc send*(peer: PPeer; channel: cuchar; packet: PPacket): cint{.
+  importc: "enet_peer_send", dynlib: Lib.}
+proc receive*(peer: PPeer; channelID: ptr cuchar): PPacket{.
+  importc: "enet_peer_receive", dynlib: Lib.}
+proc ping*(peer: PPeer){.
+  importc: "enet_peer_ping", dynlib: Lib.}
+proc reset*(peer: PPeer){.
+  importc: "enet_peer_reset", dynlib: Lib.}
+proc disconnect*(peer: PPeer; a3: cuint){.
+  importc: "enet_peer_disconnect", dynlib: Lib.}
+proc disconnectNow*(peer: PPeer; a3: cuint){.
+  importc: "enet_peer_disconnect_now", dynlib: Lib.}
+proc disconnectLater*(peer: PPeer; a3: cuint){.
+  importc: "enet_peer_disconnect_later", dynlib: Lib.}
+proc throttleConfigure*(peer: PPeer; interval, acceleration, deceleration: cuint){.
+  importc: "enet_peer_throttle_configure", dynlib: Lib.}
+proc throttle*(peer: PPeer; rtt: cuint): cint{.
+  importc: "enet_peer_throttle", dynlib: Lib.}
+proc resetQueues*(peer: PPeer){.
+  importc: "enet_peer_reset_queues", dynlib: Lib.}
+proc setupOutgoingCommand*(peer: PPeer; outgoingCommand: POutgoingCommand){.
+  importc: "enet_peer_setup_outgoing_command", dynlib: Lib.}
+
+proc queueOutgoingCommand*(peer: PPeer; command: ptr TEnetProtocol; 
+          packet: PPacket; offset: cuint; length: cushort): POutgoingCommand{.
+  importc: "enet_peer_queue_outgoing_command", dynlib: Lib.}
+proc queueIncomingCommand*(peer: PPeer; command: ptr TEnetProtocol; 
+                    packet: PPacket; fragmentCount: cuint): PIncomingCommand{.
+  importc: "enet_peer_queue_incoming_command", dynlib: Lib.}
+proc queueAcknowledgement*(peer: PPeer; command: ptr TEnetProtocol; 
+                            sentTime: cushort): PAcknowledgement{.
+  importc: "enet_peer_queue_acknowledgement", dynlib: Lib.}
+proc dispatchIncomingUnreliableCommands*(peer: PPeer; channel: PChannel){.
+  importc: "enet_peer_dispatch_incoming_unreliable_commands", dynlib: Lib.}
+proc dispatchIncomingReliableCommands*(peer: PPeer; channel: PChannel){.
+  importc: "enet_peer_dispatch_incoming_reliable_commands", dynlib: Lib.}
+
+proc createRangeCoder*(): pointer{.
+  importc: "enet_range_coder_create", dynlib: Lib.}
+proc rangeCoderDestroy*(context: pointer){.
+  importc: "enet_range_coder_destroy", dynlib: Lib.}
+proc rangeCoderCompress*(context: pointer; inBuffers: PEnetBuffer; inLimit, 
+               bufferCount: csize; outData: cstring; outLimit: csize): csize{.
+  importc: "enet_range_coder_compress", dynlib: Lib.}
+proc rangeCoderDecompress*(context: pointer; inData: cstring; inLimit: csize; 
+                            outData: cstring; outLimit: csize): csize{.
+  importc: "enet_range_coder_decompress", dynlib: Lib.}
+proc protocolCommandSize*(commandNumber: cuchar): csize{.
+  importc: "enet_protocol_command_size", dynlib: Lib.}
+
+{.pop.}
+
+from hashes import `!$`, `!&`, THash, hash
+proc hash*(x: TAddress): THash {.nimcall, noSideEffect.} =
+  result = !$(hash(x.host.int32) !& hash(x.port.int16))
+
diff --git a/tests/manyloc/keineschweine/dependencies/enet/testclient.nim b/tests/manyloc/keineschweine/dependencies/enet/testclient.nim
new file mode 100644
index 000000000..2447a1fb5
--- /dev/null
+++ b/tests/manyloc/keineschweine/dependencies/enet/testclient.nim
@@ -0,0 +1,49 @@
+import enet, strutils
+
+if enetInit() != 0:
+  quit "Could not initialize ENet"
+var
+  address: enet.TAddress
+  event: TEvent
+  peer: PPeer
+  client: PHost
+
+client = createHost(nil, 1, 2, 0, 0)
+if client == nil:
+  quit "Could not create client!"
+
+if setHost(addr address, "localhost") != 0:
+  quit "Could not set host"
+address.port = 8024
+
+peer = client.connect(addr address, 2, 0)
+if peer == nil:
+  quit "No available peers"
+
+block:
+  var bConnected = false
+  while not bConnected:
+    if client.hostService(event, 5000) > 0 and event.kind == EvtConnect:
+      echo "Connected"
+      bConnected = true
+    else:
+      echo "Connection failed"
+      quit 0
+
+var runServer = true
+while client.hostService(event, 1000) >= 0 and runServer:
+  case event.kind
+  of EvtReceive:
+    echo "Recvd ($1) $2 ".format(
+      event.packet.dataLength,
+      event.packet.data)
+  of EvtDisconnect:
+    echo "Disconnected"
+    event.peer.data = nil
+    runServer = false
+  of EvtNone: discard
+  else:
+    echo repr(event)
+
+
+client.destroy()
diff --git a/tests/manyloc/keineschweine/dependencies/enet/testserver.nim b/tests/manyloc/keineschweine/dependencies/enet/testserver.nim
new file mode 100644
index 000000000..28a6bd1f7
--- /dev/null
+++ b/tests/manyloc/keineschweine/dependencies/enet/testserver.nim
@@ -0,0 +1,45 @@
+import enet, strutils
+var
+  address: enet.TAddress
+  server: PHost
+  event: TEvent
+
+if enetInit() != 0:
+  quit "Could not initialize ENet"
+
+address.host = EnetHostAny
+address.port = 8024
+
+server = enet.createHost(
+  addr address, 32, 2,  0,  0)
+if server == nil:
+  quit "Could not create the server!"
+
+while server.hostService(addr event, 2500) >= 0:
+  case event.kind
+  of EvtConnect:
+    echo "New client from $1:$2".format(event.peer.address.host, event.peer.address.port)
+    
+    var
+      msg = "hello" 
+      resp = createPacket(cstring(msg), msg.len + 1, FlagReliable)
+      
+    if event.peer.send(0.cuchar, resp) < 0:
+      echo "FAILED"
+    else:
+      echo "Replied"
+  of EvtReceive:
+    echo "Recvd ($1) $2 ".format(
+      event.packet.dataLength,
+      event.packet.data)
+    
+    destroy(event.packet)
+    
+  of EvtDisconnect:
+    echo "Disconnected"
+    event.peer.data = nil
+  else:
+    discard
+
+server.destroy()
+enetDeinit()
\ No newline at end of file
diff --git a/tests/manyloc/keineschweine/dependencies/genpacket/genpacket.nim b/tests/manyloc/keineschweine/dependencies/genpacket/genpacket.nim
new file mode 100644
index 000000000..ae9dfb39f
--- /dev/null
+++ b/tests/manyloc/keineschweine/dependencies/genpacket/genpacket.nim
@@ -0,0 +1,295 @@
+import macros, macro_dsl, streams, streams_enh
+from strutils import format
+
+template newLenName(): stmt {.immediate.} =
+  let lenName {.inject.} = ^("len"& $lenNames)
+  inc(lenNames)
+
+template defPacketImports*(): stmt {.immediate, dirty.} =
+  import macros, macro_dsl, streams, streams_enh
+  from strutils import format
+
+proc `$`*[T](x: seq[T]): string =
+  result = "[seq len="
+  result.add($x.len)
+  result.add ':'
+  for i in 0.. <len(x):
+    result.add "   "
+    result.add($x[i])
+  result.add ']'
+
+macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} = 
+  result = newNimNode(nnkStmtList)
+  let 
+    typeName = quoted2ident(typeNameN)
+    packetID = ^"p"
+    streamID = ^"s"
+  var
+    constructorParams = newNimNode(nnkFormalParams).und(typeName)
+    constructor = newNimNode(nnkProcDef).und(
+      postfix(^("new"& $typeName.ident), "*"),
+      emptyNode(),
+      emptyNode(),
+      constructorParams,
+      emptyNode(),
+      emptyNode())
+    pack = newNimNode(nnkProcDef).und(
+      postfix(^"pack", "*"),
+      emptyNode(),
+      emptyNode(),
+      newNimNode(nnkFormalParams).und(
+        emptyNode(),   # : void
+        newNimNode(nnkIdentDefs).und(
+          packetID,    # p: var typeName
+          newNimNode(nnkVarTy).und(typeName),
+          emptyNode()),
+        newNimNode(nnkIdentDefs).und(
+          streamID,    # s: PStream
+          ^"PStream",
+          newNimNode(nnkNilLit))),
+      emptyNode(),
+      emptyNode())
+    read = newNimNode(nnkProcDef).und(
+      newIdentNode("read"& $typeName.ident).postfix("*"),
+      emptyNode(),
+      emptyNode(),
+      newNimNode(nnkFormalParams).und(
+        typeName,   #result type
+        newNimNode(nnkIdentDefs).und(
+          streamID, # s: PStream = nil
+          ^"PStream",
+          newNimNode(nnkNilLit))),
+      emptyNode(),
+      emptyNode())
+    constructorBody = newNimNode(nnkStmtList)
+    packBody = newNimNode(nnkStmtList)
+    readBody = newNimNode(nnkStmtList)
+    lenNames = 0
+  for i in 0.. typeFields.len - 1:
+    let 
+      name = typeFields[i][0]
+      dotName = packetID.dot(name)
+      resName = newIdentNode(!"result").dot(name)
+    case typeFields[i][1].kind
+    of nnkBracketExpr: #ex: paddedstring[32, '\0'], array[range, type]
+      case $typeFields[i][1][0].ident
+      of "paddedstring":
+        let length = typeFields[i][1][1]
+        let padChar = typeFields[i][1][2]
+        packBody.add(newCall(
+          "writePaddedStr", streamID, dotName, length, padChar))
+        ## result.name = readPaddedStr(s, length, char)
+        readBody.add(resName := newCall(
+          "readPaddedStr", streamID, length, padChar))
+        ## make the type a string
+        typeFields[i] = newNimNode(nnkIdentDefs).und(
+          name,
+          ^"string",
+          newNimNode(nnkEmpty))
+      of "array":
+        readBody.add(
+          newNimNode(nnkDiscardStmt).und(
+            newCall("readData", streamID, newNimNode(nnkAddr).und(resName), newCall("sizeof", resName))))
+        packBody.add(
+          newCall("writeData", streamID, newNimNode(nnkAddr).und(dotName), newCall("sizeof", dotName))) 
+      of "seq":
+        ## let lenX = readInt16(s)
+        newLenName()
+        let 
+          item = ^"item"  ## item name in our iterators
+          seqType = typeFields[i][1][1] ## type of seq
+          readName = newIdentNode("read"& $seqType.ident)
+        readBody.add(newNimNode(nnkLetSection).und(
+          newNimNode(nnkIdentDefs).und(
+            lenName,
+            newNimNode(nnkEmpty),
+            newCall("readInt16", streamID))))
+        readBody.add(      ## result.name = @[]
+          resName := ("@".prefix(newNimNode(nnkBracket))),
+          newNimNode(nnkForStmt).und(  ## for item in 1..len:
+            item, 
+            infix(1.lit, "..", lenName),
+            newNimNode(nnkStmtList).und(
+              newCall(  ## add(result.name, unpack[seqType](stream))
+                "add", resName, newNimNode(nnkCall).und(readName, streamID)
+        ) ) ) )
+        packbody.add(
+          newNimNode(nnkVarSection).und(newNimNode(nnkIdentDefs).und(
+            lenName,  ## var lenName = int16(len(p.name))
+            newIdentNode("int16"),
+            newCall("int16", newCall("len", dotName)))), 
+          newCall("writeData", streamID, newNimNode(nnkAddr).und(lenName), 2.lit),
+          newNimNode(nnkForStmt).und(  ## for item in 0..length - 1: pack(p.name[item], stream)
+            item,
+            infix(0.lit, "..", infix(lenName, "-", 1.lit)),
+            newNimNode(nnkStmtList).und(
+              newCall("echo", item, ": ".lit),
+              newCall("pack", dotName[item], streamID))))
+        #set the default value to @[] (new sequence)
+        typeFields[i][2] = "@".prefix(newNimNode(nnkBracket))
+      else:
+        error("Unknown type: "& treeRepr(typeFields[i]))
+    of nnkIdent: ##normal type
+      case $typeFields[i][1].ident
+      of "string": # length encoded string
+        packBody.add(newCall("writeLEStr", streamID, dotName))
+        readBody.add(resName := newCall("readLEStr", streamID))
+      of "int8", "int16", "int32", "float32", "float64", "char", "bool":
+        packBody.add(newCall(
+          "writeData", streamID, newNimNode(nnkAddr).und(dotName), newCall("sizeof", dotName)))
+        readBody.add(resName := newCall("read"& $typeFields[i][1].ident, streamID))
+      else:  ## hopefully the type you specified was another defpacket() type
+        packBody.add(newCall("pack", dotName, streamID))
+        readBody.add(resName := newCall("read"& $typeFields[i][1].ident, streamID))
+    else:
+      error("I dont know what to do with: "& treerepr(typeFields[i]))
+  
+  var 
+    toStringFunc = newNimNode(nnkProcDef).und(
+      newNimNode(nnkPostfix).und(
+        ^"*",
+        newNimNode(nnkAccQuoted).und(^"$")),
+      emptyNode(),
+      emptyNode(),
+      newNimNode(nnkFormalParams).und(
+        ^"string",
+        newNimNode(nnkIdentDefs).und(
+          packetID, # p: typeName
+          typeName,
+          emptyNode())),
+      emptyNode(),
+      emptyNode(),
+      newNimNode(nnkStmtList).und(#[6]
+        newNimNode(nnkAsgn).und(
+          ^"result",                  ## result = 
+          newNimNode(nnkCall).und(#[6][0][1]
+            ^"format",  ## format
+            emptyNode()))))  ## "[TypeName   $1   $2]"
+    formatStr = "["& $typeName.ident
+  
+  const emptyFields = {nnkEmpty, nnkNilLit}
+  var objFields = newNimNode(nnkRecList)
+  for i in 0.. < len(typeFields):
+    let fname = typeFields[i][0]
+    constructorParams.add(newNimNode(nnkIdentDefs).und(
+      fname,
+      typeFields[i][1],
+      typeFields[i][2]))
+    constructorBody.add((^"result").dot(fname) := fname)
+    #export the name
+    typeFields[i][0] = fname.postfix("*")
+    if not(typeFields[i][2].kind in emptyFields):
+      ## empty the type default for the type def
+      typeFields[i][2] = newNimNode(nnkEmpty)
+    objFields.add(typeFields[i])
+    toStringFunc[6][0][1].add(
+      prefix("$", packetID.dot(fname)))
+    formatStr.add "   $"
+    formatStr.add($(i + 1))
+  
+  formatStr.add ']'
+  toStringFunc[6][0][1][1] = formatStr.lit()
+  
+  result.add(
+    newNimNode(nnkTypeSection).und(
+      newNimNode(nnkTypeDef).und(
+        typeName.postfix("*"),
+        newNimNode(nnkEmpty),
+        newNimNode(nnkObjectTy).und(
+          newNimNode(nnkEmpty), #not sure what this is
+          newNimNode(nnkEmpty), #parent: OfInherit(Ident(!"SomeObj"))
+          objFields))))
+  result.add(constructor.und(constructorBody))
+  result.add(pack.und(packBody))
+  result.add(read.und(readBody))
+  result.add(toStringFunc)
+  when defined(GenPacketShowOutput):
+    echo(repr(result))
+
+proc `->`(a: string, b: string): PNimrodNode {.compileTime.} =
+  result = newNimNode(nnkIdentDefs).und(^a, ^b, newNimNode(nnkEmpty))
+proc `->`(a: string, b: PNimrodNode): PNimrodNode {.compileTime.} =
+  result = newNimNode(nnkIdentDefs).und(^a, b, newNimNode(nnkEmpty))
+proc `->`(a, b: PNimrodNode): PNimrodNode {.compileTime.} =
+  a[2] = b
+  result = a
+
+proc newProc*(name: string, params: varargs[PNimrodNode], resultType: PNimrodNode): PNimrodNode {.compileTime.} =
+  result = newNimNode(nnkProcDef).und(
+    ^name,
+    emptyNode(),
+    emptyNode(),
+    newNimNode(nnkFormalParams).und(resultType),
+    emptyNode(),
+    emptyNode(),
+    newNimNode(nnkStmtList))
+  result[3].add(params)
+macro forwardPacket*(typeName: expr, underlyingType: typedesc): stmt {.immediate.} =
+  result = newNimNode(nnkStmtList).und(
+    newProc(
+      "read"& $typeName.ident, 
+      ["s" -> "PStream" -> newNimNode(nnkNilLit)],
+      typeName),
+    newProc(
+      "pack",
+      [ "p" -> newNimNode(nnkVarTy).und(typeName),
+        "s" -> "PStream" -> newNimNode(nnkNilLit)],
+      emptyNode()))
+  result[0][6].add(newNimNode(nnkDiscardStmt).und(
+    newCall(
+      "readData", ^"s", newNimNode(nnkAddr).und(^"result"), newCall("sizeof", ^"result")
+    )))
+  result[1][6].add(
+    newCall(
+      "writeData", ^"s", newNimNode(nnkAddr).und(^"p"), newCall(
+        "sizeof", ^"p")))
+  when defined(GenPacketShowOutput):
+    echo(repr(result))
+
+template forwardPacketT*(typeName: expr): stmt {.dirty, immediate.} =
+  proc `read typeName`*(s: PStream): typeName =
+    discard readData(s, addr result, sizeof(result))
+  proc `pack typeName`*(p: var typeName; s: PStream) =
+    writeData(s, addr p, sizeof(p))
+
+when isMainModule:
+  type
+    SomeEnum = enum
+      A = 0'i8,
+      B, C
+  forwardPacket(SomeEnum, int8)
+  
+  
+  defPacket(Foo, tuple[x: array[0..4, int8]])
+  var f = newFoo([4'i8, 3'i8, 2'i8, 1'i8, 0'i8])
+  var s2 = newStringStream("")
+  f.pack(s2)
+  assert s2.data == "\4\3\2\1\0"
+  
+  var s = newStringStream()
+  s.flushImpl = proc(s: PStream) =
+    var z = PStringStream(s)
+    z.setPosition(0)
+    z.data.setLen(0)
+  
+  
+  s.setPosition(0)
+  s.data.setLen(0)
+  var o = B
+  o.pack(s)
+  o = A
+  o.pack(s)
+  o = C
+  o.pack(s)
+  assert s.data == "\1\0\2"
+  s.flush
+  
+  defPacket(Y, tuple[z: int8])
+  proc `$`(z: Y): string = result = "Y("& $z.z &")"
+  defPacket(TestPkt, tuple[x: seq[Y]])
+  var test = newTestPkt()
+  test.x.add([newY(5), newY(4), newY(3), newY(2), newY(1)])
+  for itm in test.x:
+    echo(itm)
+  test.pack(s)
+  echo(repr(s.data))
\ No newline at end of file
diff --git a/tests/manyloc/keineschweine/dependencies/genpacket/genpacket_enet.nim b/tests/manyloc/keineschweine/dependencies/genpacket/genpacket_enet.nim
new file mode 100644
index 000000000..44d00db53
--- /dev/null
+++ b/tests/manyloc/keineschweine/dependencies/genpacket/genpacket_enet.nim
@@ -0,0 +1,296 @@
+import macros, macro_dsl, estreams
+from strutils import format
+
+template newLenName(): stmt {.immediate.} =
+  let lenName {.inject.} = ^("len"& $lenNames)
+  inc(lenNames)
+
+template defPacketImports*(): stmt {.immediate, dirty.} =
+  import macros, macro_dsl, estreams
+  from strutils import format
+
+proc `$`*[T](x: seq[T]): string =
+  result = "[seq len="
+  result.add($x.len)
+  result.add ':'
+  for i in 0.. <len(x):
+    result.add "   "
+    result.add($x[i])
+  result.add ']'
+
+macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} = 
+  result = newNimNode(nnkStmtList)
+  let 
+    typeName = quoted2ident(typeNameN)
+    packetID = ^"p"
+    streamID = ^"s"
+  var
+    constructorParams = newNimNode(nnkFormalParams).und(typeName)
+    constructor = newNimNode(nnkProcDef).und(
+      postfix(^("new"& $typeName.ident), "*"),
+      emptyNode(),
+      emptyNode(),
+      constructorParams,
+      emptyNode(),
+      emptyNode())
+    pack = newNimNode(nnkProcDef).und(
+      postfix(^"pack", "*"),
+      emptyNode(),
+      emptyNode(),
+      newNimNode(nnkFormalParams).und(
+        emptyNode(),   # : void
+        newNimNode(nnkIdentDefs).und(
+          streamID,    # s: PBuffer
+          ^"PBuffer",
+          newNimNode(nnkNilLit)),
+        newNimNode(nnkIdentDefs).und(
+          packetID,    # p: var typeName
+          newNimNode(nnkVarTy).und(typeName),
+          emptyNode())),
+      emptyNode(),
+      emptyNode())
+    read = newNimNode(nnkProcDef).und(
+      newIdentNode("read"& $typeName.ident).postfix("*"),
+      emptyNode(),
+      emptyNode(),
+      newNimNode(nnkFormalParams).und(
+        typeName,   #result type
+        newNimNode(nnkIdentDefs).und(
+          streamID, # s: PBuffer = nil
+          ^"PBuffer",
+          newNimNode(nnkNilLit))),
+      emptyNode(),
+      emptyNode())
+    constructorBody = newNimNode(nnkStmtList)
+    packBody = newNimNode(nnkStmtList)
+    readBody = newNimNode(nnkStmtList)
+    lenNames = 0
+  for i in 0.. typeFields.len - 1:
+    let 
+      name = typeFields[i][0]
+      dotName = packetID.dot(name)
+      resName = newIdentNode(!"result").dot(name)
+    case typeFields[i][1].kind
+    of nnkBracketExpr: #ex: paddedstring[32, '\0'], array[range, type]
+      case $typeFields[i][1][0].ident
+      of "seq":
+        ## let lenX = readInt16(s)
+        newLenName()
+        let 
+          item = ^"item"  ## item name in our iterators
+          seqType = typeFields[i][1][1] ## type of seq
+          readName = newIdentNode("read"& $seqType.ident)
+        readBody.add(newNimNode(nnkLetSection).und(
+          newNimNode(nnkIdentDefs).und(
+            lenName,
+            newNimNode(nnkEmpty),
+            newCall("readInt16", streamID))))
+        readBody.add(      ## result.name = @[]
+          resName := ("@".prefix(newNimNode(nnkBracket))),
+          newNimNode(nnkForStmt).und(  ## for item in 1..len:
+            item, 
+            infix(1.lit, "..", lenName),
+            newNimNode(nnkStmtList).und(
+              newCall(  ## add(result.name, unpack[seqType](stream))
+                "add", resName, newNimNode(nnkCall).und(readName, streamID)
+        ) ) ) )
+        packbody.add(
+          newNimNode(nnkVarSection).und(newNimNode(nnkIdentDefs).und(
+            lenName,  ## var lenName = int16(len(p.name))
+            newIdentNode("int16"),
+            newCall("int16", newCall("len", dotName)))), 
+          newCall("writeBE", streamID, lenName),
+          newNimNode(nnkForStmt).und(  ## for item in 0..length - 1: pack(p.name[item], stream)
+            item,
+            infix(0.lit, "..", infix(lenName, "-", 1.lit)),
+            newNimNode(nnkStmtList).und(
+              newCall("echo", item, ": ".lit),
+              newCall("pack", streamID, dotName[item]))))
+        #set the default value to @[] (new sequence)
+        typeFields[i][2] = "@".prefix(newNimNode(nnkBracket))
+      else:
+        error("Unknown type: "& treeRepr(typeFields[i]))
+    of nnkIdent: ##normal type
+      case $typeFields[i][1].ident
+      of "string": # length encoded string
+        packBody.add(newCall("write", streamID, dotName))
+        readBody.add(resName := newCall("readStr", streamID))
+      of "int8", "int16", "int32", "float32", "float64", "char", "bool":
+        packBody.add(newCall(
+          "writeBE", streamID, dotName))
+        readBody.add(resName := newCall("read"& $typeFields[i][1].ident, streamID))
+      else:  ## hopefully the type you specified was another defpacket() type
+        packBody.add(newCall("pack", streamID, dotName))
+        readBody.add(resName := newCall("read"& $typeFields[i][1].ident, streamID))
+    else:
+      error("I dont know what to do with: "& treerepr(typeFields[i]))
+  
+  var 
+    toStringFunc = newNimNode(nnkProcDef).und(
+      newNimNode(nnkPostfix).und(
+        ^"*",
+        newNimNode(nnkAccQuoted).und(^"$")),
+      emptyNode(),
+      emptyNode(),
+      newNimNode(nnkFormalParams).und(
+        ^"string",
+        newNimNode(nnkIdentDefs).und(
+          packetID, # p: typeName
+          typeName,
+          emptyNode())),
+      emptyNode(),
+      emptyNode(),
+      newNimNode(nnkStmtList).und(#[6]
+        newNimNode(nnkAsgn).und(
+          ^"result",                  ## result = 
+          newNimNode(nnkCall).und(#[6][0][1]
+            ^"format",  ## format
+            emptyNode()))))  ## "[TypeName   $1   $2]"
+    formatStr = "["& $typeName.ident
+  
+  const emptyFields = {nnkEmpty, nnkNilLit}
+  var objFields = newNimNode(nnkRecList)
+  for i in 0.. < len(typeFields):
+    let fname = typeFields[i][0]
+    constructorParams.add(newNimNode(nnkIdentDefs).und(
+      fname,
+      typeFields[i][1],
+      typeFields[i][2]))
+    constructorBody.add((^"result").dot(fname) := fname)
+    #export the name
+    typeFields[i][0] = fname.postfix("*")
+    if not(typeFields[i][2].kind in emptyFields):
+      ## empty the type default for the type def
+      typeFields[i][2] = newNimNode(nnkEmpty)
+    objFields.add(typeFields[i])
+    toStringFunc[6][0][1].add(
+      prefix("$", packetID.dot(fname)))
+    formatStr.add "   $"
+    formatStr.add($(i + 1))
+  
+  formatStr.add ']'
+  toStringFunc[6][0][1][1] = formatStr.lit()
+  
+  result.add(
+    newNimNode(nnkTypeSection).und(
+      newNimNode(nnkTypeDef).und(
+        typeName.postfix("*"),
+        newNimNode(nnkEmpty),
+        newNimNode(nnkObjectTy).und(
+          newNimNode(nnkEmpty), #not sure what this is
+          newNimNode(nnkEmpty), #parent: OfInherit(Ident(!"SomeObj"))
+          objFields))))
+  result.add(constructor.und(constructorBody))
+  result.add(pack.und(packBody))
+  result.add(read.und(readBody))
+  result.add(toStringFunc)
+  when defined(GenPacketShowOutput):
+    echo(repr(result))
+
+proc newProc*(name: PNimrodNode; params: varargs[PNimrodNode]; resultType: PNimrodNode): PNimrodNode {.compileTime.} =
+  result = newNimNode(nnkProcDef).und(
+    name,
+    emptyNode(),
+    emptyNode(),
+    newNimNode(nnkFormalParams).und(resultType),
+    emptyNode(),
+    emptyNode(),
+    newNimNode(nnkStmtList))
+  result[3].add(params)
+
+proc body*(procNode: PNimrodNode): PNimrodNode {.compileTime.} =
+  assert procNode.kind == nnkProcDef and procNode[6].kind == nnkStmtList
+  result = procNode[6]
+
+proc iddefs*(a, b: string; c: PNimrodNode): PNimrodNode {.compileTime.} =
+  result = newNimNode(nnkIdentDefs).und(^a, ^b, c)
+proc iddefs*(a: string; b: PNimrodNode): PNimrodNode {.compileTime.} =
+  result = newNimNode(nnkIdentDefs).und(^a, b, emptyNode())
+proc varTy*(a: PNimrodNode): PNimrodNode {.compileTime.} =
+  result = newNimNode(nnkVarTy).und(a)
+
+macro forwardPacket*(typeName: expr, underlyingType: expr): stmt {.immediate.} =
+  var
+    packetID = ^"p"
+    streamID = ^"s"
+  result = newNimNode(nnkStmtList).und(
+    newProc(
+      (^("read"& $typeName.ident)).postfix("*"), 
+      [ iddefs("s", "PBuffer", newNimNode(nnkNilLit)) ],
+      typeName),
+    newProc(
+      (^"pack").postfix("*"),
+      [ iddefs("s", "PBuffer", newNimNode(nnkNilLit)),
+        iddefs("p", varTy(typeName)) ],
+      emptyNode()))
+  var
+    readBody = result[0][6]
+    packBody = result[1][6]
+    resName = ^"result"
+  
+  case underlyingType.kind
+  of nnkBracketExpr:
+    case $underlyingType[0].ident
+    of "array":
+      for i in underlyingType[1][1].intval.int .. underlyingType[1][2].intval.int:
+        readBody.add(
+          newCall("read", ^"s", resName[lit(i)]))
+        packBody.add(
+          newCall("writeBE", ^"s", packetID[lit(i)]))
+    else:
+      echo "Unknown type: ", repr(underlyingtype)
+  else:
+    echo "unknown type:", repr(underlyingtype)
+  echo(repr(result))
+
+template forwardPacketT*(typeName: expr; underlyingType: expr): stmt {.dirty, immediate.} =
+  proc `read typeName`*(buffer: PBuffer): typeName =
+    #discard readData(s, addr result, sizeof(result))
+    var res: underlyingType
+    buffer.read(res)
+    result = typeName(res)
+  proc `pack`*(buffer: PBuffer; ord: var typeName) =
+    #writeData(s, addr p, sizeof(p))
+    buffer.write(underlyingType(ord))
+
+when isMainModule:
+  type
+    SomeEnum = enum
+      A = 0'i8,
+      B, C
+  forwardPacket(SomeEnum, int8)
+  
+  
+  defPacket(Foo, tuple[x: array[0..4, int8]])
+  var f = newFoo([4'i8, 3'i8, 2'i8, 1'i8, 0'i8])
+  var s2 = newStringStream("")
+  f.pack(s2)
+  assert s2.data == "\4\3\2\1\0"
+  
+  var s = newStringStream()
+  s.flushImpl = proc(s: PStream) =
+    var z = PStringStream(s)
+    z.setPosition(0)
+    z.data.setLen(0)
+  
+  
+  s.setPosition(0)
+  s.data.setLen(0)
+  var o = B
+  o.pack(s)
+  o = A
+  o.pack(s)
+  o = C
+  o.pack(s)
+  assert s.data == "\1\0\2"
+  s.flush
+  
+  defPacket(Y, tuple[z: int8])
+  proc `$`(z: Y): string = result = "Y("& $z.z &")"
+  defPacket(TestPkt, tuple[x: seq[Y]])
+  var test = newTestPkt()
+  test.x.add([newY(5), newY(4), newY(3), newY(2), newY(1)])
+  for itm in test.x:
+    echo(itm)
+  test.pack(s)
+  echo(repr(s.data))
\ No newline at end of file
diff --git a/tests/manyloc/keineschweine/dependencies/genpacket/macro_dsl.nim b/tests/manyloc/keineschweine/dependencies/genpacket/macro_dsl.nim
new file mode 100644
index 000000000..cbae1334e
--- /dev/null
+++ b/tests/manyloc/keineschweine/dependencies/genpacket/macro_dsl.nim
@@ -0,0 +1,73 @@
+import macros
+{.deadCodeElim: on.}
+#Inline macro.add() to allow for easier nesting
+proc und*(a: PNimrodNode; b: PNimrodNode): PNimrodNode {.compileTime.} =
+  a.add(b)
+  result = a
+proc und*(a: PNimrodNode; b: varargs[PNimrodNode]): PNimrodNode {.compileTime.} =
+  a.add(b)
+  result = a
+
+proc `^`*(a: string): PNimrodNode {.compileTime.} = 
+  ## new ident node
+  result = newIdentNode(!a)
+proc `[]`*(a, b: PNimrodNode): PNimrodNode {.compileTime.} =
+  ## new bracket expression: node[node] not to be confused with node[indx]
+  result = newNimNode(nnkBracketExpr).und(a, b)
+proc `:=`*(left, right: PNimrodNode): PNimrodNode {.compileTime.} =
+  ## new Asgn node:  left = right
+  result = newNimNode(nnkAsgn).und(left, right)
+
+proc lit*(a: string): PNimrodNode {.compileTime.} =
+  result = newStrLitNode(a)
+proc lit*(a: int): PNimrodNode {.compileTime.} =
+  result = newIntLitNode(a)
+proc lit*(a: float): PNimrodNode {.compileTime.} =
+  result = newFloatLitNode(a)
+proc lit*(a: char): PNimrodNode {.compileTime.} =
+  result = newNimNode(nnkCharLit)
+  result.intval = a.ord
+
+proc emptyNode*(): PNimrodNode {.compileTime.} =
+  result = newNimNode(nnkEmpty)
+
+proc dot*(left, right: PNimrodNode): PNimrodNode {.compileTime.} =
+  result = newNimNode(nnkDotExpr).und(left, right)
+proc postfix*(a: PNimrodNode, b: string): PNimrodNode {.compileTime.} =
+  result = newNimNode(nnkPostfix).und(newIdentNode(!b), a)
+proc prefix*(a: string, b: PNimrodNode): PNimrodNode {.compileTime.} =
+  result = newNimNode(nnkPrefix).und(newIdentNode(!a), b)
+
+proc infix*(a, b, c: PNimrodNode): PNimrodNode {.compileTime.} =
+  ## 5.infix("+", 10)  ## => 5 + 10
+  result = newNimNode(nnkInfix).und(b, a, c)
+proc infix*(a: PNimrodNode; b: string; c: PNimrodNode): PNimrodNode {.compileTime.} =
+  ## Infix operation: infix(5, "+", 10) ## => 
+  result = newNimNode(nnkInfix).und(newIdentNode(b), a, c)
+
+proc quoted2ident*(a: PNimrodNode): PNimrodNode {.compileTime.} = 
+  if a.kind != nnkAccQuoted:
+    return a
+  var pname = ""
+  for piece in 0..a.len - 1:
+    pname.add($a[piece].ident)
+  result = ^pname
+
+
+macro `?`(a: expr): expr =
+  ## Character literal ?A #=> 'A'
+  result = ($a[1].ident)[0].lit
+## echo(?F,?a,?t,?t,?y)
+
+when isMainModule:
+  macro foo(x: stmt): stmt =
+    result = newNimNode(nnkStmtList)
+    result.add(newNimNode(nnkCall).und(!!"echo", "Hello thar".lit))
+    result.add(newCall("echo", lit("3 * 45 = "), (3.lit.infix("*", 45.lit))))
+    let stmtlist = x[1]
+    for i in countdown(len(stmtlist)-1, 0):
+      result.add(stmtlist[i])
+  foo:
+    echo y, " * 2 = ", y * 2
+    let y = 320
+
diff --git a/tests/manyloc/keineschweine/dependencies/genpacket/streams_enh.nim b/tests/manyloc/keineschweine/dependencies/genpacket/streams_enh.nim
new file mode 100644
index 000000000..a9759687f
--- /dev/null
+++ b/tests/manyloc/keineschweine/dependencies/genpacket/streams_enh.nim
@@ -0,0 +1,47 @@
+import streams
+from strutils import repeatChar
+
+proc readPaddedStr*(s: PStream, length: int, padChar = '\0'): TaintedString = 
+  var lastChr = length
+  result = s.readStr(length)
+  while lastChr >= 0 and result[lastChr - 1] == padChar: dec(lastChr)
+  result.setLen(lastChr)
+
+proc writePaddedStr*(s: PStream, str: string, length: int, padChar = '\0') =
+  if str.len < length:
+    s.write(str)
+    s.write(repeatChar(length - str.len, padChar))
+  elif str.len > length:
+    s.write(str.substr(0, length - 1))
+  else:
+    s.write(str)
+
+proc readLEStr*(s: PStream): TaintedString =
+  var len = s.readInt16()
+  result = s.readStr(len)
+
+proc writeLEStr*(s: PStream, str: string) =
+  s.write(str.len.int16)
+  s.write(str)
+
+when isMainModule:
+  var testStream = newStringStream()
+  
+  testStream.writeLEStr("Hello")
+  doAssert testStream.data == "\5\0Hello"
+  
+  testStream.setPosition 0
+  var res = testStream.readLEStr()
+  doAssert res == "Hello"
+  
+  testStream.setPosition 0
+  testStream.writePaddedStr("Sup", 10)
+  echo(repr(testStream), testStream.data.len)
+  doAssert testStream.data == "Sup"&repeatChar(7, '\0')
+  
+  testStream.setPosition 0
+  res = testStream.readPaddedStr(10)
+  doAssert res == "Sup"
+  
+  testStream.close()
+
diff --git a/tests/manyloc/keineschweine/dependencies/nake/nake.nim b/tests/manyloc/keineschweine/dependencies/nake/nake.nim
new file mode 100644
index 000000000..eade28c70
--- /dev/null
+++ b/tests/manyloc/keineschweine/dependencies/nake/nake.nim
@@ -0,0 +1,83 @@
+discard """
+DO AS THOU WILST PUBLIC LICENSE
+
+Whoever should stumble upon this document is henceforth and forever
+entitled to DO AS THOU WILST with aforementioned document and the
+contents thereof. 
+
+As said in the Olde Country, `Keepe it Gangster'."""
+
+import strutils, parseopt, tables, os
+
+type
+  PTask* = ref object
+    desc*: string
+    action*: TTaskFunction
+  TTaskFunction* = proc() {.closure.}
+var 
+  tasks* = initTable[string, PTask](16)
+
+proc newTask*(desc: string; action: TTaskFunction): PTask
+proc runTask*(name: string) {.inline.}
+proc shell*(cmd: varargs[string, `$`]): int {.discardable.}
+proc cd*(dir: string) {.inline.}
+
+template nakeImports*(): stmt {.immediate.} =
+  import tables, parseopt, strutils, os
+
+template task*(name: string; description: string; body: stmt): stmt {.dirty, immediate.} =
+  block:
+    var t = newTask(description, proc() {.closure.} =
+      body)
+    tasks[name] = t
+
+proc newTask*(desc: string; action: TTaskFunction): PTask =
+  new(result)
+  result.desc = desc
+  result.action = action
+proc runTask*(name: string) = tasks[name].action()
+
+proc shell*(cmd: varargs[string, `$`]): int =
+  result = execShellCmd(cmd.join(" "))
+proc cd*(dir: string) = setCurrentDir(dir)
+template withDir*(dir: string; body: stmt): stmt =
+  ## temporary cd
+  ## withDir "foo":
+  ##   # inside foo
+  ## #back to last dir
+  var curDir = getCurrentDir()
+  cd(dir)
+  body
+  cd(curDir)
+
+when isMainModule:
+  if not existsFile("nakefile.nim"):
+    echo "No nakefile.nim found. Current working dir is ", getCurrentDir()
+    quit 1
+  var args = ""
+  for i in 1..paramCount():
+    args.add paramStr(i)
+    args.add " "
+  quit(shell("nimrod", "c", "-r", "nakefile.nim", args))
+else:
+  addQuitProc(proc() {.noconv.} =
+    var 
+      task: string
+      printTaskList: bool
+    for kind, key, val in getOpt():
+      case kind
+      of cmdLongOption, cmdShortOption:
+        case key.tolower
+        of "tasks", "t":
+          printTaskList = true
+        else: 
+          echo "Unknown option: ", key, ": ", val
+      of cmdArgument:
+        task = key
+      else: nil
+    if printTaskList or task.isNil or not(tasks.hasKey(task)):
+      echo "Available tasks:"
+      for name, task in pairs(tasks):
+        echo name, " - ", task.desc
+      quit 0
+    tasks[task].action())
diff --git a/tests/manyloc/keineschweine/dependencies/nake/nakefile.nim b/tests/manyloc/keineschweine/dependencies/nake/nakefile.nim
new file mode 100644
index 000000000..24af63d10
--- /dev/null
+++ b/tests/manyloc/keineschweine/dependencies/nake/nakefile.nim
@@ -0,0 +1,23 @@
+import nake
+nakeImports
+
+task "install", "compile and install nake binary":
+  if shell("nimrod", "c", "nake") == 0:
+    let path = getEnv("PATH").split(PathSep)
+    for index, dir in pairs(path):
+      echo "  ", index, ". ", dir
+    echo "Where to install nake binary? (quit with ^C or quit or exit)"
+    let ans = stdin.readLine().toLower
+    var index = 0
+    case ans
+    of "q", "quit", "x", "exit":
+      quit 0
+    else:
+      index = parseInt(ans)
+    if index > path.len or index < 0:
+      echo "Invalid index."
+      quit 1
+    moveFile "nake", path[index]/"nake"
+    echo "Great success!"
+
+
diff --git a/tests/manyloc/keineschweine/dependencies/sfml/README.md b/tests/manyloc/keineschweine/dependencies/sfml/README.md
new file mode 100644
index 000000000..bd9b3d0e7
--- /dev/null
+++ b/tests/manyloc/keineschweine/dependencies/sfml/README.md
@@ -0,0 +1,13 @@
+sfml-nimrod
+===========
+
+Nimrod binding of SFML 2.0
+
+This is only tested for Linux at the moment
+
+### What is needed for Windows / OS X?
+
+* The library names need filling in
+* TWindowHandle is handled differently on those platforms
+
+I believe that is it
diff --git a/tests/manyloc/keineschweine/dependencies/sfml/sfml.nim b/tests/manyloc/keineschweine/dependencies/sfml/sfml.nim
new file mode 100644
index 000000000..27163e271
--- /dev/null
+++ b/tests/manyloc/keineschweine/dependencies/sfml/sfml.nim
@@ -0,0 +1,1115 @@
+import 
+  strutils, math
+when defined(linux):
+  const
+    LibG = "libcsfml-graphics.so.2.0"
+    LibS = "libcsfml-system.so.2.0"
+    LibW = "libcsfml-window.so.2.0"
+else:
+  {.error: "Platform unsupported".}
+{.deadCodeElim: on.}
+{.pragma: pf, pure, final.}
+type
+  PClock* = ptr TClock
+  TClock* {.pf.} = object
+  TTime* {.pf.} = object
+    microseconds*: int64
+  TVector2i* {.pf.} = object
+    x*, y*: cint
+  TVector2f* {.pf.} = object
+    x*, y*: cfloat
+  TVector3f* {.pf.} = object
+    x*, y*, z*: cfloat
+
+  PInputStream* = ptr TInputStream
+  TInputStream* {.pf.} = object 
+    read*: TInputStreamReadFunc
+    seek*: TInputStreamSeekFunc
+    tell*: TInputStreamTellFunc
+    getSize*: TInputStreamGetSizeFunc
+    userData*: pointer
+  TInputStreamReadFunc* = proc (data: pointer, size: int64, userData: pointer): int64{.
+    cdecl.}
+  TInputStreamSeekFunc* = proc (position: int16, userData: pointer): int64{.
+    cdecl.}
+  TInputStreamTellFunc* = proc (userData: pointer): int64 {.cdecl.}
+  TInputStreamGetSizeFunc* = proc (userData: pointer): int64 {.cdecl.}
+  PWindow* = ptr TWindow
+  TWindow* {.pf.} = object
+  PContextSettings* = ptr TContextSettings
+  TContextSettings*{.pf.} = object
+    depthBits: cint
+    stencilBits: cint
+    antialiasingLevel: cint
+    majorVersion: cint
+    minorVersion: cint
+  TVideoMode* {.pf.} = object
+    width*: cint
+    height*: cint
+    bitsPerPixel*: cint
+  TEventType*{.size: sizeof(cint).} = enum 
+    EvtClosed, EvtResized, EvtLostFocus, EvtGainedFocus, 
+    EvtTextEntered, EvtKeyPressed, EvtKeyReleased, EvtMouseWheelMoved, 
+    EvtMouseButtonPressed, EvtMouseButtonReleased, EvtMouseMoved, 
+    EvtMouseEntered, EvtMouseLeft, EvtJoystickButtonPressed, 
+    EvtJoystickButtonReleased, EvtJoystickMoved, EvtJoystickConnected, 
+    EvtJoystickDisconnected
+  TKeyEvent*{.pf.} = object 
+    code*: TKeyCode
+    alt*    : bool
+    control*: bool
+    shift*  : bool
+    system* : bool
+  TJoystickConnectEvent*{.pf.} = object
+    joystickId*: cint
+  TJoystickButtonEvent*{.pf.} = object
+    joystickId*: cint
+    button*: cint
+  TJoystickMoveEvent*{.pf.} = object
+    joystickId*: cint
+    axis*: TJoystickAxis
+    position*: cfloat
+  TMouseWheelEvent*{.pf.} = object 
+    delta*: cint
+    x*: cint
+    y*: cint
+  TMouseButtonEvent*{.pf.} = object
+    button*: TMouseButton
+    x*: cint
+    y*: cint
+  TMouseMoveEvent*{.pf.} = object
+    x*: cint
+    y*: cint
+  TTextEvent*{.pf.} = object
+    unicode*: cint
+  PEvent* = ptr TEvent
+  TEvent*{.pf.} = object
+    case kind*: TEventType
+    of EvtKeyPressed, EvtKeyReleased: 
+      key*: TKeyEvent
+    of EvtMouseButtonPressed, EvtMouseButtonReleased:
+      mouseButton*: TMouseButtonEvent
+    of EvtTextEntered:
+      text*: TTextEvent
+    of EvtJoystickConnected, EvtJoystickDisconnected:
+      joystickConnect*: TJoystickConnectEvent
+    of EvtJoystickMoved:
+      joystickMove*: TJoystickMoveEvent
+    of EvtJoystickButtonPressed, EvtJoystickButtonReleased:
+      joystickButton*: TJoystickButtonEvent
+    of EvtResized:
+      size*: TSizeEvent
+    of EvtMouseMoved, EvtMouseEntered, EvtMouseLeft:
+      mouseMove*: TMouseMoveEvent
+    of EvtMouseWheelMoved:
+      mouseWheel*: TMouseWheelEvent
+    else: nil
+  TJoystickAxis*{.size: sizeof(cint).} = enum 
+    JoystickX, JoystickY, JoystickZ, JoystickR,      
+    JoystickU, JoystickV, JoystickPovX, JoystickPovY
+  TSizeEvent*{.pf.} = object
+    width*: cint
+    height*: cint
+  TMouseButton*{.size: sizeof(cint).} = enum 
+    MouseLeft, MouseRight, MouseMiddle,  
+    MouseXButton1, MouseXButton2, MouseButtonCount
+  TKeyCode*{.size: sizeof(cint).} = enum 
+    KeyUnknown = - 1, KeyA, KeyB, KeyC, KeyD, KeyE,
+    KeyF, KeyG, KeyH, KeyI, KeyJ, KeyK, KeyL, KeyM,                 #/< The M key
+    KeyN, KeyO, KeyP, KeyQ, KeyR, KeyS, KeyT, KeyU,                 #/< The U key
+    KeyV, KeyW, KeyX, KeyY, KeyZ, KeyNum0, KeyNum1,              #/< The 1 key
+    KeyNum2, KeyNum3, KeyNum4, KeyNum5, KeyNum6,              #/< The 6 key
+    KeyNum7, KeyNum8, KeyNum9, KeyEscape, KeyLControl,          #/< The left Control key
+    KeyLShift, KeyLAlt, KeyLSystem, KeyRControl,          #/< The right Control key
+    KeyRShift, KeyRAlt, KeyRSystem, KeyMenu,              #/< The Menu key
+    KeyLBracket, KeyRBracket, KeySemiColon, KeyComma,             #/< The , key
+    KeyPeriod, KeyQuote, KeySlash, KeyBackSlash,         #/< The \ key
+    KeyTilde, KeyEqual, KeyDash, KeySpace, KeyReturn,            #/< The Return key
+    KeyBack, KeyTab, KeyPageUp, KeyPageDown, KeyEnd,               #/< The End key
+    KeyHome, KeyInsert, KeyDelete, KeyAdd, KeySubtract,          #/< -
+    KeyMultiply, KeyDivide, KeyLeft, KeyRight, KeyUp,                #/< Up arrow
+    KeyDown, KeyNumpad0, KeyNumpad1, KeyNumpad2,           #/< The numpad 2 key
+    KeyNumpad3,           #/< The numpad 3 key
+    KeyNumpad4,           #/< The numpad 4 key
+    KeyNumpad5,           #/< The numpad 5 key
+    KeyNumpad6,           #/< The numpad 6 key
+    KeyNumpad7,           #/< The numpad 7 key
+    KeyNumpad8,           #/< The numpad 8 key
+    KeyNumpad9,           #/< The numpad 9 key
+    KeyF1,                #/< The F1 key
+    KeyF2,                #/< The F2 key
+    KeyF3,                #/< The F3 key
+    KeyF4,                #/< The F4 key
+    KeyF5,                #/< The F5 key
+    KeyF6,                #/< The F6 key
+    KeyF7,                #/< The F7 key
+    KeyF8,                #/< The F8 key
+    KeyF9,                #/< The F8 key
+    KeyF10,               #/< The F10 key
+    KeyF11,               #/< The F11 key
+    KeyF12,               #/< The F12 key
+    KeyF13,               #/< The F13 key
+    KeyF14,               #/< The F14 key
+    KeyF15,               #/< The F15 key
+    KeyPause,             #/< The Pause key
+    KeyCount              #/< Keep last -- the total number of keyboard keys
+when defined(linux): #or defined(bsd) ??
+  type TWindowHandle* = clong
+#elif defined(mac):
+#  type TWindowHandle* = pointer ##typedef void* sfWindowHandle; <- whatever the hell that is
+#elif defined(windows):
+#  type TWindowHandle* = HWND__ ? windows is crazy. ##struct HWND__; typedef struct HWND__* sfWindowHandle;
+const
+  sfNone*         = 0
+  sfTitlebar*     = 1 shl 0
+  sfResize*       = 1 shl 1
+  sfClose*        = 1 shl 2
+  sfFullscreen*   = 1 shl 3
+  sfDefaultStyle* = sfTitlebar or sfResize or sfClose
+type
+  PRenderWindow* = ptr TRenderWindow
+  TRenderWindow* {.pf.} = object
+
+  PFont* = ptr TFont
+  TFont* {.pf.} = object
+  PImage* = ptr TImage
+  TImage* {.pf.} = object
+  PShader* = ptr TShader
+  TShader* {.pf.} = object
+  PSprite* = ptr TSprite
+  TSprite* {.pf.} = object
+  PText* = ptr TText
+  TText* {.pf.} = object
+  PTexture* = ptr TTexture
+  TTexture* {.pf.} = object
+  PVertexArray* = ptr TVertexArray
+  TVertexArray* {.pf.} = object
+  PView* = ptr TView
+  TView* {.pf.} = object
+  PRenderTexture* = ptr TRenderTexture
+  TRenderTexture* {.pf.} = object
+
+  PShape* = ptr TShape
+  TShape* {.pf.} = object
+  PCircleShape* = ptr TCircleShape
+  TCircleShape* {.pf.} = object
+  PRectangleShape* = ptr TRectangleShape
+  TRectangleShape* {.pf.} = object
+  PConvexShape* = ptr TConvexShape
+  TConvexShape* {.pf.} = object
+
+  TTextStyle*{.size: sizeof(cint).} = enum 
+    TextRegular = 0, TextBold = 1 shl 0, TextItalic = 1 shl 1, 
+    TextUnderlined = 1 shl 2
+
+  TBlendMode*{.size: sizeof(cint).} = enum 
+      BlendAlpha, BlendAdd, BlendMultiply, BlendNone
+  PRenderStates* = ptr TRenderStates
+  TRenderStates* {.pf.} = object
+    blendMode*: TBlendMode
+    transform*: TTransform
+    texture*: PTexture
+    shader*: PShader
+
+  PTransform* = ptr TTransform
+  TTransform* {.pf.} = object
+    matrix*: array[0..8, cfloat]
+  TColor* {.pf.} = object 
+    r*: Uint8
+    g*: Uint8
+    b*: Uint8
+    a*: Uint8
+  PFloatRect* = ptr TFloatRect
+  TFloatRect*{.pf.} = object 
+    left*: cfloat
+    top*: cfloat
+    width*: cfloat
+    height*: cfloat
+  PIntRect* = ptr TIntRect
+  TIntRect*{.pf.} = object 
+    left*: cint
+    top*: cint
+    width*: cint
+    height*: cint
+  TGlyph* {.pf.} = object
+    advance*: cint
+    bounds*: TIntRect
+    textureRect*: TIntRect
+  PVertex* = ptr TVertex
+  TVertex* {.pf.} = object
+    position*: TVector2f
+    color*: TColor
+    texCoords*: TVector2f
+  TPrimitiveType*{.size: sizeof(cint).} = enum 
+    Points,               #/< List of individual points
+    Lines,                #/< List of individual lines
+    LinesStrip,           #/< List of connected lines, a point uses the previous point to form a line
+    Triangles,            #/< List of individual triangles
+    TrianglesStrip,       #/< List of connected triangles, a point uses the two previous points to form a triangle
+    TrianglesFan,         #/< List of connected triangles, a point uses the common center and the previous point to form a triangle
+    Quads
+
+
+proc newWindow*(mode: TVideoMode, title: cstring, style: uint32, settings: PContextSettings = nil): PWindow {.
+  cdecl, importc: "sfWindow_create", dynlib: LibW.}
+
+proc close*(window: PWindow) {.
+  cdecl, importc: "sfWindow_close", dynlib: LibW.}
+proc isOpen*(window: PWindow): bool {.cdecl, importc: "sfWindow_isOpen", dynlib: LibW.}
+
+proc pollEvent*(window: PWindow, event: PEvent): bool {.
+  cdecl, importc: "sfWindow_pollEvent", dynlib: LibW.}
+proc waitEvent*(window: PWindow, event: PEvent): bool {.
+  cdecl, importc: "sfWindow_waitEvent", dynlib: LibW.}
+
+proc getDesktopMode*(): TVideoMode {.
+  cdecl, importc: "sfVideoMode_getDesktopMode", dynlib: LibW.}
+proc isKeyPressed*(key: TKeyCode): bool {.
+  cdecl, importc: "sfKeyboard_isKeyPressed", dynlib: LibW.}
+
+proc mouseIsButtonPressed*(button: TMouseButton): bool {.
+  cdecl, importc: "sfMouse_isButtonPressed", dynlib: LibW.}
+proc mouseGetPosition*(relativeTo: PWindow): TVector2i {.
+  cdecl, importc: "sfMouse_getPosition", dynlib: LibW.}
+proc mouseSetPosition*(position: TVector2i, relativeTo: PWindow) {.
+  cdecl, importc: "sfMouse_setPosition", dynlib: LibW.}
+
+proc joystickIsConnected*(joystick: cint): bool {.
+  cdecl, importc: "sfJoystick_isConnected", dynlib: LibW.}
+proc joystickGetButtonCount*(joystick: cint): cint {.
+  cdecl, importc: "sfJoystick_getButtonCount", dynlib: LibW.}
+proc joystickHasAxis*(joystick: cint, axis: TJoystickAxis): bool {.
+  cdecl, importc: "sfJoystick_hasAxis", dynlib: LibW.}
+proc joystickIsButtonPressed*(joystick: cint, button: cint): bool {.
+  cdecl, importc: "sfJoystick_isButtonPressed", dynlib: LibW.}
+proc joystickGetAxisPosition*(joystick: cint, axis: TJoystickAxis): float {.
+  cdecl, importc: "sfJoystick_getAxisPosition", dynlib: LibW.}
+proc joystickUpdate*(): void {.
+  cdecl, importc: "sfJoystick_update", dynlib: LibW.}
+
+
+proc newRenderWindow*(handle: TWindowHandle, settings: PContextSettings = nil): PRenderWindow{.
+  cdecl, importc: "sfRenderWindow_createFromHandle", dynlib: LibG.}
+proc newRenderWindow*(mode: TVideoMode, title: cstring, style: int32, settings: PContextSettings = nil): PRenderWindow {.
+  cdecl, importc: "sfRenderWindow_create", dynlib: LibG.}
+
+proc destroy*(window: PRenderWindow) {.
+  cdecl, importc: "sfRenderWindow_destroy", dynlib: LibG.}
+proc close*(window: PRenderWindow) {.
+  cdecl, importc: "sfRenderWindow_close", dynlib: LibG.}
+proc isOpen*(window: PRenderWindow): bool {.
+  cdecl, importc: "sfRenderWindow_isOpen", dynlib: LibG.}
+
+#void sfRenderWindow_setIcon(sfRenderWindow* renderWindow, unsigned int width, unsigned int height, const sfUint8* pixels);
+#proc setIcon*(window: PRenderWindow, width, height: cint, pixels: seq[uint8]) {.
+#  cdecl, importc: "sfRenderWindow_setIcon", dynlib: LibG.}
+
+proc getSettings*(window: PRenderWindow): TContextSettings {.
+  cdecl, importc: "sfRenderWindow_getSettings", dynlib: LibG.}
+
+proc pollEvent*(window: PRenderWindow, event: PEvent): bool {.
+  cdecl, importc: "sfRenderWindow_pollEvent", dynlib: LibG.}
+proc pollEvent*(window: PRenderWindow; event: var TEvent): bool {.
+  cdecl, importc: "sfRenderWindow_pollEvent", dynlib: LibG.}
+proc waitEvent*(window: PRenderWindow, event: PEvent): bool {.
+  cdecl, importc: "sfRenderWindow_waitEvent", dynlib: LibG.}
+proc waitEvent*(window: PRenderWindow, event: var TEvent): bool {.
+  cdecl, importc: "sfRenderWindow_waitEvent", dynlib: LibG.}
+proc getPosition*(window: PRenderWindow): TVector2i {.
+  cdecl, importc: "sfRenderWindow_getPosition", dynlib: LibG.}
+proc setPosition*(window: PRenderWindow, position: TVector2i) {.
+  cdecl, importc: "sfRenderWindow_setPosition", dynlib: LibG.}
+proc getSize*(window: PRenderWindow): TVector2i {.
+  cdecl, importc: "sfRenderWindow_getSize", dynlib: LibG.}
+proc setSize*(window: PRenderWindow, size: TVector2i): void {.
+  cdecl, importc: "sfRenderWindow_setSize", dynlib: LibG.}
+proc setTitle*(window: PRenderWindow, title: cstring): void {.
+  cdecl, importc: "sfRenderWindow_setTitle", dynlib: LibG.}
+
+proc setVisible*(window: PRenderWindow, visible: bool) {.
+  cdecl, importc: "sfRenderWindow_setVisible", dynlib: LibG.}
+proc setMouseCursorVisible*(window: PRenderWindow, show: bool) {.
+  cdecl, importc: "sfRenderWindow_setMouseCursorVisible", dynlib: LibG.}
+proc setVerticalSyncEnabled*(window: PRenderWindow, enabled: bool) {.
+  cdecl, importc: "sfRenderWindow_setVerticalSyncEnabled", dynlib: LibG.}
+proc setKeyRepeatEnabled*(window: PRenderWindow, enabled: bool) {.
+  cdecl, importc: "sfRenderWindow_setKeyRepeatEnabled", dynlib: LibG.}
+proc setActive*(window: PRenderWindow, active: bool): bool {.
+  cdecl, importc: "sfRenderWindow_setActive", dynlib: LibG.}
+proc display*(window: PRenderWindow) {.
+  cdecl, importc: "sfRenderWindow_display", dynlib: LibG.}
+proc setFramerateLimit*(window: PRenderWindow, limit: uint) {.
+  cdecl, importc: "sfRenderWindow_setFramerateLimit", dynlib: LibG.}
+proc setJoystickThreshold*(window: PRenderWindow, threshold: float) {.
+  cdecl, importc: "sfRenderWindow_setJoystickThreshold", dynlib: LibG.}
+proc getSystemHandle*(window: PRenderWindow): TWindowHandle {.
+  cdecl, importc: "sfRenderWindow_getSystemHandle", dynlib: LibG.}
+
+proc clear*(window: PRenderWindow, color: TColor) {.
+  cdecl, importc: "sfRenderWindow_clear", dynlib: LibG.}
+
+proc setView*(window: PRenderWindow, view: PView) {.
+  cdecl, importc: "sfRenderWindow_setView", dynlib: LibG.}
+proc getView*(window: PRenderWindow): PView {.
+  cdecl, importc: "sfRenderWindow_getView", dynlib: LibG.}
+proc getDefaultView*(window: PRenderWindow): PView {.
+  cdecl, importc: "sfRenderWindow_getDefaultView", dynlib: LibG.}
+proc getViewport*(window: PRenderWindow, view: PView): TIntRect {.
+  cdecl, importc: "sfRenderWindow_getViewport", dynlib: LibG.}
+
+proc convertCoords*(window: PRenderWindow, point: TVector2i, targetView: PView): TVector2f {.
+  cdecl, importc: "sfRenderWindow_convertCoords", dynlib: LibG.}
+
+proc draw*(window: PRenderWindow, sprite: PSprite, states: PRenderStates = nil) {.
+  cdecl, importc: "sfRenderWindow_drawSprite", dynlib: LibG.}
+proc draw*(window: PRenderWindow, text: PText, states: PRenderStates = nil) {.
+  cdecl, importc: "sfRenderWindow_drawText", dynlib: LibG.}
+proc draw*(window: PRenderWindow, shape: PShape, states: PRenderStates = nil) {.
+  cdecl, importc: "sfRenderWindow_drawShape", dynlib: LibG.}
+proc draw*(window: PRenderWindow, shape: PCircleShape, states: PRenderStates = nil) {.
+  cdecl, importc: "sfRenderWindow_drawCircleShape", dynlib: LibG.}
+proc draw*(window: PRenderWindow, shape: PRectangleShape, states: PRenderStates = nil) {.
+  cdecl, importc: "sfRenderWindow_drawRectangleShape", dynlib: LibG.}
+
+proc draw*(window: PRenderWindow, shape: PConvexShape, states: PRenderStates = nil) {.
+  cdecl, importc: "sfRenderWindow_drawConvexShape", dynlib: LibG.}
+proc draw*(window: PRenderWindow, shape: PVertexArray, states: PRenderStates = nil) {.
+  cdecl, importc: "sfRenderWindow_drawVertexArray", dynlib: LibG.}
+proc draw*(window: PRenderWindow, vertices: PVertex, vertexCount: cint, 
+           vertexType: TPrimitiveType, states: PRenderStates = nil) {.
+  cdecl, importc: "sfRenderWindow_drawPrimitives", dynlib: LibG.}
+
+proc pushGlStates*(window: PRenderWindow) {.
+  cdecl, importc: "sfRenderWindow_pushGLStates", dynlib: LibG.}
+proc popGlStates*(window: PRenderWindow) {.
+  cdecl, importc: "sfRenderWindow_popGLStates", dynlib: LibG.}
+proc resetGlStates*(window: PRenderWindow) {.
+  cdecl, importc: "sfRenderWindow_resetGLStates", dynlib: LibG.}
+proc capture*(window: PRenderWindow): PImage {.
+  cdecl, importc: "sfRenderWindow_capture", dynlib: LibG.}
+
+#Construct a new render texture
+proc newRenderTexture*(width, height: cint; depthBuffer: Bool): PRenderTexture {.
+  cdecl, importc: "sfRenderTexture_create", dynlib: LibG.}
+#Destroy an existing render texture
+proc destroy*(renderTexture: PRenderTexture){.
+  cdecl, importc: "sfRenderTexture_destroy", dynlib: LibG.}
+#Get the size of the rendering region of a render texture
+proc getSize*(renderTexture: PRenderTexture): TVector2i {.
+  cdecl, importc: "sfRenderTexture_getSize", dynlib: LibG.}
+#Activate or deactivate a render texture as the current target for rendering
+proc setActive*(renderTexture: PRenderTexture; active: bool): bool{.
+  cdecl, importc: "sfRenderTexture_setActive", dynlib: LibG.}
+#Update the contents of the target texture
+proc display*(renderTexture: PRenderTexture){.
+  cdecl, importc: "sfRenderTexture_display", dynlib: LibG.}
+#Clear the rendertexture with the given color
+proc clear*(renderTexture: PRenderTexture; color: TColor){.
+  cdecl, importc: "sfRenderTexture_clear", dynlib: LibG.}
+#Change the current active view of a render texture
+proc setView*(renderTexture: PRenderTexture; view: PView){.
+  cdecl, importc: "sfRenderTexture_setView", dynlib: LibG.}
+#Get the current active view of a render texture
+proc getView*(renderTexture: PRenderTexture): PView{.
+  cdecl, importc: "sfRenderTexture_getView", dynlib: LibG.}
+#Get the default view of a render texture
+proc getDefaultView*(renderTexture: PRenderTexture): PView{.
+  cdecl, importc: "sfRenderTexture_getDefaultView", dynlib: LibG.}
+#Get the viewport of a view applied to this target
+proc getViewport*(renderTexture: PRenderTexture; view: PView): TIntRect{.
+  cdecl, importc: "sfRenderTexture_getViewport", dynlib: LibG.}
+#Convert a point in texture coordinates into view coordinates
+proc convertCoords*(renderTexture: PRenderTexture; point: TVector2i; targetView: PView): TVector2f{.
+  cdecl, importc: "sfRenderTexture_convertCoords", dynlib: LibG.}
+#Draw a drawable object to the render-target
+proc draw*(renderTexture: PRenderTexture; sprite: PSprite; states: PRenderStates){.
+  cdecl, importc: "sfRenderTexture_drawSprite", dynlib: LibG.}
+proc draw*(renderTexture: PRenderTexture; text: PText; states: PRenderStates){.
+  cdecl, importc: "sfRenderTexture_drawText", dynlib: LibG.}
+proc draw*(renderTexture: PRenderTexture; shape: PShape; states: PRenderStates){.
+  cdecl, importc: "sfRenderTexture_drawShape", dynlib: LibG.}
+proc draw*(renderTexture: PRenderTexture; shape: PCircleShape; 
+            states: PRenderStates){.
+  cdecl, importc: "sfRenderTexture_drawCircleShape", dynlib: LibG.}
+proc draw*(renderTexture: PRenderTexture; shape: PConvexShape; 
+            states: PRenderStates){.
+  cdecl, importc: "sfRenderTexture_drawConvexShape", dynlib: LibG.}
+proc draw*(renderTexture: PRenderTexture; shape: PRectangleShape; 
+            states: PRenderStates){.
+  cdecl, importc: "sfRenderTexture_drawRectangleShape", dynlib: LibG.}
+proc draw*(renderTexture: PRenderTexture; va: PVertexArray; 
+            states: PRenderStates){.
+  cdecl, importc: "sfRenderTexture_drawVertexArray", dynlib: LibG.}
+#Draw primitives defined by an array of vertices to a render texture
+proc draw*(renderTexture: PRenderTexture; vertices: PVertex; vertexCount: cint; 
+            primitiveType: TPrimitiveType; states: PRenderStates){.
+  cdecl, importc: "sfRenderTexture_drawPrimitives", dynlib: LibG.}
+#Save the current OpenGL render states and matrices
+#/
+#/ This function can be used when you mix SFML drawing
+#/ and direct OpenGL rendering. Combined with popGLStates,
+#/ it ensures that:
+#/ * SFML's internal states are not messed up by your OpenGL code
+#/ * your OpenGL states are not modified by a call to a SFML function
+#/
+#/ Note that this function is quite expensive: it saves all the
+#/ possible OpenGL states and matrices, even the ones you
+#/ don't care about. Therefore it should be used wisely.
+#/ It is provided for convenience, but the best results will
+#/ be achieved if you handle OpenGL states yourself (because
+#/ you know which states have really changed, and need to be
+#/ saved and restored). Take a look at the resetGLStates
+#/ function if you do so.
+proc pushGLStates*(renderTexture: PRenderTexture){.
+  cdecl, importc: "sfRenderTexture_pushGLStates", dynlib: LibG.}
+#Restore the previously saved OpenGL render states and matrices
+#/
+#/ See the description of pushGLStates to get a detailed
+#/ description of these functions.
+proc popGLStates*(renderTexture: PRenderTexture){.
+  cdecl, importc: "sfRenderTexture_popGLStates", dynlib: LibG.}
+#Reset the internal OpenGL states so that the target is ready for drawing
+#/
+#/ This function can be used when you mix SFML drawing
+#/ and direct OpenGL rendering, if you choose not to use
+#/ pushGLStates/popGLStates. It makes sure that all OpenGL
+#/ states needed by SFML are set, so that subsequent sfRenderTexture_draw*()
+#/ calls will work as expected.
+proc resetGLStates*(renderTexture: PRenderTexture){.
+  cdecl, importc: "sfRenderTexture_resetGLStates", dynlib: LibG.}
+#Get the target texture of a render texture
+proc getTexture*(renderTexture: PRenderTexture): PTexture{.
+  cdecl, importc: "sfRenderTexture_getTexture", dynlib: LibG.}
+#Enable or disable the smooth filter on a render texture
+proc setSmooth*(renderTexture: PRenderTexture; smooth: bool){.
+  cdecl, importc: "sfRenderTexture_setSmooth", dynlib: LibG.}
+#Tell whether the smooth filter is enabled or not for a render texture
+proc isSmooth*(renderTexture: PRenderTexture): bool {.
+  cdecl, importc: "sfRenderTexture_isSmooth", dynlib: LibG.}
+
+proc intRect*(left, top, width, height: cint): TIntRect =
+  result.left   = left
+  result.top    = top
+  result.width  = width
+  result.height = height
+proc floatRect*(left, top, width, height: cfloat): TFloatRect =
+  result.left   = left
+  result.top    = top 
+  result.width  = width
+  result.height = height
+proc contains*(rect: PFloatRect, x, y: cfloat): bool {.
+  cdecl, importc: "sfFloatRect_contains", dynlib: LibG.}
+proc contains*(rect: PIntRect, x: cint, y: cint): bool{.cdecl, 
+  importc: "sfIntRect_contains", dynlib: LibG.}
+proc intersects*(rect1, rect2, intersection: PFloatRect): bool {.
+  cdecl, importc: "sfFloatRect_intersects", dynlib: LibG.}
+proc intersects*(rect1, rect2, intersection: PIntRect): bool {.
+  cdecl, importc: "sfIntRect_intersects", dynlib: LibG.}
+
+proc newFont*(filename: cstring): PFont {.
+  cdecl, importc: "sfFont_createFromFile", dynlib: LibG.}
+proc newFont*(data: pointer, sizeInBytes: cint): PFont {.
+  cdecl, importc: "sfFont_createFromMemory", dynlib: LibG.}
+proc newFont*(stream: PInputStream): PFont {.
+  cdecl, importc: "sfFont_createFromStream", dynlib: LibG.}
+proc copy*(font: PFont): PFont {.
+  cdecl, importc: "sfFont_copy", dynlib: LibG.}
+proc destroy*(font: PFont) {.
+  cdecl, importc: "sfFont_destroy", dynlib: LibG.}
+proc getGlyph*(font: PFont, codePoint: Uint32, characterSize: cint, bold: bool): TGlyph{.
+  cdecl, importc: "sfFont_getGlyph", dynlib: LibG.}
+proc getKerning*(font: PFont, first: Uint32, second: Uint32, characterSize: cint): cint {.
+  cdecl, importc: "sfFont_getKerning", dynlib: LibG.}
+proc getLineSpacing*(font: PFont, characterSize: cint): cint {.
+  cdecl, importc: "sfFont_getLineSpacing", dynlib: LibG.}
+proc getTexture*(font: PFont, characterSize: cint): PTexture {.
+  cdecl, importc: "sfFont_getTexture", dynlib: LibG.}
+#getDefaultFont() has been removed from CSFML
+proc getDefaultFont*(): PFont {.
+  error, cdecl, importc: "sfFont_getDefaultFont", dynlib: LibG.}
+
+proc newCircleShape*(): PCircleShape {.
+  cdecl, importc: "sfCircleShape_create", dynlib: LibG.}
+proc copy*(shape: PCircleShape): PCircleShape {.
+  cdecl, importc: "sfCircleShape_copy", dynlib: LibG.}
+proc destroy*(shape: PCircleShape) {.
+  cdecl, importc: "sfCircleShape_destroy", dynlib: LibG.}
+proc setPosition*(shape: PCircleShape, position: TVector2f) {.
+  cdecl, importc: "sfCircleShape_setPosition", dynlib: LibG.}
+proc setRotation*(shape: PCircleShape, angle: cfloat) {.
+  cdecl, importc: "sfCircleShape_setRotation", dynlib: LibG.}
+proc setScale*(shape: PCircleShape, scale: TVector2f) {.
+  cdecl, importc: "sfCircleShape_setScale", dynlib: LibG.}
+proc setOrigin*(shape: PCircleShape, origin: TVector2f) {.
+  cdecl, importc: "sfCircleShape_setOrigin", dynlib: LibG.}
+proc getPosition*(shape: PCircleShape): TVector2f {.
+  cdecl, importc: "sfCircleShape_getPosition", dynlib: LibG.}
+proc getRotation*(shape: PCircleShape): cfloat {.
+  cdecl, importc: "sfCircleShape_getRotation", dynlib: LibG.}
+proc getScale*(shape: PCircleShape): TVector2f {.
+  cdecl, importc: "sfCircleShape_getScale", dynlib: LibG.}
+proc getOrigin*(shape: PCircleShape): TVector2f {.
+  cdecl, importc: "sfCircleShape_getOrigin", dynlib: LibG.}
+proc move*(shape: PCircleShape, offset: TVector2f) {.
+  cdecl, importc: "sfCircleShape_move", dynlib: LibG.}
+proc rotate*(shape: PCircleShape, angle: cfloat){.
+  cdecl, importc: "sfCircleShape_rotate", dynlib: LibG.}
+proc scale*(shape: PCircleShape, factors: TVector2f) {.
+  cdecl, importc: "sfCircleShape_scale", dynlib: LibG.}
+proc getTransform*(shape: PCircleShape): TTransform {.
+  cdecl, importc: "sfCircleShape_getTransform", dynlib: LibG.}
+proc getInverseTransform*(shape: PCircleShape): TTransform {.
+  cdecl, importc: "sfCircleShape_getInverseTransform", dynlib: LibG.}
+proc setTexture*(shape: PCircleShape, texture: PTexture, resetRect: bool) {.
+  cdecl, importc: "sfCircleShape_setTexture", dynlib: LibG.}
+proc setTextureRect*(shape: PCircleShape, rect: TIntRect) {.
+  cdecl, importc: "sfCircleShape_setTextureRect", dynlib: LibG.}
+proc setFillColor*(shape: PCircleShape, color: TColor) {.
+  cdecl, importc: "sfCircleShape_setFillColor", dynlib: LibG.}
+proc setOutlineColor*(shape: PCircleShape, color: TColor) {.
+  cdecl, importc: "sfCircleShape_setOutlineColor", dynlib: LibG.}
+proc setOutlineThickness*(shape: PCircleShape, thickness: cfloat) {.
+  cdecl, importc: "sfCircleShape_setOutlineThickness", dynlib: LibG.}
+proc getTexture*(shape: PCircleShape): PTexture {.
+  cdecl, importc: "sfCircleShape_getTexture", dynlib: LibG.}
+proc getTextureRect*(shape: PCircleShape): TIntRect {.
+  cdecl, importc: "sfCircleShape_getTextureRect", dynlib: LibG.}
+proc getFillColor*(shape: PCircleShape): TColor {.
+  cdecl, importc: "sfCircleShape_getFillColor", dynlib: LibG.}
+proc getOutlineColor*(shape: PCircleShape): TColor {.
+  cdecl, importc: "sfCircleShape_getOutlineColor", dynlib: LibG.}
+proc getOutlineThickness*(shape: PCircleShape): cfloat {.
+  cdecl, importc: "sfCircleShape_getOutlineThickness", dynlib: LibG.}
+proc getPointCount*(shape: PCircleShape): cint {.
+  cdecl, importc: "sfCircleShape_getPointCount", dynlib: LibG.}
+proc getPoint*(shape: PCircleShape, index: cint): TVector2f {.
+  cdecl, importc: "sfCircleShape_getPoint", dynlib: LibG.}
+proc setRadius*(shape: PCircleShape, radius: cfloat) {.
+  cdecl, importc: "sfCircleShape_setRadius", dynlib: LibG.}
+proc getRadius*(shape: PCircleShape): cfloat {.
+  cdecl, importc: "sfCircleShape_getRadius", dynlib: LibG.}
+proc setPointCount*(shape: PCircleShape, count: cint) {.
+  cdecl, importc: "sfCircleShape_setPointCount", dynlib: LibG.}
+proc getLocalBounds*(shape: PCircleShape): TFloatRect {.
+  cdecl, importc: "sfCircleShape_getLocalBounds", dynlib: LibG.}
+proc getGlobalBounds*(shape: PCircleShape): TFloatRect {.
+  cdecl, importc: "sfCircleShape_getGlobalBounds", dynlib: LibG.}
+
+proc newRectangleShape*(): PRectangleShape {.
+  cdecl, importc: "sfRectangleShape_create", dynlib: LibG.}
+proc copy*(shape: PRectangleShape): PRectangleShape {.
+  cdecl, importc: "sfRectangleShape_copy", dynlib: LibG.}
+proc destroy*(shape: PRectangleShape){.
+  cdecl, importc: "sfRectangleShape_destroy", dynlib: LibG.}
+proc setPosition*(shape: PRectangleShape, position: TVector2f) {.
+  cdecl, importc: "sfRectangleShape_setPosition", dynlib: LibG.}
+proc setRotation*(shape: PRectangleShape, angle: cfloat) {.
+  cdecl, importc: "sfRectangleShape_setRotation", dynlib: LibG.}
+proc setScale*(shape: PRectangleShape, scale: TVector2f) {.
+  cdecl, importc: "sfRectangleShape_setScale", dynlib: LibG.}
+proc setOrigin*(shape: PRectangleShape, origin: TVector2f) {.
+  cdecl, importc: "sfRectangleShape_setOrigin", dynlib: LibG.}
+proc getPosition*(shape: PRectangleShape): TVector2f {.
+  cdecl, importc: "sfRectangleShape_getPosition", dynlib: LibG.}
+proc getRotation*(shape: PRectangleShape): cfloat {.
+  cdecl, importc: "sfRectangleShape_getRotation", dynlib: LibG.}
+proc getScale*(shape: PRectangleShape): TVector2f {.
+  cdecl, importc: "sfRectangleShape_getScale", dynlib: LibG.}
+proc getOrigin*(shape: PRectangleShape): TVector2f {.
+  cdecl, importc: "sfRectangleShape_getOrigin", dynlib: LibG.}
+proc move*(shape: PRectangleShape, offset: TVector2f) {.
+  cdecl, importc: "sfRectangleShape_move", dynlib: LibG.}
+proc rotate*(shape: PRectangleShape, angle: cfloat) {.
+  cdecl, importc: "sfRectangleShape_rotate", dynlib: LibG.}
+proc scale*(shape: PRectangleShape, factors: TVector2f) {.
+  cdecl, importc: "sfRectangleShape_scale", dynlib: LibG.}
+proc getTransform*(shape: PRectangleShape): TTransform {.
+  cdecl, importc: "sfRectangleShape_getTransform", dynlib: LibG.}
+proc getInverseTransform*(shape: PRectangleShape): TTransform {.
+  cdecl, importc: "sfRectangleShape_getInverseTransform", dynlib: LibG.}
+proc setTexture*(shape: PRectangleShape, texture: PTexture, resetRect: bool) {.
+  cdecl, importc: "sfRectangleShape_setTexture", dynlib: LibG.}
+proc setTextureRect*(shape: PRectangleShape, rect: TIntRect) {.
+  cdecl, importc: "sfRectangleShape_setTextureRect", dynlib: LibG.}
+proc setFillColor*(shape: PRectangleShape, color: TColor) {.
+  cdecl, importc: "sfRectangleShape_setFillColor", dynlib: LibG.}
+proc setOutlineColor*(shape: PRectangleShape, color: TColor) {.
+  cdecl, importc: "sfRectangleShape_setOutlineColor", dynlib: LibG.}
+proc setOutlineThickness*(shape: PRectangleShape, thickness: cfloat) {.
+  cdecl, importc: "sfRectangleShape_setOutlineThickness", dynlib: LibG.}
+proc getTexture*(shape: PRectangleShape): PTexture {.
+  cdecl, importc: "sfRectangleShape_getTexture", dynlib: LibG.}
+proc getTextureRect*(shape: PRectangleShape): TIntRect {.
+  cdecl, importc: "sfRectangleShape_getTextureRect", dynlib: LibG.}
+proc getFillColor*(shape: PRectangleShape): TColor {.
+  cdecl, importc: "sfRectangleShape_getFillColor", dynlib: LibG.}
+proc getOutlineColor*(shape: PRectangleShape): TColor {.
+  cdecl, importc: "sfRectangleShape_getOutlineColor", dynlib: LibG.}
+proc getOutlineThickness*(shape: PRectangleShape): cfloat {.
+  cdecl, importc: "sfRectangleShape_getOutlineThickness", dynlib: LibG.}
+proc getPointCount*(shape: PRectangleShape): cint {.
+  cdecl, importc: "sfRectangleShape_getPointCount", dynlib: LibG.}
+proc getPoint*(shape: PRectangleShape, index: cint): TVector2f {.
+  cdecl, importc: "sfRectangleShape_getPoint", dynlib: LibG.}
+proc setSize*(shape: PRectangleShape, size: TVector2f) {.
+  cdecl, importc: "sfRectangleShape_setSize", dynlib: LibG.}
+proc getSize*(shape: PRectangleShape): TVector2f {.
+  cdecl, importc: "sfRectangleShape_getSize", dynlib: LibG.}
+proc getLocalBounds*(shape: PRectangleShape): TFloatRect {.
+  cdecl, importc: "sfRectangleShape_getLocalBounds", dynlib: LibG.}
+proc getGlobalBounds*(shape: PRectangleShape): TFloatRect {.
+  cdecl, importc: "sfRectangleShape_getGlobalBounds", dynlib: LibG.}
+
+
+proc newView*(): PView {.
+  cdecl, importc: "sfView_create", dynlib: LibG.}
+proc viewFromRect*(rectangle: TFloatRect): PView{.
+  cdecl, importc: "sfView_createFromRect", dynlib: LibG.}
+proc copy*(view: PView): PView {.
+  cdecl, importc: "sfView_copy", dynlib: LibG.}
+proc destroy*(view: PView) {.
+  cdecl, importc: "sfView_destroy", dynlib: LibG.}
+proc setCenter*(view: PView, center: TVector2f) {.
+  cdecl, importc: "sfView_setCenter", dynlib: LibG.}
+proc setSize*(view: PView, size: TVector2f) {.
+  cdecl, importc: "sfView_setSize", dynlib: LibG.}
+proc setRotation*(view: PView, angle: cfloat) {.
+  cdecl, importc: "sfView_setRotation", dynlib: LibG.}
+proc setViewport*(view: PView, viewport: TFloatRect) {.
+  cdecl, importc: "sfView_setViewport", dynlib: LibG.}
+proc reset*(view: PView, rectangle: TFloatRect) {.
+  cdecl, importc: "sfView_reset", dynlib: LibG.}
+proc getCenter*(view: PView): TVector2f {.
+  cdecl, importc: "sfView_getCenter", dynlib: LibG.}
+proc getSize*(view: PView): TVector2f {.
+  cdecl, importc: "sfView_getSize", dynlib: LibG.}
+proc getRotation*(view: PView): cfloat {.
+  cdecl, importc: "sfView_getRotation", dynlib: LibG.}
+proc getViewport*(view: PView): TFloatRect {.
+  cdecl, importc: "sfView_getViewport", dynlib: LibG.}
+proc move*(view: PView, offset: TVector2f) {.
+  cdecl, importc: "sfView_move", dynlib: LibG.}
+proc rotate*(view: PView, angle: cfloat) {.
+  cdecl, importc: "sfView_rotate", dynlib: LibG.}
+proc zoom*(view: PView, factor: cfloat) {.
+  cdecl, importc: "sfView_zoom", dynlib: LibG.}
+
+proc newImage*(width, height: cint): PImage {.
+  cdecl, importc: "sfImage_create", dynlib: LibG.}
+proc newImage*(width, height: cint, color: TColor): PImage {.
+  cdecl, importc: "sfImage_createFromColor", dynlib: LibG.}
+proc newImage*(width, height: cint, pixels: pointer): PImage {. ##same deal as setIcon()
+  cdecl, importc: "sfImage_createFromPixels", dynlib: LibG.}
+proc newImage*(filename: cstring): PImage {.
+  cdecl, importc: "sfImage_createFromFile", dynlib: LibG.}
+proc newImage*(data: pointer, size: cint): PImage {.
+  cdecl, importc: "sfImage_createFromMemory", dynlib: LibG.}
+proc newImage*(stream: PInputStream): PImage {.
+  cdecl, importc: "sfImage_createFromStream", dynlib: LibG.}
+proc copy*(image: PImage): PImage {.
+  cdecl, importc: "sfImage_copy", dynlib: LibG.}
+proc destroy*(image: PImage) {.
+  cdecl, importc: "sfImage_destroy", dynlib: LibG.}
+proc save*(image: PImage, filename: cstring): bool {.
+  cdecl, importc: "sfImage_saveToFile", dynlib: LibG.}
+proc getSize*(image: PImage): TVector2i {.
+  cdecl, importc: "sfImage_getSize", dynlib: LibG.}
+proc createMask*(image: PImage, color: TColor, alpha: cchar) {.
+  cdecl, importc: "sfImage_createMaskFromColor", dynlib: LibG.}
+proc copy*(destination, source: PImage, destX, destY: cint;
+            sourceRect: TIntRect, applyAlpha: bool) {.
+  cdecl, importc: "sfImage_copyImage", dynlib: LibG.}
+proc setPixel*(image: PImage, x, y: cint, color: TColor) {.
+  cdecl, importc: "sfImage_setPixel", dynlib: LibG.}
+proc getPixel*(image: PImage, x, y: cint): TColor {.
+  cdecl, importc: "sfImage_getPixel", dynlib: LibG.}
+proc getPixels*(image: PImage): pointer {.
+  cdecl, importc: "sfImage_getPixelsPtr", dynlib: LibG.}
+proc flipHorizontally*(image: PImage) {.
+  cdecl, importc: "sfImage_flipHorizontally", dynlib: LibG.}
+proc flipVertically*(image: PImage) {.
+  cdecl, importc: "sfImage_flipVertically", dynlib: LibG.}
+
+proc newSprite*(): PSprite {.
+  cdecl, importc: "sfSprite_create", dynlib: LibG.}
+proc copy*(sprite: PSprite): PSprite {.
+  cdecl, importc: "sfSprite_copy", dynlib: LibG.}
+proc destroy*(sprite: PSprite) {.
+  cdecl, importc: "sfSprite_destroy", dynlib: LibG.}
+proc setPosition*(sprite: PSprite, position: TVector2f) {.
+  cdecl, importc: "sfSprite_setPosition", dynlib: LibG.}
+proc setRotation*(sprite: PSprite, angle: cfloat) {.
+  cdecl, importc: "sfSprite_setRotation", dynlib: LibG.}
+proc setScale*(sprite: PSprite, scale: TVector2f) {.
+  cdecl, importc: "sfSprite_setScale", dynlib: LibG.}
+proc setOrigin*(sprite: PSprite, origin: TVector2f) {.
+  cdecl, importc: "sfSprite_setOrigin", dynlib: LibG.}
+proc getPosition*(sprite: PSprite): TVector2f {.
+  cdecl, importc: "sfSprite_getPosition", dynlib: LibG.}
+proc getRotation*(sprite: PSprite): cfloat {.
+  cdecl, importc: "sfSprite_getRotation", dynlib: LibG.}
+proc getScale*(sprite: PSprite): TVector2f {.
+  cdecl, importc: "sfSprite_getScale", dynlib: LibG.}
+proc getOrigin*(sprite: PSprite): TVector2f {.
+  cdecl, importc: "sfSprite_getOrigin", dynlib: LibG.}
+proc move*(sprite: PSprite, offset: TVector2f) {.
+  cdecl, importc: "sfSprite_move", dynlib: LibG.}
+proc rotate*(sprite: PSprite, angle: cfloat) {.
+  cdecl, importc: "sfSprite_rotate", dynlib: LibG.}
+proc scale*(sprite: PSprite, factor: TVector2f) {.
+  cdecl, importc: "sfSprite_scale", dynlib: LibG.}
+proc getTransform*(sprite: PSprite): TTransform {.
+  cdecl, importc: "sfSprite_getTransform", dynlib: LibG.}
+proc getInverseTransform*(sprite: PSprite): TTransform {.
+  cdecl, importc: "sfSprite_getInverseTransform", dynlib: LibG.}
+proc setTexture*(sprite: PSprite, texture: PTexture, resetRect: bool) {.
+  cdecl, importc: "sfSprite_setTexture", dynlib: LibG.}
+proc setTextureRect*(sprite: PSprite, rectangle: TIntRect) {.
+  cdecl, importc: "sfSprite_setTextureRect", dynlib: LibG.}
+proc setColor*(sprite: PSprite, color: TColor) {.
+  cdecl, importc: "sfSprite_setColor", dynlib: LibG.}
+proc getTexture*(sprite: PSprite): TTexture {.
+  cdecl, importc: "sfSprite_getTexture", dynlib: LibG.}
+proc getTextureRect*(sprite: PSprite): TIntRect {.
+  cdecl, importc: "sfSprite_getTextureRect", dynlib: LibG.}
+proc getColor*(sprite: PSprite): TColor {.
+  cdecl, importc: "sfSprite_getColor", dynlib: LibG.}
+proc getLocalBounds*(sprite: PSprite): TFloatRect {.
+  cdecl, importc: "sfSprite_getLocalBounds", dynlib: LibG.}
+proc getGlobalBounds*(sprite: PSprite): TFloatRect {.
+  cdecl, importc: "sfSprite_getGlobalBounds", dynlib: LibG.}
+
+proc newTexture*(width, height: cint): PTexture {.
+  cdecl, importc: "sfTexture_create", dynlib: LibG.}
+proc newTexture*(filename: cstring): PTexture {.
+  cdecl, importc: "sfTexture_createFromFile", dynlib: LibG.}
+proc newTexture*(data: pointer, size: cint, area: PIntRect): PTexture {.
+  cdecl, importc: "sfTexture_createFromMemory", dynlib: LibG.}
+proc newTexture*(stream: PInputStream, area: PIntRect): PTexture {.
+  cdecl, importc: "sfTexture_createFromStream", dynlib: LibG.}
+proc newTexture*(image: PImage, area: PIntRect = nil): PTexture {.
+  cdecl, importc: "sfTexture_createFromImage", dynlib: LibG.}
+proc copy*(texture: PTexture): PTexture {.
+  cdecl, importc: "sfTexture_copy", dynlib: LibG.}
+proc destroy*(texture: PTexture) {.
+  cdecl, importc: "sfTexture_destroy", dynlib: LibG.}
+proc getSize*(texture: PTexture): TVector2i {.
+  cdecl, importc: "sfTexture_getSize", dynlib: LibG.}
+proc copyToImage*(texture: PTexture): PImage {.
+  cdecl, importc: "sfTexture_copyToImage", dynlib: LibG.}
+proc updateFromPixels*(texture: PTexture, pixels: pointer, width, height, x, y: cint) {.
+  cdecl, importc: "sfTexture_updateFromPixels", dynlib: LibG.}
+proc updateFromImage*(texture: PTexture, image: PImage, x, y: cint) {.
+  cdecl, importc: "sfTexture_updateFromImage", dynlib: LibG.}
+proc updateFromWindow*(texture: PTexture, window: PWindow, x, y: cint) {.
+  cdecl, importc: "sfTexture_updateFromWindow", dynlib: LibG.}
+proc updateFromWindow*(texture: PTexture, window: PRenderWindow, x, y: cint) {.
+  cdecl, importc: "sfTexture_updateFromRenderWindow", dynlib: LibG.}
+proc bindGL*(texture: PTexture) {.
+  cdecl, importc: "sfTexture_bind", dynlib: LibG.}
+proc setSmooth*(texture: PTexture, smooth: bool) {.
+  cdecl, importc: "sfTexture_setSmooth", dynlib: LibG.}
+proc isSmooth*(texture: PTexture): bool {.
+  cdecl, importc: "sfTexture_isSmooth", dynlib: LibG.}
+proc setRepeated*(texture: PTexture, repeated: bool) {.
+  cdecl, importc: "sfTexture_setRepeated", dynlib: LibG.}
+proc isRepeated*(texture: PTexture): bool {.
+  cdecl, importc: "sfTexture_isRepeated", dynlib: LibG.}
+proc textureMaxSize*(): cint {.
+  cdecl, importc: "sfTexture_getMaximumSize", dynlib: LibG.}
+
+proc newVertexArray*(): PVertexArray {.
+  cdecl, importc: "sfVertexArray_create", dynlib: LibG.}
+proc copy*(vertexArray: PVertexArray): PVertexArray {.
+  cdecl, importc: "sfVertexArray_copy", dynlib: LibG.}
+proc destroy*(va: PVertexArray) {.
+  cdecl, importc: "sfVertexArray_destroy", dynlib: LibG.}
+proc getVertexCount*(va: PVertexArray): cint {.
+  cdecl, importc: "sfVertexArray_getVertexCount", dynlib: LibG.}
+proc getVertex*(va: PVertexArray, index: cint): PVertex {.
+  cdecl, importc: "sfVertexArray_getVertex", dynlib: LibG.}
+proc clear*(va: PVertexArray) {.
+  cdecl, importc: "sfVertexArray_clear", dynlib: LibG.}
+proc resize*(va: PVertexArray, size: cint) {.
+  cdecl, importc: "sfVertexArray_resize", dynlib: LibG.}
+proc append*(va: PVertexArray, vertex: TVertex) {.
+  cdecl, importc: "sfVertexArray_append", dynlib: LibG.}
+proc setPrimitiveType*(va: PVertexArray, primitiveType: TPrimitiveType) {.
+  cdecl, importc: "sfVertexArray_setPrimitiveType", dynlib: LibG.}
+proc getPrimitiveType*(va: PVertexArray): TPrimitiveType {.
+  cdecl, importc: "sfVertexArray_getPrimitiveType", dynlib: LibG.}
+proc getBounds*(va: PVertexArray): TFloatRect {.
+  cdecl, importc: "sfVertexArray_getBounds", dynlib: LibG.}
+
+
+proc newText*(): PText {.
+  cdecl, importc: "sfText_create", dynlib: LibG.}
+proc copy*(text: PText): PText {.
+  cdecl, importc: "sfText_copy", dynlib: LibG.}
+proc destroy*(text: PText) {.
+  cdecl, importc: "sfText_destroy", dynlib: LibG.}
+proc setPosition*(text: PText, position: TVector2f) {.
+  cdecl, importc: "sfText_setPosition", dynlib: LibG.}
+proc setRotation*(text: PText, angle: cfloat) {.
+  cdecl, importc: "sfText_setRotation", dynlib: LibG.}
+proc setScale*(text: PText, scale: TVector2f) {.
+  cdecl, importc: "sfText_setScale", dynlib: LibG.}
+proc setOrigin*(text: PText, origin: TVector2f) {.
+  cdecl, importc: "sfText_setOrigin", dynlib: LibG.}
+proc getPosition*(text: PText): TVector2f {.
+  cdecl, importc: "sfText_getPosition", dynlib: LibG.}
+proc getRotation*(text: PText): cfloat {.
+  cdecl, importc: "sfText_getRotation", dynlib: LibG.}
+proc getScale*(text: PText): TVector2f {.
+  cdecl, importc: "sfText_getScale", dynlib: LibG.}
+proc getOrigin*(text: PText): TVector2f {.
+  cdecl, importc: "sfText_getOrigin", dynlib: LibG.}
+proc move*(text: PText, offset: TVector2f) {.
+  cdecl, importc: "sfText_move", dynlib: LibG.}
+proc rotate*(text: PText, angle: cfloat) {.
+  cdecl, importc: "sfText_rotate", dynlib: LibG.}
+proc scale*(text: PText, factors: TVector2f) {.
+  cdecl, importc: "sfText_scale", dynlib: LibG.}
+proc getTransform*(text: PText): TTransform {.
+  cdecl, importc: "sfText_getTransform", dynlib: LibG.}
+proc getInverseTransform*(text: PText): TTransform {.
+  cdecl, importc: "sfText_getInverseTransform", dynlib: LibG.}
+proc setString*(text: PText, string: cstring) {.
+  cdecl, importc: "sfText_setString", dynlib: LibG.}
+proc setUnicodeString*(text: PText, string: ptr Uint32) {.
+  cdecl, importc: "sfText_setUnicodeString", dynlib: LibG.}
+proc setFont*(text: PText, font: PFont) {.
+  cdecl, importc: "sfText_setFont", dynlib: LibG.}
+proc setCharacterSize*(text: PText, size: cint) {.
+  cdecl, importc: "sfText_setCharacterSize", dynlib: LibG.}
+proc setStyle*(text: PText, style: TTextStyle) {.
+  cdecl, importc: "sfText_setStyle", dynlib: LibG.}
+proc setColor*(text: PText, color: TColor) {.
+  cdecl, importc: "sfText_setColor", dynlib: LibG.}
+proc getString*(text: PText): cstring {.
+  cdecl, importc: "sfText_getString", dynlib: LibG.}
+proc getUnicodeString*(text: PText): ptr Uint32 {.cdecl, 
+  importc: "sfText_getUnicodeString", dynlib: LibG.}
+proc getFont*(text: PText): PFont {.
+  cdecl, importc: "sfText_getFont", dynlib: LibG.}
+proc getCharacterSize*(text: PText): cint {.
+  cdecl, importc: "sfText_getCharacterSize", dynlib: LibG.}
+proc getStyle*(text: PText): Uint32 {.
+  cdecl, importc: "sfText_getStyle", dynlib: LibG.}
+proc getColor*(text: PText): TColor {.
+  cdecl, importc: "sfText_getColor", dynlib: LibG.}
+proc findCharacterPos*(text: PText, index: cint): TVector2f {.
+  cdecl, importc: "sfText_findCharacterPos", dynlib: LibG.}
+proc getLocalBounds*(text: PText): TFloatRect {.
+  cdecl, importc: "sfText_getLocalBounds", dynlib: LibG.}
+proc getGlobalBounds*(text: PText): TFloatRect {.
+  cdecl, importc: "sfText_getGlobalBounds", dynlib: LibG.}
+
+proc transformFromMatrix*(a00, a01, a02, a10, a11, a12, a20, a21, a22: cfloat): TTransform {.
+  cdecl, importc: "sfTransform_fromMatrix", dynlib: LibG.}
+proc getMatrix*(transform: PTransform, matrix: ptr cfloat) {.
+  cdecl, importc: "sfTransform_getMatrix", dynlib: LibG.}
+proc getInverse*(transform: PTransform): TTransform {.
+  cdecl, importc: "sfTransform_getInverse", dynlib: LibG.}
+proc transformPoint*(transform: PTransform, point: TVector2f): TVector2f {.
+  cdecl, importc: "sfTransform_transformPoint", dynlib: LibG.}
+proc transformRect*(transform: PTransform, rectangle: TFloatRect): TFloatRect {.
+  cdecl, importc: "sfTransform_transformRect", dynlib: LibG.}
+proc combine*(transform: PTransform, other: PTransform) {.
+  cdecl, importc: "sfTransform_combine", dynlib: LibG.}
+proc translate*(transform: PTransform, x, y: cfloat) {.
+  cdecl, importc: "sfTransform_translate", dynlib: LibG.}
+proc rotate*(transform: PTransform, angle: cfloat) {.
+  cdecl, importc: "sfTransform_rotate", dynlib: LibG.}
+proc rotateWithCenter*(transform: PTransform, angle, centerX, centerY: cfloat){.
+  cdecl, importc: "sfTransform_rotateWithCenter", dynlib: LibG.}
+proc scale*(transform: PTransform, scaleX, scaleY: cfloat) {.
+  cdecl, importc: "sfTransform_scale", dynlib: LibG.}
+proc scaleWithCenter*(transform: PTransform, scaleX, scaleY, centerX, centerY: cfloat) {.
+  cdecl, importc: "sfTransform_scaleWithCenter", dynlib: LibG.}
+let IdentityMatrix*: TTransform = transformFromMatrix(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0)
+
+
+proc newShader*(VSfilename: cstring, fragmentShaderFilename: cstring): PShader {.
+  cdecl, importc: "sfShader_createFromFile", dynlib: LibG.}
+proc newShaderFromStr*(vertexShader: cstring, fragmentShader: cstring): PShader {.
+  cdecl, importc: "sfShader_createFromMemory", dynlib: LibG.}
+proc newShader*(vertexShaderStream: PInputStream, fragmentShaderStream: PInputStream): PShader {.
+  cdecl, importc: "sfShader_createFromStream", dynlib: LibG.}
+proc destroy*(shader: PShader) {.
+  cdecl, importc: "sfShader_destroy", dynlib: LibG.}
+proc setFloatParameter*(shader: PShader, name: cstring, x: cfloat) {.
+  cdecl, importc: "sfShader_setFloatParameter", dynlib: LibG.}
+proc setFloat2Parameter*(shader: PShader, name: cstring, x, y: cfloat) {.
+  cdecl, importc: "sfShader_setFloat2Parameter", dynlib: LibG.}
+proc setFloat3Parameter*(shader: PShader, name: cstring, x, y, z: cfloat) {.
+  cdecl, importc: "sfShader_setFloat3Parameter", dynlib: LibG.}
+proc setFloat4Parameter*(shader: PShader, name: cstring, x, y, z, w: cfloat) {.
+  cdecl, importc: "sfShader_setFloat4Parameter", dynlib: LibG.}
+proc setVector2Parameter*(shader: PShader, name: cstring, vector: TVector2f) {.
+  cdecl, importc: "sfShader_setVector2Parameter", dynlib: LibG.}
+proc setVector3Parameter*(shader: PShader, name: cstring, vector: TVector3f) {.
+  cdecl, importc: "sfShader_setVector3Parameter", dynlib: LibG.}
+proc setColorParameter*(shader: PShader, name: cstring, color: TColor) {.
+  cdecl, importc: "sfShader_setColorParameter", dynlib: LibG.}
+proc setTransformParameter*(shader: PShader, name: cstring, transform: TTransform) {.
+  cdecl, importc: "sfShader_setTransformParameter", dynlib: LibG.}
+proc setTextureParameter*(shader: PShader, name: cstring, texture: PTexture) {.
+  cdecl, importc: "sfShader_setTextureParameter", dynlib: LibG.}
+proc setCurrentTextureParameter*(shader: PShader, name: cstring) {.
+  cdecl, importc: "sfShader_setCurrentTextureParameter", dynlib: LibG.}
+proc bindGL*(shader: PShader) {.
+  cdecl, importc: "sfShader_bind", dynlib: LibG.}
+proc unbindGL*(shader: PShader) {.
+  cdecl, importc: "sfShader_unbind", dynlib: LibG.}
+proc shaderIsAvailable*(): bool {.
+  cdecl, importc: "sfShader_isAvailable", dynlib: LibG.}
+
+proc color*(red, green, blue: cchar): TColor {.
+  cdecl, importc: "sfColor_fromRGB", dynlib: LibG.}
+proc color*(red, green, blue: int): TColor {.inline.} =
+  return color(red.cchar, green.cchar, blue.cchar)
+proc color*(red, green, blue, alpha: cchar): TColor {.
+  cdecl, importc: "sfColor_fromRGBA", dynlib: LibG.}
+proc color*(red, green, blue, alpha: int): TColor {.inline.} =
+  return color(red.cchar, green.cchar, blue.cchar, alpha.cchar)
+proc `+`*(color1, color2: TColor): TColor {.
+  cdecl, importc: "sfColor_add", dynlib: LibG.}
+proc `*`*(color1, color2: TColor): TColor {.
+  cdecl, importc: "sfColor_modulate", dynlib: LibG.}
+proc newColor*(r,g,b: int): TColor {.inline.} =
+  return color(r,g,b)
+proc newColor*(r,g,b,a: int): TColor {.inline.} = 
+  return color(r,g,b,a)
+
+proc newClock*(): PClock {.
+  cdecl, importc: "sfClock_create", dynlib: LibS.}
+proc copy*(clocK: PClock): PClock {.
+  cdecl, importc: "sfClock_copy", dynlib: LibS.}
+proc destroy*(clock: PClock): PClock {.
+  cdecl, importc: "sfClock_destroy", dynlib: LibS.}
+proc getElapsedTime*(clock: PClock): TTime {.
+  cdecl, importc: "sfClock_getElapsedTime", dynlib: LibS.}
+proc restart*(clock: PClock): TTime {.
+  cdecl, importc: "sfClock_restart", dynlib: LibS, discardable.}
+proc asSeconds*(time: TTime): cfloat {.
+  cdecl, importc: "sfTime_asSeconds", dynlib: LibS.}
+proc asMilliseconds*(time: TTime): int32 {.
+  cdecl, importc: "sfTime_asMilliseconds", dynlib: LibS.}
+proc asMicroseconds*(time: TTime): int64 {.
+  cdecl, importc: "sfTime_asMicroseconds", dynlib: LibS.}
+proc seconds*(seconds: cfloat): TTime {.
+  cdecl, importc: "sfSeconds", dynlib: LibS.}
+proc milliseconds*(ms: int32): TTime {.
+  cdecl, importc: "sfMilliseconds", dynlib: LibS.}
+proc microseconds*(us: int64): TTime {.
+  cdecl, importc: "sfMicroseconds", dynlib: LibS.}
+
+proc newContextSettings*(depthBits: cint = 0,
+                         stencilBits: cint = 0,
+                         antialiasingLevel: cint = 0,
+                         majorVersion: cint = 0,
+                         minorVersion: cint = 0): TContextSettings =
+  result.depthBits = depthBits
+  result.stencilBits = stencilBits
+  result.antialiasingLevel = antialiasingLevel
+  result.majorVersion = majorVersion
+  result.minorVersion = minorVersion
+
+proc newCircleShape*(radius: cfloat; pointCount: cint = 30): PCircleShape = 
+  result = newCircleShape()
+  result.setRadius radius
+  result.setPointCount pointCount
+proc newText*(str: string, font: PFont, size: int): PText =
+  result = newText()
+  result.setString(str)
+  result.setFont(font)
+  result.setCharacterSize(size.cint)
+proc newVertexArray*(primitiveType: TPrimitiveType, vertexCount: cint = 0): PVertexArray =
+  result = newVertexArray()
+  result.setPrimitiveType(primitiveType)
+  if vertexCount != 0:
+    result.resize(vertexCount)
+proc videoMode*(width, height, bpp: cint): TVideoMode =
+  result.width = width
+  result.height = height
+  result.bitsPerPixel = bpp
+
+proc `[]`*(a: PVertexArray, index: int): PVertex =
+  return getVertex(a, index.cint)
+
+proc `$` *(a: TContextSettings): string =
+  return "<TContextSettings stencil=$1 aa=$2 major=$3 minor=$4 depth=$5>" % [
+    $a.stencilBits, $a.antialiasingLevel, $a.majorVersion, $a.minorVersion, $a.depthBits]
+proc `$` *(a: TVideoMode): string = 
+  return "<TVideoMode $1x$2 $3bpp>" % [$a.width, $a.height, $a.bitsPerPixel]
+proc `$` *(a: TFloatRect): string = 
+  return "<TFloatRect $1,$2 $3x$4>" % [$a.left, $a.top, $a.width, $a.height]
+proc `$` *(a: PView): string = 
+  return $a.getViewport()
+proc `$` *(a: TVector2f): string = 
+  return "<TVector2f $1,$2>" % [$a.x, $a.y]
+
+proc vec2i*(x, y: int): TVector2i =
+  result.x = x.cint
+  result.y = y.cint
+proc vec2f*(x, y: float): TVector2f =
+  result.x = x.cfloat
+  result.y = y.cfloat
+
+proc `+`*(a, b: TVector2f): TVector2f {.inline.} =
+  result.x = a.x + b.x
+  result.y = a.y + b.y
+proc `-`*(a: TVector2f): TVector2f {.inline.} =
+  result.x = -a.x
+  result.y = -a.y
+proc `-`*(a, b: TVector2f): TVector2f {.inline.}=
+  result.x = a.x - b.x
+  result.y = a.y - b.y
+proc `*`*(a: TVector2f, b: cfloat): TVector2f {.inline.} =
+  result.x = a.x * b
+  result.y = a.y * b
+proc `*`*(a, b: TVector2f): TVector2f {.inline.} =
+  result.x = a.x * b.x
+  result.y = a.y * b.y
+proc `/`*(a: TVector2f, b: cfloat): TVector2f {.inline.} =
+  result.x = a.x / b
+  result.y = a.y / b
+proc `+=` *(a: var TVector2f, b: TVector2f) {.inline, noSideEffect.} =
+  a = a + b
+proc `-=` *(a: var TVector2f, b: TVector2f) {.inline, noSideEffect.} =
+  a = a - b
+proc `*=` *(a: var TVector2f, b: float) {.inline, noSideEffect.} =
+  a = a * b
+proc `*=` *(a: var TVector2f, b: TVector2f) {.inline, noSideEffect.} =
+  a = a * b
+proc `/=` *(a: var TVector2f, b: float) {.inline, noSideEffect.} =
+  a = a / b
+proc `<` *(a, b: TVector2f): bool {.inline, noSideEffect.} =
+  return a.x < b.x or (a.x == b.x and a.y < b.y)
+proc `<=` *(a, b: TVector2f): bool {.inline, noSideEffect.} =
+  return a.x <= b.x and a.y <= b.y
+proc `==` *(a, b: TVector2f): bool {.inline, noSideEffect.} =
+  return a.x == b.x and a.y == b.y
+proc length*(a: TVector2f): float {.inline.} =
+  return sqrt(pow(a.x, 2.0) + pow(a.y, 2.0))
+proc lengthSq*(a: TVector2f): float {.inline.} =
+  return pow(a.x, 2.0) + pow(a.y, 2.0)
+proc distanceSq*(a, b: TVector2f): float {.inline.} =
+  return pow(a.x - b.x, 2.0) + pow(a.y - b.y, 2.0)
+proc distance*(a, b: TVector2f): float {.inline.} =
+  return sqrt(pow(a.x - b.x, 2.0) + pow(a.y - b.y, 2.0))
+proc permul*(a, b: TVector2f): TVector2f =
+  result.x = a.x * b.x
+  result.y = a.y * b.y
+proc rotate*(a: TVector2f, phi: float): TVector2f =
+  var c = cos(phi)
+  var s = sin(phi)
+  result.x = a.x * c - a.y * s
+  result.y = a.x * s + a.y * c
+proc perpendicular(a: TVector2f): TVector2f =
+  result.x = -a.x
+  result.y =  a.y
+proc cross(a, b: TVector2f): float =
+  return a.x * b.y - a.y * b.x
+
diff --git a/tests/manyloc/keineschweine/dependencies/sfml/sfml_audio.nim b/tests/manyloc/keineschweine/dependencies/sfml/sfml_audio.nim
new file mode 100644
index 000000000..3cfd33c02
--- /dev/null
+++ b/tests/manyloc/keineschweine/dependencies/sfml/sfml_audio.nim
@@ -0,0 +1,899 @@
+import
+  sfml
+const
+  Lib = "libcsfml-audio.so.2.0"
+type
+  PMusic* = ptr TMusic
+  TMusic* {.pure, final.} = object
+  PSound* = ptr TSound
+  TSound* {.pure, final.} = object
+  PSoundBuffer* = ptr TSoundBuffer
+  TSoundBuffer* {.pure, final.} = object
+  PSoundBufferRecorder* = ptr TSoundBufferRecorder
+  TSoundBufferRecorder* {.pure, final.} = object
+  PSoundRecorder* = ptr TSoundRecorder
+  TSoundRecorder* {.pure, final.} = object
+  PSoundStream* = ptr TSoundStream
+  TSoundStream* {.pure, final.} = object
+  TSoundStatus* {.size: sizeof(cint).} = enum
+    Stopped, Paused, Playing
+
+proc newMusic*(filename: cstring): PMusic {.
+  cdecl, importc: "sfMusic_createFromFile", dynlib: Lib.}
+proc newMusic*(data: pointer, size: cint): PMusic {.
+  cdecl, importc: "sfMusic_createFromMemory", dynlib: Lib.}
+proc newMusic*(stream: PInputStream): PMusic {.
+  cdecl, importc: "sfMusic_createFromStream", dynlib: Lib.}
+proc destroy*(music: PMusic) {.
+  cdecl, importc: "sfMusic_destroy", dynlib: Lib.}
+proc setLoop*(music: PMusic, loop: bool) {.
+  cdecl, importc: "sfMusic_setLoop", dynlib: Lib.}
+proc getLoop*(music: PMusic): bool {.
+  cdecl, importc: "sfMusic_getLoop", dynlib: Lib.}
+proc getDuration*(music: PMusic): TTime {.
+  cdecl, importc: "sfMusic_getDuration", dynlib: Lib.}
+proc play*(music: PMusic) {.
+  cdecl, importc: "sfMusic_play", dynlib: Lib.}
+proc pause*(music: PMusic) {.
+  cdecl, importc: "sfMusic_pause", dynlib: Lib.}
+proc stop*(music: PMusic) {.
+  cdecl, importc: "sfMusic_stop", dynlib: Lib.}
+proc getChannelCount*(music: PMusic): cint {.
+  cdecl, importc: "sfMusic_getChannelCount", dynlib: Lib.}
+proc getSampleRate*(music: PMusic): cint {.
+  cdecl, importc: "sfMusic_getSampleRate", dynlib: Lib.}
+proc getStatus*(music: PMusic): TSoundStatus {.
+  cdecl, importc: "sfMusic_getStatus", dynlib: Lib.}
+proc getPlayingOffset*(music: PMusic): TTime {.
+  cdecl, importc: "sfMusic_getPlayingOffset", dynlib: Lib.}
+proc setPitch*(music: PMusic, pitch: cfloat) {.
+  cdecl, importc: "sfMusic_setPitch", dynlib: Lib.}
+proc setVolume*(music: PMusic, volume: float) {.
+  cdecl, importc: "sfMusic_setVolume", dynlib: Lib.}
+proc setPosition*(music: PMusic, position: TVector3f) {.
+  cdecl, importc: "sfMusic_setPosition", dynlib: Lib.}
+proc setRelativeToListener*(music: PMusic, relative: bool) {.
+  cdecl, importc: "sfMusic_setRelativeToListener", dynlib: Lib.}
+proc setMinDistance*(music: PMusic, distance: cfloat) {.
+  cdecl, importc: "sfMusic_setMinDistance", dynlib: Lib.}
+proc setAttenuation*(music: PMusic, attenuation: cfloat) {.
+  cdecl, importc: "sfMusic_setAttenuation", dynlib: Lib.}
+proc setPlayingOffset*(music: PMusic, time: TTime) {.
+  cdecl, importc: "sfMusic_setPlayingOffset", dynlib: Lib.}
+proc getPitch*(music: PMusic): cfloat {.
+  cdecl, importc: "sfMusic_getPitch", dynlib: Lib.}
+proc getVolume*(music: PMusic): cfloat {.
+  cdecl, importc: "sfMusic_getVolume", dynlib: Lib.}
+proc getPosition*(music: PMusic): TVector3f {.
+  cdecl, importc: "sfMusic_getPosition", dynlib: Lib.}
+proc isRelativeToListener*(music: PMusic): bool {.
+  cdecl, importc: "sfMusic_isRelativeToListener", dynlib: Lib.}
+proc getMinDistance*(music: PMusic): cfloat {.
+  cdecl, importc: "sfMusic_isRelativeToListener", dynlib: Lib.}
+proc getAttenuation*(music: PMusic): cfloat {.
+  cdecl, importc: "sfMusic_isRelativeToListener", dynlib: Lib.}
+
+#/ \brief Create a new sound
+proc newSound*(): PSound{.
+  cdecl, importc: "sfSound_create", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Create a new sound by copying an existing one
+#/
+#/ \param sound Sound to copy
+#/
+#/ \return A new sfSound object which is a copy of \a sound
+#/
+#//////////////////////////////////////////////////////////
+proc copy*(sound: PSound): PSound{.
+  cdecl, importc: "sfSound_copy", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Destroy a sound
+proc destroy*(sound: PSound){.
+  cdecl, importc: "sfSound_destroy", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Start or resume playing a sound
+#/
+#/ This function starts the sound if it was stopped, resumes
+#/ it if it was paused, and restarts it from beginning if it
+#/ was it already playing.
+#/ This function uses its own thread so that it doesn't block
+#/ the rest of the program while the sound is played.
+proc play*(sound: PSound){.
+  cdecl, importc: "sfSound_play", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ This function pauses the sound if it was playing,
+#/ otherwise (sound already paused or stopped) it has no effect.
+proc pause*(sound: PSound){.
+  cdecl, importc: "sfSound_pause", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ This function stops the sound if it was playing or paused,
+#/ and does nothing if it was already stopped.
+#/ It also resets the playing position (unlike sfSound_pause).
+proc stop*(sound: PSound){.
+  cdecl, importc: "sfSound_stop", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ It is important to note that the sound buffer is not copied,
+#/ thus the sfSoundBuffer object must remain alive as long
+#/ as it is attached to the sound.
+proc setBuffer*(sound: PSound; buffer: PSoundBuffer){.
+  cdecl, importc: "sfSound_setBuffer", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Get the audio buffer attached to a sound
+proc getBuffer*(sound: PSound): PSoundBuffer{.
+  cdecl, importc: "sfSound_getBuffer", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Set whether or not a sound should loop after reaching the end
+#/
+#/ If set, the sound will restart from beginning after
+#/ reaching the end and so on, until it is stopped or
+#/ sfSound_setLoop(sound, sfFalse) is called.
+#/ The default looping state for sounds is false.
+proc setLoop*(sound: PSound; loop: bool){.
+  cdecl, importc: "sfSound_setLoop", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Tell whether or not a soud is in loop mode
+proc getLoop*(sound: PSound): bool {.
+  cdecl, importc: "sfSound_getLoop", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Get the current status of a sound (stopped, paused, playing)
+proc getStatus*(sound: PSound): TSoundStatus{.
+  cdecl, importc: "sfSound_getStatus", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Set the pitch of a sound
+#/
+#/ The pitch represents the perceived fundamental frequency
+#/ of a sound; thus you can make a sound more acute or grave
+#/ by changing its pitch. A side effect of changing the pitch
+#/ is to modify the playing speed of the sound as well.
+#/ The default value for the pitch is 1.
+proc setPitch*(sound: PSound; pitch: cfloat){.
+  cdecl, importc: "sfSound_setPitch", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Set the volume of a sound
+#/
+#/ The volume is a value between 0 (mute) and 100 (full volume).
+#/ The default value for the volume is 100.
+proc setVolume*(sound: PSound; volume: cfloat){.
+  cdecl, importc: "sfSound_setVolume", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Set the 3D position of a sound in the audio scene
+#/
+#/ Only sounds with one channel (mono sounds) can be
+#/ spatialized.
+#/ The default position of a sound is (0, 0, 0).
+proc setPosition*(sound: PSound; position: TVector3f){.
+  cdecl, importc: "sfSound_setPosition", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Make the sound's position relative to the listener or absolute
+#/
+#/ Making a sound relative to the listener will ensure that it will always
+#/ be played the same way regardless the position of the listener.
+#/ This can be useful for non-spatialized sounds, sounds that are
+#/ produced by the listener, or sounds attached to it.
+#/ The default value is false (position is absolute).
+proc setRelativeToListener*(sound: PSound; relative: bool){.
+  cdecl, importc: "sfSound_setRelativeToListener", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Set the minimum distance of a sound
+#/
+#/ The "minimum distance" of a sound is the maximum
+#/ distance at which it is heard at its maximum volume. Further
+#/ than the minimum distance, it will start to fade out according
+#/ to its attenuation factor. A value of 0 ("inside the head
+#/ of the listener") is an invalid value and is forbidden.
+#/ The default value of the minimum distance is 1.
+proc setMinDistance*(sound: PSound; distance: cfloat){.
+  cdecl, importc: "sfSound_setMinDistance", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Set the attenuation factor of a sound
+#/
+#/ The attenuation is a multiplicative factor which makes
+#/ the sound more or less loud according to its distance
+#/ from the listener. An attenuation of 0 will produce a
+#/ non-attenuated sound, i.e. its volume will always be the same
+#/ whether it is heard from near or from far. On the other hand,
+#/ an attenuation value such as 100 will make the sound fade out
+#/ very quickly as it gets further from the listener.
+#/ The default value of the attenuation is 1.
+proc setAttenuation*(sound: PSound; attenuation: cfloat){.
+  cdecl, importc: "sfSound_setAttenuation", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Change the current playing position of a sound
+#/
+#/ The playing position can be changed when the sound is
+#/ either paused or playing.
+proc setPlayingOffset*(sound: PSound; timeOffset: sfml.TTime){.
+  cdecl, importc: "sfSound_setPlayingOffset", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Get the pitch of a sound
+proc getPitch*(sound: PSound): cfloat{.
+  cdecl, importc: "sfSound_getPitch", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Get the volume of a sound
+proc getVolume*(sound: PSound): cfloat{.
+  cdecl, importc: "sfSound_getVolume", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Get the 3D position of a sound in the audio scene
+proc getPosition*(sound: PSound): TVector3f{.
+  cdecl, importc: "sfSound_getPosition", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Tell whether a sound's position is relative to the
+#/        listener or is absolute
+proc isRelativeToListener*(sound: PSound): bool{.
+  cdecl, importc: "sfSound_isRelativeToListener", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Get the minimum distance of a sound
+proc getMinDistance*(sound: PSound): cfloat{.
+  cdecl, importc: "sfSound_getMinDistance", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Get the attenuation factor of a sound
+proc getAttenuation*(sound: PSound): cfloat{.
+  cdecl, importc: "sfSound_getAttenuation", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Get the current playing position of a sound
+proc getPlayingOffset*(sound: PSound): TTime{.
+  cdecl, importc: "sfSound_getPlayingOffset", dynlib: Lib.}
+
+#//////////////////////////////////////////////////////////
+# Headers
+#//////////////////////////////////////////////////////////
+#//////////////////////////////////////////////////////////
+#/ \brief Create a new sound buffer and load it from a file
+#/
+#/ Here is a complete list of all the supported audio formats:
+#/ ogg, wav, flac, aiff, au, raw, paf, svx, nist, voc, ircam,
+#/ w64, mat4, mat5 pvf, htk, sds, avr, sd2, caf, wve, mpc2k, rf64.
+#/
+#/ \param filename Path of the sound file to load
+#/
+#/ \return A new sfSoundBuffer object (NULL if failed)
+#/
+#//////////////////////////////////////////////////////////
+proc newSoundBuffer*(filename: cstring): PSoundBuffer{.
+  cdecl, importc: "sfSoundBuffer_createFromFile", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Create a new sound buffer and load it from a file in memory
+#/
+#/ Here is a complete list of all the supported audio formats:
+#/ ogg, wav, flac, aiff, au, raw, paf, svx, nist, voc, ircam,
+#/ w64, mat4, mat5 pvf, htk, sds, avr, sd2, caf, wve, mpc2k, rf64.
+#/
+#/ \param data        Pointer to the file data in memory
+#/ \param sizeInBytes Size of the data to load, in bytes
+#/
+#/ \return A new sfSoundBuffer object (NULL if failed)
+#/
+#//////////////////////////////////////////////////////////
+proc newSoundBuffer*(data: pointer; sizeInBytes: cint): PSoundBuffer{.
+  cdecl, importc: "sfSoundBuffer_createFromMemory", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Create a new sound buffer and load it from a custom stream
+#/
+#/ Here is a complete list of all the supported audio formats:
+#/ ogg, wav, flac, aiff, au, raw, paf, svx, nist, voc, ircam,
+#/ w64, mat4, mat5 pvf, htk, sds, avr, sd2, caf, wve, mpc2k, rf64.
+#/
+#/ \param stream Source stream to read from
+#/
+#/ \return A new sfSoundBuffer object (NULL if failed)
+#/
+#//////////////////////////////////////////////////////////
+proc newSoundBuffer*(stream: PInputStream): PSoundBuffer{.
+  cdecl, importc: "sfSoundBuffer_createFromStream", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Create a new sound buffer and load it from an array of samples in memory
+#/
+#/ The assumed format of the audio samples is 16 bits signed integer
+#/ (sfInt16).
+#/
+#/ \param samples      Pointer to the array of samples in memory
+#/ \param sampleCount  Number of samples in the array
+#/ \param channelCount Number of channels (1 = mono, 2 = stereo, ...)
+#/ \param sampleRate   Sample rate (number of samples to play per second)
+#/
+#/ \return A new sfSoundBuffer object (NULL if failed)
+#/
+#//////////////////////////////////////////////////////////
+proc createFromSamples*(samples: ptr int16; sampleCount: cuint; 
+                         channelCount: cuint; sampleRate: cuint): PSoundBuffer{.
+  cdecl, importc: "sfSoundBuffer_createFromSamples", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Create a new sound buffer by copying an existing one
+#/
+#/ \param soundBuffer Sound buffer to copy
+#/
+#/ \return A new sfSoundBuffer object which is a copy of \a soundBuffer
+#/
+#//////////////////////////////////////////////////////////
+proc copy*(soundBuffer: PSoundBuffer): PSoundBuffer{.
+  cdecl, importc: "sfSoundBuffer_copy", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Destroy a sound buffer
+#/
+#/ \param soundBuffer Sound buffer to destroy
+#/
+#//////////////////////////////////////////////////////////
+proc destroy*(soundBuffer: PSoundBuffer){.
+  cdecl, importc: "sfSoundBuffer_destroy", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Save a sound buffer to an audio file
+#/
+#/ Here is a complete list of all the supported audio formats:
+#/ ogg, wav, flac, aiff, au, raw, paf, svx, nist, voc, ircam,
+#/ w64, mat4, mat5 pvf, htk, sds, avr, sd2, caf, wve, mpc2k, rf64.
+#/
+#/ \param soundBuffer Sound buffer object
+#/ \param filename    Path of the sound file to write
+#/
+#/ \return sfTrue if saving succeeded, sfFalse if it failed
+#/
+#//////////////////////////////////////////////////////////
+proc saveToFile*(soundBuffer: PSoundBuffer; filename: cstring): bool {.
+  cdecl, importc: "sfSoundBuffer_saveToFile", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Get the array of audio samples stored in a sound buffer
+#/
+#/ The format of the returned samples is 16 bits signed integer
+#/ (sfInt16). The total number of samples in this array
+#/ is given by the sfSoundBuffer_getSampleCount function.
+#/
+#/ \param soundBuffer Sound buffer object
+#/
+#/ \return Read-only pointer to the array of sound samples
+#/
+#//////////////////////////////////////////////////////////
+proc sfSoundBuffer_getSamples*(soundBuffer: PSoundBuffer): ptr Int16{.
+  cdecl, importc: "sfSoundBuffer_getSamples", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Get the number of samples stored in a sound buffer
+#/
+#/ The array of samples can be accessed with the
+#/ sfSoundBuffer_getSamples function.
+proc getSampleCount*(soundBuffer: PSoundBuffer): cint{.
+  cdecl, importc: "sfSoundBuffer_getSampleCount", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Get the sample rate of a sound buffer
+#/
+#/ The sample rate is the number of samples played per second.
+#/ The higher, the better the quality (for example, 44100
+#/ samples/s is CD quality).
+proc getSampleRate*(soundBuffer: PSoundBuffer): cuint{.
+  cdecl, importc: "sfSoundBuffer_getSampleRate", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Get the number of channels used by a sound buffer
+#/
+#/ If the sound is mono then the number of channels will
+#/ be 1, 2 for stereo, etc.
+proc getChannelCount*(soundBuffer: PSoundBuffer): cuint{.
+  cdecl, importc: "sfSoundBuffer_getChannelCount", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Get the total duration of a sound buffer
+#/
+#/ \param soundBuffer Sound buffer object
+#/
+#/ \return Sound duration
+#/
+#//////////////////////////////////////////////////////////
+proc getDuration*(soundBuffer: PSoundBuffer): TTime{.
+  cdecl, importc: "sfSoundBuffer_getDuration", dynlib: Lib.}
+
+#//////////////////////////////////////////////////////////
+#/ \brief Change the global volume of all the sounds and musics
+#/
+#/ The volume is a number between 0 and 100; it is combined with
+#/ the individual volume of each sound / music.
+#/ The default value for the volume is 100 (maximum).
+#/
+#/ \param volume New global volume, in the range [0, 100]
+#/
+#//////////////////////////////////////////////////////////
+proc listenerSetGlobalVolume*(volume: cfloat){.
+  cdecl, importc: "sfListener_setGlobalVolume", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Get the current value of the global volume
+#/
+#/ \return Current global volume, in the range [0, 100]
+#/
+#//////////////////////////////////////////////////////////
+proc listenerGetGlobalVolume*(): cfloat{.
+  cdecl, importc: "sfListener_getGlobalVolume", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Set the position of the listener in the scene
+#/
+#/ The default listener's position is (0, 0, 0).
+#/
+#/ \param position New position of the listener
+#/
+#//////////////////////////////////////////////////////////
+proc listenerSetPosition*(position: TVector3f){.
+  cdecl, importc: "sfListener_setPosition", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Get the current position of the listener in the scene
+#/
+#/ \return The listener's position
+#/
+#//////////////////////////////////////////////////////////
+proc listenerGetPosition*(): TVector3f{.
+  cdecl, importc: "sfListener_getPosition", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Set the orientation of the listener in the scene
+#/
+#/ The orientation defines the 3D axes of the listener
+#/ (left, up, front) in the scene. The orientation vector
+#/ doesn't have to be normalized.
+#/ The default listener's orientation is (0, 0, -1).
+#/
+#/ \param position New direction of the listener
+#/
+#//////////////////////////////////////////////////////////
+proc listenerSetDirection*(orientation: TVector3f){.
+  cdecl, importc: "sfListener_setDirection", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Get the current orientation of the listener in the scene
+#/
+#/ \return The listener's direction
+#/
+#//////////////////////////////////////////////////////////
+proc listenerGetDirection*(): TVector3f{.
+  cdecl, importc: "sfListener_getDirection", dynlib: Lib.}
+
+type 
+  TSoundRecorderStartCallback* = proc (a2: pointer): bool {.cdecl.}
+  #/< Type of the callback used when starting a capture 
+  TSoundRecorderProcessCallback* = proc(a2: ptr int16; a3: cuint; 
+    a4: pointer): bool {.cdecl.}
+  #/< Type of the callback used to process audio data
+  TSoundRecorderStopCallback* = proc (a2: pointer){.cdecl.}
+  #/< Type of the callback used when stopping a capture
+#//////////////////////////////////////////////////////////
+#/ \brief Construct a new sound recorder from callback functions
+#/
+#/ \param onStart   Callback function which will be called when a new capture starts (can be NULL)
+#/ \param onProcess Callback function which will be called each time there's audio data to process
+#/ \param onStop    Callback function which will be called when the current capture stops (can be NULL)
+#/ \param userData  Data to pass to the callback function (can be NULL)
+#/
+#/ \return A new sfSoundRecorder object (NULL if failed)
+#/
+#//////////////////////////////////////////////////////////
+proc newSoundRecorder*(onStart: TSoundRecorderStartCallback; 
+                        onProcess: TSoundRecorderProcessCallback; 
+                        onStop: TSoundRecorderStopCallback; 
+                        userData: pointer = nil): PSoundRecorder{.
+  cdecl, importc: "sfSoundRecorder_create", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Destroy a sound recorder
+#/
+#/ \param soundRecorder Sound recorder to destroy
+#/
+#//////////////////////////////////////////////////////////
+proc destroy*(soundRecorder: PSoundRecorder){.
+  cdecl, importc: "sfSoundRecorder_destroy", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Start the capture of a sound recorder
+#/
+#/ The \a sampleRate parameter defines the number of audio samples
+#/ captured per second. The higher, the better the quality
+#/ (for example, 44100 samples/sec is CD quality).
+#/ This function uses its own thread so that it doesn't block
+#/ the rest of the program while the capture runs.
+#/ Please note that only one capture can happen at the same time.
+#/
+#/ \param soundRecorder Sound recorder object
+#/ \param sampleRate    Desired capture rate, in number of samples per second
+#/
+#//////////////////////////////////////////////////////////
+proc start*(soundRecorder: PSoundRecorder; sampleRate: cuint){.
+  cdecl, importc: "sfSoundRecorder_start", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Stop the capture of a sound recorder
+#/
+#/ \param soundRecorder Sound recorder object
+#/
+#//////////////////////////////////////////////////////////
+proc stop*(soundRecorder: PSoundRecorder){.
+  cdecl, importc: "sfSoundRecorder_stop", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Get the sample rate of a sound recorder
+#/
+#/ The sample rate defines the number of audio samples
+#/ captured per second. The higher, the better the quality
+#/ (for example, 44100 samples/sec is CD quality).
+#/
+#/ \param soundRecorder Sound recorder object
+#/
+#/ \return Sample rate, in samples per second
+#/
+#//////////////////////////////////////////////////////////
+proc getSampleRate*(soundRecorder: PSoundRecorder): cuint{.
+  cdecl, importc: "sfSoundRecorder_getSampleRate", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Check if the system supports audio capture
+#/
+#/ This function should always be called before using
+#/ the audio capture features. If it returns false, then
+#/ any attempt to use sfSoundRecorder will fail.
+#/
+#/ \return sfTrue if audio capture is supported, sfFalse otherwise
+#/
+#//////////////////////////////////////////////////////////
+proc soundRecorderIsAvailable*(): bool {.
+  cdecl, importc: "sfSoundRecorder_isAvailable", dynlib: Lib.}
+
+#//////////////////////////////////////////////////////////
+#/ \brief Create a new sound buffer recorder
+#/
+#/ \return A new sfSoundBufferRecorder object (NULL if failed)
+#/
+#//////////////////////////////////////////////////////////
+proc newSoundBufferRecorder*(): PSoundBufferRecorder{.
+  cdecl, importc: "sfSoundBufferRecorder_create", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Destroy a sound buffer recorder
+#/
+#/ \param soundBufferRecorder Sound buffer recorder to destroy
+#/
+#//////////////////////////////////////////////////////////
+proc destroy*(soundBufferRecorder: PSoundBufferRecorder){.
+  cdecl, importc: "sfSoundBufferRecorder_destroy", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Start the capture of a sound recorder recorder
+#/
+#/ The \a sampleRate parameter defines the number of audio samples
+#/ captured per second. The higher, the better the quality
+#/ (for example, 44100 samples/sec is CD quality).
+#/ This function uses its own thread so that it doesn't block
+#/ the rest of the program while the capture runs.
+#/ Please note that only one capture can happen at the same time.
+#/
+#/ \param soundBufferRecorder Sound buffer recorder object
+#/ \param sampleRate          Desired capture rate, in number of samples per second
+#/
+#//////////////////////////////////////////////////////////
+proc start*(soundBufferRecorder: PSoundBufferRecorder; sampleRate: cuint){.
+  cdecl, importc: "sfSoundBufferRecorder_start", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Stop the capture of a sound recorder
+#/
+#/ \param soundBufferRecorder Sound buffer recorder object
+#/
+#//////////////////////////////////////////////////////////
+proc stop*(soundBufferRecorder: PSoundBufferRecorder){.
+  cdecl, importc: "sfSoundBufferRecorder_stop", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Get the sample rate of a sound buffer recorder
+#/
+#/ The sample rate defines the number of audio samples
+#/ captured per second. The higher, the better the quality
+#/ (for example, 44100 samples/sec is CD quality).
+#/
+#/ \param soundBufferRecorder Sound buffer recorder object
+#/
+#/ \return Sample rate, in samples per second
+#/
+#//////////////////////////////////////////////////////////
+proc getSampleRate*(soundBufferRecorder: PSoundBufferRecorder): cuint{.
+  cdecl, importc: "sfSoundBufferRecorder_getSampleRate", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Get the sound buffer containing the captured audio data
+#/
+#/ The sound buffer is valid only after the capture has ended.
+#/ This function provides a read-only access to the internal
+#/ sound buffer, but it can be copied if you need to
+#/ make any modification to it.
+#/
+#/ \param soundBufferRecorder Sound buffer recorder object
+#/
+#/ \return Read-only access to the sound buffer
+#/
+#//////////////////////////////////////////////////////////
+proc getBuffer*(soundBufferRecorder: PSoundBufferRecorder): PSoundBuffer{.
+  cdecl, importc: "sfSoundBufferRecorder_getBuffer", dynlib: Lib.}
+
+
+#//////////////////////////////////////////////////////////
+#/ \brief defines the data to fill by the OnGetData callback
+#/
+#//////////////////////////////////////////////////////////
+type 
+  PSoundStreamChunk* = ptr TSoundStreamChunk
+  TSoundStreamChunk*{.pure, final.} = object 
+    samples*: ptr int16   #/< Pointer to the audio samples
+    sampleCount*: cuint     #/< Number of samples pointed by Samples
+  
+  TSoundStreamGetDataCallback* = proc (a2: PSoundStreamChunk; 
+      a3: pointer): bool{.cdecl.}
+  #/< Type of the callback used to get a sound stream data
+  TSoundStreamSeekCallback* = proc (a2: TTime; a3: pointer){.cdecl.}
+  #/< Type of the callback used to seek in a sound stream
+#//////////////////////////////////////////////////////////
+#/ \brief Create a new sound stream
+#/
+#/ \param onGetData    Function called when the stream needs more data (can't be NULL)
+#/ \param onSeek       Function called when the stream seeks (can't be NULL)
+#/ \param channelCount Number of channels to use (1 = mono, 2 = stereo)
+#/ \param sampleRate   Sample rate of the sound (44100 = CD quality)
+#/ \param userData     Data to pass to the callback functions
+#/
+#/ \return A new sfSoundStream object
+#/
+#//////////////////////////////////////////////////////////
+proc create*(onGetData: TSoundStreamGetDataCallback; onSeek: TSoundStreamSeekCallback; 
+              channelCount: cuint; sampleRate: cuint; userData: pointer): PSoundStream{.
+  cdecl, importc: "sfSoundStream_create", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Destroy a sound stream
+#/
+#/ \param soundStream Sound stream to destroy
+#/
+#//////////////////////////////////////////////////////////
+proc destroy*(soundStream: PSoundStream){.
+  cdecl, importc: "sfSoundStream_destroy", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Start or resume playing a sound stream
+#/
+#/ This function starts the stream if it was stopped, resumes
+#/ it if it was paused, and restarts it from beginning if it
+#/ was it already playing.
+#/ This function uses its own thread so that it doesn't block
+#/ the rest of the program while the music is played.
+#/
+#/ \param soundStream Sound stream object
+#/
+#//////////////////////////////////////////////////////////
+proc play*(soundStream: PSoundStream){.
+  cdecl, importc: "sfSoundStream_play", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Pause a sound stream
+#/
+#/ This function pauses the stream if it was playing,
+#/ otherwise (stream already paused or stopped) it has no effect.
+#/
+#/ \param soundStream Sound stream object
+#/
+#//////////////////////////////////////////////////////////
+proc pause*(soundStream: PSoundStream){.
+  cdecl, importc: "sfSoundStream_pause", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Stop playing a sound stream
+#/
+#/ This function stops the stream if it was playing or paused,
+#/ and does nothing if it was already stopped.
+#/ It also resets the playing position (unlike sfSoundStream_pause).
+#/
+#/ \param soundStream Sound stream object
+#/
+#//////////////////////////////////////////////////////////
+proc stop*(soundStream: PSoundStream){.
+  cdecl, importc: "sfSoundStream_stop", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Get the current status of a sound stream (stopped, paused, playing)
+#/
+#/ \param soundStream Sound stream object
+#/
+#/ \return Current status
+#/
+#//////////////////////////////////////////////////////////
+proc getStatus*(soundStream: PSoundStream): TSoundStatus{.
+  cdecl, importc: "sfSoundStream_getStatus", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Return the number of channels of a sound stream
+#/
+#/ 1 channel means a mono sound, 2 means stereo, etc.
+#/
+#/ \param soundStream Sound stream object
+#/
+#/ \return Number of channels
+#/
+#//////////////////////////////////////////////////////////
+proc getChannelCount*(soundStream: PSoundStream): cuint{.
+  cdecl, importc: "sfSoundStream_getChannelCount", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Get the sample rate of a sound stream
+#/
+#/ The sample rate is the number of audio samples played per
+#/ second. The higher, the better the quality.
+#/
+#/ \param soundStream Sound stream object
+#/
+#/ \return Sample rate, in number of samples per second
+#/
+#//////////////////////////////////////////////////////////
+proc getSampleRate*(soundStream: PSoundStream): cuint{.
+  cdecl, importc: "sfSoundStream_getSampleRate", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Set the pitch of a sound stream
+#/
+#/ The pitch represents the perceived fundamental frequency
+#/ of a sound; thus you can make a stream more acute or grave
+#/ by changing its pitch. A side effect of changing the pitch
+#/ is to modify the playing speed of the stream as well.
+#/ The default value for the pitch is 1.
+#/
+#/ \param soundStream Sound stream object
+#/ \param pitch       New pitch to apply to the stream
+#/
+#//////////////////////////////////////////////////////////
+proc setPitch*(soundStream: PSoundStream; pitch: cfloat){.
+  cdecl, importc: "sfSoundStream_setPitch", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Set the volume of a sound stream
+#/
+#/ The volume is a value between 0 (mute) and 100 (full volume).
+#/ The default value for the volume is 100.
+#/
+#/ \param soundStream Sound stream object
+#/ \param volume      Volume of the stream
+#/
+#//////////////////////////////////////////////////////////
+proc setVolume*(soundStream: PSoundStream; volume: cfloat){.
+  cdecl, importc: "sfSoundStream_setVolume", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Set the 3D position of a sound stream in the audio scene
+#/
+#/ Only streams with one channel (mono streams) can be
+#/ spatialized.
+#/ The default position of a stream is (0, 0, 0).
+#/
+#/ \param soundStream Sound stream object
+#/ \param position    Position of the stream in the scene
+#/
+#//////////////////////////////////////////////////////////
+proc setPosition*(soundStream: PSoundStream; position: TVector3f){.
+  cdecl, importc: "sfSoundStream_setPosition", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Make a sound stream's position relative to the listener or absolute
+#/
+#/ Making a stream relative to the listener will ensure that it will always
+#/ be played the same way regardless the position of the listener.
+#/ This can be useful for non-spatialized streams, streams that are
+#/ produced by the listener, or streams attached to it.
+#/ The default value is false (position is absolute).
+#/
+#/ \param soundStream Sound stream object
+#/ \param relative    sfTrue to set the position relative, sfFalse to set it absolute
+#/
+#//////////////////////////////////////////////////////////
+proc setRelativeToListener*(soundStream: PSoundStream; relative: bool){.
+  cdecl, importc: "sfSoundStream_setRelativeToListener", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Set the minimum distance of a sound stream
+#/
+#/ The "minimum distance" of a stream is the maximum
+#/ distance at which it is heard at its maximum volume. Further
+#/ than the minimum distance, it will start to fade out according
+#/ to its attenuation factor. A value of 0 ("inside the head
+#/ of the listener") is an invalid value and is forbidden.
+#/ The default value of the minimum distance is 1.
+#/
+#/ \param soundStream Sound stream object
+#/ \param distance    New minimum distance of the stream
+#/
+#//////////////////////////////////////////////////////////
+proc setMinDistance*(soundStream: PSoundStream; distance: cfloat){.
+  cdecl, importc: "sfSoundStream_setMinDistance", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Set the attenuation factor of a sound stream
+#/
+#/ The attenuation is a multiplicative factor which makes
+#/ the stream more or less loud according to its distance
+#/ from the listener. An attenuation of 0 will produce a
+#/ non-attenuated stream, i.e. its volume will always be the same
+#/ whether it is heard from near or from far. On the other hand,
+#/ an attenuation value such as 100 will make the stream fade out
+#/ very quickly as it gets further from the listener.
+#/ The default value of the attenuation is 1.
+#/
+#/ \param soundStream Sound stream object
+#/ \param attenuation New attenuation factor of the stream
+#/
+#//////////////////////////////////////////////////////////
+proc setAttenuation*(soundStream: PSoundStream; attenuation: cfloat){.
+  cdecl, importc: "sfSoundStream_setAttenuation", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Change the current playing position of a sound stream
+#/
+#/ The playing position can be changed when the stream is
+#/ either paused or playing.
+#/
+#/ \param soundStream Sound stream object
+#/ \param timeOffset  New playing position
+#/
+#//////////////////////////////////////////////////////////
+proc setPlayingOffset*(soundStream: PSoundStream; timeOffset: TTime){.
+  cdecl, importc: "sfSoundStream_setPlayingOffset", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Set whether or not a sound stream should loop after reaching the end
+#/
+#/ If set, the stream will restart from beginning after
+#/ reaching the end and so on, until it is stopped or
+#/ sfSoundStream_setLoop(stream, sfFalse) is called.
+#/ The default looping state for sound streams is false.
+#/
+#/ \param soundStream Sound stream object
+#/ \param loop        sfTrue to play in loop, sfFalse to play once
+#/
+#//////////////////////////////////////////////////////////
+proc setLoop*(soundStream: PSoundStream; loop: bool){.
+  cdecl, importc: "sfSoundStream_setLoop", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Get the pitch of a sound stream
+#/
+#/ \param soundStream Sound stream object
+#/
+#/ \return Pitch of the stream
+#/
+#//////////////////////////////////////////////////////////
+proc getPitch*(soundStream: PSoundStream): cfloat{.
+  cdecl, importc: "sfSoundStream_getPitch", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Get the volume of a sound stream
+#/
+#/ \param soundStream Sound stream object
+#/
+#/ \return Volume of the stream, in the range [0, 100]
+#/
+#//////////////////////////////////////////////////////////
+proc getVolume*(soundStream: PSoundStream): cfloat{.
+  cdecl, importc: "sfSoundStream_getVolume", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Get the 3D position of a sound stream in the audio scene
+#/
+#/ \param soundStream Sound stream object
+#/
+#/ \return Position of the stream in the world
+#/
+#//////////////////////////////////////////////////////////
+proc getPosition*(soundStream: PSoundStream): TVector3f{.
+  cdecl, importc: "sfSoundStream_getPosition", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Tell whether a sound stream's position is relative to the
+#/        listener or is absolute
+#/
+#/ \param soundStream Sound stream object
+#/
+#/ \return sfTrue if the position is relative, sfFalse if it's absolute
+#/
+#//////////////////////////////////////////////////////////
+proc isRelativeToListener*(soundStream: PSoundStream): bool{.
+  cdecl, importc: "sfSoundStream_isRelativeToListener", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Get the minimum distance of a sound stream
+#/
+#/ \param soundStream Sound stream object
+#/
+#/ \return Minimum distance of the stream
+#/
+#//////////////////////////////////////////////////////////
+proc getMinDistance*(soundStream: PSoundStream): cfloat{.
+  cdecl, importc: "sfSoundStream_getMinDistance", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Get the attenuation factor of a sound stream
+#/
+#/ \param soundStream Sound stream object
+#/
+#/ \return Attenuation factor of the stream
+#/
+#//////////////////////////////////////////////////////////
+proc getAttenuation*(soundStream: PSoundStream): cfloat{.
+  cdecl, importc: "sfSoundStream_getAttenuation", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Tell whether or not a sound stream is in loop mode
+#/
+#/ \param soundStream Sound stream object
+#/
+#/ \return sfTrue if the music is looping, sfFalse otherwise
+#/
+#//////////////////////////////////////////////////////////
+proc getLoop*(soundStream: PSoundStream): bool{.
+  cdecl, importc: "sfSoundStream_getLoop", dynlib: Lib.}
+#//////////////////////////////////////////////////////////
+#/ \brief Get the current playing position of a sound stream
+#/
+#/ \param soundStream Sound stream object
+#/
+#/ \return Current playing position
+#/
+#//////////////////////////////////////////////////////////
+proc getPlayingOffset*(soundStream: PSoundStream): TTime{.
+  cdecl, importc: "sfSoundStream_getPlayingOffset", dynlib: Lib.}
diff --git a/tests/manyloc/keineschweine/dependencies/sfml/sfml_colors.nim b/tests/manyloc/keineschweine/dependencies/sfml/sfml_colors.nim
new file mode 100644
index 000000000..31473b17a
--- /dev/null
+++ b/tests/manyloc/keineschweine/dependencies/sfml/sfml_colors.nim
@@ -0,0 +1,15 @@
+import sfml
+{.deadCodeElim: on.}
+let
+  Black*: TColor = color(0, 0, 0)
+  White*: TColor = color(255, 255, 255)
+  Red*: TColor = color(255, 0, 0)
+  Green*: TColor = color(0, 255, 0)
+  Blue*: TColor = color(0, 0, 255)
+  Yellow*: TColor = color(255, 255, 0)
+  Magenta*: TColor = color(255, 0, 255)
+  Cyan*: TColor = color(0, 255, 255)
+  Transparent*: TColor = color(0, 0, 0, 0)
+  Gray* = color(84, 84, 84)
+  RoyalBlue* = color(65, 105, 225)
+##todo: define more colors lul
\ No newline at end of file
diff --git a/tests/manyloc/keineschweine/dependencies/sfml/sfml_vector.nim b/tests/manyloc/keineschweine/dependencies/sfml/sfml_vector.nim
new file mode 100644
index 000000000..474d249aa
--- /dev/null
+++ b/tests/manyloc/keineschweine/dependencies/sfml/sfml_vector.nim
@@ -0,0 +1,2 @@
+import sfml, math, strutils
+{.deadCodeElim: on.}