1198 lines
42 KiB
C
1198 lines
42 KiB
C
|
//------------------------------------------------------------------------------
|
||
|
// sokol_spine_test.c
|
||
|
//------------------------------------------------------------------------------
|
||
|
#include "sokol_gfx.h"
|
||
|
#define SOKOL_SPINE_IMPL
|
||
|
#include "spine/spine.h"
|
||
|
#include "sokol_spine.h"
|
||
|
#include "utest.h"
|
||
|
|
||
|
#define T(b) EXPECT_TRUE(b)
|
||
|
|
||
|
static sspine_log_item last_logitem = SSPINE_LOGITEM_OK;
|
||
|
static void log_func(const char* tag, uint32_t log_level, uint32_t log_item, const char* message, uint32_t line_nr, const char* filename, void* user_data) {
|
||
|
(void)tag; (void)log_level; (void)message; (void)line_nr; (void)filename; (void)user_data;
|
||
|
last_logitem = log_item;
|
||
|
}
|
||
|
|
||
|
static void init(void) {
|
||
|
last_logitem = SSPINE_LOGITEM_OK;
|
||
|
sg_setup(&(sg_desc){0});
|
||
|
sspine_setup(&(sspine_desc){ .logger = { .func = log_func } });
|
||
|
}
|
||
|
|
||
|
static void init_with_desc(const sspine_desc* desc) {
|
||
|
last_logitem = SSPINE_LOGITEM_OK;
|
||
|
sspine_desc desc1 = *desc;
|
||
|
desc1.logger.func = log_func;
|
||
|
sg_setup(&(sg_desc){0});
|
||
|
sspine_setup(&desc1);
|
||
|
}
|
||
|
|
||
|
static void shutdown(void) {
|
||
|
sspine_shutdown();
|
||
|
sg_shutdown();
|
||
|
}
|
||
|
|
||
|
// NOTE: this guarantees that the data is zero terminated because the loaded data
|
||
|
// might either be binary or text (the zero sentinel is NOT counted in the returned size)
|
||
|
static sspine_range load_data(const char* path) {
|
||
|
assert(path);
|
||
|
FILE* fp = fopen(path, "rb");
|
||
|
assert(fp);
|
||
|
fseek(fp, 0, SEEK_END);
|
||
|
const size_t size = (size_t)ftell(fp);
|
||
|
fseek(fp, 0, SEEK_SET);
|
||
|
// room for terminating zero
|
||
|
const size_t alloc_size = size + 1;
|
||
|
uint8_t* ptr = (uint8_t*)malloc(alloc_size);
|
||
|
memset(ptr, 0, alloc_size);
|
||
|
// NOTE: GCC warns if result of fread() is ignored
|
||
|
size_t num_bytes = fread(ptr, size, 1, fp);
|
||
|
(void)num_bytes;
|
||
|
fclose(fp);
|
||
|
return (sspine_range) { .ptr = ptr, .size = size };
|
||
|
}
|
||
|
|
||
|
static void free_data(sspine_range r) {
|
||
|
free((void*)r.ptr);
|
||
|
}
|
||
|
|
||
|
static sspine_atlas create_atlas(void) {
|
||
|
sspine_range atlas_data = load_data("spineboy.atlas");
|
||
|
sspine_atlas atlas = sspine_make_atlas(&(sspine_atlas_desc){
|
||
|
.data = atlas_data
|
||
|
});
|
||
|
free_data(atlas_data);
|
||
|
return atlas;
|
||
|
}
|
||
|
|
||
|
static sspine_skeleton create_skeleton_json(sspine_atlas atlas) {
|
||
|
sspine_range skeleton_json_data = load_data("spineboy-pro.json");
|
||
|
sspine_skeleton skeleton = sspine_make_skeleton(&(sspine_skeleton_desc){
|
||
|
.atlas = atlas,
|
||
|
.json_data = (const char*)skeleton_json_data.ptr
|
||
|
});
|
||
|
free_data(skeleton_json_data);
|
||
|
return skeleton;
|
||
|
}
|
||
|
|
||
|
static sspine_skeleton create_skeleton_binary(sspine_atlas atlas) {
|
||
|
sspine_range skeleton_binary_data = load_data("spineboy-pro.skel");
|
||
|
sspine_skeleton skeleton = sspine_make_skeleton(&(sspine_skeleton_desc){
|
||
|
.atlas = atlas,
|
||
|
.binary_data = skeleton_binary_data
|
||
|
});
|
||
|
free_data(skeleton_binary_data);
|
||
|
return skeleton;
|
||
|
}
|
||
|
|
||
|
static sspine_skeleton create_skeleton(void) {
|
||
|
return create_skeleton_json(create_atlas());
|
||
|
}
|
||
|
|
||
|
static sspine_instance create_instance(void) {
|
||
|
return sspine_make_instance(&(sspine_instance_desc){
|
||
|
.skeleton = create_skeleton(),
|
||
|
});
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, default_init_shutdown) {
|
||
|
// FIXME!
|
||
|
T(true);
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, atlas_pool_exhausted) {
|
||
|
init_with_desc(&(sspine_desc){
|
||
|
.atlas_pool_size = 4,
|
||
|
});
|
||
|
for (int i = 0; i < 4; i++) {
|
||
|
sspine_atlas atlas = sspine_make_atlas(&(sspine_atlas_desc){0});
|
||
|
T(sspine_get_atlas_resource_state(atlas) == SSPINE_RESOURCESTATE_FAILED);
|
||
|
T(last_logitem == SSPINE_LOGITEM_ATLAS_DESC_NO_DATA);
|
||
|
}
|
||
|
sspine_atlas atlas = sspine_make_atlas(&(sspine_atlas_desc){0});
|
||
|
T(SSPINE_INVALID_ID == atlas.id);
|
||
|
T(sspine_get_atlas_resource_state(atlas) == SSPINE_RESOURCESTATE_INVALID);
|
||
|
T(last_logitem == SSPINE_LOGITEM_ATLAS_POOL_EXHAUSTED);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, make_destroy_atlas_ok) {
|
||
|
init();
|
||
|
sspine_atlas atlas = create_atlas();
|
||
|
T(sspine_get_atlas_resource_state(atlas) == SSPINE_RESOURCESTATE_VALID);
|
||
|
T(sspine_atlas_valid(atlas));
|
||
|
sspine_destroy_atlas(atlas);
|
||
|
T(sspine_get_atlas_resource_state(atlas) == SSPINE_RESOURCESTATE_INVALID);
|
||
|
T(!sspine_atlas_valid(atlas))
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, make_atlas_fail_no_data) {
|
||
|
init();
|
||
|
sspine_atlas atlas = sspine_make_atlas(&(sspine_atlas_desc){0});
|
||
|
T(atlas.id != SSPINE_INVALID_ID);
|
||
|
T(last_logitem == SSPINE_LOGITEM_ATLAS_DESC_NO_DATA);
|
||
|
T(sspine_get_atlas_resource_state(atlas) == SSPINE_RESOURCESTATE_FAILED);
|
||
|
T(!sspine_atlas_valid(atlas));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
// an invalid atlas must return zero number of images
|
||
|
UTEST(sokol_spine, failed_atlas_no_images) {
|
||
|
init();
|
||
|
sspine_atlas atlas = sspine_make_atlas(&(sspine_atlas_desc){0});
|
||
|
T(last_logitem == SSPINE_LOGITEM_ATLAS_DESC_NO_DATA);
|
||
|
T(atlas.id != SSPINE_INVALID_ID);
|
||
|
T(!sspine_atlas_valid(atlas));
|
||
|
T(sspine_num_images(atlas) == 0);
|
||
|
shutdown();
|
||
|
|
||
|
}
|
||
|
|
||
|
// NOTE: spine-c doesn't detect wrong/corrupt atlas file data, so we can't test for that
|
||
|
|
||
|
UTEST(sokol_spine, image_valid) {
|
||
|
init();
|
||
|
sspine_atlas atlas = create_atlas();
|
||
|
T(sspine_image_valid(sspine_image_by_index(atlas, 0)));
|
||
|
T(!sspine_image_valid(sspine_image_by_index(atlas, 1)));
|
||
|
T(!sspine_image_valid(sspine_image_by_index(atlas, -1)));
|
||
|
sspine_destroy_atlas(atlas);
|
||
|
T(!sspine_image_valid(sspine_image_by_index(atlas, 0)));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, atlas_image_info) {
|
||
|
init();
|
||
|
sspine_atlas atlas = create_atlas();
|
||
|
T(sspine_atlas_valid(atlas));
|
||
|
T(sspine_num_images(atlas) == 1);
|
||
|
const sspine_image_info img_info = sspine_get_image_info(sspine_image_by_index(atlas, 0));
|
||
|
T(img_info.valid);
|
||
|
T(img_info.sgimage.id != SG_INVALID_ID);
|
||
|
T(sg_query_image_state(img_info.sgimage) == SG_RESOURCESTATE_ALLOC);
|
||
|
T(strcmp(img_info.filename.cstr, "spineboy.png") == 0);
|
||
|
T(img_info.min_filter == SG_FILTER_LINEAR);
|
||
|
T(img_info.mag_filter == SG_FILTER_LINEAR);
|
||
|
T(img_info.wrap_u == SG_WRAP_CLAMP_TO_EDGE);
|
||
|
T(img_info.wrap_v == SG_WRAP_CLAMP_TO_EDGE);
|
||
|
T(img_info.width == 1024);
|
||
|
T(img_info.height == 256);
|
||
|
T(img_info.premul_alpha == false);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, atlas_with_overrides) {
|
||
|
init();
|
||
|
sspine_range atlas_data = load_data("spineboy.atlas");
|
||
|
sspine_atlas atlas = sspine_make_atlas(&(sspine_atlas_desc){
|
||
|
.data = atlas_data,
|
||
|
.override = {
|
||
|
.min_filter = SG_FILTER_NEAREST,
|
||
|
.mag_filter = SG_FILTER_NEAREST,
|
||
|
.mipmap_filter = SG_FILTER_LINEAR,
|
||
|
.wrap_u = SG_WRAP_REPEAT,
|
||
|
.wrap_v = SG_WRAP_CLAMP_TO_EDGE,
|
||
|
.premul_alpha_enabled = true,
|
||
|
}
|
||
|
});
|
||
|
T(sspine_atlas_valid(atlas));
|
||
|
T(sspine_num_images(atlas) == 1);
|
||
|
const sspine_image_info img_info = sspine_get_image_info(sspine_image_by_index(atlas, 0));
|
||
|
T(img_info.valid);
|
||
|
T(img_info.sgimage.id != SG_INVALID_ID);
|
||
|
T(sg_query_image_state(img_info.sgimage) == SG_RESOURCESTATE_ALLOC);
|
||
|
T(strcmp(img_info.filename.cstr, "spineboy.png") == 0);
|
||
|
T(img_info.min_filter == SG_FILTER_NEAREST);
|
||
|
T(img_info.mag_filter == SG_FILTER_NEAREST);
|
||
|
T(img_info.mipmap_filter == SG_FILTER_LINEAR);
|
||
|
T(img_info.wrap_u == SG_WRAP_REPEAT);
|
||
|
T(img_info.wrap_v == SG_WRAP_CLAMP_TO_EDGE);
|
||
|
T(img_info.width == 1024);
|
||
|
T(img_info.height == 256);
|
||
|
T(img_info.premul_alpha == true);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, skeleton_pool_exhausted) {
|
||
|
init_with_desc(&(sspine_desc){
|
||
|
.skeleton_pool_size = 4
|
||
|
});
|
||
|
for (int i = 0; i < 4; i++) {
|
||
|
sspine_skeleton skeleton = sspine_make_skeleton(&(sspine_skeleton_desc){0});
|
||
|
T(sspine_get_skeleton_resource_state(skeleton) == SSPINE_RESOURCESTATE_FAILED);
|
||
|
T(last_logitem == SSPINE_LOGITEM_SKELETON_DESC_NO_DATA);
|
||
|
}
|
||
|
sspine_skeleton skeleton = sspine_make_skeleton(&(sspine_skeleton_desc){0});
|
||
|
T(SSPINE_INVALID_ID == skeleton.id);
|
||
|
T(sspine_get_skeleton_resource_state(skeleton) == SSPINE_RESOURCESTATE_INVALID);
|
||
|
T(last_logitem == SSPINE_LOGITEM_SKELETON_POOL_EXHAUSTED);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, make_destroy_skeleton_json_ok) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton_json(create_atlas());
|
||
|
T(sspine_get_skeleton_resource_state(skeleton) == SSPINE_RESOURCESTATE_VALID);
|
||
|
T(sspine_skeleton_valid(skeleton));
|
||
|
sspine_destroy_skeleton(skeleton);
|
||
|
T(sspine_get_skeleton_resource_state(skeleton) == SSPINE_RESOURCESTATE_INVALID);
|
||
|
T(!sspine_skeleton_valid(skeleton));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, make_destroy_skeleton_binary_ok) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton_binary(create_atlas());
|
||
|
T(sspine_get_skeleton_resource_state(skeleton) == SSPINE_RESOURCESTATE_VALID);
|
||
|
T(sspine_skeleton_valid(skeleton));
|
||
|
sspine_destroy_skeleton(skeleton);
|
||
|
T(sspine_get_skeleton_resource_state(skeleton) == SSPINE_RESOURCESTATE_INVALID);
|
||
|
T(!sspine_skeleton_valid(skeleton));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, make_skeleton_fail_no_data) {
|
||
|
init();
|
||
|
sspine_atlas atlas = create_atlas();
|
||
|
sspine_skeleton skeleton = sspine_make_skeleton(&(sspine_skeleton_desc){
|
||
|
.atlas = atlas
|
||
|
});
|
||
|
T(sspine_get_skeleton_resource_state(skeleton) == SSPINE_RESOURCESTATE_FAILED);
|
||
|
T(!sspine_skeleton_valid(skeleton));
|
||
|
T(last_logitem == SSPINE_LOGITEM_SKELETON_DESC_NO_DATA);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, make_skeleton_fail_no_atlas) {
|
||
|
init();
|
||
|
sspine_range skeleton_json_data = load_data("spineboy-pro.json");
|
||
|
sspine_skeleton skeleton = sspine_make_skeleton(&(sspine_skeleton_desc){
|
||
|
.json_data = (const char*)skeleton_json_data.ptr
|
||
|
});
|
||
|
free_data(skeleton_json_data);
|
||
|
T(sspine_get_skeleton_resource_state(skeleton) == SSPINE_RESOURCESTATE_FAILED);
|
||
|
T(!sspine_skeleton_valid(skeleton));
|
||
|
T(last_logitem == SSPINE_LOGITEM_SKELETON_DESC_NO_ATLAS);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, make_skeleton_fail_with_failed_atlas) {
|
||
|
init();
|
||
|
sspine_atlas atlas = sspine_make_atlas(&(sspine_atlas_desc){0});
|
||
|
T(last_logitem == SSPINE_LOGITEM_ATLAS_DESC_NO_DATA);
|
||
|
T(sspine_get_atlas_resource_state(atlas) == SSPINE_RESOURCESTATE_FAILED);
|
||
|
sspine_skeleton skeleton = create_skeleton_json(atlas);
|
||
|
T(sspine_get_skeleton_resource_state(skeleton) == SSPINE_RESOURCESTATE_FAILED);
|
||
|
T(!sspine_skeleton_valid(skeleton));
|
||
|
T(last_logitem == SSPINE_LOGITEM_SKELETON_ATLAS_NOT_VALID);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, make_skeleton_json_fail_corrupt_data) {
|
||
|
init();
|
||
|
sspine_atlas atlas = create_atlas();
|
||
|
const char* invalid_json_data = "This is not valid JSON!";
|
||
|
sspine_skeleton skeleton = sspine_make_skeleton(&(sspine_skeleton_desc){
|
||
|
.atlas = atlas,
|
||
|
.json_data = (const char*)invalid_json_data,
|
||
|
});
|
||
|
T(sspine_get_skeleton_resource_state(skeleton) == SSPINE_RESOURCESTATE_FAILED);
|
||
|
T(last_logitem == SSPINE_LOGITEM_CREATE_SKELETON_DATA_FROM_JSON_FAILED);
|
||
|
sspine_destroy_skeleton(skeleton);
|
||
|
T(sspine_get_skeleton_resource_state(skeleton) == SSPINE_RESOURCESTATE_INVALID);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
// FIXME: this crashes the spine-c runtime
|
||
|
/*
|
||
|
UTEST(sokol_spine, make_skeleton_binary_fail_corrupt_data) {
|
||
|
init();
|
||
|
sspine_atlas atlas = create_atlas();
|
||
|
uint8_t invalid_binary_data[] = { 0x23, 0x63, 0x11, 0xFF };
|
||
|
sspine_skeleton skeleton = sspine_make_skeleton(&(sspine_skeleton_desc){
|
||
|
.atlas = atlas,
|
||
|
.binary_data = { .ptr = invalid_binary_data, .size = sizeof(invalid_binary_data) }
|
||
|
});
|
||
|
T(sspine_get_skeleton_resource_state(skeleton) == SSPINE_RESOURCESTATE_FAILED);
|
||
|
sspine_destroy_skeleton(skeleton);
|
||
|
T(sspine_get_skeleton_resource_state(skeleton) == SSPINE_RESOURCESTATE_INVALID);
|
||
|
shutdown();
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
UTEST(sokol_spine, instance_pool_exhausted) {
|
||
|
init_with_desc(&(sspine_desc){
|
||
|
.instance_pool_size = 4
|
||
|
});
|
||
|
for (int i = 0; i < 4; i++) {
|
||
|
sspine_instance instance = sspine_make_instance(&(sspine_instance_desc){0});
|
||
|
T(sspine_get_instance_resource_state(instance) == SSPINE_RESOURCESTATE_FAILED);
|
||
|
T(last_logitem == SSPINE_LOGITEM_INSTANCE_DESC_NO_SKELETON);
|
||
|
}
|
||
|
sspine_instance instance = sspine_make_instance(&(sspine_instance_desc){0});
|
||
|
T(SSPINE_INVALID_ID == instance.id);
|
||
|
T(sspine_get_instance_resource_state(instance) == SSPINE_RESOURCESTATE_INVALID);
|
||
|
T(last_logitem == SSPINE_LOGITEM_INSTANCE_POOL_EXHAUSTED);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, make_destroy_instance_ok) {
|
||
|
init();
|
||
|
sspine_instance instance = sspine_make_instance(&(sspine_instance_desc){
|
||
|
.skeleton = create_skeleton_json(create_atlas())
|
||
|
});
|
||
|
T(sspine_get_instance_resource_state(instance) == SSPINE_RESOURCESTATE_VALID);
|
||
|
T(sspine_instance_valid(instance));
|
||
|
sspine_destroy_instance(instance);
|
||
|
T(sspine_get_instance_resource_state(instance) == SSPINE_RESOURCESTATE_INVALID);
|
||
|
T(!sspine_instance_valid(instance));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, make_instance_fail_no_skeleton) {
|
||
|
init();
|
||
|
sspine_instance instance = sspine_make_instance(&(sspine_instance_desc){0});
|
||
|
T(sspine_get_instance_resource_state(instance) == SSPINE_RESOURCESTATE_FAILED);
|
||
|
T(last_logitem == SSPINE_LOGITEM_INSTANCE_DESC_NO_SKELETON);
|
||
|
sspine_destroy_instance(instance);
|
||
|
T(sspine_get_instance_resource_state(instance) == SSPINE_RESOURCESTATE_INVALID);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, make_instance_fail_with_failed_skeleton) {
|
||
|
init();
|
||
|
sspine_skeleton failed_skeleton = sspine_make_skeleton(&(sspine_skeleton_desc){0});
|
||
|
T(last_logitem == SSPINE_LOGITEM_SKELETON_DESC_NO_DATA);
|
||
|
T(sspine_get_skeleton_resource_state(failed_skeleton) == SSPINE_RESOURCESTATE_FAILED);
|
||
|
sspine_instance instance = sspine_make_instance(&(sspine_instance_desc){
|
||
|
.skeleton = failed_skeleton
|
||
|
});
|
||
|
T(sspine_get_instance_resource_state(instance) == SSPINE_RESOURCESTATE_FAILED);
|
||
|
T(last_logitem == SSPINE_LOGITEM_INSTANCE_SKELETON_NOT_VALID);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, make_instance_fail_with_destroyed_atlas) {
|
||
|
init();
|
||
|
sspine_atlas atlas = create_atlas();
|
||
|
T(sspine_atlas_valid(atlas));
|
||
|
sspine_skeleton skeleton = create_skeleton_json(atlas);
|
||
|
T(sspine_skeleton_valid(skeleton));
|
||
|
sspine_destroy_atlas(atlas);
|
||
|
T(!sspine_atlas_valid(atlas));
|
||
|
sspine_instance instance = sspine_make_instance(&(sspine_instance_desc){
|
||
|
.skeleton = skeleton
|
||
|
});
|
||
|
T(sspine_get_instance_resource_state(instance) == SSPINE_RESOURCESTATE_FAILED);
|
||
|
T(last_logitem == SSPINE_LOGITEM_INSTANCE_ATLAS_NOT_VALID);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, get_skeleton_atlas) {
|
||
|
init();
|
||
|
sspine_atlas atlas = create_atlas();
|
||
|
sspine_skeleton skeleton = create_skeleton_json(atlas);
|
||
|
T(sspine_get_skeleton_atlas(skeleton).id == atlas.id);
|
||
|
sspine_destroy_skeleton(skeleton);
|
||
|
T(sspine_get_skeleton_atlas(skeleton).id == SSPINE_INVALID_ID);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, get_instance_skeleton) {
|
||
|
init();
|
||
|
sspine_atlas atlas = create_atlas();
|
||
|
sspine_skeleton skeleton = create_skeleton_json(atlas);
|
||
|
sspine_instance instance = sspine_make_instance(&(sspine_instance_desc){
|
||
|
.skeleton = skeleton
|
||
|
});
|
||
|
T(sspine_get_instance_skeleton(instance).id == skeleton.id);
|
||
|
sspine_destroy_instance(instance);
|
||
|
T(sspine_get_instance_skeleton(instance).id == SSPINE_INVALID_ID);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, set_get_position) {
|
||
|
init();
|
||
|
sspine_instance instance = create_instance();
|
||
|
sspine_set_position(instance, (sspine_vec2){ .x=1.0f, .y=2.0f });
|
||
|
const sspine_vec2 pos = sspine_get_position(instance);
|
||
|
T(pos.x == 1.0f);
|
||
|
T(pos.y == 2.0f);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, set_get_position_destroyed_instance) {
|
||
|
init();
|
||
|
sspine_instance instance = create_instance();
|
||
|
sspine_set_position(instance, (sspine_vec2){ .x=1.0f, .y=2.0f });
|
||
|
sspine_destroy_instance(instance);
|
||
|
const sspine_vec2 pos = sspine_get_position(instance);
|
||
|
T(pos.x == 0.0f);
|
||
|
T(pos.y == 0.0f);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, set_get_scale) {
|
||
|
init();
|
||
|
sspine_instance instance = create_instance();
|
||
|
sspine_set_scale(instance, (sspine_vec2){ .x=2.0f, .y=3.0f });
|
||
|
const sspine_vec2 scale = sspine_get_scale(instance);
|
||
|
T(scale.x == 2.0f);
|
||
|
T(scale.y == 3.0f);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, set_get_scale_destroyed_instance) {
|
||
|
init();
|
||
|
sspine_instance instance = create_instance();
|
||
|
sspine_set_scale(instance, (sspine_vec2){ .x=2.0f, .y=3.0f });
|
||
|
sspine_destroy_instance(instance);
|
||
|
const sspine_vec2 scale = sspine_get_scale(instance);
|
||
|
T(scale.x == 0.0f);
|
||
|
T(scale.y == 0.0f);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, set_get_color) {
|
||
|
init();
|
||
|
sspine_instance instance = create_instance();
|
||
|
sspine_set_color(instance, (sspine_color) { .r=1.0f, .g=2.0f, .b=3.0f, .a=4.0f });
|
||
|
const sspine_color color = sspine_get_color(instance);
|
||
|
T(color.r == 1.0f);
|
||
|
T(color.g == 2.0f);
|
||
|
T(color.b == 3.0f);
|
||
|
T(color.a == 4.0f);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, set_get_color_destroyed_instance) {
|
||
|
init();
|
||
|
sspine_instance instance = create_instance();
|
||
|
sspine_set_color(instance, (sspine_color) { .r=1.0f, .g=2.0f, .b=3.0f, .a=4.0f });
|
||
|
sspine_destroy_instance(instance);
|
||
|
const sspine_color color = sspine_get_color(instance);
|
||
|
T(color.r == 0.0f);
|
||
|
T(color.g == 0.0f);
|
||
|
T(color.b == 0.0f);
|
||
|
T(color.a == 0.0f);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, anim_by_name) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
sspine_anim a0 = sspine_anim_by_name(skeleton, "hoverboard");
|
||
|
T((a0.skeleton_id == skeleton.id) && (a0.index == 2));
|
||
|
sspine_anim a1 = sspine_anim_by_name(skeleton, "bla");
|
||
|
T((a1.skeleton_id == 0) && (a1.index == 0));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, anim_by_name_destroyed_instance) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
sspine_destroy_skeleton(skeleton);
|
||
|
sspine_anim a0 = sspine_anim_by_name(skeleton, "hoverboard");
|
||
|
T((a0.skeleton_id == 0) && (a0.index == 0));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, anim_valid) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
T(sspine_anim_valid(sspine_anim_by_index(skeleton, 0)));
|
||
|
T(sspine_anim_valid(sspine_anim_by_index(skeleton, 10)));
|
||
|
T(!sspine_anim_valid(sspine_anim_by_index(skeleton, -1)));
|
||
|
T(!sspine_anim_valid(sspine_anim_by_index(skeleton, 11)));
|
||
|
sspine_destroy_skeleton(skeleton);
|
||
|
T(!sspine_anim_valid(sspine_anim_by_index(skeleton, 0)));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, anim_equal) {
|
||
|
init();
|
||
|
T(sspine_anim_equal((sspine_anim){ 1, 2 }, (sspine_anim){ 1, 2 }));
|
||
|
T(!sspine_anim_equal((sspine_anim){ 2, 2 }, (sspine_anim){ 1, 2 }));
|
||
|
T(!sspine_anim_equal((sspine_anim){ 1, 3 }, (sspine_anim){ 1, 2 }));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, num_anims) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
T(sspine_num_anims(skeleton) == 11);
|
||
|
sspine_destroy_skeleton(skeleton);
|
||
|
T(sspine_num_anims(skeleton) == 0);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, get_anim_info) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
sspine_anim anim = sspine_anim_by_name(skeleton, "hoverboard");
|
||
|
const sspine_anim_info info = sspine_get_anim_info(anim);
|
||
|
T(info.valid);
|
||
|
T(info.index == 2);
|
||
|
T(strcmp(info.name.cstr, "hoverboard") == 0);
|
||
|
T(info.duration == 1.0f);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, get_anim_info_destroyed_skeleton) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
sspine_anim anim = sspine_anim_by_name(skeleton, "hoverboard");
|
||
|
sspine_destroy_skeleton(skeleton);
|
||
|
const sspine_anim_info info = sspine_get_anim_info(anim);
|
||
|
T(!info.valid);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, get_anim_info_invalid_index) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
const sspine_anim_info i0 = sspine_get_anim_info(sspine_anim_by_index(skeleton, -1));
|
||
|
T(!i0.valid);
|
||
|
T(!i0.name.valid);
|
||
|
const sspine_anim_info i1 = sspine_get_anim_info(sspine_anim_by_index(skeleton, 1234));
|
||
|
T(!i1.valid);
|
||
|
T(!i1.name.valid);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, atlas_page_valid) {
|
||
|
init();
|
||
|
sspine_atlas atlas = create_atlas();
|
||
|
T(sspine_atlas_page_valid(sspine_atlas_page_by_index(atlas, 0)));
|
||
|
T(!sspine_atlas_page_valid(sspine_atlas_page_by_index(atlas, -1)));
|
||
|
T(!sspine_atlas_page_valid(sspine_atlas_page_by_index(atlas, 1)));
|
||
|
sspine_destroy_atlas(atlas);
|
||
|
T(!sspine_atlas_page_valid(sspine_atlas_page_by_index(atlas, 0)));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, num_atlas_pages) {
|
||
|
init();
|
||
|
sspine_atlas atlas = create_atlas();
|
||
|
T(sspine_num_atlas_pages(atlas) == 1);
|
||
|
sspine_destroy_atlas(atlas);
|
||
|
T(sspine_num_atlas_pages(atlas) == 0);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, get_atlas_page_info) {
|
||
|
init();
|
||
|
sspine_atlas atlas = create_atlas();
|
||
|
const sspine_atlas_page_info info = sspine_get_atlas_page_info(sspine_atlas_page_by_index(atlas, 0));
|
||
|
T(info.valid);
|
||
|
T(info.atlas.id == atlas.id);
|
||
|
T(info.image.valid);
|
||
|
T(info.image.sgimage.id != SG_INVALID_ID);
|
||
|
T(sg_query_image_state(info.image.sgimage) == SG_RESOURCESTATE_ALLOC);
|
||
|
T(strcmp(info.image.filename.cstr, "spineboy.png") == 0);
|
||
|
T(info.image.min_filter == SG_FILTER_LINEAR);
|
||
|
T(info.image.mag_filter == SG_FILTER_LINEAR);
|
||
|
T(info.image.wrap_u == SG_WRAP_CLAMP_TO_EDGE);
|
||
|
T(info.image.wrap_v == SG_WRAP_CLAMP_TO_EDGE);
|
||
|
T(info.image.width == 1024);
|
||
|
T(info.image.height == 256);
|
||
|
T(info.image.premul_alpha == false);
|
||
|
T(info.overrides.min_filter == _SG_FILTER_DEFAULT);
|
||
|
T(info.overrides.mag_filter == _SG_FILTER_DEFAULT);
|
||
|
T(info.overrides.wrap_u == _SG_WRAP_DEFAULT);
|
||
|
T(info.overrides.wrap_v == _SG_WRAP_DEFAULT);
|
||
|
T(!info.overrides.premul_alpha_enabled);
|
||
|
T(!info.overrides.premul_alpha_disabled);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, get_atlas_page_info_destroyed_atlas) {
|
||
|
init();
|
||
|
sspine_atlas atlas = create_atlas();
|
||
|
sspine_destroy_atlas(atlas);
|
||
|
const sspine_atlas_page_info info = sspine_get_atlas_page_info(sspine_atlas_page_by_index(atlas, 0));
|
||
|
T(!info.valid);
|
||
|
T(info.atlas.id == SSPINE_INVALID_ID);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, get_atlas_page_info_invalid_index) {
|
||
|
init();
|
||
|
sspine_atlas atlas = create_atlas();
|
||
|
sspine_destroy_atlas(atlas);
|
||
|
const sspine_atlas_page_info i0 = sspine_get_atlas_page_info(sspine_atlas_page_by_index(atlas, -1));
|
||
|
T(!i0.valid);
|
||
|
T(i0.atlas.id == SSPINE_INVALID_ID);
|
||
|
const sspine_atlas_page_info i1 = sspine_get_atlas_page_info(sspine_atlas_page_by_index(atlas, 1234));
|
||
|
T(!i0.valid);
|
||
|
T(i1.atlas.id == SSPINE_INVALID_ID);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, atlas_get_atlas_page_info_with_overrides) {
|
||
|
init();
|
||
|
sspine_range atlas_data = load_data("spineboy.atlas");
|
||
|
sspine_atlas atlas = sspine_make_atlas(&(sspine_atlas_desc){
|
||
|
.data = atlas_data,
|
||
|
.override = {
|
||
|
.min_filter = SG_FILTER_NEAREST,
|
||
|
.mag_filter = SG_FILTER_NEAREST,
|
||
|
.mipmap_filter = SG_FILTER_NEAREST,
|
||
|
.wrap_u = SG_WRAP_REPEAT,
|
||
|
.wrap_v = SG_WRAP_CLAMP_TO_EDGE,
|
||
|
.premul_alpha_enabled = true,
|
||
|
}
|
||
|
});
|
||
|
const sspine_atlas_page_info info = sspine_get_atlas_page_info(sspine_atlas_page_by_index(atlas, 0));
|
||
|
T(info.valid);
|
||
|
T(info.atlas.id == atlas.id);
|
||
|
T(info.image.valid);
|
||
|
T(info.image.sgimage.id != SG_INVALID_ID);
|
||
|
T(sg_query_image_state(info.image.sgimage) == SG_RESOURCESTATE_ALLOC);
|
||
|
T(strcmp(info.image.filename.cstr, "spineboy.png") == 0);
|
||
|
T(info.image.min_filter == SG_FILTER_LINEAR);
|
||
|
T(info.image.mag_filter == SG_FILTER_LINEAR);
|
||
|
T(info.image.mipmap_filter == SG_FILTER_NONE);
|
||
|
T(info.image.wrap_u == SG_WRAP_CLAMP_TO_EDGE);
|
||
|
T(info.image.wrap_v == SG_WRAP_CLAMP_TO_EDGE);
|
||
|
T(info.image.width == 1024);
|
||
|
T(info.image.height == 256);
|
||
|
T(info.image.premul_alpha == true); // FIXME: hmm, this is actually inconsistent
|
||
|
T(info.overrides.min_filter == SG_FILTER_NEAREST);
|
||
|
T(info.overrides.mag_filter == SG_FILTER_NEAREST);
|
||
|
T(info.overrides.mipmap_filter == SG_FILTER_NEAREST);
|
||
|
T(info.overrides.wrap_u == SG_WRAP_REPEAT);
|
||
|
T(info.overrides.wrap_v == SG_WRAP_CLAMP_TO_EDGE);
|
||
|
T(info.overrides.premul_alpha_enabled);
|
||
|
T(!info.overrides.premul_alpha_disabled);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, bone_by_name) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
sspine_bone b0 = sspine_bone_by_name(skeleton, "crosshair");
|
||
|
T((b0.skeleton_id == skeleton.id) && (b0.index == 2));
|
||
|
sspine_bone b1 = sspine_bone_by_name(skeleton, "blablub");
|
||
|
T((b1.skeleton_id == 0) && (b1.index == 0));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, bone_by_name_destroyed_skeleton) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
sspine_destroy_skeleton(skeleton);
|
||
|
sspine_bone b0 = sspine_bone_by_name(skeleton, "crosshair");
|
||
|
T((b0.skeleton_id == 0) && (b0.index == 0));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, bone_valid) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
T(sspine_bone_valid(sspine_bone_by_index(skeleton, 0)));
|
||
|
T(sspine_bone_valid(sspine_bone_by_index(skeleton, 66)));
|
||
|
T(!sspine_bone_valid(sspine_bone_by_index(skeleton, -1)));
|
||
|
T(!sspine_bone_valid(sspine_bone_by_index(skeleton, 67)));
|
||
|
sspine_destroy_skeleton(skeleton);
|
||
|
T(!sspine_bone_valid(sspine_bone_by_index(skeleton, 0)));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, bone_equal) {
|
||
|
init();
|
||
|
T(sspine_bone_equal((sspine_bone){ 1, 2 }, (sspine_bone){ 1, 2 }));
|
||
|
T(!sspine_bone_equal((sspine_bone){ 2, 2 }, (sspine_bone){ 1, 2 }));
|
||
|
T(!sspine_bone_equal((sspine_bone){ 1, 3 }, (sspine_bone){ 1, 2 }));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, num_bones) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
T(sspine_num_bones(skeleton) == 67);
|
||
|
sspine_destroy_skeleton(skeleton);
|
||
|
T(sspine_num_bones(skeleton) == 0);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, get_bone_info_root) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
const sspine_bone_info info = sspine_get_bone_info(sspine_bone_by_name(skeleton, "root"));
|
||
|
T(info.valid);
|
||
|
T(info.index == 0);
|
||
|
T((info.parent_bone.skeleton_id == 0) && (info.parent_bone.index == 0));
|
||
|
T(strcmp(info.name.cstr, "root") == 0);
|
||
|
T(info.length == 0.0f);
|
||
|
T(info.pose.position.x == 0.0f);
|
||
|
T(info.pose.position.y == 0.0f);
|
||
|
T(info.pose.rotation == 0.05f);
|
||
|
T(info.pose.scale.x == 1.0f);
|
||
|
T(info.pose.scale.y == 1.0f);
|
||
|
T(info.pose.shear.x == 0.0f);
|
||
|
T(info.pose.shear.y == 0.0f);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, get_bone_info_parent_bone) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
const sspine_bone_info info = sspine_get_bone_info(sspine_bone_by_name(skeleton, "rear-shin"));
|
||
|
T(info.valid);
|
||
|
T(info.index == 7);
|
||
|
T((info.parent_bone.skeleton_id == skeleton.id) && (info.parent_bone.index == 6));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, get_bone_info_destroyed_skeleton) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
sspine_bone bone = sspine_bone_by_name(skeleton, "root");
|
||
|
sspine_destroy_skeleton(skeleton);
|
||
|
const sspine_bone_info info = sspine_get_bone_info(bone);
|
||
|
T(!info.valid);
|
||
|
T(!info.name.valid);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, get_bone_info_invalid_index) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
const sspine_bone_info i0 = sspine_get_bone_info(sspine_bone_by_index(skeleton, -1));
|
||
|
T(!i0.valid);
|
||
|
T(!i0.name.valid);
|
||
|
const sspine_bone_info i1 = sspine_get_bone_info(sspine_bone_by_index(skeleton, 1234));
|
||
|
T(!i1.valid);
|
||
|
T(!i1.name.valid);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, set_get_bone_transform) {
|
||
|
init();
|
||
|
sspine_instance instance = create_instance();
|
||
|
sspine_skeleton skeleton = sspine_get_instance_skeleton(instance);
|
||
|
sspine_bone bone = sspine_bone_by_name(skeleton, "root");
|
||
|
sspine_set_bone_transform(instance, bone, &(sspine_bone_transform){
|
||
|
.position = { 1.0f, 2.0f },
|
||
|
.rotation = 3.0f,
|
||
|
.scale = { 4.0f, 5.0f },
|
||
|
.shear = { 6.0f, 7.0f }
|
||
|
});
|
||
|
const sspine_bone_transform tform = sspine_get_bone_transform(instance, bone);
|
||
|
T(tform.position.x == 1.0f);
|
||
|
T(tform.position.y == 2.0f);
|
||
|
T(tform.rotation == 3.0f);
|
||
|
T(tform.scale.x == 4.0f);
|
||
|
T(tform.scale.y == 5.0f);
|
||
|
T(tform.shear.x == 6.0f);
|
||
|
T(tform.shear.y == 7.0f);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, set_get_bone_transform_destroyed_instance) {
|
||
|
init();
|
||
|
sspine_instance instance = create_instance();
|
||
|
sspine_skeleton skeleton = sspine_get_instance_skeleton(instance);
|
||
|
sspine_bone bone = sspine_bone_by_name(skeleton, "root");
|
||
|
sspine_destroy_instance(instance);
|
||
|
sspine_set_bone_transform(instance, bone, &(sspine_bone_transform){
|
||
|
.position = { 1.0f, 2.0f },
|
||
|
.rotation = 3.0f,
|
||
|
.scale = { 4.0f, 5.0f },
|
||
|
.shear = { 6.0f, 7.0f }
|
||
|
});
|
||
|
const sspine_bone_transform tform = sspine_get_bone_transform(instance, bone);
|
||
|
T(tform.position.x == 0.0f);
|
||
|
T(tform.position.y == 0.0f);
|
||
|
T(tform.rotation == 0.0f);
|
||
|
T(tform.scale.x == 0.0f);
|
||
|
T(tform.scale.y == 0.0f);
|
||
|
T(tform.shear.x == 0.0f);
|
||
|
T(tform.shear.y == 0.0f);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, set_get_bone_position) {
|
||
|
init();
|
||
|
sspine_instance instance = create_instance();
|
||
|
sspine_skeleton skeleton = sspine_get_instance_skeleton(instance);
|
||
|
sspine_bone bone = sspine_bone_by_name(skeleton, "root");
|
||
|
sspine_set_bone_position(instance, bone, (sspine_vec2){ 1.0f, 2.0f });
|
||
|
const sspine_vec2 p0 = sspine_get_bone_position(instance, bone);
|
||
|
T(p0.x == 1.0f);
|
||
|
T(p0.y == 2.0f);
|
||
|
sspine_destroy_instance(instance);
|
||
|
const sspine_vec2 p1 = sspine_get_bone_position(instance, bone);
|
||
|
T(p1.x == 0.0f);
|
||
|
T(p1.y == 0.0f);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, set_get_bone_rotation) {
|
||
|
init();
|
||
|
sspine_instance instance = create_instance();
|
||
|
sspine_skeleton skeleton = sspine_get_instance_skeleton(instance);
|
||
|
sspine_bone bone = sspine_bone_by_name(skeleton, "root");
|
||
|
sspine_set_bone_rotation(instance, bone, 5.0f);
|
||
|
T(sspine_get_bone_rotation(instance, bone) == 5.0f);
|
||
|
sspine_destroy_instance(instance);
|
||
|
T(sspine_get_bone_rotation(instance, bone) == 0.0f);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, set_get_bone_scale) {
|
||
|
init();
|
||
|
sspine_instance instance = create_instance();
|
||
|
sspine_skeleton skeleton = sspine_get_instance_skeleton(instance);
|
||
|
sspine_bone bone = sspine_bone_by_name(skeleton, "root");
|
||
|
sspine_set_bone_scale(instance, bone, (sspine_vec2){ 1.0f, 2.0f });
|
||
|
const sspine_vec2 s0 = sspine_get_bone_scale(instance, bone);
|
||
|
T(s0.x == 1.0f);
|
||
|
T(s0.y == 2.0f);
|
||
|
sspine_destroy_instance(instance);
|
||
|
const sspine_vec2 s1 = sspine_get_bone_scale(instance, bone);
|
||
|
T(s1.x == 0.0f);
|
||
|
T(s1.y == 0.0f);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, set_get_bone_shear) {
|
||
|
init();
|
||
|
sspine_instance instance = create_instance();
|
||
|
sspine_skeleton skeleton = sspine_get_instance_skeleton(instance);
|
||
|
sspine_bone bone = sspine_bone_by_name(skeleton, "root");
|
||
|
sspine_set_bone_shear(instance, bone, (sspine_vec2){ 1.0f, 2.0f });
|
||
|
const sspine_vec2 s0 = sspine_get_bone_shear(instance, bone);
|
||
|
T(s0.x == 1.0f);
|
||
|
T(s0.y == 2.0f);
|
||
|
sspine_destroy_instance(instance);
|
||
|
const sspine_vec2 s1 = sspine_get_bone_shear(instance, bone);
|
||
|
T(s1.x == 0.0f);
|
||
|
T(s1.y == 0.0f);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, slot_by_name) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
sspine_slot s0 = sspine_slot_by_name(skeleton, "portal-streaks1");
|
||
|
T((s0.skeleton_id == skeleton.id) && (s0.index == 3));
|
||
|
sspine_slot s1 = sspine_slot_by_name(skeleton, "blablub");
|
||
|
T((s1.skeleton_id == 0) && (s1.index == 0));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, slot_by_name_destroyed_skeleton) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
sspine_destroy_skeleton(skeleton);
|
||
|
sspine_slot s0 = sspine_slot_by_name(skeleton, "portal-streaks1");
|
||
|
T((s0.skeleton_id == 0) && (s0.index == 0));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, num_slots) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
T(sspine_num_slots(skeleton) == 52);
|
||
|
sspine_destroy_skeleton(skeleton);
|
||
|
T(sspine_num_slots(skeleton) == 0);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, slot_valid) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
T(sspine_slot_valid(sspine_slot_by_index(skeleton, 0)));
|
||
|
T(sspine_slot_valid(sspine_slot_by_index(skeleton, 51)));
|
||
|
T(!sspine_slot_valid(sspine_slot_by_index(skeleton, -1)));
|
||
|
T(!sspine_slot_valid(sspine_slot_by_index(skeleton, 52)));
|
||
|
sspine_destroy_skeleton(skeleton);
|
||
|
T(!sspine_slot_valid(sspine_slot_by_index(skeleton, 0)));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, slot_equal) {
|
||
|
init();
|
||
|
T(sspine_slot_equal((sspine_slot){ 1, 2 }, (sspine_slot){ 1, 2 }));
|
||
|
T(!sspine_slot_equal((sspine_slot){ 2, 2 }, (sspine_slot){ 1, 2 }));
|
||
|
T(!sspine_slot_equal((sspine_slot){ 1, 3 }, (sspine_slot){ 1, 2 }));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, get_slot_info) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
const sspine_slot_info info = sspine_get_slot_info(sspine_slot_by_name(skeleton, "portal-streaks1"));
|
||
|
T(info.valid);
|
||
|
T(info.index == 3);
|
||
|
T(strcmp(info.name.cstr, "portal-streaks1") == 0);
|
||
|
T(!info.attachment_name.valid);
|
||
|
T((info.bone.skeleton_id == skeleton.id) && (info.bone.index == 62));
|
||
|
T(info.color.r == 1.0f);
|
||
|
T(info.color.g == 1.0f);
|
||
|
T(info.color.b == 1.0f);
|
||
|
T(info.color.a == 1.0f);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, get_slot_info_destroyed_skeleton) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
sspine_slot slot = sspine_slot_by_name(skeleton, "portal-streaks1");
|
||
|
sspine_destroy_skeleton(skeleton);
|
||
|
const sspine_slot_info info = sspine_get_slot_info(slot);
|
||
|
T(!info.valid);
|
||
|
T(!info.name.valid);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, get_slot_info_invalid_index) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
const sspine_slot_info i0 = sspine_get_slot_info(sspine_slot_by_index(skeleton, -1));
|
||
|
T(!i0.valid);
|
||
|
T(!i0.name.valid);
|
||
|
const sspine_slot_info i1 = sspine_get_slot_info(sspine_slot_by_index(skeleton, 1234));
|
||
|
T(!i1.valid);
|
||
|
T(!i1.name.valid);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, set_get_slot_color) {
|
||
|
init();
|
||
|
sspine_instance instance = create_instance();
|
||
|
sspine_skeleton skeleton = sspine_get_instance_skeleton(instance);
|
||
|
sspine_slot slot = sspine_slot_by_name(skeleton, "portal-streaks1");
|
||
|
sspine_set_slot_color(instance, slot, (sspine_color){ 1.0f, 2.0f, 3.0f, 4.0f });
|
||
|
const sspine_color color = sspine_get_slot_color(instance, slot);
|
||
|
T(color.r == 1.0f);
|
||
|
T(color.g == 2.0f);
|
||
|
T(color.b == 3.0f);
|
||
|
T(color.a == 4.0f);
|
||
|
const sspine_slot_info info = sspine_get_slot_info(slot);
|
||
|
T(info.color.r == 1.0f);
|
||
|
T(info.color.g == 1.0f);
|
||
|
T(info.color.b == 1.0f);
|
||
|
T(info.color.a == 1.0f);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, event_by_name) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
sspine_event e0 = sspine_event_by_name(skeleton, "footstep");
|
||
|
T((e0.skeleton_id == skeleton.id) && (e0.index == 0));
|
||
|
sspine_event e1 = sspine_event_by_name(skeleton, "bla");
|
||
|
T((e1.skeleton_id == 0) && (e1.index == 0));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, event_by_name_destroyed_skeleton) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
sspine_destroy_skeleton(skeleton);
|
||
|
sspine_event e0 = sspine_event_by_name(skeleton, "footstep");
|
||
|
T((e0.skeleton_id == 0) && (e0.index == 0));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, event_valid) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
T(sspine_event_valid(sspine_event_by_index(skeleton, 0)));
|
||
|
T(!sspine_event_valid(sspine_event_by_index(skeleton, 1)));
|
||
|
T(!sspine_event_valid(sspine_event_by_index(skeleton, -1)));
|
||
|
sspine_destroy_skeleton(skeleton);
|
||
|
T(!sspine_event_valid(sspine_event_by_index(skeleton, 0)));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, event_equal) {
|
||
|
init();
|
||
|
T(sspine_event_equal((sspine_event){ 1, 2 }, (sspine_event){ 1, 2 }));
|
||
|
T(!sspine_event_equal((sspine_event){ 2, 2 }, (sspine_event){ 1, 2 }));
|
||
|
T(!sspine_event_equal((sspine_event){ 1, 3 }, (sspine_event){ 1, 2 }));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, num_events) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
T(sspine_num_events(skeleton) == 1);
|
||
|
sspine_destroy_skeleton(skeleton);
|
||
|
T(sspine_num_events(skeleton) == 0);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, get_event_info) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
const sspine_event_info info = sspine_get_event_info(sspine_event_by_index(skeleton, 0));
|
||
|
T(info.valid);
|
||
|
T(0 == strcmp(info.name.cstr, "footstep"));
|
||
|
T(0 == info.index);
|
||
|
T(0 == info.int_value);
|
||
|
T(0.0f == info.float_value);
|
||
|
T(!info.string_value.valid);
|
||
|
T(!info.audio_path.valid);
|
||
|
T(0.0f == info.volume);
|
||
|
T(0.0f == info.balance);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, get_event_info_destroyed_skeleton) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
sspine_destroy_skeleton(skeleton);
|
||
|
const sspine_event_info info = sspine_get_event_info(sspine_event_by_index(skeleton, 0));
|
||
|
T(!info.valid);
|
||
|
T(!info.name.valid);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, iktarget_by_name) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
sspine_iktarget ik0 = sspine_iktarget_by_name(skeleton, "board-ik");
|
||
|
T((ik0.skeleton_id == skeleton.id) && (ik0.index == 2));
|
||
|
sspine_iktarget ik1 = sspine_iktarget_by_name(skeleton, "bla");
|
||
|
T((ik1.skeleton_id == 0) && (ik1.index == 0));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, iktarget_by_name_destroyed_skeleton) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
sspine_destroy_skeleton(skeleton);
|
||
|
sspine_iktarget ik0 = sspine_iktarget_by_name(skeleton, "board-ik");
|
||
|
T((ik0.skeleton_id == 0) && (ik0.index == 0));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, iktarget_valid) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
T(sspine_iktarget_valid(sspine_iktarget_by_index(skeleton, 0)));
|
||
|
T(sspine_iktarget_valid(sspine_iktarget_by_index(skeleton, 6)));
|
||
|
T(!sspine_iktarget_valid(sspine_iktarget_by_index(skeleton, -1)));
|
||
|
T(!sspine_iktarget_valid(sspine_iktarget_by_index(skeleton, 7)));
|
||
|
sspine_destroy_skeleton(skeleton);
|
||
|
T(!sspine_iktarget_valid(sspine_iktarget_by_index(skeleton, 0)));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, iktarget_equal) {
|
||
|
init();
|
||
|
T(sspine_iktarget_equal((sspine_iktarget){ 1, 2 }, (sspine_iktarget){ 1, 2 }));
|
||
|
T(!sspine_iktarget_equal((sspine_iktarget){ 2, 2 }, (sspine_iktarget){ 1, 2 }));
|
||
|
T(!sspine_iktarget_equal((sspine_iktarget){ 1, 3 }, (sspine_iktarget){ 1, 2 }));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, num_iktargets) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
T(sspine_num_iktargets(skeleton) == 7);
|
||
|
sspine_destroy_skeleton(skeleton);
|
||
|
T(sspine_num_iktargets(skeleton) == 0);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, get_iktarget_info) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
const sspine_iktarget_info info = sspine_get_iktarget_info(sspine_iktarget_by_index(skeleton, 1));
|
||
|
T(info.valid);
|
||
|
T(1 == info.index);
|
||
|
T(0 == strcmp(info.name.cstr, "aim-torso-ik"));
|
||
|
T((info.target_bone.skeleton_id == skeleton.id) && (info.target_bone.index == 2));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, get_iktarget_info_destroyed_skeleton) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
sspine_destroy_skeleton(skeleton);
|
||
|
const sspine_iktarget_info info = sspine_get_iktarget_info(sspine_iktarget_by_index(skeleton, 1));
|
||
|
T(!info.valid);
|
||
|
T(!info.name.valid);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, get_iktarget_info_out_of_bounds) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
sspine_destroy_skeleton(skeleton);
|
||
|
const sspine_iktarget_info info0 = sspine_get_iktarget_info(sspine_iktarget_by_index(skeleton, -1));
|
||
|
T(!info0.name.valid);
|
||
|
const sspine_iktarget_info info1 = sspine_get_iktarget_info(sspine_iktarget_by_index(skeleton, 7));
|
||
|
T(!info1.name.valid);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, skin_by_name) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
sspine_skin s0 = sspine_skin_by_name(skeleton, "default");
|
||
|
T((s0.skeleton_id == skeleton.id) && (s0.index == 0));
|
||
|
sspine_skin s1 = sspine_skin_by_name(skeleton, "bla");
|
||
|
T((s1.skeleton_id == 0) && (s1.index == 0));
|
||
|
sspine_destroy_skeleton(skeleton);
|
||
|
sspine_skin s2 = sspine_skin_by_name(skeleton, "default");
|
||
|
T((s2.skeleton_id == 0) && (s2.index == 0));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, skin_valid) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
T(sspine_skin_valid(sspine_skin_by_index(skeleton, 0)));
|
||
|
T(!sspine_skin_valid(sspine_skin_by_index(skeleton, -1)));
|
||
|
T(!sspine_skin_valid(sspine_skin_by_index(skeleton, 1)));
|
||
|
sspine_destroy_skeleton(skeleton);
|
||
|
T(!sspine_skin_valid(sspine_skin_by_index(skeleton, 0)));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, skin_equal) {
|
||
|
init();
|
||
|
T(sspine_skin_equal((sspine_skin){ 1, 2 }, (sspine_skin){ 1, 2 }));
|
||
|
T(!sspine_skin_equal((sspine_skin){ 2, 2 }, (sspine_skin){ 1, 2 }));
|
||
|
T(!sspine_skin_equal((sspine_skin){ 1, 3 }, (sspine_skin){ 1, 2 }));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, num_skins) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
T(sspine_num_skins(skeleton) == 1);
|
||
|
sspine_destroy_skeleton(skeleton);
|
||
|
T(sspine_num_skins(skeleton) == 0);
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, get_skin_info) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
const sspine_skin_info info = sspine_get_skin_info(sspine_skin_by_index(skeleton, 0));
|
||
|
T(info.valid);
|
||
|
T(0 == info.index);
|
||
|
T(0 == strcmp(info.name.cstr, "default"));
|
||
|
shutdown();
|
||
|
}
|
||
|
|
||
|
UTEST(sokol_spine, get_skin_info_destroyed_skeleton) {
|
||
|
init();
|
||
|
sspine_skeleton skeleton = create_skeleton();
|
||
|
sspine_destroy_skeleton(skeleton);
|
||
|
const sspine_skin_info info = sspine_get_skin_info(sspine_skin_by_index(skeleton, 0));
|
||
|
T(!info.valid);
|
||
|
T(!info.name.valid);
|
||
|
shutdown();
|
||
|
}
|