diff --git a/spine-c/CMakeLists.txt b/spine-c/CMakeLists.txt index 0e568171b..7665929c8 100644 --- a/spine-c/CMakeLists.txt +++ b/spine-c/CMakeLists.txt @@ -14,11 +14,8 @@ add_subdirectory(../spine-cpp ${CMAKE_CURRENT_BINARY_DIR}/spine-cpp) file(GLOB SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.c" "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp" -) -file(GLOB GENERATED_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/generated/*.cpp" ) -list(APPEND SOURCES ${GENERATED_SOURCES}) # Create the library add_library(spine-c STATIC ${SOURCES}) @@ -42,7 +39,6 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # Create test executable only if this is the top-level project if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) - add_executable(spine-c-test test/test.c) - target_link_libraries(spine-c-test spine-c) - target_include_directories(spine-c-test PRIVATE include) -endif() \ No newline at end of file + add_executable(debug-printer ${CMAKE_CURRENT_SOURCE_DIR}/tests/debug-printer.c) + target_link_libraries(debug-printer spine-c) +endif() diff --git a/spine-c/codegen/spine-cpp-types.json b/spine-c/codegen/spine-cpp-types.json index b9a540e7a..c3eadfc26 100644 --- a/spine-c/codegen/spine-cpp-types.json +++ b/spine-c/codegen/spine-cpp-types.json @@ -25270,7 +25270,7 @@ { "kind": "method", "name": "getPath", - "returnType": "String", + "returnType": "String &", "parameters": [ { "name": "basePath", @@ -25435,7 +25435,7 @@ } ], "loc": { - "line": 90, + "line": 91, "col": 7 } } diff --git a/spine-c/codegen/src/c-writer.ts b/spine-c/codegen/src/c-writer.ts index 65b003578..2a9aa06b7 100644 --- a/spine-c/codegen/src/c-writer.ts +++ b/spine-c/codegen/src/c-writer.ts @@ -3,7 +3,7 @@ import * as path from 'path'; import { Type, toSnakeCase } from './types'; import { CClassOrStruct, CEnum, CMethod, CParameter } from './c-types'; -const LICENSE_HEADER = fs.readFileSync(path.join(__dirname, '../../../spine-cpp/spine-cpp/src/spine/Skeleton.cpp'), 'utf8').split('\n').slice(0, 28).join('\n'); +const LICENSE_HEADER = fs.readFileSync(path.join(__dirname, '../../../spine-cpp/src/spine/Skeleton.cpp'), 'utf8').split('\n').slice(0, 28).join('\n'); /** Generates strings for CClassOrStruct and CEnum, and writes them to files. */ export class CWriter { diff --git a/spine-c/codegen/src/ir-generator.ts b/spine-c/codegen/src/ir-generator.ts index f100bdbd1..2a63ec1ee 100644 --- a/spine-c/codegen/src/ir-generator.ts +++ b/spine-c/codegen/src/ir-generator.ts @@ -178,7 +178,7 @@ export function generateMethods(type: ClassOrStruct, knownTypeNames: Set for (const [methodName, methodOverloads] of methodsByName) { // Special handling for methods named "create" to avoid conflicts with constructors const isCreateMethod = methodName === 'create'; - + if (methodOverloads.length === 1 && !isCreateMethod) { // No overloads and not a create method, use standard name const cMethod = generateMethod(type, methodOverloads[0], cTypeName, cppTypeName, knownTypeNames); @@ -713,8 +713,13 @@ function generateReturnStatement(returnType: string, methodCall: string, knownTy return `${methodCall};`; } - // Handle String returns - if (returnType === 'String' || returnType === 'const String' || returnType === 'const String&') { + // Handle String returns (with or without space before &) + if (returnType === 'String' || returnType === 'const String') { + // error! + throw new Error(`String return type not supported: ${returnType}`); + } + + if(returnType === 'const String&' || returnType === 'const String &') { return `return ${methodCall}.buffer();`; } diff --git a/spine-c/codegen/src/type-extractor.ts b/spine-c/codegen/src/type-extractor.ts index 2021a7a42..9a90f2c2c 100644 --- a/spine-c/codegen/src/type-extractor.ts +++ b/spine-c/codegen/src/type-extractor.ts @@ -4,7 +4,7 @@ import { execSync } from 'child_process'; import { Type, Member, Method, Field, Constructor, Destructor, Parameter, EnumValue, ClassOrStruct, Enum } from './types'; const SPINE_CPP_PATH = path.join(__dirname, '../../../spine-cpp'); -const SPINE_INCLUDE_DIR = path.join(SPINE_CPP_PATH, 'spine-cpp/include'); +const SPINE_INCLUDE_DIR = path.join(SPINE_CPP_PATH, 'include'); const OUTPUT_FILE = path.join(__dirname, '../spine-cpp-types.json'); /** @@ -493,7 +493,7 @@ function addInheritedMethods(type: ClassOrStruct & { inheritedMethodsAdded: bool if (type.inheritedMethodsAdded) { return; } - + const inheritedMethods: Member[] = []; const ownMethodSignatures = new Set(); @@ -560,7 +560,7 @@ function addInheritedMethods(type: ClassOrStruct & { inheritedMethodsAdded: bool if (type.members) { type.members.push(...inheritedMethods); } - + // Mark as processed type.inheritedMethodsAdded = true; } diff --git a/spine-c/src/extensions.cpp b/spine-c/src/extensions.cpp index da2bbdd2c..ce28e4f4a 100644 --- a/spine-c/src/extensions.cpp +++ b/spine-c/src/extensions.cpp @@ -275,7 +275,7 @@ void spine_atlas_dispose(spine_atlas atlas) { } // Skeleton data loading -spine_skeleton_data_result spine_skeleton_data_load_json(spine_atlas atlas, const char *skeletonData) { +spine_skeleton_data_result spine_skeleton_data_load_json(spine_atlas atlas, const char *skeletonData, const char *path) { if (!atlas || !skeletonData) return nullptr; _spine_skeleton_data_result *result = SpineExtension::calloc<_spine_skeleton_data_result>(1, __FILE__, __LINE__); SkeletonJson json((Atlas *) ((_spine_atlas *) atlas)->atlas); @@ -287,11 +287,30 @@ spine_skeleton_data_result spine_skeleton_data_load_json(spine_atlas atlas, cons return (spine_skeleton_data_result) result; } + // Set name from path if provided + if (path != nullptr) { + // Extract filename without extension from path + const char *lastSlash = strrchr(path, '/'); + const char *lastBackslash = strrchr(path, '\\'); + const char *start = path; + + if (lastSlash != nullptr) start = lastSlash + 1; + if (lastBackslash != nullptr && lastBackslash > start) start = lastBackslash + 1; + + const char *lastDot = strrchr(start, '.'); + if (lastDot != nullptr) { + int length = lastDot - start; + data->setName(String(start, length)); + } else { + data->setName(String(start)); + } + } + result->skeletonData = (spine_skeleton_data) data; return (spine_skeleton_data_result) result; } -spine_skeleton_data_result spine_skeleton_data_load_binary(spine_atlas atlas, const uint8_t *skeletonData, int32_t length) { +spine_skeleton_data_result spine_skeleton_data_load_binary(spine_atlas atlas, const uint8_t *skeletonData, int32_t length, const char *path) { if (!atlas || !skeletonData) return nullptr; _spine_skeleton_data_result *result = SpineExtension::calloc<_spine_skeleton_data_result>(1, __FILE__, __LINE__); SkeletonBinary binary((Atlas *) ((_spine_atlas *) atlas)->atlas); @@ -303,6 +322,25 @@ spine_skeleton_data_result spine_skeleton_data_load_binary(spine_atlas atlas, co return (spine_skeleton_data_result) result; } + // Set name from path if provided + if (path != nullptr) { + // Extract filename without extension from path + const char *lastSlash = strrchr(path, '/'); + const char *lastBackslash = strrchr(path, '\\'); + const char *start = path; + + if (lastSlash != nullptr) start = lastSlash + 1; + if (lastBackslash != nullptr && lastBackslash > start) start = lastBackslash + 1; + + const char *lastDot = strrchr(start, '.'); + if (lastDot != nullptr) { + int length = lastDot - start; + data->setName(String(start, length)); + } else { + data->setName(String(start)); + } + } + result->skeletonData = (spine_skeleton_data) data; return (spine_skeleton_data_result) result; } diff --git a/spine-c/src/extensions.h b/spine-c/src/extensions.h index 33dbb53cc..324b3e821 100644 --- a/spine-c/src/extensions.h +++ b/spine-c/src/extensions.h @@ -82,8 +82,8 @@ SPINE_C_API const char *spine_atlas_get_error(spine_atlas atlas); SPINE_C_API void spine_atlas_dispose(spine_atlas atlas); // Skeleton data functions -SPINE_C_API spine_skeleton_data_result spine_skeleton_data_load_json(spine_atlas atlas, const char *skeletonData); -SPINE_C_API spine_skeleton_data_result spine_skeleton_data_load_binary(spine_atlas atlas, const uint8_t *skeletonData, int32_t length); +SPINE_C_API spine_skeleton_data_result spine_skeleton_data_load_json(spine_atlas atlas, const char *skeletonData, const char *path); +SPINE_C_API spine_skeleton_data_result spine_skeleton_data_load_binary(spine_atlas atlas, const uint8_t *skeletonData, int32_t length, const char *path); SPINE_C_API const char *spine_skeleton_data_result_get_error(spine_skeleton_data_result result); SPINE_C_API spine_skeleton_data spine_skeleton_data_result_get_data(spine_skeleton_data_result result); SPINE_C_API void spine_skeleton_data_result_dispose(spine_skeleton_data_result result); diff --git a/spine-c/src/generated/animation.cpp b/spine-c/src/generated/animation.cpp index 0ed8eea2a..798803096 100644 --- a/spine-c/src/generated/animation.cpp +++ b/spine-c/src/generated/animation.cpp @@ -36,7 +36,7 @@ void spine_animation_apply(spine_animation self, spine_skeleton skeleton, float } const char* spine_animation_get_name(spine_animation self) { - return (const char*)&((Animation*)self)->getName(); + return ((Animation*)self)->getName().buffer(); } spine_array_int spine_animation_get_bones(spine_animation self) { diff --git a/spine-c/src/generated/attachment.cpp b/spine-c/src/generated/attachment.cpp index 24b74e217..d8dc82f03 100644 --- a/spine-c/src/generated/attachment.cpp +++ b/spine-c/src/generated/attachment.cpp @@ -12,7 +12,7 @@ spine_rtti spine_attachment_get_rtti(spine_attachment self) { } const char* spine_attachment_get_name(spine_attachment self) { - return (const char*)&((Attachment*)self)->getName(); + return ((Attachment*)self)->getName().buffer(); } spine_attachment spine_attachment_copy(spine_attachment self) { diff --git a/spine-c/src/generated/bone_data.cpp b/spine-c/src/generated/bone_data.cpp index 839281b6f..dd94369be 100644 --- a/spine-c/src/generated/bone_data.cpp +++ b/spine-c/src/generated/bone_data.cpp @@ -32,7 +32,7 @@ spine_color spine_bone_data_get_color(spine_bone_data self) { } const char* spine_bone_data_get_icon(spine_bone_data self) { - return (const char*)&((BoneData*)self)->getIcon(); + return ((BoneData*)self)->getIcon().buffer(); } void spine_bone_data_set_icon(spine_bone_data self, const char* icon) { @@ -52,7 +52,7 @@ spine_bone_local spine_bone_data_get_setup_pose(spine_bone_data self) { } const char* spine_bone_data_get_name(spine_bone_data self) { - return (const char*)&((PosedDataGeneric*)(BoneData*)self)->getName(); + return ((PosedDataGeneric*)(BoneData*)self)->getName().buffer(); } bool spine_bone_data_is_skin_required(spine_bone_data self) { diff --git a/spine-c/src/generated/bounding_box_attachment.cpp b/spine-c/src/generated/bounding_box_attachment.cpp index 915a74c6b..a8141ad2a 100644 --- a/spine-c/src/generated/bounding_box_attachment.cpp +++ b/spine-c/src/generated/bounding_box_attachment.cpp @@ -72,7 +72,7 @@ void spine_bounding_box_attachment_copy_to(spine_bounding_box_attachment self, s } const char* spine_bounding_box_attachment_get_name(spine_bounding_box_attachment self) { - return (const char*)&((VertexAttachment*)(BoundingBoxAttachment*)self)->getName(); + return ((VertexAttachment*)(BoundingBoxAttachment*)self)->getName().buffer(); } int spine_bounding_box_attachment_get_ref_count(spine_bounding_box_attachment self) { diff --git a/spine-c/src/generated/clipping_attachment.cpp b/spine-c/src/generated/clipping_attachment.cpp index cde2f0e04..d2a0cd161 100644 --- a/spine-c/src/generated/clipping_attachment.cpp +++ b/spine-c/src/generated/clipping_attachment.cpp @@ -80,7 +80,7 @@ void spine_clipping_attachment_copy_to(spine_clipping_attachment self, spine_ver } const char* spine_clipping_attachment_get_name(spine_clipping_attachment self) { - return (const char*)&((VertexAttachment*)(ClippingAttachment*)self)->getName(); + return ((VertexAttachment*)(ClippingAttachment*)self)->getName().buffer(); } int spine_clipping_attachment_get_ref_count(spine_clipping_attachment self) { diff --git a/spine-c/src/generated/constraint_data.cpp b/spine-c/src/generated/constraint_data.cpp index f981678cd..6414b3dba 100644 --- a/spine-c/src/generated/constraint_data.cpp +++ b/spine-c/src/generated/constraint_data.cpp @@ -16,7 +16,7 @@ spine_constraint spine_constraint_data_create_method(spine_constraint_data self, } const char* spine_constraint_data_get_name(spine_constraint_data self) { - return (const char*)&((ConstraintData*)self)->getName(); + return ((ConstraintData*)self)->getName().buffer(); } bool spine_constraint_data_is_skin_required(spine_constraint_data self) { diff --git a/spine-c/src/generated/event.cpp b/spine-c/src/generated/event.cpp index 0f1c619f6..b35be219d 100644 --- a/spine-c/src/generated/event.cpp +++ b/spine-c/src/generated/event.cpp @@ -36,7 +36,7 @@ void spine_event_set_float(spine_event self, float inValue) { } const char* spine_event_get_string(spine_event self) { - return (const char*)&((Event*)self)->getString(); + return ((Event*)self)->getString().buffer(); } void spine_event_set_string(spine_event self, const char* inValue) { diff --git a/spine-c/src/generated/event_data.cpp b/spine-c/src/generated/event_data.cpp index 3866e698c..21967b80e 100644 --- a/spine-c/src/generated/event_data.cpp +++ b/spine-c/src/generated/event_data.cpp @@ -12,7 +12,7 @@ void spine_event_data_dispose(spine_event_data self) { } const char* spine_event_data_get_name(spine_event_data self) { - return (const char*)&((EventData*)self)->getName(); + return ((EventData*)self)->getName().buffer(); } int spine_event_data_get_int_value(spine_event_data self) { @@ -32,7 +32,7 @@ void spine_event_data_set_float_value(spine_event_data self, float inValue) { } const char* spine_event_data_get_string_value(spine_event_data self) { - return (const char*)&((EventData*)self)->getStringValue(); + return ((EventData*)self)->getStringValue().buffer(); } void spine_event_data_set_string_value(spine_event_data self, const char* inValue) { @@ -40,7 +40,7 @@ void spine_event_data_set_string_value(spine_event_data self, const char* inValu } const char* spine_event_data_get_audio_path(spine_event_data self) { - return (const char*)&((EventData*)self)->getAudioPath(); + return ((EventData*)self)->getAudioPath().buffer(); } void spine_event_data_set_audio_path(spine_event_data self, const char* inValue) { diff --git a/spine-c/src/generated/ik_constraint_data.cpp b/spine-c/src/generated/ik_constraint_data.cpp index b53b9296c..67927016d 100644 --- a/spine-c/src/generated/ik_constraint_data.cpp +++ b/spine-c/src/generated/ik_constraint_data.cpp @@ -40,7 +40,7 @@ void spine_ik_constraint_data_set_uniform(spine_ik_constraint_data self, bool un } const char* spine_ik_constraint_data_get_name(spine_ik_constraint_data self) { - return (const char*)&((ConstraintDataGeneric*)(IkConstraintData*)self)->getName(); + return ((ConstraintDataGeneric*)(IkConstraintData*)self)->getName().buffer(); } bool spine_ik_constraint_data_is_skin_required(spine_ik_constraint_data self) { diff --git a/spine-c/src/generated/mesh_attachment.cpp b/spine-c/src/generated/mesh_attachment.cpp index 450b40582..48c34fc82 100644 --- a/spine-c/src/generated/mesh_attachment.cpp +++ b/spine-c/src/generated/mesh_attachment.cpp @@ -60,7 +60,7 @@ spine_color spine_mesh_attachment_get_color(spine_mesh_attachment self) { } const char* spine_mesh_attachment_get_path(spine_mesh_attachment self) { - return (const char*)&((MeshAttachment*)self)->getPath(); + return ((MeshAttachment*)self)->getPath().buffer(); } void spine_mesh_attachment_set_path(spine_mesh_attachment self, const char* inValue) { @@ -164,7 +164,7 @@ void spine_mesh_attachment_copy_to(spine_mesh_attachment self, spine_vertex_atta } const char* spine_mesh_attachment_get_name(spine_mesh_attachment self) { - return (const char*)&((VertexAttachment*)(MeshAttachment*)self)->getName(); + return ((VertexAttachment*)(MeshAttachment*)self)->getName().buffer(); } int spine_mesh_attachment_get_ref_count(spine_mesh_attachment self) { diff --git a/spine-c/src/generated/path_attachment.cpp b/spine-c/src/generated/path_attachment.cpp index 419513b54..b9d078ed5 100644 --- a/spine-c/src/generated/path_attachment.cpp +++ b/spine-c/src/generated/path_attachment.cpp @@ -96,7 +96,7 @@ void spine_path_attachment_copy_to(spine_path_attachment self, spine_vertex_atta } const char* spine_path_attachment_get_name(spine_path_attachment self) { - return (const char*)&((VertexAttachment*)(PathAttachment*)self)->getName(); + return ((VertexAttachment*)(PathAttachment*)self)->getName().buffer(); } int spine_path_attachment_get_ref_count(spine_path_attachment self) { diff --git a/spine-c/src/generated/path_constraint_data.cpp b/spine-c/src/generated/path_constraint_data.cpp index dccd2301e..f6300fda5 100644 --- a/spine-c/src/generated/path_constraint_data.cpp +++ b/spine-c/src/generated/path_constraint_data.cpp @@ -64,7 +64,7 @@ void spine_path_constraint_data_set_offset_rotation(spine_path_constraint_data s } const char* spine_path_constraint_data_get_name(spine_path_constraint_data self) { - return (const char*)&((ConstraintDataGeneric*)(PathConstraintData*)self)->getName(); + return ((ConstraintDataGeneric*)(PathConstraintData*)self)->getName().buffer(); } bool spine_path_constraint_data_is_skin_required(spine_path_constraint_data self) { diff --git a/spine-c/src/generated/physics_constraint_data.cpp b/spine-c/src/generated/physics_constraint_data.cpp index ca2a8307d..54d4ac009 100644 --- a/spine-c/src/generated/physics_constraint_data.cpp +++ b/spine-c/src/generated/physics_constraint_data.cpp @@ -140,7 +140,7 @@ void spine_physics_constraint_data_set_mix_global(spine_physics_constraint_data } const char* spine_physics_constraint_data_get_name(spine_physics_constraint_data self) { - return (const char*)&((ConstraintDataGeneric*)(PhysicsConstraintData*)self)->getName(); + return ((ConstraintDataGeneric*)(PhysicsConstraintData*)self)->getName().buffer(); } bool spine_physics_constraint_data_is_skin_required(spine_physics_constraint_data self) { diff --git a/spine-c/src/generated/point_attachment.cpp b/spine-c/src/generated/point_attachment.cpp index 9177d00f6..a5907883f 100644 --- a/spine-c/src/generated/point_attachment.cpp +++ b/spine-c/src/generated/point_attachment.cpp @@ -56,7 +56,7 @@ spine_attachment spine_point_attachment_copy(spine_point_attachment self) { } const char* spine_point_attachment_get_name(spine_point_attachment self) { - return (const char*)&((Attachment*)(PointAttachment*)self)->getName(); + return ((Attachment*)(PointAttachment*)self)->getName().buffer(); } int spine_point_attachment_get_ref_count(spine_point_attachment self) { diff --git a/spine-c/src/generated/posed_data.cpp b/spine-c/src/generated/posed_data.cpp index 6e58004a2..8df5da80b 100644 --- a/spine-c/src/generated/posed_data.cpp +++ b/spine-c/src/generated/posed_data.cpp @@ -12,7 +12,7 @@ void spine_posed_data_dispose(spine_posed_data self) { } const char* spine_posed_data_get_name(spine_posed_data self) { - return (const char*)&((PosedData*)self)->getName(); + return ((PosedData*)self)->getName().buffer(); } bool spine_posed_data_is_skin_required(spine_posed_data self) { diff --git a/spine-c/src/generated/region_attachment.cpp b/spine-c/src/generated/region_attachment.cpp index f1c89b86c..a2538472c 100644 --- a/spine-c/src/generated/region_attachment.cpp +++ b/spine-c/src/generated/region_attachment.cpp @@ -88,7 +88,7 @@ spine_color spine_region_attachment_get_color(spine_region_attachment self) { } const char* spine_region_attachment_get_path(spine_region_attachment self) { - return (const char*)&((RegionAttachment*)self)->getPath(); + return ((RegionAttachment*)self)->getPath().buffer(); } void spine_region_attachment_set_path(spine_region_attachment self, const char* inValue) { @@ -124,7 +124,7 @@ spine_attachment spine_region_attachment_copy(spine_region_attachment self) { } const char* spine_region_attachment_get_name(spine_region_attachment self) { - return (const char*)&((Attachment*)(RegionAttachment*)self)->getName(); + return ((Attachment*)(RegionAttachment*)self)->getName().buffer(); } int spine_region_attachment_get_ref_count(spine_region_attachment self) { diff --git a/spine-c/src/generated/sequence.cpp b/spine-c/src/generated/sequence.cpp index 56315ca41..c31b008fb 100644 --- a/spine-c/src/generated/sequence.cpp +++ b/spine-c/src/generated/sequence.cpp @@ -20,7 +20,7 @@ void spine_sequence_apply(spine_sequence self, spine_slot_pose slot, spine_attac } const char* spine_sequence_get_path(spine_sequence self, const char* basePath, int index) { - return ((Sequence*)self)->getPath(String(basePath), index).buffer(); + return (const char*)&((Sequence*)self)->getPath(String(basePath), index); } int spine_sequence_get_id(spine_sequence self) { diff --git a/spine-c/src/generated/skeleton_binary.cpp b/spine-c/src/generated/skeleton_binary.cpp index def39595e..a59d9477f 100644 --- a/spine-c/src/generated/skeleton_binary.cpp +++ b/spine-c/src/generated/skeleton_binary.cpp @@ -28,5 +28,5 @@ void spine_skeleton_binary_set_scale(spine_skeleton_binary self, float scale) { } const char* spine_skeleton_binary_get_error(spine_skeleton_binary self) { - return (const char*)&((SkeletonBinary*)self)->getError(); + return ((SkeletonBinary*)self)->getError().buffer(); } diff --git a/spine-c/src/generated/skeleton_data.cpp b/spine-c/src/generated/skeleton_data.cpp index 823abe907..4145c6547 100644 --- a/spine-c/src/generated/skeleton_data.cpp +++ b/spine-c/src/generated/skeleton_data.cpp @@ -32,7 +32,7 @@ spine_animation spine_skeleton_data_find_animation(spine_skeleton_data self, con } const char* spine_skeleton_data_get_name(spine_skeleton_data self) { - return (const char*)&((SkeletonData*)self)->getName(); + return ((SkeletonData*)self)->getName().buffer(); } void spine_skeleton_data_set_name(spine_skeleton_data self, const char* inValue) { @@ -112,7 +112,7 @@ void spine_skeleton_data_set_reference_scale(spine_skeleton_data self, float inV } const char* spine_skeleton_data_get_version(spine_skeleton_data self) { - return (const char*)&((SkeletonData*)self)->getVersion(); + return ((SkeletonData*)self)->getVersion().buffer(); } void spine_skeleton_data_set_version(spine_skeleton_data self, const char* inValue) { @@ -120,7 +120,7 @@ void spine_skeleton_data_set_version(spine_skeleton_data self, const char* inVal } const char* spine_skeleton_data_get_hash(spine_skeleton_data self) { - return (const char*)&((SkeletonData*)self)->getHash(); + return ((SkeletonData*)self)->getHash().buffer(); } void spine_skeleton_data_set_hash(spine_skeleton_data self, const char* inValue) { @@ -128,7 +128,7 @@ void spine_skeleton_data_set_hash(spine_skeleton_data self, const char* inValue) } const char* spine_skeleton_data_get_images_path(spine_skeleton_data self) { - return (const char*)&((SkeletonData*)self)->getImagesPath(); + return ((SkeletonData*)self)->getImagesPath().buffer(); } void spine_skeleton_data_set_images_path(spine_skeleton_data self, const char* inValue) { @@ -136,7 +136,7 @@ void spine_skeleton_data_set_images_path(spine_skeleton_data self, const char* i } const char* spine_skeleton_data_get_audio_path(spine_skeleton_data self) { - return (const char*)&((SkeletonData*)self)->getAudioPath(); + return ((SkeletonData*)self)->getAudioPath().buffer(); } void spine_skeleton_data_set_audio_path(spine_skeleton_data self, const char* inValue) { diff --git a/spine-c/src/generated/skeleton_json.cpp b/spine-c/src/generated/skeleton_json.cpp index 2116a79d2..ddd92cf58 100644 --- a/spine-c/src/generated/skeleton_json.cpp +++ b/spine-c/src/generated/skeleton_json.cpp @@ -28,5 +28,5 @@ void spine_skeleton_json_set_scale(spine_skeleton_json self, float scale) { } const char* spine_skeleton_json_get_error(spine_skeleton_json self) { - return (const char*)&((SkeletonJson*)self)->getError(); + return ((SkeletonJson*)self)->getError().buffer(); } diff --git a/spine-c/src/generated/skin.cpp b/spine-c/src/generated/skin.cpp index 468b64634..e7581c1d7 100644 --- a/spine-c/src/generated/skin.cpp +++ b/spine-c/src/generated/skin.cpp @@ -28,7 +28,7 @@ void spine_skin_find_attachments_for_slot(spine_skin self, size_t slotIndex, spi } const char* spine_skin_get_name(spine_skin self) { - return (const char*)&((Skin*)self)->getName(); + return ((Skin*)self)->getName().buffer(); } void spine_skin_add_skin(spine_skin self, spine_skin other) { diff --git a/spine-c/src/generated/slider_data.cpp b/spine-c/src/generated/slider_data.cpp index 94a255c52..8d1a41c58 100644 --- a/spine-c/src/generated/slider_data.cpp +++ b/spine-c/src/generated/slider_data.cpp @@ -84,7 +84,7 @@ void spine_slider_data_set_local(spine_slider_data self, bool local) { } const char* spine_slider_data_get_name(spine_slider_data self) { - return (const char*)&((ConstraintDataGeneric*)(SliderData*)self)->getName(); + return ((ConstraintDataGeneric*)(SliderData*)self)->getName().buffer(); } bool spine_slider_data_is_skin_required(spine_slider_data self) { diff --git a/spine-c/src/generated/slot_data.cpp b/spine-c/src/generated/slot_data.cpp index 587732497..81b400680 100644 --- a/spine-c/src/generated/slot_data.cpp +++ b/spine-c/src/generated/slot_data.cpp @@ -24,7 +24,7 @@ void spine_slot_data_set_attachment_name(spine_slot_data self, const char* attac } const char* spine_slot_data_get_attachment_name(spine_slot_data self) { - return (const char*)&((SlotData*)self)->getAttachmentName(); + return ((SlotData*)self)->getAttachmentName().buffer(); } spine_blend_mode spine_slot_data_get_blend_mode(spine_slot_data self) { @@ -48,7 +48,7 @@ spine_slot_pose spine_slot_data_get_setup_pose(spine_slot_data self) { } const char* spine_slot_data_get_name(spine_slot_data self) { - return (const char*)&((PosedDataGeneric*)(SlotData*)self)->getName(); + return ((PosedDataGeneric*)(SlotData*)self)->getName().buffer(); } bool spine_slot_data_is_skin_required(spine_slot_data self) { diff --git a/spine-c/src/generated/transform_constraint_data.cpp b/spine-c/src/generated/transform_constraint_data.cpp index 0c57ce26b..7cd9e6d8c 100644 --- a/spine-c/src/generated/transform_constraint_data.cpp +++ b/spine-c/src/generated/transform_constraint_data.cpp @@ -116,7 +116,7 @@ spine_array_from_property spine_transform_constraint_data_get_properties(spine_t } const char* spine_transform_constraint_data_get_name(spine_transform_constraint_data self) { - return (const char*)&((ConstraintDataGeneric*)(TransformConstraintData*)self)->getName(); + return ((ConstraintDataGeneric*)(TransformConstraintData*)self)->getName().buffer(); } bool spine_transform_constraint_data_is_skin_required(spine_transform_constraint_data self) { diff --git a/spine-c/src/generated/vertex_attachment.cpp b/spine-c/src/generated/vertex_attachment.cpp index 6f6f61acb..9773a5075 100644 --- a/spine-c/src/generated/vertex_attachment.cpp +++ b/spine-c/src/generated/vertex_attachment.cpp @@ -60,7 +60,7 @@ void spine_vertex_attachment_copy_to(spine_vertex_attachment self, spine_vertex_ } const char* spine_vertex_attachment_get_name(spine_vertex_attachment self) { - return (const char*)&((Attachment*)(VertexAttachment*)self)->getName(); + return ((Attachment*)(VertexAttachment*)self)->getName().buffer(); } spine_attachment spine_vertex_attachment_copy(spine_vertex_attachment self) { diff --git a/spine-c/test/test.c b/spine-c/test/test.c deleted file mode 100644 index 9a3e5dfee..000000000 --- a/spine-c/test/test.c +++ /dev/null @@ -1,26 +0,0 @@ -#include -#include -#include - -int main(int argc, char *argv[]) { - printf("Testing spine-c-new...\n"); - - // Test version functions - printf("Spine version: %d.%d\n", spine_major_version(), spine_minor_version()); - - // Test debug extension - spine_enable_debug_extension(1); - - // Test loading an atlas (will fail but tests the API) - spine_atlas atlas = spine_atlas_load("test.atlas"); - if (!atlas) { - printf("Failed to load atlas (expected)\n"); - } else { - spine_atlas_dispose(atlas); - } - - // Report any memory leaks - spine_report_leaks(); - - return 0; -} diff --git a/spine-c/tests/debug-printer.c b/spine-c/tests/debug-printer.c new file mode 100644 index 000000000..e32ea3d5e --- /dev/null +++ b/spine-c/tests/debug-printer.c @@ -0,0 +1,245 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated April 5, 2025. Replaces all prior versions. + * + * Copyright (c) 2013-2025, Esoteric Software LLC + * + * Integration of the Spine Runtimes into software or otherwise creating + * derivative works of the Spine Runtimes is permitted under the terms and + * conditions of Section 2 of the Spine Editor License Agreement: + * http://esotericsoftware.com/spine-editor-license + * + * Otherwise, it is permitted to integrate the Spine Runtimes into software + * or otherwise create derivative works of the Spine Runtimes (collectively, + * "Products"), provided that each user of the Products must obtain their own + * Spine Editor license and redistribution of the Products in any form must + * include this license and copyright notice. + * + * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, + * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#include +#include +#include +#include +#include + +// Custom texture loader that doesn't load actual textures +void *headlessTextureLoader(const char *path) { + // Don't load actual texture, just return a dummy pointer + return (void *) 1; +} + +void headlessTextureUnloader(void *texture) { + // Nothing to do +} + +// Printer functions +static int indentLevel = 0; +static const char *INDENT = " "; + +void print_indent(const char *format, ...) { + for (int i = 0; i < indentLevel; i++) { + printf("%s", INDENT); + } + va_list args; + va_start(args, format); + vprintf(format, args); + va_end(args); + printf("\n"); +} + +void indent(void) { + indentLevel++; +} + +void unindent(void) { + indentLevel--; +} + +void printSkeletonData(spine_skeleton_data data) { + print_indent("SkeletonData {"); + indent(); + + const char *name = spine_skeleton_data_get_name(data); + const char *version = spine_skeleton_data_get_version(data); + const char *hash = spine_skeleton_data_get_hash(data); + const char *imagesPath = spine_skeleton_data_get_images_path(data); + const char *audioPath = spine_skeleton_data_get_audio_path(data); + + print_indent("name: \"%s\"", name ? name : ""); + print_indent("version: \"%s\"", version ? version : ""); + print_indent("hash: \"%s\"", hash ? hash : ""); + print_indent("x: %.6f", spine_skeleton_data_get_x(data)); + print_indent("y: %.6f", spine_skeleton_data_get_y(data)); + print_indent("width: %.6f", spine_skeleton_data_get_width(data)); + print_indent("height: %.6f", spine_skeleton_data_get_height(data)); + print_indent("referenceScale: %.6f", spine_skeleton_data_get_reference_scale(data)); + print_indent("fps: %.6f", spine_skeleton_data_get_fps(data)); + print_indent("imagesPath: \"%s\"", imagesPath ? imagesPath : ""); + print_indent("audioPath: \"%s\"", audioPath ? audioPath : ""); + + // TODO: Add bones, slots, skins, animations, etc. in future expansion + + unindent(); + print_indent("}"); +} + +void printSkeleton(spine_skeleton skeleton) { + print_indent("Skeleton {"); + indent(); + + print_indent("x: %.6f", spine_skeleton_get_x(skeleton)); + print_indent("y: %.6f", spine_skeleton_get_y(skeleton)); + print_indent("scaleX: %.6f", spine_skeleton_get_scale_x(skeleton)); + print_indent("scaleY: %.6f", spine_skeleton_get_scale_y(skeleton)); + print_indent("time: %.6f", spine_skeleton_get_time(skeleton)); + + // TODO: Add runtime state (bones, slots, etc.) in future expansion + + unindent(); + print_indent("}"); +} + +// Helper function to read file contents +uint8_t *read_file(const char *path, int *length) { + FILE *file = fopen(path, "rb"); + if (!file) return NULL; + + fseek(file, 0, SEEK_END); + *length = (int) ftell(file); + fseek(file, 0, SEEK_SET); + + uint8_t *data = (uint8_t *) malloc(*length + 1); + fread(data, 1, *length, file); + data[*length] = '\0'; + fclose(file); + + return data; +} + +int main(int argc, char *argv[]) { + if (argc < 4) { + fprintf(stderr, "Usage: DebugPrinter \n"); + return 1; + } + + const char *skeletonPath = argv[1]; + const char *atlasPath = argv[2]; + const char *animationName = argv[3]; + + // Read atlas file + int atlasLength = 0; + uint8_t *atlasBytes = read_file(atlasPath, &atlasLength); + if (!atlasBytes) { + fprintf(stderr, "Failed to read atlas file\n"); + return 1; + } + + // Extract directory from atlas path for texture loading + char atlasDir[1024] = ""; + const char *lastSlash = strrchr(atlasPath, '/'); + if (lastSlash) { + int dirLen = lastSlash - atlasPath + 1; + strncpy(atlasDir, atlasPath, dirLen); + atlasDir[dirLen] = '\0'; + } + + // Load atlas with headless texture loader + spine_atlas atlas = spine_atlas_load_callback((const char *) atlasBytes, atlasDir, + headlessTextureLoader, headlessTextureUnloader); + free(atlasBytes); + + if (!atlas) { + fprintf(stderr, "Failed to load atlas\n"); + return 1; + } + + // Load skeleton data + spine_skeleton_data_result result = {0}; + spine_skeleton_data skeletonData = NULL; + + if (strstr(skeletonPath, ".json") != NULL) { + int skeletonLength = 0; + uint8_t *skeletonBytes = read_file(skeletonPath, &skeletonLength); + if (!skeletonBytes) { + fprintf(stderr, "Failed to read skeleton file\n"); + spine_atlas_dispose(atlas); + return 1; + } + result = spine_skeleton_data_load_json(atlas, (const char *) skeletonBytes, skeletonPath); + free(skeletonBytes); + } else { + int skeletonLength = 0; + uint8_t *skeletonBytes = read_file(skeletonPath, &skeletonLength); + if (!skeletonBytes) { + fprintf(stderr, "Failed to read skeleton file\n"); + spine_atlas_dispose(atlas); + return 1; + } + result = spine_skeleton_data_load_binary(atlas, skeletonBytes, skeletonLength, skeletonPath); + free(skeletonBytes); + } + + skeletonData = spine_skeleton_data_result_get_data(result); + if (!skeletonData) { + const char *error = spine_skeleton_data_result_get_error(result); + fprintf(stderr, "Failed to load skeleton data: %s\n", error ? error : "Unknown error"); + spine_skeleton_data_result_dispose(result); + spine_atlas_dispose(atlas); + return 1; + } + + // Print skeleton data + printf("=== SKELETON DATA ===\n"); + printSkeletonData(skeletonData); + + // Create skeleton instance + spine_skeleton skeleton = spine_skeleton_create(skeletonData); + + // Create animation state + spine_animation_state_data stateData = spine_animation_state_data_create(skeletonData); + spine_animation_state state = spine_animation_state_create(stateData); + + // Find and set animation + spine_animation animation = spine_skeleton_data_find_animation(skeletonData, animationName); + if (!animation) { + fprintf(stderr, "Animation not found: %s\n", animationName); + spine_animation_state_dispose(state); + spine_animation_state_data_dispose(stateData); + spine_skeleton_dispose(skeleton); + spine_skeleton_data_result_dispose(result); + spine_atlas_dispose(atlas); + return 1; + } + + spine_animation_state_set_animation_1(state, 0, animationName, 1); + + // Update and apply + spine_animation_state_update(state, 0.016f); + spine_animation_state_apply(state, skeleton); + spine_skeleton_update(skeleton, 0.016f); + spine_skeleton_update_world_transform_1(skeleton, SPINE_PHYSICS_UPDATE); + + // Print skeleton state + printf("\n=== SKELETON STATE ===\n"); + printSkeleton(skeleton); + + // Cleanup + spine_animation_state_dispose(state); + spine_animation_state_data_dispose(stateData); + spine_skeleton_dispose(skeleton); + spine_skeleton_data_result_dispose(result); + spine_atlas_dispose(atlas); + + return 0; +}