This is for anyone who wants to know how to read the data from a Spriter SCML file:
Code: Select all
; ### Key Data Extracted:
;
; **Image Files:**
; - boss_0/boss_torso_0.png (127x146) pivot: 0.5357,0.0909
; - boss_0/boss_thigh_a.png (57x52) pivot: 0.7988,0.7838
; - boss_0/boss_thigh_0.png (39x48) pivot: 0.4035,0.8406
; - ... (28 total image files)
;
; **Sound Files:**
; - sounds/EXPLOD14.wav
; - sounds/BossLaugh.wav
; - sounds/BossHit_1.wav
; - sounds/BossHit_2.wav
; - sounds/FireBreath.wav
;
; **Bone Data:**
; - Bone_001 (boss_torso_0) size: 127.0x146.0
; - Bone_002 (boss_thigh_a) size: 57.0x52.0
; - ... (11 bones total)
;
; **Animation Data:**
; - Animation "Idle" (2000ms)
; - Timeline 0: bone_001 (Boss_0_boss_torso_0)
; - Key @0ms: x=0.00, y=0.00, angle=0.00, scale=1.00
; - Key @128ms: x=0.00, y=0.00, angle=359.00, scale=1.00
; - ... (16 keys)
; - Timeline 24: bone_010
; - Key @0ms: x=19.56, y=18.11, angle=110.66, scale=0.41
; - Key @128ms: x=19.56, y=18.11, angle=106.98, scale=0.41
; - ... (17 keys)
; - ... (26 timelines total)
Structure SpriterFile
id.i
name.s
width.i
height.i
pivot_x.f
pivot_y.f
type.s
EndStructure
Structure SpriterFolder
id.i
name.s
List files.SpriterFile()
EndStructure
Structure SpriterBone
name.s
realname.s
w.f
h.f
EndStructure
Structure SpriterAnimationKey
time.i
x.f
y.f
angle.f
scale_x.f
spin.i
EndStructure
Structure SpriterTimeline
id.i
name.s
obj.s
List keys.SpriterAnimationKey()
EndStructure
Structure SpriterAnimation
name.s
length.i
List timelines.SpriterTimeline()
EndStructure
Structure SpriterEntity
id.i
name.s
List bones.SpriterBone()
List animations.SpriterAnimation()
EndStructure
Global NewList folders.SpriterFolder()
Global NewList entities.SpriterEntity()
Procedure LoadSpriterData(filename.s)
Protected xml = LoadXML(#PB_Any, filename)
If Not xml
Debug "Error loading XML file: " + filename
ProcedureReturn #False
EndIf
Protected *root = MainXMLNode(xml)
If Not *root Or GetXMLNodeName(*root) <> "spriter_data"
Debug "Invalid Spriter file format"
FreeXML(xml)
ProcedureReturn #False
EndIf
; Load folders and files
Protected *folder = ChildXMLNode(*root)
While *folder
If GetXMLNodeName(*folder) = "folder"
AddElement(folders())
folders()\id = Val(GetXMLAttribute(*folder, "id"))
folders()\name = GetXMLAttribute(*folder, "name")
Protected *file = ChildXMLNode(*folder)
While *file
If GetXMLNodeName(*file) = "file"
AddElement(folders()\files())
folders()\files()\id = Val(GetXMLAttribute(*file, "id"))
folders()\files()\name = GetXMLAttribute(*file, "name")
folders()\files()\width = Val(GetXMLAttribute(*file, "width"))
folders()\files()\height = Val(GetXMLAttribute(*file, "height"))
folders()\files()\pivot_x = ValF(GetXMLAttribute(*file, "pivot_x"))
folders()\files()\pivot_y = ValF(GetXMLAttribute(*file, "pivot_y"))
folders()\files()\type = GetXMLAttribute(*file, "type")
EndIf
*file = NextXMLNode(*file)
Wend
EndIf
*folder = NextXMLNode(*folder)
Wend
; Load entities, bones and animations
*folder = ChildXMLNode(*root)
While *folder
If GetXMLNodeName(*folder) = "entity"
AddElement(entities())
entities()\id = Val(GetXMLAttribute(*folder, "id"))
entities()\name = GetXMLAttribute(*folder, "name")
Protected *obj = ChildXMLNode(*folder)
While *obj
Select GetXMLNodeName(*obj)
Case "obj_info"
Protected type.s = GetXMLAttribute(*obj, "type")
If type = "bone"
AddElement(entities()\bones())
entities()\bones()\name = GetXMLAttribute(*obj, "name")
entities()\bones()\realname = GetXMLAttribute(*obj, "realname")
entities()\bones()\w = ValF(GetXMLAttribute(*obj, "w"))
entities()\bones()\h = ValF(GetXMLAttribute(*obj, "h"))
EndIf
Case "animation"
AddElement(entities()\animations())
entities()\animations()\name = GetXMLAttribute(*obj, "name")
entities()\animations()\length = Val(GetXMLAttribute(*obj, "length"))
Protected *timeline = ChildXMLNode(*obj)
While *timeline
If GetXMLNodeName(*timeline) = "timeline"
AddElement(entities()\animations()\timelines())
entities()\animations()\timelines()\id = Val(GetXMLAttribute(*timeline, "id"))
entities()\animations()\timelines()\name = GetXMLAttribute(*timeline, "name")
entities()\animations()\timelines()\obj = GetXMLAttribute(*timeline, "obj")
Protected *key = ChildXMLNode(*timeline)
While *key
If GetXMLNodeName(*key) = "key"
AddElement(entities()\animations()\timelines()\keys())
entities()\animations()\timelines()\keys()\time = Val(GetXMLAttribute(*key, "time"))
entities()\animations()\timelines()\keys()\spin = Val(GetXMLAttribute(*key, "spin"))
Protected *bone = ChildXMLNode(*key)
If *bone And GetXMLNodeName(*bone) = "bone"
entities()\animations()\timelines()\keys()\x = ValF(GetXMLAttribute(*bone, "x"))
entities()\animations()\timelines()\keys()\y = ValF(GetXMLAttribute(*bone, "y"))
entities()\animations()\timelines()\keys()\angle = ValF(GetXMLAttribute(*bone, "angle"))
entities()\animations()\timelines()\keys()\scale_x = ValF(GetXMLAttribute(*bone, "scale_x"))
EndIf
EndIf
*key = NextXMLNode(*key)
Wend
EndIf
*timeline = NextXMLNode(*timeline)
Wend
EndSelect
*obj = NextXMLNode(*obj)
Wend
EndIf
*folder = NextXMLNode(*folder)
Wend
FreeXML(xml)
ProcedureReturn #True
EndProcedure
; Example usage
File.s = OpenFileRequester("Open Spriter SCML", "", "Spriter (*.scml)|*.scml|All files (*.*)|*.*" ,0)
If File
Debug "Spriter File :" + file
If LoadSpriterData(File)
Debug "Loaded Spriter data successfully"
; List all image files
Debug "=== Image Files ==="
ForEach folders()
ForEach folders()\files()
If folders()\files()\type <> "sound"
Debug Str(folders()\files()\id) + ": " + folders()\files()\name +
" (" + Str(folders()\files()\width) + "x" + Str(folders()\files()\height) + ")" +
" pivot: " + StrF(folders()\files()\pivot_x, 4) + "," + StrF(folders()\files()\pivot_y, 4)
EndIf
Next
Next
; List all sound files
Debug "=== Sound Files ==="
ForEach folders()
ForEach folders()\files()
If folders()\files()\type = "sound"
Debug Str(folders()\files()\id) + ": " + folders()\files()\name
EndIf
Next
Next
; List all bones
Debug "=== Bone Data ==="
ForEach entities()
ForEach entities()\bones()
Debug entities()\bones()\name + " (" + entities()\bones()\realname + ")" +
" size: " + StrF(entities()\bones()\w, 1) + "x" + StrF(entities()\bones()\h, 1)
Next
Next
; List animation data
Debug "=== Animation Data ==="
ForEach entities()
ForEach entities()\animations()
Debug "Animation: " + entities()\animations()\name +
" (" + Str(entities()\animations()\length) + "ms)"
ForEach entities()\animations()\timelines()
Debug " Timeline " + Str(entities()\animations()\timelines()\id) +
": " + entities()\animations()\timelines()\name +
" (" + entities()\animations()\timelines()\obj + ")"
ForEach entities()\animations()\timelines()\keys()
Debug " Key @ " + Str(entities()\animations()\timelines()\keys()\time) + "ms: " +
"x=" + StrF(entities()\animations()\timelines()\keys()\x, 2) +
", y=" + StrF(entities()\animations()\timelines()\keys()\y, 2) +
", angle=" + StrF(entities()\animations()\timelines()\keys()\angle, 2) +
", scale=" + StrF(entities()\animations()\timelines()\keys()\scale_x, 2)
Next
Next
Next
Next
EndIf
EndIf