diff options
author | Araq <rumpf_a@web.de> | 2013-04-13 21:55:02 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2013-04-13 21:55:02 +0200 |
commit | 75b508032b9da285f30d4ec7f2af4c63075b8611 (patch) | |
tree | 79476c0e8b7c70ee373bde21a2ea0a62d84520f8 /tests/manyloc/keineschweine/dependencies | |
parent | 4f09794be9fb9b96728078712f01e990e0021929 (diff) | |
download | Nim-75b508032b9da285f30d4ec7f2af4c63075b8611.tar.gz |
added manyloc test suite; --path now relative to project dir if not absolute
Diffstat (limited to 'tests/manyloc/keineschweine/dependencies')
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.} |