]> gitweb.factorcode.org Git - factor.git/commitdiff
Merge branch 'master' of git://factorcode.org/git/factor
authorJoe Groff <arcata@gmail.com>
Thu, 25 Feb 2010 02:26:46 +0000 (18:26 -0800)
committerJoe Groff <arcata@gmail.com>
Thu, 25 Feb 2010 02:26:46 +0000 (18:26 -0800)
extra/chipmunk/chipmunk.factor [deleted file]
extra/chipmunk/demo/demo.factor
extra/chipmunk/ffi/ffi.factor [new file with mode: 0644]

diff --git a/extra/chipmunk/chipmunk.factor b/extra/chipmunk/chipmunk.factor
deleted file mode 100644 (file)
index b242321..0000000
+++ /dev/null
@@ -1,845 +0,0 @@
-! Copyright (C) 2010 Erik Charlebois
-! See http:// factorcode.org/license.txt for BSD license.
-USING: accessors alien.c-types alien.syntax classes.struct combinators
-combinators.short-circuit kernel math math.order sequences
-specialized-arrays.instances.alien.c-types.void* typed
-specialized-arrays locals system alien.libraries ;
-IN: chipmunk
-
-<< "chipmunk" {
-        { [ os windows? ] [ "chipmunk.dll" ] }
-        { [ os macosx? ] [ "libchipmunk.dylib"  ] }
-        { [ os unix?  ] [ "libchipmunk.so" ] }
-    } cond "cdecl" add-library >>
-LIBRARY: chipmunk
-
-! chipmunk_types.h
-TYPEDEF: double cpFloat
-STRUCT: cpVect
-    { x cpFloat }
-    { y cpFloat } ;
-SPECIALIZED-ARRAY: cpVect
-
-TYPEDEF: uint cpHashValue
-TYPEDEF: void* cpDataPointer
-TYPEDEF: uint cpCollisionType
-TYPEDEF: uint cpLayers
-TYPEDEF: uint cpGroup
-
-CONSTANT: CP_NO_GROUP 0
-CONSTANT: CP_ALL_LAYERS HEX: ffffffff
-
-! cpVect.h
-TYPED: cpv ( x y -- v: cpVect )
-    cpVect <struct-boa> ; inline
-
-TYPED: cpvzero ( -- v: cpVect )
-    0.0 0.0 cpv ; inline
-
-FUNCTION: cpFloat cpvlength ( cpVect v ) ;
-FUNCTION: cpVect cpvslerp ( cpVect v1, cpVect v2, cpFloat t ) ;
-FUNCTION: cpVect cpvslerpconst ( cpVect v1, cpVect v2, cpFloat a ) ;
-FUNCTION: cpVect cpvforangle ( cpFloat a ) ;
-FUNCTION: cpFloat cpvtoangle ( cpVect v ) ;
-FUNCTION: c-string cpvstr ( cpVect v ) ;
-
-TYPED: cpvadd ( v1: cpVect v2: cpVect -- v3: cpVect )
-    [ [ x>> ] bi@ + ]
-    [ [ y>> ] bi@ + ] 2bi cpv ; inline
-
-TYPED: cpvneg ( v1: cpVect -- v2: cpVect )
-    [ x>> ] [ y>> ] bi [ neg ] bi@ cpv ; inline
-
-TYPED: cpvsub ( v1: cpVect v2: cpVect -- v3: cpVect )
-    [ [ x>> ] bi@ - ]
-    [ [ y>> ] bi@ - ] 2bi cpv ; inline
-
-TYPED: cpvmult ( v1: cpVect s -- v2: cpVect )
-    [ swap x>> * ]
-    [ swap y>> * ] 2bi cpv ; inline
-
-TYPED: cpvdot ( v1: cpVect v2: cpVect -- s )
-    [ [ x>> ] bi@ * ]
-    [ [ y>> ] bi@ * ] 2bi + ; inline
-
-TYPED: cpvcross ( v1: cpVect v2: cpVect -- s )
-    [ [ x>> ] [ y>> ] bi* * ]
-    [ [ y>> ] [ x>> ] bi* * ] 2bi - ; inline
-
-TYPED: cpvperp ( v1: cpVect -- v2: cpVect )
-    [ y>> neg ] [ x>> ] bi cpv ; inline
-
-TYPED: cpvrperp ( v1: cpVect -- v2: cpVect )
-    [ y>> ] [ x>> neg ] bi cpv ; inline
-
-TYPED: cpvproject ( v1: cpVect v2: cpVect -- v3: cpVect )
-    [ nip ]
-    [ cpvdot ]
-    [ nip dup cpvdot ]
-    2tri / cpvmult ; inline
-
-TYPED: cpvrotate ( v1: cpVect v2: cpVect -- v3: cpVect )
-    [
-        [ [ x>> ] bi@ * ]
-        [ [ y>> ] bi@ * ] 2bi -
-    ]
-    [
-        [ [ x>> ] [ y>> ] bi* * ]
-        [ [ y>> ] [ x>> ] bi* * ] 2bi +
-    ] 2bi cpv ; inline
-
-TYPED: cpvunrotate ( v1: cpVect v2: cpVect -- v3: cpVect )
-    [
-        [ [ x>> ] bi@ * ]
-        [ [ y>> ] bi@ * ] 2bi +
-    ]
-    [
-        [ [ y>> ] [ x>> ] bi* * ]
-        [ [ x>> ] [ y>> ] bi* * ] 2bi -
-    ] 2bi cpv ; inline
-
-TYPED: cpvlengthsq ( v: cpVect -- s )
-    dup cpvdot ; inline
-
-TYPED: cpvlerp ( v1: cpVect v2: cpVect s -- v3: cpVect )
-    [ nip 1.0 swap - cpvmult ]
-    [ cpvmult nip ] 3bi cpvadd ; inline
-
-TYPED: cpvnormalize ( v1: cpVect -- v2: cpVect )
-    dup cpvlength 1.0 swap / cpvmult ; inline
-
-TYPED: cpvnormalize_safe ( v1: cpVect -- v2: cpVect )
-    dup [ x>> 0.0 = ] [ y>> 0.0 = ] bi and
-    [ drop cpvzero ]
-    [ cpvnormalize ] if ; inline
-
-TYPED: cpvclamp ( v1: cpVect len -- v2: cpVect )
-    2dup
-    [ dup cpvdot ]
-    [ sq ] 2bi* >
-    [ [ cpvnormalize ] dip cpvmult ]
-    [ drop ] if ; inline
-
-TYPED: cpvlerpconst ( v1: cpVect v2: cpVect d -- v3: cpVect )
-    [ 2drop ]
-    [ [ swap cpvsub ] dip cpvclamp ] 3bi cpvadd ; inline
-
-TYPED: cpvdist ( v1: cpVect v2: cpVect -- dist )
-    cpvsub cpvlength ; inline
-
-TYPED: cpvdistsq ( v1: cpVect v2: cpVect -- distsq )
-    cpvsub cpvlengthsq ; inline
-
-TYPED: cpvnear ( v1: cpVect v2: cpVect dist -- ? )
-    [ cpvdistsq ] dip sq < ; inline
-
-! cpBB.h
-STRUCT: cpBB
-    { l cpFloat }
-    { b cpFloat }
-    { r cpFloat }
-    { t cpFloat } ;
-
-TYPED: cpBBNew ( l b r t -- cpbb: cpBB )
-    cpBB <struct-boa> ; inline
-
-TYPED: cpBBintersects ( a: cpBB b: cpBB -- ? )
-    {
-        [ [ l>> ] [ r>> ] bi* <= ]
-        [ [ r>> ] [ l>> ] bi*  > ]
-        [ [ b>> ] [ t>> ] bi* <= ]
-        [ [ t>> ] [ b>> ] bi*  > ]
-    } 2&& ; inline
-
-TYPED: cpBBcontainsBB ( bb: cpBB other: cpBB -- ? )
-    {
-        [ [ l>> ] bi@ < ]
-        [ [ r>> ] bi@ > ]
-        [ [ b>> ] bi@ < ]
-        [ [ t>> ] bi@ > ]
-    } 2&& ; inline
-
-TYPED: cpBBcontainsVect ( bb: cpBB v: cpVect -- ? )
-    {
-        [ [ l>> ] [ x>> ] bi* < ]
-        [ [ r>> ] [ x>> ] bi* > ]
-        [ [ b>> ] [ y>> ] bi* < ]
-        [ [ t>> ] [ y>> ] bi* > ]
-    } 2&& ; inline
-
-TYPED: cpBBmerge ( a: cpBB b: cpBB -- c: cpBB )
-    {
-        [ [ l>> ] bi@ min ]
-        [ [ b>> ] bi@ min ]
-        [ [ r>> ] bi@ max ]
-        [ [ t>> ] bi@ max ]
-    } 2cleave cpBBNew ; inline
-
-TYPED: cpBBexpand ( bb: cpBB v: cpVect -- b: cpBB )
-    {
-        [ [ l>> ] [ x>> ] bi* min ]
-        [ [ b>> ] [ y>> ] bi* min ]
-        [ [ r>> ] [ x>> ] bi* max ]
-        [ [ t>> ] [ y>> ] bi* max ]
-    } 2cleave cpBBNew ; inline
-
-FUNCTION: cpVect cpBBClampVect ( cpBB bb, cpVect v ) ;
-FUNCTION: cpVect cpBBWrapVect ( cpBB bb, cpVect v ) ;
-
-! cpBody.h
-C-TYPE: cpBody
-CALLBACK: void cpBodyVelocityFunc ( cpBody* body, cpVect gravity, cpFloat damping, cpFloat dt ) ;
-CALLBACK: void cpBodyPositionFunc ( cpBody* body, cpFloat dt ) ;
-
-STRUCT: cpBody
-    { velocity_func cpBodyVelocityFunc }
-    { position_func cpBodyPositionFunc }
-    { m             cpFloat            }
-    { m_inv         cpFloat            }
-    { i             cpFloat            }
-    { i_inv         cpFloat            }
-    { p             cpVect             }
-    { v             cpVect             }
-    { f             cpVect             }
-    { a             cpFloat            }
-    { w             cpFloat            }
-    { t             cpFloat            }
-    { rot           cpVect             }
-    { data          cpDataPointer      }
-    { v_limit       cpFloat            }
-    { w_limit       cpFloat            }
-    { v_bias        cpVect             }
-    { w_bias        cpFloat            } ;
-
-FUNCTION: cpBody* cpBodyAlloc ( ) ;
-FUNCTION: cpBody* cpBodyInit ( cpBody* body, cpFloat m, cpFloat i ) ;
-FUNCTION: cpBody* cpBodyNew ( cpFloat m, cpFloat i ) ;
-FUNCTION: void cpBodyDestroy ( cpBody* body ) ;
-FUNCTION: void cpBodyFree ( cpBody* body ) ;
-FUNCTION: void cpBodySetMass ( cpBody* body, cpFloat m ) ;
-FUNCTION: void cpBodySetMoment ( cpBody* body, cpFloat i ) ;
-FUNCTION: void cpBodySetAngle ( cpBody* body, cpFloat a ) ;
-FUNCTION: void cpBodySlew ( cpBody* body, cpVect pos, cpFloat dt ) ;
-FUNCTION: void cpBodyUpdateVelocity ( cpBody* body, cpVect gravity, cpFloat damping, cpFloat dt ) ;
-FUNCTION: void cpBodyUpdatePosition ( cpBody* body, cpFloat dt ) ;
-
-TYPED: cpBodyLocal2World ( body: cpBody v: cpVect -- v2: cpVect )
-    [ drop p>> ]
-    [ swap rot>> cpvrotate ] 2bi cpvadd ; inline
-
-TYPED: cpBodyWorld2Local ( body: cpBody v: cpVect -- v2: cpVect )
-    [ swap p>> cpvsub ]
-    [ drop rot>> ] 2bi cpvunrotate ; inline
-
-TYPED: cpBodyApplyImpulse ( body: cpBody j: cpVect r: cpVect -- )
-    [
-        drop
-        [ drop dup v>> ]
-        [ swap m_inv>> cpvmult ] 2bi cpvadd >>v drop
-    ]
-    [
-        [ 2drop dup w_bias>> ]
-        [ swap cpvcross [ i_inv>> ] dip * ] 3bi + >>w_bias drop
-    ] 3bi ; inline
-
-FUNCTION: void cpBodyResetForces ( cpBody* body ) ;
-FUNCTION: void cpBodyApplyForce ( cpBody* body, cpVect f, cpVect r ) ;
-FUNCTION: void cpApplyDampedSpring ( cpBody* a, cpBody* b, cpVect anchr1, cpVect anchr2, cpFloat rlen, cpFloat k, cpFloat dmp, cpFloat dt ) ;
-
-! cpArray.h
-STRUCT: cpArray
-    { num int    }
-    { max int    }
-    { arr void** } ;
-
-CALLBACK: void cpArrayIter ( void* ptr, void* data ) ;
-
-FUNCTION: cpArray* cpArrayAlloc ( ) ;
-FUNCTION: cpArray* cpArrayInit ( cpArray* arr, int size ) ;
-FUNCTION: cpArray* cpArrayNew ( int size ) ;
-FUNCTION: void cpArrayDestroy ( cpArray* arr ) ;
-FUNCTION: void cpArrayFree ( cpArray* arr ) ;
-FUNCTION: void cpArrayPush ( cpArray* arr, void* object ) ;
-FUNCTION: void cpArrayDeleteIndex ( cpArray* arr, int idx ) ;
-FUNCTION: void cpArrayDeleteObj ( cpArray* arr, void* obj ) ;
-FUNCTION: void cpArrayEach ( cpArray* arr, cpArrayIter iterFunc, void* data ) ;
-FUNCTION: int cpArrayContains ( cpArray* arr, void* ptr ) ;
-
-! cpHashSet.h
-STRUCT: cpHashSetBin
-    { elt  void*         }
-    { hash cpHashValue   }
-    { next cpHashSetBin* } ;
-
-CALLBACK: int cpHashSetEqlFunc ( void* ptr, void* elt ) ;
-CALLBACK: void* cpHashSetTransFunc ( void* ptr, void* data ) ;
-CALLBACK: void cpHashSetIterFunc ( void* elt, void* data ) ;
-CALLBACK: int cpHashSetFilterFunc ( void* elt, void* data ) ;
-
-STRUCT: cpHashSet
-    { entries       int                }
-    { size          int                }
-    { eql           cpHashSetEqlFunc   }
-    { trans         cpHashSetTransFunc }
-    { default_value void*              }
-    { table         cpHashSetBin**     } ;
-
-FUNCTION: void cpHashSetDestroy ( cpHashSet* set ) ;
-FUNCTION: void cpHashSetFree ( cpHashSet* set ) ;
-FUNCTION: cpHashSet* cpHashSetAlloc ( ) ;
-FUNCTION: cpHashSet* cpHashSetInit ( cpHashSet* set, int size, cpHashSetEqlFunc eqlFunc, cpHashSetTransFunc trans ) ;
-FUNCTION: cpHashSet* cpHashSetNew ( int size, cpHashSetEqlFunc eqlFunc, cpHashSetTransFunc trans ) ;
-FUNCTION: void* cpHashSetInsert ( cpHashSet* set, cpHashValue hash, void* ptr, void* data ) ;
-FUNCTION: void* cpHashSetRemove ( cpHashSet* set, cpHashValue hash, void* ptr ) ;
-FUNCTION: void* cpHashSetFind ( cpHashSet* set, cpHashValue hash, void* ptr ) ;
-FUNCTION: void cpHashSetEach ( cpHashSet* set, cpHashSetIterFunc func, void* data ) ;
-FUNCTION: void cpHashSetFilter ( cpHashSet* set, cpHashSetFilterFunc func, void* data ) ;
-
-! cpSpaceHash.h
-STRUCT: cpHandle
-    { obj    void* }
-    { retain int   }
-    { stamp  int   } ;
-
-STRUCT: cpSpaceHashBin
-    { handle cpHandle*       }
-    { next   cpSpaceHashBin* } ;
-
-CALLBACK: cpBB cpSpaceHashBBFunc ( void* obj ) ;
-
-STRUCT: cpSpaceHash
-    { numcells  int               }
-    { celldim   cpFloat           }
-    { bbfunc    cpSpaceHashBBFunc }
-    { handleSet cpHashSet*        }
-    { table     cpSpaceHashBin**  }
-    { bins      cpSpaceHashBin*   }
-    { stamp     int               } ;
-
-FUNCTION: cpSpaceHash* cpSpaceHashAlloc ( ) ;
-FUNCTION: cpSpaceHash* cpSpaceHashInit ( cpSpaceHash* hash, cpFloat celldim, int cells, cpSpaceHashBBFunc bbfunc ) ;
-FUNCTION: cpSpaceHash* cpSpaceHashNew ( cpFloat celldim, int cells, cpSpaceHashBBFunc bbfunc ) ;
-FUNCTION: void cpSpaceHashDestroy ( cpSpaceHash* hash ) ;
-FUNCTION: void cpSpaceHashFree ( cpSpaceHash* hash ) ;
-FUNCTION: void cpSpaceHashResize ( cpSpaceHash* hash, cpFloat celldim, int numcells ) ;
-FUNCTION: void cpSpaceHashInsert ( cpSpaceHash* hash, void* obj, cpHashValue id, cpBB bb ) ;
-FUNCTION: void cpSpaceHashRemove ( cpSpaceHash* hash, void* obj, cpHashValue id ) ;
-CALLBACK: void cpSpaceHashIterator ( void* obj, void* data ) ;
-FUNCTION: void cpSpaceHashEach ( cpSpaceHash* hash, cpSpaceHashIterator func, void* data ) ;
-FUNCTION: void cpSpaceHashRehash ( cpSpaceHash* hash ) ;
-FUNCTION: void cpSpaceHashRehashObject ( cpSpaceHash* hash, void* obj, cpHashValue id ) ;
-CALLBACK: void cpSpaceHashQueryFunc ( void* obj1, void* obj2, void* data ) ;
-FUNCTION: void cpSpaceHashPointQuery ( cpSpaceHash* hash, cpVect point, cpSpaceHashQueryFunc func, void* data ) ;
-FUNCTION: void cpSpaceHashQuery ( cpSpaceHash* hash, void* obj, cpBB bb, cpSpaceHashQueryFunc func, void* data ) ;
-FUNCTION: void cpSpaceHashQueryRehash ( cpSpaceHash* hash, cpSpaceHashQueryFunc func, void* data ) ;
-CALLBACK: cpFloat cpSpaceHashSegmentQueryFunc ( void* obj1, void* obj2, void* data ) ;
-FUNCTION: void cpSpaceHashSegmentQuery ( cpSpaceHash* hash, void* obj, cpVect a, cpVect b, cpFloat t_exit, cpSpaceHashSegmentQueryFunc func, void* data ) ;
-
-! cpShape.h
-C-TYPE: cpShape
-C-TYPE: cpShapeClass
-
-STRUCT: cpSegmentQueryInfo
-    { shape cpShape* }
-    { t     cpFloat  }
-    { n     cpVect   } ;
-
-C-ENUM:
-    CP_CIRCLE_SHAPE
-    CP_SEGMENT_SHAPE
-    CP_POLY_SHAPE
-    CP_NUM_SHAPES ;
-TYPEDEF: int cpShapeType
-
-CALLBACK: cpBB cacheData_cb ( cpShape* shape, cpVect p, cpVect rot ) ;
-CALLBACK: void destroy_cb ( cpShape* shape ) ;
-CALLBACK: int pointQuery_cb ( cpShape* shape, cpVect p ) ;
-CALLBACK: void segmentQuery_cb ( cpShape* shape, cpVect a, cpVect b, cpSegmentQueryInfo* info ) ;
-
-STRUCT: cpShapeClass
-    { type         cpShapeType     }
-    { cacheData    cacheData_cb    }
-    { destroy      destroy_cb      }
-    { pointQuery   pointQuery_cb   }
-    { segmentQuery segmentQuery_cb } ;
-
-STRUCT: cpShape
-    { klass          cpShapeClass*   }
-    { body           cpBody*         }
-    { bb             cpBB            }
-    { sensor         int             }
-    { e              cpFloat         }
-    { u              cpFloat         }
-    { surface_v      cpVect          }
-    { data           cpDataPointer   }
-    { collision_type cpCollisionType }
-    { group          cpGroup         }
-    { layers         cpLayers        }
-    { hashid         cpHashValue     } ;
-
-FUNCTION: cpShape* cpShapeInit ( cpShape* shape, cpShapeClass* klass, cpBody* body ) ;
-FUNCTION: void cpShapeDestroy ( cpShape* shape ) ;
-FUNCTION: void cpShapeFree ( cpShape* shape ) ;
-FUNCTION: cpBB cpShapeCacheBB ( cpShape* shape ) ;
-FUNCTION: int cpShapePointQuery ( cpShape* shape, cpVect p ) ;
-
-STRUCT: cpCircleShape
-    { shape cpShape }
-    { c     cpVect  }
-    { r     cpFloat }
-    { tc    cpVect  } ;
-
-FUNCTION: cpCircleShape* cpCircleShapeAlloc ( ) ;
-FUNCTION: cpCircleShape* cpCircleShapeInit ( cpCircleShape* circle, cpBody* body, cpFloat radius, cpVect offset ) ;
-FUNCTION: cpShape* cpCircleShapeNew ( cpBody* body, cpFloat radius, cpVect offset ) ;
-
-STRUCT: cpSegmentShape
-    { shape cpShape }
-    { a     cpVect  }
-    { b     cpVect  }
-    { n     cpVect  }
-    { r     cpFloat }
-    { ta    cpVect  }
-    { tb    cpVect  }
-    { tn    cpVect  } ;
-
-FUNCTION: cpSegmentShape* cpSegmentShapeAlloc ( ) ;
-FUNCTION: cpSegmentShape* cpSegmentShapeInit ( cpSegmentShape* seg, cpBody* body, cpVect a, cpVect b, cpFloat radius ) ;
-FUNCTION: cpShape* cpSegmentShapeNew ( cpBody* body, cpVect a, cpVect b, cpFloat radius ) ;
-FUNCTION: void cpResetShapeIdCounter ( ) ;
-FUNCTION: void cpSegmentQueryInfoPrint ( cpSegmentQueryInfo* info ) ;
-FUNCTION: int cpShapeSegmentQuery ( cpShape* shape, cpVect a, cpVect b, cpSegmentQueryInfo* info ) ;
-
-TYPED: cpSegmentQueryHitPoint ( start: cpVect end: cpVect info: cpSegmentQueryInfo -- hit-point: cpVect )
-    t>> cpvlerp ; inline
-
-TYPED: cpSegmentQueryHitDist ( start: cpVect end: cpVect info: cpSegmentQueryInfo -- hit-dist )
-    t>> [ cpvdist ] dip * ; inline
-
-! cpPolyShape.h
-STRUCT: cpPolyShapeAxis
-    { n cpVect  }
-    { d cpFloat } ;
-SPECIALIZED-ARRAY: cpPolyShapeAxis
-
-STRUCT: cpPolyShape
-    { shape    cpShape          }
-    { numVerts int              }
-    { verts    cpVect*          }
-    { axes     cpPolyShapeAxis* }
-    { tVerts   cpVect*          }
-    { tAxes    cpPolyShapeAxis* } ;
-
-FUNCTION: cpPolyShape* cpPolyShapeAlloc ( ) ;
-FUNCTION: cpPolyShape* cpPolyShapeInit ( cpPolyShape* poly, cpBody* body, int numVerts, cpVect* verts, cpVect offset ) ;
-FUNCTION: cpShape* cpPolyShapeNew ( cpBody* body, int numVerts, cpVect* verts, cpVect offset ) ;
-FUNCTION: int cpPolyValidate ( cpVect* verts, int numVerts ) ;
-FUNCTION: int cpPolyShapeGetNumVerts ( cpShape* shape ) ;
-FUNCTION: cpVect cpPolyShapeGetVert ( cpShape* shape, int idx ) ;
-
-TYPED: cpPolyShapeValueOnAxis ( poly: cpPolyShape n: cpVect d -- min-dist )
-    swap rot [ numVerts>> ] [ tVerts>> swap <direct-cpVect-array> ] bi swap
-    [ cpvdot ] curry [ min ] reduce swap - ; inline
-
-TYPED: cpPolyShapeContainsVert ( poly: cpPolyShape v: cpVect -- ? )
-    swap [ numVerts>> ] [ tAxes>> swap <direct-cpPolyShapeAxis-array> ] bi swap
-    [
-        [ [ n>> ] dip cpvdot ] [ drop d>> ] 2bi -
-    ] curry [ max ] reduce 0.0 <= ; inline
-
-TYPED: cpPolyShapeContainsVertPartial ( poly: cpPolyShape v: cpVect n: cpVect -- ? )
-    rot [ numVerts>> ] [ tAxes>> swap <direct-cpPolyShapeAxis-array> ] bi -rot
-    [| axis v n |
-        axis n>> n cpvdot 0.0 < 0
-        [ 0.0 ]
-        [ axis n>> v cpvdot axis d>> - ]
-        if
-    ] 2curry [ max ] reduce 0.0 <= ; inline
-
-! cpArbiter.h
-C-TYPE: cpArbiter
-C-TYPE: cpSpace
-C-TYPE: cpCollisionHandler
-
-STRUCT: cpContact
-    { p      cpVect      }
-    { n      cpVect      }
-    { dist   cpFloat     }
-    { r1     cpVect      }
-    { r2     cpVect      }
-    { nMass  cpFloat     }
-    { tMass  cpFloat     }
-    { bounce cpFloat     }
-    { jnAcc  cpFloat     }
-    { jtAcc  cpFloat     }
-    { jBias  cpFloat     }
-    { bias   cpFloat     }
-    { hash   cpHashValue } ;
-
-FUNCTION: cpContact* cpContactInit ( cpContact* con, cpVect p, cpVect n, cpFloat dist, cpHashValue hash ) ;
-
-C-ENUM:
-    cpArbiterStateNormal
-    cpArbiterStateFirstColl
-    cpArbiterStateIgnore ;
-TYPEDEF: int cpArbiterState
-
-STRUCT: cpArbiter
-    { numContacts int                 }
-    { contacts    cpContact*          }
-    { a           cpShape*            }
-    { b           cpShape*            }
-    { e           cpFloat             }
-    { u           cpFloat             }
-    { surface_vr  cpVect              }
-    { stamp       int                 }
-    { handler     cpCollisionHandler* }
-    { swappedColl char                }
-    { state       char                } ;
-
-FUNCTION: cpArbiter* cpArbiterAlloc ( ) ;
-FUNCTION: cpArbiter* cpArbiterInit ( cpArbiter* arb, cpShape* a, cpShape* b ) ;
-FUNCTION: cpArbiter* cpArbiterNew ( cpShape* a, cpShape* b ) ;
-FUNCTION: void cpArbiterDestroy ( cpArbiter* arb ) ;
-FUNCTION: void cpArbiterFree ( cpArbiter* arb ) ;
-FUNCTION: void cpArbiterUpdate ( cpArbiter* arb, cpContact* contacts, int numContacts, cpCollisionHandler* handler, cpShape* a, cpShape* b ) ;
-FUNCTION: void cpArbiterPreStep ( cpArbiter* arb, cpFloat dt_inv ) ;
-FUNCTION: void cpArbiterApplyCachedImpulse ( cpArbiter* arb ) ;
-FUNCTION: void cpArbiterApplyImpulse ( cpArbiter* arb, cpFloat eCoef ) ;
-FUNCTION: cpVect cpArbiterTotalImpulse ( cpArbiter* arb ) ;
-FUNCTION: cpVect cpArbiterTotalImpulseWithFriction ( cpArbiter* arb ) ;
-FUNCTION: void cpArbiterIgnore ( cpArbiter* arb ) ;
-
-TYPED: cpArbiterGetShapes ( arb: cpArbiter -- a: cpShape b: cpShape )
-    dup swappedColl>> 0 = [
-        [ a>> ] [ b>> ] bi
-    ] [
-        [ b>> ] [ a>> ] bi
-    ] if ; inline
-
-TYPED: cpArbiterIsFirstContact ( arb: cpArbiter -- ? )
-    state>> cpArbiterStateFirstColl = ; inline
-
-TYPED: cpArbiterGetNormal ( arb: cpArbiter i -- n: cpVect )
-    [
-        swap
-        [ numContacts>> ]
-        [ contacts>> swap <direct-void*-array> ] bi nth cpContact memory>struct n>>
-    ]
-    [
-        drop swappedColl>> 0 = [ ] [ cpvneg ] if
-    ] 2bi ; inline
-
-TYPED: cpArbiterGetPoint ( arb: cpArbiter i -- p: cpVect )
-    swap
-    [ numContacts>> ]
-    [ contacts>> swap <direct-void*-array> ] bi
-    nth cpContact memory>struct p>> ; inline
-
-! cpCollision.h
-FUNCTION: int cpCollideShapes ( cpShape* a, cpShape* b, cpContact** arr ) ;
-
-! cpConstraint.h
-
-C-TYPE: cpConstraintClass
-C-TYPE: cpConstraint
-
-CALLBACK: void cpConstraintPreStepFunction ( cpConstraint* constraint, cpFloat dt, cpFloat dt_inv ) ;
-CALLBACK: void cpConstraintApplyImpulseFunction ( cpConstraint* constraint ) ;
-CALLBACK: cpFloat cpConstraintGetImpulseFunction ( cpConstraint* constraint ) ;
-
-STRUCT: cpConstraintClass
-    { preStep      cpConstraintPreStepFunction      }
-    { applyImpulse cpConstraintApplyImpulseFunction }
-    { getImpulse   cpConstraintGetImpulseFunction   } ;
-
-STRUCT: cpConstraint
-    { klass    cpConstraintClass* }
-    { a        cpBody*            }
-    { b        cpBody*            }
-    { maxForce cpFloat            }
-    { biasCoef cpFloat            }
-    { maxBias  cpFloat            }
-    { data     cpDataPointer      } ;
-
-FUNCTION: void cpConstraintDestroy ( cpConstraint* constraint ) ;
-FUNCTION: void cpConstraintFree ( cpConstraint* constraint ) ;
-FUNCTION: void cpConstraintCheckCast ( cpConstraint* constraint, cpConstraintClass* klass ) ;
-
-! cpPinJoint.h
-FUNCTION: cpConstraintClass* cpPinJointGetClass ( ) ;
-
-STRUCT: cpPinJoint
-    { constraint cpConstraint }
-    { anchr1     cpVect       }
-    { anchr2     cpVect       }
-    { dist       cpFloat      }
-    { r1         cpVect       }
-    { r2         cpVect       }
-    { n          cpVect       }
-    { nMass      cpFloat      }
-    { jnAcc      cpFloat      }
-    { jnMax      cpFloat      }
-    { bias       cpFloat      } ;
-
-FUNCTION: cpPinJoint* cpPinJointAlloc ( ) ;
-FUNCTION: cpPinJoint* cpPinJointInit ( cpPinJoint* joint, cpBody* a, cpBody* b, cpVect anchr1, cpVect anchr2 ) ;
-FUNCTION: cpConstraint* cpPinJointNew ( cpBody* a, cpBody* b, cpVect anchr1, cpVect anchr2 ) ;
-
-! cpSlideJoint.h
-FUNCTION: cpConstraintClass* cpSlideJointGetClass ( ) ;
-
-STRUCT: cpSlideJoint
-    { constraint cpConstraint }
-    { anchr1     cpVect       }
-    { anchr2     cpVect       }
-    { min        cpFloat      }
-    { max        cpFloat      }
-    { r1         cpVect       }
-    { r2         cpVect       }
-    { n          cpVect       }
-    { nMass      cpFloat      }
-    { jnAcc      cpFloat      }
-    { jnMax      cpFloat      }
-    { bias       cpFloat      } ;
-
-FUNCTION: cpSlideJoint* cpSlideJointAlloc ( ) ;
-FUNCTION: cpSlideJoint* cpSlideJointInit ( cpSlideJoint* joint, cpBody* a, cpBody* b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max ) ;
-FUNCTION: cpConstraint* cpSlideJointNew ( cpBody* a, cpBody* b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max ) ;
-
-! cpPivotJoint.h
-FUNCTION: cpConstraintClass* cpPivotJointGetClass ( ) ;
-
-STRUCT: cpPivotJoint
-    { constraint cpConstraint }
-    { anchr1     cpVect       }
-    { anchr2     cpVect       }
-    { r1         cpVect       }
-    { r2         cpVect       }
-    { k1         cpVect       }
-    { k2         cpVect       }
-    { jAcc       cpVect       }
-    { jMaxLen    cpFloat      }
-    { bias       cpVect       } ;
-
-FUNCTION: cpPivotJoint* cpPivotJointAlloc ( ) ;
-FUNCTION: cpPivotJoint* cpPivotJointInit ( cpPivotJoint* joint, cpBody* a, cpBody* b, cpVect anchr1, cpVect anchr2 ) ;
-FUNCTION: cpConstraint* cpPivotJointNew ( cpBody* a, cpBody* b, cpVect pivot ) ;
-FUNCTION: cpConstraint* cpPivotJointNew2 ( cpBody* a, cpBody* b, cpVect anchr1, cpVect anchr2 ) ;
-
-! cpGrooveJoint.h
-FUNCTION: cpConstraintClass* cpGrooveJointGetClass ( ) ;
-
-STRUCT: cpGrooveJoint
-    { constraint   cpConstraint   }
-    { grv_n        cpVect         }
-    { grv_a        cpVect         }
-    { grv_b        cpVect         }
-    { anchr2       cpVect         }
-    { grv_tn       cpVect         }
-    { clamp        cpFloat        }
-    { r1           cpVect         }
-    { r2           cpVect         }
-    { k1           cpVect         }
-    { k2           cpVect         }
-    { jAcc         cpVect         }
-    { jMaxLen      cpFloat        }
-    { bias         cpVect         } ;
-
-FUNCTION: cpGrooveJoint* cpGrooveJointAlloc ( ) ;
-FUNCTION: cpGrooveJoint* cpGrooveJointInit ( cpGrooveJoint* joint, cpBody* a, cpBody* b, cpVect groove_a, cpVect groove_b, cpVect anchr2 ) ;
-FUNCTION: cpConstraint* cpGrooveJointNew ( cpBody* a, cpBody* b, cpVect groove_a, cpVect groove_b, cpVect anchr2 ) ;
-
-! cpDampedSpring.h
-CALLBACK: cpFloat cpDampedSpringForceFunc ( cpConstraint* spring, cpFloat dist ) ;
-FUNCTION: cpConstraintClass* cpDampedSpringGetClass ( ) ;
-
-STRUCT: cpDampedSpring
-    { constraint      cpConstraint            }
-    { anchr1          cpVect                  }
-    { anchr2          cpVect                  }
-    { restLength      cpFloat                 }
-    { stiffness       cpFloat                 }
-    { damping         cpFloat                 }
-    { springForceFunc cpDampedSpringForceFunc }
-    { dt              cpFloat                 }
-    { target_vrn      cpFloat                 }
-    { r1              cpVect                  }
-    { r2              cpVect                  }
-    { nMass           cpFloat                 }
-    { n               cpVect                  } ;
-
-FUNCTION: cpDampedSpring* cpDampedSpringAlloc ( ) ;
-FUNCTION: cpDampedSpring* cpDampedSpringInit ( cpDampedSpring* joint, cpBody* a, cpBody* b, cpVect anchr1, cpVect anchr2, cpFloat restLength, cpFloat stiffness, cpFloat damping ) ;
-FUNCTION: cpConstraint* cpDampedSpringNew ( cpBody* a, cpBody* b, cpVect anchr1, cpVect anchr2, cpFloat restLength, cpFloat stiffness, cpFloat damping ) ;
-
-! cpDampedRotarySpring.h
-CALLBACK: cpFloat cpDampedRotarySpringTorqueFunc ( cpConstraint* spring, cpFloat relativeAngle ) ;
-FUNCTION: cpConstraintClass* cpDampedRotarySpringGetClass ( ) ;
-
-STRUCT: cpDampedRotarySpring
-    { constraint       cpConstraint                   }
-    { restAngle        cpFloat                        }
-    { stiffness        cpFloat                        }
-    { damping          cpFloat                        }
-    { springTorqueFunc cpDampedRotarySpringTorqueFunc }
-    { dt               cpFloat                        }
-    { target_wrn       cpFloat                        }
-    { iSum             cpFloat                        } ;
-
-FUNCTION: cpDampedRotarySpring* cpDampedRotarySpringAlloc ( ) ;
-FUNCTION: cpDampedRotarySpring* cpDampedRotarySpringInit ( cpDampedRotarySpring* joint, cpBody* a, cpBody* b, cpFloat restAngle, cpFloat stiffness, cpFloat damping ) ;
-FUNCTION: cpConstraint* cpDampedRotarySpringNew ( cpBody* a, cpBody* b, cpFloat restAngle, cpFloat stiffness, cpFloat damping ) ;
-
-! cpRotaryLimitJoint.h
-FUNCTION: cpConstraintClass* cpRotaryLimitJointGetClass ( ) ;
-
-STRUCT: cpRotaryLimitJoint
-    { constraint cpConstraint   }
-    { min        cpFloat        }
-    { max        cpFloat        }
-    { iSum       cpFloat        }
-    { bias       cpFloat        }
-    { jAcc       cpFloat        }
-    { jMax       cpFloat        } ;
-
-FUNCTION: cpRotaryLimitJoint* cpRotaryLimitJointAlloc ( ) ;
-FUNCTION: cpRotaryLimitJoint* cpRotaryLimitJointInit ( cpRotaryLimitJoint* joint, cpBody* a, cpBody* b, cpFloat min, cpFloat max ) ;
-FUNCTION: cpConstraint* cpRotaryLimitJointNew ( cpBody* a, cpBody* b, cpFloat min, cpFloat max ) ;
-
-! cpRatchetJoint.h
-FUNCTION: cpConstraintClass* cpRatchetJointGetClass ( ) ;
-
-STRUCT: cpRatchetJoint
-    { constraint cpConstraint }
-    { angle      cpFloat      }
-    { phase      cpFloat      }
-    { ratchet    cpFloat      }
-    { iSum       cpFloat      }
-    { bias       cpFloat      }
-    { jAcc       cpFloat      }
-    { jMax       cpFloat      } ;
-
-FUNCTION: cpRatchetJoint* cpRatchetJointAlloc ( ) ;
-FUNCTION: cpRatchetJoint* cpRatchetJointInit ( cpRatchetJoint* joint, cpBody* a, cpBody* b, cpFloat phase, cpFloat ratchet ) ;
-FUNCTION: cpConstraint* cpRatchetJointNew ( cpBody* a, cpBody* b, cpFloat phase, cpFloat ratchet ) ;
-
-! cpGearJoint.h
-FUNCTION: cpConstraintClass* cpGearJointGetClass ( ) ;
-
-STRUCT: cpGearJoint
-    { constraint cpConstraint }
-    { phase      cpFloat      }
-    { ratio      cpFloat      }
-    { ratio_inv  cpFloat      }
-    { iSum       cpFloat      }
-    { bias       cpFloat      }
-    { jAcc       cpFloat      }
-    { jMax       cpFloat      } ;
-
-FUNCTION: cpGearJoint* cpGearJointAlloc ( ) ;
-FUNCTION: cpGearJoint* cpGearJointInit ( cpGearJoint* joint, cpBody* a, cpBody* b, cpFloat phase, cpFloat ratio ) ;
-FUNCTION: cpConstraint* cpGearJointNew ( cpBody* a, cpBody* b, cpFloat phase, cpFloat ratio ) ;
-FUNCTION: void cpGearJointSetRatio ( cpConstraint* constraint, cpFloat value ) ;
-
-! cpSimpleMotor.h
-FUNCTION: cpConstraintClass* cpSimpleMotorGetClass ( ) ;
-
-STRUCT: cpSimpleMotor
-    { constraint cpConstraint }
-    { rate       cpFloat      }
-    { iSum       cpFloat      }
-    { jAcc       cpFloat      }
-    { jMax       cpFloat      } ;
-
-FUNCTION: cpSimpleMotor* cpSimpleMotorAlloc ( ) ;
-FUNCTION: cpSimpleMotor* cpSimpleMotorInit ( cpSimpleMotor* joint, cpBody* a, cpBody* b, cpFloat rate ) ;
-FUNCTION: cpConstraint* cpSimpleMotorNew ( cpBody* a, cpBody* b, cpFloat rate ) ;
-
-! cpSpace.h
-C-TYPE: cpSpace
-
-CALLBACK: int cpCollisionBeginFunc ( cpArbiter* arb, cpSpace* space, void* data ) ;
-CALLBACK: int cpCollisionPreSolveFunc ( cpArbiter* arb, cpSpace* space, void* data ) ;
-CALLBACK: void cpCollisionPostSolveFunc ( cpArbiter* arb, cpSpace* space, void* data ) ;
-CALLBACK: void cpCollisionSeparateFunc ( cpArbiter* arb, cpSpace* space, void* data ) ;
-
-STRUCT: cpCollisionHandler
-    { a         cpCollisionType          }
-    { b         cpCollisionType          }
-    { begin     cpCollisionBeginFunc     }
-    { preSolve  cpCollisionPreSolveFunc  }
-    { postSolve cpCollisionPostSolveFunc }
-    { separate  cpCollisionSeparateFunc  }
-    { data      void*                    } ;
-
-STRUCT: cpSpace
-    { iterations        int                }
-    { elasticIterations int                }
-    { gravity           cpVect             }
-    { damping           cpFloat            }
-    { stamp             int                }
-    { staticShapes      cpSpaceHash*       }
-    { activeShapes      cpSpaceHash*       }
-    { bodies            cpArray*           }
-    { arbiters          cpArray*           }
-    { contactSet        cpHashSet*         }
-    { constraints       cpArray*           }
-    { collFuncSet       cpHashSet*         }
-    { defaultHandler    cpCollisionHandler }
-    { postStepCallbacks cpHashSet*         } ;
-
-FUNCTION: cpSpace* cpSpaceAlloc ( ) ;
-FUNCTION: cpSpace* cpSpaceInit ( cpSpace* space ) ;
-FUNCTION: cpSpace* cpSpaceNew ( ) ;
-FUNCTION: void cpSpaceDestroy ( cpSpace* space ) ;
-FUNCTION: void cpSpaceFree ( cpSpace* space ) ;
-FUNCTION: void cpSpaceFreeChildren ( cpSpace* space ) ;
-FUNCTION: void cpSpaceSetDefaultCollisionHandler (
-    cpSpace*                 space,
-    cpCollisionBeginFunc     begin,
-    cpCollisionPreSolveFunc  preSolve,
-    cpCollisionPostSolveFunc postSolve,
-    cpCollisionSeparateFunc  separate,
-    void*                    data ) ;
-FUNCTION: void cpSpaceAddCollisionHandler (
-    cpSpace*                 space,
-    cpCollisionType          a,
-    cpCollisionType          b,
-    cpCollisionBeginFunc     begin,
-    cpCollisionPreSolveFunc  preSolve,
-    cpCollisionPostSolveFunc postSolve,
-    cpCollisionSeparateFunc  separate,
-    void*                    data ) ;
-FUNCTION: void cpSpaceRemoveCollisionHandler ( cpSpace* space, cpCollisionType a, cpCollisionType b ) ;
-FUNCTION: cpShape* cpSpaceAddShape ( cpSpace* space, cpShape* shape ) ;
-FUNCTION: cpShape* cpSpaceAddStaticShape ( cpSpace* space, cpShape* shape ) ;
-FUNCTION: cpBody* cpSpaceAddBody ( cpSpace* space, cpBody* body ) ;
-FUNCTION: cpConstraint* cpSpaceAddConstraint ( cpSpace* space, cpConstraint* constraint ) ;
-FUNCTION: void cpSpaceRemoveShape ( cpSpace* space, cpShape* shape ) ;
-FUNCTION: void cpSpaceRemoveStaticShape ( cpSpace* space, cpShape* shape ) ;
-FUNCTION: void cpSpaceRemoveBody ( cpSpace* space, cpBody* body ) ;
-FUNCTION: void cpSpaceRemoveConstraint ( cpSpace* space, cpConstraint* constraint ) ;
-CALLBACK: void cpPostStepFunc ( cpSpace* space, void* obj, void* data ) ;
-FUNCTION: void cpSpaceAddPostStepCallback ( cpSpace* space, cpPostStepFunc func, void* obj, void* data ) ;
-CALLBACK: void cpSpacePointQueryFunc ( cpShape* shape, void* data ) ;
-FUNCTION: void cpSpacePointQuery ( cpSpace* space, cpVect point, cpLayers layers, cpGroup group, cpSpacePointQueryFunc func, void* data ) ;
-FUNCTION: cpShape* cpSpacePointQueryFirst ( cpSpace* space, cpVect point, cpLayers layers, cpGroup group ) ;
-CALLBACK: void cpSpaceSegmentQueryFunc ( cpShape* shape, cpFloat t, cpVect n, void* data ) ;
-FUNCTION: int cpSpaceSegmentQuery ( cpSpace* space, cpVect start, cpVect end, cpLayers layers, cpGroup group, cpSpaceSegmentQueryFunc func, void* data ) ;
-FUNCTION: cpShape* cpSpaceSegmentQueryFirst ( cpSpace* space, cpVect start, cpVect end, cpLayers layers, cpGroup group, cpSegmentQueryInfo* out ) ;
-CALLBACK: void cpSpaceBBQueryFunc ( cpShape* shape, void* data ) ;
-FUNCTION: void cpSpaceBBQuery ( cpSpace* space, cpBB bb, cpLayers layers, cpGroup group, cpSpaceBBQueryFunc func, void* data ) ;
-CALLBACK: void cpSpaceBodyIterator ( cpBody* body, void* data ) ;
-FUNCTION: void cpSpaceEachBody ( cpSpace* space, cpSpaceBodyIterator func, void* data ) ;
-FUNCTION: void cpSpaceResizeStaticHash ( cpSpace* space, cpFloat dim, int count ) ;
-FUNCTION: void cpSpaceResizeActiveHash ( cpSpace* space, cpFloat dim, int count ) ;
-FUNCTION: void cpSpaceRehashStatic ( cpSpace* space ) ;
-FUNCTION: void cpSpaceStep ( cpSpace* space, cpFloat dt ) ;
-
-! chipmunk.h
-FUNCTION: void cpInitChipmunk ( ) ;
-FUNCTION: cpFloat cpMomentForCircle ( cpFloat m, cpFloat r1, cpFloat r2, cpVect offset ) ;
-FUNCTION: cpFloat cpMomentForSegment ( cpFloat m, cpVect a, cpVect b ) ;
-FUNCTION: cpFloat cpMomentForPoly ( cpFloat m, int numVerts, cpVect* verts, cpVect offset ) ;
-
index 38a8689bece0544769692761d586db9d05e116cb..b0aa7f18b4027763aa0362ca4464f8f680bb3c24 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2010 Erik Charlebois
 ! See http:// factorcode.org/license.txt for BSD license.
-USING: accessors chipmunk classes.struct game.worlds kernel locals
+USING: accessors chipmunk.ffi classes.struct game.worlds kernel locals
 math method-chains opengl.gl random sequences specialized-arrays
 specialized-arrays.instances.alien.c-types.void* ui ui.gadgets.worlds
 ui.pixel-formats ;
diff --git a/extra/chipmunk/ffi/ffi.factor b/extra/chipmunk/ffi/ffi.factor
new file mode 100644 (file)
index 0000000..e2adf2d
--- /dev/null
@@ -0,0 +1,845 @@
+! Copyright (C) 2010 Erik Charlebois
+! See http:// factorcode.org/license.txt for BSD license.
+USING: accessors alien.c-types alien.syntax classes.struct combinators
+combinators.short-circuit kernel math math.order sequences
+specialized-arrays.instances.alien.c-types.void* typed
+specialized-arrays locals system alien.libraries ;
+IN: chipmunk.ffi
+
+<< "chipmunk" {
+        { [ os windows? ] [ "chipmunk.dll" ] }
+        { [ os macosx? ] [ "libchipmunk.dylib"  ] }
+        { [ os unix?  ] [ "libchipmunk.so" ] }
+    } cond "cdecl" add-library >>
+LIBRARY: chipmunk
+
+! chipmunk_types.h
+TYPEDEF: double cpFloat
+STRUCT: cpVect
+    { x cpFloat }
+    { y cpFloat } ;
+SPECIALIZED-ARRAY: cpVect
+
+TYPEDEF: uint cpHashValue
+TYPEDEF: void* cpDataPointer
+TYPEDEF: uint cpCollisionType
+TYPEDEF: uint cpLayers
+TYPEDEF: uint cpGroup
+
+CONSTANT: CP_NO_GROUP 0
+CONSTANT: CP_ALL_LAYERS HEX: ffffffff
+
+! cpVect.h
+TYPED: cpv ( x y -- v: cpVect )
+    cpVect <struct-boa> ; inline
+
+TYPED: cpvzero ( -- v: cpVect )
+    0.0 0.0 cpv ; inline
+
+FUNCTION: cpFloat cpvlength ( cpVect v ) ;
+FUNCTION: cpVect cpvslerp ( cpVect v1, cpVect v2, cpFloat t ) ;
+FUNCTION: cpVect cpvslerpconst ( cpVect v1, cpVect v2, cpFloat a ) ;
+FUNCTION: cpVect cpvforangle ( cpFloat a ) ;
+FUNCTION: cpFloat cpvtoangle ( cpVect v ) ;
+FUNCTION: c-string cpvstr ( cpVect v ) ;
+
+TYPED: cpvadd ( v1: cpVect v2: cpVect -- v3: cpVect )
+    [ [ x>> ] bi@ + ]
+    [ [ y>> ] bi@ + ] 2bi cpv ; inline
+
+TYPED: cpvneg ( v1: cpVect -- v2: cpVect )
+    [ x>> ] [ y>> ] bi [ neg ] bi@ cpv ; inline
+
+TYPED: cpvsub ( v1: cpVect v2: cpVect -- v3: cpVect )
+    [ [ x>> ] bi@ - ]
+    [ [ y>> ] bi@ - ] 2bi cpv ; inline
+
+TYPED: cpvmult ( v1: cpVect s -- v2: cpVect )
+    [ swap x>> * ]
+    [ swap y>> * ] 2bi cpv ; inline
+
+TYPED: cpvdot ( v1: cpVect v2: cpVect -- s )
+    [ [ x>> ] bi@ * ]
+    [ [ y>> ] bi@ * ] 2bi + ; inline
+
+TYPED: cpvcross ( v1: cpVect v2: cpVect -- s )
+    [ [ x>> ] [ y>> ] bi* * ]
+    [ [ y>> ] [ x>> ] bi* * ] 2bi - ; inline
+
+TYPED: cpvperp ( v1: cpVect -- v2: cpVect )
+    [ y>> neg ] [ x>> ] bi cpv ; inline
+
+TYPED: cpvrperp ( v1: cpVect -- v2: cpVect )
+    [ y>> ] [ x>> neg ] bi cpv ; inline
+
+TYPED: cpvproject ( v1: cpVect v2: cpVect -- v3: cpVect )
+    [ nip ]
+    [ cpvdot ]
+    [ nip dup cpvdot ]
+    2tri / cpvmult ; inline
+
+TYPED: cpvrotate ( v1: cpVect v2: cpVect -- v3: cpVect )
+    [
+        [ [ x>> ] bi@ * ]
+        [ [ y>> ] bi@ * ] 2bi -
+    ]
+    [
+        [ [ x>> ] [ y>> ] bi* * ]
+        [ [ y>> ] [ x>> ] bi* * ] 2bi +
+    ] 2bi cpv ; inline
+
+TYPED: cpvunrotate ( v1: cpVect v2: cpVect -- v3: cpVect )
+    [
+        [ [ x>> ] bi@ * ]
+        [ [ y>> ] bi@ * ] 2bi +
+    ]
+    [
+        [ [ y>> ] [ x>> ] bi* * ]
+        [ [ x>> ] [ y>> ] bi* * ] 2bi -
+    ] 2bi cpv ; inline
+
+TYPED: cpvlengthsq ( v: cpVect -- s )
+    dup cpvdot ; inline
+
+TYPED: cpvlerp ( v1: cpVect v2: cpVect s -- v3: cpVect )
+    [ nip 1.0 swap - cpvmult ]
+    [ cpvmult nip ] 3bi cpvadd ; inline
+
+TYPED: cpvnormalize ( v1: cpVect -- v2: cpVect )
+    dup cpvlength 1.0 swap / cpvmult ; inline
+
+TYPED: cpvnormalize_safe ( v1: cpVect -- v2: cpVect )
+    dup [ x>> 0.0 = ] [ y>> 0.0 = ] bi and
+    [ drop cpvzero ]
+    [ cpvnormalize ] if ; inline
+
+TYPED: cpvclamp ( v1: cpVect len -- v2: cpVect )
+    2dup
+    [ dup cpvdot ]
+    [ sq ] 2bi* >
+    [ [ cpvnormalize ] dip cpvmult ]
+    [ drop ] if ; inline
+
+TYPED: cpvlerpconst ( v1: cpVect v2: cpVect d -- v3: cpVect )
+    [ 2drop ]
+    [ [ swap cpvsub ] dip cpvclamp ] 3bi cpvadd ; inline
+
+TYPED: cpvdist ( v1: cpVect v2: cpVect -- dist )
+    cpvsub cpvlength ; inline
+
+TYPED: cpvdistsq ( v1: cpVect v2: cpVect -- distsq )
+    cpvsub cpvlengthsq ; inline
+
+TYPED: cpvnear ( v1: cpVect v2: cpVect dist -- ? )
+    [ cpvdistsq ] dip sq < ; inline
+
+! cpBB.h
+STRUCT: cpBB
+    { l cpFloat }
+    { b cpFloat }
+    { r cpFloat }
+    { t cpFloat } ;
+
+TYPED: cpBBNew ( l b r t -- cpbb: cpBB )
+    cpBB <struct-boa> ; inline
+
+TYPED: cpBBintersects ( a: cpBB b: cpBB -- ? )
+    {
+        [ [ l>> ] [ r>> ] bi* <= ]
+        [ [ r>> ] [ l>> ] bi*  > ]
+        [ [ b>> ] [ t>> ] bi* <= ]
+        [ [ t>> ] [ b>> ] bi*  > ]
+    } 2&& ; inline
+
+TYPED: cpBBcontainsBB ( bb: cpBB other: cpBB -- ? )
+    {
+        [ [ l>> ] bi@ < ]
+        [ [ r>> ] bi@ > ]
+        [ [ b>> ] bi@ < ]
+        [ [ t>> ] bi@ > ]
+    } 2&& ; inline
+
+TYPED: cpBBcontainsVect ( bb: cpBB v: cpVect -- ? )
+    {
+        [ [ l>> ] [ x>> ] bi* < ]
+        [ [ r>> ] [ x>> ] bi* > ]
+        [ [ b>> ] [ y>> ] bi* < ]
+        [ [ t>> ] [ y>> ] bi* > ]
+    } 2&& ; inline
+
+TYPED: cpBBmerge ( a: cpBB b: cpBB -- c: cpBB )
+    {
+        [ [ l>> ] bi@ min ]
+        [ [ b>> ] bi@ min ]
+        [ [ r>> ] bi@ max ]
+        [ [ t>> ] bi@ max ]
+    } 2cleave cpBBNew ; inline
+
+TYPED: cpBBexpand ( bb: cpBB v: cpVect -- b: cpBB )
+    {
+        [ [ l>> ] [ x>> ] bi* min ]
+        [ [ b>> ] [ y>> ] bi* min ]
+        [ [ r>> ] [ x>> ] bi* max ]
+        [ [ t>> ] [ y>> ] bi* max ]
+    } 2cleave cpBBNew ; inline
+
+FUNCTION: cpVect cpBBClampVect ( cpBB bb, cpVect v ) ;
+FUNCTION: cpVect cpBBWrapVect ( cpBB bb, cpVect v ) ;
+
+! cpBody.h
+C-TYPE: cpBody
+CALLBACK: void cpBodyVelocityFunc ( cpBody* body, cpVect gravity, cpFloat damping, cpFloat dt ) ;
+CALLBACK: void cpBodyPositionFunc ( cpBody* body, cpFloat dt ) ;
+
+STRUCT: cpBody
+    { velocity_func cpBodyVelocityFunc }
+    { position_func cpBodyPositionFunc }
+    { m             cpFloat            }
+    { m_inv         cpFloat            }
+    { i             cpFloat            }
+    { i_inv         cpFloat            }
+    { p             cpVect             }
+    { v             cpVect             }
+    { f             cpVect             }
+    { a             cpFloat            }
+    { w             cpFloat            }
+    { t             cpFloat            }
+    { rot           cpVect             }
+    { data          cpDataPointer      }
+    { v_limit       cpFloat            }
+    { w_limit       cpFloat            }
+    { v_bias        cpVect             }
+    { w_bias        cpFloat            } ;
+
+FUNCTION: cpBody* cpBodyAlloc ( ) ;
+FUNCTION: cpBody* cpBodyInit ( cpBody* body, cpFloat m, cpFloat i ) ;
+FUNCTION: cpBody* cpBodyNew ( cpFloat m, cpFloat i ) ;
+FUNCTION: void cpBodyDestroy ( cpBody* body ) ;
+FUNCTION: void cpBodyFree ( cpBody* body ) ;
+FUNCTION: void cpBodySetMass ( cpBody* body, cpFloat m ) ;
+FUNCTION: void cpBodySetMoment ( cpBody* body, cpFloat i ) ;
+FUNCTION: void cpBodySetAngle ( cpBody* body, cpFloat a ) ;
+FUNCTION: void cpBodySlew ( cpBody* body, cpVect pos, cpFloat dt ) ;
+FUNCTION: void cpBodyUpdateVelocity ( cpBody* body, cpVect gravity, cpFloat damping, cpFloat dt ) ;
+FUNCTION: void cpBodyUpdatePosition ( cpBody* body, cpFloat dt ) ;
+
+TYPED: cpBodyLocal2World ( body: cpBody v: cpVect -- v2: cpVect )
+    [ drop p>> ]
+    [ swap rot>> cpvrotate ] 2bi cpvadd ; inline
+
+TYPED: cpBodyWorld2Local ( body: cpBody v: cpVect -- v2: cpVect )
+    [ swap p>> cpvsub ]
+    [ drop rot>> ] 2bi cpvunrotate ; inline
+
+TYPED: cpBodyApplyImpulse ( body: cpBody j: cpVect r: cpVect -- )
+    [
+        drop
+        [ drop dup v>> ]
+        [ swap m_inv>> cpvmult ] 2bi cpvadd >>v drop
+    ]
+    [
+        [ 2drop dup w_bias>> ]
+        [ swap cpvcross [ i_inv>> ] dip * ] 3bi + >>w_bias drop
+    ] 3bi ; inline
+
+FUNCTION: void cpBodyResetForces ( cpBody* body ) ;
+FUNCTION: void cpBodyApplyForce ( cpBody* body, cpVect f, cpVect r ) ;
+FUNCTION: void cpApplyDampedSpring ( cpBody* a, cpBody* b, cpVect anchr1, cpVect anchr2, cpFloat rlen, cpFloat k, cpFloat dmp, cpFloat dt ) ;
+
+! cpArray.h
+STRUCT: cpArray
+    { num int    }
+    { max int    }
+    { arr void** } ;
+
+CALLBACK: void cpArrayIter ( void* ptr, void* data ) ;
+
+FUNCTION: cpArray* cpArrayAlloc ( ) ;
+FUNCTION: cpArray* cpArrayInit ( cpArray* arr, int size ) ;
+FUNCTION: cpArray* cpArrayNew ( int size ) ;
+FUNCTION: void cpArrayDestroy ( cpArray* arr ) ;
+FUNCTION: void cpArrayFree ( cpArray* arr ) ;
+FUNCTION: void cpArrayPush ( cpArray* arr, void* object ) ;
+FUNCTION: void cpArrayDeleteIndex ( cpArray* arr, int idx ) ;
+FUNCTION: void cpArrayDeleteObj ( cpArray* arr, void* obj ) ;
+FUNCTION: void cpArrayEach ( cpArray* arr, cpArrayIter iterFunc, void* data ) ;
+FUNCTION: int cpArrayContains ( cpArray* arr, void* ptr ) ;
+
+! cpHashSet.h
+STRUCT: cpHashSetBin
+    { elt  void*         }
+    { hash cpHashValue   }
+    { next cpHashSetBin* } ;
+
+CALLBACK: int cpHashSetEqlFunc ( void* ptr, void* elt ) ;
+CALLBACK: void* cpHashSetTransFunc ( void* ptr, void* data ) ;
+CALLBACK: void cpHashSetIterFunc ( void* elt, void* data ) ;
+CALLBACK: int cpHashSetFilterFunc ( void* elt, void* data ) ;
+
+STRUCT: cpHashSet
+    { entries       int                }
+    { size          int                }
+    { eql           cpHashSetEqlFunc   }
+    { trans         cpHashSetTransFunc }
+    { default_value void*              }
+    { table         cpHashSetBin**     } ;
+
+FUNCTION: void cpHashSetDestroy ( cpHashSet* set ) ;
+FUNCTION: void cpHashSetFree ( cpHashSet* set ) ;
+FUNCTION: cpHashSet* cpHashSetAlloc ( ) ;
+FUNCTION: cpHashSet* cpHashSetInit ( cpHashSet* set, int size, cpHashSetEqlFunc eqlFunc, cpHashSetTransFunc trans ) ;
+FUNCTION: cpHashSet* cpHashSetNew ( int size, cpHashSetEqlFunc eqlFunc, cpHashSetTransFunc trans ) ;
+FUNCTION: void* cpHashSetInsert ( cpHashSet* set, cpHashValue hash, void* ptr, void* data ) ;
+FUNCTION: void* cpHashSetRemove ( cpHashSet* set, cpHashValue hash, void* ptr ) ;
+FUNCTION: void* cpHashSetFind ( cpHashSet* set, cpHashValue hash, void* ptr ) ;
+FUNCTION: void cpHashSetEach ( cpHashSet* set, cpHashSetIterFunc func, void* data ) ;
+FUNCTION: void cpHashSetFilter ( cpHashSet* set, cpHashSetFilterFunc func, void* data ) ;
+
+! cpSpaceHash.h
+STRUCT: cpHandle
+    { obj    void* }
+    { retain int   }
+    { stamp  int   } ;
+
+STRUCT: cpSpaceHashBin
+    { handle cpHandle*       }
+    { next   cpSpaceHashBin* } ;
+
+CALLBACK: cpBB cpSpaceHashBBFunc ( void* obj ) ;
+
+STRUCT: cpSpaceHash
+    { numcells  int               }
+    { celldim   cpFloat           }
+    { bbfunc    cpSpaceHashBBFunc }
+    { handleSet cpHashSet*        }
+    { table     cpSpaceHashBin**  }
+    { bins      cpSpaceHashBin*   }
+    { stamp     int               } ;
+
+FUNCTION: cpSpaceHash* cpSpaceHashAlloc ( ) ;
+FUNCTION: cpSpaceHash* cpSpaceHashInit ( cpSpaceHash* hash, cpFloat celldim, int cells, cpSpaceHashBBFunc bbfunc ) ;
+FUNCTION: cpSpaceHash* cpSpaceHashNew ( cpFloat celldim, int cells, cpSpaceHashBBFunc bbfunc ) ;
+FUNCTION: void cpSpaceHashDestroy ( cpSpaceHash* hash ) ;
+FUNCTION: void cpSpaceHashFree ( cpSpaceHash* hash ) ;
+FUNCTION: void cpSpaceHashResize ( cpSpaceHash* hash, cpFloat celldim, int numcells ) ;
+FUNCTION: void cpSpaceHashInsert ( cpSpaceHash* hash, void* obj, cpHashValue id, cpBB bb ) ;
+FUNCTION: void cpSpaceHashRemove ( cpSpaceHash* hash, void* obj, cpHashValue id ) ;
+CALLBACK: void cpSpaceHashIterator ( void* obj, void* data ) ;
+FUNCTION: void cpSpaceHashEach ( cpSpaceHash* hash, cpSpaceHashIterator func, void* data ) ;
+FUNCTION: void cpSpaceHashRehash ( cpSpaceHash* hash ) ;
+FUNCTION: void cpSpaceHashRehashObject ( cpSpaceHash* hash, void* obj, cpHashValue id ) ;
+CALLBACK: void cpSpaceHashQueryFunc ( void* obj1, void* obj2, void* data ) ;
+FUNCTION: void cpSpaceHashPointQuery ( cpSpaceHash* hash, cpVect point, cpSpaceHashQueryFunc func, void* data ) ;
+FUNCTION: void cpSpaceHashQuery ( cpSpaceHash* hash, void* obj, cpBB bb, cpSpaceHashQueryFunc func, void* data ) ;
+FUNCTION: void cpSpaceHashQueryRehash ( cpSpaceHash* hash, cpSpaceHashQueryFunc func, void* data ) ;
+CALLBACK: cpFloat cpSpaceHashSegmentQueryFunc ( void* obj1, void* obj2, void* data ) ;
+FUNCTION: void cpSpaceHashSegmentQuery ( cpSpaceHash* hash, void* obj, cpVect a, cpVect b, cpFloat t_exit, cpSpaceHashSegmentQueryFunc func, void* data ) ;
+
+! cpShape.h
+C-TYPE: cpShape
+C-TYPE: cpShapeClass
+
+STRUCT: cpSegmentQueryInfo
+    { shape cpShape* }
+    { t     cpFloat  }
+    { n     cpVect   } ;
+
+C-ENUM:
+    CP_CIRCLE_SHAPE
+    CP_SEGMENT_SHAPE
+    CP_POLY_SHAPE
+    CP_NUM_SHAPES ;
+TYPEDEF: int cpShapeType
+
+CALLBACK: cpBB cacheData_cb ( cpShape* shape, cpVect p, cpVect rot ) ;
+CALLBACK: void destroy_cb ( cpShape* shape ) ;
+CALLBACK: int pointQuery_cb ( cpShape* shape, cpVect p ) ;
+CALLBACK: void segmentQuery_cb ( cpShape* shape, cpVect a, cpVect b, cpSegmentQueryInfo* info ) ;
+
+STRUCT: cpShapeClass
+    { type         cpShapeType     }
+    { cacheData    cacheData_cb    }
+    { destroy      destroy_cb      }
+    { pointQuery   pointQuery_cb   }
+    { segmentQuery segmentQuery_cb } ;
+
+STRUCT: cpShape
+    { klass          cpShapeClass*   }
+    { body           cpBody*         }
+    { bb             cpBB            }
+    { sensor         int             }
+    { e              cpFloat         }
+    { u              cpFloat         }
+    { surface_v      cpVect          }
+    { data           cpDataPointer   }
+    { collision_type cpCollisionType }
+    { group          cpGroup         }
+    { layers         cpLayers        }
+    { hashid         cpHashValue     } ;
+
+FUNCTION: cpShape* cpShapeInit ( cpShape* shape, cpShapeClass* klass, cpBody* body ) ;
+FUNCTION: void cpShapeDestroy ( cpShape* shape ) ;
+FUNCTION: void cpShapeFree ( cpShape* shape ) ;
+FUNCTION: cpBB cpShapeCacheBB ( cpShape* shape ) ;
+FUNCTION: int cpShapePointQuery ( cpShape* shape, cpVect p ) ;
+
+STRUCT: cpCircleShape
+    { shape cpShape }
+    { c     cpVect  }
+    { r     cpFloat }
+    { tc    cpVect  } ;
+
+FUNCTION: cpCircleShape* cpCircleShapeAlloc ( ) ;
+FUNCTION: cpCircleShape* cpCircleShapeInit ( cpCircleShape* circle, cpBody* body, cpFloat radius, cpVect offset ) ;
+FUNCTION: cpShape* cpCircleShapeNew ( cpBody* body, cpFloat radius, cpVect offset ) ;
+
+STRUCT: cpSegmentShape
+    { shape cpShape }
+    { a     cpVect  }
+    { b     cpVect  }
+    { n     cpVect  }
+    { r     cpFloat }
+    { ta    cpVect  }
+    { tb    cpVect  }
+    { tn    cpVect  } ;
+
+FUNCTION: cpSegmentShape* cpSegmentShapeAlloc ( ) ;
+FUNCTION: cpSegmentShape* cpSegmentShapeInit ( cpSegmentShape* seg, cpBody* body, cpVect a, cpVect b, cpFloat radius ) ;
+FUNCTION: cpShape* cpSegmentShapeNew ( cpBody* body, cpVect a, cpVect b, cpFloat radius ) ;
+FUNCTION: void cpResetShapeIdCounter ( ) ;
+FUNCTION: void cpSegmentQueryInfoPrint ( cpSegmentQueryInfo* info ) ;
+FUNCTION: int cpShapeSegmentQuery ( cpShape* shape, cpVect a, cpVect b, cpSegmentQueryInfo* info ) ;
+
+TYPED: cpSegmentQueryHitPoint ( start: cpVect end: cpVect info: cpSegmentQueryInfo -- hit-point: cpVect )
+    t>> cpvlerp ; inline
+
+TYPED: cpSegmentQueryHitDist ( start: cpVect end: cpVect info: cpSegmentQueryInfo -- hit-dist )
+    t>> [ cpvdist ] dip * ; inline
+
+! cpPolyShape.h
+STRUCT: cpPolyShapeAxis
+    { n cpVect  }
+    { d cpFloat } ;
+SPECIALIZED-ARRAY: cpPolyShapeAxis
+
+STRUCT: cpPolyShape
+    { shape    cpShape          }
+    { numVerts int              }
+    { verts    cpVect*          }
+    { axes     cpPolyShapeAxis* }
+    { tVerts   cpVect*          }
+    { tAxes    cpPolyShapeAxis* } ;
+
+FUNCTION: cpPolyShape* cpPolyShapeAlloc ( ) ;
+FUNCTION: cpPolyShape* cpPolyShapeInit ( cpPolyShape* poly, cpBody* body, int numVerts, cpVect* verts, cpVect offset ) ;
+FUNCTION: cpShape* cpPolyShapeNew ( cpBody* body, int numVerts, cpVect* verts, cpVect offset ) ;
+FUNCTION: int cpPolyValidate ( cpVect* verts, int numVerts ) ;
+FUNCTION: int cpPolyShapeGetNumVerts ( cpShape* shape ) ;
+FUNCTION: cpVect cpPolyShapeGetVert ( cpShape* shape, int idx ) ;
+
+TYPED: cpPolyShapeValueOnAxis ( poly: cpPolyShape n: cpVect d -- min-dist )
+    swap rot [ numVerts>> ] [ tVerts>> swap <direct-cpVect-array> ] bi swap
+    [ cpvdot ] curry [ min ] reduce swap - ; inline
+
+TYPED: cpPolyShapeContainsVert ( poly: cpPolyShape v: cpVect -- ? )
+    swap [ numVerts>> ] [ tAxes>> swap <direct-cpPolyShapeAxis-array> ] bi swap
+    [
+        [ [ n>> ] dip cpvdot ] [ drop d>> ] 2bi -
+    ] curry [ max ] reduce 0.0 <= ; inline
+
+TYPED: cpPolyShapeContainsVertPartial ( poly: cpPolyShape v: cpVect n: cpVect -- ? )
+    rot [ numVerts>> ] [ tAxes>> swap <direct-cpPolyShapeAxis-array> ] bi -rot
+    [| axis v n |
+        axis n>> n cpvdot 0.0 < 0
+        [ 0.0 ]
+        [ axis n>> v cpvdot axis d>> - ]
+        if
+    ] 2curry [ max ] reduce 0.0 <= ; inline
+
+! cpArbiter.h
+C-TYPE: cpArbiter
+C-TYPE: cpSpace
+C-TYPE: cpCollisionHandler
+
+STRUCT: cpContact
+    { p      cpVect      }
+    { n      cpVect      }
+    { dist   cpFloat     }
+    { r1     cpVect      }
+    { r2     cpVect      }
+    { nMass  cpFloat     }
+    { tMass  cpFloat     }
+    { bounce cpFloat     }
+    { jnAcc  cpFloat     }
+    { jtAcc  cpFloat     }
+    { jBias  cpFloat     }
+    { bias   cpFloat     }
+    { hash   cpHashValue } ;
+
+FUNCTION: cpContact* cpContactInit ( cpContact* con, cpVect p, cpVect n, cpFloat dist, cpHashValue hash ) ;
+
+C-ENUM:
+    cpArbiterStateNormal
+    cpArbiterStateFirstColl
+    cpArbiterStateIgnore ;
+TYPEDEF: int cpArbiterState
+
+STRUCT: cpArbiter
+    { numContacts int                 }
+    { contacts    cpContact*          }
+    { a           cpShape*            }
+    { b           cpShape*            }
+    { e           cpFloat             }
+    { u           cpFloat             }
+    { surface_vr  cpVect              }
+    { stamp       int                 }
+    { handler     cpCollisionHandler* }
+    { swappedColl char                }
+    { state       char                } ;
+
+FUNCTION: cpArbiter* cpArbiterAlloc ( ) ;
+FUNCTION: cpArbiter* cpArbiterInit ( cpArbiter* arb, cpShape* a, cpShape* b ) ;
+FUNCTION: cpArbiter* cpArbiterNew ( cpShape* a, cpShape* b ) ;
+FUNCTION: void cpArbiterDestroy ( cpArbiter* arb ) ;
+FUNCTION: void cpArbiterFree ( cpArbiter* arb ) ;
+FUNCTION: void cpArbiterUpdate ( cpArbiter* arb, cpContact* contacts, int numContacts, cpCollisionHandler* handler, cpShape* a, cpShape* b ) ;
+FUNCTION: void cpArbiterPreStep ( cpArbiter* arb, cpFloat dt_inv ) ;
+FUNCTION: void cpArbiterApplyCachedImpulse ( cpArbiter* arb ) ;
+FUNCTION: void cpArbiterApplyImpulse ( cpArbiter* arb, cpFloat eCoef ) ;
+FUNCTION: cpVect cpArbiterTotalImpulse ( cpArbiter* arb ) ;
+FUNCTION: cpVect cpArbiterTotalImpulseWithFriction ( cpArbiter* arb ) ;
+FUNCTION: void cpArbiterIgnore ( cpArbiter* arb ) ;
+
+TYPED: cpArbiterGetShapes ( arb: cpArbiter -- a: cpShape b: cpShape )
+    dup swappedColl>> 0 = [
+        [ a>> ] [ b>> ] bi
+    ] [
+        [ b>> ] [ a>> ] bi
+    ] if ; inline
+
+TYPED: cpArbiterIsFirstContact ( arb: cpArbiter -- ? )
+    state>> cpArbiterStateFirstColl = ; inline
+
+TYPED: cpArbiterGetNormal ( arb: cpArbiter i -- n: cpVect )
+    [
+        swap
+        [ numContacts>> ]
+        [ contacts>> swap <direct-void*-array> ] bi nth cpContact memory>struct n>>
+    ]
+    [
+        drop swappedColl>> 0 = [ ] [ cpvneg ] if
+    ] 2bi ; inline
+
+TYPED: cpArbiterGetPoint ( arb: cpArbiter i -- p: cpVect )
+    swap
+    [ numContacts>> ]
+    [ contacts>> swap <direct-void*-array> ] bi
+    nth cpContact memory>struct p>> ; inline
+
+! cpCollision.h
+FUNCTION: int cpCollideShapes ( cpShape* a, cpShape* b, cpContact** arr ) ;
+
+! cpConstraint.h
+
+C-TYPE: cpConstraintClass
+C-TYPE: cpConstraint
+
+CALLBACK: void cpConstraintPreStepFunction ( cpConstraint* constraint, cpFloat dt, cpFloat dt_inv ) ;
+CALLBACK: void cpConstraintApplyImpulseFunction ( cpConstraint* constraint ) ;
+CALLBACK: cpFloat cpConstraintGetImpulseFunction ( cpConstraint* constraint ) ;
+
+STRUCT: cpConstraintClass
+    { preStep      cpConstraintPreStepFunction      }
+    { applyImpulse cpConstraintApplyImpulseFunction }
+    { getImpulse   cpConstraintGetImpulseFunction   } ;
+
+STRUCT: cpConstraint
+    { klass    cpConstraintClass* }
+    { a        cpBody*            }
+    { b        cpBody*            }
+    { maxForce cpFloat            }
+    { biasCoef cpFloat            }
+    { maxBias  cpFloat            }
+    { data     cpDataPointer      } ;
+
+FUNCTION: void cpConstraintDestroy ( cpConstraint* constraint ) ;
+FUNCTION: void cpConstraintFree ( cpConstraint* constraint ) ;
+FUNCTION: void cpConstraintCheckCast ( cpConstraint* constraint, cpConstraintClass* klass ) ;
+
+! cpPinJoint.h
+FUNCTION: cpConstraintClass* cpPinJointGetClass ( ) ;
+
+STRUCT: cpPinJoint
+    { constraint cpConstraint }
+    { anchr1     cpVect       }
+    { anchr2     cpVect       }
+    { dist       cpFloat      }
+    { r1         cpVect       }
+    { r2         cpVect       }
+    { n          cpVect       }
+    { nMass      cpFloat      }
+    { jnAcc      cpFloat      }
+    { jnMax      cpFloat      }
+    { bias       cpFloat      } ;
+
+FUNCTION: cpPinJoint* cpPinJointAlloc ( ) ;
+FUNCTION: cpPinJoint* cpPinJointInit ( cpPinJoint* joint, cpBody* a, cpBody* b, cpVect anchr1, cpVect anchr2 ) ;
+FUNCTION: cpConstraint* cpPinJointNew ( cpBody* a, cpBody* b, cpVect anchr1, cpVect anchr2 ) ;
+
+! cpSlideJoint.h
+FUNCTION: cpConstraintClass* cpSlideJointGetClass ( ) ;
+
+STRUCT: cpSlideJoint
+    { constraint cpConstraint }
+    { anchr1     cpVect       }
+    { anchr2     cpVect       }
+    { min        cpFloat      }
+    { max        cpFloat      }
+    { r1         cpVect       }
+    { r2         cpVect       }
+    { n          cpVect       }
+    { nMass      cpFloat      }
+    { jnAcc      cpFloat      }
+    { jnMax      cpFloat      }
+    { bias       cpFloat      } ;
+
+FUNCTION: cpSlideJoint* cpSlideJointAlloc ( ) ;
+FUNCTION: cpSlideJoint* cpSlideJointInit ( cpSlideJoint* joint, cpBody* a, cpBody* b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max ) ;
+FUNCTION: cpConstraint* cpSlideJointNew ( cpBody* a, cpBody* b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max ) ;
+
+! cpPivotJoint.h
+FUNCTION: cpConstraintClass* cpPivotJointGetClass ( ) ;
+
+STRUCT: cpPivotJoint
+    { constraint cpConstraint }
+    { anchr1     cpVect       }
+    { anchr2     cpVect       }
+    { r1         cpVect       }
+    { r2         cpVect       }
+    { k1         cpVect       }
+    { k2         cpVect       }
+    { jAcc       cpVect       }
+    { jMaxLen    cpFloat      }
+    { bias       cpVect       } ;
+
+FUNCTION: cpPivotJoint* cpPivotJointAlloc ( ) ;
+FUNCTION: cpPivotJoint* cpPivotJointInit ( cpPivotJoint* joint, cpBody* a, cpBody* b, cpVect anchr1, cpVect anchr2 ) ;
+FUNCTION: cpConstraint* cpPivotJointNew ( cpBody* a, cpBody* b, cpVect pivot ) ;
+FUNCTION: cpConstraint* cpPivotJointNew2 ( cpBody* a, cpBody* b, cpVect anchr1, cpVect anchr2 ) ;
+
+! cpGrooveJoint.h
+FUNCTION: cpConstraintClass* cpGrooveJointGetClass ( ) ;
+
+STRUCT: cpGrooveJoint
+    { constraint   cpConstraint   }
+    { grv_n        cpVect         }
+    { grv_a        cpVect         }
+    { grv_b        cpVect         }
+    { anchr2       cpVect         }
+    { grv_tn       cpVect         }
+    { clamp        cpFloat        }
+    { r1           cpVect         }
+    { r2           cpVect         }
+    { k1           cpVect         }
+    { k2           cpVect         }
+    { jAcc         cpVect         }
+    { jMaxLen      cpFloat        }
+    { bias         cpVect         } ;
+
+FUNCTION: cpGrooveJoint* cpGrooveJointAlloc ( ) ;
+FUNCTION: cpGrooveJoint* cpGrooveJointInit ( cpGrooveJoint* joint, cpBody* a, cpBody* b, cpVect groove_a, cpVect groove_b, cpVect anchr2 ) ;
+FUNCTION: cpConstraint* cpGrooveJointNew ( cpBody* a, cpBody* b, cpVect groove_a, cpVect groove_b, cpVect anchr2 ) ;
+
+! cpDampedSpring.h
+CALLBACK: cpFloat cpDampedSpringForceFunc ( cpConstraint* spring, cpFloat dist ) ;
+FUNCTION: cpConstraintClass* cpDampedSpringGetClass ( ) ;
+
+STRUCT: cpDampedSpring
+    { constraint      cpConstraint            }
+    { anchr1          cpVect                  }
+    { anchr2          cpVect                  }
+    { restLength      cpFloat                 }
+    { stiffness       cpFloat                 }
+    { damping         cpFloat                 }
+    { springForceFunc cpDampedSpringForceFunc }
+    { dt              cpFloat                 }
+    { target_vrn      cpFloat                 }
+    { r1              cpVect                  }
+    { r2              cpVect                  }
+    { nMass           cpFloat                 }
+    { n               cpVect                  } ;
+
+FUNCTION: cpDampedSpring* cpDampedSpringAlloc ( ) ;
+FUNCTION: cpDampedSpring* cpDampedSpringInit ( cpDampedSpring* joint, cpBody* a, cpBody* b, cpVect anchr1, cpVect anchr2, cpFloat restLength, cpFloat stiffness, cpFloat damping ) ;
+FUNCTION: cpConstraint* cpDampedSpringNew ( cpBody* a, cpBody* b, cpVect anchr1, cpVect anchr2, cpFloat restLength, cpFloat stiffness, cpFloat damping ) ;
+
+! cpDampedRotarySpring.h
+CALLBACK: cpFloat cpDampedRotarySpringTorqueFunc ( cpConstraint* spring, cpFloat relativeAngle ) ;
+FUNCTION: cpConstraintClass* cpDampedRotarySpringGetClass ( ) ;
+
+STRUCT: cpDampedRotarySpring
+    { constraint       cpConstraint                   }
+    { restAngle        cpFloat                        }
+    { stiffness        cpFloat                        }
+    { damping          cpFloat                        }
+    { springTorqueFunc cpDampedRotarySpringTorqueFunc }
+    { dt               cpFloat                        }
+    { target_wrn       cpFloat                        }
+    { iSum             cpFloat                        } ;
+
+FUNCTION: cpDampedRotarySpring* cpDampedRotarySpringAlloc ( ) ;
+FUNCTION: cpDampedRotarySpring* cpDampedRotarySpringInit ( cpDampedRotarySpring* joint, cpBody* a, cpBody* b, cpFloat restAngle, cpFloat stiffness, cpFloat damping ) ;
+FUNCTION: cpConstraint* cpDampedRotarySpringNew ( cpBody* a, cpBody* b, cpFloat restAngle, cpFloat stiffness, cpFloat damping ) ;
+
+! cpRotaryLimitJoint.h
+FUNCTION: cpConstraintClass* cpRotaryLimitJointGetClass ( ) ;
+
+STRUCT: cpRotaryLimitJoint
+    { constraint cpConstraint   }
+    { min        cpFloat        }
+    { max        cpFloat        }
+    { iSum       cpFloat        }
+    { bias       cpFloat        }
+    { jAcc       cpFloat        }
+    { jMax       cpFloat        } ;
+
+FUNCTION: cpRotaryLimitJoint* cpRotaryLimitJointAlloc ( ) ;
+FUNCTION: cpRotaryLimitJoint* cpRotaryLimitJointInit ( cpRotaryLimitJoint* joint, cpBody* a, cpBody* b, cpFloat min, cpFloat max ) ;
+FUNCTION: cpConstraint* cpRotaryLimitJointNew ( cpBody* a, cpBody* b, cpFloat min, cpFloat max ) ;
+
+! cpRatchetJoint.h
+FUNCTION: cpConstraintClass* cpRatchetJointGetClass ( ) ;
+
+STRUCT: cpRatchetJoint
+    { constraint cpConstraint }
+    { angle      cpFloat      }
+    { phase      cpFloat      }
+    { ratchet    cpFloat      }
+    { iSum       cpFloat      }
+    { bias       cpFloat      }
+    { jAcc       cpFloat      }
+    { jMax       cpFloat      } ;
+
+FUNCTION: cpRatchetJoint* cpRatchetJointAlloc ( ) ;
+FUNCTION: cpRatchetJoint* cpRatchetJointInit ( cpRatchetJoint* joint, cpBody* a, cpBody* b, cpFloat phase, cpFloat ratchet ) ;
+FUNCTION: cpConstraint* cpRatchetJointNew ( cpBody* a, cpBody* b, cpFloat phase, cpFloat ratchet ) ;
+
+! cpGearJoint.h
+FUNCTION: cpConstraintClass* cpGearJointGetClass ( ) ;
+
+STRUCT: cpGearJoint
+    { constraint cpConstraint }
+    { phase      cpFloat      }
+    { ratio      cpFloat      }
+    { ratio_inv  cpFloat      }
+    { iSum       cpFloat      }
+    { bias       cpFloat      }
+    { jAcc       cpFloat      }
+    { jMax       cpFloat      } ;
+
+FUNCTION: cpGearJoint* cpGearJointAlloc ( ) ;
+FUNCTION: cpGearJoint* cpGearJointInit ( cpGearJoint* joint, cpBody* a, cpBody* b, cpFloat phase, cpFloat ratio ) ;
+FUNCTION: cpConstraint* cpGearJointNew ( cpBody* a, cpBody* b, cpFloat phase, cpFloat ratio ) ;
+FUNCTION: void cpGearJointSetRatio ( cpConstraint* constraint, cpFloat value ) ;
+
+! cpSimpleMotor.h
+FUNCTION: cpConstraintClass* cpSimpleMotorGetClass ( ) ;
+
+STRUCT: cpSimpleMotor
+    { constraint cpConstraint }
+    { rate       cpFloat      }
+    { iSum       cpFloat      }
+    { jAcc       cpFloat      }
+    { jMax       cpFloat      } ;
+
+FUNCTION: cpSimpleMotor* cpSimpleMotorAlloc ( ) ;
+FUNCTION: cpSimpleMotor* cpSimpleMotorInit ( cpSimpleMotor* joint, cpBody* a, cpBody* b, cpFloat rate ) ;
+FUNCTION: cpConstraint* cpSimpleMotorNew ( cpBody* a, cpBody* b, cpFloat rate ) ;
+
+! cpSpace.h
+C-TYPE: cpSpace
+
+CALLBACK: int cpCollisionBeginFunc ( cpArbiter* arb, cpSpace* space, void* data ) ;
+CALLBACK: int cpCollisionPreSolveFunc ( cpArbiter* arb, cpSpace* space, void* data ) ;
+CALLBACK: void cpCollisionPostSolveFunc ( cpArbiter* arb, cpSpace* space, void* data ) ;
+CALLBACK: void cpCollisionSeparateFunc ( cpArbiter* arb, cpSpace* space, void* data ) ;
+
+STRUCT: cpCollisionHandler
+    { a         cpCollisionType          }
+    { b         cpCollisionType          }
+    { begin     cpCollisionBeginFunc     }
+    { preSolve  cpCollisionPreSolveFunc  }
+    { postSolve cpCollisionPostSolveFunc }
+    { separate  cpCollisionSeparateFunc  }
+    { data      void*                    } ;
+
+STRUCT: cpSpace
+    { iterations        int                }
+    { elasticIterations int                }
+    { gravity           cpVect             }
+    { damping           cpFloat            }
+    { stamp             int                }
+    { staticShapes      cpSpaceHash*       }
+    { activeShapes      cpSpaceHash*       }
+    { bodies            cpArray*           }
+    { arbiters          cpArray*           }
+    { contactSet        cpHashSet*         }
+    { constraints       cpArray*           }
+    { collFuncSet       cpHashSet*         }
+    { defaultHandler    cpCollisionHandler }
+    { postStepCallbacks cpHashSet*         } ;
+
+FUNCTION: cpSpace* cpSpaceAlloc ( ) ;
+FUNCTION: cpSpace* cpSpaceInit ( cpSpace* space ) ;
+FUNCTION: cpSpace* cpSpaceNew ( ) ;
+FUNCTION: void cpSpaceDestroy ( cpSpace* space ) ;
+FUNCTION: void cpSpaceFree ( cpSpace* space ) ;
+FUNCTION: void cpSpaceFreeChildren ( cpSpace* space ) ;
+FUNCTION: void cpSpaceSetDefaultCollisionHandler (
+    cpSpace*                 space,
+    cpCollisionBeginFunc     begin,
+    cpCollisionPreSolveFunc  preSolve,
+    cpCollisionPostSolveFunc postSolve,
+    cpCollisionSeparateFunc  separate,
+    void*                    data ) ;
+FUNCTION: void cpSpaceAddCollisionHandler (
+    cpSpace*                 space,
+    cpCollisionType          a,
+    cpCollisionType          b,
+    cpCollisionBeginFunc     begin,
+    cpCollisionPreSolveFunc  preSolve,
+    cpCollisionPostSolveFunc postSolve,
+    cpCollisionSeparateFunc  separate,
+    void*                    data ) ;
+FUNCTION: void cpSpaceRemoveCollisionHandler ( cpSpace* space, cpCollisionType a, cpCollisionType b ) ;
+FUNCTION: cpShape* cpSpaceAddShape ( cpSpace* space, cpShape* shape ) ;
+FUNCTION: cpShape* cpSpaceAddStaticShape ( cpSpace* space, cpShape* shape ) ;
+FUNCTION: cpBody* cpSpaceAddBody ( cpSpace* space, cpBody* body ) ;
+FUNCTION: cpConstraint* cpSpaceAddConstraint ( cpSpace* space, cpConstraint* constraint ) ;
+FUNCTION: void cpSpaceRemoveShape ( cpSpace* space, cpShape* shape ) ;
+FUNCTION: void cpSpaceRemoveStaticShape ( cpSpace* space, cpShape* shape ) ;
+FUNCTION: void cpSpaceRemoveBody ( cpSpace* space, cpBody* body ) ;
+FUNCTION: void cpSpaceRemoveConstraint ( cpSpace* space, cpConstraint* constraint ) ;
+CALLBACK: void cpPostStepFunc ( cpSpace* space, void* obj, void* data ) ;
+FUNCTION: void cpSpaceAddPostStepCallback ( cpSpace* space, cpPostStepFunc func, void* obj, void* data ) ;
+CALLBACK: void cpSpacePointQueryFunc ( cpShape* shape, void* data ) ;
+FUNCTION: void cpSpacePointQuery ( cpSpace* space, cpVect point, cpLayers layers, cpGroup group, cpSpacePointQueryFunc func, void* data ) ;
+FUNCTION: cpShape* cpSpacePointQueryFirst ( cpSpace* space, cpVect point, cpLayers layers, cpGroup group ) ;
+CALLBACK: void cpSpaceSegmentQueryFunc ( cpShape* shape, cpFloat t, cpVect n, void* data ) ;
+FUNCTION: int cpSpaceSegmentQuery ( cpSpace* space, cpVect start, cpVect end, cpLayers layers, cpGroup group, cpSpaceSegmentQueryFunc func, void* data ) ;
+FUNCTION: cpShape* cpSpaceSegmentQueryFirst ( cpSpace* space, cpVect start, cpVect end, cpLayers layers, cpGroup group, cpSegmentQueryInfo* out ) ;
+CALLBACK: void cpSpaceBBQueryFunc ( cpShape* shape, void* data ) ;
+FUNCTION: void cpSpaceBBQuery ( cpSpace* space, cpBB bb, cpLayers layers, cpGroup group, cpSpaceBBQueryFunc func, void* data ) ;
+CALLBACK: void cpSpaceBodyIterator ( cpBody* body, void* data ) ;
+FUNCTION: void cpSpaceEachBody ( cpSpace* space, cpSpaceBodyIterator func, void* data ) ;
+FUNCTION: void cpSpaceResizeStaticHash ( cpSpace* space, cpFloat dim, int count ) ;
+FUNCTION: void cpSpaceResizeActiveHash ( cpSpace* space, cpFloat dim, int count ) ;
+FUNCTION: void cpSpaceRehashStatic ( cpSpace* space ) ;
+FUNCTION: void cpSpaceStep ( cpSpace* space, cpFloat dt ) ;
+
+! chipmunk.h
+FUNCTION: void cpInitChipmunk ( ) ;
+FUNCTION: cpFloat cpMomentForCircle ( cpFloat m, cpFloat r1, cpFloat r2, cpVect offset ) ;
+FUNCTION: cpFloat cpMomentForSegment ( cpFloat m, cpVect a, cpVect b ) ;
+FUNCTION: cpFloat cpMomentForPoly ( cpFloat m, int numVerts, cpVect* verts, cpVect offset ) ;
+