#include #include #include #include #include #include #include #include #include #include #include #include #include static akerr_ErrorContext *akgl_sprite_load_json_spritesheet(json_t *json, akgl_SpriteSheet **sheet, char *relative_path) { PREPARE_ERROR(errctx); json_t *spritesheet_json = NULL; int ss_frame_width = 0; int ss_frame_height = 0; akgl_String *ss_filename = NULL; akgl_String *tmpstr = NULL; ATTEMPT { CATCH(errctx, akgl_heap_next_string(&tmpstr)); CATCH(errctx, akgl_string_initialize(tmpstr, NULL)); CATCH(errctx, akgl_get_json_object_value((json_t *)json, "spritesheet", &spritesheet_json)); CATCH(errctx, akgl_get_json_string_value((json_t *)spritesheet_json, "filename", &ss_filename)); if ( ss_filename->data[0] != '/' ) { SDL_snprintf((char *)&tmpstr->data, AKGL_MAX_STRING_LENGTH, "%s/%s", relative_path, ss_filename->data); } else { SDL_snprintf((char *)&tmpstr->data, AKGL_MAX_STRING_LENGTH, "%s", ss_filename->data); } *sheet = SDL_GetPointerProperty( AKGL_AKGL_REGISTRY_SPRITESHEET, (char *)&tmpstr->data, NULL ); if ( *sheet == NULL ) { CATCH(errctx, akgl_heap_next_spritesheet(sheet)); CATCH(errctx, akgl_get_json_integer_value((json_t *)spritesheet_json, "frame_width", &ss_frame_width)); CATCH(errctx, akgl_get_json_integer_value((json_t *)spritesheet_json, "frame_height", &ss_frame_width)); CATCH(errctx, akgl_spritesheet_initialize( (akgl_SpriteSheet *)*sheet, ss_frame_width, ss_frame_height, (char *)&tmpstr->data) ); } } CLEANUP { IGNORE(akgl_heap_release_string(ss_filename)); IGNORE(akgl_heap_release_string(tmpstr)); } PROCESS(errctx) { } FINISH(errctx, true); SUCCEED_RETURN(errctx); } akerr_ErrorContext *akgl_sprite_load_json(char *filename) { PREPARE_ERROR(errctx); json_t *json = NULL; json_t *frames = NULL; json_error_t error; akgl_Sprite *obj = NULL; akgl_SpriteSheet *sheet = NULL; akgl_String *spritename = NULL; //string *tmpstr = NULL; int i = 0; FAIL_ZERO_RETURN(errctx, filename, AKERR_NULLPOINTER, "Received null filename"); ATTEMPT { CATCH(errctx, akgl_heap_next_sprite(&obj)); //CATCH(errctx, akgl_heap_next_string(&tmpstr)); //CATCH(errctx, akgl_string_initialize(tmpstr, NULL)); CATCH(errctx, akgl_heap_next_string(&spritename)); CATCH(errctx, akgl_string_initialize(spritename, NULL)); //SDL_snprintf((char *)&tmpstr->data, AKGL_MAX_STRING_LENGTH, "%s%s", SDL_GetBasePath(), filename); json = (json_t *)json_load_file(filename, 0, &error); FAIL_ZERO_BREAK( errctx, json, AKERR_NULLPOINTER, "Error while loading sprite from %s on line %d: %s", filename, error.line, error.text ); CATCH(errctx, akgl_sprite_load_json_spritesheet((json_t *)json, &sheet, dirname(filename))); CATCH(errctx, akgl_get_json_string_value((json_t *)json, "name", &spritename)); CATCH(errctx, akgl_sprite_initialize( (akgl_Sprite *)obj, spritename->data, (akgl_SpriteSheet *)sheet) ); CATCH(errctx, akgl_get_json_integer_value((json_t *)json, "width", &obj->width)); CATCH(errctx, akgl_get_json_integer_value((json_t *)json, "height", &obj->height)); CATCH(errctx, akgl_get_json_integer_value((json_t *)json, "speed", &obj->speed)); obj->speed = obj->speed * AKGL_TIME_ONESEC_MS; CATCH(errctx, akgl_get_json_boolean_value((json_t *)json, "loop", &obj->loop)); CATCH(errctx, akgl_get_json_boolean_value((json_t *)json, "loopReverse", &obj->loopReverse)); CATCH(errctx, akgl_get_json_array_value((json_t *)json, "frames", &frames)); obj->frames = json_array_size((json_t *)frames); for ( i = 0 ; i < obj->frames; i++ ) { CATCH(errctx, akgl_get_json_array_index_integer((json_t *)frames, i, (uint32_t *)&obj->frameids[i])); } } CLEANUP { if ( errctx != NULL && errctx->status != 0 ) { IGNORE(akgl_heap_release_sprite(obj)); IGNORE(akgl_heap_release_spritesheet(sheet)); } IGNORE(akgl_heap_release_string(spritename)); //IGNORE(akgl_heap_release_string(tmpstr)); } PROCESS(errctx) { } FINISH(errctx, true); SUCCEED_RETURN(errctx); } akerr_ErrorContext *akgl_sprite_initialize(akgl_Sprite *spr, char *name, akgl_SpriteSheet *sheet) { PREPARE_ERROR(errctx); FAIL_ZERO_RETURN(errctx, spr, AKERR_NULLPOINTER, "Null sprite reference"); FAIL_ZERO_RETURN(errctx, name, AKERR_NULLPOINTER, "Empty sprite name"); FAIL_ZERO_RETURN(errctx, sheet, AKERR_NULLPOINTER, "Null spritesheet reference"); memset(spr, 0x00, sizeof(akgl_Sprite)); memcpy(spr->name, name, AKGL_SPRITE_MAX_NAME_LENGTH); spr->sheet = sheet; FAIL_ZERO_RETURN( errctx, SDL_SetPointerProperty(AKGL_REGISTRY_SPRITE, (char *)&spr->name, (void *)spr), AKERR_KEY, "Unable to add sprite to registry"); spr->refcount += 1; SUCCEED_RETURN(errctx); } akerr_ErrorContext *akgl_spritesheet_initialize(akgl_SpriteSheet *sheet, int sprite_w, int sprite_h, char *filename) { PREPARE_ERROR(errctx); //akgl_String *tmpstr = NULL; ATTEMPT { FAIL_ZERO_BREAK(errctx, sheet, AKERR_NULLPOINTER, "Null spritesheet pointer"); FAIL_ZERO_BREAK(errctx, filename, AKERR_NULLPOINTER, "Null filename pointer"); memset(sheet, 0x00, sizeof(akgl_SpriteSheet)); //CATCH(errctx, akgl_heap_next_string(&tmpstr)); //CATCH(errctx, akgl_string_initialize(tmpstr, NULL)); strncpy((char *)&sheet->name, filename, AKGL_SPRITE_SHEET_MAX_FILENAME_LENGTH); //snprintf((char *)&tmpstr->data, AKGL_MAX_STRING_LENGTH, "%s%s", SDL_GetBasePath(), filename); sheet->texture = IMG_LoadTexture(renderer, filename); FAIL_ZERO_BREAK(errctx, sheet->texture, AKGL_ERR_SDL, "Failed loading asset %s : %s", filename, SDL_GetError()); FAIL_ZERO_BREAK( errctx, SDL_SetPointerProperty(AKGL_AKGL_REGISTRY_SPRITESHEET, (char *)sheet->name, (void *)sheet), AKERR_KEY, "Unable to add spritesheet to registry: %s", SDL_GetError()); sheet->refcount += 1; } CLEANUP { //IGNORE(akgl_heap_release_string(tmpstr)); } PROCESS(errctx) { } FINISH(errctx, true); SUCCEED_RETURN(errctx); }