#define _GNU_SOURCE #include #include #include #include #include #include #include /** * Allocate a new object of the given type. * * This function uses information from registered object types only. * * @param type a type registed in object_table. * * @return a new object. It's casted down to object_t. */ object_t * object_new( uint16_t type ) { object_t *obj = NULL; if ( type == OBJECT_TYPE_UNDEFINED ) err( "Cannot create an undefined object!\n" ); else { struct object_table_entry *e = get_object_table_entry( type ); if ( e != NULL ) { if ( e->ops.new != NULL ) { obj = e->ops.new(); if ( obj != NULL ) assert( obj->type == type ); } else err( "Object is known, but unable to create one!\n" ); } else err( "Object type %d is unknown\n", type ); } return obj; } /** * Free memory allocated to object. * * @param object an allocated object. */ void __object_free( object_t *object ) { assert( object != NULL ); if ( object->type == OBJECT_TYPE_UNDEFINED ) err( "Cannot free an undefined object! (This is a bug somewhere!)\n" ); else { struct object_table_entry *e = get_object_table_entry( object->type ); if ( e != NULL ) { if ( e->ops.free != NULL ) e->ops.free( object ); else err( "Object is known, but unable to free it!\n" ); } else err( "Object type %d is unknown\n", object->type ); } } /** * Initialize object. * * @param object object to act on. * @param color object color. * @param transp transparency value, between 0.0 and 1.0 * @param depth object depth in scene. * @param draw_opts OR'ed flags from DRAW_*, like DRAW_ANTIALIAS, DRAW_FILL. */ void __object_init( object_t *object, color_t color, float transp, uint16_t depth, uint8_t draw_opts ) { assert( object != NULL ); object->color = color; object->transp = transp; object->depth = depth; object->draw_opts = draw_opts; } /** * Return the string representation of this object. * * @note string is malloc()ated, please free() it later. * * @param obj the object to act on. * * @return string representation. */ char * __object_str( object_t *object ) { char *s = NULL; int r = 0; if ( object == NULL ) r = asprintf( &s, "Object is NULL!" ); else { struct object_table_entry *t = get_object_table_entry( object->type ); if ( t == NULL || t->ops.str == NULL ) r = asprintf( &s, "Object( type=%d, depth=%d, color=0x%08x, " "transp=%0.3f )", object->type, object->depth, COLOR_TO_ARGB( object->color ), object->transp ); else s = t->ops.str( object ); } if ( r < 0 ) s = NULL; return s; } /** * Draw object on surface * * @param object an allocated object. * @param surface an existing surface. */ void __object_draw( object_t *object, surface_t *surface ) { assert( object != NULL ); if ( object->type == OBJECT_TYPE_UNDEFINED ) err( "Cannot draw an undefined object! (This is a bug somewhere!)\n" ); else { struct object_table_entry *e = get_object_table_entry( object->type ); if ( e != NULL ) { if ( e->ops.draw != NULL ) e->ops.draw( object, surface ); else err( "Object is known, but unable to draw it!\n" ); } else err( "Object type %d is unknown\n", object->type ); } }