World_t *world_create(void) { World_t *out = obj_create_autoreleased(&Class_World); out->cpSpace = cpSpaceNew(); out->cpSpace->data = out; cpSpaceAddCollisionHandler(out->cpSpace, 0, 0, collisionWillBegin, NULL, collisionDidBegin, collisionDidEnd, NULL); out->entities = obj_retain(llist_create((InsertionCallback_t)&obj_retain, &obj_release)); // Create the static entity out->staticEntity = obj_create(&Class_WorldEntity); out->staticEntity->world = out; out->staticEntity->owner = out; out->staticEntity->cpBody = out->cpSpace->staticBody; out->staticEntity->luaUpdateHandler = -1; out->staticEntity->luaPreCollisionHandler = -1; out->staticEntity->luaCollisionHandler = -1; out->staticEntity->luaPostCollisionHandler = -1; out->cpSpace->staticBody->data = out->staticEntity; out->staticEntity->shapes = obj_retain(llist_create((InsertionCallback_t)&obj_retain, &obj_release)); return out; }
WorldShape_t *worldShape_createBox(vec2_t aSize) { WorldShape_t *out = obj_create_autoreleased(&Class_WorldShape); out->cpShape = cpBoxShapeNew(NULL, aSize.w, aSize.h); out->cpShape->data = out; return out; }
WorldShape_t *worldShape_createSegment(vec2_t a, vec2_t b, GLMFloat aThickness) { WorldShape_t *out = obj_create_autoreleased(&Class_WorldShape); out->cpShape = cpSegmentShapeNew(NULL, VEC2_TO_CPV(a), VEC2_TO_CPV(b), aThickness); out->cpShape->data = out; return out; }
WorldShape_t *worldShape_createCircle(vec2_t aCenter, GLMFloat aRadius) { WorldShape_t *out = obj_create_autoreleased(&Class_WorldShape); out->cpShape = cpCircleShapeNew(NULL, aRadius, VEC2_TO_CPV(aCenter)); out->cpShape->data = out; return out; }
LuaContext_t *luaCtx_createContext() { LuaContext_t *out = obj_create_autoreleased(&Class_LuaContext); if(!GlobalLuaContext) GlobalLuaContext = obj_retain(out); out->luaState = lua_open(); luaL_openlibs(out->luaState); lua_pushcfunction(out->luaState, &luaApi_dynamo_registerCallback); lua_setglobal(out->luaState, "dynamo_registerCallback"); lua_pushcfunction(out->luaState, &luaApi_dynamo_unregisterCallback); lua_setglobal(out->luaState, "dynamo_unregisterCallback"); char buf[1024]; dynamo_assert(util_pathForResource(NULL, NULL, "DynamoScripts", buf, 1024), "Couldn't find dynamo scripts"); luaCtx_addSearchPath(out, buf); dynamo_assert(util_pathForResource("glmath", "lua", "DynamoScripts", buf, 1024), "Couldn't find glmath init script"); dynamo_assert(luaCtx_executeFile(out, buf), "Error initializing GLMath"); dynamo_assert(util_pathForResource("dynamo", "lua", "DynamoScripts", buf, 1024), "Couldn't find dynamo init script"); dynamo_assert(luaCtx_executeFile(out, buf), "Error initializing dynamo"); return out; }
InputManager_t *input_createManager() { InputManager_t *out = obj_create_autoreleased(&Class_InputManager); out->observers = obj_retain(llist_create((InsertionCallback_t)&obj_retain, (RemovalCallback_t)&obj_release)); out->activeEvents = obj_retain(llist_create(NULL, NULL)); return out; }
SpriteBatch_t *spriteBatch_create(TextureAtlas_t *aAtlas) { SpriteBatch_t *out = obj_create_autoreleased(&Class_SpriteBatch); out->spriteCount = 0; out->sprites = obj_retain(llist_create((InsertionCallback_t)&obj_retain, (RemovalCallback_t)&obj_release)); out->displayCallback = (RenderableDisplayCallback_t)&_spriteBatch_draw; return out; }
LuaContext_t *luaCtx_createContext() { LuaContext_t *out = obj_create_autoreleased(&Class_LuaContext); out->luaState = lua_open(); luaL_openlibs(out->luaState); return out; }
InputObserver_t *input_createObserver(Input_type_t aObservedType, Input_handler_t aHandlerCallback, char *aCode, void *aMetaData) { InputObserver_t *out = obj_create_autoreleased(&Class_InputObserver); out->type = aObservedType; out->handlerCallback = aHandlerCallback; out->metaData = aMetaData; out->lastKnownState = kInputState_up; if(aCode) out->code = *aCode; return out; }
WorldConstraint_t *worldConstr_createSimpleMotorJoint(WorldEntity_t *a, WorldEntity_t *b, GLMFloat aRate) { dynamo_assert(a->world == b->world, "Entities are not in the same world"); WorldConstraint_t *ret = obj_create_autoreleased(&Class_WorldConstraint); ret->world = a->world; ret->a = obj_retain(a); ret->b = obj_retain(b); ret->type = kWorldJointType_SimpleMotor; ret->cpConstraint = cpSimpleMotorNew(a->cpBody, b->cpBody, aRate); cpSpaceAddConstraint(ret->world->cpSpace, ret->cpConstraint); return ret; }
WorldConstraint_t *worldConstr_createRotaryLimitJoint(WorldEntity_t *a, WorldEntity_t *b, GLMFloat aMinAngle, GLMFloat aMaxAngle) { dynamo_assert(a->world == b->world, "Entities are not in the same world"); WorldConstraint_t *ret = obj_create_autoreleased(&Class_WorldConstraint); ret->world = a->world; ret->a = obj_retain(a); ret->b = obj_retain(b); ret->type = kWorldJointType_RotaryLimit; ret->cpConstraint = cpRotaryLimitJointNew(a->cpBody, b->cpBody, aMinAngle, aMaxAngle); cpSpaceAddConstraint(ret->world->cpSpace, ret->cpConstraint); return ret; }
WorldConstraint_t *worldConstr_createPivotJoint(WorldEntity_t *a, WorldEntity_t *b, vec2_t aPivot) { dynamo_assert(a->world == b->world, "Entities are not in the same world"); WorldConstraint_t *ret = obj_create_autoreleased(&Class_WorldConstraint); ret->world = a->world; ret->a = obj_retain(a); ret->b = obj_retain(b); ret->type = kWorldJointType_Pivot; ret->cpConstraint = cpPivotJointNew(a->cpBody, b->cpBody, VEC2_TO_CPV(aPivot)); cpSpaceAddConstraint(ret->world->cpSpace, ret->cpConstraint); return ret; }
WorldConstraint_t *worldConstr_createDampedRotarySpringJoint(WorldEntity_t *a, WorldEntity_t *b, GLMFloat aRestAngle, GLMFloat aStiffness, GLMFloat aDamping) { dynamo_assert(a->world == b->world, "Entities are not in the same world"); WorldConstraint_t *ret = obj_create_autoreleased(&Class_WorldConstraint); ret->world = a->world; ret->a = obj_retain(a); ret->b = obj_retain(b); ret->type = kWorldJointType_DampedRotarySpring; ret->cpConstraint = cpDampedRotarySpringNew(a->cpBody, b->cpBody, aRestAngle, aStiffness, aDamping); cpSpaceAddConstraint(ret->world->cpSpace, ret->cpConstraint); return ret; }
WorldConstraint_t *worldConstr_createSlideJoint(WorldEntity_t *a, WorldEntity_t *b, vec2_t aAnchorA, vec2_t aAnchorB, GLMFloat aMinDist, GLMFloat aMaxDist) { dynamo_assert(a->world == b->world, "Entities are not in the same world"); WorldConstraint_t *ret = obj_create_autoreleased(&Class_WorldConstraint); ret->world = a->world; ret->a = obj_retain(a); ret->b = obj_retain(b); ret->type = kWorldJointType_Slide; ret->cpConstraint = cpSlideJointNew(a->cpBody, b->cpBody, VEC2_TO_CPV(aAnchorA), VEC2_TO_CPV(aAnchorB), aMinDist, aMaxDist); cpSpaceAddConstraint(ret->world->cpSpace, ret->cpConstraint); return ret; }
WorldConstraint_t *worldConstr_createDampedSpringJoint(WorldEntity_t *a, WorldEntity_t *b, vec2_t aAnchorA, vec2_t aAnchorB, GLMFloat aRestLength, GLMFloat aStiffness, GLMFloat aDamping) { dynamo_assert(a->world == b->world, "Entities are not in the same world"); WorldConstraint_t *ret = obj_create_autoreleased(&Class_WorldConstraint); ret->world = a->world; ret->a = obj_retain(a); ret->b = obj_retain(b); ret->type = kWorldJointType_DampedSpring; ret->cpConstraint = cpDampedSpringNew(a->cpBody, b->cpBody, VEC2_TO_CPV(aAnchorA), VEC2_TO_CPV(aAnchorB), aRestLength, aStiffness, aDamping); cpSpaceAddConstraint(ret->world->cpSpace, ret->cpConstraint); return ret; }
WorldConstraint_t *worldConstr_createGrooveJoint(WorldEntity_t *a, WorldEntity_t *b, vec2_t aGrooveStart, vec2_t aGrooveEnd, vec2_t aAnchorB) { dynamo_assert(a->world == b->world, "Entities are not in the same world"); WorldConstraint_t *ret = obj_create_autoreleased(&Class_WorldConstraint); ret->world = a->world; ret->a = obj_retain(a); ret->b = obj_retain(b); ret->type = kWorldJointType_Groove; ret->cpConstraint = cpGrooveJointNew(a->cpBody, b->cpBody, VEC2_TO_CPV(aGrooveStart), VEC2_TO_CPV(aGrooveEnd), VEC2_TO_CPV(aAnchorB)); cpSpaceAddConstraint(ret->world->cpSpace, ret->cpConstraint); return ret; }
Sprite_t *sprite_create(vec3_t aLocation, vec2_t aSize, TextureAtlas_t *aAtlas, int aAnimationCapacity) { Sprite_t *out = (Sprite_t*)obj_create_autoreleased(&Class_Sprite); out->displayCallback = (RenderableDisplayCallback_t)&_sprite_draw; out->location = aLocation; out->size = aSize; out->scale = 1.0f; out->angle = 0.0f; out->atlas = obj_retain(aAtlas); out->flippedHorizontally = false; out->flippedVertically = false; out->activeAnimation = 0; out->animations = calloc(aAnimationCapacity, sizeof(SpriteAnimation_t)); return out; }
WorldEntity_t *worldEnt_create(World_t *aWorld, Obj_t *aOwner, GLMFloat aMass, GLMFloat amoment) { WorldEntity_t *out = obj_create_autoreleased(&Class_WorldEntity); out->world = aWorld; out->owner = aOwner; out->cpBody = cpBodyNew(aMass, amoment); out->cpBody->data = out; out->shapes = obj_retain(llist_create((InsertionCallback_t)&obj_retain, &obj_release)); out->luaUpdateHandler = -1; out->luaPreCollisionHandler = -1; out->luaCollisionHandler = -1; out->luaPostCollisionHandler = -1; return out; }
Texture_t *texture_loadFromPng(const char *aPath, bool aRepeatHorizontal, bool aRepeatVertical) { Texture_t *out = obj_create_autoreleased(&Class_Texture); out->displayCallback = (RenderableDisplayCallback_t)&_texture_draw; Png_t *png = png_load(aPath); if(!png) { dynamo_log("Unable to load png file from %s", aPath); return NULL; } glGenTextures(1, &out->id); glBindTexture(GL_TEXTURE_2D, out->id); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D(GL_TEXTURE_2D, 0, png->hasAlpha ? GL_RGBA : GL_RGB, png->width, png->height, 0, png->hasAlpha ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, png->data); glError() glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aRepeatHorizontal ? GL_REPEAT : GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aRepeatVertical ? GL_REPEAT : GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Mipmaps can only be generated if the texture size is a power of 2 if(_isPowerOfTwo(png->width) && _isPowerOfTwo(png->height) && !aRepeatHorizontal && !aRepeatVertical) { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); glGenerateMipmap(GL_TEXTURE_2D); } else { dynamo_assert(!( (!_isPowerOfTwo(png->width) || !_isPowerOfTwo(png->height)) && (aRepeatHorizontal || aRepeatVertical) ), "Repeating textures must have power of 2 dimensions"); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } glError() out->size = vec2_create(png->width, png->height); out->pxAlignInset = vec2_create( (1.0f/out->size.w) * 0.5, (1.0f/out->size.h) * 0.5 ); return out; }
Shader_t *shader_load(const char *aVertSrc, const char *aFragSrc) { Shader_t *out = obj_create_autoreleased(&Class_Shader); out->activationCallback = NULL; out->deactivationCallback = NULL; for(int i = 0; i < kShader_MaxUniforms; ++i) out->uniforms[i] = -1; for(int i = 0; i < kShader_MaxAttributes; ++i) out->attributes[i] = -1; out->program = glCreateProgram(); bool success; GLuint vertexShader = _shader_compile(aVertSrc, GL_VERTEX_SHADER, &success); dynamo_assert(success, "Couldn't compile vertex shader"); GLuint fragmentShader = _shader_compile(aFragSrc, GL_FRAGMENT_SHADER, &success); dynamo_assert(success, "Couldn't compile fragment shader"); glAttachShader(out->program, vertexShader); out->vertexShader = vertexShader; glAttachShader(out->program, fragmentShader); out->fragmentShader = fragmentShader; success = _shader_link(out->program); glError() dynamo_assert(success, "Couldn't link shader program"); // Hook up the default uniforms&attributes if available out->uniforms[kShader_worldMatrixUniform] = shader_getUniformLocation(out, kShader_UniformNames[kShader_worldMatrixUniform]); out->uniforms[kShader_projectionMatrixUniform] = shader_getUniformLocation(out, kShader_UniformNames[kShader_projectionMatrixUniform]); out->uniforms[kShader_colormap0Uniform] = shader_getUniformLocation(out, kShader_UniformNames[kShader_colormap0Uniform]); out->attributes[kShader_positionAttribute] = shader_getAttributeLocation(out, kShader_AttributeNames[kShader_positionAttribute]); out->attributes[kShader_texCoord0Attribute] = shader_getAttributeLocation(out, kShader_AttributeNames[kShader_texCoord0Attribute]); return out; }
WorldShape_t *worldShape_createPoly(unsigned aVertCount, vec2_t *aVerts) { WorldShape_t *out = obj_create_autoreleased(&Class_WorldShape); out->cpShape = cpPolyShapeNew(NULL, aVertCount, (cpVect*)aVerts, cpvzero); return out; }