|
@@ -0,0 +1,5666 @@
|
|
|
+#if defined(SOKOL_IMPL) && !defined(SOKOL_SPINE_IMPL)
|
|
|
+#define SOKOL_SPINE_IMPL
|
|
|
+#endif
|
|
|
+#ifndef SOKOL_SPINE_INCLUDED
|
|
|
+/*
|
|
|
+ sokol_spine.h -- a sokol-gfx renderer for the spine-c runtime
|
|
|
+ (see https://github.com/EsotericSoftware/spine-runtimes/tree/4.1/spine-c)
|
|
|
+
|
|
|
+ Project URL: https://github.com/floooh/sokol
|
|
|
+
|
|
|
+ Do this:
|
|
|
+ #define SOKOL_IMPL or
|
|
|
+ #define SOKOL_SPINE_IMPL
|
|
|
+
|
|
|
+ before you include this file in *one* C or C++ file to create the
|
|
|
+ implementation.
|
|
|
+
|
|
|
+ The following defines are used by the implementation to select the
|
|
|
+ platform-specific embedded shader code (these are the same defines as
|
|
|
+ used by sokol_gfx.h and sokol_app.h):
|
|
|
+
|
|
|
+ SOKOL_GLCORE33
|
|
|
+ SOKOL_GLES2
|
|
|
+ SOKOL_GLES3
|
|
|
+ SOKOL_D3D11
|
|
|
+ SOKOL_METAL
|
|
|
+
|
|
|
+ ...optionally provide the following macros to override defaults:
|
|
|
+
|
|
|
+ SOKOL_ASSERT(c) - your own assert macro (default: assert(c))
|
|
|
+ SOKOL_SPINE_API_DECL - public function declaration prefix (default: extern)
|
|
|
+ SOKOL_API_DECL - same as SOKOL_SPINE_API_DECL
|
|
|
+ SOKOL_API_IMPL - public function implementation prefix (default: -)
|
|
|
+ SOKOL_UNREACHABLE() - a guard macro for unreachable code (default: assert(false))
|
|
|
+
|
|
|
+ If sokol_spine.h is compiled as a DLL, define the following before
|
|
|
+ including the declaration or implementation:
|
|
|
+
|
|
|
+ SOKOL_DLL
|
|
|
+
|
|
|
+ On Windows, SOKOL_DLL will define SOKOL_SPINE_API_DECL as __declspec(dllexport)
|
|
|
+ or __declspec(dllimport) as needed.
|
|
|
+
|
|
|
+ Include the following headers before including sokol_spine.h:
|
|
|
+
|
|
|
+ sokol_gfx.h
|
|
|
+
|
|
|
+ Include the following headers before include the sokol_spine.h *IMPLEMENTATION*:
|
|
|
+
|
|
|
+ spine/spine.h
|
|
|
+
|
|
|
+ You'll also need to compile and link with the spine-c runtime:
|
|
|
+
|
|
|
+ https://github.com/EsotericSoftware/spine-runtimes/tree/4.1/spine-c/spine-c
|
|
|
+
|
|
|
+
|
|
|
+ FEATURE OVERVIEW
|
|
|
+ ================
|
|
|
+ sokol_spine.h is a sokol-gfx renderer and 'handle wrapper' for Spine
|
|
|
+ (http://en.esotericsoftware.com/spine-in-depth) on top of the
|
|
|
+ spine-c runtime: http://en.esotericsoftware.com/spine-c (source code:
|
|
|
+ https://github.com/EsotericSoftware/spine-runtimes/tree/4.1/spine-c/spine-c).
|
|
|
+
|
|
|
+ The sokol-gfx renderer allows to manage multiple contexts for rendering
|
|
|
+ Spine scenes into different sokol-gfx render passes (similar to sokol-gl and
|
|
|
+ sokol-debugtext), allows to split rendering into layers to mix Spine
|
|
|
+ rendering with other rendering operations, and it automatically batches
|
|
|
+ adjacent draw calls for Spine objects that use the same texture and in the
|
|
|
+ same layer.
|
|
|
+
|
|
|
+ Sokol-spine wraps 'raw' spine-c objects with tagged index handles. This
|
|
|
+ eliminates the risk of memory corruption via dangling pointers. Any
|
|
|
+ API calls involving invalid objects either result in a no-op, or
|
|
|
+ in a proper error.
|
|
|
+
|
|
|
+ The sokol-spine API exposes four 'base object types', and a number of
|
|
|
+ 'subobject types' which are owned by base objects.
|
|
|
+
|
|
|
+ Base object types are:
|
|
|
+
|
|
|
+ - sspine_atlas: A wrapper around a spine-c spAtlas object, each spAtlas
|
|
|
+ object owns at least one spAtlasPage object, and each spAtlasPage object
|
|
|
+ owns exactly one sokol-gfx image object.
|
|
|
+
|
|
|
+ - sspine_skeleton: A skeleton object requires an atlas object for creation,
|
|
|
+ and is a wrapper around one spine-c spSkeletonData and one
|
|
|
+ spAnimationStateData object. both contain the shared static data for
|
|
|
+ individual spine instances
|
|
|
+
|
|
|
+ - sspine_instance: Instance objects are created from skeleton objects.
|
|
|
+ Instances are the objects that are actually getting rendered. Each instance
|
|
|
+ tracks its own transformation and animation state, but otherwise just
|
|
|
+ references shared data of the skeleton object it was created from. An
|
|
|
+ sspine_instance object is a wrapper around one spine-c spSkeleton,
|
|
|
+ spAnimationState and spSkeletonClipping object each.
|
|
|
+
|
|
|
+ - sspine_skinset: Skin-set objects are collections of skins which define
|
|
|
+ the look of an instance. Some Spine scenes consist of combinable skins
|
|
|
+ (for instance a human character could offer different skins for different
|
|
|
+ types of clothing, hats, scarfs, shirts, pants, and so on..., and a skin
|
|
|
+ set would represent a specific outfit).
|
|
|
+
|
|
|
+ Subobject types allow to inspect and manipulate Spine objects in more detail:
|
|
|
+
|
|
|
+ - sspine_anim: Each skeleton object usually offers animations which can
|
|
|
+ then be scheduled and mixed on an instance.
|
|
|
+
|
|
|
+ - sspine_bone: Bone objects are the hierarchical transform nodes of
|
|
|
+ a skeleton. The sokol-spine API allows both to inspect the shared
|
|
|
+ static bone attributes of an sspine_skeleton object, as well as
|
|
|
+ inspecting and manipulating the per-instance bone attributes
|
|
|
+ on an sspine_instance object.
|
|
|
+
|
|
|
+ - sspine_event: A running Spine animation may fire 'events' at certain
|
|
|
+ positions in time (for instance a 'footstep' event whenever a foot
|
|
|
+ hits the ground). Events can be used to play sound effects (or visual
|
|
|
+ effects) at the right time.
|
|
|
+
|
|
|
+ - sspine_iktarget: Allows to set the target position for a group of
|
|
|
+ bones controlled by inverse kinematics.
|
|
|
+
|
|
|
+ There's a couple of other subobject types which are mostly useful to
|
|
|
+ inspect the interior structure of skeletons. Those will be explained
|
|
|
+ in detail further down.
|
|
|
+
|
|
|
+ MINIMAL API USAGE OVERVIEW
|
|
|
+ ==========================
|
|
|
+ During initialization:
|
|
|
+
|
|
|
+ - call sspine_setup() after initializating sokol-gfx
|
|
|
+ - create an atlas object from a Spine atlas file with sspine_make_atlas()
|
|
|
+ - load and initialize the sokol-gfx image objects referenced by the atlas
|
|
|
+ - create a skeleton object from a Spine skeleton file with sspine_make_skeleton()
|
|
|
+ - create at least one instance object with sspine_make_instance()
|
|
|
+
|
|
|
+ In the frame loop, outside of sokol-gfx render passes:
|
|
|
+
|
|
|
+ - call sspine_new_frame() before any other sokol-spine function
|
|
|
+ - if needed, move instances around with sspine_set_position()
|
|
|
+ - if needed, schedule new animations with sspine_set_animation() and sspine_add_animation()
|
|
|
+ - each frame, advance the current instance animation state with sspine_update_instance()
|
|
|
+ - each frame, render instances with sspine_draw_instance_in_layer(), this just records
|
|
|
+ vertices, indices and draw commands into internal buffers, but does no actual
|
|
|
+ sokol-gfx rendering
|
|
|
+
|
|
|
+ In the frame loop, inside a sokol-gfx render pass:
|
|
|
+
|
|
|
+ - call sspine_draw_layer() to draw all previously recorded instances in a specific layer
|
|
|
+
|
|
|
+ On shutdown:
|
|
|
+
|
|
|
+ - call sspine_shutdown(), ideally before shutting down sokol-gfx
|
|
|
+
|
|
|
+ QUICKSTART STEP BY STEP
|
|
|
+ =======================
|
|
|
+ For a simple demo program using sokol_app.h, sokol_gfx.h and sokol_fetch.h,
|
|
|
+ see here: [TODO: add link to spine-simple-sapp wasm demo].
|
|
|
+
|
|
|
+ - sokol_spine.h must be included after sokol_gfx.h (this is true both
|
|
|
+ for the declaration and implementation):
|
|
|
+
|
|
|
+ #include "sokol_gfx.h"
|
|
|
+ #include "sokol_spine.h"
|
|
|
+
|
|
|
+ - ...and sokol_gfx.h must be initialized before sokol_spine.h:
|
|
|
+
|
|
|
+ sg_setup(&(sg_desc){ ... });
|
|
|
+ sspine_setup(&(sspine_desc){ ... });
|
|
|
+
|
|
|
+ - You can tweak the memory usage of sokol-spine by limiting or expanding the
|
|
|
+ maximum number of vertices, draw commands and pool sizes:
|
|
|
+
|
|
|
+ sspine_setup(&(sspine_desc){
|
|
|
+ .max_vertices = 1024, // default: (1<<16) = 65536
|
|
|
+ .max_commands = 128, // default: (1<<14) = 16384
|
|
|
+ .context_pool_size = 1, // default: 4
|
|
|
+ .atlas_pool_size = 1, // default: 64
|
|
|
+ .skeleton_pool_size = 1, // default: 64
|
|
|
+ .skinset_pool_size = 1, // default: 64
|
|
|
+ .instance_pool_size = 16, // default: 1024
|
|
|
+ });
|
|
|
+
|
|
|
+ Sokol-spine uses 32-bit vertex-indices for rendering
|
|
|
+ (SG_INDEXTYPE_UINT32), so that the maximum number of Spine vertices
|
|
|
+ in a frame isn't limited to (1<<16).
|
|
|
+
|
|
|
+ - You can override the default memory allocation and
|
|
|
+ error logging functions, this is explained in detail further down:
|
|
|
+
|
|
|
+ sspine_setup(&(sspine_desc){
|
|
|
+ .allocator = { ... },
|
|
|
+ .logger = { ... }
|
|
|
+ });
|
|
|
+
|
|
|
+ - After initialization, the first thing you need is an sspine_atlas object.
|
|
|
+ Sokol-spine doesn't concern itself with file IO, it expects all external
|
|
|
+ data to be provided as pointer/size pairs:
|
|
|
+
|
|
|
+ sspine_atlas atlas = sspine_make_atlas(&(sspine_atlas_desc){
|
|
|
+ .data = {
|
|
|
+ .ptr = ..., // pointer to Spine atlas file data in memory
|
|
|
+ .size = ..., // atlas file data size in bytes
|
|
|
+ }
|
|
|
+ });
|
|
|
+ assert(sspine_atlas_valid(atlas));
|
|
|
+
|
|
|
+ If you load the atlas data asynchronously, you can still run your
|
|
|
+ per-frame rendering code without waiting for the atlas data to be loaded
|
|
|
+ and the atlas to be created. This works because calling sokol-spine
|
|
|
+ functions with 'invalid' object handles is a valid no-op.
|
|
|
+
|
|
|
+ - Optionally you can override some or all of the atlas texture creation parameters:
|
|
|
+
|
|
|
+ sspine_atlas atlas = sspine_make_atlas(&(sspine_atlas_desc){
|
|
|
+ .data = { ... },
|
|
|
+ .overrides = {
|
|
|
+ .min_filter = SG_FILTER_NEAREST,
|
|
|
+ .mag_filter = SG_FILTER_NEAREST,
|
|
|
+ .wrap_u = SG_WRAP_MIRROR,
|
|
|
+ .wrap_v = SG_WRAP_MIRROR,
|
|
|
+ .premul_alpha_enabled = ...,
|
|
|
+ .premul_alpha_disabled = ...,
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ - The atlas file itself doesn't contain any texture data, it only contains
|
|
|
+ filenames of the required textures. Sokol-spine has already allocated
|
|
|
+ a sokol-gfx sg_image handle for each required texture, but the actual
|
|
|
+ texture loading and initialization must be performed by user code:
|
|
|
+
|
|
|
+ // iterate over atlas textures and initialize sokol-gfx image objects
|
|
|
+ // with existing handles
|
|
|
+ const int num = sspine_num_images(atlas);
|
|
|
+ for (int i = 0; i < num; i++) {
|
|
|
+ const sspine_image img = sspine_image_by_index(atlas, i);
|
|
|
+ const sspine_image_info img_info = sspine_get_image_info(img);
|
|
|
+ assert(img_info.valid);
|
|
|
+ assert(!img_info.filename.truncated);
|
|
|
+
|
|
|
+ // the filename is now in img_info.filename.cstr, 'somehow'
|
|
|
+ // load and decode the image data into memory, and then
|
|
|
+ // initialize the sokol-gfx image from the existing sg_image handle
|
|
|
+ // in img_info.sgimage:
|
|
|
+ sg_init_image(img_info.sgimage, &(sg_image_desc){
|
|
|
+ .width = ...,
|
|
|
+ .height = ...,
|
|
|
+ .pixel_format = ...,
|
|
|
+ .min_filter = img_info.min_filter,
|
|
|
+ .mag_filter = img_info.mag_filter,
|
|
|
+ .wrap_u = img_info.wrap_u,
|
|
|
+ .wrap_v = img_info.wrap_v,
|
|
|
+ .data.subimage[0][0] = {
|
|
|
+ .ptr = ..., // pointer to decoded image pixel data
|
|
|
+ .size = ..., // size of decoded image pixel data in bytes
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ If you load the image data asynchronously, you can still simply start rendering
|
|
|
+ before the image data is loaded. This works because sokol-gfx will silently drop
|
|
|
+ any rendering operations that involve 'incomplete' objects.
|
|
|
+
|
|
|
+ - Once an atlas object has been created (independently from loading any image data),
|
|
|
+ an sspine_skeleton object is needed next. This requires a valid atlas object
|
|
|
+ handle as input, and a pointer to the Spine skeleton file data loaded into memory.
|
|
|
+
|
|
|
+ Spine skeleton files come in two flavours: binary or json, for binary data,
|
|
|
+ a ptr/size pair must be provided:
|
|
|
+
|
|
|
+ sspine_skeleton skeleton = sspine_make_skeleton(&(sspine_skeleton_desc){
|
|
|
+ .atlas = atlas, // atlas must be a valid sspine_atlas handle
|
|
|
+ .binary_data = {
|
|
|
+ .ptr = ..., // pointer to binary skeleton data in memory
|
|
|
+ .size = ..., // size of binary skeleton data in bytes
|
|
|
+ }
|
|
|
+ });
|
|
|
+ assert(sspine_skeleton_valid(skeleton));
|
|
|
+
|
|
|
+ For JSON skeleton file data, the data must be provided as a zero-terminated C string:
|
|
|
+
|
|
|
+ sspine_skeleton skeleton = sspine_make_skeleton(&(sspine_skeleton_desc){
|
|
|
+ .atlas = atlas,
|
|
|
+ .json_data = ..., // JSON skeleton data as zero-terminated(!) C-string
|
|
|
+ });
|
|
|
+
|
|
|
+ Like with all sokol-spine objects, if you load the skeleton data asynchronously
|
|
|
+ and only then create a skeleton object, you can already start rendering before
|
|
|
+ the data is loaded and the Spine objects have been created. Any operations
|
|
|
+ involving 'incomplete' handles will be dropped.
|
|
|
+
|
|
|
+ - You can pre-scale the Spine scene size, and you can provide a default cross-fade
|
|
|
+ duration for animation mixing:
|
|
|
+
|
|
|
+ sspine_skeleton skeleton = sspine_make_skeleton(&(sspine_skeleton_desc){
|
|
|
+ .atlas = atlas,
|
|
|
+ .binary_data = { ... },
|
|
|
+ .prescale = 0.5f, // scale to half-size
|
|
|
+ .anim_default_mix = 0.2f, // default anim mixing cross-fade duration 0.2 seconds
|
|
|
+ });
|
|
|
+
|
|
|
+ - Once the skeleton object has been created, it's finally time to create one or many instance objects.
|
|
|
+ If you want to independently render and animate the 'same' Spine object many times in a frame,
|
|
|
+ you should only create one sspine_skeleton object, and then as many sspine_instance object
|
|
|
+ as needed from the shared skeleton object:
|
|
|
+
|
|
|
+ sspine_instance instance = sspine_make_instance(&(sspine_instance_desc){
|
|
|
+ .skeleton = skeleton, // must be a valid skeleton handle
|
|
|
+ });
|
|
|
+ assert(sspine_instance_valid(instance));
|
|
|
+
|
|
|
+ After creation, the sspine_instance will have a 'default skin' set as its appearance.
|
|
|
+
|
|
|
+ - To set the position of an instance:
|
|
|
+
|
|
|
+ sspine_set_position(inst, (sspine_vec2){ .x=..., .y=... });
|
|
|
+
|
|
|
+ Sokol-spine doesn't define a specific unit (like pixels or meters), instead the
|
|
|
+ rendering coordinate system is defined later at 'render time'.
|
|
|
+
|
|
|
+ - To schedule an initial looping animation by its name:
|
|
|
+
|
|
|
+ // first lookup up the animation by name on the skeleton:
|
|
|
+ sspine_anim anim = sspine_anim_by_name(skeleton, "walk");
|
|
|
+ assert(sspine_anim_valid(anim));
|
|
|
+
|
|
|
+ // then schedule the animation on the instance, on mixer track 0, as looping:
|
|
|
+ sspine_set_animation(instance, anim, 0, true);
|
|
|
+
|
|
|
+ Scheduling and mixing animations will be explained in more detail further down.
|
|
|
+
|
|
|
+ - IMPORTANT: at the start of a frame, before calling any other per-frame sokol-spine
|
|
|
+ functions, you *must* call:
|
|
|
+
|
|
|
+ sspine_new_frame()
|
|
|
+
|
|
|
+ This advances an internal frame counter which is important for updating
|
|
|
+ recorded vertex- and index-data exactly once per frame, and to rewind
|
|
|
+ internal vertex-, index- and command buffers. Failing to do so may result
|
|
|
+ in the internal buffers running full, resulting in faulty or missing
|
|
|
+ rendering operations.
|
|
|
+
|
|
|
+ - To advance and mix instance animations:
|
|
|
+
|
|
|
+ sspine_update_instance(instance, delta_time_in_seconds);
|
|
|
+
|
|
|
+ Usually you'd call this each frame for each active instance with the
|
|
|
+ frame duration in seconds.
|
|
|
+
|
|
|
+ - Now it's finally time to 'render' the instance at its current position and
|
|
|
+ animation state:
|
|
|
+
|
|
|
+ sspine_draw_instance_in_layer(instance, 0);
|
|
|
+
|
|
|
+ Instances are generally rendered into numbered virtual 'render layers' (in this
|
|
|
+ case, layer 0). Layers are useful for interleaving sokol-spine rendering
|
|
|
+ with other rendering commands (like background and foreground tile maps,
|
|
|
+ sprites or text).
|
|
|
+
|
|
|
+ - It's important to note that no actual sokol-gfx rendering happens in
|
|
|
+ sspine_draw_instance_in_layer(), instead only vertices, indices and
|
|
|
+ draw commands are recorded into internal memory buffes.
|
|
|
+
|
|
|
+ - The only sokol-spine function which *must* (and should) be called inside
|
|
|
+ a sokol-gfx rendering pass is sspine_draw_layer().
|
|
|
+
|
|
|
+ This renders all draw commands that have been recorded previously in a
|
|
|
+ specific layer via sspine_draw_instance_in_layer().
|
|
|
+
|
|
|
+ const sspine_layer_transform tform = { ... };
|
|
|
+
|
|
|
+ sg_begin_default_pass(...);
|
|
|
+ sspine_draw_layer(0, tform);
|
|
|
+ sg_end_pass();
|
|
|
+ sg_commit();
|
|
|
+
|
|
|
+ IMPORTANT: DO *NOT* MIX any calls to sspine_draw_instance_in_layer()
|
|
|
+ with sspine_draw_layer(), as this will confuse the internal draw command
|
|
|
+ recording. Ideally, move all sokol-gfx pass rendering (including all
|
|
|
+ sspine_draw_layer() calls) towards the end of the frame, separate from
|
|
|
+ any other sokol-spine calls.
|
|
|
+
|
|
|
+ The sspine_layer_transform struct defines the layer's screen space coordinate
|
|
|
+ system. For instance to map Spine coordinates to framebuffer pixels, with the
|
|
|
+ origin in the screen center, you'd setup the layer transform like this:
|
|
|
+
|
|
|
+ const float width = sapp_widthf();
|
|
|
+ const float height = sapp_heightf();
|
|
|
+ const sspine_layer_transform tform = {
|
|
|
+ .size = { .x = width, .y = height },
|
|
|
+ .origin = { .x = width * 0.5f, .y = height * 0.5f },
|
|
|
+ };
|
|
|
+
|
|
|
+ With this pixel mapping, the Spine scene would *not* scale with window size,
|
|
|
+ which often is not very useful. Instead it might make more sense to render
|
|
|
+ to a fixed 'virtual' resolution, for instance 1024 * 768:
|
|
|
+
|
|
|
+ const sspine_layer_transform tform = {
|
|
|
+ .size = { .x = 1024.0f, .y = 768.0f },
|
|
|
+ .origin = { .x = 512.0f, .y = 384.0f },
|
|
|
+ };
|
|
|
+
|
|
|
+ How to configure a virtual resolution with a fixed aspect ratio is
|
|
|
+ left as an exercise to the reader ;)
|
|
|
+
|
|
|
+ - That's it for basic sokol-spine setup and rendering. Any existing objects
|
|
|
+ will automatically be cleaned up when calling sspine_shutdown(), this
|
|
|
+ should be called before shutting down sokol-gfx, but this is not required:
|
|
|
+
|
|
|
+ sspine_shutdown();
|
|
|
+ sg_shutdown();
|
|
|
+
|
|
|
+ - You can explicitely destroy the base object types if you don't need them
|
|
|
+ any longer. This will cause the underlying spine-c objects to be
|
|
|
+ freed and the memory to be returned to the operating system:
|
|
|
+
|
|
|
+ sspine_destroy_instance(instance);
|
|
|
+ sspine_destroy_skinset(skinset);
|
|
|
+ sspine_destroy_skeleton(skeleton);
|
|
|
+ sspine_destroy_atlas(atlas);
|
|
|
+
|
|
|
+ You can destroy these objects in any order without causing memory corruption
|
|
|
+ issues. Instead any dependent object handles will simply become invalid (e.g.
|
|
|
+ if you destroy an atlas object, all skeletons and instances created from
|
|
|
+ this atlas will 'technically' still exist, but their handles will resolve to
|
|
|
+ 'invalid' and all sokol-spine calls involving these handles will silently fail).
|
|
|
+
|
|
|
+ For instance:
|
|
|
+
|
|
|
+ // create an atlas, skeleton and instance
|
|
|
+ sspine_atlas atlas = sspine_make_atlas(&(sspine_atlas_desc){ ... });
|
|
|
+ assert(sspine_atlas_valid(atlas));
|
|
|
+
|
|
|
+ sspine_skeleton skeleton = sspine_make_skeleton(&(sspine_skeleton_desc){
|
|
|
+ .atlas = atlas,
|
|
|
+ ...
|
|
|
+ });
|
|
|
+ assert(sspine_skeleton_valid(skeleton));
|
|
|
+
|
|
|
+ sspine_instance instance = sspine_make_instance(&(sspine_instance_desc){
|
|
|
+ .skeleton = skeleton,
|
|
|
+ });
|
|
|
+ assert(sspine_instance_valid(instance));
|
|
|
+
|
|
|
+ // destroy the atlas object:
|
|
|
+ sspine_destroy_atlas(atlas);
|
|
|
+
|
|
|
+ // the skeleton and instance handle should now be invalid, but
|
|
|
+ // otherwise, nothing bad will happen:
|
|
|
+ if (!sspine_skeleton_valid(skeleton)) {
|
|
|
+ ...
|
|
|
+ }
|
|
|
+ if (!sspine_instance_valid(instance)) {
|
|
|
+ ...
|
|
|
+ }
|
|
|
+
|
|
|
+ RENDERER DETAILS
|
|
|
+ ================
|
|
|
+ Any rendering related work happens in the functions sspine_draw_instance_in_layer() and
|
|
|
+ sspine_draw_layer().
|
|
|
+
|
|
|
+ sspine_draw_instance_in_layer() will result in vertices, indices and internal
|
|
|
+ draw commands which will be recorded into internal memory buffers (e.g.
|
|
|
+ no sokol-gfx functions will be called here).
|
|
|
+
|
|
|
+ If possible, batching will be performed by merging a new draw command with
|
|
|
+ the previously recorded draw command. For two draw commands to be merged,
|
|
|
+ the following conditions must be tru:
|
|
|
+
|
|
|
+ - rendering needs to go into the same layer
|
|
|
+ - the same atlas texture must be used
|
|
|
+ - the blend mode must be compatible (the Spine blending modes
|
|
|
+ 'normal' and 'additive' can be merged, but not 'multiply')
|
|
|
+ - the same premultiplied alpha mode must be used
|
|
|
+
|
|
|
+ To make the most out of batching:
|
|
|
+
|
|
|
+ - use Spine objects which only have a single atlas texture
|
|
|
+ and blend mode across all slots
|
|
|
+ - group sspine_draw_instance_in_layer() calls by layer
|
|
|
+
|
|
|
+ After all instances have been 'rendered' (or rather: recorded) into layers,
|
|
|
+ the actually rendering happens inside a sokol-gfx pass by calling the
|
|
|
+ function sspine_draw_layer() for each layer in 'z order' (e.g. the layer
|
|
|
+ index doesn't matter for z-ordering, only the order how sspine_draw_layer() is
|
|
|
+ called).
|
|
|
+
|
|
|
+ Only the first call to sspine_draw_layer() in a frame will copy the recorded
|
|
|
+ vertices and indices into sokol-gfx buffers.
|
|
|
+
|
|
|
+ Each call to sspine_draw_layer() will iterate over all recorded (and
|
|
|
+ hopefully well-batched) draw commands, skip any draw commands with a
|
|
|
+ non-matching layer index, and draw only those with a matching layer by
|
|
|
+ calling:
|
|
|
+
|
|
|
+ - if the pipeline object has changed:
|
|
|
+ - sg_apply_pipeline()
|
|
|
+ - sg_apply_uniforms() for the vertex stage
|
|
|
+ - if the atlas texture has changed:
|
|
|
+ - sg_apply_bindings()
|
|
|
+ - if the premultiplied-alpha mode has changed:
|
|
|
+ - sg_apply_uniforms() for the fragment stage
|
|
|
+ - and finally sg_draw()
|
|
|
+
|
|
|
+ The main purpose of render layers is to mix Spine rendering with other
|
|
|
+ render operations. In the not too distant future, the same render layer idea
|
|
|
+ will also be implemented at least for sokol-gl and sokol-debugtext.
|
|
|
+
|
|
|
+ FIXME: does this section need more details about layer transforms?
|
|
|
+
|
|
|
+ RENDERING WITH CONTEXTS
|
|
|
+ =======================
|
|
|
+ At first glance, render contexts may look like more heavy-weight
|
|
|
+ render layers, but they serve a different purpose: they are useful
|
|
|
+ if Spine rendering needs to happen in different sokol-gfx render passes
|
|
|
+ with different pixel formats and MSAA sample counts.
|
|
|
+
|
|
|
+ All Spine rendering happens within a context, even you don't call any
|
|
|
+ of the context API functions, in this case, an internal 'default context'
|
|
|
+ will be used.
|
|
|
+
|
|
|
+ Each context has its own internal vertex-, index- and command buffer and
|
|
|
+ all context state is completely independent from any other contexts.
|
|
|
+
|
|
|
+ To create a new context object, call:
|
|
|
+
|
|
|
+ sspine_context ctx = sspine_make_context(&(sspine_context_desc){
|
|
|
+ .max_vertices = ...,
|
|
|
+ .max_commands = ...,
|
|
|
+ .color_format = SG_PIXELFORMAT_...,
|
|
|
+ .depth_format = SG_PIXELFORMAT_...,
|
|
|
+ .sample_count = ...,
|
|
|
+ .color_write_mask = SG_COLORMASK_...,
|
|
|
+ });
|
|
|
+
|
|
|
+ The color_format, depth_format and sample_count items must be compatible
|
|
|
+ with the sokol-gfx render pass you're going to render into.
|
|
|
+
|
|
|
+ If you omit the color_format, depth_format and sample_count designators,
|
|
|
+ the new context will be compatible with the sokol-gfx default pass
|
|
|
+ (which is most likely not what you want, unless your offscreen render passes
|
|
|
+ exactly match the default pass attributes).
|
|
|
+
|
|
|
+ Once a context has been created, it can be made active with:
|
|
|
+
|
|
|
+ sspine_set_context(ctx);
|
|
|
+
|
|
|
+ To set the default context again:
|
|
|
+
|
|
|
+ sspine_set_contxt(sspine_default_context());
|
|
|
+
|
|
|
+ ...and to get the currently active context:
|
|
|
+
|
|
|
+ sspine_context cur_ctx = sspine_get_context();
|
|
|
+
|
|
|
+ The currently active context only matter for two functions:
|
|
|
+
|
|
|
+ - sspine_draw_instance_in_layer()
|
|
|
+ - sspine_draw_layer()
|
|
|
+
|
|
|
+ Alternatively you can bypass the currently set context with these
|
|
|
+ alternative functions:
|
|
|
+
|
|
|
+ - sspine_context_draw_layer_in_instance(ctx, ...)
|
|
|
+ - sspine_context_draw_layer(ctx, ...)
|
|
|
+
|
|
|
+ These explicitely take a context argument, completely ignore
|
|
|
+ and don't change the active context.
|
|
|
+
|
|
|
+ You can query some information about the a context with the function:
|
|
|
+
|
|
|
+ sspine_context_info info = ssgpine_get_context_info(ctx);
|
|
|
+
|
|
|
+ This returns the current number of recorded vertices, indices
|
|
|
+ and draw commands.
|
|
|
+
|
|
|
+ RESOURCE STATES:
|
|
|
+ ================
|
|
|
+ Similar to sokol-gfx, you can query the current 'resource state' of Spine
|
|
|
+ objects:
|
|
|
+
|
|
|
+ sspine_resource_state sspine_get_atlas_resource_state(sspine_atlas atlas);
|
|
|
+ sspine_resource_state sspine_get_skeleton_resource_state(sspine_atlas atlas);
|
|
|
+ sspine_resource_state sspine_get_instance_resource_state(sspine_atlas atlas);
|
|
|
+ sspine_resource_state sspine_get_skinset_resource_state(sspine_atlas atlas);
|
|
|
+ sspine_resource_state sspine_get_context_resource_state(sspine_atlas atlas);
|
|
|
+
|
|
|
+ This returns one of
|
|
|
+
|
|
|
+ - SSPINE_RESOURCE_VALID: the object is valid and ready to use
|
|
|
+ - SSPINE_RESOURCE_FAILED: the object creation has failed
|
|
|
+ - SSPINE_RESOURCE_INVALID: the object or one of its dependencies is
|
|
|
+ invalid, it either no longer exists, or the the handle hasn't been
|
|
|
+ initialized with a call to one of the object creation functions
|
|
|
+
|
|
|
+ MISC HELPER FUNCTIONS:
|
|
|
+ ======================
|
|
|
+ There's a couple of helper functions which don't fit into a big enough category
|
|
|
+ of their own:
|
|
|
+
|
|
|
+ You can ask a skeleton for the atlas it has been created from:
|
|
|
+
|
|
|
+ sspine_atlas atlas = sspine_get_skeleton_atlas(skeleton);
|
|
|
+
|
|
|
+ ...and likewise, ask an instance for the skeleton it has been created from:
|
|
|
+
|
|
|
+ sspine_skeleton skeleton = sspine_get_instance_skeleton(instance);
|
|
|
+
|
|
|
+ ...and finally you can convert a layer transform struct into a 4x4 projection
|
|
|
+ matrix that's memory-layout compatible with sokol-gl:
|
|
|
+
|
|
|
+ const sspine_layer_transform tform = { ... };
|
|
|
+ const sspine_mat4 proj = sspine_layer_transform_to_mat4(&tform);
|
|
|
+ sgl_matrix_mode_projection();
|
|
|
+ sgl_load_matrix(proj.m);
|
|
|
+
|
|
|
+ ANIMATIONS
|
|
|
+ ==========
|
|
|
+ Animations have their own handle type sspine_anim. A valid sspine_anim
|
|
|
+ handle is either obtained by looking up an animation by name from a skeleton:
|
|
|
+
|
|
|
+ sspine_anim anim = sspine_anim_by_name(skeleton, "walk");
|
|
|
+
|
|
|
+ ...or by index:
|
|
|
+
|
|
|
+ sspine_anim anim = sspine_anim_by_index(skeleton, 0);
|
|
|
+
|
|
|
+ The returned anim handle will be invalid if an animation of that name doesn't
|
|
|
+ exist, or the provided index is out-of-range:
|
|
|
+
|
|
|
+ if (!sspine_anim_is_valid(anim)) {
|
|
|
+ // animation handle is not valid
|
|
|
+ }
|
|
|
+
|
|
|
+ An animation handle will also become invalid when the skeleton object it was
|
|
|
+ created is destroyed, or otherwise becomes invalid.
|
|
|
+
|
|
|
+ You can iterate over all animations in a skeleton:
|
|
|
+
|
|
|
+ const int num_anims = sspine_num_anims(skeleton);
|
|
|
+ for (int anim_index = 0; anim_index < num_anims; anim_index++) {
|
|
|
+ sspine_anim anim = sspine_anim_by_index(skeleton, anim_index);
|
|
|
+ ...
|
|
|
+ }
|
|
|
+
|
|
|
+ Since sspine_anim is a 'fat handle' (it houses a skeleton handle and an index),
|
|
|
+ there's a helper function which checks if two anim handles are equal:
|
|
|
+
|
|
|
+ if (sspine_anim_equal(anim0, anim1)) {
|
|
|
+ ...
|
|
|
+ }
|
|
|
+
|
|
|
+ To query information about an animation:
|
|
|
+
|
|
|
+ const sspine_anim_info info = sspine_get_anim_info(anim);
|
|
|
+ if (info.valid) {
|
|
|
+ printf("index: %d, duration: %f, name: %s", info.index, info.duration, info.name.cstr);
|
|
|
+ }
|
|
|
+
|
|
|
+ Scheduling and mixing animations is controlled through the following functions:
|
|
|
+
|
|
|
+ void sspine_clear_animation_tracks(sspine_instance instance);
|
|
|
+ void sspine_clear_animation_track(sspine_instance instance, int track_index);
|
|
|
+ void sspine_set_animation(sspine_instance instance, sspine_anim anim, int track_index, bool loop);
|
|
|
+ void sspine_add_animation(sspine_instance instance, sspine_anim anim, int track_index, bool loop, float delay);
|
|
|
+ void sspine_set_empty_animation(sspine_instance instance, int track_index, float mix_duration);
|
|
|
+ void sspine_add_empty_animation(sspine_instance instance, int track_index, float mix_duration, float delay);
|
|
|
+
|
|
|
+ Please refer to the spine-c documentation to get an idea what these functions do:
|
|
|
+
|
|
|
+ http://en.esotericsoftware.com/spine-c#Applying-animations
|
|
|
+
|
|
|
+ EVENTS
|
|
|
+ ======
|
|
|
+ For a general idea of Spine events, see here: http://esotericsoftware.com/spine-events
|
|
|
+
|
|
|
+ After calling sspine_update_instance() to advance the currently configured animations,
|
|
|
+ you can poll for triggered events like this:
|
|
|
+
|
|
|
+ const int num_triggered_events = sspine_num_triggered_events(instance);
|
|
|
+ for (int i = 0; i < num_triggered_events; i++) {
|
|
|
+ const sspine_triggered_event_info info = sspine_get_triggered_event_info(instance, i);
|
|
|
+ if (info.valid) {
|
|
|
+ ...
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ The returned sspine_triggered_event_info struct gives you the current runtime properties
|
|
|
+ of the event (in case the event has keyed properties). For the actual list of event
|
|
|
+ properties please see the actual sspine_triggered_event_info struct declaration.
|
|
|
+
|
|
|
+ It's also possible to inspect the static event definition on a skeleton, this works
|
|
|
+ the same as iterating through animations. You can lookup an event by name,
|
|
|
+ get the number of events, lookup an event by its index, and get detailed
|
|
|
+ information about an event:
|
|
|
+
|
|
|
+ int sspine_num_events(sspine_skeleton skeleton);
|
|
|
+ sspine_event sspine_event_by_name(sspine_skeleton skeleton, const char* name);
|
|
|
+ sspine_event sspine_event_by_index(sspine_skeleton skeleton, int index);
|
|
|
+ bool sspine_event_valid(sspine_event event);
|
|
|
+ bool sspine_event_equal(sspine_event first, sspine_event second);
|
|
|
+ sspine_event_info sspine_get_event_info(sspine_event event);
|
|
|
+
|
|
|
+ (FIXME: shouldn't the event info struct contains an sspine_anim handle?)
|
|
|
+
|
|
|
+ IK TARGETS
|
|
|
+ ==========
|
|
|
+ The IK target function group allows to iterate over the IK targets that have been
|
|
|
+ defined on a skeleton, find an IK target by name, get detailed information about
|
|
|
+ an IK target, and most importantly, set the world space position of an IK target
|
|
|
+ which updates the position of all bones influenced by the IK target:
|
|
|
+
|
|
|
+ int sspine_num_iktargets(sspine_skeleton skeleton);
|
|
|
+ sspine_iktarget sspine_iktarget_by_name(sspine_skeleton skeleton, const char* name);
|
|
|
+ sspine_iktarget sspine_iktarget_by_index(sspine_skeleton skeleton, int index);
|
|
|
+ bool sspine_iktarget_valid(sspine_iktarget iktarget);
|
|
|
+ bool sspine_iktarget_equal(sspine_iktarget first, sspine_iktarget second);
|
|
|
+ sspine_iktarget_info sspine_get_iktarget_info(sspine_iktarget iktarget);
|
|
|
+ void sspine_set_iktarget_world_pos(sspine_instance instance, sspine_iktarget iktarget, sspine_vec2 world_pos);
|
|
|
+
|
|
|
+ BONES
|
|
|
+ =====
|
|
|
+ Skeleton bones are wrapped with an sspine_bone handle which can be created from
|
|
|
+ a skeleton handle, and either a bone name:
|
|
|
+
|
|
|
+ sspine_bone bone = sspine_bone_by_name(skeleton, "root");
|
|
|
+ assert(sspine_bone_valid(bone));
|
|
|
+
|
|
|
+ ...or a bone index:
|
|
|
+
|
|
|
+ sspine_bone bone = sspine_bone_by_index(skeleton, 0);
|
|
|
+ assert(sspine_bone_valid(bone));
|
|
|
+
|
|
|
+ ...to iterate over all bones of a skeleton and query information about each
|
|
|
+ bone:
|
|
|
+
|
|
|
+ const int num_bones = sspine_num_bones(skeleton);
|
|
|
+ for (int bone_index = 0; bone_index < num_bones; bone_index++) {
|
|
|
+ sspine_bone bone = sspine_bone_by_index(skeleton, bone_index);
|
|
|
+ const sspine_bone_info info = sspine_get_bone_info(skeleton, bone);
|
|
|
+ if (info.valid) {
|
|
|
+ ...
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ The sspine_bone_info struct provides the shared, static bone state in the skeleton (like
|
|
|
+ the name, a parent bone handle, bone length, pose transform and a color attribute),
|
|
|
+ but doesn't contain any dynamic information of per-instance bones.
|
|
|
+
|
|
|
+ To manipulate the per-instance bone attributes use the following setter functions:
|
|
|
+
|
|
|
+ void sspine_set_bone_transform(sspine_instance instance, sspine_bone bone, const sspine_bone_transform* transform);
|
|
|
+ void sspine_set_bone_position(sspine_instance instance, sspine_bone bone, sspine_vec2 position);
|
|
|
+ void sspine_set_bone_rotation(sspine_instance instance, sspine_bone bone, float rotation);
|
|
|
+ void sspine_set_bone_scale(sspine_instance instance, sspine_bone bone, sspine_vec2 scale);
|
|
|
+ void sspine_set_bone_shear(sspine_instance instance, sspine_bone bone, sspine_vec2 shear);
|
|
|
+
|
|
|
+ ...and to query the per-instance bone attributes, the following getters:
|
|
|
+
|
|
|
+ sspine_bone_transform sspine_get_bone_transform(sspine_instance instance, sspine_bone bone);
|
|
|
+ sspine_vec2 sspine_get_bone_position(sspine_instance instance, sspine_bone bone);
|
|
|
+ float sspine_get_bone_rotation(sspine_instance instance, sspine_bone bone);
|
|
|
+ sspine_vec2 sspine_get_bone_scale(sspine_instance instance, sspine_bone bone);
|
|
|
+ sspine_vec2 sspine_get_bone_shear(sspine_instance instance, sspine_bone bone);
|
|
|
+
|
|
|
+ These functions all work in the local bone coordinate system (relative to a bone's parent bone).
|
|
|
+
|
|
|
+ To transform positions between bone-local and global space use the following helper functions:
|
|
|
+
|
|
|
+ sspine_vec2 sspine_bone_local_to_world(sspine_instance instance, sspine_bone bone, sspine_vec2 local_pos);
|
|
|
+ sspine_vec2 sspine_bone_world_to_local(sspine_instance instance, sspine_bone bone, sspine_vec2 world_pos);
|
|
|
+
|
|
|
+ ...and as a convenience, there's a helper function which obtains the bone position in global space
|
|
|
+ directly:
|
|
|
+
|
|
|
+ sspine_vec2 sspine_get_bone_world_position(sspine_instance instance, sspine_bone bone);
|
|
|
+
|
|
|
+ SKINS AND SKINSETS
|
|
|
+ ==================
|
|
|
+ Skins are named pieces of geometry which can be turned on and off, what makes Spine skins a bit
|
|
|
+ confusing is that they are hierarchical. A skin can itself be a collection of other skins. Setting
|
|
|
+ the 'root skin' will also make all 'child skins' visible. In sokol-spine collections of skins are
|
|
|
+ managed through dedicated 'skin set' objects. Under the hood they create a 'root skin' where the
|
|
|
+ skins of the skin set are attached to, but from the outside it just looks like a 'flat' collection
|
|
|
+ of skins without the tricky hierarchical management.
|
|
|
+
|
|
|
+ Like other 'subobjects', skin handles can be obtained by the skin name from a skeleton handle:
|
|
|
+
|
|
|
+ sspine_skin skin = sspine_skin_by_name(skeleton, "jacket");
|
|
|
+ assert(sspine_skin_valid(skin));
|
|
|
+
|
|
|
+ ...or by a skin index:
|
|
|
+
|
|
|
+ sspine_skin skin = sspine_skin_by_index(skeleton, 0);
|
|
|
+ assert(sspine_skin_valid(skin));
|
|
|
+
|
|
|
+ ...you can iterate over all skins of a skeleton and query some information about the skin:
|
|
|
+
|
|
|
+ const int num_skins = sspine_num_skins(skeleton);
|
|
|
+ for (int skin_index = 0; skin_index < num_skins; skin_index++) {
|
|
|
+ sspine_skin skin = sspine_skin_by_index(skin_index);
|
|
|
+ sspine_skin_info info = sspine_get_skin_info(skin);
|
|
|
+ if (info.valid) {
|
|
|
+ ...
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Currently, the only useful query item is the skin name though.
|
|
|
+
|
|
|
+ To make a skin visible on an instance, just call:
|
|
|
+
|
|
|
+ sspine_set_skin(instance, skin);
|
|
|
+
|
|
|
+ ...this will first deactivate the previous skin before setting a new skin.
|
|
|
+
|
|
|
+ A more powerful way to configure the skin visibility is through 'skin sets'. Skin
|
|
|
+ sets are simply flat collections of skins which should be made visible at once.
|
|
|
+ A new skin set is created like this:
|
|
|
+
|
|
|
+ sspine_skinset skinset = sspine_make_skinset(&(sspine_skinset_desc){
|
|
|
+ .skeleton = skeleton,
|
|
|
+ .skins = {
|
|
|
+ sspine_skin_by_name(skeleton, "blue-jacket"),
|
|
|
+ sspine_skin_by_name(skeleton, "green-pants"),
|
|
|
+ sspine_skin_by_name(skeleton, "blonde-hair"),
|
|
|
+ ...
|
|
|
+ }
|
|
|
+ });
|
|
|
+ assert(sspine_skinset_valid(skinset))
|
|
|
+
|
|
|
+ ...then simply set the skinset on an instance to reconfigure the appearance
|
|
|
+ of the instance:
|
|
|
+
|
|
|
+ sspine_set_skinset(instance, skinset);
|
|
|
+
|
|
|
+ The functions sspine_set_skinset() and sspine_set_skin() will cancel each other.
|
|
|
+ Calling sspine_set_skinset() deactivates the effect of sspine_set_skin() and
|
|
|
+ vice versa.
|
|
|
+
|
|
|
+ ERROR REPORTING AND LOGGING
|
|
|
+ ===========================
|
|
|
+ sokol_spine.h introduces a new combined logging- and error-reporting
|
|
|
+ mechanism which replaces the old SOKOL_LOG macro, and the more recent
|
|
|
+ logging callback.
|
|
|
+
|
|
|
+ The new reporting uses a more elaborate logger callback which provides:
|
|
|
+
|
|
|
+ - a short tag string identifying the header (for instance 'sspine')
|
|
|
+ - a numeric log level (panic, error, warning, info)
|
|
|
+ - a numeric error code (SSPINE_ERROR_*)
|
|
|
+ - in debug mode: the error code as human readable string
|
|
|
+ - a line number, where in the header the problem occured
|
|
|
+ - in debug mode: the filename of the header
|
|
|
+ - and a user data parameter
|
|
|
+
|
|
|
+ The logging callback will be standardized across all sokol headers,
|
|
|
+ so that it will be possible to use the same logging function with
|
|
|
+ all headers.
|
|
|
+
|
|
|
+ To override logging, first write a logging function like this:
|
|
|
+
|
|
|
+ void my_log(const char* tag, // e.g. 'sspine'
|
|
|
+ uint32_t log_level, // 0=panic, 1=error, 2=warn, 3=info
|
|
|
+ uint32_t error_code, // SSPINE_ERROR_*
|
|
|
+ const char* error_id, // error as string, only in debug mode, otherwise empty string
|
|
|
+ int line_nr, // line number in sokol_spine.h
|
|
|
+ const char* filename, // debug mode only, otherwise empty string
|
|
|
+ void* user_data)
|
|
|
+ {
|
|
|
+ ...
|
|
|
+ }
|
|
|
+
|
|
|
+ ...and then setup sokol-spine like this:
|
|
|
+
|
|
|
+ sspine_setup(&(sspine_desc){
|
|
|
+ .logger = {
|
|
|
+ .func = my_log,
|
|
|
+ .user_data = ...,
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ If no custom logger is provided, verbose default logging goes to stderr
|
|
|
+ (this means you won't see any logging messages on Android, or on Windows
|
|
|
+ unless the problem is attached to a terminal!).
|
|
|
+
|
|
|
+ Eventually there will be a more luxurious sokol_log.h header, which will
|
|
|
+ provide more control over logging, also on Windows or Android.
|
|
|
+
|
|
|
+ MEMORY ALLOCATION OVERRIDE
|
|
|
+ ==========================
|
|
|
+ You can override the memory allocation functions at initialization time
|
|
|
+ like this:
|
|
|
+
|
|
|
+ void* my_alloc(size_t size, void* user_data) {
|
|
|
+ return malloc(size);
|
|
|
+ }
|
|
|
+
|
|
|
+ void my_free(void* ptr, void* user_data) {
|
|
|
+ free(ptr);
|
|
|
+ }
|
|
|
+
|
|
|
+ ...
|
|
|
+ sspine_setup(&(sspine_desc){
|
|
|
+ // ...
|
|
|
+ .allocator = {
|
|
|
+ .alloc = my_alloc,
|
|
|
+ .free = my_free,
|
|
|
+ .user_data = ...;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ ...
|
|
|
+
|
|
|
+ If no overrides are provided, malloc and free will be used.
|
|
|
+
|
|
|
+ This only affects memory allocation calls done by sokol_gfx.h
|
|
|
+ itself though, not any allocations in OS libraries.
|
|
|
+
|
|
|
+ LICENSE
|
|
|
+ =======
|
|
|
+ zlib/libpng license
|
|
|
+
|
|
|
+ Copyright (c) 2022 Andre Weissflog
|
|
|
+
|
|
|
+ This software is provided 'as-is', without any express or implied warranty.
|
|
|
+ In no event will the authors be held liable for any damages arising from the
|
|
|
+ use of this software.
|
|
|
+
|
|
|
+ Permission is granted to anyone to use this software for any purpose,
|
|
|
+ including commercial applications, and to alter it and redistribute it
|
|
|
+ freely, subject to the following restrictions:
|
|
|
+
|
|
|
+ 1. The origin of this software must not be misrepresented; you must not
|
|
|
+ claim that you wrote the original software. If you use this software in a
|
|
|
+ product, an acknowledgment in the product documentation would be
|
|
|
+ appreciated but is not required.
|
|
|
+
|
|
|
+ 2. Altered source versions must be plainly marked as such, and must not
|
|
|
+ be misrepresented as being the original software.
|
|
|
+
|
|
|
+ 3. This notice may not be removed or altered from any source
|
|
|
+ distribution.
|
|
|
+*/
|
|
|
+#define SOKOL_SPINE_INCLUDED (1)
|
|
|
+#include <stdint.h>
|
|
|
+#include <stdbool.h>
|
|
|
+#include <stddef.h> // size_t
|
|
|
+
|
|
|
+#if !defined(SOKOL_GFX_INCLUDED)
|
|
|
+#error "Please include sokol_gfx.h before sokol_spine.h"
|
|
|
+#endif
|
|
|
+
|
|
|
+#if defined(SOKOL_API_DECL) && !defined(SOKOL_SPINE_API_DECL)
|
|
|
+#define SOKOL_SPINE_API_DECL SOKOL_API_DECL
|
|
|
+#endif
|
|
|
+#ifndef SOKOL_SPINE_API_DECL
|
|
|
+#if defined(_WIN32) && defined(SOKOL_DLL) && defined(SOKOL_SPINE_IMPL)
|
|
|
+#define SOKOL_SPINE_API_DECL __declspec(dllexport)
|
|
|
+#elif defined(_WIN32) && defined(SOKOL_DLL)
|
|
|
+#define SOKOL_SPINE_API_DECL __declspec(dllimport)
|
|
|
+#else
|
|
|
+#define SOKOL_SPINE_API_DECL extern
|
|
|
+#endif
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifdef __cplusplus
|
|
|
+extern "C" {
|
|
|
+#endif
|
|
|
+
|
|
|
+enum {
|
|
|
+ SSPINE_INVALID_ID = 0,
|
|
|
+ SSPINE_MAX_SKINSET_SKINS = 32,
|
|
|
+ SSPINE_MAX_STRING_SIZE = 61, // see sspine_string struct
|
|
|
+};
|
|
|
+
|
|
|
+typedef struct sspine_context { uint32_t id; } sspine_context;
|
|
|
+typedef struct sspine_atlas { uint32_t id; } sspine_atlas;
|
|
|
+typedef struct sspine_skeleton { uint32_t id; } sspine_skeleton;
|
|
|
+typedef struct sspine_instance { uint32_t id; } sspine_instance;
|
|
|
+typedef struct sspine_skinset { uint32_t id; } sspine_skinset;
|
|
|
+
|
|
|
+typedef struct sspine_image { uint32_t atlas_id; int index; } sspine_image;
|
|
|
+typedef struct sspine_atlas_page { uint32_t atlas_id; int index; } sspine_atlas_page;
|
|
|
+typedef struct sspine_anim { uint32_t skeleton_id; int index; } sspine_anim;
|
|
|
+typedef struct sspine_bone { uint32_t skeleton_id; int index; } sspine_bone;
|
|
|
+typedef struct sspine_slot { uint32_t skeleton_id; int index; } sspine_slot;
|
|
|
+typedef struct sspine_event { uint32_t skeleton_id; int index; } sspine_event;
|
|
|
+typedef struct sspine_iktarget { uint32_t skeleton_id; int index; } sspine_iktarget;
|
|
|
+typedef struct sspine_skin { uint32_t skeleton_id; int index; } sspine_skin;
|
|
|
+
|
|
|
+typedef struct sspine_range { const void* ptr; size_t size; } sspine_range;
|
|
|
+typedef struct sspine_vec2 { float x, y; } sspine_vec2;
|
|
|
+typedef struct sspine_mat4 { float m[16]; } sspine_mat4;
|
|
|
+typedef sg_color sspine_color;
|
|
|
+
|
|
|
+typedef struct sspine_string {
|
|
|
+ bool valid;
|
|
|
+ bool truncated;
|
|
|
+ uint8_t len;
|
|
|
+ char cstr[SSPINE_MAX_STRING_SIZE];
|
|
|
+} sspine_string;
|
|
|
+
|
|
|
+typedef enum sspine_resource_state {
|
|
|
+ SSPINE_RESOURCESTATE_INITIAL,
|
|
|
+ SSPINE_RESOURCESTATE_ALLOC,
|
|
|
+ SSPINE_RESOURCESTATE_VALID,
|
|
|
+ SSPINE_RESOURCESTATE_FAILED,
|
|
|
+ SSPINE_RESOURCESTATE_INVALID,
|
|
|
+ _SSPINE_RESOURCESTATE_FORCE_U32 = 0x7FFFFFFF
|
|
|
+} sspine_resource_state;
|
|
|
+
|
|
|
+// error codes via x-macro magic
|
|
|
+#define _SSPINE_ERRORS \
|
|
|
+ _SSPINE_XMACRO(OK)\
|
|
|
+ _SSPINE_XMACRO(CONTEXT_POOL_EXHAUSTED)\
|
|
|
+ _SSPINE_XMACRO(ATLAS_POOL_EXHAUSTED)\
|
|
|
+ _SSPINE_XMACRO(SKELETON_POOL_EXHAUSTED)\
|
|
|
+ _SSPINE_XMACRO(SKINSET_POOL_EXHAUSTED)\
|
|
|
+ _SSPINE_XMACRO(INSTANCE_POOL_EXHAUSTED)\
|
|
|
+ _SSPINE_XMACRO(CANNOT_DESTROY_DEFAULT_CONTEXT)\
|
|
|
+ _SSPINE_XMACRO(ATLAS_DESC_NO_DATA)\
|
|
|
+ _SSPINE_XMACRO(SPINE_ATLAS_CREATION_FAILED)\
|
|
|
+ _SSPINE_XMACRO(SG_ALLOC_IMAGE_FAILED)\
|
|
|
+ _SSPINE_XMACRO(SKELETON_DESC_NO_DATA)\
|
|
|
+ _SSPINE_XMACRO(SKELETON_DESC_NO_ATLAS)\
|
|
|
+ _SSPINE_XMACRO(SKELETON_ATLAS_NOT_VALID)\
|
|
|
+ _SSPINE_XMACRO(SPINE_SKELETON_DATA_CREATION_FAILED)\
|
|
|
+ _SSPINE_XMACRO(SKINSET_DESC_NO_SKELETON)\
|
|
|
+ _SSPINE_XMACRO(SKINSET_SKELETON_NOT_VALID)\
|
|
|
+ _SSPINE_XMACRO(SKINSET_INVALID_SKIN_HANDLE)\
|
|
|
+ _SSPINE_XMACRO(INSTANCE_DESC_NO_SKELETON)\
|
|
|
+ _SSPINE_XMACRO(INSTANCE_SKELETON_NOT_VALID)\
|
|
|
+ _SSPINE_XMACRO(INSTANCE_ATLAS_NOT_VALID)\
|
|
|
+ _SSPINE_XMACRO(SPINE_SKELETON_CREATION_FAILED)\
|
|
|
+ _SSPINE_XMACRO(SPINE_ANIMATIONSTATE_CREATION_FAILED)\
|
|
|
+ _SSPINE_XMACRO(SPINE_SKELETONCLIPPING_CREATION_FAILED)\
|
|
|
+ _SSPINE_XMACRO(COMMAND_BUFFER_OVERFLOW)\
|
|
|
+ _SSPINE_XMACRO(VERTEX_BUFFER_OVERFLOW)\
|
|
|
+ _SSPINE_XMACRO(INDEX_BUFFER_OVERFLOW)\
|
|
|
+ _SSPINE_XMACRO(STRING_TRUNCATED)\
|
|
|
+
|
|
|
+#define _SSPINE_XMACRO(code) SSPINE_ERROR_##code,
|
|
|
+typedef enum sspine_error {
|
|
|
+ _SSPINE_ERRORS
|
|
|
+} sspine_error;
|
|
|
+#undef _SSPINE_XMACRO
|
|
|
+
|
|
|
+typedef enum sspine_loglevel {
|
|
|
+ SSPINE_LOGLEVEL_PANIC = 0,
|
|
|
+ SSPINE_LOGLEVEL_ERROR = 1,
|
|
|
+ SSPINE_LOGLEVEL_WARN = 2,
|
|
|
+ SSPINE_LOGLEVEL_INFO = 3,
|
|
|
+} sspine_loglevel;
|
|
|
+
|
|
|
+typedef struct sspine_layer_transform {
|
|
|
+ sspine_vec2 size;
|
|
|
+ sspine_vec2 origin;
|
|
|
+} sspine_layer_transform;
|
|
|
+
|
|
|
+typedef struct sspine_bone_transform {
|
|
|
+ sspine_vec2 position;
|
|
|
+ float rotation; // in degrees
|
|
|
+ sspine_vec2 scale;
|
|
|
+ sspine_vec2 shear; // in degrees
|
|
|
+} sspine_bone_transform;
|
|
|
+
|
|
|
+typedef struct sspine_context_desc {
|
|
|
+ int max_vertices;
|
|
|
+ int max_commands;
|
|
|
+ sg_pixel_format color_format;
|
|
|
+ sg_pixel_format depth_format;
|
|
|
+ int sample_count;
|
|
|
+ sg_color_mask color_write_mask;
|
|
|
+} sspine_context_desc;
|
|
|
+
|
|
|
+typedef struct sspine_context_info {
|
|
|
+ int num_vertices; // current number of vertices
|
|
|
+ int num_indices; // current number of indices
|
|
|
+ int num_commands; // current number of commands
|
|
|
+} sspine_context_info;
|
|
|
+
|
|
|
+typedef struct sspine_image_info {
|
|
|
+ bool valid;
|
|
|
+ sg_image sgimage;
|
|
|
+ sg_filter min_filter;
|
|
|
+ sg_filter mag_filter;
|
|
|
+ sg_wrap wrap_u;
|
|
|
+ sg_wrap wrap_v;
|
|
|
+ int width;
|
|
|
+ int height;
|
|
|
+ bool premul_alpha;
|
|
|
+ sspine_string filename;
|
|
|
+} sspine_image_info;
|
|
|
+
|
|
|
+typedef struct sspine_atlas_overrides {
|
|
|
+ sg_filter min_filter;
|
|
|
+ sg_filter mag_filter;
|
|
|
+ sg_wrap wrap_u;
|
|
|
+ sg_wrap wrap_v;
|
|
|
+ bool premul_alpha_enabled;
|
|
|
+ bool premul_alpha_disabled;
|
|
|
+} sspine_atlas_overrides;
|
|
|
+
|
|
|
+typedef struct sspine_atlas_desc {
|
|
|
+ sspine_range data;
|
|
|
+ sspine_atlas_overrides override;
|
|
|
+} sspine_atlas_desc;
|
|
|
+
|
|
|
+typedef struct sspine_atlas_page_info {
|
|
|
+ bool valid;
|
|
|
+ sspine_atlas atlas;
|
|
|
+ sspine_image_info image;
|
|
|
+ sspine_atlas_overrides overrides;
|
|
|
+} sspine_atlas_page_info;
|
|
|
+
|
|
|
+typedef struct sspine_skeleton_desc {
|
|
|
+ sspine_atlas atlas;
|
|
|
+ float prescale;
|
|
|
+ float anim_default_mix;
|
|
|
+ const char* json_data;
|
|
|
+ sspine_range binary_data;
|
|
|
+} sspine_skeleton_desc;
|
|
|
+
|
|
|
+typedef struct sspine_skinset_desc {
|
|
|
+ sspine_skeleton skeleton;
|
|
|
+ sspine_skin skins[SSPINE_MAX_SKINSET_SKINS];
|
|
|
+} sspine_skinset_desc;
|
|
|
+
|
|
|
+typedef struct sspine_anim_info {
|
|
|
+ bool valid;
|
|
|
+ int index;
|
|
|
+ float duration;
|
|
|
+ sspine_string name;
|
|
|
+} sspine_anim_info;
|
|
|
+
|
|
|
+typedef struct sspine_bone_info {
|
|
|
+ bool valid;
|
|
|
+ int index;
|
|
|
+ sspine_bone parent_bone;
|
|
|
+ float length;
|
|
|
+ sspine_bone_transform pose;
|
|
|
+ sspine_color color;
|
|
|
+ sspine_string name;
|
|
|
+} sspine_bone_info;
|
|
|
+
|
|
|
+typedef struct sspine_slot_info {
|
|
|
+ bool valid;
|
|
|
+ int index;
|
|
|
+ sspine_bone bone;
|
|
|
+ sspine_color color;
|
|
|
+ sspine_string attachment_name;
|
|
|
+ sspine_string name;
|
|
|
+} sspine_slot_info;
|
|
|
+
|
|
|
+typedef struct sspine_iktarget_info {
|
|
|
+ bool valid;
|
|
|
+ int index;
|
|
|
+ sspine_bone target_bone;
|
|
|
+ sspine_string name;
|
|
|
+} sspine_iktarget_info;
|
|
|
+
|
|
|
+typedef struct sspine_skin_info {
|
|
|
+ bool valid;
|
|
|
+ int index;
|
|
|
+ sspine_string name;
|
|
|
+} sspine_skin_info;
|
|
|
+
|
|
|
+typedef struct sspine_event_info {
|
|
|
+ bool valid;
|
|
|
+ int index;
|
|
|
+ int int_value;
|
|
|
+ float float_value;
|
|
|
+ float volume;
|
|
|
+ float balance;
|
|
|
+ sspine_string name;
|
|
|
+ sspine_string string_value;
|
|
|
+ sspine_string audio_path;
|
|
|
+} sspine_event_info;
|
|
|
+
|
|
|
+typedef struct sspine_triggered_event_info {
|
|
|
+ bool valid;
|
|
|
+ sspine_event event;
|
|
|
+ float time;
|
|
|
+ int int_value;
|
|
|
+ float float_value;
|
|
|
+ float volume;
|
|
|
+ float balance;
|
|
|
+ sspine_string string_value;
|
|
|
+} sspine_triggered_event_info;
|
|
|
+
|
|
|
+typedef struct sspine_instance_desc {
|
|
|
+ sspine_skeleton skeleton;
|
|
|
+} sspine_instance_desc;
|
|
|
+
|
|
|
+typedef struct sspine_allocator {
|
|
|
+ void* (*alloc)(size_t size, void* user_data);
|
|
|
+ void (*free)(void* ptr, void* user_data);
|
|
|
+ void* user_data;
|
|
|
+} sspine_allocator;
|
|
|
+
|
|
|
+typedef struct sspine_logger {
|
|
|
+ void (*func)(
|
|
|
+ const char* tag, // always "sspine"
|
|
|
+ uint32_t log_level, // 0=panic, 1=error, 2=warning, 3=info
|
|
|
+ uint32_t error_code, // SSPINE_ERROR_*
|
|
|
+ const char* error_id, // error as string, debug only, otherwise empty string
|
|
|
+ int line_nr, // line number in sokol_spine.h
|
|
|
+ const char* filename, // debug mode only, otherwise empty string
|
|
|
+ void* user_data);
|
|
|
+ void* user_data;
|
|
|
+} sspine_logger;
|
|
|
+
|
|
|
+typedef struct sspine_desc {
|
|
|
+ int max_vertices;
|
|
|
+ int max_commands;
|
|
|
+ int context_pool_size;
|
|
|
+ int atlas_pool_size;
|
|
|
+ int skeleton_pool_size;
|
|
|
+ int skinset_pool_size;
|
|
|
+ int instance_pool_size;
|
|
|
+ sg_pixel_format color_format;
|
|
|
+ sg_pixel_format depth_format;
|
|
|
+ int sample_count;
|
|
|
+ sg_color_mask color_write_mask;
|
|
|
+ sspine_allocator allocator;
|
|
|
+ sspine_logger logger;
|
|
|
+} sspine_desc;
|
|
|
+
|
|
|
+// setup/shutdown
|
|
|
+SOKOL_SPINE_API_DECL void sspine_setup(const sspine_desc* desc);
|
|
|
+SOKOL_SPINE_API_DECL void sspine_shutdown(void);
|
|
|
+
|
|
|
+// context functions
|
|
|
+SOKOL_SPINE_API_DECL sspine_context sspine_make_context(const sspine_context_desc* desc);
|
|
|
+SOKOL_SPINE_API_DECL void sspine_destroy_context(sspine_context ctx);
|
|
|
+SOKOL_SPINE_API_DECL void sspine_set_context(sspine_context ctx);
|
|
|
+SOKOL_SPINE_API_DECL sspine_context sspine_get_context(void);
|
|
|
+SOKOL_SPINE_API_DECL sspine_context sspine_default_context(void);
|
|
|
+SOKOL_SPINE_API_DECL sspine_context_info sspine_get_context_info(sspine_context ctx);
|
|
|
+
|
|
|
+// create and destroy spine objects
|
|
|
+SOKOL_SPINE_API_DECL sspine_atlas sspine_make_atlas(const sspine_atlas_desc* desc);
|
|
|
+SOKOL_SPINE_API_DECL sspine_skeleton sspine_make_skeleton(const sspine_skeleton_desc* desc);
|
|
|
+SOKOL_SPINE_API_DECL sspine_skinset sspine_make_skinset(const sspine_skinset_desc* desc);
|
|
|
+SOKOL_SPINE_API_DECL sspine_instance sspine_make_instance(const sspine_instance_desc* desc);
|
|
|
+SOKOL_SPINE_API_DECL void sspine_destroy_atlas(sspine_atlas atlas);
|
|
|
+SOKOL_SPINE_API_DECL void sspine_destroy_skeleton(sspine_skeleton skeleton);
|
|
|
+SOKOL_SPINE_API_DECL void sspine_destroy_skinset(sspine_skinset skinset);
|
|
|
+SOKOL_SPINE_API_DECL void sspine_destroy_instance(sspine_instance instance);
|
|
|
+
|
|
|
+// mark a new frame (call at start of a frame before any sspine_draw_instance())
|
|
|
+SOKOL_SPINE_API_DECL void sspine_new_frame(void);
|
|
|
+
|
|
|
+// configure instance appearance via skinsets
|
|
|
+SOKOL_SPINE_API_DECL void sspine_set_skinset(sspine_instance instance, sspine_skinset skinset);
|
|
|
+
|
|
|
+// update instance animations before drawing
|
|
|
+SOKOL_SPINE_API_DECL void sspine_update_instance(sspine_instance instance, float delta_time);
|
|
|
+
|
|
|
+// iterate over triggered events after updating an instance
|
|
|
+SOKOL_SPINE_API_DECL int sspine_num_triggered_events(sspine_instance instance);
|
|
|
+SOKOL_SPINE_API_DECL sspine_triggered_event_info sspine_get_triggered_event_info(sspine_instance instance, int triggered_event_index);
|
|
|
+
|
|
|
+// draw instance into current or explicit context
|
|
|
+SOKOL_SPINE_API_DECL void sspine_draw_instance_in_layer(sspine_instance instance, int layer);
|
|
|
+SOKOL_SPINE_API_DECL void sspine_context_draw_instance_in_layer(sspine_context ctx, sspine_instance instance, int layer);
|
|
|
+
|
|
|
+// helper function to convert sspine_layer_transform into projection matrix
|
|
|
+SOKOL_SPINE_API_DECL sspine_mat4 sspine_layer_transform_to_mat4(const sspine_layer_transform* tform);
|
|
|
+
|
|
|
+// draw a layer in current context or explicit context (call once per context and frame in sokol-gfx pass)
|
|
|
+SOKOL_SPINE_API_DECL void sspine_draw_layer(int layer, const sspine_layer_transform* tform);
|
|
|
+SOKOL_SPINE_API_DECL void sspine_context_draw_layer(sspine_context ctx, int layer, const sspine_layer_transform* tform);
|
|
|
+
|
|
|
+// get current resource state (INITIAL, ALLOC, VALID, FAILED, INVALID)
|
|
|
+SOKOL_SPINE_API_DECL sspine_resource_state sspine_get_context_resource_state(sspine_context context);
|
|
|
+SOKOL_SPINE_API_DECL sspine_resource_state sspine_get_atlas_resource_state(sspine_atlas atlas);
|
|
|
+SOKOL_SPINE_API_DECL sspine_resource_state sspine_get_skeleton_resource_state(sspine_skeleton skeleton);
|
|
|
+SOKOL_SPINE_API_DECL sspine_resource_state sspine_get_skinset_resource_state(sspine_skinset skinset);
|
|
|
+SOKOL_SPINE_API_DECL sspine_resource_state sspine_get_instance_resource_state(sspine_instance instance);
|
|
|
+
|
|
|
+// shortcut for sspine_get_*_state() == SSPINE_RESOURCESTATE_VALID
|
|
|
+SOKOL_SPINE_API_DECL bool sspine_context_valid(sspine_context context);
|
|
|
+SOKOL_SPINE_API_DECL bool sspine_atlas_valid(sspine_atlas atlas);
|
|
|
+SOKOL_SPINE_API_DECL bool sspine_skeleton_valid(sspine_skeleton skeleton);
|
|
|
+SOKOL_SPINE_API_DECL bool sspine_instance_valid(sspine_instance instance);
|
|
|
+SOKOL_SPINE_API_DECL bool sspine_skinset_valid(sspine_skinset skinset);
|
|
|
+
|
|
|
+// get dependency objects
|
|
|
+SOKOL_SPINE_API_DECL sspine_atlas sspine_get_skeleton_atlas(sspine_skeleton skeleton);
|
|
|
+SOKOL_SPINE_API_DECL sspine_skeleton sspine_get_instance_skeleton(sspine_instance instance);
|
|
|
+
|
|
|
+// atlas images
|
|
|
+SOKOL_SPINE_API_DECL int sspine_num_images(sspine_atlas atlas);
|
|
|
+SOKOL_SPINE_API_DECL sspine_image sspine_image_by_index(sspine_atlas atlas, int index);
|
|
|
+SOKOL_SPINE_API_DECL bool sspine_image_valid(sspine_image image);
|
|
|
+SOKOL_SPINE_API_DECL bool sspine_image_equal(sspine_image first, sspine_image second);
|
|
|
+SOKOL_SPINE_API_DECL sspine_image_info sspine_get_image_info(sspine_image image);
|
|
|
+
|
|
|
+// atlas page functions
|
|
|
+SOKOL_SPINE_API_DECL int sspine_num_atlas_pages(sspine_atlas atlas);
|
|
|
+SOKOL_SPINE_API_DECL sspine_atlas_page sspine_atlas_page_by_index(sspine_atlas atlas, int index);
|
|
|
+SOKOL_SPINE_API_DECL bool sspine_atlas_page_valid(sspine_atlas_page page);
|
|
|
+SOKOL_SPINE_API_DECL bool sspine_atlas_page_equal(sspine_atlas_page first, sspine_atlas_page second);
|
|
|
+SOKOL_SPINE_API_DECL sspine_atlas_page_info sspine_get_atlas_page_info(sspine_atlas_page page);
|
|
|
+
|
|
|
+// instance transform functions
|
|
|
+SOKOL_SPINE_API_DECL void sspine_set_position(sspine_instance instance, sspine_vec2 position);
|
|
|
+SOKOL_SPINE_API_DECL void sspine_set_scale(sspine_instance instance, sspine_vec2 scale);
|
|
|
+SOKOL_SPINE_API_DECL void sspine_set_color(sspine_instance instance, sspine_color color);
|
|
|
+SOKOL_SPINE_API_DECL sspine_vec2 sspine_get_position(sspine_instance instance);
|
|
|
+SOKOL_SPINE_API_DECL sspine_vec2 sspine_get_scale(sspine_instance instance);
|
|
|
+SOKOL_SPINE_API_DECL sspine_color sspine_get_color(sspine_instance instance);
|
|
|
+
|
|
|
+// instance animation functions
|
|
|
+SOKOL_SPINE_API_DECL int sspine_num_anims(sspine_skeleton skeleton);
|
|
|
+SOKOL_SPINE_API_DECL sspine_anim sspine_anim_by_name(sspine_skeleton skeleton, const char* name);
|
|
|
+SOKOL_SPINE_API_DECL sspine_anim sspine_anim_by_index(sspine_skeleton skeleton, int index);
|
|
|
+SOKOL_SPINE_API_DECL bool sspine_anim_valid(sspine_anim anim);
|
|
|
+SOKOL_SPINE_API_DECL bool sspine_anim_equal(sspine_anim first, sspine_anim second);
|
|
|
+SOKOL_SPINE_API_DECL sspine_anim_info sspine_get_anim_info(sspine_anim anim);
|
|
|
+SOKOL_SPINE_API_DECL void sspine_clear_animation_tracks(sspine_instance instance);
|
|
|
+SOKOL_SPINE_API_DECL void sspine_clear_animation_track(sspine_instance instance, int track_index);
|
|
|
+SOKOL_SPINE_API_DECL void sspine_set_animation(sspine_instance instance, sspine_anim anim, int track_index, bool loop);
|
|
|
+SOKOL_SPINE_API_DECL void sspine_add_animation(sspine_instance instance, sspine_anim anim, int track_index, bool loop, float delay);
|
|
|
+SOKOL_SPINE_API_DECL void sspine_set_empty_animation(sspine_instance instance, int track_index, float mix_duration);
|
|
|
+SOKOL_SPINE_API_DECL void sspine_add_empty_animation(sspine_instance instance, int track_index, float mix_duration, float delay);
|
|
|
+
|
|
|
+// bone functions
|
|
|
+SOKOL_SPINE_API_DECL int sspine_num_bones(sspine_skeleton skeleton);
|
|
|
+SOKOL_SPINE_API_DECL sspine_bone sspine_bone_by_name(sspine_skeleton skeleton, const char* name);
|
|
|
+SOKOL_SPINE_API_DECL sspine_bone sspine_bone_by_index(sspine_skeleton skeleton, int index);
|
|
|
+SOKOL_SPINE_API_DECL bool sspine_bone_valid(sspine_bone bone);
|
|
|
+SOKOL_SPINE_API_DECL bool sspine_bone_equal(sspine_bone first, sspine_bone second);
|
|
|
+SOKOL_SPINE_API_DECL sspine_bone_info sspine_get_bone_info(sspine_bone bone);
|
|
|
+SOKOL_SPINE_API_DECL void sspine_set_bone_transform(sspine_instance instance, sspine_bone bone, const sspine_bone_transform* transform);
|
|
|
+SOKOL_SPINE_API_DECL void sspine_set_bone_position(sspine_instance instance, sspine_bone bone, sspine_vec2 position);
|
|
|
+SOKOL_SPINE_API_DECL void sspine_set_bone_rotation(sspine_instance instance, sspine_bone bone, float rotation);
|
|
|
+SOKOL_SPINE_API_DECL void sspine_set_bone_scale(sspine_instance instance, sspine_bone bone, sspine_vec2 scale);
|
|
|
+SOKOL_SPINE_API_DECL void sspine_set_bone_shear(sspine_instance instance, sspine_bone bone, sspine_vec2 shear);
|
|
|
+SOKOL_SPINE_API_DECL sspine_bone_transform sspine_get_bone_transform(sspine_instance instance, sspine_bone bone);
|
|
|
+SOKOL_SPINE_API_DECL sspine_vec2 sspine_get_bone_position(sspine_instance instance, sspine_bone bone);
|
|
|
+SOKOL_SPINE_API_DECL float sspine_get_bone_rotation(sspine_instance instance, sspine_bone bone);
|
|
|
+SOKOL_SPINE_API_DECL sspine_vec2 sspine_get_bone_scale(sspine_instance instance, sspine_bone bone);
|
|
|
+SOKOL_SPINE_API_DECL sspine_vec2 sspine_get_bone_shear(sspine_instance instance, sspine_bone bone);
|
|
|
+SOKOL_SPINE_API_DECL sspine_vec2 sspine_get_bone_world_position(sspine_instance instance, sspine_bone bone);
|
|
|
+SOKOL_SPINE_API_DECL sspine_vec2 sspine_bone_local_to_world(sspine_instance instance, sspine_bone bone, sspine_vec2 local_pos);
|
|
|
+SOKOL_SPINE_API_DECL sspine_vec2 sspine_bone_world_to_local(sspine_instance instance, sspine_bone bone, sspine_vec2 world_pos);
|
|
|
+
|
|
|
+// slot functions
|
|
|
+SOKOL_SPINE_API_DECL int sspine_num_slots(sspine_skeleton skeleton);
|
|
|
+SOKOL_SPINE_API_DECL sspine_slot sspine_slot_by_name(sspine_skeleton skeleton, const char* name);
|
|
|
+SOKOL_SPINE_API_DECL sspine_slot sspine_slot_by_index(sspine_skeleton skeleton, int index);
|
|
|
+SOKOL_SPINE_API_DECL bool sspine_slot_valid(sspine_slot slot);
|
|
|
+SOKOL_SPINE_API_DECL bool sspine_slot_equal(sspine_slot first, sspine_slot second);
|
|
|
+SOKOL_SPINE_API_DECL sspine_slot_info sspine_get_slot_info(sspine_slot slot);
|
|
|
+SOKOL_SPINE_API_DECL void sspine_set_slot_color(sspine_instance instance, sspine_slot slot, sspine_color color);
|
|
|
+SOKOL_SPINE_API_DECL sspine_color sspine_get_slot_color(sspine_instance instance, sspine_slot slot);
|
|
|
+
|
|
|
+// event functions
|
|
|
+SOKOL_SPINE_API_DECL int sspine_num_events(sspine_skeleton skeleton);
|
|
|
+SOKOL_SPINE_API_DECL sspine_event sspine_event_by_name(sspine_skeleton skeleton, const char* name);
|
|
|
+SOKOL_SPINE_API_DECL sspine_event sspine_event_by_index(sspine_skeleton skeleton, int index);
|
|
|
+SOKOL_SPINE_API_DECL bool sspine_event_valid(sspine_event event);
|
|
|
+SOKOL_SPINE_API_DECL bool sspine_event_equal(sspine_event first, sspine_event second);
|
|
|
+SOKOL_SPINE_API_DECL sspine_event_info sspine_get_event_info(sspine_event event);
|
|
|
+
|
|
|
+// ik target functions
|
|
|
+SOKOL_SPINE_API_DECL int sspine_num_iktargets(sspine_skeleton skeleton);
|
|
|
+SOKOL_SPINE_API_DECL sspine_iktarget sspine_iktarget_by_name(sspine_skeleton skeleton, const char* name);
|
|
|
+SOKOL_SPINE_API_DECL sspine_iktarget sspine_iktarget_by_index(sspine_skeleton skeleton, int index);
|
|
|
+SOKOL_SPINE_API_DECL bool sspine_iktarget_valid(sspine_iktarget iktarget);
|
|
|
+SOKOL_SPINE_API_DECL bool sspine_iktarget_equal(sspine_iktarget first, sspine_iktarget second);
|
|
|
+SOKOL_SPINE_API_DECL sspine_iktarget_info sspine_get_iktarget_info(sspine_iktarget iktarget);
|
|
|
+SOKOL_SPINE_API_DECL void sspine_set_iktarget_world_pos(sspine_instance instance, sspine_iktarget iktarget, sspine_vec2 world_pos);
|
|
|
+
|
|
|
+// skin functions
|
|
|
+SOKOL_SPINE_API_DECL int sspine_num_skins(sspine_skeleton skeleton);
|
|
|
+SOKOL_SPINE_API_DECL sspine_skin sspine_skin_by_name(sspine_skeleton skeleton, const char* name);
|
|
|
+SOKOL_SPINE_API_DECL sspine_skin sspine_skin_by_index(sspine_skeleton skeleton, int index);
|
|
|
+SOKOL_SPINE_API_DECL bool sspine_skin_valid(sspine_skin skin);
|
|
|
+SOKOL_SPINE_API_DECL bool sspine_skin_equal(sspine_skin first, sspine_skin second);
|
|
|
+SOKOL_SPINE_API_DECL sspine_skin_info sspine_get_skin_info(sspine_skin skin);
|
|
|
+SOKOL_SPINE_API_DECL void sspine_set_skin(sspine_instance instance, sspine_skin skin);
|
|
|
+
|
|
|
+#ifdef __cplusplus
|
|
|
+} // extern "C"
|
|
|
+#endif
|
|
|
+
|
|
|
+//-- IMPLEMENTATION ------------------------------------------------------------
|
|
|
+#ifdef SOKOL_SPINE_IMPL
|
|
|
+#define SOKOL_SPINE_IMPL_INCLUDED (1)
|
|
|
+
|
|
|
+#if !defined(SPINE_SPINE_H_)
|
|
|
+#error "Please include spine/spine.h before the sokol_spine.h implementation"
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifndef SOKOL_API_IMPL
|
|
|
+ #define SOKOL_API_IMPL
|
|
|
+#endif
|
|
|
+#ifndef SOKOL_DEBUG
|
|
|
+ #ifndef NDEBUG
|
|
|
+ #define SOKOL_DEBUG (1)
|
|
|
+ #endif
|
|
|
+#endif
|
|
|
+#ifndef SOKOL_ASSERT
|
|
|
+ #include <assert.h>
|
|
|
+ #define SOKOL_ASSERT(c) assert(c)
|
|
|
+#endif
|
|
|
+#ifndef SOKOL_UNREACHABLE
|
|
|
+ #define SOKOL_UNREACHABLE SOKOL_ASSERT(false)
|
|
|
+#endif
|
|
|
+#ifndef SOKOL_UNUSED
|
|
|
+ #define SOKOL_UNUSED(x) (void)(x)
|
|
|
+#endif
|
|
|
+
|
|
|
+#include <stdlib.h> // malloc/free
|
|
|
+#include <string.h> // memset, strcmp
|
|
|
+#include <stdio.h> // stderr, fprintf (debug mode), fputs (release mode)
|
|
|
+
|
|
|
+/*
|
|
|
+ Embedded source compiled with:
|
|
|
+
|
|
|
+ sokol-shdc -i sspine.glsl -o sspine.h -l glsl330:glsl100:hlsl4:metal_macos:metal_ios:metal_sim:wgpu -b
|
|
|
+
|
|
|
+ @vs vs
|
|
|
+ uniform vs_params {
|
|
|
+ mat4 mvp;
|
|
|
+ };
|
|
|
+ in vec2 position;
|
|
|
+ in vec2 texcoord0;
|
|
|
+ in vec4 color0;
|
|
|
+ out vec2 uv;
|
|
|
+ out vec4 color;
|
|
|
+ void main() {
|
|
|
+ gl_Position = mvp * vec4(position, 0.0, 1.0);
|
|
|
+ uv = texcoord0;
|
|
|
+ color = color0;
|
|
|
+ }
|
|
|
+ @end
|
|
|
+
|
|
|
+ @fs fs
|
|
|
+ uniform sampler2D tex;
|
|
|
+ uniform fs_params {
|
|
|
+ float pma;
|
|
|
+ };
|
|
|
+ in vec2 uv;
|
|
|
+ in vec4 color;
|
|
|
+ out vec4 frag_color;
|
|
|
+ void main() {
|
|
|
+ vec4 c0 = texture(tex, uv) * color;
|
|
|
+ vec4 c1 = vec4(c0.rgb * c0.a, c0.a) * color;
|
|
|
+ frag_color = mix(c0, c1, pma);
|
|
|
+ }
|
|
|
+ @end
|
|
|
+
|
|
|
+ @program sspine vs fs
|
|
|
+*/
|
|
|
+#if defined(SOKOL_GLCORE33)
|
|
|
+static const char _sspine_vs_source_glsl330[352] = {
|
|
|
+ 0x23,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x33,0x33,0x30,0x0a,0x0a,0x75,0x6e,
|
|
|
+ 0x69,0x66,0x6f,0x72,0x6d,0x20,0x76,0x65,0x63,0x34,0x20,0x76,0x73,0x5f,0x70,0x61,
|
|
|
+ 0x72,0x61,0x6d,0x73,0x5b,0x34,0x5d,0x3b,0x0a,0x6c,0x61,0x79,0x6f,0x75,0x74,0x28,
|
|
|
+ 0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x30,0x29,0x20,0x69,0x6e,
|
|
|
+ 0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x3b,0x0a,
|
|
|
+ 0x6f,0x75,0x74,0x20,0x76,0x65,0x63,0x32,0x20,0x75,0x76,0x3b,0x0a,0x6c,0x61,0x79,
|
|
|
+ 0x6f,0x75,0x74,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x31,
|
|
|
+ 0x29,0x20,0x69,0x6e,0x20,0x76,0x65,0x63,0x32,0x20,0x74,0x65,0x78,0x63,0x6f,0x6f,
|
|
|
+ 0x72,0x64,0x30,0x3b,0x0a,0x6f,0x75,0x74,0x20,0x76,0x65,0x63,0x34,0x20,0x63,0x6f,
|
|
|
+ 0x6c,0x6f,0x72,0x3b,0x0a,0x6c,0x61,0x79,0x6f,0x75,0x74,0x28,0x6c,0x6f,0x63,0x61,
|
|
|
+ 0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x32,0x29,0x20,0x69,0x6e,0x20,0x76,0x65,0x63,
|
|
|
+ 0x34,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x30,0x3b,0x0a,0x0a,0x76,0x6f,0x69,0x64,0x20,
|
|
|
+ 0x6d,0x61,0x69,0x6e,0x28,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x67,0x6c,0x5f,
|
|
|
+ 0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x6d,0x61,0x74,0x34,0x28,
|
|
|
+ 0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x30,0x5d,0x2c,0x20,0x76,0x73,
|
|
|
+ 0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x31,0x5d,0x2c,0x20,0x76,0x73,0x5f,0x70,
|
|
|
+ 0x61,0x72,0x61,0x6d,0x73,0x5b,0x32,0x5d,0x2c,0x20,0x76,0x73,0x5f,0x70,0x61,0x72,
|
|
|
+ 0x61,0x6d,0x73,0x5b,0x33,0x5d,0x29,0x20,0x2a,0x20,0x76,0x65,0x63,0x34,0x28,0x70,
|
|
|
+ 0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x2c,0x20,0x30,0x2e,0x30,0x2c,0x20,0x31,0x2e,
|
|
|
+ 0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x75,0x76,0x20,0x3d,0x20,0x74,0x65,0x78,
|
|
|
+ 0x63,0x6f,0x6f,0x72,0x64,0x30,0x3b,0x0a,0x20,0x20,0x20,0x20,0x63,0x6f,0x6c,0x6f,
|
|
|
+ 0x72,0x20,0x3d,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x30,0x3b,0x0a,0x7d,0x0a,0x0a,0x00,
|
|
|
+};
|
|
|
+static const char _sspine_fs_source_glsl330[300] = {
|
|
|
+ 0x23,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x33,0x33,0x30,0x0a,0x0a,0x75,0x6e,
|
|
|
+ 0x69,0x66,0x6f,0x72,0x6d,0x20,0x76,0x65,0x63,0x34,0x20,0x66,0x73,0x5f,0x70,0x61,
|
|
|
+ 0x72,0x61,0x6d,0x73,0x5b,0x31,0x5d,0x3b,0x0a,0x75,0x6e,0x69,0x66,0x6f,0x72,0x6d,
|
|
|
+ 0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x32,0x44,0x20,0x74,0x65,0x78,0x3b,0x0a,
|
|
|
+ 0x0a,0x69,0x6e,0x20,0x76,0x65,0x63,0x32,0x20,0x75,0x76,0x3b,0x0a,0x69,0x6e,0x20,
|
|
|
+ 0x76,0x65,0x63,0x34,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x3b,0x0a,0x6c,0x61,0x79,0x6f,
|
|
|
+ 0x75,0x74,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x30,0x29,
|
|
|
+ 0x20,0x6f,0x75,0x74,0x20,0x76,0x65,0x63,0x34,0x20,0x66,0x72,0x61,0x67,0x5f,0x63,
|
|
|
+ 0x6f,0x6c,0x6f,0x72,0x3b,0x0a,0x0a,0x76,0x6f,0x69,0x64,0x20,0x6d,0x61,0x69,0x6e,
|
|
|
+ 0x28,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x34,0x20,0x5f,0x32,
|
|
|
+ 0x35,0x20,0x3d,0x20,0x74,0x65,0x78,0x74,0x75,0x72,0x65,0x28,0x74,0x65,0x78,0x2c,
|
|
|
+ 0x20,0x75,0x76,0x29,0x20,0x2a,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x3b,0x0a,0x20,0x20,
|
|
|
+ 0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x33,0x34,0x20,0x3d,0x20,0x5f,0x32,
|
|
|
+ 0x35,0x2e,0x77,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x72,0x61,0x67,0x5f,0x63,0x6f,
|
|
|
+ 0x6c,0x6f,0x72,0x20,0x3d,0x20,0x6d,0x69,0x78,0x28,0x5f,0x32,0x35,0x2c,0x20,0x76,
|
|
|
+ 0x65,0x63,0x34,0x28,0x5f,0x32,0x35,0x2e,0x78,0x79,0x7a,0x20,0x2a,0x20,0x5f,0x33,
|
|
|
+ 0x34,0x2c,0x20,0x5f,0x33,0x34,0x29,0x20,0x2a,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x2c,
|
|
|
+ 0x20,0x76,0x65,0x63,0x34,0x28,0x66,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,
|
|
|
+ 0x30,0x5d,0x2e,0x78,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x00,
|
|
|
+};
|
|
|
+#elif defined(SOKOL_GLES2) || defined(SOKOL_GLES3)
|
|
|
+static const char _sspine_vs_source_glsl100[318] = {
|
|
|
+ 0x23,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x31,0x30,0x30,0x0a,0x0a,0x75,0x6e,
|
|
|
+ 0x69,0x66,0x6f,0x72,0x6d,0x20,0x76,0x65,0x63,0x34,0x20,0x76,0x73,0x5f,0x70,0x61,
|
|
|
+ 0x72,0x61,0x6d,0x73,0x5b,0x34,0x5d,0x3b,0x0a,0x61,0x74,0x74,0x72,0x69,0x62,0x75,
|
|
|
+ 0x74,0x65,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,
|
|
|
+ 0x3b,0x0a,0x76,0x61,0x72,0x79,0x69,0x6e,0x67,0x20,0x76,0x65,0x63,0x32,0x20,0x75,
|
|
|
+ 0x76,0x3b,0x0a,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x20,0x76,0x65,0x63,
|
|
|
+ 0x32,0x20,0x74,0x65,0x78,0x63,0x6f,0x6f,0x72,0x64,0x30,0x3b,0x0a,0x76,0x61,0x72,
|
|
|
+ 0x79,0x69,0x6e,0x67,0x20,0x76,0x65,0x63,0x34,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x3b,
|
|
|
+ 0x0a,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x20,0x76,0x65,0x63,0x34,0x20,
|
|
|
+ 0x63,0x6f,0x6c,0x6f,0x72,0x30,0x3b,0x0a,0x0a,0x76,0x6f,0x69,0x64,0x20,0x6d,0x61,
|
|
|
+ 0x69,0x6e,0x28,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x67,0x6c,0x5f,0x50,0x6f,
|
|
|
+ 0x73,0x69,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x6d,0x61,0x74,0x34,0x28,0x76,0x73,
|
|
|
+ 0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x30,0x5d,0x2c,0x20,0x76,0x73,0x5f,0x70,
|
|
|
+ 0x61,0x72,0x61,0x6d,0x73,0x5b,0x31,0x5d,0x2c,0x20,0x76,0x73,0x5f,0x70,0x61,0x72,
|
|
|
+ 0x61,0x6d,0x73,0x5b,0x32,0x5d,0x2c,0x20,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,
|
|
|
+ 0x73,0x5b,0x33,0x5d,0x29,0x20,0x2a,0x20,0x76,0x65,0x63,0x34,0x28,0x70,0x6f,0x73,
|
|
|
+ 0x69,0x74,0x69,0x6f,0x6e,0x2c,0x20,0x30,0x2e,0x30,0x2c,0x20,0x31,0x2e,0x30,0x29,
|
|
|
+ 0x3b,0x0a,0x20,0x20,0x20,0x20,0x75,0x76,0x20,0x3d,0x20,0x74,0x65,0x78,0x63,0x6f,
|
|
|
+ 0x6f,0x72,0x64,0x30,0x3b,0x0a,0x20,0x20,0x20,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x20,
|
|
|
+ 0x3d,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x30,0x3b,0x0a,0x7d,0x0a,0x0a,0x00,
|
|
|
+};
|
|
|
+static const char _sspine_fs_source_glsl100[356] = {
|
|
|
+ 0x23,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x31,0x30,0x30,0x0a,0x70,0x72,0x65,
|
|
|
+ 0x63,0x69,0x73,0x69,0x6f,0x6e,0x20,0x6d,0x65,0x64,0x69,0x75,0x6d,0x70,0x20,0x66,
|
|
|
+ 0x6c,0x6f,0x61,0x74,0x3b,0x0a,0x70,0x72,0x65,0x63,0x69,0x73,0x69,0x6f,0x6e,0x20,
|
|
|
+ 0x68,0x69,0x67,0x68,0x70,0x20,0x69,0x6e,0x74,0x3b,0x0a,0x0a,0x75,0x6e,0x69,0x66,
|
|
|
+ 0x6f,0x72,0x6d,0x20,0x68,0x69,0x67,0x68,0x70,0x20,0x76,0x65,0x63,0x34,0x20,0x66,
|
|
|
+ 0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x31,0x5d,0x3b,0x0a,0x75,0x6e,0x69,
|
|
|
+ 0x66,0x6f,0x72,0x6d,0x20,0x68,0x69,0x67,0x68,0x70,0x20,0x73,0x61,0x6d,0x70,0x6c,
|
|
|
+ 0x65,0x72,0x32,0x44,0x20,0x74,0x65,0x78,0x3b,0x0a,0x0a,0x76,0x61,0x72,0x79,0x69,
|
|
|
+ 0x6e,0x67,0x20,0x68,0x69,0x67,0x68,0x70,0x20,0x76,0x65,0x63,0x32,0x20,0x75,0x76,
|
|
|
+ 0x3b,0x0a,0x76,0x61,0x72,0x79,0x69,0x6e,0x67,0x20,0x68,0x69,0x67,0x68,0x70,0x20,
|
|
|
+ 0x76,0x65,0x63,0x34,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x3b,0x0a,0x0a,0x76,0x6f,0x69,
|
|
|
+ 0x64,0x20,0x6d,0x61,0x69,0x6e,0x28,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x68,
|
|
|
+ 0x69,0x67,0x68,0x70,0x20,0x76,0x65,0x63,0x34,0x20,0x5f,0x32,0x35,0x20,0x3d,0x20,
|
|
|
+ 0x74,0x65,0x78,0x74,0x75,0x72,0x65,0x32,0x44,0x28,0x74,0x65,0x78,0x2c,0x20,0x75,
|
|
|
+ 0x76,0x29,0x20,0x2a,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x3b,0x0a,0x20,0x20,0x20,0x20,
|
|
|
+ 0x68,0x69,0x67,0x68,0x70,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x33,0x34,0x20,
|
|
|
+ 0x3d,0x20,0x5f,0x32,0x35,0x2e,0x77,0x3b,0x0a,0x20,0x20,0x20,0x20,0x67,0x6c,0x5f,
|
|
|
+ 0x46,0x72,0x61,0x67,0x44,0x61,0x74,0x61,0x5b,0x30,0x5d,0x20,0x3d,0x20,0x6d,0x69,
|
|
|
+ 0x78,0x28,0x5f,0x32,0x35,0x2c,0x20,0x76,0x65,0x63,0x34,0x28,0x5f,0x32,0x35,0x2e,
|
|
|
+ 0x78,0x79,0x7a,0x20,0x2a,0x20,0x5f,0x33,0x34,0x2c,0x20,0x5f,0x33,0x34,0x29,0x20,
|
|
|
+ 0x2a,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x2c,0x20,0x76,0x65,0x63,0x34,0x28,0x66,0x73,
|
|
|
+ 0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x30,0x5d,0x2e,0x78,0x29,0x29,0x3b,0x0a,
|
|
|
+ 0x7d,0x0a,0x0a,0x00,
|
|
|
+};
|
|
|
+#elif defined(SOKOL_D3D11)
|
|
|
+static const uint8_t _sspine_vs_bytecode_hlsl4[844] = {
|
|
|
+ 0x44,0x58,0x42,0x43,0xb2,0xdb,0x57,0x6f,0x29,0xa5,0x26,0x49,0xa3,0x0e,0xb4,0x9e,
|
|
|
+ 0x0f,0x0d,0x7f,0xcd,0x01,0x00,0x00,0x00,0x4c,0x03,0x00,0x00,0x05,0x00,0x00,0x00,
|
|
|
+ 0x34,0x00,0x00,0x00,0xf4,0x00,0x00,0x00,0x58,0x01,0x00,0x00,0xc8,0x01,0x00,0x00,
|
|
|
+ 0xd0,0x02,0x00,0x00,0x52,0x44,0x45,0x46,0xb8,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
|
|
|
+ 0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x1c,0x00,0x00,0x00,0x00,0x04,0xfe,0xff,
|
|
|
+ 0x10,0x81,0x00,0x00,0x90,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,
|
|
|
+ 0x73,0x00,0xab,0xab,0x3c,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x60,0x00,0x00,0x00,
|
|
|
+ 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x80,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x5f,0x32,0x31,0x5f,0x6d,0x76,0x70,0x00,0x02,0x00,0x03,0x00,
|
|
|
+ 0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4d,0x69,0x63,0x72,
|
|
|
+ 0x6f,0x73,0x6f,0x66,0x74,0x20,0x28,0x52,0x29,0x20,0x48,0x4c,0x53,0x4c,0x20,0x53,
|
|
|
+ 0x68,0x61,0x64,0x65,0x72,0x20,0x43,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x72,0x20,0x31,
|
|
|
+ 0x30,0x2e,0x31,0x00,0x49,0x53,0x47,0x4e,0x5c,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
|
|
|
+ 0x08,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x00,0x00,0x50,0x00,0x00,0x00,
|
|
|
+ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
|
|
|
+ 0x03,0x03,0x00,0x00,0x50,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x03,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x0f,0x0f,0x00,0x00,0x54,0x45,0x58,0x43,
|
|
|
+ 0x4f,0x4f,0x52,0x44,0x00,0xab,0xab,0xab,0x4f,0x53,0x47,0x4e,0x68,0x00,0x00,0x00,
|
|
|
+ 0x03,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0c,0x00,0x00,
|
|
|
+ 0x50,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
|
|
|
+ 0x01,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x59,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x01,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,
|
|
|
+ 0x54,0x45,0x58,0x43,0x4f,0x4f,0x52,0x44,0x00,0x53,0x56,0x5f,0x50,0x6f,0x73,0x69,
|
|
|
+ 0x74,0x69,0x6f,0x6e,0x00,0xab,0xab,0xab,0x53,0x48,0x44,0x52,0x00,0x01,0x00,0x00,
|
|
|
+ 0x40,0x00,0x01,0x00,0x40,0x00,0x00,0x00,0x59,0x00,0x00,0x04,0x46,0x8e,0x20,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x5f,0x00,0x00,0x03,0x32,0x10,0x10,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x5f,0x00,0x00,0x03,0x32,0x10,0x10,0x00,0x01,0x00,0x00,0x00,
|
|
|
+ 0x5f,0x00,0x00,0x03,0xf2,0x10,0x10,0x00,0x02,0x00,0x00,0x00,0x65,0x00,0x00,0x03,
|
|
|
+ 0x32,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x65,0x00,0x00,0x03,0xf2,0x20,0x10,0x00,
|
|
|
+ 0x01,0x00,0x00,0x00,0x67,0x00,0x00,0x04,0xf2,0x20,0x10,0x00,0x02,0x00,0x00,0x00,
|
|
|
+ 0x01,0x00,0x00,0x00,0x68,0x00,0x00,0x02,0x01,0x00,0x00,0x00,0x36,0x00,0x00,0x05,
|
|
|
+ 0x32,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x46,0x10,0x10,0x00,0x01,0x00,0x00,0x00,
|
|
|
+ 0x36,0x00,0x00,0x05,0xf2,0x20,0x10,0x00,0x01,0x00,0x00,0x00,0x46,0x1e,0x10,0x00,
|
|
|
+ 0x02,0x00,0x00,0x00,0x38,0x00,0x00,0x08,0xf2,0x00,0x10,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x56,0x15,0x10,0x00,0x00,0x00,0x00,0x00,0x46,0x8e,0x20,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x01,0x00,0x00,0x00,0x32,0x00,0x00,0x0a,0xf2,0x00,0x10,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x06,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x46,0x8e,0x20,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x46,0x0e,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,
|
|
|
+ 0xf2,0x20,0x10,0x00,0x02,0x00,0x00,0x00,0x46,0x0e,0x10,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x46,0x8e,0x20,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x3e,0x00,0x00,0x01,
|
|
|
+ 0x53,0x54,0x41,0x54,0x74,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+};
|
|
|
+static const uint8_t _sspine_fs_bytecode_hlsl4[876] = {
|
|
|
+ 0x44,0x58,0x42,0x43,0xd8,0xf3,0x35,0x5e,0xf6,0xd6,0x61,0x80,0x71,0x85,0x56,0x46,
|
|
|
+ 0x08,0x09,0x74,0xcd,0x01,0x00,0x00,0x00,0x6c,0x03,0x00,0x00,0x05,0x00,0x00,0x00,
|
|
|
+ 0x34,0x00,0x00,0x00,0x44,0x01,0x00,0x00,0x90,0x01,0x00,0x00,0xc4,0x01,0x00,0x00,
|
|
|
+ 0xf0,0x02,0x00,0x00,0x52,0x44,0x45,0x46,0x08,0x01,0x00,0x00,0x01,0x00,0x00,0x00,
|
|
|
+ 0x98,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x1c,0x00,0x00,0x00,0x00,0x04,0xff,0xff,
|
|
|
+ 0x10,0x81,0x00,0x00,0xe0,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x89,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
|
|
|
+ 0x05,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
|
|
|
+ 0x01,0x00,0x00,0x00,0x0d,0x00,0x00,0x00,0x8d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x5f,0x74,0x65,0x78,0x5f,0x73,0x61,0x6d,
|
|
|
+ 0x70,0x6c,0x65,0x72,0x00,0x74,0x65,0x78,0x00,0x66,0x73,0x5f,0x70,0x61,0x72,0x61,
|
|
|
+ 0x6d,0x73,0x00,0xab,0x8d,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0xb0,0x00,0x00,0x00,
|
|
|
+ 0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0xd0,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x5f,0x35,0x30,0x5f,0x70,0x6d,0x61,0x00,0x00,0x00,0x03,0x00,
|
|
|
+ 0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4d,0x69,0x63,0x72,
|
|
|
+ 0x6f,0x73,0x6f,0x66,0x74,0x20,0x28,0x52,0x29,0x20,0x48,0x4c,0x53,0x4c,0x20,0x53,
|
|
|
+ 0x68,0x61,0x64,0x65,0x72,0x20,0x43,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x72,0x20,0x31,
|
|
|
+ 0x30,0x2e,0x31,0x00,0x49,0x53,0x47,0x4e,0x44,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
|
|
|
+ 0x08,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x00,0x00,0x38,0x00,0x00,0x00,
|
|
|
+ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
|
|
|
+ 0x0f,0x0f,0x00,0x00,0x54,0x45,0x58,0x43,0x4f,0x4f,0x52,0x44,0x00,0xab,0xab,0xab,
|
|
|
+ 0x4f,0x53,0x47,0x4e,0x2c,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,
|
|
|
+ 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x53,0x56,0x5f,0x54,0x61,0x72,0x67,0x65,
|
|
|
+ 0x74,0x00,0xab,0xab,0x53,0x48,0x44,0x52,0x24,0x01,0x00,0x00,0x40,0x00,0x00,0x00,
|
|
|
+ 0x49,0x00,0x00,0x00,0x59,0x00,0x00,0x04,0x46,0x8e,0x20,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x01,0x00,0x00,0x00,0x5a,0x00,0x00,0x03,0x00,0x60,0x10,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x58,0x18,0x00,0x04,0x00,0x70,0x10,0x00,0x00,0x00,0x00,0x00,0x55,0x55,0x00,0x00,
|
|
|
+ 0x62,0x10,0x00,0x03,0x32,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x62,0x10,0x00,0x03,
|
|
|
+ 0xf2,0x10,0x10,0x00,0x01,0x00,0x00,0x00,0x65,0x00,0x00,0x03,0xf2,0x20,0x10,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x68,0x00,0x00,0x02,0x02,0x00,0x00,0x00,0x45,0x00,0x00,0x09,
|
|
|
+ 0xf2,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x46,0x10,0x10,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x46,0x7e,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x10,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x38,0x00,0x00,0x07,0xf2,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x46,0x0e,0x10,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x46,0x1e,0x10,0x00,0x01,0x00,0x00,0x00,0x38,0x00,0x00,0x07,
|
|
|
+ 0x72,0x00,0x10,0x00,0x01,0x00,0x00,0x00,0xf6,0x0f,0x10,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x46,0x02,0x10,0x00,0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x05,0x82,0x00,0x10,0x00,
|
|
|
+ 0x01,0x00,0x00,0x00,0x3a,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x32,0x00,0x00,0x0a,
|
|
|
+ 0xf2,0x00,0x10,0x00,0x01,0x00,0x00,0x00,0x46,0x0e,0x10,0x00,0x01,0x00,0x00,0x00,
|
|
|
+ 0x46,0x1e,0x10,0x00,0x01,0x00,0x00,0x00,0x46,0x0e,0x10,0x80,0x41,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x32,0x00,0x00,0x0a,0xf2,0x20,0x10,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x06,0x80,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x0e,0x10,0x00,
|
|
|
+ 0x01,0x00,0x00,0x00,0x46,0x0e,0x10,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x01,
|
|
|
+ 0x53,0x54,0x41,0x54,0x74,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+};
|
|
|
+#elif defined(SOKOL_METAL)
|
|
|
+static const uint8_t _sspine_vs_bytecode_metal_macos[3068] = {
|
|
|
+ 0x4d,0x54,0x4c,0x42,0x01,0x80,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0xfc,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x6d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x3b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0xf0,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x6d,0x00,0x00,0x00,
|
|
|
+ 0x4e,0x41,0x4d,0x45,0x06,0x00,0x6d,0x61,0x69,0x6e,0x30,0x00,0x54,0x59,0x50,0x45,
|
|
|
+ 0x01,0x00,0x00,0x48,0x41,0x53,0x48,0x20,0x00,0x00,0x1c,0x82,0xf4,0xbb,0x79,0xa7,
|
|
|
+ 0x30,0x7f,0x4a,0xbc,0xb6,0x93,0x11,0x29,0xf6,0x24,0x44,0x87,0xfa,0x98,0x7e,0xd3,
|
|
|
+ 0x73,0xca,0x18,0xc6,0xe1,0x22,0x50,0x45,0x09,0x4f,0x46,0x46,0x54,0x18,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x56,0x45,0x52,0x53,0x08,0x00,0x01,0x00,0x08,
|
|
|
+ 0x00,0x01,0x00,0x01,0x00,0x45,0x4e,0x44,0x54,0x37,0x00,0x00,0x00,0x56,0x41,0x54,
|
|
|
+ 0x54,0x22,0x00,0x03,0x00,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x00,0x00,0x80,
|
|
|
+ 0x74,0x65,0x78,0x63,0x6f,0x6f,0x72,0x64,0x30,0x00,0x01,0x80,0x63,0x6f,0x6c,0x6f,
|
|
|
+ 0x72,0x30,0x00,0x02,0x80,0x56,0x41,0x54,0x59,0x05,0x00,0x03,0x00,0x04,0x04,0x06,
|
|
|
+ 0x45,0x4e,0x44,0x54,0x04,0x00,0x00,0x00,0x45,0x4e,0x44,0x54,0xde,0xc0,0x17,0x0b,
|
|
|
+ 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0xdc,0x0a,0x00,0x00,0xff,0xff,0xff,0xff,
|
|
|
+ 0x42,0x43,0xc0,0xde,0x21,0x0c,0x00,0x00,0xb4,0x02,0x00,0x00,0x0b,0x82,0x20,0x00,
|
|
|
+ 0x02,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x07,0x81,0x23,0x91,0x41,0xc8,0x04,0x49,
|
|
|
+ 0x06,0x10,0x32,0x39,0x92,0x01,0x84,0x0c,0x25,0x05,0x08,0x19,0x1e,0x04,0x8b,0x62,
|
|
|
+ 0x80,0x14,0x45,0x02,0x42,0x92,0x0b,0x42,0xa4,0x10,0x32,0x14,0x38,0x08,0x18,0x49,
|
|
|
+ 0x0a,0x32,0x44,0x24,0x48,0x0a,0x90,0x21,0x23,0xc4,0x52,0x80,0x0c,0x19,0x21,0x72,
|
|
|
+ 0x24,0x07,0xc8,0x48,0x11,0x62,0xa8,0xa0,0xa8,0x40,0xc6,0xf0,0x01,0x00,0x00,0x00,
|
|
|
+ 0x51,0x18,0x00,0x00,0x81,0x00,0x00,0x00,0x1b,0xc8,0x25,0xf8,0xff,0xff,0xff,0xff,
|
|
|
+ 0x01,0x90,0x80,0x8a,0x18,0x87,0x77,0x90,0x07,0x79,0x28,0x87,0x71,0xa0,0x07,0x76,
|
|
|
+ 0xc8,0x87,0x36,0x90,0x87,0x77,0xa8,0x07,0x77,0x20,0x87,0x72,0x20,0x87,0x36,0x20,
|
|
|
+ 0x87,0x74,0xb0,0x87,0x74,0x20,0x87,0x72,0x68,0x83,0x79,0x88,0x07,0x79,0xa0,0x87,
|
|
|
+ 0x36,0x30,0x07,0x78,0x68,0x83,0x76,0x08,0x07,0x7a,0x40,0x07,0xc0,0x1c,0xc2,0x81,
|
|
|
+ 0x1d,0xe6,0xa1,0x1c,0x00,0x82,0x1c,0xd2,0x61,0x1e,0xc2,0x41,0x1c,0xd8,0xa1,0x1c,
|
|
|
+ 0xda,0x80,0x1e,0xc2,0x21,0x1d,0xd8,0xa1,0x0d,0xc6,0x21,0x1c,0xd8,0x81,0x1d,0xe6,
|
|
|
+ 0x01,0x30,0x87,0x70,0x60,0x87,0x79,0x28,0x07,0x80,0x60,0x87,0x72,0x98,0x87,0x79,
|
|
|
+ 0x68,0x03,0x78,0x90,0x87,0x72,0x18,0x87,0x74,0x98,0x87,0x72,0x68,0x03,0x73,0x80,
|
|
|
+ 0x87,0x76,0x08,0x07,0x72,0x00,0xcc,0x21,0x1c,0xd8,0x61,0x1e,0xca,0x01,0x20,0xdc,
|
|
|
+ 0xe1,0x1d,0xda,0xc0,0x1c,0xe4,0x21,0x1c,0xda,0xa1,0x1c,0xda,0x00,0x1e,0xde,0x21,
|
|
|
+ 0x1d,0xdc,0x81,0x1e,0xca,0x41,0x1e,0xda,0xa0,0x1c,0xd8,0x21,0x1d,0xda,0x01,0xa0,
|
|
|
+ 0x07,0x79,0xa8,0x87,0x72,0x00,0x06,0x77,0x78,0x87,0x36,0x30,0x07,0x79,0x08,0x87,
|
|
|
+ 0x76,0x28,0x87,0x36,0x80,0x87,0x77,0x48,0x07,0x77,0xa0,0x87,0x72,0x90,0x87,0x36,
|
|
|
+ 0x28,0x07,0x76,0x48,0x87,0x76,0x68,0x03,0x77,0x78,0x07,0x77,0x68,0x03,0x76,0x28,
|
|
|
+ 0x87,0x70,0x30,0x07,0x80,0x70,0x87,0x77,0x68,0x83,0x74,0x70,0x07,0x73,0x98,0x87,
|
|
|
+ 0x36,0x30,0x07,0x78,0x68,0x83,0x76,0x08,0x07,0x7a,0x40,0x07,0x80,0x1e,0xe4,0xa1,
|
|
|
+ 0x1e,0xca,0x01,0x20,0xdc,0xe1,0x1d,0xda,0x40,0x1d,0xea,0xa1,0x1d,0xe0,0xa1,0x0d,
|
|
|
+ 0xe8,0x21,0x1c,0xc4,0x81,0x1d,0xca,0x61,0x1e,0x00,0x73,0x08,0x07,0x76,0x98,0x87,
|
|
|
+ 0x72,0x00,0x08,0x77,0x78,0x87,0x36,0x70,0x87,0x70,0x70,0x87,0x79,0x68,0x03,0x73,
|
|
|
+ 0x80,0x87,0x36,0x68,0x87,0x70,0xa0,0x07,0x74,0x00,0xe8,0x41,0x1e,0xea,0xa1,0x1c,
|
|
|
+ 0x00,0xc2,0x1d,0xde,0xa1,0x0d,0xe6,0x21,0x1d,0xce,0xc1,0x1d,0xca,0x81,0x1c,0xda,
|
|
|
+ 0x40,0x1f,0xca,0x41,0x1e,0xde,0x61,0x1e,0xda,0xc0,0x1c,0xe0,0xa1,0x0d,0xda,0x21,
|
|
|
+ 0x1c,0xe8,0x01,0x1d,0x00,0x7a,0x90,0x87,0x7a,0x28,0x07,0x80,0x70,0x87,0x77,0x68,
|
|
|
+ 0x03,0x7a,0x90,0x87,0x70,0x80,0x07,0x78,0x48,0x07,0x77,0x38,0x87,0x36,0x68,0x87,
|
|
|
+ 0x70,0xa0,0x07,0x74,0x00,0xe8,0x41,0x1e,0xea,0xa1,0x1c,0x00,0x62,0x1e,0xe8,0x21,
|
|
|
+ 0x1c,0xc6,0x61,0x1d,0xda,0x00,0x1e,0xe4,0xe1,0x1d,0xe8,0xa1,0x1c,0xc6,0x81,0x1e,
|
|
|
+ 0xde,0x41,0x1e,0xda,0x40,0x1c,0xea,0xc1,0x1c,0xcc,0xa1,0x1c,0xe4,0xa1,0x0d,0xe6,
|
|
|
+ 0x21,0x1d,0xf4,0xa1,0x1c,0x00,0x3c,0x00,0x88,0x7a,0x70,0x87,0x79,0x08,0x07,0x73,
|
|
|
+ 0x28,0x87,0x36,0x30,0x07,0x78,0x68,0x83,0x76,0x08,0x07,0x7a,0x40,0x07,0x80,0x1e,
|
|
|
+ 0xe4,0xa1,0x1e,0xca,0x01,0x20,0xea,0x61,0x1e,0xca,0xa1,0x0d,0xe6,0xe1,0x1d,0xcc,
|
|
|
+ 0x81,0x1e,0xda,0xc0,0x1c,0xd8,0xe1,0x1d,0xc2,0x81,0x1e,0x00,0x73,0x08,0x07,0x76,
|
|
|
+ 0x98,0x87,0x72,0x00,0x36,0x18,0x02,0x01,0x2c,0x40,0x05,0x00,0x49,0x18,0x00,0x00,
|
|
|
+ 0x01,0x00,0x00,0x00,0x13,0x84,0x40,0x00,0x89,0x20,0x00,0x00,0x1f,0x00,0x00,0x00,
|
|
|
+ 0x32,0x22,0x48,0x09,0x20,0x64,0x85,0x04,0x93,0x22,0xa4,0x84,0x04,0x93,0x22,0xe3,
|
|
|
+ 0x84,0xa1,0x90,0x14,0x12,0x4c,0x8a,0x8c,0x0b,0x84,0xa4,0x4c,0x10,0x44,0x33,0x00,
|
|
|
+ 0xc3,0x08,0x02,0x30,0x8c,0x40,0x00,0x76,0x08,0x42,0x24,0x81,0x98,0x89,0x9a,0x07,
|
|
|
+ 0x7a,0x90,0x87,0x7a,0x18,0x07,0x7a,0x70,0x83,0x76,0x28,0x07,0x7a,0x08,0x07,0x76,
|
|
|
+ 0xd0,0x03,0x3d,0x68,0x87,0x70,0xa0,0x07,0x79,0x48,0x07,0x7c,0x40,0x01,0x39,0x48,
|
|
|
+ 0x9a,0x22,0x4a,0x98,0xfc,0x4a,0xfa,0x1f,0x20,0x02,0x18,0x09,0x05,0x65,0x10,0xc1,
|
|
|
+ 0x10,0x4a,0x31,0x42,0x10,0x87,0xd0,0x40,0xc0,0x1c,0x01,0x18,0xa4,0xc0,0x9a,0x23,
|
|
|
+ 0x00,0x85,0x41,0x04,0x41,0x18,0x46,0x20,0x96,0x11,0x00,0x00,0x13,0xb2,0x70,0x48,
|
|
|
+ 0x07,0x79,0xb0,0x03,0x3a,0x68,0x83,0x70,0x80,0x07,0x78,0x60,0x87,0x72,0x68,0x83,
|
|
|
+ 0x76,0x08,0x87,0x71,0x78,0x87,0x79,0xc0,0x87,0x38,0x80,0x03,0x37,0x88,0x83,0x38,
|
|
|
+ 0x70,0x03,0x38,0xd8,0x70,0x1b,0xe5,0xd0,0x06,0xf0,0xa0,0x07,0x76,0x40,0x07,0x7a,
|
|
|
+ 0x60,0x07,0x74,0xa0,0x07,0x76,0x40,0x07,0x6d,0x90,0x0e,0x71,0xa0,0x07,0x78,0xa0,
|
|
|
+ 0x07,0x78,0xd0,0x06,0xe9,0x80,0x07,0x7a,0x80,0x07,0x7a,0x80,0x07,0x6d,0x90,0x0e,
|
|
|
+ 0x71,0x60,0x07,0x7a,0x10,0x07,0x76,0xa0,0x07,0x71,0x60,0x07,0x6d,0x90,0x0e,0x73,
|
|
|
+ 0x20,0x07,0x7a,0x30,0x07,0x72,0xa0,0x07,0x73,0x20,0x07,0x6d,0x90,0x0e,0x76,0x40,
|
|
|
+ 0x07,0x7a,0x60,0x07,0x74,0xa0,0x07,0x76,0x40,0x07,0x6d,0x60,0x0e,0x73,0x20,0x07,
|
|
|
+ 0x7a,0x30,0x07,0x72,0xa0,0x07,0x73,0x20,0x07,0x6d,0x60,0x0e,0x76,0x40,0x07,0x7a,
|
|
|
+ 0x60,0x07,0x74,0xa0,0x07,0x76,0x40,0x07,0x6d,0x60,0x0f,0x71,0x60,0x07,0x7a,0x10,
|
|
|
+ 0x07,0x76,0xa0,0x07,0x71,0x60,0x07,0x6d,0x60,0x0f,0x72,0x40,0x07,0x7a,0x30,0x07,
|
|
|
+ 0x72,0xa0,0x07,0x73,0x20,0x07,0x6d,0x60,0x0f,0x73,0x20,0x07,0x7a,0x30,0x07,0x72,
|
|
|
+ 0xa0,0x07,0x73,0x20,0x07,0x6d,0x60,0x0f,0x74,0x80,0x07,0x7a,0x60,0x07,0x74,0xa0,
|
|
|
+ 0x07,0x76,0x40,0x07,0x6d,0x60,0x0f,0x76,0x40,0x07,0x7a,0x60,0x07,0x74,0xa0,0x07,
|
|
|
+ 0x76,0x40,0x07,0x6d,0x60,0x0f,0x79,0x60,0x07,0x7a,0x10,0x07,0x72,0x80,0x07,0x7a,
|
|
|
+ 0x10,0x07,0x72,0x80,0x07,0x6d,0x60,0x0f,0x71,0x20,0x07,0x78,0xa0,0x07,0x71,0x20,
|
|
|
+ 0x07,0x78,0xa0,0x07,0x71,0x20,0x07,0x78,0xd0,0x06,0xf6,0x10,0x07,0x79,0x20,0x07,
|
|
|
+ 0x7a,0x20,0x07,0x75,0x60,0x07,0x7a,0x20,0x07,0x75,0x60,0x07,0x6d,0x60,0x0f,0x72,
|
|
|
+ 0x50,0x07,0x76,0xa0,0x07,0x72,0x50,0x07,0x76,0xa0,0x07,0x72,0x50,0x07,0x76,0xd0,
|
|
|
+ 0x06,0xf6,0x50,0x07,0x71,0x20,0x07,0x7a,0x50,0x07,0x71,0x20,0x07,0x7a,0x50,0x07,
|
|
|
+ 0x71,0x20,0x07,0x6d,0x60,0x0f,0x71,0x00,0x07,0x72,0x40,0x07,0x7a,0x10,0x07,0x70,
|
|
|
+ 0x20,0x07,0x74,0xa0,0x07,0x71,0x00,0x07,0x72,0x40,0x07,0x6d,0xe0,0x0e,0x78,0xa0,
|
|
|
+ 0x07,0x71,0x60,0x07,0x7a,0x30,0x07,0x72,0x30,0x84,0x49,0x00,0x00,0x08,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0xc8,0x02,0x01,0x00,0x00,0x0a,0x00,0x00,0x00,0x32,0x1e,0x98,0x10,
|
|
|
+ 0x19,0x11,0x4c,0x90,0x8c,0x09,0x26,0x47,0xc6,0x04,0x43,0x5a,0x25,0x30,0x02,0x50,
|
|
|
+ 0x04,0x05,0x18,0x50,0x08,0x05,0x51,0x06,0x05,0x42,0x6d,0x04,0x80,0xd8,0x58,0x02,
|
|
|
+ 0x33,0x00,0x00,0x00,0x79,0x18,0x00,0x00,0xea,0x00,0x00,0x00,0x1a,0x03,0x4c,0x10,
|
|
|
+ 0x97,0x29,0xa2,0x25,0x10,0xab,0x32,0xb9,0xb9,0xb4,0x37,0xb7,0x21,0xc6,0x32,0x28,
|
|
|
+ 0x00,0xa3,0x50,0xb9,0x1b,0x43,0x0b,0x93,0xfb,0x9a,0x4b,0xd3,0x2b,0x1b,0x62,0x2c,
|
|
|
+ 0x81,0x22,0x2c,0x05,0xe3,0x20,0x08,0x0e,0x8e,0xad,0x0c,0xa4,0xad,0x8c,0x2e,0x8c,
|
|
|
+ 0x0d,0xc4,0xae,0x4c,0x6e,0x2e,0xed,0xcd,0x0d,0x64,0x26,0x06,0x06,0x26,0xc6,0xa5,
|
|
|
+ 0x46,0x46,0x06,0x04,0xa5,0xad,0x8c,0x2e,0x8c,0xcd,0xac,0xac,0x65,0x26,0x06,0x06,
|
|
|
+ 0x26,0xc6,0xa5,0x46,0x46,0x26,0x65,0x88,0xa0,0x10,0x43,0x8c,0x25,0x58,0x8c,0x45,
|
|
|
+ 0x60,0xd1,0x54,0x46,0x17,0xc6,0x36,0x04,0x51,0x8e,0x25,0x58,0x82,0x45,0xe0,0x16,
|
|
|
+ 0x96,0x26,0xe7,0x32,0xf6,0xd6,0x06,0x97,0xc6,0x56,0xe6,0x42,0x56,0xe6,0xf6,0x26,
|
|
|
+ 0xd7,0x36,0xf7,0x45,0x96,0x36,0x17,0x26,0xc6,0x56,0x36,0x44,0x50,0x12,0x72,0x61,
|
|
|
+ 0x69,0x72,0x2e,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x2e,0x66,0x61,0x73,0x74,0x5f,
|
|
|
+ 0x6d,0x61,0x74,0x68,0x5f,0x65,0x6e,0x61,0x62,0x6c,0x65,0x43,0x04,0x65,0x61,0x19,
|
|
|
+ 0x84,0xa5,0xc9,0xb9,0x8c,0xbd,0xb5,0xc1,0xa5,0xb1,0x95,0xb9,0x98,0xc9,0x85,0xb5,
|
|
|
+ 0x95,0x89,0xd5,0x99,0x99,0x95,0xc9,0x7d,0x99,0x95,0xd1,0x8d,0xa1,0x7d,0x91,0xa5,
|
|
|
+ 0xcd,0x85,0x89,0xb1,0x95,0x0d,0x11,0x94,0x86,0x51,0x58,0x9a,0x9c,0x8b,0x5d,0x99,
|
|
|
+ 0x1c,0x5d,0x19,0xde,0xd7,0x5b,0x1d,0x1d,0x5c,0x1d,0x1d,0x97,0xba,0xb9,0x32,0x39,
|
|
|
+ 0x14,0xb6,0xb7,0x31,0x37,0x98,0x14,0x46,0x61,0x69,0x72,0x2e,0x61,0x72,0x67,0x5f,
|
|
|
+ 0x74,0x79,0x70,0x65,0x5f,0x6e,0x61,0x6d,0x65,0x34,0xcc,0xd8,0xde,0xc2,0xe8,0x64,
|
|
|
+ 0xc8,0x84,0xa5,0xc9,0xb9,0x84,0xc9,0x9d,0x7d,0xb9,0x85,0xb5,0x95,0x51,0xa8,0xb3,
|
|
|
+ 0x1b,0xc2,0x28,0x8f,0x02,0x29,0x91,0x22,0x29,0x93,0x42,0x71,0xa9,0x9b,0x2b,0x93,
|
|
|
+ 0x43,0x61,0x7b,0x1b,0x73,0x8b,0x49,0xa1,0x61,0xc6,0xf6,0x16,0x46,0x47,0xc3,0x62,
|
|
|
+ 0xec,0x8d,0xed,0x4d,0x6e,0x08,0xa3,0x3c,0x8a,0xa5,0x44,0xca,0xa5,0x4c,0x0a,0x46,
|
|
|
+ 0x26,0x2c,0x4d,0xce,0x05,0xee,0x6d,0x2e,0x8d,0x2e,0xed,0xcd,0x8d,0xcb,0x19,0xdb,
|
|
|
+ 0x17,0xd4,0xdb,0x5c,0x1a,0x5d,0xda,0x9b,0xdb,0x10,0x45,0xd1,0x94,0x48,0xb9,0x94,
|
|
|
+ 0x49,0xd9,0x86,0x18,0x4a,0xa5,0x64,0x0a,0x47,0x28,0x2c,0x4d,0xce,0xc5,0xae,0x4c,
|
|
|
+ 0x8e,0xae,0x0c,0xef,0x2b,0xcd,0x0d,0xae,0x8e,0x8e,0x52,0x58,0x9a,0x9c,0x0b,0xdb,
|
|
|
+ 0xdb,0x58,0x18,0x5d,0xda,0x9b,0xdb,0x57,0x9a,0x1b,0x59,0x19,0x1e,0xbd,0xb3,0x32,
|
|
|
+ 0xb7,0x32,0xb9,0x30,0xba,0x32,0x32,0x94,0xaf,0xaf,0xb0,0x34,0xb9,0x2f,0x38,0xb6,
|
|
|
+ 0xb0,0xb1,0x32,0xb4,0x37,0x36,0xb2,0x32,0xb9,0xaf,0xaf,0x14,0x22,0x70,0x6f,0x73,
|
|
|
+ 0x69,0x74,0x69,0x6f,0x6e,0x43,0xa8,0x45,0x50,0x3c,0xe5,0x5b,0x84,0x25,0x50,0xc0,
|
|
|
+ 0x40,0x89,0x14,0x49,0x99,0x94,0x30,0x60,0x42,0x57,0x86,0x37,0xf6,0xf6,0x26,0x47,
|
|
|
+ 0x06,0x33,0x84,0x5a,0x02,0xc5,0x53,0xbe,0x25,0x58,0x02,0x05,0x0c,0x94,0x48,0x91,
|
|
|
+ 0x94,0x49,0x19,0x03,0x1a,0x63,0x6f,0x6c,0x6f,0x72,0x30,0x43,0xa8,0x65,0x50,0x3c,
|
|
|
+ 0xe5,0x5b,0x86,0x25,0x50,0xc0,0x40,0x89,0x94,0x4b,0x99,0x94,0x32,0xa0,0x12,0x96,
|
|
|
+ 0x26,0xe7,0x22,0x56,0x67,0x66,0x56,0x26,0xc7,0x27,0x2c,0x4d,0xce,0x45,0xac,0xce,
|
|
|
+ 0xcc,0xac,0x4c,0xee,0x6b,0x2e,0x4d,0xaf,0x8c,0x48,0x58,0x9a,0x9c,0x8b,0x5c,0x59,
|
|
|
+ 0x18,0x19,0xa9,0xb0,0x34,0x39,0x97,0x39,0x3a,0xb9,0xba,0x31,0xba,0x2f,0xba,0x3c,
|
|
|
+ 0xb8,0xb2,0xaf,0x34,0x37,0xb3,0x37,0x22,0x66,0x6c,0x6f,0x61,0x74,0x34,0x78,0x34,
|
|
|
+ 0x1c,0xda,0xec,0xe0,0x86,0x28,0x8b,0xb0,0x10,0x8b,0xa0,0xac,0x81,0xc2,0x06,0x8c,
|
|
|
+ 0xc2,0xd2,0xe4,0x5c,0xc2,0xe4,0xce,0xbe,0xe8,0xf2,0xe0,0xca,0xbe,0xe6,0xd2,0xf4,
|
|
|
+ 0xca,0x78,0x85,0xa5,0xc9,0xb9,0x84,0xc9,0x9d,0x7d,0xd1,0xe5,0xc1,0x95,0x7d,0x85,
|
|
|
+ 0xb1,0xa5,0x9d,0xb9,0x7d,0xcd,0xa5,0xe9,0x95,0x31,0xb1,0x9b,0xfb,0x82,0x0b,0x93,
|
|
|
+ 0x0b,0x6b,0x9b,0xe3,0xf0,0x25,0x13,0x33,0x84,0x0c,0x96,0x43,0x39,0x03,0x05,0x0d,
|
|
|
+ 0x16,0x42,0xf9,0x16,0x61,0x09,0x94,0x34,0x50,0xd4,0x40,0x69,0x03,0xc5,0x0d,0x16,
|
|
|
+ 0x42,0x79,0x83,0x05,0x51,0x22,0x05,0x0e,0x94,0x49,0x89,0x83,0x21,0x88,0x22,0x06,
|
|
|
+ 0x0a,0x19,0x28,0x66,0xa0,0xc8,0xc1,0x10,0x23,0x01,0x94,0x4e,0x99,0x03,0x3e,0x6f,
|
|
|
+ 0x6d,0x6e,0x69,0x70,0x6f,0x74,0x65,0x6e,0x74,0x20,0x63,0x68,0x61,0x72,0x7c,0xa6,
|
|
|
+ 0xd2,0xda,0xe0,0xd8,0xca,0x40,0x86,0x56,0x56,0x40,0xa8,0x84,0x82,0x82,0x86,0x08,
|
|
|
+ 0x8a,0x1d,0x0c,0x31,0x94,0x3a,0x50,0xee,0xa0,0x49,0x86,0x18,0x0a,0x1e,0x28,0x78,
|
|
|
+ 0xd0,0x24,0x23,0x22,0x76,0x60,0x07,0x7b,0x68,0x07,0x37,0x68,0x87,0x77,0x20,0x87,
|
|
|
+ 0x7a,0x60,0x87,0x72,0x70,0x03,0x73,0x60,0x87,0x70,0x38,0x87,0x79,0x98,0x22,0x04,
|
|
|
+ 0xc3,0x08,0x85,0x1d,0xd8,0xc1,0x1e,0xda,0xc1,0x0d,0xd2,0x81,0x1c,0xca,0xc1,0x1d,
|
|
|
+ 0xe8,0x61,0x4a,0x50,0x8c,0x58,0xc2,0x21,0x1d,0xe4,0xc1,0x0d,0xec,0xa1,0x1c,0xe4,
|
|
|
+ 0x61,0x1e,0xd2,0xe1,0x1d,0xdc,0x61,0x4a,0x60,0x8c,0xa0,0xc2,0x21,0x1d,0xe4,0xc1,
|
|
|
+ 0x0d,0xd8,0x21,0x1c,0xdc,0xe1,0x1c,0xea,0x21,0x1c,0xce,0xa1,0x1c,0x7e,0xc1,0x1e,
|
|
|
+ 0xca,0x41,0x1e,0xe6,0x21,0x1d,0xde,0xc1,0x1d,0xa6,0x04,0xc8,0x88,0x29,0x1c,0xd2,
|
|
|
+ 0x41,0x1e,0xdc,0x60,0x1c,0xde,0xa1,0x1d,0xe0,0x21,0x1d,0xd8,0xa1,0x1c,0x7e,0xe1,
|
|
|
+ 0x1d,0xe0,0x81,0x1e,0xd2,0xe1,0x1d,0xdc,0x61,0x1e,0xa6,0x0c,0x0a,0xe3,0x8c,0x50,
|
|
|
+ 0xc2,0x21,0x1d,0xe4,0xc1,0x0d,0xec,0xa1,0x1c,0xe4,0x81,0x1e,0xca,0x01,0x1f,0xa6,
|
|
|
+ 0x04,0x74,0x00,0x00,0x79,0x18,0x00,0x00,0x7b,0x00,0x00,0x00,0x33,0x08,0x80,0x1c,
|
|
|
+ 0xc4,0xe1,0x1c,0x66,0x14,0x01,0x3d,0x88,0x43,0x38,0x84,0xc3,0x8c,0x42,0x80,0x07,
|
|
|
+ 0x79,0x78,0x07,0x73,0x98,0x71,0x0c,0xe6,0x00,0x0f,0xed,0x10,0x0e,0xf4,0x80,0x0e,
|
|
|
+ 0x33,0x0c,0x42,0x1e,0xc2,0xc1,0x1d,0xce,0xa1,0x1c,0x66,0x30,0x05,0x3d,0x88,0x43,
|
|
|
+ 0x38,0x84,0x83,0x1b,0xcc,0x03,0x3d,0xc8,0x43,0x3d,0x8c,0x03,0x3d,0xcc,0x78,0x8c,
|
|
|
+ 0x74,0x70,0x07,0x7b,0x08,0x07,0x79,0x48,0x87,0x70,0x70,0x07,0x7a,0x70,0x03,0x76,
|
|
|
+ 0x78,0x87,0x70,0x20,0x87,0x19,0xcc,0x11,0x0e,0xec,0x90,0x0e,0xe1,0x30,0x0f,0x6e,
|
|
|
+ 0x30,0x0f,0xe3,0xf0,0x0e,0xf0,0x50,0x0e,0x33,0x10,0xc4,0x1d,0xde,0x21,0x1c,0xd8,
|
|
|
+ 0x21,0x1d,0xc2,0x61,0x1e,0x66,0x30,0x89,0x3b,0xbc,0x83,0x3b,0xd0,0x43,0x39,0xb4,
|
|
|
+ 0x03,0x3c,0xbc,0x83,0x3c,0x84,0x03,0x3b,0xcc,0xf0,0x14,0x76,0x60,0x07,0x7b,0x68,
|
|
|
+ 0x07,0x37,0x68,0x87,0x72,0x68,0x07,0x37,0x80,0x87,0x70,0x90,0x87,0x70,0x60,0x07,
|
|
|
+ 0x76,0x28,0x07,0x76,0xf8,0x05,0x76,0x78,0x87,0x77,0x80,0x87,0x5f,0x08,0x87,0x71,
|
|
|
+ 0x18,0x87,0x72,0x98,0x87,0x79,0x98,0x81,0x2c,0xee,0xf0,0x0e,0xee,0xe0,0x0e,0xf5,
|
|
|
+ 0xc0,0x0e,0xec,0x30,0x03,0x62,0xc8,0xa1,0x1c,0xe4,0xa1,0x1c,0xcc,0xa1,0x1c,0xe4,
|
|
|
+ 0xa1,0x1c,0xdc,0x61,0x1c,0xca,0x21,0x1c,0xc4,0x81,0x1d,0xca,0x61,0x06,0xd6,0x90,
|
|
|
+ 0x43,0x39,0xc8,0x43,0x39,0x98,0x43,0x39,0xc8,0x43,0x39,0xb8,0xc3,0x38,0x94,0x43,
|
|
|
+ 0x38,0x88,0x03,0x3b,0x94,0xc3,0x2f,0xbc,0x83,0x3c,0xfc,0x82,0x3b,0xd4,0x03,0x3b,
|
|
|
+ 0xb0,0xc3,0x0c,0xc7,0x69,0x87,0x70,0x58,0x87,0x72,0x70,0x83,0x74,0x68,0x07,0x78,
|
|
|
+ 0x60,0x87,0x74,0x18,0x87,0x74,0xa0,0x87,0x19,0xce,0x53,0x0f,0xee,0x00,0x0f,0xf2,
|
|
|
+ 0x50,0x0e,0xe4,0x90,0x0e,0xe3,0x40,0x0f,0xe1,0x20,0x0e,0xec,0x50,0x0e,0x33,0x20,
|
|
|
+ 0x28,0x1d,0xdc,0xc1,0x1e,0xc2,0x41,0x1e,0xd2,0x21,0x1c,0xdc,0x81,0x1e,0xdc,0xe0,
|
|
|
+ 0x1c,0xe4,0xe1,0x1d,0xea,0x01,0x1e,0x66,0x18,0x51,0x38,0xb0,0x43,0x3a,0x9c,0x83,
|
|
|
+ 0x3b,0xcc,0x50,0x24,0x76,0x60,0x07,0x7b,0x68,0x07,0x37,0x60,0x87,0x77,0x78,0x07,
|
|
|
+ 0x78,0x98,0x51,0x4c,0xf4,0x90,0x0f,0xf0,0x50,0x0e,0x33,0x1e,0x6a,0x1e,0xca,0x61,
|
|
|
+ 0x1c,0xe8,0x21,0x1d,0xde,0xc1,0x1d,0x7e,0x01,0x1e,0xe4,0xa1,0x1c,0xcc,0x21,0x1d,
|
|
|
+ 0xf0,0x61,0x06,0x54,0x85,0x83,0x38,0xcc,0xc3,0x3b,0xb0,0x43,0x3d,0xd0,0x43,0x39,
|
|
|
+ 0xfc,0xc2,0x3c,0xe4,0x43,0x3b,0x88,0xc3,0x3b,0xb0,0xc3,0x8c,0xc5,0x0a,0x87,0x79,
|
|
|
+ 0x98,0x87,0x77,0x18,0x87,0x74,0x08,0x07,0x7a,0x28,0x07,0x72,0x98,0x81,0x5c,0xe3,
|
|
|
+ 0x10,0x0e,0xec,0xc0,0x0e,0xe5,0x50,0x0e,0xf3,0x30,0x23,0xc1,0xd2,0x41,0x1e,0xe4,
|
|
|
+ 0xe1,0x17,0xd8,0xe1,0x1d,0xde,0x01,0x1e,0x66,0x50,0x59,0x38,0xa4,0x83,0x3c,0xb8,
|
|
|
+ 0x81,0x39,0xd4,0x83,0x3b,0x8c,0x03,0x3d,0xa4,0xc3,0x3b,0xb8,0xc3,0x2f,0x9c,0x83,
|
|
|
+ 0x3c,0xbc,0x43,0x3d,0xc0,0xc3,0x3c,0x00,0x71,0x20,0x00,0x00,0x02,0x00,0x00,0x00,
|
|
|
+ 0x06,0x50,0x30,0x00,0xd2,0xd0,0x00,0x00,0x61,0x20,0x00,0x00,0x1e,0x00,0x00,0x00,
|
|
|
+ 0x13,0x04,0x41,0x2c,0x10,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0xf4,0xc6,0x22,0x82,
|
|
|
+ 0x20,0x08,0x46,0x00,0xa8,0x95,0x40,0x19,0xd0,0x98,0x01,0xa0,0x30,0x03,0x00,0x00,
|
|
|
+ 0xe3,0x15,0x07,0x33,0x4d,0x0c,0x05,0x65,0x90,0x81,0x19,0x0e,0x13,0x02,0xf9,0x8c,
|
|
|
+ 0x57,0x2c,0xd0,0x75,0x21,0x14,0x94,0x41,0x06,0xe8,0x60,0x4c,0x08,0xe4,0x63,0x41,
|
|
|
+ 0x01,0x9f,0xf1,0x0a,0xa8,0xe2,0x38,0x86,0x82,0x62,0x43,0x00,0x9f,0xd9,0x06,0xa7,
|
|
|
+ 0x02,0x66,0x1b,0x82,0x2a,0x98,0x6d,0x08,0x06,0x21,0x83,0x80,0x18,0x00,0x00,0x00,
|
|
|
+ 0x04,0x00,0x00,0x00,0x5b,0x86,0x20,0xc8,0x83,0x2d,0x43,0x11,0xe4,0xc1,0x96,0x41,
|
|
|
+ 0x09,0xf2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+};
|
|
|
+static const uint8_t _sspine_fs_bytecode_metal_macos[3257] = {
|
|
|
+ 0x4d,0x54,0x4c,0x42,0x01,0x80,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0xb9,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x6d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0xe0,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x6d,0x00,0x00,0x00,
|
|
|
+ 0x4e,0x41,0x4d,0x45,0x06,0x00,0x6d,0x61,0x69,0x6e,0x30,0x00,0x54,0x59,0x50,0x45,
|
|
|
+ 0x01,0x00,0x01,0x48,0x41,0x53,0x48,0x20,0x00,0xeb,0x62,0x74,0xda,0xdc,0xfb,0x51,
|
|
|
+ 0x12,0x89,0xbd,0xc2,0xa1,0xdc,0x89,0x67,0x5f,0x96,0x17,0x50,0xd6,0x8b,0xbc,0x5d,
|
|
|
+ 0xa9,0xe9,0x5d,0xef,0xeb,0x59,0xe4,0x51,0x64,0x4f,0x46,0x46,0x54,0x18,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x56,0x45,0x52,0x53,0x08,0x00,0x01,0x00,0x08,
|
|
|
+ 0x00,0x01,0x00,0x01,0x00,0x45,0x4e,0x44,0x54,0x04,0x00,0x00,0x00,0x45,0x4e,0x44,
|
|
|
+ 0x54,0x04,0x00,0x00,0x00,0x45,0x4e,0x44,0x54,0xde,0xc0,0x17,0x0b,0x00,0x00,0x00,
|
|
|
+ 0x00,0x14,0x00,0x00,0x00,0xc8,0x0b,0x00,0x00,0xff,0xff,0xff,0xff,0x42,0x43,0xc0,
|
|
|
+ 0xde,0x21,0x0c,0x00,0x00,0xef,0x02,0x00,0x00,0x0b,0x82,0x20,0x00,0x02,0x00,0x00,
|
|
|
+ 0x00,0x12,0x00,0x00,0x00,0x07,0x81,0x23,0x91,0x41,0xc8,0x04,0x49,0x06,0x10,0x32,
|
|
|
+ 0x39,0x92,0x01,0x84,0x0c,0x25,0x05,0x08,0x19,0x1e,0x04,0x8b,0x62,0x80,0x14,0x45,
|
|
|
+ 0x02,0x42,0x92,0x0b,0x42,0xa4,0x10,0x32,0x14,0x38,0x08,0x18,0x49,0x0a,0x32,0x44,
|
|
|
+ 0x24,0x48,0x0a,0x90,0x21,0x23,0xc4,0x52,0x80,0x0c,0x19,0x21,0x72,0x24,0x07,0xc8,
|
|
|
+ 0x48,0x11,0x62,0xa8,0xa0,0xa8,0x40,0xc6,0xf0,0x01,0x00,0x00,0x00,0x51,0x18,0x00,
|
|
|
+ 0x00,0x8e,0x00,0x00,0x00,0x1b,0xcc,0x25,0xf8,0xff,0xff,0xff,0xff,0x01,0x60,0x00,
|
|
|
+ 0x09,0xa8,0x88,0x71,0x78,0x07,0x79,0x90,0x87,0x72,0x18,0x07,0x7a,0x60,0x87,0x7c,
|
|
|
+ 0x68,0x03,0x79,0x78,0x87,0x7a,0x70,0x07,0x72,0x28,0x07,0x72,0x68,0x03,0x72,0x48,
|
|
|
+ 0x07,0x7b,0x48,0x07,0x72,0x28,0x87,0x36,0x98,0x87,0x78,0x90,0x07,0x7a,0x68,0x03,
|
|
|
+ 0x73,0x80,0x87,0x36,0x68,0x87,0x70,0xa0,0x07,0x74,0x00,0xcc,0x21,0x1c,0xd8,0x61,
|
|
|
+ 0x1e,0xca,0x01,0x20,0xc8,0x21,0x1d,0xe6,0x21,0x1c,0xc4,0x81,0x1d,0xca,0xa1,0x0d,
|
|
|
+ 0xe8,0x21,0x1c,0xd2,0x81,0x1d,0xda,0x60,0x1c,0xc2,0x81,0x1d,0xd8,0x61,0x1e,0x00,
|
|
|
+ 0x73,0x08,0x07,0x76,0x98,0x87,0x72,0x00,0x08,0x76,0x28,0x87,0x79,0x98,0x87,0x36,
|
|
|
+ 0x80,0x07,0x79,0x28,0x87,0x71,0x48,0x87,0x79,0x28,0x87,0x36,0x30,0x07,0x78,0x68,
|
|
|
+ 0x87,0x70,0x20,0x07,0xc0,0x1c,0xc2,0x81,0x1d,0xe6,0xa1,0x1c,0x00,0xc2,0x1d,0xde,
|
|
|
+ 0xa1,0x0d,0xcc,0x41,0x1e,0xc2,0xa1,0x1d,0xca,0xa1,0x0d,0xe0,0xe1,0x1d,0xd2,0xc1,
|
|
|
+ 0x1d,0xe8,0xa1,0x1c,0xe4,0xa1,0x0d,0xca,0x81,0x1d,0xd2,0xa1,0x1d,0x00,0x7a,0x90,
|
|
|
+ 0x87,0x7a,0x28,0x07,0x60,0x70,0x87,0x77,0x68,0x03,0x73,0x90,0x87,0x70,0x68,0x87,
|
|
|
+ 0x72,0x68,0x03,0x78,0x78,0x87,0x74,0x70,0x07,0x7a,0x28,0x07,0x79,0x68,0x83,0x72,
|
|
|
+ 0x60,0x87,0x74,0x68,0x87,0x36,0x70,0x87,0x77,0x70,0x87,0x36,0x60,0x87,0x72,0x08,
|
|
|
+ 0x07,0x73,0x00,0x08,0x77,0x78,0x87,0x36,0x48,0x07,0x77,0x30,0x87,0x79,0x68,0x03,
|
|
|
+ 0x73,0x80,0x87,0x36,0x68,0x87,0x70,0xa0,0x07,0x74,0x00,0xe8,0x41,0x1e,0xea,0xa1,
|
|
|
+ 0x1c,0x00,0xc2,0x1d,0xde,0xa1,0x0d,0xd4,0xa1,0x1e,0xda,0x01,0x1e,0xda,0x80,0x1e,
|
|
|
+ 0xc2,0x41,0x1c,0xd8,0xa1,0x1c,0xe6,0x01,0x30,0x87,0x70,0x60,0x87,0x79,0x28,0x07,
|
|
|
+ 0x80,0x70,0x87,0x77,0x68,0x03,0x77,0x08,0x07,0x77,0x98,0x87,0x36,0x30,0x07,0x78,
|
|
|
+ 0x68,0x83,0x76,0x08,0x07,0x7a,0x40,0x07,0x80,0x1e,0xe4,0xa1,0x1e,0xca,0x01,0x20,
|
|
|
+ 0xdc,0xe1,0x1d,0xda,0x60,0x1e,0xd2,0xe1,0x1c,0xdc,0xa1,0x1c,0xc8,0xa1,0x0d,0xf4,
|
|
|
+ 0xa1,0x1c,0xe4,0xe1,0x1d,0xe6,0xa1,0x0d,0xcc,0x01,0x1e,0xda,0xa0,0x1d,0xc2,0x81,
|
|
|
+ 0x1e,0xd0,0x01,0xa0,0x07,0x79,0xa8,0x87,0x72,0x00,0x08,0x77,0x78,0x87,0x36,0xa0,
|
|
|
+ 0x07,0x79,0x08,0x07,0x78,0x80,0x87,0x74,0x70,0x87,0x73,0x68,0x83,0x76,0x08,0x07,
|
|
|
+ 0x7a,0x40,0x07,0x80,0x1e,0xe4,0xa1,0x1e,0xca,0x01,0x20,0xe6,0x81,0x1e,0xc2,0x61,
|
|
|
+ 0x1c,0xd6,0xa1,0x0d,0xe0,0x41,0x1e,0xde,0x81,0x1e,0xca,0x61,0x1c,0xe8,0xe1,0x1d,
|
|
|
+ 0xe4,0xa1,0x0d,0xc4,0xa1,0x1e,0xcc,0xc1,0x1c,0xca,0x41,0x1e,0xda,0x60,0x1e,0xd2,
|
|
|
+ 0x41,0x1f,0xca,0x01,0xc0,0x03,0x80,0xa8,0x07,0x77,0x98,0x87,0x70,0x30,0x87,0x72,
|
|
|
+ 0x68,0x03,0x73,0x80,0x87,0x36,0x68,0x87,0x70,0xa0,0x07,0x74,0x00,0xe8,0x41,0x1e,
|
|
|
+ 0xea,0xa1,0x1c,0x00,0xa2,0x1e,0xe6,0xa1,0x1c,0xda,0x60,0x1e,0xde,0xc1,0x1c,0xe8,
|
|
|
+ 0xa1,0x0d,0xcc,0x81,0x1d,0xde,0x21,0x1c,0xe8,0x01,0x30,0x87,0x70,0x60,0x87,0x79,
|
|
|
+ 0x28,0x07,0x60,0x83,0x21,0x0c,0xc0,0x02,0x54,0x1b,0x8c,0x81,0x00,0x16,0xa0,0xda,
|
|
|
+ 0x60,0x10,0x05,0xb0,0x00,0xd5,0x06,0xa3,0xf8,0xff,0xff,0xff,0xff,0x01,0x90,0x00,
|
|
|
+ 0x6a,0x03,0x62,0xfc,0xff,0xff,0xff,0xff,0x00,0x30,0x80,0x04,0x54,0x1b,0x8c,0x23,
|
|
|
+ 0x00,0x16,0xa0,0xda,0x60,0x20,0x02,0xb0,0x00,0x15,0x00,0x00,0x00,0x49,0x18,0x00,
|
|
|
+ 0x00,0x03,0x00,0x00,0x00,0x13,0x88,0x40,0x18,0x88,0x09,0x41,0x31,0x61,0x30,0x0e,
|
|
|
+ 0x04,0x89,0x20,0x00,0x00,0x27,0x00,0x00,0x00,0x32,0x22,0x48,0x09,0x20,0x64,0x85,
|
|
|
+ 0x04,0x93,0x22,0xa4,0x84,0x04,0x93,0x22,0xe3,0x84,0xa1,0x90,0x14,0x12,0x4c,0x8a,
|
|
|
+ 0x8c,0x0b,0x84,0xa4,0x4c,0x10,0x6c,0x33,0x00,0xc3,0x08,0x04,0x60,0x83,0x30,0x8c,
|
|
|
+ 0x20,0x00,0x07,0x49,0x53,0x44,0x09,0x93,0x5f,0x48,0xff,0x03,0x44,0x00,0x23,0xa1,
|
|
|
+ 0x00,0x0c,0x22,0x10,0xc2,0x51,0xd2,0x14,0x51,0xc2,0xe4,0xff,0x13,0x71,0x4d,0x54,
|
|
|
+ 0x44,0xfc,0xf6,0xf0,0x4f,0x63,0x04,0xc0,0x20,0x82,0x11,0x5c,0x24,0x4d,0x11,0x25,
|
|
|
+ 0x4c,0xfe,0x2f,0x01,0xcc,0xb3,0x10,0xd1,0x3f,0x8d,0x11,0x00,0x83,0x08,0x88,0x50,
|
|
|
+ 0x0c,0x31,0x42,0x39,0x89,0x54,0x21,0x42,0x08,0x81,0xd8,0x1c,0x41,0x30,0x47,0x00,
|
|
|
+ 0x06,0xc3,0x08,0xc2,0x53,0x90,0x70,0xd2,0x70,0xd0,0x01,0x8a,0x03,0x01,0x29,0xf0,
|
|
|
+ 0x86,0x11,0x86,0x67,0x18,0x61,0x00,0x86,0x11,0x88,0x67,0x8e,0x00,0x14,0x06,0x11,
|
|
|
+ 0x00,0x61,0x04,0x00,0x00,0x13,0xb2,0x70,0x48,0x07,0x79,0xb0,0x03,0x3a,0x68,0x83,
|
|
|
+ 0x70,0x80,0x07,0x78,0x60,0x87,0x72,0x68,0x83,0x76,0x08,0x87,0x71,0x78,0x87,0x79,
|
|
|
+ 0xc0,0x87,0x38,0x80,0x03,0x37,0x88,0x83,0x38,0x70,0x03,0x38,0xd8,0x70,0x1b,0xe5,
|
|
|
+ 0xd0,0x06,0xf0,0xa0,0x07,0x76,0x40,0x07,0x7a,0x60,0x07,0x74,0xa0,0x07,0x76,0x40,
|
|
|
+ 0x07,0x6d,0x90,0x0e,0x71,0xa0,0x07,0x78,0xa0,0x07,0x78,0xd0,0x06,0xe9,0x80,0x07,
|
|
|
+ 0x7a,0x80,0x07,0x7a,0x80,0x07,0x6d,0x90,0x0e,0x71,0x60,0x07,0x7a,0x10,0x07,0x76,
|
|
|
+ 0xa0,0x07,0x71,0x60,0x07,0x6d,0x90,0x0e,0x73,0x20,0x07,0x7a,0x30,0x07,0x72,0xa0,
|
|
|
+ 0x07,0x73,0x20,0x07,0x6d,0x90,0x0e,0x76,0x40,0x07,0x7a,0x60,0x07,0x74,0xa0,0x07,
|
|
|
+ 0x76,0x40,0x07,0x6d,0x60,0x0e,0x73,0x20,0x07,0x7a,0x30,0x07,0x72,0xa0,0x07,0x73,
|
|
|
+ 0x20,0x07,0x6d,0x60,0x0e,0x76,0x40,0x07,0x7a,0x60,0x07,0x74,0xa0,0x07,0x76,0x40,
|
|
|
+ 0x07,0x6d,0x60,0x0f,0x71,0x60,0x07,0x7a,0x10,0x07,0x76,0xa0,0x07,0x71,0x60,0x07,
|
|
|
+ 0x6d,0x60,0x0f,0x72,0x40,0x07,0x7a,0x30,0x07,0x72,0xa0,0x07,0x73,0x20,0x07,0x6d,
|
|
|
+ 0x60,0x0f,0x73,0x20,0x07,0x7a,0x30,0x07,0x72,0xa0,0x07,0x73,0x20,0x07,0x6d,0x60,
|
|
|
+ 0x0f,0x74,0x80,0x07,0x7a,0x60,0x07,0x74,0xa0,0x07,0x76,0x40,0x07,0x6d,0x60,0x0f,
|
|
|
+ 0x76,0x40,0x07,0x7a,0x60,0x07,0x74,0xa0,0x07,0x76,0x40,0x07,0x6d,0x60,0x0f,0x79,
|
|
|
+ 0x60,0x07,0x7a,0x10,0x07,0x72,0x80,0x07,0x7a,0x10,0x07,0x72,0x80,0x07,0x6d,0x60,
|
|
|
+ 0x0f,0x71,0x20,0x07,0x78,0xa0,0x07,0x71,0x20,0x07,0x78,0xa0,0x07,0x71,0x20,0x07,
|
|
|
+ 0x78,0xd0,0x06,0xf6,0x10,0x07,0x79,0x20,0x07,0x7a,0x20,0x07,0x75,0x60,0x07,0x7a,
|
|
|
+ 0x20,0x07,0x75,0x60,0x07,0x6d,0x60,0x0f,0x72,0x50,0x07,0x76,0xa0,0x07,0x72,0x50,
|
|
|
+ 0x07,0x76,0xa0,0x07,0x72,0x50,0x07,0x76,0xd0,0x06,0xf6,0x50,0x07,0x71,0x20,0x07,
|
|
|
+ 0x7a,0x50,0x07,0x71,0x20,0x07,0x7a,0x50,0x07,0x71,0x20,0x07,0x6d,0x60,0x0f,0x71,
|
|
|
+ 0x00,0x07,0x72,0x40,0x07,0x7a,0x10,0x07,0x70,0x20,0x07,0x74,0xa0,0x07,0x71,0x00,
|
|
|
+ 0x07,0x72,0x40,0x07,0x6d,0xe0,0x0e,0x78,0xa0,0x07,0x71,0x60,0x07,0x7a,0x30,0x07,
|
|
|
+ 0x72,0x30,0x84,0x59,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x18,0xc2,0x34,0x40,
|
|
|
+ 0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x0c,0x61,0x24,0x20,0x00,0x06,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0xb2,0x40,0x00,0x09,0x00,0x00,0x00,0x32,0x1e,0x98,0x10,0x19,0x11,0x4c,
|
|
|
+ 0x90,0x8c,0x09,0x26,0x47,0xc6,0x04,0x43,0x7a,0x23,0x00,0x25,0x50,0x08,0x45,0x50,
|
|
|
+ 0x10,0x65,0x40,0x78,0x04,0x80,0xe8,0x58,0x02,0x33,0x00,0x00,0x00,0x79,0x18,0x00,
|
|
|
+ 0x00,0xfa,0x00,0x00,0x00,0x1a,0x03,0x4c,0x10,0x97,0x29,0xa2,0x25,0x10,0xab,0x32,
|
|
|
+ 0xb9,0xb9,0xb4,0x37,0xb7,0x21,0xc6,0x63,0x4c,0x00,0xa5,0x50,0xb9,0x1b,0x43,0x0b,
|
|
|
+ 0x93,0xfb,0x9a,0x4b,0xd3,0x2b,0x1b,0x62,0x3c,0xc4,0x24,0x3c,0x05,0xe3,0x20,0x08,
|
|
|
+ 0x0e,0x8e,0xad,0x0c,0xa4,0xad,0x8c,0x2e,0x8c,0x0d,0xc4,0xae,0x4c,0x6e,0x2e,0xed,
|
|
|
+ 0xcd,0x0d,0x64,0x26,0x06,0x06,0x26,0xc6,0xa5,0x46,0x46,0x06,0x04,0xa5,0xad,0x8c,
|
|
|
+ 0x2e,0x8c,0xcd,0xac,0xac,0x65,0x26,0x06,0x06,0x26,0xc6,0xa5,0x46,0x46,0x26,0x65,
|
|
|
+ 0x88,0x30,0x11,0x43,0x8c,0x87,0x78,0x8e,0x67,0x60,0xd1,0x54,0x46,0x17,0xc6,0x36,
|
|
|
+ 0x04,0x99,0x8e,0x87,0x78,0x88,0x67,0xe0,0x16,0x96,0x26,0xe7,0x32,0xf6,0xd6,0x06,
|
|
|
+ 0x97,0xc6,0x56,0xe6,0x42,0x56,0xe6,0xf6,0x26,0xd7,0x36,0xf7,0x45,0x96,0x36,0x17,
|
|
|
+ 0x26,0xc6,0x56,0x36,0x44,0x98,0x12,0x72,0x61,0x69,0x72,0x2e,0x63,0x6f,0x6d,0x70,
|
|
|
+ 0x69,0x6c,0x65,0x2e,0x66,0x61,0x73,0x74,0x5f,0x6d,0x61,0x74,0x68,0x5f,0x65,0x6e,
|
|
|
+ 0x61,0x62,0x6c,0x65,0x43,0x84,0x69,0x61,0x19,0x84,0xa5,0xc9,0xb9,0x8c,0xbd,0xb5,
|
|
|
+ 0xc1,0xa5,0xb1,0x95,0xb9,0x98,0xc9,0x85,0xb5,0x95,0x89,0xd5,0x99,0x99,0x95,0xc9,
|
|
|
+ 0x7d,0x99,0x95,0xd1,0x8d,0xa1,0x7d,0x91,0xa5,0xcd,0x85,0x89,0xb1,0x95,0x0d,0x11,
|
|
|
+ 0xa6,0x86,0x51,0x58,0x9a,0x9c,0x8b,0x5c,0x99,0x1b,0x59,0x99,0xdc,0x17,0x5d,0x98,
|
|
|
+ 0xdc,0x59,0x19,0x1d,0xa3,0xb0,0x34,0x39,0x97,0x30,0xb9,0xb3,0x2f,0xba,0x3c,0xb8,
|
|
|
+ 0xb2,0x2f,0xb7,0xb0,0xb6,0x32,0x1a,0x66,0x6c,0x6f,0x61,0x74,0x34,0x64,0xc2,0xd2,
|
|
|
+ 0xe4,0x5c,0xc2,0xe4,0xce,0xbe,0xdc,0xc2,0xda,0xca,0xa8,0x98,0xc9,0x85,0x9d,0x7d,
|
|
|
+ 0x8d,0xbd,0xb1,0xbd,0xc9,0x0d,0x61,0xa6,0xe7,0x19,0x26,0x68,0x8a,0x26,0x69,0x9a,
|
|
|
+ 0x86,0x08,0x13,0x45,0x29,0x2c,0x4d,0xce,0xc5,0x4c,0x2e,0xec,0xac,0xad,0xcc,0x8d,
|
|
|
+ 0xee,0x2b,0xcd,0x0d,0xae,0x8e,0x8e,0x4b,0xdd,0x5c,0x99,0x1c,0x0a,0xdb,0xdb,0x98,
|
|
|
+ 0x1b,0x4c,0x0a,0x95,0xb0,0x34,0x39,0x97,0xb1,0x32,0x37,0xba,0x32,0x39,0x3e,0x61,
|
|
|
+ 0x69,0x72,0x2e,0x70,0x65,0x72,0x73,0x70,0x65,0x63,0x74,0x69,0x76,0x65,0x34,0xcc,
|
|
|
+ 0xd8,0xde,0xc2,0xe8,0x64,0x28,0xd4,0xd9,0x0d,0x91,0x9e,0x61,0xb2,0xa6,0x6b,0xc2,
|
|
|
+ 0xa6,0x6c,0x82,0x26,0x6d,0x92,0xa6,0x8d,0x4b,0xdd,0x5c,0x99,0x1c,0x0a,0xdb,0xdb,
|
|
|
+ 0x98,0x5b,0x4c,0x0a,0x8b,0xb1,0x37,0xb6,0x37,0xb9,0x21,0xd2,0x43,0x4c,0xd6,0xd4,
|
|
|
+ 0x4d,0xd8,0x94,0x4d,0xd0,0x14,0x4d,0xd2,0xe4,0x51,0x09,0x4b,0x93,0x73,0x11,0xab,
|
|
|
+ 0x33,0x33,0x2b,0x93,0xe3,0x13,0x96,0x26,0xe7,0x22,0x56,0x67,0x66,0x56,0x26,0xf7,
|
|
|
+ 0x35,0x97,0xa6,0x57,0x46,0x29,0x2c,0x4d,0xce,0x85,0xed,0x6d,0x2c,0x8c,0x2e,0xed,
|
|
|
+ 0xcd,0xed,0x2b,0xcd,0x8d,0xac,0x0c,0x8f,0x48,0x58,0x9a,0x9c,0x8b,0x5c,0x59,0x18,
|
|
|
+ 0x19,0xa9,0xb0,0x34,0x39,0x97,0x39,0x3a,0xb9,0xba,0x31,0xba,0x2f,0xba,0x3c,0xb8,
|
|
|
+ 0xb2,0xaf,0x34,0x37,0xb3,0x37,0x16,0x66,0x6c,0x6f,0x61,0x74,0x1c,0xe0,0xda,0xc2,
|
|
|
+ 0x86,0x28,0xcf,0xf0,0x14,0xcf,0x30,0x95,0xc1,0x64,0x06,0x8c,0xc2,0xd2,0xe4,0x5c,
|
|
|
+ 0xc2,0xe4,0xce,0xbe,0xe8,0xf2,0xe0,0xca,0xbe,0xe6,0xd2,0xf4,0xca,0x78,0x85,0xa5,
|
|
|
+ 0xc9,0xb9,0x84,0xc9,0x9d,0x7d,0xd1,0xe5,0xc1,0x95,0x7d,0x85,0xb1,0xa5,0x9d,0xb9,
|
|
|
+ 0x7d,0xcd,0xa5,0xe9,0x95,0x31,0x31,0x9b,0xfb,0x82,0x0b,0x93,0x0b,0x6b,0x9b,0xe3,
|
|
|
+ 0xf0,0x55,0x03,0x33,0x84,0x0c,0x1e,0x63,0x02,0x83,0x29,0x0c,0x9e,0x62,0x12,0x83,
|
|
|
+ 0x67,0x78,0x88,0x69,0x0c,0x26,0x32,0x98,0xce,0x60,0x42,0x83,0xa7,0x98,0xd2,0xe0,
|
|
|
+ 0x29,0x26,0x68,0x52,0x83,0x49,0x9a,0xd6,0x80,0x4b,0x58,0x9a,0x9c,0x0b,0x5d,0x19,
|
|
|
+ 0x1e,0x5d,0x9d,0x5c,0x19,0x95,0xb0,0x34,0x39,0x97,0xb9,0xb0,0x36,0x38,0xb6,0x32,
|
|
|
+ 0x62,0x74,0x65,0x78,0x74,0x75,0x72,0x65,0x32,0x64,0x3c,0x66,0x6c,0x6f,0x61,0x74,
|
|
|
+ 0x2c,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x3e,0x1c,0xe8,0xca,0xf0,0x86,0x50,0x0f,
|
|
|
+ 0x32,0xb5,0xc1,0x24,0x06,0xcf,0xf0,0x10,0x93,0x1b,0x4c,0xd0,0xf4,0x06,0x93,0x34,
|
|
|
+ 0xc1,0x01,0x97,0xb0,0x34,0x39,0x97,0xb9,0xb0,0x36,0x38,0xb6,0x32,0x39,0x1e,0x73,
|
|
|
+ 0x61,0x6d,0x70,0x6c,0x65,0x72,0x44,0xe8,0xca,0xf0,0xa6,0xda,0xe0,0xd8,0xe4,0x86,
|
|
|
+ 0x48,0x4f,0x31,0xc9,0xc1,0x24,0x06,0xcf,0xf0,0x10,0x13,0x34,0xcd,0xc1,0x24,0x4d,
|
|
|
+ 0x74,0x30,0x44,0x99,0xb8,0xe9,0x9b,0xd8,0x60,0x8a,0x83,0xa9,0x0e,0x86,0x18,0x0b,
|
|
|
+ 0x30,0x55,0x93,0x1d,0xd0,0xf9,0xd2,0xa2,0x9a,0xca,0x31,0x9b,0xfb,0x82,0x0b,0x93,
|
|
|
+ 0x0b,0x6b,0x9b,0xe3,0xf3,0xd6,0xe6,0x96,0x06,0xf7,0x46,0x57,0xe6,0x46,0x07,0x32,
|
|
|
+ 0x86,0x16,0x26,0xc7,0x67,0x2a,0xad,0x0d,0x8e,0xad,0x0c,0x64,0x68,0x65,0x05,0x84,
|
|
|
+ 0x4a,0x28,0x28,0x68,0x88,0x30,0xe9,0xc1,0x10,0x63,0xca,0x83,0x69,0x0f,0xb0,0x64,
|
|
|
+ 0x88,0x31,0x95,0xc1,0xc4,0x07,0x58,0x32,0xc4,0x98,0xf0,0x60,0xea,0x03,0x2c,0x19,
|
|
|
+ 0x62,0x4c,0x7e,0x30,0xf5,0x01,0x96,0x8c,0x88,0xd8,0x81,0x1d,0xec,0xa1,0x1d,0xdc,
|
|
|
+ 0xa0,0x1d,0xde,0x81,0x1c,0xea,0x81,0x1d,0xca,0xc1,0x0d,0xcc,0x81,0x1d,0xc2,0xe1,
|
|
|
+ 0x1c,0xe6,0x61,0x8a,0x10,0x0c,0x23,0x14,0x76,0x60,0x07,0x7b,0x68,0x07,0x37,0x48,
|
|
|
+ 0x07,0x72,0x28,0x07,0x77,0xa0,0x87,0x29,0x41,0x31,0x62,0x09,0x87,0x74,0x90,0x07,
|
|
|
+ 0x37,0xb0,0x87,0x72,0x90,0x87,0x79,0x48,0x87,0x77,0x70,0x87,0x29,0x81,0x31,0x82,
|
|
|
+ 0x0a,0x87,0x74,0x90,0x07,0x37,0x60,0x87,0x70,0x70,0x87,0x73,0xa8,0x87,0x70,0x38,
|
|
|
+ 0x87,0x72,0xf8,0x05,0x7b,0x28,0x07,0x79,0x98,0x87,0x74,0x78,0x07,0x77,0x98,0x12,
|
|
|
+ 0x20,0x23,0xa6,0x70,0x48,0x07,0x79,0x70,0x83,0x71,0x78,0x87,0x76,0x80,0x87,0x74,
|
|
|
+ 0x60,0x87,0x72,0xf8,0x85,0x77,0x80,0x07,0x7a,0x48,0x87,0x77,0x70,0x87,0x79,0x98,
|
|
|
+ 0x32,0x28,0x8c,0x33,0x82,0x09,0x87,0x74,0x90,0x07,0x37,0x30,0x07,0x79,0x08,0x87,
|
|
|
+ 0x73,0x68,0x87,0x72,0x70,0x07,0x7a,0x98,0x12,0xdc,0x01,0x00,0x00,0x79,0x18,0x00,
|
|
|
+ 0x00,0x7b,0x00,0x00,0x00,0x33,0x08,0x80,0x1c,0xc4,0xe1,0x1c,0x66,0x14,0x01,0x3d,
|
|
|
+ 0x88,0x43,0x38,0x84,0xc3,0x8c,0x42,0x80,0x07,0x79,0x78,0x07,0x73,0x98,0x71,0x0c,
|
|
|
+ 0xe6,0x00,0x0f,0xed,0x10,0x0e,0xf4,0x80,0x0e,0x33,0x0c,0x42,0x1e,0xc2,0xc1,0x1d,
|
|
|
+ 0xce,0xa1,0x1c,0x66,0x30,0x05,0x3d,0x88,0x43,0x38,0x84,0x83,0x1b,0xcc,0x03,0x3d,
|
|
|
+ 0xc8,0x43,0x3d,0x8c,0x03,0x3d,0xcc,0x78,0x8c,0x74,0x70,0x07,0x7b,0x08,0x07,0x79,
|
|
|
+ 0x48,0x87,0x70,0x70,0x07,0x7a,0x70,0x03,0x76,0x78,0x87,0x70,0x20,0x87,0x19,0xcc,
|
|
|
+ 0x11,0x0e,0xec,0x90,0x0e,0xe1,0x30,0x0f,0x6e,0x30,0x0f,0xe3,0xf0,0x0e,0xf0,0x50,
|
|
|
+ 0x0e,0x33,0x10,0xc4,0x1d,0xde,0x21,0x1c,0xd8,0x21,0x1d,0xc2,0x61,0x1e,0x66,0x30,
|
|
|
+ 0x89,0x3b,0xbc,0x83,0x3b,0xd0,0x43,0x39,0xb4,0x03,0x3c,0xbc,0x83,0x3c,0x84,0x03,
|
|
|
+ 0x3b,0xcc,0xf0,0x14,0x76,0x60,0x07,0x7b,0x68,0x07,0x37,0x68,0x87,0x72,0x68,0x07,
|
|
|
+ 0x37,0x80,0x87,0x70,0x90,0x87,0x70,0x60,0x07,0x76,0x28,0x07,0x76,0xf8,0x05,0x76,
|
|
|
+ 0x78,0x87,0x77,0x80,0x87,0x5f,0x08,0x87,0x71,0x18,0x87,0x72,0x98,0x87,0x79,0x98,
|
|
|
+ 0x81,0x2c,0xee,0xf0,0x0e,0xee,0xe0,0x0e,0xf5,0xc0,0x0e,0xec,0x30,0x03,0x62,0xc8,
|
|
|
+ 0xa1,0x1c,0xe4,0xa1,0x1c,0xcc,0xa1,0x1c,0xe4,0xa1,0x1c,0xdc,0x61,0x1c,0xca,0x21,
|
|
|
+ 0x1c,0xc4,0x81,0x1d,0xca,0x61,0x06,0xd6,0x90,0x43,0x39,0xc8,0x43,0x39,0x98,0x43,
|
|
|
+ 0x39,0xc8,0x43,0x39,0xb8,0xc3,0x38,0x94,0x43,0x38,0x88,0x03,0x3b,0x94,0xc3,0x2f,
|
|
|
+ 0xbc,0x83,0x3c,0xfc,0x82,0x3b,0xd4,0x03,0x3b,0xb0,0xc3,0x0c,0xc7,0x69,0x87,0x70,
|
|
|
+ 0x58,0x87,0x72,0x70,0x83,0x74,0x68,0x07,0x78,0x60,0x87,0x74,0x18,0x87,0x74,0xa0,
|
|
|
+ 0x87,0x19,0xce,0x53,0x0f,0xee,0x00,0x0f,0xf2,0x50,0x0e,0xe4,0x90,0x0e,0xe3,0x40,
|
|
|
+ 0x0f,0xe1,0x20,0x0e,0xec,0x50,0x0e,0x33,0x20,0x28,0x1d,0xdc,0xc1,0x1e,0xc2,0x41,
|
|
|
+ 0x1e,0xd2,0x21,0x1c,0xdc,0x81,0x1e,0xdc,0xe0,0x1c,0xe4,0xe1,0x1d,0xea,0x01,0x1e,
|
|
|
+ 0x66,0x18,0x51,0x38,0xb0,0x43,0x3a,0x9c,0x83,0x3b,0xcc,0x50,0x24,0x76,0x60,0x07,
|
|
|
+ 0x7b,0x68,0x07,0x37,0x60,0x87,0x77,0x78,0x07,0x78,0x98,0x51,0x4c,0xf4,0x90,0x0f,
|
|
|
+ 0xf0,0x50,0x0e,0x33,0x1e,0x6a,0x1e,0xca,0x61,0x1c,0xe8,0x21,0x1d,0xde,0xc1,0x1d,
|
|
|
+ 0x7e,0x01,0x1e,0xe4,0xa1,0x1c,0xcc,0x21,0x1d,0xf0,0x61,0x06,0x54,0x85,0x83,0x38,
|
|
|
+ 0xcc,0xc3,0x3b,0xb0,0x43,0x3d,0xd0,0x43,0x39,0xfc,0xc2,0x3c,0xe4,0x43,0x3b,0x88,
|
|
|
+ 0xc3,0x3b,0xb0,0xc3,0x8c,0xc5,0x0a,0x87,0x79,0x98,0x87,0x77,0x18,0x87,0x74,0x08,
|
|
|
+ 0x07,0x7a,0x28,0x07,0x72,0x98,0x81,0x5c,0xe3,0x10,0x0e,0xec,0xc0,0x0e,0xe5,0x50,
|
|
|
+ 0x0e,0xf3,0x30,0x23,0xc1,0xd2,0x41,0x1e,0xe4,0xe1,0x17,0xd8,0xe1,0x1d,0xde,0x01,
|
|
|
+ 0x1e,0x66,0x50,0x59,0x38,0xa4,0x83,0x3c,0xb8,0x81,0x39,0xd4,0x83,0x3b,0x8c,0x03,
|
|
|
+ 0x3d,0xa4,0xc3,0x3b,0xb8,0xc3,0x2f,0x9c,0x83,0x3c,0xbc,0x43,0x3d,0xc0,0xc3,0x3c,
|
|
|
+ 0x00,0x71,0x20,0x00,0x00,0x0b,0x00,0x00,0x00,0x26,0xb0,0x01,0x48,0xe4,0x4b,0x00,
|
|
|
+ 0xf3,0x2c,0xc4,0x3f,0x11,0xd7,0x44,0x45,0xc4,0x6f,0x0f,0x7e,0x85,0x17,0xb7,0x6d,
|
|
|
+ 0x00,0x05,0x03,0x20,0x0d,0x6d,0x01,0x0d,0x80,0x44,0x3e,0x83,0x5c,0x7e,0x85,0x17,
|
|
|
+ 0xb7,0x0d,0x00,0x00,0x00,0x61,0x20,0x00,0x00,0x25,0x00,0x00,0x00,0x13,0x04,0x41,
|
|
|
+ 0x2c,0x10,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x74,0x47,0x00,0xc6,0x22,0x80,0x40,
|
|
|
+ 0x38,0xe6,0x20,0x06,0xc2,0xa8,0xc8,0xd5,0xc0,0x08,0x00,0xbd,0x19,0x00,0x82,0x23,
|
|
|
+ 0x00,0x54,0xc7,0x1a,0x80,0x40,0x18,0x6b,0x18,0x86,0x81,0xec,0x0c,0x00,0x89,0x19,
|
|
|
+ 0x00,0x0a,0x33,0x00,0x04,0x46,0x00,0x00,0x00,0x23,0x06,0xca,0x10,0x6c,0x8f,0x23,
|
|
|
+ 0x29,0x47,0x12,0x58,0x20,0xc9,0x67,0x90,0x21,0x20,0x90,0x41,0x06,0xa1,0x40,0x4c,
|
|
|
+ 0x08,0xe4,0x33,0xc8,0x10,0x24,0xd0,0x20,0x43,0x50,0x48,0x16,0x60,0xf2,0x19,0x6f,
|
|
|
+ 0xc0,0x38,0x31,0xa0,0x60,0xcc,0x31,0x30,0x01,0x19,0x0c,0x32,0x04,0x0d,0x36,0x62,
|
|
|
+ 0x60,0x08,0x01,0x1a,0x2c,0x45,0x30,0xdb,0x00,0x05,0x40,0x06,0x01,0x31,0x00,0x00,
|
|
|
+ 0x00,0x02,0x00,0x00,0x00,0x5b,0x86,0x24,0xf8,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+};
|
|
|
+static const uint8_t _sspine_vs_bytecode_metal_ios[3068] = {
|
|
|
+ 0x4d,0x54,0x4c,0x42,0x01,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0xfc,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x6d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x3b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0xf0,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x6d,0x00,0x00,0x00,
|
|
|
+ 0x4e,0x41,0x4d,0x45,0x06,0x00,0x6d,0x61,0x69,0x6e,0x30,0x00,0x54,0x59,0x50,0x45,
|
|
|
+ 0x01,0x00,0x00,0x48,0x41,0x53,0x48,0x20,0x00,0x96,0x65,0x31,0x3a,0xaa,0x1f,0x1f,
|
|
|
+ 0x56,0xb5,0xb0,0x40,0x9b,0xfd,0xd1,0x68,0xc7,0x7d,0x4c,0x0f,0x15,0x45,0xbb,0x02,
|
|
|
+ 0x8a,0x0a,0x18,0xa7,0xf2,0xf6,0x03,0x3e,0x76,0x4f,0x46,0x46,0x54,0x18,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x56,0x45,0x52,0x53,0x08,0x00,0x01,0x00,0x08,
|
|
|
+ 0x00,0x01,0x00,0x00,0x00,0x45,0x4e,0x44,0x54,0x37,0x00,0x00,0x00,0x56,0x41,0x54,
|
|
|
+ 0x54,0x22,0x00,0x03,0x00,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x00,0x00,0x80,
|
|
|
+ 0x74,0x65,0x78,0x63,0x6f,0x6f,0x72,0x64,0x30,0x00,0x01,0x80,0x63,0x6f,0x6c,0x6f,
|
|
|
+ 0x72,0x30,0x00,0x02,0x80,0x56,0x41,0x54,0x59,0x05,0x00,0x03,0x00,0x04,0x04,0x06,
|
|
|
+ 0x45,0x4e,0x44,0x54,0x04,0x00,0x00,0x00,0x45,0x4e,0x44,0x54,0xde,0xc0,0x17,0x0b,
|
|
|
+ 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0xd8,0x0a,0x00,0x00,0xff,0xff,0xff,0xff,
|
|
|
+ 0x42,0x43,0xc0,0xde,0x21,0x0c,0x00,0x00,0xb3,0x02,0x00,0x00,0x0b,0x82,0x20,0x00,
|
|
|
+ 0x02,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x07,0x81,0x23,0x91,0x41,0xc8,0x04,0x49,
|
|
|
+ 0x06,0x10,0x32,0x39,0x92,0x01,0x84,0x0c,0x25,0x05,0x08,0x19,0x1e,0x04,0x8b,0x62,
|
|
|
+ 0x80,0x14,0x45,0x02,0x42,0x92,0x0b,0x42,0xa4,0x10,0x32,0x14,0x38,0x08,0x18,0x49,
|
|
|
+ 0x0a,0x32,0x44,0x24,0x48,0x0a,0x90,0x21,0x23,0xc4,0x52,0x80,0x0c,0x19,0x21,0x72,
|
|
|
+ 0x24,0x07,0xc8,0x48,0x11,0x62,0xa8,0xa0,0xa8,0x40,0xc6,0xf0,0x01,0x00,0x00,0x00,
|
|
|
+ 0x51,0x18,0x00,0x00,0x82,0x00,0x00,0x00,0x1b,0xc8,0x25,0xf8,0xff,0xff,0xff,0xff,
|
|
|
+ 0x01,0x90,0x80,0x8a,0x18,0x87,0x77,0x90,0x07,0x79,0x28,0x87,0x71,0xa0,0x07,0x76,
|
|
|
+ 0xc8,0x87,0x36,0x90,0x87,0x77,0xa8,0x07,0x77,0x20,0x87,0x72,0x20,0x87,0x36,0x20,
|
|
|
+ 0x87,0x74,0xb0,0x87,0x74,0x20,0x87,0x72,0x68,0x83,0x79,0x88,0x07,0x79,0xa0,0x87,
|
|
|
+ 0x36,0x30,0x07,0x78,0x68,0x83,0x76,0x08,0x07,0x7a,0x40,0x07,0xc0,0x1c,0xc2,0x81,
|
|
|
+ 0x1d,0xe6,0xa1,0x1c,0x00,0x82,0x1c,0xd2,0x61,0x1e,0xc2,0x41,0x1c,0xd8,0xa1,0x1c,
|
|
|
+ 0xda,0x80,0x1e,0xc2,0x21,0x1d,0xd8,0xa1,0x0d,0xc6,0x21,0x1c,0xd8,0x81,0x1d,0xe6,
|
|
|
+ 0x01,0x30,0x87,0x70,0x60,0x87,0x79,0x28,0x07,0x80,0x60,0x87,0x72,0x98,0x87,0x79,
|
|
|
+ 0x68,0x03,0x78,0x90,0x87,0x72,0x18,0x87,0x74,0x98,0x87,0x72,0x68,0x03,0x73,0x80,
|
|
|
+ 0x87,0x76,0x08,0x07,0x72,0x00,0xcc,0x21,0x1c,0xd8,0x61,0x1e,0xca,0x01,0x20,0xdc,
|
|
|
+ 0xe1,0x1d,0xda,0xc0,0x1c,0xe4,0x21,0x1c,0xda,0xa1,0x1c,0xda,0x00,0x1e,0xde,0x21,
|
|
|
+ 0x1d,0xdc,0x81,0x1e,0xca,0x41,0x1e,0xda,0xa0,0x1c,0xd8,0x21,0x1d,0xda,0x01,0xa0,
|
|
|
+ 0x07,0x79,0xa8,0x87,0x72,0x00,0x06,0x77,0x78,0x87,0x36,0x30,0x07,0x79,0x08,0x87,
|
|
|
+ 0x76,0x28,0x87,0x36,0x80,0x87,0x77,0x48,0x07,0x77,0xa0,0x87,0x72,0x90,0x87,0x36,
|
|
|
+ 0x28,0x07,0x76,0x48,0x87,0x76,0x68,0x03,0x77,0x78,0x07,0x77,0x68,0x03,0x76,0x28,
|
|
|
+ 0x87,0x70,0x30,0x07,0x80,0x70,0x87,0x77,0x68,0x83,0x74,0x70,0x07,0x73,0x98,0x87,
|
|
|
+ 0x36,0x30,0x07,0x78,0x68,0x83,0x76,0x08,0x07,0x7a,0x40,0x07,0x80,0x1e,0xe4,0xa1,
|
|
|
+ 0x1e,0xca,0x01,0x20,0xdc,0xe1,0x1d,0xda,0x40,0x1d,0xea,0xa1,0x1d,0xe0,0xa1,0x0d,
|
|
|
+ 0xe8,0x21,0x1c,0xc4,0x81,0x1d,0xca,0x61,0x1e,0x00,0x73,0x08,0x07,0x76,0x98,0x87,
|
|
|
+ 0x72,0x00,0x08,0x77,0x78,0x87,0x36,0x70,0x87,0x70,0x70,0x87,0x79,0x68,0x03,0x73,
|
|
|
+ 0x80,0x87,0x36,0x68,0x87,0x70,0xa0,0x07,0x74,0x00,0xe8,0x41,0x1e,0xea,0xa1,0x1c,
|
|
|
+ 0x00,0xc2,0x1d,0xde,0xa1,0x0d,0xe6,0x21,0x1d,0xce,0xc1,0x1d,0xca,0x81,0x1c,0xda,
|
|
|
+ 0x40,0x1f,0xca,0x41,0x1e,0xde,0x61,0x1e,0xda,0xc0,0x1c,0xe0,0xa1,0x0d,0xda,0x21,
|
|
|
+ 0x1c,0xe8,0x01,0x1d,0x00,0x7a,0x90,0x87,0x7a,0x28,0x07,0x80,0x70,0x87,0x77,0x68,
|
|
|
+ 0x03,0x7a,0x90,0x87,0x70,0x80,0x07,0x78,0x48,0x07,0x77,0x38,0x87,0x36,0x68,0x87,
|
|
|
+ 0x70,0xa0,0x07,0x74,0x00,0xe8,0x41,0x1e,0xea,0xa1,0x1c,0x00,0x62,0x1e,0xe8,0x21,
|
|
|
+ 0x1c,0xc6,0x61,0x1d,0xda,0x00,0x1e,0xe4,0xe1,0x1d,0xe8,0xa1,0x1c,0xc6,0x81,0x1e,
|
|
|
+ 0xde,0x41,0x1e,0xda,0x40,0x1c,0xea,0xc1,0x1c,0xcc,0xa1,0x1c,0xe4,0xa1,0x0d,0xe6,
|
|
|
+ 0x21,0x1d,0xf4,0xa1,0x1c,0x00,0x3c,0x00,0x88,0x7a,0x70,0x87,0x79,0x08,0x07,0x73,
|
|
|
+ 0x28,0x87,0x36,0x30,0x07,0x78,0x68,0x83,0x76,0x08,0x07,0x7a,0x40,0x07,0x80,0x1e,
|
|
|
+ 0xe4,0xa1,0x1e,0xca,0x01,0x20,0xea,0x61,0x1e,0xca,0xa1,0x0d,0xe6,0xe1,0x1d,0xcc,
|
|
|
+ 0x81,0x1e,0xda,0xc0,0x1c,0xd8,0xe1,0x1d,0xc2,0x81,0x1e,0x00,0x73,0x08,0x07,0x76,
|
|
|
+ 0x98,0x87,0x72,0x00,0x36,0x20,0x02,0x01,0x24,0xc0,0x02,0x54,0x00,0x00,0x00,0x00,
|
|
|
+ 0x49,0x18,0x00,0x00,0x01,0x00,0x00,0x00,0x13,0x84,0x40,0x00,0x89,0x20,0x00,0x00,
|
|
|
+ 0x1f,0x00,0x00,0x00,0x32,0x22,0x48,0x09,0x20,0x64,0x85,0x04,0x93,0x22,0xa4,0x84,
|
|
|
+ 0x04,0x93,0x22,0xe3,0x84,0xa1,0x90,0x14,0x12,0x4c,0x8a,0x8c,0x0b,0x84,0xa4,0x4c,
|
|
|
+ 0x10,0x44,0x33,0x00,0xc3,0x08,0x02,0x30,0x8c,0x40,0x00,0x76,0x08,0x42,0x24,0x81,
|
|
|
+ 0x98,0x89,0x9a,0x07,0x7a,0x90,0x87,0x7a,0x18,0x07,0x7a,0x70,0x83,0x76,0x28,0x07,
|
|
|
+ 0x7a,0x08,0x07,0x76,0xd0,0x03,0x3d,0x68,0x87,0x70,0xa0,0x07,0x79,0x48,0x07,0x7c,
|
|
|
+ 0x40,0x01,0x39,0x48,0x9a,0x22,0x4a,0x98,0xfc,0x4a,0xfa,0x1f,0x20,0x02,0x18,0x09,
|
|
|
+ 0x05,0x65,0x10,0xc1,0x10,0x4a,0x31,0x42,0x10,0x87,0xd0,0x40,0xc0,0x1c,0x01,0x18,
|
|
|
+ 0xa4,0xc0,0x9a,0x23,0x00,0x85,0x41,0x04,0x41,0x18,0x46,0x20,0x96,0x11,0x00,0x00,
|
|
|
+ 0x13,0xa8,0x70,0x48,0x07,0x79,0xb0,0x03,0x3a,0x68,0x83,0x70,0x80,0x07,0x78,0x60,
|
|
|
+ 0x87,0x72,0x68,0x83,0x74,0x78,0x87,0x79,0xc8,0x03,0x37,0x80,0x03,0x37,0x80,0x83,
|
|
|
+ 0x0d,0xb7,0x51,0x0e,0x6d,0x00,0x0f,0x7a,0x60,0x07,0x74,0xa0,0x07,0x76,0x40,0x07,
|
|
|
+ 0x7a,0x60,0x07,0x74,0xd0,0x06,0xe9,0x10,0x07,0x7a,0x80,0x07,0x7a,0x80,0x07,0x6d,
|
|
|
+ 0x90,0x0e,0x78,0xa0,0x07,0x78,0xa0,0x07,0x78,0xd0,0x06,0xe9,0x10,0x07,0x76,0xa0,
|
|
|
+ 0x07,0x71,0x60,0x07,0x7a,0x10,0x07,0x76,0xd0,0x06,0xe9,0x30,0x07,0x72,0xa0,0x07,
|
|
|
+ 0x73,0x20,0x07,0x7a,0x30,0x07,0x72,0xd0,0x06,0xe9,0x60,0x07,0x74,0xa0,0x07,0x76,
|
|
|
+ 0x40,0x07,0x7a,0x60,0x07,0x74,0xd0,0x06,0xe6,0x30,0x07,0x72,0xa0,0x07,0x73,0x20,
|
|
|
+ 0x07,0x7a,0x30,0x07,0x72,0xd0,0x06,0xe6,0x60,0x07,0x74,0xa0,0x07,0x76,0x40,0x07,
|
|
|
+ 0x7a,0x60,0x07,0x74,0xd0,0x06,0xf6,0x10,0x07,0x76,0xa0,0x07,0x71,0x60,0x07,0x7a,
|
|
|
+ 0x10,0x07,0x76,0xd0,0x06,0xf6,0x20,0x07,0x74,0xa0,0x07,0x73,0x20,0x07,0x7a,0x30,
|
|
|
+ 0x07,0x72,0xd0,0x06,0xf6,0x30,0x07,0x72,0xa0,0x07,0x73,0x20,0x07,0x7a,0x30,0x07,
|
|
|
+ 0x72,0xd0,0x06,0xf6,0x40,0x07,0x78,0xa0,0x07,0x76,0x40,0x07,0x7a,0x60,0x07,0x74,
|
|
|
+ 0xd0,0x06,0xf6,0x60,0x07,0x74,0xa0,0x07,0x76,0x40,0x07,0x7a,0x60,0x07,0x74,0xd0,
|
|
|
+ 0x06,0xf6,0x90,0x07,0x76,0xa0,0x07,0x71,0x20,0x07,0x78,0xa0,0x07,0x71,0x20,0x07,
|
|
|
+ 0x78,0xd0,0x06,0xf6,0x10,0x07,0x72,0x80,0x07,0x7a,0x10,0x07,0x72,0x80,0x07,0x7a,
|
|
|
+ 0x10,0x07,0x72,0x80,0x07,0x6d,0x60,0x0f,0x71,0x90,0x07,0x72,0xa0,0x07,0x72,0x50,
|
|
|
+ 0x07,0x76,0xa0,0x07,0x72,0x50,0x07,0x76,0xd0,0x06,0xf6,0x20,0x07,0x75,0x60,0x07,
|
|
|
+ 0x7a,0x20,0x07,0x75,0x60,0x07,0x7a,0x20,0x07,0x75,0x60,0x07,0x6d,0x60,0x0f,0x75,
|
|
|
+ 0x10,0x07,0x72,0xa0,0x07,0x75,0x10,0x07,0x72,0xa0,0x07,0x75,0x10,0x07,0x72,0xd0,
|
|
|
+ 0x06,0xf6,0x10,0x07,0x70,0x20,0x07,0x74,0xa0,0x07,0x71,0x00,0x07,0x72,0x40,0x07,
|
|
|
+ 0x7a,0x10,0x07,0x70,0x20,0x07,0x74,0xd0,0x06,0xee,0x80,0x07,0x7a,0x10,0x07,0x76,
|
|
|
+ 0xa0,0x07,0x73,0x20,0x07,0x43,0x98,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x80,
|
|
|
+ 0x2c,0x10,0x00,0x00,0x0a,0x00,0x00,0x00,0x32,0x1e,0x98,0x10,0x19,0x11,0x4c,0x90,
|
|
|
+ 0x8c,0x09,0x26,0x47,0xc6,0x04,0x43,0x5a,0x25,0x30,0x02,0x50,0x04,0x05,0x18,0x50,
|
|
|
+ 0x08,0x05,0x51,0x06,0x05,0x42,0x6d,0x04,0x80,0xd8,0x58,0xc2,0x53,0x00,0x00,0x00,
|
|
|
+ 0x79,0x18,0x00,0x00,0xea,0x00,0x00,0x00,0x1a,0x03,0x4c,0x10,0x97,0x29,0xa2,0x25,
|
|
|
+ 0x10,0xab,0x32,0xb9,0xb9,0xb4,0x37,0xb7,0x21,0xc6,0x32,0x28,0x00,0xa3,0x50,0xb9,
|
|
|
+ 0x1b,0x43,0x0b,0x93,0xfb,0x9a,0x4b,0xd3,0x2b,0x1b,0x62,0x2c,0x81,0x22,0x2c,0x05,
|
|
|
+ 0xe3,0x20,0x08,0x0e,0x8e,0xad,0x0c,0xa4,0xad,0x8c,0x2e,0x8c,0x0d,0xc4,0xae,0x4c,
|
|
|
+ 0x6e,0x2e,0xed,0xcd,0x0d,0x64,0x26,0x06,0x06,0x26,0xc6,0xa5,0x26,0xe6,0x06,0x04,
|
|
|
+ 0xa5,0xad,0x8c,0x2e,0x8c,0xcd,0xac,0xac,0x65,0x26,0x06,0x06,0x26,0xc6,0xa5,0x26,
|
|
|
+ 0xe6,0x26,0x65,0x88,0xa0,0x10,0x43,0x8c,0x25,0x58,0x8c,0x45,0x60,0xd1,0x54,0x46,
|
|
|
+ 0x17,0xc6,0x36,0x04,0x51,0x8e,0x25,0x58,0x84,0x45,0xe0,0x16,0x96,0x26,0xe7,0x32,
|
|
|
+ 0xf6,0xd6,0x06,0x97,0xc6,0x56,0xe6,0x42,0x56,0xe6,0xf6,0x26,0xd7,0x36,0xf7,0x45,
|
|
|
+ 0x96,0x36,0x17,0x26,0xc6,0x56,0x36,0x44,0x50,0x12,0x72,0x61,0x69,0x72,0x2e,0x63,
|
|
|
+ 0x6f,0x6d,0x70,0x69,0x6c,0x65,0x2e,0x66,0x61,0x73,0x74,0x5f,0x6d,0x61,0x74,0x68,
|
|
|
+ 0x5f,0x65,0x6e,0x61,0x62,0x6c,0x65,0x43,0x04,0x65,0x21,0x19,0x84,0xa5,0xc9,0xb9,
|
|
|
+ 0x8c,0xbd,0xb5,0xc1,0xa5,0xb1,0x95,0xb9,0x98,0xc9,0x85,0xb5,0x95,0x89,0xd5,0x99,
|
|
|
+ 0x99,0x95,0xc9,0x7d,0x99,0x95,0xd1,0x8d,0xa1,0x7d,0x95,0xb9,0x85,0x89,0xb1,0x95,
|
|
|
+ 0x0d,0x11,0x94,0x86,0x51,0x58,0x9a,0x9c,0x8b,0x5d,0x99,0x1c,0x5d,0x19,0xde,0xd7,
|
|
|
+ 0x5b,0x1d,0x1d,0x5c,0x1d,0x1d,0x97,0xba,0xb9,0x32,0x39,0x14,0xb6,0xb7,0x31,0x37,
|
|
|
+ 0x98,0x14,0x46,0x61,0x69,0x72,0x2e,0x61,0x72,0x67,0x5f,0x74,0x79,0x70,0x65,0x5f,
|
|
|
+ 0x6e,0x61,0x6d,0x65,0x34,0xcc,0xd8,0xde,0xc2,0xe8,0x64,0xc8,0x84,0xa5,0xc9,0xb9,
|
|
|
+ 0x84,0xc9,0x9d,0x7d,0xb9,0x85,0xb5,0x95,0x51,0xa8,0xb3,0x1b,0xc2,0x28,0x8f,0x02,
|
|
|
+ 0x29,0x91,0x22,0x29,0x93,0x42,0x71,0xa9,0x9b,0x2b,0x93,0x43,0x61,0x7b,0x1b,0x73,
|
|
|
+ 0x8b,0x49,0xa1,0x61,0xc6,0xf6,0x16,0x46,0x47,0xc3,0x62,0xec,0x8d,0xed,0x4d,0x6e,
|
|
|
+ 0x08,0xa3,0x3c,0x8a,0xa5,0x44,0xca,0xa5,0x4c,0x0a,0x46,0x26,0x2c,0x4d,0xce,0x05,
|
|
|
+ 0xee,0x6d,0x2e,0x8d,0x2e,0xed,0xcd,0x8d,0xcb,0x19,0xdb,0x17,0xd4,0xdb,0x5c,0x1a,
|
|
|
+ 0x5d,0xda,0x9b,0xdb,0x10,0x45,0xd1,0x94,0x48,0xb9,0x94,0x49,0xd9,0x86,0x18,0x4a,
|
|
|
+ 0xa5,0x64,0x0a,0x47,0x28,0x2c,0x4d,0xce,0xc5,0xae,0x4c,0x8e,0xae,0x0c,0xef,0x2b,
|
|
|
+ 0xcd,0x0d,0xae,0x8e,0x8e,0x52,0x58,0x9a,0x9c,0x0b,0xdb,0xdb,0x58,0x18,0x5d,0xda,
|
|
|
+ 0x9b,0xdb,0x57,0x9a,0x1b,0x59,0x19,0x1e,0xbd,0xb3,0x32,0xb7,0x32,0xb9,0x30,0xba,
|
|
|
+ 0x32,0x32,0x94,0xaf,0xaf,0xb0,0x34,0xb9,0x2f,0x38,0xb6,0xb0,0xb1,0x32,0xb4,0x37,
|
|
|
+ 0x36,0xb2,0x32,0xb9,0xaf,0xaf,0x14,0x22,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,
|
|
|
+ 0x43,0xa8,0x45,0x50,0x3c,0xe5,0x5b,0x84,0x25,0x50,0xc0,0x40,0x89,0x14,0x49,0x99,
|
|
|
+ 0x94,0x30,0x60,0x42,0x57,0x86,0x37,0xf6,0xf6,0x26,0x47,0x06,0x33,0x84,0x5a,0x02,
|
|
|
+ 0xc5,0x53,0xbe,0x25,0x58,0x02,0x05,0x0c,0x94,0x48,0x91,0x94,0x49,0x19,0x03,0x1a,
|
|
|
+ 0x63,0x6f,0x6c,0x6f,0x72,0x30,0x43,0xa8,0x65,0x50,0x3c,0xe5,0x5b,0x86,0x25,0x50,
|
|
|
+ 0xc0,0x40,0x89,0x94,0x4b,0x99,0x94,0x32,0xa0,0x12,0x96,0x26,0xe7,0x22,0x56,0x67,
|
|
|
+ 0x66,0x56,0x26,0xc7,0x27,0x2c,0x4d,0xce,0x45,0xac,0xce,0xcc,0xac,0x4c,0xee,0x6b,
|
|
|
+ 0x2e,0x4d,0xaf,0x8c,0x48,0x58,0x9a,0x9c,0x8b,0x5c,0x59,0x18,0x19,0xa9,0xb0,0x34,
|
|
|
+ 0x39,0x97,0x39,0x3a,0xb9,0xba,0x31,0xba,0x2f,0xba,0x3c,0xb8,0xb2,0xaf,0x34,0x37,
|
|
|
+ 0xb3,0x37,0x22,0x66,0x6c,0x6f,0x61,0x74,0x34,0x78,0x34,0x1c,0xda,0xec,0xe0,0x86,
|
|
|
+ 0x28,0x8b,0xb0,0x10,0x8b,0xa0,0xac,0x81,0xc2,0x06,0x8c,0xc2,0xd2,0xe4,0x5c,0xc2,
|
|
|
+ 0xe4,0xce,0xbe,0xe8,0xf2,0xe0,0xca,0xbe,0xe6,0xd2,0xf4,0xca,0x78,0x85,0xa5,0xc9,
|
|
|
+ 0xb9,0x84,0xc9,0x9d,0x7d,0xd1,0xe5,0xc1,0x95,0x7d,0x85,0xb1,0xa5,0x9d,0xb9,0x7d,
|
|
|
+ 0xcd,0xa5,0xe9,0x95,0x31,0xb1,0x9b,0xfb,0x82,0x0b,0x93,0x0b,0x6b,0x9b,0xe3,0xf0,
|
|
|
+ 0x25,0x13,0x33,0x84,0x0c,0x96,0x43,0x39,0x03,0x05,0x0d,0x16,0x42,0xf9,0x16,0x61,
|
|
|
+ 0x09,0x94,0x34,0x50,0xd4,0x40,0x69,0x03,0xc5,0x0d,0x16,0x42,0x79,0x83,0x05,0x51,
|
|
|
+ 0x22,0x05,0x0e,0x94,0x49,0x89,0x83,0x21,0x88,0x22,0x06,0x0a,0x19,0x28,0x66,0xa0,
|
|
|
+ 0xc8,0xc1,0x10,0x23,0x01,0x94,0x4e,0x99,0x03,0x3e,0x6f,0x6d,0x6e,0x69,0x70,0x6f,
|
|
|
+ 0x74,0x65,0x6e,0x74,0x20,0x63,0x68,0x61,0x72,0x7c,0xa6,0xd2,0xda,0xe0,0xd8,0xca,
|
|
|
+ 0x40,0x86,0x56,0x56,0x40,0xa8,0x84,0x82,0x82,0x86,0x08,0x8a,0x1d,0x0c,0x31,0x94,
|
|
|
+ 0x3a,0x50,0xee,0xa0,0x49,0x86,0x18,0x0a,0x1e,0x28,0x78,0xd0,0x24,0x23,0x22,0x76,
|
|
|
+ 0x60,0x07,0x7b,0x68,0x07,0x37,0x68,0x87,0x77,0x20,0x87,0x7a,0x60,0x87,0x72,0x70,
|
|
|
+ 0x03,0x73,0x60,0x87,0x70,0x38,0x87,0x79,0x98,0x22,0x04,0xc3,0x08,0x85,0x1d,0xd8,
|
|
|
+ 0xc1,0x1e,0xda,0xc1,0x0d,0xd2,0x81,0x1c,0xca,0xc1,0x1d,0xe8,0x61,0x4a,0x50,0x8c,
|
|
|
+ 0x58,0xc2,0x21,0x1d,0xe4,0xc1,0x0d,0xec,0xa1,0x1c,0xe4,0x61,0x1e,0xd2,0xe1,0x1d,
|
|
|
+ 0xdc,0x61,0x4a,0x60,0x8c,0xa0,0xc2,0x21,0x1d,0xe4,0xc1,0x0d,0xd8,0x21,0x1c,0xdc,
|
|
|
+ 0xe1,0x1c,0xea,0x21,0x1c,0xce,0xa1,0x1c,0x7e,0xc1,0x1e,0xca,0x41,0x1e,0xe6,0x21,
|
|
|
+ 0x1d,0xde,0xc1,0x1d,0xa6,0x04,0xc8,0x88,0x29,0x1c,0xd2,0x41,0x1e,0xdc,0x60,0x1c,
|
|
|
+ 0xde,0xa1,0x1d,0xe0,0x21,0x1d,0xd8,0xa1,0x1c,0x7e,0xe1,0x1d,0xe0,0x81,0x1e,0xd2,
|
|
|
+ 0xe1,0x1d,0xdc,0x61,0x1e,0xa6,0x0c,0x0a,0xe3,0x8c,0x50,0xc2,0x21,0x1d,0xe4,0xc1,
|
|
|
+ 0x0d,0xec,0xa1,0x1c,0xe4,0x81,0x1e,0xca,0x01,0x1f,0xa6,0x04,0x74,0x00,0x00,0x00,
|
|
|
+ 0x79,0x18,0x00,0x00,0x7b,0x00,0x00,0x00,0x33,0x08,0x80,0x1c,0xc4,0xe1,0x1c,0x66,
|
|
|
+ 0x14,0x01,0x3d,0x88,0x43,0x38,0x84,0xc3,0x8c,0x42,0x80,0x07,0x79,0x78,0x07,0x73,
|
|
|
+ 0x98,0x71,0x0c,0xe6,0x00,0x0f,0xed,0x10,0x0e,0xf4,0x80,0x0e,0x33,0x0c,0x42,0x1e,
|
|
|
+ 0xc2,0xc1,0x1d,0xce,0xa1,0x1c,0x66,0x30,0x05,0x3d,0x88,0x43,0x38,0x84,0x83,0x1b,
|
|
|
+ 0xcc,0x03,0x3d,0xc8,0x43,0x3d,0x8c,0x03,0x3d,0xcc,0x78,0x8c,0x74,0x70,0x07,0x7b,
|
|
|
+ 0x08,0x07,0x79,0x48,0x87,0x70,0x70,0x07,0x7a,0x70,0x03,0x76,0x78,0x87,0x70,0x20,
|
|
|
+ 0x87,0x19,0xcc,0x11,0x0e,0xec,0x90,0x0e,0xe1,0x30,0x0f,0x6e,0x30,0x0f,0xe3,0xf0,
|
|
|
+ 0x0e,0xf0,0x50,0x0e,0x33,0x10,0xc4,0x1d,0xde,0x21,0x1c,0xd8,0x21,0x1d,0xc2,0x61,
|
|
|
+ 0x1e,0x66,0x30,0x89,0x3b,0xbc,0x83,0x3b,0xd0,0x43,0x39,0xb4,0x03,0x3c,0xbc,0x83,
|
|
|
+ 0x3c,0x84,0x03,0x3b,0xcc,0xf0,0x14,0x76,0x60,0x07,0x7b,0x68,0x07,0x37,0x68,0x87,
|
|
|
+ 0x72,0x68,0x07,0x37,0x80,0x87,0x70,0x90,0x87,0x70,0x60,0x07,0x76,0x28,0x07,0x76,
|
|
|
+ 0xf8,0x05,0x76,0x78,0x87,0x77,0x80,0x87,0x5f,0x08,0x87,0x71,0x18,0x87,0x72,0x98,
|
|
|
+ 0x87,0x79,0x98,0x81,0x2c,0xee,0xf0,0x0e,0xee,0xe0,0x0e,0xf5,0xc0,0x0e,0xec,0x30,
|
|
|
+ 0x03,0x62,0xc8,0xa1,0x1c,0xe4,0xa1,0x1c,0xcc,0xa1,0x1c,0xe4,0xa1,0x1c,0xdc,0x61,
|
|
|
+ 0x1c,0xca,0x21,0x1c,0xc4,0x81,0x1d,0xca,0x61,0x06,0xd6,0x90,0x43,0x39,0xc8,0x43,
|
|
|
+ 0x39,0x98,0x43,0x39,0xc8,0x43,0x39,0xb8,0xc3,0x38,0x94,0x43,0x38,0x88,0x03,0x3b,
|
|
|
+ 0x94,0xc3,0x2f,0xbc,0x83,0x3c,0xfc,0x82,0x3b,0xd4,0x03,0x3b,0xb0,0xc3,0x0c,0xc7,
|
|
|
+ 0x69,0x87,0x70,0x58,0x87,0x72,0x70,0x83,0x74,0x68,0x07,0x78,0x60,0x87,0x74,0x18,
|
|
|
+ 0x87,0x74,0xa0,0x87,0x19,0xce,0x53,0x0f,0xee,0x00,0x0f,0xf2,0x50,0x0e,0xe4,0x90,
|
|
|
+ 0x0e,0xe3,0x40,0x0f,0xe1,0x20,0x0e,0xec,0x50,0x0e,0x33,0x20,0x28,0x1d,0xdc,0xc1,
|
|
|
+ 0x1e,0xc2,0x41,0x1e,0xd2,0x21,0x1c,0xdc,0x81,0x1e,0xdc,0xe0,0x1c,0xe4,0xe1,0x1d,
|
|
|
+ 0xea,0x01,0x1e,0x66,0x18,0x51,0x38,0xb0,0x43,0x3a,0x9c,0x83,0x3b,0xcc,0x50,0x24,
|
|
|
+ 0x76,0x60,0x07,0x7b,0x68,0x07,0x37,0x60,0x87,0x77,0x78,0x07,0x78,0x98,0x51,0x4c,
|
|
|
+ 0xf4,0x90,0x0f,0xf0,0x50,0x0e,0x33,0x1e,0x6a,0x1e,0xca,0x61,0x1c,0xe8,0x21,0x1d,
|
|
|
+ 0xde,0xc1,0x1d,0x7e,0x01,0x1e,0xe4,0xa1,0x1c,0xcc,0x21,0x1d,0xf0,0x61,0x06,0x54,
|
|
|
+ 0x85,0x83,0x38,0xcc,0xc3,0x3b,0xb0,0x43,0x3d,0xd0,0x43,0x39,0xfc,0xc2,0x3c,0xe4,
|
|
|
+ 0x43,0x3b,0x88,0xc3,0x3b,0xb0,0xc3,0x8c,0xc5,0x0a,0x87,0x79,0x98,0x87,0x77,0x18,
|
|
|
+ 0x87,0x74,0x08,0x07,0x7a,0x28,0x07,0x72,0x98,0x81,0x5c,0xe3,0x10,0x0e,0xec,0xc0,
|
|
|
+ 0x0e,0xe5,0x50,0x0e,0xf3,0x30,0x23,0xc1,0xd2,0x41,0x1e,0xe4,0xe1,0x17,0xd8,0xe1,
|
|
|
+ 0x1d,0xde,0x01,0x1e,0x66,0x50,0x59,0x38,0xa4,0x83,0x3c,0xb8,0x81,0x39,0xd4,0x83,
|
|
|
+ 0x3b,0x8c,0x03,0x3d,0xa4,0xc3,0x3b,0xb8,0xc3,0x2f,0x9c,0x83,0x3c,0xbc,0x43,0x3d,
|
|
|
+ 0xc0,0xc3,0x3c,0x00,0x71,0x20,0x00,0x00,0x02,0x00,0x00,0x00,0x06,0x50,0x30,0x00,
|
|
|
+ 0xd2,0xd0,0x00,0x00,0x61,0x20,0x00,0x00,0x1e,0x00,0x00,0x00,0x13,0x04,0x41,0x2c,
|
|
|
+ 0x10,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0xf4,0xc6,0x22,0x82,0x20,0x08,0x46,0x00,
|
|
|
+ 0xa8,0x95,0x40,0x19,0xd0,0x98,0x01,0xa0,0x30,0x03,0x00,0x00,0xe3,0x15,0x07,0x33,
|
|
|
+ 0x4d,0x0c,0x05,0x65,0x90,0x81,0x19,0x0e,0x13,0x02,0xf9,0x8c,0x57,0x2c,0xd0,0x75,
|
|
|
+ 0x21,0x14,0x94,0x41,0x06,0xe8,0x60,0x4c,0x08,0xe4,0x63,0x41,0x01,0x9f,0xf1,0x0a,
|
|
|
+ 0xa8,0xe2,0x38,0x86,0x82,0x62,0x43,0x00,0x9f,0xd9,0x06,0xa7,0x02,0x66,0x1b,0x82,
|
|
|
+ 0x2a,0x98,0x6d,0x08,0x06,0x21,0x83,0x80,0x18,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
|
|
|
+ 0x5b,0x86,0x20,0xc8,0x83,0x2d,0x43,0x11,0xe4,0xc1,0x96,0x41,0x09,0xf2,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+};
|
|
|
+static const uint8_t _sspine_fs_bytecode_metal_ios[3257] = {
|
|
|
+ 0x4d,0x54,0x4c,0x42,0x01,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0xb9,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x6d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0xe0,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x6d,0x00,0x00,0x00,
|
|
|
+ 0x4e,0x41,0x4d,0x45,0x06,0x00,0x6d,0x61,0x69,0x6e,0x30,0x00,0x54,0x59,0x50,0x45,
|
|
|
+ 0x01,0x00,0x01,0x48,0x41,0x53,0x48,0x20,0x00,0xd9,0xfc,0xdf,0x3c,0xd7,0xa7,0xa7,
|
|
|
+ 0x8d,0xdf,0x35,0x03,0xca,0x84,0xdd,0x0c,0x35,0xa5,0xf8,0x0e,0x6e,0x0d,0x77,0x9a,
|
|
|
+ 0x47,0x0e,0xe1,0x20,0xf6,0x87,0xac,0x7a,0x9e,0x4f,0x46,0x46,0x54,0x18,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x56,0x45,0x52,0x53,0x08,0x00,0x01,0x00,0x08,
|
|
|
+ 0x00,0x01,0x00,0x00,0x00,0x45,0x4e,0x44,0x54,0x04,0x00,0x00,0x00,0x45,0x4e,0x44,
|
|
|
+ 0x54,0x04,0x00,0x00,0x00,0x45,0x4e,0x44,0x54,0xde,0xc0,0x17,0x0b,0x00,0x00,0x00,
|
|
|
+ 0x00,0x14,0x00,0x00,0x00,0xc0,0x0b,0x00,0x00,0xff,0xff,0xff,0xff,0x42,0x43,0xc0,
|
|
|
+ 0xde,0x21,0x0c,0x00,0x00,0xed,0x02,0x00,0x00,0x0b,0x82,0x20,0x00,0x02,0x00,0x00,
|
|
|
+ 0x00,0x12,0x00,0x00,0x00,0x07,0x81,0x23,0x91,0x41,0xc8,0x04,0x49,0x06,0x10,0x32,
|
|
|
+ 0x39,0x92,0x01,0x84,0x0c,0x25,0x05,0x08,0x19,0x1e,0x04,0x8b,0x62,0x80,0x14,0x45,
|
|
|
+ 0x02,0x42,0x92,0x0b,0x42,0xa4,0x10,0x32,0x14,0x38,0x08,0x18,0x49,0x0a,0x32,0x44,
|
|
|
+ 0x24,0x48,0x0a,0x90,0x21,0x23,0xc4,0x52,0x80,0x0c,0x19,0x21,0x72,0x24,0x07,0xc8,
|
|
|
+ 0x48,0x11,0x62,0xa8,0xa0,0xa8,0x40,0xc6,0xf0,0x01,0x00,0x00,0x00,0x51,0x18,0x00,
|
|
|
+ 0x00,0x8e,0x00,0x00,0x00,0x1b,0xcc,0x25,0xf8,0xff,0xff,0xff,0xff,0x01,0x60,0x00,
|
|
|
+ 0x09,0xa8,0x88,0x71,0x78,0x07,0x79,0x90,0x87,0x72,0x18,0x07,0x7a,0x60,0x87,0x7c,
|
|
|
+ 0x68,0x03,0x79,0x78,0x87,0x7a,0x70,0x07,0x72,0x28,0x07,0x72,0x68,0x03,0x72,0x48,
|
|
|
+ 0x07,0x7b,0x48,0x07,0x72,0x28,0x87,0x36,0x98,0x87,0x78,0x90,0x07,0x7a,0x68,0x03,
|
|
|
+ 0x73,0x80,0x87,0x36,0x68,0x87,0x70,0xa0,0x07,0x74,0x00,0xcc,0x21,0x1c,0xd8,0x61,
|
|
|
+ 0x1e,0xca,0x01,0x20,0xc8,0x21,0x1d,0xe6,0x21,0x1c,0xc4,0x81,0x1d,0xca,0xa1,0x0d,
|
|
|
+ 0xe8,0x21,0x1c,0xd2,0x81,0x1d,0xda,0x60,0x1c,0xc2,0x81,0x1d,0xd8,0x61,0x1e,0x00,
|
|
|
+ 0x73,0x08,0x07,0x76,0x98,0x87,0x72,0x00,0x08,0x76,0x28,0x87,0x79,0x98,0x87,0x36,
|
|
|
+ 0x80,0x07,0x79,0x28,0x87,0x71,0x48,0x87,0x79,0x28,0x87,0x36,0x30,0x07,0x78,0x68,
|
|
|
+ 0x87,0x70,0x20,0x07,0xc0,0x1c,0xc2,0x81,0x1d,0xe6,0xa1,0x1c,0x00,0xc2,0x1d,0xde,
|
|
|
+ 0xa1,0x0d,0xcc,0x41,0x1e,0xc2,0xa1,0x1d,0xca,0xa1,0x0d,0xe0,0xe1,0x1d,0xd2,0xc1,
|
|
|
+ 0x1d,0xe8,0xa1,0x1c,0xe4,0xa1,0x0d,0xca,0x81,0x1d,0xd2,0xa1,0x1d,0x00,0x7a,0x90,
|
|
|
+ 0x87,0x7a,0x28,0x07,0x60,0x70,0x87,0x77,0x68,0x03,0x73,0x90,0x87,0x70,0x68,0x87,
|
|
|
+ 0x72,0x68,0x03,0x78,0x78,0x87,0x74,0x70,0x07,0x7a,0x28,0x07,0x79,0x68,0x83,0x72,
|
|
|
+ 0x60,0x87,0x74,0x68,0x87,0x36,0x70,0x87,0x77,0x70,0x87,0x36,0x60,0x87,0x72,0x08,
|
|
|
+ 0x07,0x73,0x00,0x08,0x77,0x78,0x87,0x36,0x48,0x07,0x77,0x30,0x87,0x79,0x68,0x03,
|
|
|
+ 0x73,0x80,0x87,0x36,0x68,0x87,0x70,0xa0,0x07,0x74,0x00,0xe8,0x41,0x1e,0xea,0xa1,
|
|
|
+ 0x1c,0x00,0xc2,0x1d,0xde,0xa1,0x0d,0xd4,0xa1,0x1e,0xda,0x01,0x1e,0xda,0x80,0x1e,
|
|
|
+ 0xc2,0x41,0x1c,0xd8,0xa1,0x1c,0xe6,0x01,0x30,0x87,0x70,0x60,0x87,0x79,0x28,0x07,
|
|
|
+ 0x80,0x70,0x87,0x77,0x68,0x03,0x77,0x08,0x07,0x77,0x98,0x87,0x36,0x30,0x07,0x78,
|
|
|
+ 0x68,0x83,0x76,0x08,0x07,0x7a,0x40,0x07,0x80,0x1e,0xe4,0xa1,0x1e,0xca,0x01,0x20,
|
|
|
+ 0xdc,0xe1,0x1d,0xda,0x60,0x1e,0xd2,0xe1,0x1c,0xdc,0xa1,0x1c,0xc8,0xa1,0x0d,0xf4,
|
|
|
+ 0xa1,0x1c,0xe4,0xe1,0x1d,0xe6,0xa1,0x0d,0xcc,0x01,0x1e,0xda,0xa0,0x1d,0xc2,0x81,
|
|
|
+ 0x1e,0xd0,0x01,0xa0,0x07,0x79,0xa8,0x87,0x72,0x00,0x08,0x77,0x78,0x87,0x36,0xa0,
|
|
|
+ 0x07,0x79,0x08,0x07,0x78,0x80,0x87,0x74,0x70,0x87,0x73,0x68,0x83,0x76,0x08,0x07,
|
|
|
+ 0x7a,0x40,0x07,0x80,0x1e,0xe4,0xa1,0x1e,0xca,0x01,0x20,0xe6,0x81,0x1e,0xc2,0x61,
|
|
|
+ 0x1c,0xd6,0xa1,0x0d,0xe0,0x41,0x1e,0xde,0x81,0x1e,0xca,0x61,0x1c,0xe8,0xe1,0x1d,
|
|
|
+ 0xe4,0xa1,0x0d,0xc4,0xa1,0x1e,0xcc,0xc1,0x1c,0xca,0x41,0x1e,0xda,0x60,0x1e,0xd2,
|
|
|
+ 0x41,0x1f,0xca,0x01,0xc0,0x03,0x80,0xa8,0x07,0x77,0x98,0x87,0x70,0x30,0x87,0x72,
|
|
|
+ 0x68,0x03,0x73,0x80,0x87,0x36,0x68,0x87,0x70,0xa0,0x07,0x74,0x00,0xe8,0x41,0x1e,
|
|
|
+ 0xea,0xa1,0x1c,0x00,0xa2,0x1e,0xe6,0xa1,0x1c,0xda,0x60,0x1e,0xde,0xc1,0x1c,0xe8,
|
|
|
+ 0xa1,0x0d,0xcc,0x81,0x1d,0xde,0x21,0x1c,0xe8,0x01,0x30,0x87,0x70,0x60,0x87,0x79,
|
|
|
+ 0x28,0x07,0x60,0x03,0x22,0x0c,0x40,0x02,0x2c,0x40,0xb5,0xc1,0x18,0x08,0x60,0x01,
|
|
|
+ 0xaa,0x0d,0x06,0x51,0x00,0x0b,0x50,0x6d,0x30,0x8a,0xff,0xff,0xff,0xff,0x1f,0x00,
|
|
|
+ 0x09,0xa0,0x36,0x20,0xc6,0xff,0xff,0xff,0xff,0x0f,0x00,0x03,0x48,0x40,0xb5,0xc1,
|
|
|
+ 0x38,0x02,0x60,0x01,0xaa,0x0d,0x06,0x22,0x00,0x0b,0x50,0x01,0x00,0x49,0x18,0x00,
|
|
|
+ 0x00,0x03,0x00,0x00,0x00,0x13,0x88,0x40,0x18,0x88,0x09,0x41,0x31,0x61,0x30,0x0e,
|
|
|
+ 0x04,0x89,0x20,0x00,0x00,0x27,0x00,0x00,0x00,0x32,0x22,0x48,0x09,0x20,0x64,0x85,
|
|
|
+ 0x04,0x93,0x22,0xa4,0x84,0x04,0x93,0x22,0xe3,0x84,0xa1,0x90,0x14,0x12,0x4c,0x8a,
|
|
|
+ 0x8c,0x0b,0x84,0xa4,0x4c,0x10,0x6c,0x33,0x00,0xc3,0x08,0x04,0x60,0x83,0x30,0x8c,
|
|
|
+ 0x20,0x00,0x07,0x49,0x53,0x44,0x09,0x93,0x5f,0x48,0xff,0x03,0x44,0x00,0x23,0xa1,
|
|
|
+ 0x00,0x0c,0x22,0x10,0xc2,0x51,0xd2,0x14,0x51,0xc2,0xe4,0xff,0x13,0x71,0x4d,0x54,
|
|
|
+ 0x44,0xfc,0xf6,0xf0,0x4f,0x63,0x04,0xc0,0x20,0x82,0x11,0x5c,0x24,0x4d,0x11,0x25,
|
|
|
+ 0x4c,0xfe,0x2f,0x01,0xcc,0xb3,0x10,0xd1,0x3f,0x8d,0x11,0x00,0x83,0x08,0x88,0x50,
|
|
|
+ 0x0c,0x31,0x42,0x39,0x89,0x54,0x21,0x42,0x08,0x81,0xd8,0x1c,0x41,0x30,0x47,0x00,
|
|
|
+ 0x06,0xc3,0x08,0xc2,0x53,0x90,0x70,0xd2,0x70,0xd0,0x01,0x8a,0x03,0x01,0x29,0xf0,
|
|
|
+ 0x86,0x11,0x86,0x67,0x18,0x61,0x00,0x86,0x11,0x88,0x67,0x8e,0x00,0x14,0x06,0x11,
|
|
|
+ 0x00,0x61,0x04,0x00,0x00,0x13,0xa8,0x70,0x48,0x07,0x79,0xb0,0x03,0x3a,0x68,0x83,
|
|
|
+ 0x70,0x80,0x07,0x78,0x60,0x87,0x72,0x68,0x83,0x74,0x78,0x87,0x79,0xc8,0x03,0x37,
|
|
|
+ 0x80,0x03,0x37,0x80,0x83,0x0d,0xb7,0x51,0x0e,0x6d,0x00,0x0f,0x7a,0x60,0x07,0x74,
|
|
|
+ 0xa0,0x07,0x76,0x40,0x07,0x7a,0x60,0x07,0x74,0xd0,0x06,0xe9,0x10,0x07,0x7a,0x80,
|
|
|
+ 0x07,0x7a,0x80,0x07,0x6d,0x90,0x0e,0x78,0xa0,0x07,0x78,0xa0,0x07,0x78,0xd0,0x06,
|
|
|
+ 0xe9,0x10,0x07,0x76,0xa0,0x07,0x71,0x60,0x07,0x7a,0x10,0x07,0x76,0xd0,0x06,0xe9,
|
|
|
+ 0x30,0x07,0x72,0xa0,0x07,0x73,0x20,0x07,0x7a,0x30,0x07,0x72,0xd0,0x06,0xe9,0x60,
|
|
|
+ 0x07,0x74,0xa0,0x07,0x76,0x40,0x07,0x7a,0x60,0x07,0x74,0xd0,0x06,0xe6,0x30,0x07,
|
|
|
+ 0x72,0xa0,0x07,0x73,0x20,0x07,0x7a,0x30,0x07,0x72,0xd0,0x06,0xe6,0x60,0x07,0x74,
|
|
|
+ 0xa0,0x07,0x76,0x40,0x07,0x7a,0x60,0x07,0x74,0xd0,0x06,0xf6,0x10,0x07,0x76,0xa0,
|
|
|
+ 0x07,0x71,0x60,0x07,0x7a,0x10,0x07,0x76,0xd0,0x06,0xf6,0x20,0x07,0x74,0xa0,0x07,
|
|
|
+ 0x73,0x20,0x07,0x7a,0x30,0x07,0x72,0xd0,0x06,0xf6,0x30,0x07,0x72,0xa0,0x07,0x73,
|
|
|
+ 0x20,0x07,0x7a,0x30,0x07,0x72,0xd0,0x06,0xf6,0x40,0x07,0x78,0xa0,0x07,0x76,0x40,
|
|
|
+ 0x07,0x7a,0x60,0x07,0x74,0xd0,0x06,0xf6,0x60,0x07,0x74,0xa0,0x07,0x76,0x40,0x07,
|
|
|
+ 0x7a,0x60,0x07,0x74,0xd0,0x06,0xf6,0x90,0x07,0x76,0xa0,0x07,0x71,0x20,0x07,0x78,
|
|
|
+ 0xa0,0x07,0x71,0x20,0x07,0x78,0xd0,0x06,0xf6,0x10,0x07,0x72,0x80,0x07,0x7a,0x10,
|
|
|
+ 0x07,0x72,0x80,0x07,0x7a,0x10,0x07,0x72,0x80,0x07,0x6d,0x60,0x0f,0x71,0x90,0x07,
|
|
|
+ 0x72,0xa0,0x07,0x72,0x50,0x07,0x76,0xa0,0x07,0x72,0x50,0x07,0x76,0xd0,0x06,0xf6,
|
|
|
+ 0x20,0x07,0x75,0x60,0x07,0x7a,0x20,0x07,0x75,0x60,0x07,0x7a,0x20,0x07,0x75,0x60,
|
|
|
+ 0x07,0x6d,0x60,0x0f,0x75,0x10,0x07,0x72,0xa0,0x07,0x75,0x10,0x07,0x72,0xa0,0x07,
|
|
|
+ 0x75,0x10,0x07,0x72,0xd0,0x06,0xf6,0x10,0x07,0x70,0x20,0x07,0x74,0xa0,0x07,0x71,
|
|
|
+ 0x00,0x07,0x72,0x40,0x07,0x7a,0x10,0x07,0x70,0x20,0x07,0x74,0xd0,0x06,0xee,0x80,
|
|
|
+ 0x07,0x7a,0x10,0x07,0x76,0xa0,0x07,0x73,0x20,0x07,0x43,0x98,0x05,0x00,0x80,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x80,0x21,0x4c,0x03,0x04,0x80,0x00,0x00,0x00,0x00,0x00,0xc0,
|
|
|
+ 0x10,0x46,0x02,0x02,0x60,0x00,0x00,0x00,0x00,0x00,0x20,0x0b,0x04,0x09,0x00,0x00,
|
|
|
+ 0x00,0x32,0x1e,0x98,0x10,0x19,0x11,0x4c,0x90,0x8c,0x09,0x26,0x47,0xc6,0x04,0x43,
|
|
|
+ 0x7a,0x23,0x00,0x25,0x50,0x08,0x45,0x50,0x10,0x65,0x40,0x78,0x04,0x80,0xe8,0x58,
|
|
|
+ 0xc2,0x53,0x00,0x00,0x00,0x79,0x18,0x00,0x00,0xfa,0x00,0x00,0x00,0x1a,0x03,0x4c,
|
|
|
+ 0x10,0x97,0x29,0xa2,0x25,0x10,0xab,0x32,0xb9,0xb9,0xb4,0x37,0xb7,0x21,0xc6,0x63,
|
|
|
+ 0x4c,0x00,0xa5,0x50,0xb9,0x1b,0x43,0x0b,0x93,0xfb,0x9a,0x4b,0xd3,0x2b,0x1b,0x62,
|
|
|
+ 0x3c,0xc4,0x24,0x3c,0x05,0xe3,0x20,0x08,0x0e,0x8e,0xad,0x0c,0xa4,0xad,0x8c,0x2e,
|
|
|
+ 0x8c,0x0d,0xc4,0xae,0x4c,0x6e,0x2e,0xed,0xcd,0x0d,0x64,0x26,0x06,0x06,0x26,0xc6,
|
|
|
+ 0xa5,0x26,0xe6,0x06,0x04,0xa5,0xad,0x8c,0x2e,0x8c,0xcd,0xac,0xac,0x65,0x26,0x06,
|
|
|
+ 0x06,0x26,0xc6,0xa5,0x26,0xe6,0x26,0x65,0x88,0x30,0x11,0x43,0x8c,0x87,0x78,0x8e,
|
|
|
+ 0x67,0x60,0xd1,0x54,0x46,0x17,0xc6,0x36,0x04,0x99,0x8e,0x87,0x78,0x86,0x67,0xe0,
|
|
|
+ 0x16,0x96,0x26,0xe7,0x32,0xf6,0xd6,0x06,0x97,0xc6,0x56,0xe6,0x42,0x56,0xe6,0xf6,
|
|
|
+ 0x26,0xd7,0x36,0xf7,0x45,0x96,0x36,0x17,0x26,0xc6,0x56,0x36,0x44,0x98,0x12,0x72,
|
|
|
+ 0x61,0x69,0x72,0x2e,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x2e,0x66,0x61,0x73,0x74,
|
|
|
+ 0x5f,0x6d,0x61,0x74,0x68,0x5f,0x65,0x6e,0x61,0x62,0x6c,0x65,0x43,0x84,0x69,0x21,
|
|
|
+ 0x19,0x84,0xa5,0xc9,0xb9,0x8c,0xbd,0xb5,0xc1,0xa5,0xb1,0x95,0xb9,0x98,0xc9,0x85,
|
|
|
+ 0xb5,0x95,0x89,0xd5,0x99,0x99,0x95,0xc9,0x7d,0x99,0x95,0xd1,0x8d,0xa1,0x7d,0x95,
|
|
|
+ 0xb9,0x85,0x89,0xb1,0x95,0x0d,0x11,0xa6,0x86,0x51,0x58,0x9a,0x9c,0x8b,0x5c,0x99,
|
|
|
+ 0x1b,0x59,0x99,0xdc,0x17,0x5d,0x98,0xdc,0x59,0x19,0x1d,0xa3,0xb0,0x34,0x39,0x97,
|
|
|
+ 0x30,0xb9,0xb3,0x2f,0xba,0x3c,0xb8,0xb2,0x2f,0xb7,0xb0,0xb6,0x32,0x1a,0x66,0x6c,
|
|
|
+ 0x6f,0x61,0x74,0x34,0x64,0xc2,0xd2,0xe4,0x5c,0xc2,0xe4,0xce,0xbe,0xdc,0xc2,0xda,
|
|
|
+ 0xca,0xa8,0x98,0xc9,0x85,0x9d,0x7d,0x8d,0xbd,0xb1,0xbd,0xc9,0x0d,0x61,0xa6,0xe7,
|
|
|
+ 0x19,0x26,0x68,0x8a,0x26,0x69,0x9a,0x86,0x08,0x13,0x45,0x29,0x2c,0x4d,0xce,0xc5,
|
|
|
+ 0x4c,0x2e,0xec,0xac,0xad,0xcc,0x8d,0xee,0x2b,0xcd,0x0d,0xae,0x8e,0x8e,0x4b,0xdd,
|
|
|
+ 0x5c,0x99,0x1c,0x0a,0xdb,0xdb,0x98,0x1b,0x4c,0x0a,0x95,0xb0,0x34,0x39,0x97,0xb1,
|
|
|
+ 0x32,0x37,0xba,0x32,0x39,0x3e,0x61,0x69,0x72,0x2e,0x70,0x65,0x72,0x73,0x70,0x65,
|
|
|
+ 0x63,0x74,0x69,0x76,0x65,0x34,0xcc,0xd8,0xde,0xc2,0xe8,0x64,0x28,0xd4,0xd9,0x0d,
|
|
|
+ 0x91,0x9e,0x61,0xb2,0xa6,0x6b,0xc2,0xa6,0x6c,0x82,0x26,0x6d,0x92,0xa6,0x8d,0x4b,
|
|
|
+ 0xdd,0x5c,0x99,0x1c,0x0a,0xdb,0xdb,0x98,0x5b,0x4c,0x0a,0x8b,0xb1,0x37,0xb6,0x37,
|
|
|
+ 0xb9,0x21,0xd2,0x43,0x4c,0xd6,0xd4,0x4d,0xd8,0x94,0x4d,0xd0,0x14,0x4d,0xd2,0xe4,
|
|
|
+ 0x51,0x09,0x4b,0x93,0x73,0x11,0xab,0x33,0x33,0x2b,0x93,0xe3,0x13,0x96,0x26,0xe7,
|
|
|
+ 0x22,0x56,0x67,0x66,0x56,0x26,0xf7,0x35,0x97,0xa6,0x57,0x46,0x29,0x2c,0x4d,0xce,
|
|
|
+ 0x85,0xed,0x6d,0x2c,0x8c,0x2e,0xed,0xcd,0xed,0x2b,0xcd,0x8d,0xac,0x0c,0x8f,0x48,
|
|
|
+ 0x58,0x9a,0x9c,0x8b,0x5c,0x59,0x18,0x19,0xa9,0xb0,0x34,0x39,0x97,0x39,0x3a,0xb9,
|
|
|
+ 0xba,0x31,0xba,0x2f,0xba,0x3c,0xb8,0xb2,0xaf,0x34,0x37,0xb3,0x37,0x16,0x66,0x6c,
|
|
|
+ 0x6f,0x61,0x74,0x1c,0xe0,0xda,0xc2,0x86,0x28,0xcf,0xf0,0x14,0xcf,0x30,0x95,0xc1,
|
|
|
+ 0x64,0x06,0x8c,0xc2,0xd2,0xe4,0x5c,0xc2,0xe4,0xce,0xbe,0xe8,0xf2,0xe0,0xca,0xbe,
|
|
|
+ 0xe6,0xd2,0xf4,0xca,0x78,0x85,0xa5,0xc9,0xb9,0x84,0xc9,0x9d,0x7d,0xd1,0xe5,0xc1,
|
|
|
+ 0x95,0x7d,0x85,0xb1,0xa5,0x9d,0xb9,0x7d,0xcd,0xa5,0xe9,0x95,0x31,0x31,0x9b,0xfb,
|
|
|
+ 0x82,0x0b,0x93,0x0b,0x6b,0x9b,0xe3,0xf0,0x55,0x03,0x33,0x84,0x0c,0x1e,0x63,0x02,
|
|
|
+ 0x83,0x29,0x0c,0x9e,0x62,0x12,0x83,0x67,0x78,0x88,0x69,0x0c,0x26,0x32,0x98,0xce,
|
|
|
+ 0x60,0x42,0x83,0xa7,0x98,0xd2,0xe0,0x29,0x26,0x68,0x52,0x83,0x49,0x9a,0xd6,0x80,
|
|
|
+ 0x4b,0x58,0x9a,0x9c,0x0b,0x5d,0x19,0x1e,0x5d,0x9d,0x5c,0x19,0x95,0xb0,0x34,0x39,
|
|
|
+ 0x97,0xb9,0xb0,0x36,0x38,0xb6,0x32,0x62,0x74,0x65,0x78,0x74,0x75,0x72,0x65,0x32,
|
|
|
+ 0x64,0x3c,0x66,0x6c,0x6f,0x61,0x74,0x2c,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x3e,
|
|
|
+ 0x1c,0xe8,0xca,0xf0,0x86,0x50,0x0f,0x32,0xb5,0xc1,0x24,0x06,0xcf,0xf0,0x10,0x93,
|
|
|
+ 0x1b,0x4c,0xd0,0xf4,0x06,0x93,0x34,0xc1,0x01,0x97,0xb0,0x34,0x39,0x97,0xb9,0xb0,
|
|
|
+ 0x36,0x38,0xb6,0x32,0x39,0x1e,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x44,0xe8,0xca,
|
|
|
+ 0xf0,0xa6,0xda,0xe0,0xd8,0xe4,0x86,0x48,0x4f,0x31,0xc9,0xc1,0x24,0x06,0xcf,0xf0,
|
|
|
+ 0x10,0x13,0x34,0xcd,0xc1,0x24,0x4d,0x74,0x30,0x44,0x99,0xb8,0xe9,0x9b,0xd8,0x60,
|
|
|
+ 0x8a,0x83,0xa9,0x0e,0x86,0x18,0x0b,0x30,0x55,0x93,0x1d,0xd0,0xf9,0xd2,0xa2,0x9a,
|
|
|
+ 0xca,0x31,0x9b,0xfb,0x82,0x0b,0x93,0x0b,0x6b,0x9b,0xe3,0xf3,0xd6,0xe6,0x96,0x06,
|
|
|
+ 0xf7,0x46,0x57,0xe6,0x46,0x07,0x32,0x86,0x16,0x26,0xc7,0x67,0x2a,0xad,0x0d,0x8e,
|
|
|
+ 0xad,0x0c,0x64,0x68,0x65,0x05,0x84,0x4a,0x28,0x28,0x68,0x88,0x30,0xe9,0xc1,0x10,
|
|
|
+ 0x63,0xca,0x83,0x69,0x0f,0xb0,0x64,0x88,0x31,0x95,0xc1,0xc4,0x07,0x58,0x32,0xc4,
|
|
|
+ 0x98,0xf0,0x60,0xea,0x03,0x2c,0x19,0x62,0x4c,0x7e,0x30,0xf5,0x01,0x96,0x8c,0x88,
|
|
|
+ 0xd8,0x81,0x1d,0xec,0xa1,0x1d,0xdc,0xa0,0x1d,0xde,0x81,0x1c,0xea,0x81,0x1d,0xca,
|
|
|
+ 0xc1,0x0d,0xcc,0x81,0x1d,0xc2,0xe1,0x1c,0xe6,0x61,0x8a,0x10,0x0c,0x23,0x14,0x76,
|
|
|
+ 0x60,0x07,0x7b,0x68,0x07,0x37,0x48,0x07,0x72,0x28,0x07,0x77,0xa0,0x87,0x29,0x41,
|
|
|
+ 0x31,0x62,0x09,0x87,0x74,0x90,0x07,0x37,0xb0,0x87,0x72,0x90,0x87,0x79,0x48,0x87,
|
|
|
+ 0x77,0x70,0x87,0x29,0x81,0x31,0x82,0x0a,0x87,0x74,0x90,0x07,0x37,0x60,0x87,0x70,
|
|
|
+ 0x70,0x87,0x73,0xa8,0x87,0x70,0x38,0x87,0x72,0xf8,0x05,0x7b,0x28,0x07,0x79,0x98,
|
|
|
+ 0x87,0x74,0x78,0x07,0x77,0x98,0x12,0x20,0x23,0xa6,0x70,0x48,0x07,0x79,0x70,0x83,
|
|
|
+ 0x71,0x78,0x87,0x76,0x80,0x87,0x74,0x60,0x87,0x72,0xf8,0x85,0x77,0x80,0x07,0x7a,
|
|
|
+ 0x48,0x87,0x77,0x70,0x87,0x79,0x98,0x32,0x28,0x8c,0x33,0x82,0x09,0x87,0x74,0x90,
|
|
|
+ 0x07,0x37,0x30,0x07,0x79,0x08,0x87,0x73,0x68,0x87,0x72,0x70,0x07,0x7a,0x98,0x12,
|
|
|
+ 0xdc,0x01,0x00,0x00,0x00,0x79,0x18,0x00,0x00,0x7b,0x00,0x00,0x00,0x33,0x08,0x80,
|
|
|
+ 0x1c,0xc4,0xe1,0x1c,0x66,0x14,0x01,0x3d,0x88,0x43,0x38,0x84,0xc3,0x8c,0x42,0x80,
|
|
|
+ 0x07,0x79,0x78,0x07,0x73,0x98,0x71,0x0c,0xe6,0x00,0x0f,0xed,0x10,0x0e,0xf4,0x80,
|
|
|
+ 0x0e,0x33,0x0c,0x42,0x1e,0xc2,0xc1,0x1d,0xce,0xa1,0x1c,0x66,0x30,0x05,0x3d,0x88,
|
|
|
+ 0x43,0x38,0x84,0x83,0x1b,0xcc,0x03,0x3d,0xc8,0x43,0x3d,0x8c,0x03,0x3d,0xcc,0x78,
|
|
|
+ 0x8c,0x74,0x70,0x07,0x7b,0x08,0x07,0x79,0x48,0x87,0x70,0x70,0x07,0x7a,0x70,0x03,
|
|
|
+ 0x76,0x78,0x87,0x70,0x20,0x87,0x19,0xcc,0x11,0x0e,0xec,0x90,0x0e,0xe1,0x30,0x0f,
|
|
|
+ 0x6e,0x30,0x0f,0xe3,0xf0,0x0e,0xf0,0x50,0x0e,0x33,0x10,0xc4,0x1d,0xde,0x21,0x1c,
|
|
|
+ 0xd8,0x21,0x1d,0xc2,0x61,0x1e,0x66,0x30,0x89,0x3b,0xbc,0x83,0x3b,0xd0,0x43,0x39,
|
|
|
+ 0xb4,0x03,0x3c,0xbc,0x83,0x3c,0x84,0x03,0x3b,0xcc,0xf0,0x14,0x76,0x60,0x07,0x7b,
|
|
|
+ 0x68,0x07,0x37,0x68,0x87,0x72,0x68,0x07,0x37,0x80,0x87,0x70,0x90,0x87,0x70,0x60,
|
|
|
+ 0x07,0x76,0x28,0x07,0x76,0xf8,0x05,0x76,0x78,0x87,0x77,0x80,0x87,0x5f,0x08,0x87,
|
|
|
+ 0x71,0x18,0x87,0x72,0x98,0x87,0x79,0x98,0x81,0x2c,0xee,0xf0,0x0e,0xee,0xe0,0x0e,
|
|
|
+ 0xf5,0xc0,0x0e,0xec,0x30,0x03,0x62,0xc8,0xa1,0x1c,0xe4,0xa1,0x1c,0xcc,0xa1,0x1c,
|
|
|
+ 0xe4,0xa1,0x1c,0xdc,0x61,0x1c,0xca,0x21,0x1c,0xc4,0x81,0x1d,0xca,0x61,0x06,0xd6,
|
|
|
+ 0x90,0x43,0x39,0xc8,0x43,0x39,0x98,0x43,0x39,0xc8,0x43,0x39,0xb8,0xc3,0x38,0x94,
|
|
|
+ 0x43,0x38,0x88,0x03,0x3b,0x94,0xc3,0x2f,0xbc,0x83,0x3c,0xfc,0x82,0x3b,0xd4,0x03,
|
|
|
+ 0x3b,0xb0,0xc3,0x0c,0xc7,0x69,0x87,0x70,0x58,0x87,0x72,0x70,0x83,0x74,0x68,0x07,
|
|
|
+ 0x78,0x60,0x87,0x74,0x18,0x87,0x74,0xa0,0x87,0x19,0xce,0x53,0x0f,0xee,0x00,0x0f,
|
|
|
+ 0xf2,0x50,0x0e,0xe4,0x90,0x0e,0xe3,0x40,0x0f,0xe1,0x20,0x0e,0xec,0x50,0x0e,0x33,
|
|
|
+ 0x20,0x28,0x1d,0xdc,0xc1,0x1e,0xc2,0x41,0x1e,0xd2,0x21,0x1c,0xdc,0x81,0x1e,0xdc,
|
|
|
+ 0xe0,0x1c,0xe4,0xe1,0x1d,0xea,0x01,0x1e,0x66,0x18,0x51,0x38,0xb0,0x43,0x3a,0x9c,
|
|
|
+ 0x83,0x3b,0xcc,0x50,0x24,0x76,0x60,0x07,0x7b,0x68,0x07,0x37,0x60,0x87,0x77,0x78,
|
|
|
+ 0x07,0x78,0x98,0x51,0x4c,0xf4,0x90,0x0f,0xf0,0x50,0x0e,0x33,0x1e,0x6a,0x1e,0xca,
|
|
|
+ 0x61,0x1c,0xe8,0x21,0x1d,0xde,0xc1,0x1d,0x7e,0x01,0x1e,0xe4,0xa1,0x1c,0xcc,0x21,
|
|
|
+ 0x1d,0xf0,0x61,0x06,0x54,0x85,0x83,0x38,0xcc,0xc3,0x3b,0xb0,0x43,0x3d,0xd0,0x43,
|
|
|
+ 0x39,0xfc,0xc2,0x3c,0xe4,0x43,0x3b,0x88,0xc3,0x3b,0xb0,0xc3,0x8c,0xc5,0x0a,0x87,
|
|
|
+ 0x79,0x98,0x87,0x77,0x18,0x87,0x74,0x08,0x07,0x7a,0x28,0x07,0x72,0x98,0x81,0x5c,
|
|
|
+ 0xe3,0x10,0x0e,0xec,0xc0,0x0e,0xe5,0x50,0x0e,0xf3,0x30,0x23,0xc1,0xd2,0x41,0x1e,
|
|
|
+ 0xe4,0xe1,0x17,0xd8,0xe1,0x1d,0xde,0x01,0x1e,0x66,0x50,0x59,0x38,0xa4,0x83,0x3c,
|
|
|
+ 0xb8,0x81,0x39,0xd4,0x83,0x3b,0x8c,0x03,0x3d,0xa4,0xc3,0x3b,0xb8,0xc3,0x2f,0x9c,
|
|
|
+ 0x83,0x3c,0xbc,0x43,0x3d,0xc0,0xc3,0x3c,0x00,0x71,0x20,0x00,0x00,0x0b,0x00,0x00,
|
|
|
+ 0x00,0x26,0xb0,0x01,0x48,0xe4,0x4b,0x00,0xf3,0x2c,0xc4,0x3f,0x11,0xd7,0x44,0x45,
|
|
|
+ 0xc4,0x6f,0x0f,0x7e,0x85,0x17,0xb7,0x6d,0x00,0x05,0x03,0x20,0x0d,0x6d,0x01,0x0d,
|
|
|
+ 0x80,0x44,0x3e,0x83,0x5c,0x7e,0x85,0x17,0xb7,0x0d,0x00,0x00,0x00,0x61,0x20,0x00,
|
|
|
+ 0x00,0x25,0x00,0x00,0x00,0x13,0x04,0x41,0x2c,0x10,0x00,0x00,0x00,0x0c,0x00,0x00,
|
|
|
+ 0x00,0x74,0x47,0x00,0xc6,0x22,0x80,0x40,0x38,0xe6,0x20,0x06,0xc2,0xa8,0xc8,0xd5,
|
|
|
+ 0xc0,0x08,0x00,0xbd,0x19,0x00,0x82,0x23,0x00,0x54,0xc7,0x1a,0x80,0x40,0x18,0x6b,
|
|
|
+ 0x18,0x86,0x81,0xec,0x0c,0x00,0x89,0x19,0x00,0x0a,0x33,0x00,0x04,0x46,0x00,0x00,
|
|
|
+ 0x00,0x23,0x06,0xca,0x10,0x6c,0x8f,0x23,0x29,0x47,0x12,0x58,0x20,0xc9,0x67,0x90,
|
|
|
+ 0x21,0x20,0x90,0x41,0x06,0xa1,0x40,0x4c,0x08,0xe4,0x33,0xc8,0x10,0x24,0xd0,0x20,
|
|
|
+ 0x43,0x50,0x48,0x16,0x60,0xf2,0x19,0x6f,0xc0,0x38,0x31,0xa0,0x60,0xcc,0x31,0x30,
|
|
|
+ 0x01,0x19,0x0c,0x32,0x04,0x0d,0x36,0x62,0x60,0x08,0x01,0x1a,0x2c,0x45,0x30,0xdb,
|
|
|
+ 0x00,0x05,0x40,0x06,0x01,0x31,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x5b,0x86,0x24,
|
|
|
+ 0xf8,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+};
|
|
|
+static const char _sspine_vs_source_metal_sim[716] = {
|
|
|
+ 0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,0x20,0x3c,0x6d,0x65,0x74,0x61,0x6c,0x5f,
|
|
|
+ 0x73,0x74,0x64,0x6c,0x69,0x62,0x3e,0x0a,0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,
|
|
|
+ 0x20,0x3c,0x73,0x69,0x6d,0x64,0x2f,0x73,0x69,0x6d,0x64,0x2e,0x68,0x3e,0x0a,0x0a,
|
|
|
+ 0x75,0x73,0x69,0x6e,0x67,0x20,0x6e,0x61,0x6d,0x65,0x73,0x70,0x61,0x63,0x65,0x20,
|
|
|
+ 0x6d,0x65,0x74,0x61,0x6c,0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x76,
|
|
|
+ 0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66,
|
|
|
+ 0x6c,0x6f,0x61,0x74,0x34,0x78,0x34,0x20,0x6d,0x76,0x70,0x3b,0x0a,0x7d,0x3b,0x0a,
|
|
|
+ 0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x6f,0x75,
|
|
|
+ 0x74,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x32,0x20,0x75,
|
|
|
+ 0x76,0x20,0x5b,0x5b,0x75,0x73,0x65,0x72,0x28,0x6c,0x6f,0x63,0x6e,0x30,0x29,0x5d,
|
|
|
+ 0x5d,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x63,0x6f,
|
|
|
+ 0x6c,0x6f,0x72,0x20,0x5b,0x5b,0x75,0x73,0x65,0x72,0x28,0x6c,0x6f,0x63,0x6e,0x31,
|
|
|
+ 0x29,0x5d,0x5d,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,
|
|
|
+ 0x67,0x6c,0x5f,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x20,0x5b,0x5b,0x70,0x6f,
|
|
|
+ 0x73,0x69,0x74,0x69,0x6f,0x6e,0x5d,0x5d,0x3b,0x0a,0x7d,0x3b,0x0a,0x0a,0x73,0x74,
|
|
|
+ 0x72,0x75,0x63,0x74,0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x69,0x6e,0x0a,0x7b,0x0a,
|
|
|
+ 0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x32,0x20,0x70,0x6f,0x73,0x69,0x74,
|
|
|
+ 0x69,0x6f,0x6e,0x20,0x5b,0x5b,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x28,
|
|
|
+ 0x30,0x29,0x5d,0x5d,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x32,
|
|
|
+ 0x20,0x74,0x65,0x78,0x63,0x6f,0x6f,0x72,0x64,0x30,0x20,0x5b,0x5b,0x61,0x74,0x74,
|
|
|
+ 0x72,0x69,0x62,0x75,0x74,0x65,0x28,0x31,0x29,0x5d,0x5d,0x3b,0x0a,0x20,0x20,0x20,
|
|
|
+ 0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x30,0x20,0x5b,
|
|
|
+ 0x5b,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x28,0x32,0x29,0x5d,0x5d,0x3b,
|
|
|
+ 0x0a,0x7d,0x3b,0x0a,0x0a,0x23,0x6c,0x69,0x6e,0x65,0x20,0x31,0x35,0x20,0x22,0x73,
|
|
|
+ 0x73,0x70,0x69,0x6e,0x65,0x2e,0x67,0x6c,0x73,0x6c,0x22,0x0a,0x76,0x65,0x72,0x74,
|
|
|
+ 0x65,0x78,0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x6f,0x75,0x74,0x20,0x6d,0x61,0x69,
|
|
|
+ 0x6e,0x30,0x28,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x69,0x6e,0x20,0x69,0x6e,0x20,0x5b,
|
|
|
+ 0x5b,0x73,0x74,0x61,0x67,0x65,0x5f,0x69,0x6e,0x5d,0x5d,0x2c,0x20,0x63,0x6f,0x6e,
|
|
|
+ 0x73,0x74,0x61,0x6e,0x74,0x20,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x26,
|
|
|
+ 0x20,0x5f,0x32,0x31,0x20,0x5b,0x5b,0x62,0x75,0x66,0x66,0x65,0x72,0x28,0x30,0x29,
|
|
|
+ 0x5d,0x5d,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f,
|
|
|
+ 0x6f,0x75,0x74,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x7b,0x7d,0x3b,0x0a,0x23,0x6c,
|
|
|
+ 0x69,0x6e,0x65,0x20,0x31,0x35,0x20,0x22,0x73,0x73,0x70,0x69,0x6e,0x65,0x2e,0x67,
|
|
|
+ 0x6c,0x73,0x6c,0x22,0x0a,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x67,0x6c,0x5f,
|
|
|
+ 0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x5f,0x32,0x31,0x2e,0x6d,
|
|
|
+ 0x76,0x70,0x20,0x2a,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x69,0x6e,0x2e,0x70,
|
|
|
+ 0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x2c,0x20,0x30,0x2e,0x30,0x2c,0x20,0x31,0x2e,
|
|
|
+ 0x30,0x29,0x3b,0x0a,0x23,0x6c,0x69,0x6e,0x65,0x20,0x31,0x36,0x20,0x22,0x73,0x73,
|
|
|
+ 0x70,0x69,0x6e,0x65,0x2e,0x67,0x6c,0x73,0x6c,0x22,0x0a,0x20,0x20,0x20,0x20,0x6f,
|
|
|
+ 0x75,0x74,0x2e,0x75,0x76,0x20,0x3d,0x20,0x69,0x6e,0x2e,0x74,0x65,0x78,0x63,0x6f,
|
|
|
+ 0x6f,0x72,0x64,0x30,0x3b,0x0a,0x23,0x6c,0x69,0x6e,0x65,0x20,0x31,0x37,0x20,0x22,
|
|
|
+ 0x73,0x73,0x70,0x69,0x6e,0x65,0x2e,0x67,0x6c,0x73,0x6c,0x22,0x0a,0x20,0x20,0x20,
|
|
|
+ 0x20,0x6f,0x75,0x74,0x2e,0x63,0x6f,0x6c,0x6f,0x72,0x20,0x3d,0x20,0x69,0x6e,0x2e,
|
|
|
+ 0x63,0x6f,0x6c,0x6f,0x72,0x30,0x3b,0x0a,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,
|
|
|
+ 0x72,0x6e,0x20,0x6f,0x75,0x74,0x3b,0x0a,0x7d,0x0a,0x0a,0x00,
|
|
|
+};
|
|
|
+static const char _sspine_fs_source_metal_sim[721] = {
|
|
|
+ 0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,0x20,0x3c,0x6d,0x65,0x74,0x61,0x6c,0x5f,
|
|
|
+ 0x73,0x74,0x64,0x6c,0x69,0x62,0x3e,0x0a,0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,
|
|
|
+ 0x20,0x3c,0x73,0x69,0x6d,0x64,0x2f,0x73,0x69,0x6d,0x64,0x2e,0x68,0x3e,0x0a,0x0a,
|
|
|
+ 0x75,0x73,0x69,0x6e,0x67,0x20,0x6e,0x61,0x6d,0x65,0x73,0x70,0x61,0x63,0x65,0x20,
|
|
|
+ 0x6d,0x65,0x74,0x61,0x6c,0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x66,
|
|
|
+ 0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66,
|
|
|
+ 0x6c,0x6f,0x61,0x74,0x20,0x70,0x6d,0x61,0x3b,0x0a,0x7d,0x3b,0x0a,0x0a,0x73,0x74,
|
|
|
+ 0x72,0x75,0x63,0x74,0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x6f,0x75,0x74,0x0a,0x7b,
|
|
|
+ 0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x66,0x72,0x61,0x67,
|
|
|
+ 0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x20,0x5b,0x5b,0x63,0x6f,0x6c,0x6f,0x72,0x28,0x30,
|
|
|
+ 0x29,0x5d,0x5d,0x3b,0x0a,0x7d,0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,
|
|
|
+ 0x6d,0x61,0x69,0x6e,0x30,0x5f,0x69,0x6e,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66,
|
|
|
+ 0x6c,0x6f,0x61,0x74,0x32,0x20,0x75,0x76,0x20,0x5b,0x5b,0x75,0x73,0x65,0x72,0x28,
|
|
|
+ 0x6c,0x6f,0x63,0x6e,0x30,0x29,0x5d,0x5d,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,
|
|
|
+ 0x6f,0x61,0x74,0x34,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x20,0x5b,0x5b,0x75,0x73,0x65,
|
|
|
+ 0x72,0x28,0x6c,0x6f,0x63,0x6e,0x31,0x29,0x5d,0x5d,0x3b,0x0a,0x7d,0x3b,0x0a,0x0a,
|
|
|
+ 0x23,0x6c,0x69,0x6e,0x65,0x20,0x31,0x34,0x20,0x22,0x73,0x73,0x70,0x69,0x6e,0x65,
|
|
|
+ 0x2e,0x67,0x6c,0x73,0x6c,0x22,0x0a,0x66,0x72,0x61,0x67,0x6d,0x65,0x6e,0x74,0x20,
|
|
|
+ 0x6d,0x61,0x69,0x6e,0x30,0x5f,0x6f,0x75,0x74,0x20,0x6d,0x61,0x69,0x6e,0x30,0x28,
|
|
|
+ 0x6d,0x61,0x69,0x6e,0x30,0x5f,0x69,0x6e,0x20,0x69,0x6e,0x20,0x5b,0x5b,0x73,0x74,
|
|
|
+ 0x61,0x67,0x65,0x5f,0x69,0x6e,0x5d,0x5d,0x2c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x61,
|
|
|
+ 0x6e,0x74,0x20,0x66,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x26,0x20,0x5f,0x35,
|
|
|
+ 0x30,0x20,0x5b,0x5b,0x62,0x75,0x66,0x66,0x65,0x72,0x28,0x30,0x29,0x5d,0x5d,0x2c,
|
|
|
+ 0x20,0x74,0x65,0x78,0x74,0x75,0x72,0x65,0x32,0x64,0x3c,0x66,0x6c,0x6f,0x61,0x74,
|
|
|
+ 0x3e,0x20,0x74,0x65,0x78,0x20,0x5b,0x5b,0x74,0x65,0x78,0x74,0x75,0x72,0x65,0x28,
|
|
|
+ 0x30,0x29,0x5d,0x5d,0x2c,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x20,0x74,0x65,
|
|
|
+ 0x78,0x53,0x6d,0x70,0x6c,0x72,0x20,0x5b,0x5b,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,
|
|
|
+ 0x28,0x30,0x29,0x5d,0x5d,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x6d,0x61,0x69,
|
|
|
+ 0x6e,0x30,0x5f,0x6f,0x75,0x74,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x7b,0x7d,0x3b,
|
|
|
+ 0x0a,0x23,0x6c,0x69,0x6e,0x65,0x20,0x31,0x34,0x20,0x22,0x73,0x73,0x70,0x69,0x6e,
|
|
|
+ 0x65,0x2e,0x67,0x6c,0x73,0x6c,0x22,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,
|
|
|
+ 0x74,0x34,0x20,0x5f,0x32,0x35,0x20,0x3d,0x20,0x74,0x65,0x78,0x2e,0x73,0x61,0x6d,
|
|
|
+ 0x70,0x6c,0x65,0x28,0x74,0x65,0x78,0x53,0x6d,0x70,0x6c,0x72,0x2c,0x20,0x69,0x6e,
|
|
|
+ 0x2e,0x75,0x76,0x29,0x20,0x2a,0x20,0x69,0x6e,0x2e,0x63,0x6f,0x6c,0x6f,0x72,0x3b,
|
|
|
+ 0x0a,0x23,0x6c,0x69,0x6e,0x65,0x20,0x31,0x35,0x20,0x22,0x73,0x73,0x70,0x69,0x6e,
|
|
|
+ 0x65,0x2e,0x67,0x6c,0x73,0x6c,0x22,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,
|
|
|
+ 0x74,0x20,0x5f,0x33,0x34,0x20,0x3d,0x20,0x5f,0x32,0x35,0x2e,0x77,0x3b,0x0a,0x23,
|
|
|
+ 0x6c,0x69,0x6e,0x65,0x20,0x31,0x36,0x20,0x22,0x73,0x73,0x70,0x69,0x6e,0x65,0x2e,
|
|
|
+ 0x67,0x6c,0x73,0x6c,0x22,0x0a,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x66,0x72,
|
|
|
+ 0x61,0x67,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x20,0x3d,0x20,0x6d,0x69,0x78,0x28,0x5f,
|
|
|
+ 0x32,0x35,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x5f,0x32,0x35,0x2e,0x78,
|
|
|
+ 0x79,0x7a,0x20,0x2a,0x20,0x5f,0x33,0x34,0x2c,0x20,0x5f,0x33,0x34,0x29,0x20,0x2a,
|
|
|
+ 0x20,0x69,0x6e,0x2e,0x63,0x6f,0x6c,0x6f,0x72,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,
|
|
|
+ 0x34,0x28,0x5f,0x35,0x30,0x2e,0x70,0x6d,0x61,0x29,0x29,0x3b,0x0a,0x20,0x20,0x20,
|
|
|
+ 0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6f,0x75,0x74,0x3b,0x0a,0x7d,0x0a,0x0a,
|
|
|
+ 0x00,
|
|
|
+};
|
|
|
+#elif defined(SOKOL_WGPU)
|
|
|
+FIXME
|
|
|
+#elif defined(SOKOL_DUMMY_BACKEND)
|
|
|
+static const char* _sspine_vs_source_dummy = "";
|
|
|
+static const char* _sspine_fs_source_dummy = "";
|
|
|
+#else
|
|
|
+#error "Please define one of SOKOL_GLCORE33, SOKOL_GLES2, SOKOL_GLES3, SOKOL_D3D11, SOKOL_METAL, SOKOL_WGPU or SOKOL_DUMMY_BACKEND!"
|
|
|
+#endif
|
|
|
+
|
|
|
+#define _sspine_def(val, def) (((val) == 0) ? (def) : (val))
|
|
|
+#define _SSPINE_INIT_COOKIE (0xABBAABBA)
|
|
|
+#define _SSPINE_INVALID_SLOT_INDEX (0)
|
|
|
+#define _SSPINE_DEFAULT_CONTEXT_POOL_SIZE (4)
|
|
|
+#define _SSPINE_DEFAULT_ATLAS_POOL_SIZE (64)
|
|
|
+#define _SSPINE_DEFAULT_SKELETON_POOL_SIZE (64)
|
|
|
+#define _SSPINE_DEFAULT_SKINSET_POOL_SIZE (64)
|
|
|
+#define _SSPINE_DEFAULT_INSTANCE_POOL_SIZE (1024)
|
|
|
+#define _SSPINE_DEFAULT_MAX_VERTICES (1<<16)
|
|
|
+#define _SSPINE_DEFAULT_MAX_COMMANDS (1<<14)
|
|
|
+#define _SSPINE_MAX_TRIGGERED_EVENTS (16)
|
|
|
+#define _SSPINE_SLOT_SHIFT (16)
|
|
|
+#define _SSPINE_MAX_POOL_SIZE (1<<_SSPINE_SLOT_SHIFT)
|
|
|
+#define _SSPINE_SLOT_MASK (_SSPINE_MAX_POOL_SIZE-1)
|
|
|
+
|
|
|
+#if defined(SOKOL_DEBUG)
|
|
|
+#define _SSPINE_XMACRO(code) #code,
|
|
|
+static const char* _sspine_error_ids[] = {
|
|
|
+ _SSPINE_ERRORS
|
|
|
+};
|
|
|
+#undef _SSPINE_XMACRO
|
|
|
+#endif // SOKOL_DEBUG
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ float mvp[16];
|
|
|
+} _sspine_vsparams_t;
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ float pma;
|
|
|
+ uint8_t _pad[12];
|
|
|
+} _sspine_fsparams_t;
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ uint32_t id;
|
|
|
+ sspine_resource_state state;
|
|
|
+} _sspine_slot_t;
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ int size;
|
|
|
+ int queue_top;
|
|
|
+ uint32_t* gen_ctrs;
|
|
|
+ int* free_queue;
|
|
|
+} _sspine_pool_t;
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ _sspine_slot_t slot;
|
|
|
+ sspine_atlas_overrides overrides;
|
|
|
+ spAtlas* sp_atlas;
|
|
|
+ int num_pages;
|
|
|
+} _sspine_atlas_t;
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ _sspine_pool_t pool;
|
|
|
+ _sspine_atlas_t* items;
|
|
|
+} _sspine_atlas_pool_t;
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ uint32_t id;
|
|
|
+ _sspine_atlas_t* ptr;
|
|
|
+} _sspine_atlas_ref_t;
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ _sspine_slot_t slot;
|
|
|
+ _sspine_atlas_ref_t atlas;
|
|
|
+ spSkeletonData* sp_skel_data;
|
|
|
+ spAnimationStateData* sp_anim_data;
|
|
|
+ struct {
|
|
|
+ int num;
|
|
|
+ sspine_vec2* ptr;
|
|
|
+ } tform_buf;
|
|
|
+} _sspine_skeleton_t;
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ _sspine_pool_t pool;
|
|
|
+ _sspine_skeleton_t* items;
|
|
|
+} _sspine_skeleton_pool_t;
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ uint32_t id;
|
|
|
+ _sspine_skeleton_t* ptr;
|
|
|
+} _sspine_skeleton_ref_t;
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ _sspine_slot_t slot;
|
|
|
+ _sspine_skeleton_ref_t skel;
|
|
|
+ spSkin* sp_skin;
|
|
|
+} _sspine_skinset_t;
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ _sspine_pool_t pool;
|
|
|
+ _sspine_skinset_t* items;
|
|
|
+} _sspine_skinset_pool_t;
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ uint32_t id;
|
|
|
+ _sspine_skinset_t* ptr;
|
|
|
+} _sspine_skinset_ref_t;
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ _sspine_slot_t slot;
|
|
|
+ _sspine_atlas_ref_t atlas;
|
|
|
+ _sspine_skeleton_ref_t skel;
|
|
|
+ _sspine_skinset_ref_t skinset;
|
|
|
+ spSkeleton* sp_skel;
|
|
|
+ spAnimationState* sp_anim_state;
|
|
|
+ spSkeletonClipping* sp_clip;
|
|
|
+ int cur_triggered_event_index;
|
|
|
+ sspine_triggered_event_info triggered_events[_SSPINE_MAX_TRIGGERED_EVENTS];
|
|
|
+} _sspine_instance_t;
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ _sspine_pool_t pool;
|
|
|
+ _sspine_instance_t* items;
|
|
|
+} _sspine_instance_pool_t;
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ sspine_vec2 pos;
|
|
|
+ sspine_vec2 uv;
|
|
|
+ uint32_t color;
|
|
|
+} _sspine_vertex_t;
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ _sspine_vertex_t* ptr;
|
|
|
+ int index;
|
|
|
+} _sspine_alloc_vertices_result_t;
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ uint32_t* ptr;
|
|
|
+ int index;
|
|
|
+} _sspine_alloc_indices_result_t;
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ int layer;
|
|
|
+ sg_pipeline pip;
|
|
|
+ sg_image img;
|
|
|
+ float pma; // pma = 0.0: use texture color as is, pma = 1.0: multiply texture rgb by texture alpha in fragment shader
|
|
|
+ int base_element;
|
|
|
+ int num_elements;
|
|
|
+} _sspine_command_t;
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ _sspine_slot_t slot;
|
|
|
+ float transform[16];
|
|
|
+ struct {
|
|
|
+ int num;
|
|
|
+ int cur;
|
|
|
+ uint32_t rewind_frame_count;
|
|
|
+ _sspine_vertex_t* ptr;
|
|
|
+ } vertices;
|
|
|
+ struct {
|
|
|
+ int num;
|
|
|
+ int cur;
|
|
|
+ uint32_t rewind_frame_count;
|
|
|
+ uint32_t* ptr;
|
|
|
+ } indices;
|
|
|
+ struct {
|
|
|
+ int num;
|
|
|
+ int cur;
|
|
|
+ uint32_t rewind_frame_count;
|
|
|
+ _sspine_command_t* ptr;
|
|
|
+ } commands;
|
|
|
+ uint32_t update_frame_count;
|
|
|
+ sg_buffer vbuf;
|
|
|
+ sg_buffer ibuf;
|
|
|
+ struct {
|
|
|
+ sg_pipeline normal_additive;
|
|
|
+ sg_pipeline multiply;
|
|
|
+ } pip;
|
|
|
+ sg_bindings bind;
|
|
|
+} _sspine_context_t;
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ _sspine_pool_t pool;
|
|
|
+ _sspine_context_t* items;
|
|
|
+} _sspine_context_pool_t;
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ uint32_t init_cookie;
|
|
|
+ uint32_t frame_count;
|
|
|
+ sspine_desc desc;
|
|
|
+ sspine_context def_ctx_id;
|
|
|
+ sspine_context cur_ctx_id;
|
|
|
+ _sspine_context_t* cur_ctx; // may be 0!
|
|
|
+ sg_shader shd;
|
|
|
+ _sspine_context_pool_t context_pool;
|
|
|
+ _sspine_atlas_pool_t atlas_pool;
|
|
|
+ _sspine_skeleton_pool_t skeleton_pool;
|
|
|
+ _sspine_skinset_pool_t skinset_pool;
|
|
|
+ _sspine_instance_pool_t instance_pool;
|
|
|
+} _sspine_t;
|
|
|
+static _sspine_t _sspine;
|
|
|
+
|
|
|
+// dummy spine-c platform implementation functions
|
|
|
+void _spAtlasPage_createTexture(spAtlasPage* self, const char* path) {
|
|
|
+ // nothing to do here
|
|
|
+ (void)self; (void)path;
|
|
|
+}
|
|
|
+
|
|
|
+char* _spUtil_readFile(const char* path, int* length) {
|
|
|
+ (void)path;
|
|
|
+ *length = 0;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+//=== HELPER FUNCTION ==========================================================
|
|
|
+#define _SSPINE_PANIC(code) _sspine_log(SSPINE_ERROR_ ##code, SSPINE_LOGLEVEL_PANIC, __LINE__)
|
|
|
+#define _SSPINE_ERROR(code) _sspine_log(SSPINE_ERROR_ ##code, SSPINE_LOGLEVEL_ERROR, __LINE__)
|
|
|
+#define _SSPINE_WARN(code) _sspine_log(SSPINE_ERROR_ ##code, SSPINE_LOGLEVEL_WARN, __LINE__)
|
|
|
+#define _SSPINE_INFO(code) _sspine_log(SSPINE_ERROR_ ##code, SSPINE_LOGLEVEL_INFO, __LINE__)
|
|
|
+
|
|
|
+static void _sspine_log(sspine_error error_code, sspine_loglevel log_level, int line_nr) {
|
|
|
+ if (_sspine.desc.logger.func) {
|
|
|
+ #if defined(SOKOL_DEBUG)
|
|
|
+ const char* filename = __FILE__;
|
|
|
+ const char* error_id = _sspine_error_ids[error_code];
|
|
|
+ #else
|
|
|
+ const char* filename = "";
|
|
|
+ const char* error_id = "";
|
|
|
+ #endif
|
|
|
+ _sspine.desc.logger.func("sspine", log_level, error_code, error_id, line_nr, filename, _sspine.desc.logger.user_data);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ // default logging function, uses printf only if debugging is enabled to save executable size
|
|
|
+ const char* loglevel_str;
|
|
|
+ switch (log_level) {
|
|
|
+ case SSPINE_LOGLEVEL_PANIC: loglevel_str = "panic"; break;
|
|
|
+ case SSPINE_LOGLEVEL_ERROR: loglevel_str = "error"; break;
|
|
|
+ case SSPINE_LOGLEVEL_WARN: loglevel_str = "warning"; break;
|
|
|
+ default: loglevel_str = "info"; break;
|
|
|
+ }
|
|
|
+ #if defined(SOKOL_DEBUG)
|
|
|
+ const char* error_id = _sspine_error_ids[error_code];
|
|
|
+ #if defined(_MSC_VER)
|
|
|
+ // Visual Studio compiler error format
|
|
|
+ fprintf(stderr, "[sspine] %s(%d): %s: %s\n", __FILE__, line_nr, loglevel_str, error_id);
|
|
|
+ #else
|
|
|
+ // GCC error format
|
|
|
+ fprintf(stderr, "[sspine] %s:%d:0: %s: %s\n", __FILE__, line_nr, loglevel_str, error_id);
|
|
|
+ #endif
|
|
|
+ #else
|
|
|
+ fputs("[sspine] ", stderr);
|
|
|
+ fputs(loglevel_str, stderr);
|
|
|
+ fputs(" (build in debug mode for more info)\n", stderr);
|
|
|
+ #endif // SOKOL_DEBUG
|
|
|
+
|
|
|
+ // for log level PANIC it would be 'undefined behaviour' to continue
|
|
|
+ if (log_level == SSPINE_LOGLEVEL_PANIC) {
|
|
|
+ abort();
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_clear(void* ptr, size_t size) {
|
|
|
+ SOKOL_ASSERT(ptr && (size > 0));
|
|
|
+ memset(ptr, 0, size);
|
|
|
+}
|
|
|
+
|
|
|
+/* Copy a string into a fixed size buffer with guaranteed zero-
|
|
|
+ termination.
|
|
|
+
|
|
|
+ Return false if the string didn't fit into the buffer and had to be clamped.
|
|
|
+
|
|
|
+ FIXME: Currently UTF-8 strings might become invalid if the string
|
|
|
+ is clamped, because the last zero-byte might be written into
|
|
|
+ the middle of a multi-byte sequence.
|
|
|
+*/
|
|
|
+static bool _sspine_strcpy(const char* src, char* dst, int max_len) {
|
|
|
+ SOKOL_ASSERT(src && dst && (max_len > 0));
|
|
|
+ char* const end = &(dst[max_len-1]);
|
|
|
+ char c = 0;
|
|
|
+ for (int i = 0; i < max_len; i++) {
|
|
|
+ c = *src;
|
|
|
+ if (c != 0) {
|
|
|
+ src++;
|
|
|
+ }
|
|
|
+ *dst++ = c;
|
|
|
+ }
|
|
|
+ // truncated?
|
|
|
+ if (c != 0) {
|
|
|
+ *end = 0;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_string _sspine_string(const char* cstr) {
|
|
|
+ sspine_string res;
|
|
|
+ _sspine_clear(&res, sizeof(res));
|
|
|
+ if (cstr) {
|
|
|
+ res.valid = true;
|
|
|
+ res.truncated = !_sspine_strcpy(cstr, res.cstr, sizeof(res.cstr));
|
|
|
+ res.len = (uint8_t)strlen(res.cstr);
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+static void* _sspine_malloc(size_t size) {
|
|
|
+ SOKOL_ASSERT(size > 0);
|
|
|
+ void* ptr;
|
|
|
+ if (_sspine.desc.allocator.alloc) {
|
|
|
+ ptr = _sspine.desc.allocator.alloc(size, _sspine.desc.allocator.user_data);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ ptr = malloc(size);
|
|
|
+ }
|
|
|
+ SOKOL_ASSERT(ptr);
|
|
|
+ return ptr;
|
|
|
+}
|
|
|
+
|
|
|
+static void* _sspine_malloc_clear(size_t size) {
|
|
|
+ void* ptr = _sspine_malloc(size);
|
|
|
+ _sspine_clear(ptr, size);
|
|
|
+ return ptr;
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_free(void* ptr) {
|
|
|
+ if (_sspine.desc.allocator.free) {
|
|
|
+ _sspine.desc.allocator.free(ptr, _sspine.desc.allocator.user_data);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ free(ptr);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static bool _sspine_atlas_ref_valid(const _sspine_atlas_ref_t* ref) {
|
|
|
+ return ref->ptr && (ref->ptr->slot.id == ref->id);
|
|
|
+}
|
|
|
+
|
|
|
+static bool _sspine_skeleton_ref_valid(const _sspine_skeleton_ref_t* ref) {
|
|
|
+ return ref->ptr && (ref->ptr->slot.id == ref->id);
|
|
|
+}
|
|
|
+
|
|
|
+static bool _sspine_skinset_ref_valid(const _sspine_skinset_ref_t* ref) {
|
|
|
+ return ref->ptr && (ref->ptr->slot.id == ref->id);
|
|
|
+}
|
|
|
+
|
|
|
+static bool _sspine_skeleton_and_deps_valid(_sspine_skeleton_t* skeleton) {
|
|
|
+ return skeleton && _sspine_atlas_ref_valid(&skeleton->atlas);
|
|
|
+}
|
|
|
+
|
|
|
+static bool _sspine_skinset_and_deps_valid(_sspine_skinset_t* skinset) {
|
|
|
+ return skinset && _sspine_skeleton_ref_valid(&skinset->skel);
|
|
|
+}
|
|
|
+
|
|
|
+static bool _sspine_instance_and_deps_valid(_sspine_instance_t* instance) {
|
|
|
+ return instance &&
|
|
|
+ _sspine_atlas_ref_valid(&instance->atlas) &&
|
|
|
+ _sspine_skeleton_ref_valid(&instance->skel) &&
|
|
|
+ ((instance->skinset.id == SSPINE_INVALID_ID) || _sspine_skinset_ref_valid(&instance->skinset));
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_image _sspine_image(uint32_t atlas_id, int index) {
|
|
|
+ sspine_image img = { atlas_id, index };
|
|
|
+ return img;
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_atlas_page _sspine_atlas_page(uint32_t atlas_id, int index) {
|
|
|
+ sspine_atlas_page page = { atlas_id, index };
|
|
|
+ return page;
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_anim _sspine_anim(uint32_t skeleton_id, int index) {
|
|
|
+ sspine_anim anim = { skeleton_id, index };
|
|
|
+ return anim;
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_bone _sspine_bone(uint32_t skeleton_id, int index) {
|
|
|
+ sspine_bone bone = { skeleton_id, index };
|
|
|
+ return bone;
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_slot _sspine_slot(uint32_t skeleton_id, int index) {
|
|
|
+ sspine_slot slot = { skeleton_id, index };
|
|
|
+ return slot;
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_event _sspine_event(uint32_t skeleton_id, int index) {
|
|
|
+ sspine_event event = { skeleton_id, index };
|
|
|
+ return event;
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_iktarget _sspine_iktarget(uint32_t skeleton_id, int index) {
|
|
|
+ sspine_iktarget iktarget = { skeleton_id, index };
|
|
|
+ return iktarget;
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_skin _sspine_skin(uint32_t skeleton_id, int index) {
|
|
|
+ sspine_skin skin = { skeleton_id, index };
|
|
|
+ return skin;
|
|
|
+}
|
|
|
+
|
|
|
+//=== HANDLE POOL FUNCTIONS ====================================================
|
|
|
+static void _sspine_init_pool(_sspine_pool_t* pool, int num) {
|
|
|
+ SOKOL_ASSERT(pool && (num >= 1));
|
|
|
+ // slot 0 is reserved for the 'invalid id', so bump the pool size by 1
|
|
|
+ pool->size = num + 1;
|
|
|
+ pool->queue_top = 0;
|
|
|
+ // generation counters indexable by pool slot index, slot 0 is reserved
|
|
|
+ size_t gen_ctrs_size = sizeof(uint32_t) * (size_t)pool->size;
|
|
|
+ pool->gen_ctrs = (uint32_t*) _sspine_malloc_clear(gen_ctrs_size);
|
|
|
+ // it's not a bug to only reserve 'num' here
|
|
|
+ pool->free_queue = (int*) _sspine_malloc_clear(sizeof(int) * (size_t)num);
|
|
|
+ // never allocate the zero-th pool item since the invalid id is 0
|
|
|
+ for (int i = pool->size-1; i >= 1; i--) {
|
|
|
+ pool->free_queue[pool->queue_top++] = i;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_discard_pool(_sspine_pool_t* pool) {
|
|
|
+ SOKOL_ASSERT(pool);
|
|
|
+ SOKOL_ASSERT(pool->free_queue);
|
|
|
+ _sspine_free(pool->free_queue);
|
|
|
+ pool->free_queue = 0;
|
|
|
+ SOKOL_ASSERT(pool->gen_ctrs);
|
|
|
+ _sspine_free(pool->gen_ctrs);
|
|
|
+ pool->gen_ctrs = 0;
|
|
|
+ pool->size = 0;
|
|
|
+ pool->queue_top = 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int _sspine_pool_alloc_index(_sspine_pool_t* pool) {
|
|
|
+ SOKOL_ASSERT(pool);
|
|
|
+ SOKOL_ASSERT(pool->free_queue);
|
|
|
+ if (pool->queue_top > 0) {
|
|
|
+ int slot_index = pool->free_queue[--pool->queue_top];
|
|
|
+ SOKOL_ASSERT((slot_index > 0) && (slot_index < pool->size));
|
|
|
+ return slot_index;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ // pool exhausted
|
|
|
+ return _SSPINE_INVALID_SLOT_INDEX;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_pool_free_index(_sspine_pool_t* pool, int slot_index) {
|
|
|
+ SOKOL_ASSERT((slot_index > _SSPINE_INVALID_SLOT_INDEX) && (slot_index < pool->size));
|
|
|
+ SOKOL_ASSERT(pool);
|
|
|
+ SOKOL_ASSERT(pool->free_queue);
|
|
|
+ SOKOL_ASSERT(pool->queue_top < pool->size);
|
|
|
+ #ifdef SOKOL_DEBUG
|
|
|
+ // debug check against double-free
|
|
|
+ for (int i = 0; i < pool->queue_top; i++) {
|
|
|
+ SOKOL_ASSERT(pool->free_queue[i] != slot_index);
|
|
|
+ }
|
|
|
+ #endif
|
|
|
+ pool->free_queue[pool->queue_top++] = slot_index;
|
|
|
+ SOKOL_ASSERT(pool->queue_top <= (pool->size-1));
|
|
|
+}
|
|
|
+
|
|
|
+/* initiailize a pool slot:
|
|
|
+ - bump the slot's generation counter
|
|
|
+ - create a resource id from the generation counter and slot index
|
|
|
+ - set the slot's id to this id
|
|
|
+ - set the slot's state to ALLOC
|
|
|
+ - return the handle id
|
|
|
+*/
|
|
|
+static uint32_t _sspine_slot_init(_sspine_pool_t* pool, _sspine_slot_t* slot, int slot_index) {
|
|
|
+ /* FIXME: add handling for an overflowing generation counter,
|
|
|
+ for now, just overflow (another option is to disable
|
|
|
+ the slot)
|
|
|
+ */
|
|
|
+ SOKOL_ASSERT(pool && pool->gen_ctrs);
|
|
|
+ SOKOL_ASSERT((slot_index > _SSPINE_INVALID_SLOT_INDEX) && (slot_index < pool->size));
|
|
|
+ SOKOL_ASSERT((slot->state == SSPINE_RESOURCESTATE_INITIAL) && (slot->id == SSPINE_INVALID_ID));
|
|
|
+ uint32_t ctr = ++pool->gen_ctrs[slot_index];
|
|
|
+ slot->id = (ctr<<_SSPINE_SLOT_SHIFT)|(slot_index & _SSPINE_SLOT_MASK);
|
|
|
+ slot->state = SSPINE_RESOURCESTATE_ALLOC;
|
|
|
+ return slot->id;
|
|
|
+}
|
|
|
+
|
|
|
+// extract slot index from id
|
|
|
+static int _sspine_slot_index(uint32_t id) {
|
|
|
+ int slot_index = (int) (id & _SSPINE_SLOT_MASK);
|
|
|
+ SOKOL_ASSERT(_SSPINE_INVALID_SLOT_INDEX != slot_index);
|
|
|
+ return slot_index;
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_init_item_pool(_sspine_pool_t* pool, int pool_size, void** items_ptr, size_t item_size_bytes) {
|
|
|
+ // NOTE: the pools will have an additional item, since slot 0 is reserved
|
|
|
+ SOKOL_ASSERT(pool && (pool->size == 0));
|
|
|
+ SOKOL_ASSERT((pool_size > 0) && (pool_size < _SSPINE_MAX_POOL_SIZE));
|
|
|
+ SOKOL_ASSERT(items_ptr && (*items_ptr == 0));
|
|
|
+ SOKOL_ASSERT(item_size_bytes > 0);
|
|
|
+ _sspine_init_pool(pool, pool_size);
|
|
|
+ const size_t pool_size_bytes = item_size_bytes * (size_t)pool->size;
|
|
|
+ *items_ptr = _sspine_malloc_clear(pool_size_bytes);
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_discard_item_pool(_sspine_pool_t* pool, void** items_ptr) {
|
|
|
+ SOKOL_ASSERT(pool && (pool->size != 0));
|
|
|
+ SOKOL_ASSERT(items_ptr && (*items_ptr != 0));
|
|
|
+ _sspine_free(*items_ptr); *items_ptr = 0;
|
|
|
+ _sspine_discard_pool(pool);
|
|
|
+}
|
|
|
+
|
|
|
+//== CONTEXT POOL FUNCTIONS ====================================================
|
|
|
+static void _sspine_setup_context_pool(int pool_size) {
|
|
|
+ _sspine_context_pool_t* p = &_sspine.context_pool;
|
|
|
+ _sspine_init_item_pool(&p->pool, pool_size, (void**)&p->items, sizeof(_sspine_context_t));
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_discard_context_pool(void) {
|
|
|
+ _sspine_context_pool_t* p = &_sspine.context_pool;
|
|
|
+ _sspine_discard_item_pool(&p->pool, (void**)&p->items);
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_context _sspine_make_context_handle(uint32_t id) {
|
|
|
+ sspine_context handle = { id };
|
|
|
+ return handle;
|
|
|
+}
|
|
|
+
|
|
|
+static _sspine_context_t* _sspine_context_at(uint32_t id) {
|
|
|
+ SOKOL_ASSERT(SSPINE_INVALID_ID != id);
|
|
|
+ const _sspine_context_pool_t* p = &_sspine.context_pool;
|
|
|
+ int slot_index = _sspine_slot_index(id);
|
|
|
+ SOKOL_ASSERT((slot_index > _SSPINE_INVALID_SLOT_INDEX) && (slot_index < p->pool.size));
|
|
|
+ return &p->items[slot_index];
|
|
|
+}
|
|
|
+
|
|
|
+static _sspine_context_t* _sspine_lookup_context(uint32_t id) {
|
|
|
+ if (SSPINE_INVALID_ID != id) {
|
|
|
+ _sspine_context_t* ctx = _sspine_context_at(id);
|
|
|
+ if (ctx->slot.id == id) {
|
|
|
+ return ctx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_context _sspine_alloc_context(void) {
|
|
|
+ _sspine_context_pool_t* p = &_sspine.context_pool;
|
|
|
+ int slot_index = _sspine_pool_alloc_index(&p->pool);
|
|
|
+ if (_SSPINE_INVALID_SLOT_INDEX != slot_index) {
|
|
|
+ uint32_t id = _sspine_slot_init(&p->pool, &p->items[slot_index].slot, slot_index);
|
|
|
+ return _sspine_make_context_handle(id);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ // pool exhausted
|
|
|
+ return _sspine_make_context_handle(SSPINE_INVALID_ID);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_resource_state _sspine_init_context(_sspine_context_t* ctx, const sspine_context_desc* desc) {
|
|
|
+ SOKOL_ASSERT(ctx && (ctx->slot.state == SSPINE_RESOURCESTATE_ALLOC));
|
|
|
+ SOKOL_ASSERT(desc);
|
|
|
+
|
|
|
+ // setup vertex, index and command storage
|
|
|
+ ctx->vertices.num = desc->max_vertices;
|
|
|
+ ctx->indices.num = ctx->vertices.num * 3;
|
|
|
+ ctx->commands.num = desc->max_commands;
|
|
|
+
|
|
|
+ const size_t vbuf_size = (size_t)ctx->vertices.num * sizeof(_sspine_vertex_t);
|
|
|
+ const size_t ibuf_size = (size_t)ctx->indices.num * sizeof(uint32_t);
|
|
|
+ const size_t cbuf_size = (size_t)ctx->commands.num * sizeof(_sspine_command_t);
|
|
|
+
|
|
|
+ ctx->vertices.ptr = (_sspine_vertex_t*) _sspine_malloc(vbuf_size);
|
|
|
+ ctx->indices.ptr = (uint32_t*) _sspine_malloc(ibuf_size);
|
|
|
+ ctx->commands.ptr = (_sspine_command_t*) _sspine_malloc(cbuf_size);
|
|
|
+
|
|
|
+ sg_buffer_desc vbuf_desc;
|
|
|
+ _sspine_clear(&vbuf_desc, sizeof(vbuf_desc));
|
|
|
+ vbuf_desc.type = SG_BUFFERTYPE_VERTEXBUFFER;
|
|
|
+ vbuf_desc.usage = SG_USAGE_STREAM;
|
|
|
+ vbuf_desc.size = vbuf_size;
|
|
|
+ vbuf_desc.label = "sspine-vbuf";
|
|
|
+ ctx->vbuf = sg_make_buffer(&vbuf_desc);
|
|
|
+ ctx->bind.vertex_buffers[0] = ctx->vbuf;
|
|
|
+
|
|
|
+ sg_buffer_desc ibuf_desc;
|
|
|
+ _sspine_clear(&ibuf_desc, sizeof(ibuf_desc));
|
|
|
+ ibuf_desc.type = SG_BUFFERTYPE_INDEXBUFFER;
|
|
|
+ ibuf_desc.usage = SG_USAGE_STREAM;
|
|
|
+ ibuf_desc.size = ibuf_size;
|
|
|
+ ibuf_desc.label = "sspine-ibuf";
|
|
|
+ ctx->ibuf = sg_make_buffer(&ibuf_desc);
|
|
|
+ ctx->bind.index_buffer = ctx->ibuf;
|
|
|
+
|
|
|
+ // for blend modes, see: https://wiki.libsdl.org/SDL_BlendMode
|
|
|
+ //
|
|
|
+ // NOTE: we're configuring the blend mode for premultiplied alpha,
|
|
|
+ // and then do the premultiplication in the fragment shader
|
|
|
+ // if needed
|
|
|
+ sg_pipeline_desc pip_desc;
|
|
|
+ _sspine_clear(&pip_desc, sizeof(pip_desc));
|
|
|
+ pip_desc.shader = _sspine.shd;
|
|
|
+ pip_desc.layout.buffers[0].stride = sizeof(_sspine_vertex_t);
|
|
|
+ pip_desc.layout.attrs[0].format = SG_VERTEXFORMAT_FLOAT2;
|
|
|
+ pip_desc.layout.attrs[1].format = SG_VERTEXFORMAT_FLOAT2;
|
|
|
+ pip_desc.layout.attrs[2].format = SG_VERTEXFORMAT_UBYTE4N;
|
|
|
+ pip_desc.index_type = SG_INDEXTYPE_UINT32;
|
|
|
+ pip_desc.sample_count = desc->sample_count;
|
|
|
+ pip_desc.depth.pixel_format = desc->depth_format;
|
|
|
+ pip_desc.colors[0].pixel_format = desc->color_format;
|
|
|
+ pip_desc.colors[0].write_mask = desc->color_write_mask;
|
|
|
+ pip_desc.colors[0].blend.enabled = true;
|
|
|
+ pip_desc.colors[0].blend.src_factor_rgb = SG_BLENDFACTOR_ONE;
|
|
|
+ pip_desc.colors[0].blend.dst_factor_rgb = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA;
|
|
|
+ pip_desc.colors[0].blend.src_factor_alpha = SG_BLENDFACTOR_ONE;
|
|
|
+ pip_desc.colors[0].blend.dst_factor_alpha = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA;
|
|
|
+ pip_desc.label = "sspine-pip-normal/additive";
|
|
|
+ ctx->pip.normal_additive = sg_make_pipeline(&pip_desc);
|
|
|
+
|
|
|
+ pip_desc.colors[0].blend.src_factor_rgb = SG_BLENDFACTOR_ZERO;
|
|
|
+ pip_desc.colors[0].blend.dst_factor_rgb = SG_BLENDFACTOR_SRC_COLOR;
|
|
|
+ pip_desc.colors[0].blend.src_factor_alpha = SG_BLENDFACTOR_ZERO;
|
|
|
+ pip_desc.colors[0].blend.dst_factor_alpha = SG_BLENDFACTOR_ONE;
|
|
|
+ pip_desc.label = "sspine-pip-multiply";
|
|
|
+ ctx->pip.multiply = sg_make_pipeline(&pip_desc);
|
|
|
+
|
|
|
+ return SSPINE_RESOURCESTATE_VALID;
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_deinit_context(_sspine_context_t* ctx) {
|
|
|
+ // NOTE: it's ok to call sg_destroy functions with invalid handles
|
|
|
+ sg_destroy_pipeline(ctx->pip.normal_additive);
|
|
|
+ sg_destroy_pipeline(ctx->pip.multiply);
|
|
|
+ sg_destroy_buffer(ctx->ibuf);
|
|
|
+ sg_destroy_buffer(ctx->vbuf);
|
|
|
+ if (ctx->commands.ptr) {
|
|
|
+ _sspine_free(ctx->commands.ptr);
|
|
|
+ ctx->commands.ptr = 0;
|
|
|
+ }
|
|
|
+ if (ctx->indices.ptr) {
|
|
|
+ _sspine_free(ctx->indices.ptr);
|
|
|
+ ctx->indices.ptr = 0;
|
|
|
+ }
|
|
|
+ if (ctx->vertices.ptr) {
|
|
|
+ _sspine_free(ctx->vertices.ptr);
|
|
|
+ ctx->vertices.ptr = 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_destroy_context(sspine_context ctx_id) {
|
|
|
+ _sspine_context_t* ctx = _sspine_lookup_context(ctx_id.id);
|
|
|
+ if (ctx) {
|
|
|
+ _sspine_deinit_context(ctx);
|
|
|
+ _sspine_context_pool_t* p = &_sspine.context_pool;
|
|
|
+ _sspine_clear(ctx, sizeof(_sspine_context_t));
|
|
|
+ _sspine_pool_free_index(&p->pool, _sspine_slot_index(ctx_id.id));
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_destroy_all_contexts(void) {
|
|
|
+ _sspine_context_pool_t* p = &_sspine.context_pool;
|
|
|
+ for (int i = 0; i < p->pool.size; i++) {
|
|
|
+ _sspine_context_t* ctx = &p->items[i];
|
|
|
+ _sspine_destroy_context(_sspine_make_context_handle(ctx->slot.id));
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_context_desc _sspine_context_desc_defaults(const sspine_context_desc* desc) {
|
|
|
+ sspine_context_desc res = *desc;
|
|
|
+ res.max_vertices = _sspine_def(desc->max_vertices, _SSPINE_DEFAULT_MAX_VERTICES);
|
|
|
+ res.max_commands = _sspine_def(desc->max_commands, _SSPINE_DEFAULT_MAX_COMMANDS);
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+static bool _sspine_is_default_context(sspine_context ctx_id) {
|
|
|
+ return ctx_id.id == 0x00010001;
|
|
|
+}
|
|
|
+
|
|
|
+//=== ATLAS POOL FUNCTIONS =====================================================
|
|
|
+static void _sspine_setup_atlas_pool(int pool_size) {
|
|
|
+ _sspine_atlas_pool_t* p = &_sspine.atlas_pool;
|
|
|
+ _sspine_init_item_pool(&p->pool, pool_size, (void**)&p->items, sizeof(_sspine_atlas_t));
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_discard_atlas_pool(void) {
|
|
|
+ _sspine_atlas_pool_t* p = &_sspine.atlas_pool;
|
|
|
+ _sspine_discard_item_pool(&p->pool, (void**)&p->items);
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_atlas _sspine_make_atlas_handle(uint32_t id) {
|
|
|
+ sspine_atlas handle = { id };
|
|
|
+ return handle;
|
|
|
+}
|
|
|
+
|
|
|
+static _sspine_atlas_t* _sspine_atlas_at(uint32_t id) {
|
|
|
+ SOKOL_ASSERT(SSPINE_INVALID_ID != id);
|
|
|
+ const _sspine_atlas_pool_t* p = &_sspine.atlas_pool;
|
|
|
+ int slot_index = _sspine_slot_index(id);
|
|
|
+ SOKOL_ASSERT((slot_index > _SSPINE_INVALID_SLOT_INDEX) && (slot_index < p->pool.size));
|
|
|
+ return &p->items[slot_index];
|
|
|
+}
|
|
|
+
|
|
|
+static _sspine_atlas_t* _sspine_lookup_atlas(uint32_t id) {
|
|
|
+ if (SSPINE_INVALID_ID != id) {
|
|
|
+ _sspine_atlas_t* atlas = _sspine_atlas_at(id);
|
|
|
+ if (atlas->slot.id == id) {
|
|
|
+ return atlas;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_atlas _sspine_alloc_atlas(void) {
|
|
|
+ _sspine_atlas_pool_t* p = &_sspine.atlas_pool;
|
|
|
+ int slot_index = _sspine_pool_alloc_index(&p->pool);
|
|
|
+ if (_SSPINE_INVALID_SLOT_INDEX != slot_index) {
|
|
|
+ uint32_t id = _sspine_slot_init(&p->pool, &p->items[slot_index].slot, slot_index);
|
|
|
+ return _sspine_make_atlas_handle(id);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ // pool exhausted
|
|
|
+ return _sspine_make_atlas_handle(SSPINE_INVALID_ID);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void _spAtlasPage_disposeTexture(spAtlasPage* self) {
|
|
|
+ if (self->rendererObject != 0) {
|
|
|
+ const sg_image img = { (uint32_t)(uintptr_t)self->rendererObject };
|
|
|
+ sg_destroy_image(img);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_resource_state _sspine_init_atlas(_sspine_atlas_t* atlas, const sspine_atlas_desc* desc) {
|
|
|
+ SOKOL_ASSERT(atlas && (atlas->slot.state == SSPINE_RESOURCESTATE_ALLOC));
|
|
|
+ SOKOL_ASSERT(desc);
|
|
|
+ SOKOL_ASSERT(atlas->sp_atlas == 0);
|
|
|
+
|
|
|
+ if ((0 == desc->data.ptr) || (0 == desc->data.size)) {
|
|
|
+ _SSPINE_ERROR(ATLAS_DESC_NO_DATA);
|
|
|
+ return SSPINE_RESOURCESTATE_FAILED;
|
|
|
+ }
|
|
|
+ atlas->overrides = desc->override;
|
|
|
+
|
|
|
+ // NOTE: Spine doesn't detect when invalid or corrupt data is passed here,
|
|
|
+ // not much we can do about this...
|
|
|
+ atlas->sp_atlas = spAtlas_create((const char*)desc->data.ptr, (int)desc->data.size, "", 0);
|
|
|
+ if (0 == atlas->sp_atlas) {
|
|
|
+ _SSPINE_ERROR(SPINE_ATLAS_CREATION_FAILED);
|
|
|
+ return SSPINE_RESOURCESTATE_FAILED;
|
|
|
+ }
|
|
|
+
|
|
|
+ // allocate a sokol-gfx image handle for each page, but the actual image initialization
|
|
|
+ // needs to be delegated to the application
|
|
|
+ for (spAtlasPage* page = atlas->sp_atlas->pages; page != 0; page = page->next) {
|
|
|
+ atlas->num_pages++;
|
|
|
+ const sg_image img = sg_alloc_image();
|
|
|
+ if (sg_query_image_state(img) != SG_RESOURCESTATE_ALLOC) {
|
|
|
+ _SSPINE_ERROR(SG_ALLOC_IMAGE_FAILED);
|
|
|
+ return SSPINE_RESOURCESTATE_FAILED;
|
|
|
+ }
|
|
|
+ page->rendererObject = (void*)(uintptr_t)img.id;
|
|
|
+ if (desc->override.premul_alpha_enabled) {
|
|
|
+ // NOTE: -1 is spine-c convention for 'true'
|
|
|
+ page->pma = -1;
|
|
|
+ }
|
|
|
+ else if (desc->override.premul_alpha_disabled) {
|
|
|
+ page->pma = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return SSPINE_RESOURCESTATE_VALID;
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_deinit_atlas(_sspine_atlas_t* atlas) {
|
|
|
+ if (atlas->sp_atlas) {
|
|
|
+ spAtlas_dispose(atlas->sp_atlas);
|
|
|
+ atlas->sp_atlas = 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_destroy_atlas(sspine_atlas atlas_id) {
|
|
|
+ _sspine_atlas_t* atlas = _sspine_lookup_atlas(atlas_id.id);
|
|
|
+ if (atlas) {
|
|
|
+ _sspine_deinit_atlas(atlas);
|
|
|
+ _sspine_atlas_pool_t* p = &_sspine.atlas_pool;
|
|
|
+ _sspine_clear(atlas, sizeof(_sspine_atlas_t));
|
|
|
+ _sspine_pool_free_index(&p->pool, _sspine_slot_index(atlas_id.id));
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_destroy_all_atlases(void) {
|
|
|
+ _sspine_atlas_pool_t* p = &_sspine.atlas_pool;
|
|
|
+ for (int i = 0; i < p->pool.size; i++) {
|
|
|
+ _sspine_atlas_t* atlas = &p->items[i];
|
|
|
+ _sspine_destroy_atlas(_sspine_make_atlas_handle(atlas->slot.id));
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_atlas_desc _sspine_atlas_desc_defaults(const sspine_atlas_desc* desc) {
|
|
|
+ sspine_atlas_desc res = *desc;
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+static spAtlasPage* _sspine_lookup_atlas_page(uint32_t atlas_id, int page_index) {
|
|
|
+ _sspine_atlas_t* atlas = _sspine_lookup_atlas(atlas_id);
|
|
|
+ if (atlas) {
|
|
|
+ if ((page_index >= 0) && (page_index < atlas->num_pages)) {
|
|
|
+ int i = 0;
|
|
|
+ for (spAtlasPage* page = atlas->sp_atlas->pages; page != 0; page = page->next, i++) {
|
|
|
+ if (i == page_index) {
|
|
|
+ return page;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+//=== SKELETON POOL FUNCTIONS ==================================================
|
|
|
+static void _sspine_setup_skeleton_pool(int pool_size) {
|
|
|
+ _sspine_skeleton_pool_t* p = &_sspine.skeleton_pool;
|
|
|
+ _sspine_init_item_pool(&p->pool, pool_size, (void**)&p->items, sizeof(_sspine_skeleton_t));
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_discard_skeleton_pool(void) {
|
|
|
+ _sspine_skeleton_pool_t* p = &_sspine.skeleton_pool;
|
|
|
+ _sspine_discard_item_pool(&p->pool, (void**)&p->items);
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_skeleton _sspine_make_skeleton_handle(uint32_t id) {
|
|
|
+ sspine_skeleton handle = { id };
|
|
|
+ return handle;
|
|
|
+}
|
|
|
+
|
|
|
+static _sspine_skeleton_t* _sspine_skeleton_at(uint32_t id) {
|
|
|
+ SOKOL_ASSERT(SSPINE_INVALID_ID != id);
|
|
|
+ const _sspine_skeleton_pool_t* p = &_sspine.skeleton_pool;
|
|
|
+ int slot_index = _sspine_slot_index(id);
|
|
|
+ SOKOL_ASSERT((slot_index > _SSPINE_INVALID_SLOT_INDEX) && (slot_index < p->pool.size));
|
|
|
+ return &p->items[slot_index];
|
|
|
+}
|
|
|
+
|
|
|
+static _sspine_skeleton_t* _sspine_lookup_skeleton(uint32_t id) {
|
|
|
+ if (SSPINE_INVALID_ID != id) {
|
|
|
+ _sspine_skeleton_t* skeleton = _sspine_skeleton_at(id);
|
|
|
+ if (skeleton->slot.id == id) {
|
|
|
+ return skeleton;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_skeleton _sspine_alloc_skeleton(void) {
|
|
|
+ _sspine_skeleton_pool_t* p = &_sspine.skeleton_pool;
|
|
|
+ int slot_index = _sspine_pool_alloc_index(&p->pool);
|
|
|
+ if (_SSPINE_INVALID_SLOT_INDEX != slot_index) {
|
|
|
+ uint32_t id = _sspine_slot_init(&p->pool, &p->items[slot_index].slot, slot_index);
|
|
|
+ return _sspine_make_skeleton_handle(id);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ // pool exhausted
|
|
|
+ return _sspine_make_skeleton_handle(SSPINE_INVALID_ID);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_resource_state _sspine_init_skeleton(_sspine_skeleton_t* skeleton, const sspine_skeleton_desc* desc) {
|
|
|
+ SOKOL_ASSERT(skeleton && (skeleton->slot.state == SSPINE_RESOURCESTATE_ALLOC));
|
|
|
+ SOKOL_ASSERT(desc);
|
|
|
+
|
|
|
+ if ((0 == desc->json_data) && ((0 == desc->binary_data.ptr) || (0 == desc->binary_data.size))) {
|
|
|
+ _SSPINE_ERROR(SKELETON_DESC_NO_DATA);
|
|
|
+ return SSPINE_RESOURCESTATE_FAILED;
|
|
|
+ }
|
|
|
+ if (desc->atlas.id == SSPINE_INVALID_ID) {
|
|
|
+ _SSPINE_ERROR(SKELETON_DESC_NO_ATLAS);
|
|
|
+ return SSPINE_RESOURCESTATE_FAILED;
|
|
|
+ }
|
|
|
+
|
|
|
+ skeleton->atlas.id = desc->atlas.id;
|
|
|
+ skeleton->atlas.ptr = _sspine_lookup_atlas(skeleton->atlas.id);
|
|
|
+ if (!_sspine_atlas_ref_valid(&skeleton->atlas)) {
|
|
|
+ _SSPINE_ERROR(SKELETON_ATLAS_NOT_VALID);
|
|
|
+ return SSPINE_RESOURCESTATE_FAILED;
|
|
|
+ }
|
|
|
+ _sspine_atlas_t* atlas = skeleton->atlas.ptr;
|
|
|
+ if (SSPINE_RESOURCESTATE_VALID != atlas->slot.state) {
|
|
|
+ _SSPINE_ERROR(SKELETON_ATLAS_NOT_VALID);
|
|
|
+ return SSPINE_RESOURCESTATE_FAILED;
|
|
|
+ }
|
|
|
+ SOKOL_ASSERT(atlas->sp_atlas);
|
|
|
+
|
|
|
+ if (desc->json_data) {
|
|
|
+ spSkeletonJson* skel_json = spSkeletonJson_create(atlas->sp_atlas);
|
|
|
+ SOKOL_ASSERT(skel_json);
|
|
|
+ skel_json->scale = desc->prescale;
|
|
|
+ skeleton->sp_skel_data = spSkeletonJson_readSkeletonData(skel_json, desc->json_data);
|
|
|
+ spSkeletonJson_dispose(skel_json); skel_json = 0;
|
|
|
+ if (0 == skeleton->sp_skel_data) {
|
|
|
+ _SSPINE_ERROR(SPINE_SKELETON_DATA_CREATION_FAILED);
|
|
|
+ return SSPINE_RESOURCESTATE_FAILED;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ spSkeletonBinary* skel_bin = spSkeletonBinary_create(atlas->sp_atlas);
|
|
|
+ SOKOL_ASSERT(skel_bin);
|
|
|
+ skel_bin->scale = desc->prescale;
|
|
|
+ skeleton->sp_skel_data = spSkeletonBinary_readSkeletonData(skel_bin, desc->binary_data.ptr, (int)desc->binary_data.size);
|
|
|
+ spSkeletonBinary_dispose(skel_bin); skel_bin = 0;
|
|
|
+ if (0 == skeleton->sp_skel_data) {
|
|
|
+ _SSPINE_ERROR(SPINE_SKELETON_DATA_CREATION_FAILED);
|
|
|
+ return SSPINE_RESOURCESTATE_FAILED;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data);
|
|
|
+
|
|
|
+ skeleton->sp_anim_data = spAnimationStateData_create(skeleton->sp_skel_data);
|
|
|
+ SOKOL_ASSERT(skeleton->sp_anim_data);
|
|
|
+ skeleton->sp_anim_data->defaultMix = desc->anim_default_mix;
|
|
|
+
|
|
|
+ // get the max number of vertices in any mesh attachment
|
|
|
+ int max_vertex_count = 4; // number of vertices in a 'region attachment' (a 2-triangle quad)
|
|
|
+ const spSkeletonData* sp_skel_data = skeleton->sp_skel_data;
|
|
|
+ for (int skinIndex = 0; skinIndex < sp_skel_data->skinsCount; skinIndex++) {
|
|
|
+ const spSkin* sp_skin = sp_skel_data->skins[skinIndex];
|
|
|
+ const spSkinEntry* skin_entry = spSkin_getAttachments(sp_skin);
|
|
|
+ if (skin_entry) do {
|
|
|
+ if (skin_entry->attachment) {
|
|
|
+ if (skin_entry->attachment->type == SP_ATTACHMENT_MESH) {
|
|
|
+ const spMeshAttachment* mesh_attachment = (spMeshAttachment*)skin_entry->attachment;
|
|
|
+ // worldVerticesLength is number of floats
|
|
|
+ SOKOL_ASSERT((mesh_attachment->super.worldVerticesLength & 1) == 0);
|
|
|
+ const int num_vertices = mesh_attachment->super.worldVerticesLength / 2;
|
|
|
+ if (num_vertices > max_vertex_count) {
|
|
|
+ max_vertex_count = num_vertices;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } while ((skin_entry = skin_entry->next) != 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ // allocate a shared vertex transform buffer (big enough to hold vertices for biggest mesh attachment)
|
|
|
+ skeleton->tform_buf.num = max_vertex_count;
|
|
|
+ skeleton->tform_buf.ptr = (sspine_vec2*) _sspine_malloc((size_t)skeleton->tform_buf.num * sizeof(sspine_vec2));
|
|
|
+
|
|
|
+ return SSPINE_RESOURCESTATE_VALID;
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_deinit_skeleton(_sspine_skeleton_t* skeleton) {
|
|
|
+ if (skeleton->tform_buf.ptr) {
|
|
|
+ _sspine_free(skeleton->tform_buf.ptr);
|
|
|
+ skeleton->tform_buf.ptr = 0;
|
|
|
+ }
|
|
|
+ if (skeleton->sp_anim_data) {
|
|
|
+ spAnimationStateData_dispose(skeleton->sp_anim_data);
|
|
|
+ skeleton->sp_anim_data = 0;
|
|
|
+ }
|
|
|
+ if (skeleton->sp_skel_data) {
|
|
|
+ spSkeletonData_dispose(skeleton->sp_skel_data);
|
|
|
+ skeleton->sp_skel_data = 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_destroy_skeleton(sspine_skeleton skeleton_id) {
|
|
|
+ _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
|
|
|
+ if (skeleton) {
|
|
|
+ _sspine_deinit_skeleton(skeleton);
|
|
|
+ _sspine_skeleton_pool_t* p = &_sspine.skeleton_pool;
|
|
|
+ _sspine_clear(skeleton, sizeof(_sspine_skeleton_t));
|
|
|
+ _sspine_pool_free_index(&p->pool, _sspine_slot_index(skeleton_id.id));
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_destroy_all_skeletons(void) {
|
|
|
+ _sspine_skeleton_pool_t* p = &_sspine.skeleton_pool;
|
|
|
+ for (int i = 0; i < p->pool.size; i++) {
|
|
|
+ _sspine_skeleton_t* skeleton = &p->items[i];
|
|
|
+ _sspine_destroy_skeleton(_sspine_make_skeleton_handle(skeleton->slot.id));
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_skeleton_desc _sspine_skeleton_desc_defaults(const sspine_skeleton_desc* desc) {
|
|
|
+ sspine_skeleton_desc res = *desc;
|
|
|
+ res.prescale = _sspine_def(desc->prescale, 1.0f);
|
|
|
+ res.anim_default_mix = _sspine_def(desc->anim_default_mix, 0.2f);
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+static spBoneData* _sspine_lookup_bone_data(uint32_t skeleton_id, int bone_index) {
|
|
|
+ _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id);
|
|
|
+ if (_sspine_skeleton_and_deps_valid(skeleton)) {
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data && skeleton->sp_skel_data->bones);
|
|
|
+ if ((bone_index >= 0) && (bone_index <= skeleton->sp_skel_data->bonesCount)) {
|
|
|
+ return skeleton->sp_skel_data->bones[bone_index];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static spSlotData* _sspine_lookup_slot_data(uint32_t skeleton_id, int slot_index) {
|
|
|
+ _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id);
|
|
|
+ if (_sspine_skeleton_and_deps_valid(skeleton)) {
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data && skeleton->sp_skel_data->slots);
|
|
|
+ if ((slot_index >= 0) && (slot_index <= skeleton->sp_skel_data->slotsCount)) {
|
|
|
+ return skeleton->sp_skel_data->slots[slot_index];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static spEventData* _sspine_lookup_event_data(uint32_t skeleton_id, int event_index) {
|
|
|
+ _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id);
|
|
|
+ if (_sspine_skeleton_and_deps_valid(skeleton)) {
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data && skeleton->sp_skel_data->events);
|
|
|
+ if ((event_index >= 0) && (event_index < skeleton->sp_skel_data->eventsCount)) {
|
|
|
+ return skeleton->sp_skel_data->events[event_index];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static spIkConstraintData* _sspine_lookup_ikconstraint_data(uint32_t skeleton_id, int iktarget_index) {
|
|
|
+ _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id);
|
|
|
+ if (_sspine_skeleton_and_deps_valid(skeleton)) {
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data && skeleton->sp_skel_data->ikConstraints);
|
|
|
+ if ((iktarget_index >= 0) && (iktarget_index < skeleton->sp_skel_data->ikConstraintsCount)) {
|
|
|
+ return skeleton->sp_skel_data->ikConstraints[iktarget_index];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static spSkin* _sspine_lookup_skin(uint32_t skeleton_id, int skin_index) {
|
|
|
+ _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id);
|
|
|
+ if (_sspine_skeleton_and_deps_valid(skeleton)) {
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data && skeleton->sp_skel_data->skins);
|
|
|
+ if ((skin_index >= 0) && (skin_index < skeleton->sp_skel_data->skinsCount)) {
|
|
|
+ return skeleton->sp_skel_data->skins[skin_index];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+//=== SKINSET POOL FUNCTIONS ===================================================
|
|
|
+static void _sspine_setup_skinset_pool(int pool_size) {
|
|
|
+ _sspine_skinset_pool_t* p = &_sspine.skinset_pool;
|
|
|
+ _sspine_init_item_pool(&p->pool, pool_size, (void**)&p->items, sizeof(_sspine_skinset_t));
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_discard_skinset_pool(void) {
|
|
|
+ _sspine_skinset_pool_t* p = &_sspine.skinset_pool;
|
|
|
+ _sspine_discard_item_pool(&p->pool, (void**)&p->items);
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_skinset _sspine_make_skinset_handle(uint32_t id) {
|
|
|
+ sspine_skinset handle = { id };
|
|
|
+ return handle;
|
|
|
+}
|
|
|
+
|
|
|
+static _sspine_skinset_t* _sspine_skinset_at(uint32_t id) {
|
|
|
+ SOKOL_ASSERT(SSPINE_INVALID_ID != id);
|
|
|
+ const _sspine_skinset_pool_t* p = &_sspine.skinset_pool;
|
|
|
+ int slot_index = _sspine_slot_index(id);
|
|
|
+ SOKOL_ASSERT((slot_index > _SSPINE_INVALID_SLOT_INDEX) && (slot_index < p->pool.size));
|
|
|
+ return &p->items[slot_index];
|
|
|
+}
|
|
|
+
|
|
|
+static _sspine_skinset_t* _sspine_lookup_skinset(uint32_t id) {
|
|
|
+ if (SSPINE_INVALID_ID != id) {
|
|
|
+ _sspine_skinset_t* skinset = _sspine_skinset_at(id);
|
|
|
+ if (skinset->slot.id == id) {
|
|
|
+ return skinset;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_skinset _sspine_alloc_skinset(void) {
|
|
|
+ _sspine_skinset_pool_t* p = &_sspine.skinset_pool;
|
|
|
+ int slot_index = _sspine_pool_alloc_index(&p->pool);
|
|
|
+ if (_SSPINE_INVALID_SLOT_INDEX != slot_index) {
|
|
|
+ uint32_t id = _sspine_slot_init(&p->pool, &p->items[slot_index].slot, slot_index);
|
|
|
+ return _sspine_make_skinset_handle(id);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ // pool exhausted
|
|
|
+ return _sspine_make_skinset_handle(SSPINE_INVALID_ID);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_resource_state _sspine_init_skinset(_sspine_skinset_t* skinset, const sspine_skinset_desc* desc) {
|
|
|
+ SOKOL_ASSERT(skinset && (skinset->slot.state == SSPINE_RESOURCESTATE_ALLOC));
|
|
|
+ SOKOL_ASSERT(desc);
|
|
|
+
|
|
|
+ if (desc->skeleton.id == SSPINE_INVALID_ID) {
|
|
|
+ _SSPINE_ERROR(SKINSET_DESC_NO_SKELETON);
|
|
|
+ return SSPINE_RESOURCESTATE_FAILED;
|
|
|
+ }
|
|
|
+ skinset->skel.id = desc->skeleton.id;
|
|
|
+ skinset->skel.ptr = _sspine_lookup_skeleton(desc->skeleton.id);
|
|
|
+ if (!_sspine_skeleton_ref_valid(&skinset->skel)) {
|
|
|
+ _SSPINE_ERROR(SKINSET_SKELETON_NOT_VALID);
|
|
|
+ return SSPINE_RESOURCESTATE_FAILED;
|
|
|
+ }
|
|
|
+ _sspine_skeleton_t* skel = skinset->skel.ptr;
|
|
|
+ if (SSPINE_RESOURCESTATE_VALID != skel->slot.state) {
|
|
|
+ _SSPINE_ERROR(SKINSET_SKELETON_NOT_VALID);
|
|
|
+ return SSPINE_RESOURCESTATE_FAILED;
|
|
|
+ }
|
|
|
+ SOKOL_ASSERT(skel->sp_skel_data);
|
|
|
+ skinset->sp_skin = spSkin_create("skinset");
|
|
|
+ for (int i = 0; i < SSPINE_MAX_SKINSET_SKINS; i++) {
|
|
|
+ if (desc->skins[i].skeleton_id != SSPINE_INVALID_ID) {
|
|
|
+ spSkin* skin = _sspine_lookup_skin(desc->skins[i].skeleton_id, desc->skins[i].index);
|
|
|
+ if (0 == skin) {
|
|
|
+ _SSPINE_ERROR(SKINSET_INVALID_SKIN_HANDLE);
|
|
|
+ return SSPINE_RESOURCESTATE_FAILED;
|
|
|
+ }
|
|
|
+ spSkin_addSkin(skinset->sp_skin, skin);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return SSPINE_RESOURCESTATE_VALID;
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_deinit_skinset(_sspine_skinset_t* skinset) {
|
|
|
+ if (skinset->sp_skin) {
|
|
|
+ spSkin_clear(skinset->sp_skin);
|
|
|
+ spSkin_dispose(skinset->sp_skin);
|
|
|
+ skinset->sp_skin = 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_destroy_skinset(sspine_skinset skinset_id) {
|
|
|
+ _sspine_skinset_t* skinset = _sspine_lookup_skinset(skinset_id.id);
|
|
|
+ if (skinset) {
|
|
|
+ _sspine_deinit_skinset(skinset);
|
|
|
+ _sspine_skinset_pool_t* p = &_sspine.skinset_pool;
|
|
|
+ _sspine_clear(skinset, sizeof(_sspine_skinset_t));
|
|
|
+ _sspine_pool_free_index(&p->pool, _sspine_slot_index(skinset_id.id));
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_destroy_all_skinsets(void) {
|
|
|
+ _sspine_skinset_pool_t* p = &_sspine.skinset_pool;
|
|
|
+ for (int i = 0; i < p->pool.size; i++) {
|
|
|
+ _sspine_skinset_t* skinset = &p->items[i];
|
|
|
+ _sspine_destroy_skinset(_sspine_make_skinset_handle(skinset->slot.id));
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_skinset_desc _sspine_skinset_desc_defaults(const sspine_skinset_desc* desc) {
|
|
|
+ sspine_skinset_desc res = *desc;
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+//=== INSTANCE POOL FUNCTIONS ==================================================
|
|
|
+static void _sspine_setup_instance_pool(int pool_size) {
|
|
|
+ _sspine_instance_pool_t* p = &_sspine.instance_pool;
|
|
|
+ _sspine_init_item_pool(&p->pool, pool_size, (void**)&p->items, sizeof(_sspine_instance_t));
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_discard_instance_pool(void) {
|
|
|
+ _sspine_instance_pool_t* p = &_sspine.instance_pool;
|
|
|
+ _sspine_discard_item_pool(&p->pool, (void**)&p->items);
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_instance _sspine_make_instance_handle(uint32_t id) {
|
|
|
+ sspine_instance handle = { id };
|
|
|
+ return handle;
|
|
|
+}
|
|
|
+
|
|
|
+static _sspine_instance_t* _sspine_instance_at(uint32_t id) {
|
|
|
+ SOKOL_ASSERT(SSPINE_INVALID_ID != id);
|
|
|
+ const _sspine_instance_pool_t* p = &_sspine.instance_pool;
|
|
|
+ int slot_index = _sspine_slot_index(id);
|
|
|
+ SOKOL_ASSERT((slot_index > _SSPINE_INVALID_SLOT_INDEX) && (slot_index < p->pool.size));
|
|
|
+ return &p->items[slot_index];
|
|
|
+}
|
|
|
+
|
|
|
+static _sspine_instance_t* _sspine_lookup_instance(uint32_t id) {
|
|
|
+ if (SSPINE_INVALID_ID != id) {
|
|
|
+ _sspine_instance_t* instance = _sspine_instance_at(id);
|
|
|
+ if (instance->slot.id == id) {
|
|
|
+ return instance;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_instance _sspine_alloc_instance(void) {
|
|
|
+ _sspine_instance_pool_t* p = &_sspine.instance_pool;
|
|
|
+ sspine_instance res;
|
|
|
+ int slot_index = _sspine_pool_alloc_index(&p->pool);
|
|
|
+ if (_SSPINE_INVALID_SLOT_INDEX != slot_index) {
|
|
|
+ uint32_t id = _sspine_slot_init(&p->pool, &p->items[slot_index].slot, slot_index);
|
|
|
+ res = _sspine_make_instance_handle(id);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ // pool exhausted
|
|
|
+ res = _sspine_make_instance_handle(SSPINE_INVALID_ID);
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_rewind_triggered_events(_sspine_instance_t* instance) {
|
|
|
+ instance->cur_triggered_event_index = 0;
|
|
|
+ _sspine_clear(instance->triggered_events, sizeof(instance->triggered_events));
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_triggered_event_info* _sspine_next_triggered_event_info(_sspine_instance_t* instance) {
|
|
|
+ if (instance->cur_triggered_event_index < _SSPINE_MAX_TRIGGERED_EVENTS) {
|
|
|
+ return &instance->triggered_events[instance->cur_triggered_event_index++];
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_event_listener(spAnimationState* sp_anim_state, spEventType sp_event_type, spTrackEntry* sp_track_entry, spEvent* sp_event) {
|
|
|
+ if (sp_event_type == SP_ANIMATION_EVENT) {
|
|
|
+ SOKOL_ASSERT(sp_anim_state && sp_track_entry && sp_event); (void)sp_track_entry;
|
|
|
+ SOKOL_ASSERT(sp_event->data && sp_event->data->name);
|
|
|
+ _sspine_instance_t* instance = _sspine_lookup_instance((uint32_t)(uintptr_t)sp_anim_state->userData);
|
|
|
+ if (_sspine_instance_and_deps_valid(instance)) {
|
|
|
+ sspine_triggered_event_info* info = _sspine_next_triggered_event_info(instance);
|
|
|
+ if (info) {
|
|
|
+ // FIXME: this sucks, but we really need the event index
|
|
|
+ _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(instance->skel.id);
|
|
|
+ SOKOL_ASSERT(skeleton && skeleton->sp_skel_data->events);
|
|
|
+ const spEventData* sp_event_data = sp_event->data;
|
|
|
+ for (int i = 0; i < skeleton->sp_skel_data->eventsCount; i++) {
|
|
|
+ if (sp_event_data == skeleton->sp_skel_data->events[i]) {
|
|
|
+ info->event = _sspine_event(skeleton->slot.id, i);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ SOKOL_ASSERT(info->event.skeleton_id != SSPINE_INVALID_ID);
|
|
|
+ info->valid = true;
|
|
|
+ info->time = sp_event->time;
|
|
|
+ info->int_value = sp_event->intValue;
|
|
|
+ info->float_value = sp_event->floatValue;
|
|
|
+ info->volume = sp_event->volume;
|
|
|
+ info->balance = sp_event->balance;
|
|
|
+ info->string_value = _sspine_string(sp_event->stringValue);
|
|
|
+ if (info->string_value.truncated) {
|
|
|
+ _SSPINE_WARN(STRING_TRUNCATED);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_resource_state _sspine_init_instance(_sspine_instance_t* instance, const sspine_instance_desc* desc) {
|
|
|
+ SOKOL_ASSERT(instance && (instance->slot.state == SSPINE_RESOURCESTATE_ALLOC));
|
|
|
+ SOKOL_ASSERT(desc);
|
|
|
+
|
|
|
+ if (desc->skeleton.id == SSPINE_INVALID_ID) {
|
|
|
+ _SSPINE_ERROR(INSTANCE_DESC_NO_SKELETON);
|
|
|
+ return SSPINE_RESOURCESTATE_FAILED;
|
|
|
+ }
|
|
|
+ instance->skel.id = desc->skeleton.id;
|
|
|
+ instance->skel.ptr = _sspine_lookup_skeleton(instance->skel.id);
|
|
|
+ if (!_sspine_skeleton_ref_valid(&instance->skel)) {
|
|
|
+ _SSPINE_ERROR(INSTANCE_SKELETON_NOT_VALID);
|
|
|
+ return SSPINE_RESOURCESTATE_FAILED;
|
|
|
+ }
|
|
|
+ _sspine_skeleton_t* skel = instance->skel.ptr;
|
|
|
+ if (SSPINE_RESOURCESTATE_VALID != skel->slot.state) {
|
|
|
+ _SSPINE_ERROR(INSTANCE_SKELETON_NOT_VALID);
|
|
|
+ return SSPINE_RESOURCESTATE_FAILED;
|
|
|
+ }
|
|
|
+ instance->atlas = skel->atlas;
|
|
|
+ if (!_sspine_atlas_ref_valid(&instance->atlas)) {
|
|
|
+ _SSPINE_ERROR(INSTANCE_ATLAS_NOT_VALID);
|
|
|
+ return SSPINE_RESOURCESTATE_FAILED;
|
|
|
+ }
|
|
|
+ if (SSPINE_RESOURCESTATE_VALID != instance->atlas.ptr->slot.state) {
|
|
|
+ _SSPINE_ERROR(INSTANCE_ATLAS_NOT_VALID);
|
|
|
+ return SSPINE_RESOURCESTATE_FAILED;
|
|
|
+ }
|
|
|
+ SOKOL_ASSERT(skel->sp_skel_data);
|
|
|
+ SOKOL_ASSERT(skel->sp_anim_data);
|
|
|
+
|
|
|
+ instance->sp_skel = spSkeleton_create(skel->sp_skel_data);
|
|
|
+ if (0 == instance->sp_skel) {
|
|
|
+ _SSPINE_ERROR(SPINE_SKELETON_CREATION_FAILED);
|
|
|
+ return SSPINE_RESOURCESTATE_FAILED;
|
|
|
+ }
|
|
|
+ instance->sp_anim_state = spAnimationState_create(skel->sp_anim_data);
|
|
|
+ if (0 == instance->sp_anim_state) {
|
|
|
+ _SSPINE_ERROR(SPINE_ANIMATIONSTATE_CREATION_FAILED);
|
|
|
+ return SSPINE_RESOURCESTATE_FAILED;
|
|
|
+ }
|
|
|
+ instance->sp_clip = spSkeletonClipping_create();
|
|
|
+ if (0 == instance->sp_clip) {
|
|
|
+ _SSPINE_ERROR(SPINE_SKELETONCLIPPING_CREATION_FAILED);
|
|
|
+ return SSPINE_RESOURCESTATE_FAILED;
|
|
|
+ }
|
|
|
+
|
|
|
+ instance->sp_anim_state->userData = (void*)(uintptr_t)instance->slot.id;
|
|
|
+ instance->sp_anim_state->listener = _sspine_event_listener;
|
|
|
+
|
|
|
+ spSkeleton_setToSetupPose(instance->sp_skel);
|
|
|
+ spAnimationState_update(instance->sp_anim_state, 0.0f);
|
|
|
+ spAnimationState_apply(instance->sp_anim_state, instance->sp_skel);
|
|
|
+ spSkeleton_updateWorldTransform(instance->sp_skel);
|
|
|
+
|
|
|
+ return SSPINE_RESOURCESTATE_VALID;
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_deinit_instance(_sspine_instance_t* instance) {
|
|
|
+ if (instance->sp_clip) {
|
|
|
+ spSkeletonClipping_dispose(instance->sp_clip);
|
|
|
+ instance->sp_clip = 0;
|
|
|
+ }
|
|
|
+ if (instance->sp_anim_state) {
|
|
|
+ spAnimationState_dispose(instance->sp_anim_state);
|
|
|
+ instance->sp_anim_state = 0;
|
|
|
+ }
|
|
|
+ if (instance->sp_skel) {
|
|
|
+ spSkeleton_dispose(instance->sp_skel);
|
|
|
+ instance->sp_skel = 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_destroy_instance(sspine_instance instance_id) {
|
|
|
+ _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
|
|
|
+ if (instance) {
|
|
|
+ _sspine_deinit_instance(instance);
|
|
|
+ _sspine_instance_pool_t* p = &_sspine.instance_pool;
|
|
|
+ _sspine_clear(instance, sizeof(_sspine_instance_t));
|
|
|
+ _sspine_pool_free_index(&p->pool, _sspine_slot_index(instance_id.id));
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_destroy_all_instances(void) {
|
|
|
+ _sspine_instance_pool_t* p = &_sspine.instance_pool;
|
|
|
+ for (int i = 0; i < p->pool.size; i++) {
|
|
|
+ _sspine_instance_t* instance = &p->items[i];
|
|
|
+ _sspine_destroy_instance(_sspine_make_instance_handle(instance->slot.id));
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static spAnimation* _sspine_lookup_skeleton_anim(uint32_t skeleton_id, int anim_index) {
|
|
|
+ _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id);
|
|
|
+ if (_sspine_skeleton_and_deps_valid(skeleton)) {
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data);
|
|
|
+ if ((anim_index >= 0) && (anim_index < skeleton->sp_skel_data->animationsCount)) {
|
|
|
+ return skeleton->sp_skel_data->animations[anim_index];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static spAnimation* _sspine_lookup_instance_anim(uint32_t instance_id, uint32_t skeleton_id, int anim_index) {
|
|
|
+ _sspine_instance_t* instance = _sspine_lookup_instance(instance_id);
|
|
|
+ if (_sspine_instance_and_deps_valid(instance) && (instance->skel.id == skeleton_id)) {
|
|
|
+ SOKOL_ASSERT(instance->sp_skel && instance->sp_skel->data);
|
|
|
+ if ((anim_index >= 0) && (anim_index < instance->sp_skel->data->animationsCount)) {
|
|
|
+ return instance->sp_skel->data->animations[anim_index];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static spBone* _sspine_lookup_bone(uint32_t instance_id, uint32_t skeleton_id, int bone_index) {
|
|
|
+ _sspine_instance_t* instance = _sspine_lookup_instance(instance_id);
|
|
|
+ if (_sspine_instance_and_deps_valid(instance) && (instance->skel.id == skeleton_id)) {
|
|
|
+ SOKOL_ASSERT(instance->sp_skel && instance->sp_skel->bones);
|
|
|
+ if ((bone_index >= 0) && (bone_index <= instance->sp_skel->bonesCount)) {
|
|
|
+ return instance->sp_skel->bones[bone_index];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static spSlot* _sspine_lookup_slot(uint32_t instance_id, uint32_t skeleton_id, int slot_index) {
|
|
|
+ _sspine_instance_t* instance = _sspine_lookup_instance(instance_id);
|
|
|
+ if (_sspine_instance_and_deps_valid(instance) && (instance->skel.id == skeleton_id)) {
|
|
|
+ SOKOL_ASSERT(instance->sp_skel && instance->sp_skel->slots);
|
|
|
+ if ((slot_index >= 0) && (slot_index <= instance->sp_skel->slotsCount)) {
|
|
|
+ return instance->sp_skel->slots[slot_index];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static spIkConstraint* _sspine_lookup_ikconstraint(uint32_t instance_id, uint32_t skeleton_id, int iktarget_index) {
|
|
|
+ _sspine_instance_t* instance = _sspine_lookup_instance(instance_id);
|
|
|
+ if (_sspine_instance_and_deps_valid(instance) && (instance->skel.id == skeleton_id)) {
|
|
|
+ SOKOL_ASSERT(instance->sp_skel && instance->sp_skel->ikConstraints);
|
|
|
+ if ((iktarget_index >= 0) && (iktarget_index < instance->sp_skel->ikConstraintsCount)) {
|
|
|
+ return instance->sp_skel->ikConstraints[iktarget_index];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_instance_desc _sspine_instance_desc_defaults(const sspine_instance_desc* desc) {
|
|
|
+ sspine_instance_desc res = *desc;
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+// return sspine_desc with patched defaults
|
|
|
+static sspine_desc _sspine_desc_defaults(const sspine_desc* desc) {
|
|
|
+ SOKOL_ASSERT((desc->allocator.alloc && desc->allocator.free) || (!desc->allocator.alloc && !desc->allocator.free));
|
|
|
+ sspine_desc res = *desc;
|
|
|
+ res.max_vertices = _sspine_def(desc->max_vertices, _SSPINE_DEFAULT_MAX_VERTICES);
|
|
|
+ res.max_commands = _sspine_def(desc->max_commands, _SSPINE_DEFAULT_MAX_COMMANDS);
|
|
|
+ res.context_pool_size = _sspine_def(desc->context_pool_size, _SSPINE_DEFAULT_CONTEXT_POOL_SIZE);
|
|
|
+ res.atlas_pool_size = _sspine_def(desc->atlas_pool_size, _SSPINE_DEFAULT_ATLAS_POOL_SIZE);
|
|
|
+ res.skeleton_pool_size = _sspine_def(desc->skeleton_pool_size, _SSPINE_DEFAULT_SKELETON_POOL_SIZE);
|
|
|
+ res.skinset_pool_size = _sspine_def(desc->skinset_pool_size, _SSPINE_DEFAULT_SKINSET_POOL_SIZE);
|
|
|
+ res.instance_pool_size = _sspine_def(desc->instance_pool_size, _SSPINE_DEFAULT_INSTANCE_POOL_SIZE);
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+static sspine_context_desc _sspine_as_context_desc(const sspine_desc* desc) {
|
|
|
+ sspine_context_desc ctx_desc;
|
|
|
+ _sspine_clear(&ctx_desc, sizeof(ctx_desc));
|
|
|
+ ctx_desc.max_vertices = desc->max_vertices;
|
|
|
+ ctx_desc.max_commands = desc->max_commands;
|
|
|
+ ctx_desc.color_format = desc->color_format;
|
|
|
+ ctx_desc.depth_format = desc->depth_format;
|
|
|
+ ctx_desc.sample_count = desc->sample_count;
|
|
|
+ ctx_desc.color_write_mask = desc->color_write_mask;
|
|
|
+ return ctx_desc;
|
|
|
+}
|
|
|
+
|
|
|
+static sg_filter _sspine_as_image_filter(spAtlasFilter filter) {
|
|
|
+ switch (filter) {
|
|
|
+ case SP_ATLAS_UNKNOWN_FILTER: return _SG_FILTER_DEFAULT;
|
|
|
+ case SP_ATLAS_NEAREST: return SG_FILTER_NEAREST;
|
|
|
+ case SP_ATLAS_LINEAR: return SG_FILTER_LINEAR;
|
|
|
+ case SP_ATLAS_MIPMAP: return SG_FILTER_LINEAR_MIPMAP_NEAREST;
|
|
|
+ case SP_ATLAS_MIPMAP_NEAREST_NEAREST: return SG_FILTER_NEAREST_MIPMAP_NEAREST;
|
|
|
+ case SP_ATLAS_MIPMAP_LINEAR_NEAREST: return SG_FILTER_LINEAR_MIPMAP_NEAREST;
|
|
|
+ case SP_ATLAS_MIPMAP_NEAREST_LINEAR: return SG_FILTER_NEAREST_MIPMAP_LINEAR;
|
|
|
+ case SP_ATLAS_MIPMAP_LINEAR_LINEAR: return SG_FILTER_LINEAR_MIPMAP_LINEAR;
|
|
|
+ default: return _SG_FILTER_DEFAULT;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static sg_wrap _sspine_as_image_wrap(spAtlasWrap wrap) {
|
|
|
+ switch (wrap) {
|
|
|
+ case SP_ATLAS_MIRROREDREPEAT: return SG_WRAP_MIRRORED_REPEAT;
|
|
|
+ case SP_ATLAS_CLAMPTOEDGE: return SG_WRAP_CLAMP_TO_EDGE;
|
|
|
+ case SP_ATLAS_REPEAT: return SG_WRAP_REPEAT;
|
|
|
+ default: return _SG_WRAP_DEFAULT;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_init_image_info(const _sspine_atlas_t* atlas, int index, sspine_image_info* info, bool with_overrides) {
|
|
|
+ spAtlasPage* page = _sspine_lookup_atlas_page(atlas->slot.id, index);
|
|
|
+ SOKOL_ASSERT(page);
|
|
|
+ SOKOL_ASSERT(page->name);
|
|
|
+ info->valid = true;
|
|
|
+ info->sgimage.id = (uint32_t)(uintptr_t)page->rendererObject;
|
|
|
+ if (with_overrides && (atlas->overrides.min_filter != _SG_FILTER_DEFAULT)) {
|
|
|
+ info->min_filter = atlas->overrides.min_filter;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ info->min_filter = _sspine_as_image_filter(page->minFilter);
|
|
|
+ }
|
|
|
+ if (with_overrides && (atlas->overrides.mag_filter != _SG_FILTER_DEFAULT)) {
|
|
|
+ info->mag_filter = atlas->overrides.mag_filter;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ info->mag_filter = _sspine_as_image_filter(page->magFilter);
|
|
|
+ }
|
|
|
+ if (with_overrides && (atlas->overrides.wrap_u != _SG_WRAP_DEFAULT)) {
|
|
|
+ info->wrap_u = atlas->overrides.wrap_u;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ info->wrap_u = _sspine_as_image_wrap(page->uWrap);
|
|
|
+ }
|
|
|
+ if (with_overrides && (atlas->overrides.wrap_v != _SG_WRAP_DEFAULT)) {
|
|
|
+ info->wrap_v = atlas->overrides.wrap_v;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ info->wrap_v = _sspine_as_image_wrap(page->vWrap);
|
|
|
+ }
|
|
|
+ info->width = page->width;
|
|
|
+ info->height = page->height;
|
|
|
+ // NOTE: override already happened in atlas init
|
|
|
+ info->premul_alpha = page->pma != 0;
|
|
|
+ info->filename = _sspine_string(page->name);
|
|
|
+ if (info->filename.truncated) {
|
|
|
+ _SSPINE_WARN(STRING_TRUNCATED);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_check_rewind_commands(_sspine_context_t* ctx) {
|
|
|
+ if (_sspine.frame_count != ctx->commands.rewind_frame_count) {
|
|
|
+ ctx->commands.cur = 0;
|
|
|
+ ctx->commands.rewind_frame_count = _sspine.frame_count;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static _sspine_command_t* _sspine_next_command(_sspine_context_t* ctx) {
|
|
|
+ _sspine_check_rewind_commands(ctx);
|
|
|
+ if ((ctx->commands.cur + 1) <= ctx->commands.num) {
|
|
|
+ return &(ctx->commands.ptr[ctx->commands.cur++]);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ _SSPINE_ERROR(COMMAND_BUFFER_OVERFLOW);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static _sspine_command_t* _sspine_prev_command(_sspine_context_t* ctx) {
|
|
|
+ _sspine_check_rewind_commands(ctx);
|
|
|
+ if ((ctx->commands.cur > 0) && (ctx->commands.cur <= ctx->commands.num)) {
|
|
|
+ return &ctx->commands.ptr[ctx->commands.cur - 1];
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_check_rewind_vertices(_sspine_context_t* ctx) {
|
|
|
+ if (_sspine.frame_count != ctx->vertices.rewind_frame_count) {
|
|
|
+ ctx->vertices.cur = 0;
|
|
|
+ ctx->vertices.rewind_frame_count = _sspine.frame_count;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static _sspine_alloc_vertices_result_t _sspine_alloc_vertices(_sspine_context_t* ctx, int num) {
|
|
|
+ _sspine_check_rewind_vertices(ctx);
|
|
|
+ _sspine_alloc_vertices_result_t res;
|
|
|
+ _sspine_clear(&res, sizeof(res));
|
|
|
+ if ((ctx->vertices.cur + num) <= ctx->vertices.num) {
|
|
|
+ res.ptr = &(ctx->vertices.ptr[ctx->vertices.cur]);
|
|
|
+ res.index = ctx->vertices.cur;
|
|
|
+ ctx->vertices.cur += num;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ _SSPINE_ERROR(VERTEX_BUFFER_OVERFLOW);
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_check_rewind_indices(_sspine_context_t* ctx) {
|
|
|
+ if (_sspine.frame_count != ctx->indices.rewind_frame_count) {
|
|
|
+ ctx->indices.cur = 0;
|
|
|
+ ctx->indices.rewind_frame_count = _sspine.frame_count;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static _sspine_alloc_indices_result_t _sspine_alloc_indices(_sspine_context_t* ctx, int num) {
|
|
|
+ _sspine_check_rewind_indices(ctx);
|
|
|
+ _sspine_alloc_indices_result_t res;
|
|
|
+ _sspine_clear(&res, sizeof(res));
|
|
|
+ if ((ctx->indices.cur + num) <= ctx->indices.num) {
|
|
|
+ res.ptr = &(ctx->indices.ptr[ctx->indices.cur]);
|
|
|
+ res.index = ctx->indices.cur;
|
|
|
+ ctx->indices.cur += num;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ _SSPINE_ERROR(INDEX_BUFFER_OVERFLOW);
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_draw_instance(_sspine_context_t* ctx, _sspine_instance_t* instance, int layer) {
|
|
|
+ SOKOL_ASSERT(_sspine_instance_and_deps_valid(instance));
|
|
|
+ SOKOL_ASSERT(instance->sp_skel);
|
|
|
+ SOKOL_ASSERT(instance->sp_anim_state);
|
|
|
+ SOKOL_ASSERT(instance->sp_clip);
|
|
|
+
|
|
|
+ // see: https://github.com/EsotericSoftware/spine-runtimes/blob/4.1/spine-sdl/src/spine-sdl-c.c
|
|
|
+ const spSkeleton* sp_skel = instance->sp_skel;
|
|
|
+ float* tform_buf = (float*)instance->skel.ptr->tform_buf.ptr;
|
|
|
+ const int max_tform_buf_verts = instance->skel.ptr->tform_buf.num;
|
|
|
+ SOKOL_UNUSED(max_tform_buf_verts); // only used in asserts
|
|
|
+ const int tform_buf_stride = 2; // each element is 2 floats
|
|
|
+ spSkeletonClipping* sp_clip = instance->sp_clip;
|
|
|
+ for (int slot_index = 0; slot_index < sp_skel->slotsCount; slot_index++) {
|
|
|
+ spSlot* sp_slot = sp_skel->drawOrder[slot_index];
|
|
|
+ if (!sp_slot->attachment) {
|
|
|
+ spSkeletonClipping_clipEnd(sp_clip, sp_slot);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // early out if the slot alpha is 0 or the bone is not active
|
|
|
+ // FIXME: does alpha 0 actually mean 'invisible' for all blend modes?
|
|
|
+ if ((sp_slot->color.a == 0) || (!sp_slot->bone->active)) {
|
|
|
+ spSkeletonClipping_clipEnd(sp_clip, sp_slot);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ int num_vertices = 0;
|
|
|
+ float* uvs = 0;
|
|
|
+ float* vertices = 0;
|
|
|
+ int num_indices = 0;
|
|
|
+ const uint16_t* indices = 0;
|
|
|
+ const spColor* att_color = 0;
|
|
|
+ sg_image img = { SG_INVALID_ID };
|
|
|
+ bool premul_alpha = false;
|
|
|
+ if (sp_slot->attachment->type == SP_ATTACHMENT_REGION) {
|
|
|
+ static const uint16_t quad_indices[] = { 0, 1, 2, 2, 3, 0 };
|
|
|
+ spRegionAttachment* region = (spRegionAttachment*)sp_slot->attachment;
|
|
|
+ att_color = ®ion->color;
|
|
|
+ // FIXME(?) early out if the slot alpha is 0
|
|
|
+ if (att_color->a == 0) {
|
|
|
+ spSkeletonClipping_clipEnd(sp_clip, sp_slot);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ spRegionAttachment_computeWorldVertices(region, sp_slot, tform_buf, 0, tform_buf_stride);
|
|
|
+ vertices = tform_buf;
|
|
|
+ num_vertices = 4;
|
|
|
+ indices = &quad_indices[0];
|
|
|
+ num_indices = 6;
|
|
|
+ uvs = region->uvs;
|
|
|
+ const spAtlasPage* sp_page = ((spAtlasRegion*)region->rendererObject)->page;
|
|
|
+ img.id = (uint32_t)(uintptr_t)sp_page->rendererObject;
|
|
|
+ premul_alpha = sp_page->pma != 0;
|
|
|
+ }
|
|
|
+ else if (sp_slot->attachment->type == SP_ATTACHMENT_MESH) {
|
|
|
+ spMeshAttachment* mesh = (spMeshAttachment*)sp_slot->attachment;
|
|
|
+ att_color = &mesh->color;
|
|
|
+ // FIXME(?) early out if the slot alpha is 0
|
|
|
+ if (att_color->a == 0) {
|
|
|
+ spSkeletonClipping_clipEnd(sp_clip, sp_slot);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ const int num_floats = mesh->super.worldVerticesLength;
|
|
|
+ num_vertices = num_floats / 2;
|
|
|
+ SOKOL_ASSERT(num_vertices <= max_tform_buf_verts);
|
|
|
+ spVertexAttachment_computeWorldVertices(&mesh->super, sp_slot, 0, num_floats, tform_buf, 0, tform_buf_stride);
|
|
|
+ vertices = tform_buf;
|
|
|
+ indices = mesh->triangles;
|
|
|
+ num_indices = mesh->trianglesCount; // actually indicesCount???
|
|
|
+ uvs = mesh->uvs;
|
|
|
+ const spAtlasPage* sp_page = ((spAtlasRegion*)mesh->rendererObject)->page;
|
|
|
+ img.id = (uint32_t)(uintptr_t)sp_page->rendererObject;
|
|
|
+ premul_alpha = sp_page->pma != 0;
|
|
|
+ }
|
|
|
+ else if (sp_slot->attachment->type == SP_ATTACHMENT_CLIPPING) {
|
|
|
+ spClippingAttachment* clip_attachment = (spClippingAttachment*) sp_slot->attachment;
|
|
|
+ spSkeletonClipping_clipStart(sp_clip, sp_slot, clip_attachment);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ spSkeletonClipping_clipEnd(sp_clip, sp_slot);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ SOKOL_ASSERT(vertices && (num_vertices > 0));
|
|
|
+ SOKOL_ASSERT(indices && (num_indices > 0));
|
|
|
+ SOKOL_ASSERT(uvs);
|
|
|
+ SOKOL_ASSERT(img.id != SG_INVALID_ID);
|
|
|
+
|
|
|
+ if (spSkeletonClipping_isClipping(sp_clip)) {
|
|
|
+ spSkeletonClipping_clipTriangles(sp_clip, tform_buf, num_vertices * 2, (uint16_t*)indices, num_indices, uvs, tform_buf_stride);
|
|
|
+ vertices = sp_clip->clippedVertices->items;
|
|
|
+ num_vertices = sp_clip->clippedVertices->size / 2;
|
|
|
+ uvs = sp_clip->clippedUVs->items;
|
|
|
+ indices = sp_clip->clippedTriangles->items;
|
|
|
+ num_indices = sp_clip->clippedTriangles->size;
|
|
|
+ }
|
|
|
+ SOKOL_ASSERT(vertices);
|
|
|
+ SOKOL_ASSERT(indices);
|
|
|
+ SOKOL_ASSERT(uvs);
|
|
|
+ SOKOL_ASSERT(img.id != SG_INVALID_ID);
|
|
|
+
|
|
|
+ // there might be no geometry to render after clipping
|
|
|
+ if ((0 == num_vertices) || (0 == num_indices)) {
|
|
|
+ spSkeletonClipping_clipEnd(sp_clip, sp_slot);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ const _sspine_alloc_vertices_result_t dst_vertices = _sspine_alloc_vertices(ctx, num_vertices);
|
|
|
+ const _sspine_alloc_indices_result_t dst_indices = _sspine_alloc_indices(ctx, num_indices);
|
|
|
+ if ((0 == dst_vertices.ptr) || (0 == dst_indices.ptr)) {
|
|
|
+ spSkeletonClipping_clipEnd(sp_clip, sp_slot);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // write transformed and potentially clipped vertices and indices
|
|
|
+ const uint8_t r = (uint8_t)(sp_skel->color.r * sp_slot->color.r * att_color->r * 255.0f);
|
|
|
+ const uint8_t g = (uint8_t)(sp_skel->color.g * sp_slot->color.g * att_color->g * 255.0f);
|
|
|
+ const uint8_t b = (uint8_t)(sp_skel->color.b * sp_slot->color.b * att_color->b * 255.0f);
|
|
|
+ const uint8_t a = (uint8_t)(sp_skel->color.a * sp_slot->color.a * att_color->a * 255.0f);
|
|
|
+ const uint32_t color = (((uint32_t)a<<24) | ((uint32_t)b<<16) | ((uint32_t)g<<8) | (uint32_t)r);
|
|
|
+ for (int vi = 0; vi < num_vertices; vi++) {
|
|
|
+ dst_vertices.ptr[vi].pos.x = vertices[vi*2];
|
|
|
+ dst_vertices.ptr[vi].pos.y = vertices[vi*2 + 1];
|
|
|
+ dst_vertices.ptr[vi].color = color;
|
|
|
+ dst_vertices.ptr[vi].uv.x = uvs[vi*2];
|
|
|
+ dst_vertices.ptr[vi].uv.y = uvs[vi*2 + 1];
|
|
|
+ }
|
|
|
+ for (int ii = 0; ii < num_indices; ii++) {
|
|
|
+ dst_indices.ptr[ii] = (uint32_t)indices[ii] + (uint32_t)dst_vertices.index;
|
|
|
+ }
|
|
|
+
|
|
|
+ sg_pipeline pip = { SG_INVALID_ID };
|
|
|
+ // NOTE: pma == 0.0: use color from texture as is
|
|
|
+ // pma == 1.0: multiply texture rgb by texture alpha in fragment shader
|
|
|
+ float pma = 0.0f;
|
|
|
+ switch (sp_slot->data->blendMode) {
|
|
|
+ case SP_BLEND_MODE_NORMAL:
|
|
|
+ case SP_BLEND_MODE_ADDITIVE:
|
|
|
+ case SP_BLEND_MODE_SCREEN:
|
|
|
+ pip = ctx->pip.normal_additive;
|
|
|
+ pma = premul_alpha ? 0.0f : 1.0f; // NOT A BUG
|
|
|
+ break;
|
|
|
+ case SP_BLEND_MODE_MULTIPLY:
|
|
|
+ pip = ctx->pip.multiply;
|
|
|
+ pma = 0.0f; // always use texture color as is
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ // write new draw command, or merge with previous draw command
|
|
|
+ _sspine_command_t* prev_cmd = _sspine_prev_command(ctx);
|
|
|
+ if (prev_cmd && (prev_cmd->layer == layer) && (prev_cmd->pip.id == pip.id) && (prev_cmd->img.id == img.id) && (prev_cmd->pma == pma)) {
|
|
|
+ // merge with previous command
|
|
|
+ prev_cmd->num_elements += num_indices;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ // record a new command
|
|
|
+ _sspine_command_t* cmd_ptr = _sspine_next_command(ctx);
|
|
|
+ if (cmd_ptr) {
|
|
|
+ cmd_ptr->layer = layer;
|
|
|
+ cmd_ptr->pip = pip;
|
|
|
+ cmd_ptr->img = img;
|
|
|
+ cmd_ptr->pma = pma;
|
|
|
+ cmd_ptr->base_element = dst_indices.index;
|
|
|
+ cmd_ptr->num_elements = num_indices;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ spSkeletonClipping_clipEnd(sp_clip, sp_slot);
|
|
|
+ }
|
|
|
+ spSkeletonClipping_clipEnd2(sp_clip);
|
|
|
+}
|
|
|
+
|
|
|
+// compute orthographic projection matrix
|
|
|
+static void _sspine_layer_transform_to_proj(const sspine_layer_transform* tform, float* res) {
|
|
|
+ const float left = -tform->origin.x;
|
|
|
+ const float right = tform->size.x - tform->origin.x;
|
|
|
+ const float top = -tform->origin.y;
|
|
|
+ const float bottom = tform->size.y - tform->origin.y;
|
|
|
+ const float znear = -1.0f;
|
|
|
+ const float zfar = 1.0f;
|
|
|
+ res[0] = 2.0f / (right - left);
|
|
|
+ res[1] = 0.0f;
|
|
|
+ res[2] = 0.0f;
|
|
|
+ res[3] = 0.0f;
|
|
|
+ res[4] = 0.0f;
|
|
|
+ res[5] = 2.0f / (top - bottom);
|
|
|
+ res[6] = 0.0f;
|
|
|
+ res[7] = 0.0f;
|
|
|
+ res[8] = 0.0f;
|
|
|
+ res[9] = 0.0f;
|
|
|
+ res[10] = -2.0f / (zfar - znear);
|
|
|
+ res[11] = 0.0f;
|
|
|
+ res[12] = -(right + left) / (right - left);
|
|
|
+ res[13] = -(top + bottom) / (top - bottom);
|
|
|
+ res[14] = -(zfar + znear) / (zfar - znear);
|
|
|
+ res[15] = 1.0f;
|
|
|
+}
|
|
|
+
|
|
|
+static _sspine_vsparams_t _sspine_compute_vsparams(const sspine_layer_transform* tform) {
|
|
|
+ _sspine_vsparams_t p;
|
|
|
+ _sspine_clear(&p, sizeof(p));
|
|
|
+ _sspine_layer_transform_to_proj(tform, p.mvp);
|
|
|
+ return p;
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_draw_layer(_sspine_context_t* ctx, int layer, const sspine_layer_transform* tform) {
|
|
|
+ if ((ctx->vertices.cur > 0) && (ctx->commands.cur > 0)) {
|
|
|
+ sg_push_debug_group("sokol-spine");
|
|
|
+
|
|
|
+ if (ctx->update_frame_count != _sspine.frame_count) {
|
|
|
+ ctx->update_frame_count = _sspine.frame_count;
|
|
|
+ const sg_range vtx_range = { ctx->vertices.ptr, (size_t)ctx->vertices.cur * sizeof(_sspine_vertex_t) };
|
|
|
+ sg_update_buffer(ctx->vbuf, &vtx_range);
|
|
|
+ const sg_range idx_range = { ctx->indices.ptr, (size_t)ctx->indices.cur * sizeof(uint32_t) };
|
|
|
+ sg_update_buffer(ctx->ibuf, &idx_range);
|
|
|
+ }
|
|
|
+
|
|
|
+ _sspine_vsparams_t vsparams = _sspine_compute_vsparams(tform);
|
|
|
+ const sg_range vsparams_range = { &vsparams, sizeof(vsparams) };
|
|
|
+ _sspine_fsparams_t fsparams;
|
|
|
+ _sspine_clear(&fsparams, sizeof(fsparams));
|
|
|
+ const sg_range fsparams_range = { &fsparams, sizeof(fsparams) };
|
|
|
+
|
|
|
+ uint32_t cur_pip_id = SG_INVALID_ID;
|
|
|
+ uint32_t cur_img_id = SG_INVALID_ID;
|
|
|
+ float cur_pma = -1.0f;
|
|
|
+ for (int i = 0; i < ctx->commands.cur; i++) {
|
|
|
+ const _sspine_command_t* cmd = &ctx->commands.ptr[i];
|
|
|
+ if ((layer == cmd->layer) && (sg_query_image_state(cmd->img) == SG_RESOURCESTATE_VALID)) {
|
|
|
+ if (cur_pip_id != cmd->pip.id) {
|
|
|
+ sg_apply_pipeline(cmd->pip);
|
|
|
+ cur_pip_id = cmd->pip.id;
|
|
|
+ sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, &vsparams_range);
|
|
|
+ cur_img_id = SG_INVALID_ID;
|
|
|
+ }
|
|
|
+ if (cur_img_id != cmd->img.id) {
|
|
|
+ ctx->bind.fs_images[0] = cmd->img;
|
|
|
+ sg_apply_bindings(&ctx->bind);
|
|
|
+ cur_img_id = cmd->img.id;
|
|
|
+ }
|
|
|
+ if (cur_pma != cmd->pma) {
|
|
|
+ fsparams.pma = cmd->pma;
|
|
|
+ sg_apply_uniforms(SG_SHADERSTAGE_FS, 0, &fsparams_range);
|
|
|
+ cur_pma = cmd->pma;
|
|
|
+ }
|
|
|
+ if (cmd->num_elements > 0) {
|
|
|
+ sg_draw(cmd->base_element, cmd->num_elements, 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ sg_pop_debug_group();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_init_shared(void) {
|
|
|
+ sg_shader_desc shd_desc;
|
|
|
+ _sspine_clear(&shd_desc, sizeof(shd_desc));
|
|
|
+ shd_desc.attrs[0].name = "position";
|
|
|
+ shd_desc.attrs[1].name = "texcoord0";
|
|
|
+ shd_desc.attrs[2].name = "color0";
|
|
|
+ shd_desc.attrs[0].sem_name = "TEXCOORD";
|
|
|
+ shd_desc.attrs[0].sem_index = 0;
|
|
|
+ shd_desc.attrs[1].sem_name = "TEXCOORD";
|
|
|
+ shd_desc.attrs[1].sem_index = 1;
|
|
|
+ shd_desc.attrs[2].sem_name = "TEXCOORD";
|
|
|
+ shd_desc.attrs[2].sem_index = 2;
|
|
|
+ shd_desc.vs.uniform_blocks[0].size = sizeof(_sspine_vsparams_t);
|
|
|
+ shd_desc.vs.uniform_blocks[0].layout = SG_UNIFORMLAYOUT_STD140;
|
|
|
+ shd_desc.vs.uniform_blocks[0].uniforms[0].name = "vs_params";
|
|
|
+ shd_desc.vs.uniform_blocks[0].uniforms[0].type = SG_UNIFORMTYPE_FLOAT4;
|
|
|
+ shd_desc.vs.uniform_blocks[0].uniforms[0].array_count = 4;
|
|
|
+ shd_desc.fs.uniform_blocks[0].size = 16;
|
|
|
+ shd_desc.fs.uniform_blocks[0].layout = SG_UNIFORMLAYOUT_STD140;
|
|
|
+ shd_desc.fs.uniform_blocks[0].uniforms[0].name = "fs_params";
|
|
|
+ shd_desc.fs.uniform_blocks[0].uniforms[0].type = SG_UNIFORMTYPE_FLOAT4;
|
|
|
+ shd_desc.fs.uniform_blocks[0].uniforms[0].array_count = 1;
|
|
|
+ shd_desc.fs.images[0].name = "tex";
|
|
|
+ shd_desc.fs.images[0].image_type = SG_IMAGETYPE_2D;
|
|
|
+ shd_desc.fs.images[0].sampler_type = SG_SAMPLERTYPE_FLOAT;
|
|
|
+ shd_desc.label = "sspine-shader";
|
|
|
+ #if defined(SOKOL_GLCORE33)
|
|
|
+ shd_desc.vs.source = _sspine_vs_source_glsl330;
|
|
|
+ shd_desc.fs.source = _sspine_fs_source_glsl330;
|
|
|
+ #elif defined(SOKOL_GLES2) || defined(SOKOL_GLES3)
|
|
|
+ shd_desc.vs.source = _sspine_vs_source_glsl100;
|
|
|
+ shd_desc.fs.source = _sspine_fs_source_glsl100;
|
|
|
+ #elif defined(SOKOL_METAL)
|
|
|
+ shd_desc.vs.entry = "main0";
|
|
|
+ shd_desc.fs.entry = "main0";
|
|
|
+ switch (sg_query_backend()) {
|
|
|
+ case SG_BACKEND_METAL_MACOS:
|
|
|
+ shd_desc.vs.bytecode = SG_RANGE(_sspine_vs_bytecode_metal_macos);
|
|
|
+ shd_desc.fs.bytecode = SG_RANGE(_sspine_fs_bytecode_metal_macos);
|
|
|
+ break;
|
|
|
+ case SG_BACKEND_METAL_IOS:
|
|
|
+ //FIXME
|
|
|
+ //shd_desc.vs.bytecode = SG_RANGE(_sspine_vs_bytecode_metal_ios);
|
|
|
+ //shd_desc.fs.bytecode = SG_RANGE(_sspine_fs_bytecode_metal_ios);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ // FIXME
|
|
|
+ //shd_desc.vs.source = _sspine_vs_source_metal_sim;
|
|
|
+ //shd_desc.fs.source = _sspine_fs_source_metal_sim;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ #elif defined(SOKOL_D3D11)
|
|
|
+ shd_desc.vs.bytecode = SG_RANGE(_sspine_vs_bytecode_hlsl4);
|
|
|
+ shd_desc.fs.bytecode = SG_RANGE(_sspine_fs_bytecode_hlsl4);
|
|
|
+ #elif defined(SOKOL_WGPU)
|
|
|
+ shd_desc.vs.bytecode = SG_RANGE(_sspine_vs_bytecode_wgpu);
|
|
|
+ shd_desc.fs.bytecode = SG_RANGE(_sspine_fs_bytecode_wgpu);
|
|
|
+ #else
|
|
|
+ shd_desc.vs.source = _sspine_vs_source_dummy;
|
|
|
+ shd_desc.fs.source = _sspine_fs_source_dummy;
|
|
|
+ #endif
|
|
|
+ _sspine.shd = sg_make_shader(&shd_desc);
|
|
|
+}
|
|
|
+
|
|
|
+static void _sspine_destroy_shared(void) {
|
|
|
+ sg_destroy_shader(_sspine.shd);
|
|
|
+}
|
|
|
+
|
|
|
+//== PUBLIC FUNCTIONS ==========================================================
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_setup(const sspine_desc* desc) {
|
|
|
+ SOKOL_ASSERT(desc);
|
|
|
+ spBone_setYDown(1);
|
|
|
+ _sspine_clear(&_sspine, sizeof(_sspine));
|
|
|
+ _sspine.init_cookie = _SSPINE_INIT_COOKIE;
|
|
|
+ _sspine.desc = _sspine_desc_defaults(desc);
|
|
|
+ _sspine_init_shared();
|
|
|
+ _sspine_setup_context_pool(_sspine.desc.context_pool_size);
|
|
|
+ _sspine_setup_atlas_pool(_sspine.desc.atlas_pool_size);
|
|
|
+ _sspine_setup_skeleton_pool(_sspine.desc.skeleton_pool_size);
|
|
|
+ _sspine_setup_skinset_pool(_sspine.desc.skinset_pool_size);
|
|
|
+ _sspine_setup_instance_pool(_sspine.desc.instance_pool_size);
|
|
|
+ const sspine_context_desc ctx_desc = _sspine_as_context_desc(&_sspine.desc);
|
|
|
+ _sspine.def_ctx_id = sspine_make_context(&ctx_desc);
|
|
|
+ SOKOL_ASSERT(_sspine_is_default_context(_sspine.def_ctx_id));
|
|
|
+ sspine_set_context(_sspine.def_ctx_id);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_shutdown(void) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_destroy_all_instances();
|
|
|
+ _sspine_destroy_all_skinsets();
|
|
|
+ _sspine_destroy_all_skeletons();
|
|
|
+ _sspine_destroy_all_atlases();
|
|
|
+ _sspine_destroy_all_contexts();
|
|
|
+ _sspine_discard_instance_pool();
|
|
|
+ _sspine_discard_skinset_pool();
|
|
|
+ _sspine_discard_skeleton_pool();
|
|
|
+ _sspine_discard_atlas_pool();
|
|
|
+ _sspine_discard_context_pool();
|
|
|
+ _sspine_destroy_shared();
|
|
|
+ _sspine.init_cookie = 0;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_context sspine_make_context(const sspine_context_desc* desc) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ SOKOL_ASSERT(desc);
|
|
|
+ const sspine_context_desc desc_def = _sspine_context_desc_defaults(desc);
|
|
|
+ sspine_context ctx_id = _sspine_alloc_context();
|
|
|
+ _sspine_context_t* ctx = _sspine_lookup_context(ctx_id.id);
|
|
|
+ if (ctx) {
|
|
|
+ ctx->slot.state = _sspine_init_context(ctx, &desc_def);
|
|
|
+ SOKOL_ASSERT((ctx->slot.state == SSPINE_RESOURCESTATE_VALID) || (ctx->slot.state == SSPINE_RESOURCESTATE_FAILED));
|
|
|
+ if (ctx->slot.state == SSPINE_RESOURCESTATE_FAILED) {
|
|
|
+ _sspine_deinit_context(ctx);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ ctx->slot.state = SSPINE_RESOURCESTATE_FAILED;
|
|
|
+ _SSPINE_ERROR(CONTEXT_POOL_EXHAUSTED);
|
|
|
+ }
|
|
|
+ return ctx_id;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_destroy_context(sspine_context ctx_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ if (_sspine_is_default_context(ctx_id)) {
|
|
|
+ _SSPINE_ERROR(CANNOT_DESTROY_DEFAULT_CONTEXT);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ _sspine_destroy_context(ctx_id);
|
|
|
+ // re-validate the current context pointer (this will return a nullptr
|
|
|
+ // if we just destroyed the current context)
|
|
|
+ _sspine.cur_ctx = _sspine_lookup_context(_sspine.cur_ctx_id.id);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_set_context(sspine_context ctx_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ if (_sspine_is_default_context(ctx_id)) {
|
|
|
+ _sspine.cur_ctx_id = _sspine.def_ctx_id;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ _sspine.cur_ctx_id = ctx_id;
|
|
|
+ }
|
|
|
+ // this will return null if the handle isn't valid
|
|
|
+ _sspine.cur_ctx = _sspine_lookup_context(_sspine.cur_ctx_id.id);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_context sspine_get_context(void) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ return _sspine.cur_ctx_id;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_context sspine_default_context(void) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ return _sspine_make_context_handle(0x00010001);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_context_info sspine_get_context_info(sspine_context ctx_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ sspine_context_info res;
|
|
|
+ _sspine_clear(&res, sizeof(res));
|
|
|
+ const _sspine_context_t* ctx = _sspine_lookup_context(ctx_id.id);
|
|
|
+ if (ctx) {
|
|
|
+ res.num_vertices = ctx->vertices.cur;
|
|
|
+ res.num_indices = ctx->indices.cur;
|
|
|
+ res.num_commands = ctx->commands.cur;
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_new_frame(void) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine.frame_count++;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_set_skinset(sspine_instance instance_id, sspine_skinset skinset_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
|
|
|
+ _sspine_skinset_t* skinset = _sspine_lookup_skinset(skinset_id.id);
|
|
|
+ if (_sspine_instance_and_deps_valid(instance) && _sspine_skinset_and_deps_valid(skinset) && (instance->skel.id == skinset->skel.id)) {
|
|
|
+ SOKOL_ASSERT(instance->sp_skel);
|
|
|
+ SOKOL_ASSERT(instance->sp_anim_state);
|
|
|
+ SOKOL_ASSERT(skinset->sp_skin);
|
|
|
+ spSkeleton_setSkin(instance->sp_skel, 0);
|
|
|
+ spSkeleton_setSkin(instance->sp_skel, skinset->sp_skin);
|
|
|
+ spSkeleton_setSlotsToSetupPose(instance->sp_skel);
|
|
|
+ spAnimationState_apply(instance->sp_anim_state, instance->sp_skel);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_update_instance(sspine_instance instance_id, float delta_time) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
|
|
|
+ if (_sspine_instance_and_deps_valid(instance)) {
|
|
|
+ SOKOL_ASSERT(instance->sp_skel);
|
|
|
+ SOKOL_ASSERT(instance->sp_anim_state);
|
|
|
+ _sspine_rewind_triggered_events(instance);
|
|
|
+ spAnimationState_update(instance->sp_anim_state, delta_time);
|
|
|
+ spAnimationState_apply(instance->sp_anim_state, instance->sp_skel);
|
|
|
+ spSkeleton_updateWorldTransform(instance->sp_skel);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL int sspine_num_triggered_events(sspine_instance instance_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
|
|
|
+ if (_sspine_instance_and_deps_valid(instance)) {
|
|
|
+ SOKOL_ASSERT((instance->cur_triggered_event_index >= 0) && (instance->cur_triggered_event_index <= _SSPINE_MAX_TRIGGERED_EVENTS));
|
|
|
+ return instance->cur_triggered_event_index;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_triggered_event_info sspine_get_triggered_event_info(sspine_instance instance_id, int triggered_event_index) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
|
|
|
+ sspine_triggered_event_info res;
|
|
|
+ _sspine_clear(&res, sizeof(res));
|
|
|
+ if (_sspine_instance_and_deps_valid(instance)) {
|
|
|
+ if ((triggered_event_index >= 0) && (triggered_event_index < instance->cur_triggered_event_index)) {
|
|
|
+ res = instance->triggered_events[triggered_event_index];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_draw_instance_in_layer(sspine_instance instance_id, int layer) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_context_t* ctx = _sspine.cur_ctx;
|
|
|
+ _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
|
|
|
+ if (ctx && _sspine_instance_and_deps_valid(instance)) {
|
|
|
+ _sspine_draw_instance(ctx, instance, layer);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_mat4 sspine_layer_transform_to_mat4(const sspine_layer_transform* tform) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ sspine_mat4 res;
|
|
|
+ _sspine_layer_transform_to_proj(tform, res.m);
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_context_draw_instance_in_layer(sspine_context ctx_id, sspine_instance instance_id, int layer) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_context_t* ctx = _sspine_lookup_context(ctx_id.id);
|
|
|
+ _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
|
|
|
+ if (ctx && _sspine_instance_and_deps_valid(instance)) {
|
|
|
+ _sspine_draw_instance(ctx, instance, layer);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_draw_layer(int layer, const sspine_layer_transform* tform) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ SOKOL_ASSERT(tform);
|
|
|
+ _sspine_context_t* ctx = _sspine.cur_ctx;
|
|
|
+ if (ctx) {
|
|
|
+ _sspine_draw_layer(ctx, layer, tform);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_context_draw_layer(sspine_context ctx_id, int layer, const sspine_layer_transform* tform) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ SOKOL_ASSERT(tform);
|
|
|
+ _sspine_context_t* ctx = _sspine_lookup_context(ctx_id.id);
|
|
|
+ if (ctx) {
|
|
|
+ _sspine_draw_layer(ctx, layer, tform);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_atlas sspine_make_atlas(const sspine_atlas_desc* desc) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ SOKOL_ASSERT(desc);
|
|
|
+ const sspine_atlas_desc desc_def = _sspine_atlas_desc_defaults(desc);
|
|
|
+ sspine_atlas atlas_id = _sspine_alloc_atlas();
|
|
|
+ _sspine_atlas_t* atlas = _sspine_lookup_atlas(atlas_id.id);
|
|
|
+ if (atlas) {
|
|
|
+ atlas->slot.state = _sspine_init_atlas(atlas, &desc_def);
|
|
|
+ SOKOL_ASSERT((atlas->slot.state == SSPINE_RESOURCESTATE_VALID) || (atlas->slot.state == SSPINE_RESOURCESTATE_FAILED));
|
|
|
+ if (atlas->slot.state == SSPINE_RESOURCESTATE_FAILED) {
|
|
|
+ _sspine_deinit_atlas(atlas);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ _SSPINE_ERROR(ATLAS_POOL_EXHAUSTED);
|
|
|
+ }
|
|
|
+ return atlas_id;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_destroy_atlas(sspine_atlas atlas_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_destroy_atlas(atlas_id);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_skeleton sspine_make_skeleton(const sspine_skeleton_desc* desc) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ SOKOL_ASSERT(desc);
|
|
|
+ const sspine_skeleton_desc desc_def = _sspine_skeleton_desc_defaults(desc);
|
|
|
+ sspine_skeleton skeleton_id = _sspine_alloc_skeleton();
|
|
|
+ _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
|
|
|
+ if (skeleton) {
|
|
|
+ skeleton->slot.state = _sspine_init_skeleton(skeleton, &desc_def);
|
|
|
+ SOKOL_ASSERT((skeleton->slot.state == SSPINE_RESOURCESTATE_VALID) || (skeleton->slot.state == SSPINE_RESOURCESTATE_FAILED));
|
|
|
+ if (skeleton->slot.state == SSPINE_RESOURCESTATE_FAILED) {
|
|
|
+ _sspine_deinit_skeleton(skeleton);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ _SSPINE_ERROR(SKELETON_POOL_EXHAUSTED);
|
|
|
+ }
|
|
|
+ return skeleton_id;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_destroy_skeleton(sspine_skeleton skeleton_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_destroy_skeleton(skeleton_id);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_skinset sspine_make_skinset(const sspine_skinset_desc* desc) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ SOKOL_ASSERT(desc);
|
|
|
+ const sspine_skinset_desc desc_def = _sspine_skinset_desc_defaults(desc);
|
|
|
+ sspine_skinset skinset_id = _sspine_alloc_skinset();
|
|
|
+ _sspine_skinset_t* skinset = _sspine_lookup_skinset(skinset_id.id);
|
|
|
+ if (skinset) {
|
|
|
+ skinset->slot.state = _sspine_init_skinset(skinset, &desc_def);
|
|
|
+ SOKOL_ASSERT((skinset->slot.state == SSPINE_RESOURCESTATE_VALID) || (skinset->slot.state == SSPINE_RESOURCESTATE_FAILED));
|
|
|
+ if (skinset->slot.state == SSPINE_RESOURCESTATE_FAILED) {
|
|
|
+ _sspine_deinit_skinset(skinset);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ _SSPINE_ERROR(SKINSET_POOL_EXHAUSTED);
|
|
|
+ }
|
|
|
+ return skinset_id;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_destroy_skinset(sspine_skinset skinset_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_destroy_skinset(skinset_id);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_instance sspine_make_instance(const sspine_instance_desc* desc) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ SOKOL_ASSERT(desc);
|
|
|
+ const sspine_instance_desc desc_def = _sspine_instance_desc_defaults(desc);
|
|
|
+ sspine_instance instance_id = _sspine_alloc_instance();
|
|
|
+ _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
|
|
|
+ if (instance) {
|
|
|
+ instance->slot.state = _sspine_init_instance(instance, &desc_def);
|
|
|
+ SOKOL_ASSERT((instance->slot.state == SSPINE_RESOURCESTATE_VALID) || (instance->slot.state == SSPINE_RESOURCESTATE_FAILED));
|
|
|
+ if (instance->slot.state == SSPINE_RESOURCESTATE_FAILED) {
|
|
|
+ _sspine_deinit_instance(instance);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ _SSPINE_ERROR(INSTANCE_POOL_EXHAUSTED);
|
|
|
+ }
|
|
|
+ return instance_id;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_destroy_instance(sspine_instance instance_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_destroy_instance(instance_id);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_resource_state sspine_get_context_resource_state(sspine_context ctx_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ const _sspine_context_t* ctx = _sspine_lookup_context(ctx_id.id);
|
|
|
+ if (ctx) {
|
|
|
+ return ctx->slot.state;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ return SSPINE_RESOURCESTATE_INVALID;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_resource_state sspine_get_atlas_resource_state(sspine_atlas atlas_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ const _sspine_atlas_t* atlas = _sspine_lookup_atlas(atlas_id.id);
|
|
|
+ if (atlas) {
|
|
|
+ return atlas->slot.state;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ return SSPINE_RESOURCESTATE_INVALID;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_resource_state sspine_get_skeleton_resource_state(sspine_skeleton skeleton_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ const _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
|
|
|
+ if (skeleton) {
|
|
|
+ return skeleton->slot.state;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ return SSPINE_RESOURCESTATE_INVALID;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_resource_state sspine_get_skinset_resource_state(sspine_skinset skinset_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ const _sspine_skinset_t* skinset = _sspine_lookup_skinset(skinset_id.id);
|
|
|
+ if (skinset) {
|
|
|
+ return skinset->slot.state;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ return SSPINE_RESOURCESTATE_INVALID;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_resource_state sspine_get_instance_resource_state(sspine_instance instance_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ const _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
|
|
|
+ if (instance) {
|
|
|
+ return instance->slot.state;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ return SSPINE_RESOURCESTATE_INVALID;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL bool sspine_context_valid(sspine_context ctx_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ return sspine_get_context_resource_state(ctx_id) == SSPINE_RESOURCESTATE_VALID;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL bool sspine_atlas_valid(sspine_atlas atlas_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ return sspine_get_atlas_resource_state(atlas_id) == SSPINE_RESOURCESTATE_VALID;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL bool sspine_skeleton_valid(sspine_skeleton skeleton_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ return sspine_get_skeleton_resource_state(skeleton_id) == SSPINE_RESOURCESTATE_VALID;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL bool sspine_skinset_valid(sspine_skinset skinset_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ return sspine_get_skinset_resource_state(skinset_id) == SSPINE_RESOURCESTATE_VALID;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL bool sspine_instance_valid(sspine_instance instance_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ return sspine_get_instance_resource_state(instance_id) == SSPINE_RESOURCESTATE_VALID;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_atlas sspine_get_skeleton_atlas(sspine_skeleton skeleton_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
|
|
|
+ sspine_atlas res;
|
|
|
+ _sspine_clear(&res, sizeof(res));
|
|
|
+ if (skeleton) {
|
|
|
+ res.id = skeleton->atlas.id;
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_skeleton sspine_get_instance_skeleton(sspine_instance instance_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
|
|
|
+ sspine_skeleton res;
|
|
|
+ _sspine_clear(&res, sizeof(res));
|
|
|
+ if (instance) {
|
|
|
+ res.id = instance->skel.id;
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL int sspine_num_images(sspine_atlas atlas_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_atlas_t* atlas = _sspine_lookup_atlas(atlas_id.id);
|
|
|
+ if (atlas) {
|
|
|
+ return atlas->num_pages;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_image sspine_image_by_index(sspine_atlas atlas_id, int index) {
|
|
|
+ return _sspine_image(atlas_id.id, index);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL bool sspine_image_valid(sspine_image image) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_atlas_t* atlas = _sspine_lookup_atlas(image.atlas_id);
|
|
|
+ return atlas && (image.index >= 0) && (image.index < atlas->num_pages);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL bool sspine_image_equal(sspine_image first, sspine_image second) {
|
|
|
+ return (first.atlas_id == second.atlas_id) && (first.index == second.index);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_image_info sspine_get_image_info(sspine_image image) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_atlas_t* atlas = _sspine_lookup_atlas(image.atlas_id);
|
|
|
+ sspine_image_info img_info;
|
|
|
+ _sspine_clear(&img_info, sizeof(img_info));
|
|
|
+ if (atlas && (image.index >= 0) && (image.index < atlas->num_pages)) {
|
|
|
+ _sspine_init_image_info(atlas, image.index, &img_info, true);
|
|
|
+ }
|
|
|
+ return img_info;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL int sspine_num_atlas_pages(sspine_atlas atlas_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_atlas_t* atlas = _sspine_lookup_atlas(atlas_id.id);
|
|
|
+ if (atlas) {
|
|
|
+ return atlas->num_pages;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_atlas_page sspine_atlas_page_by_index(sspine_atlas atlas_id, int index) {
|
|
|
+ return _sspine_atlas_page(atlas_id.id, index);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL bool sspine_atlas_page_valid(sspine_atlas_page page) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_atlas_t* atlas = _sspine_lookup_atlas(page.atlas_id);
|
|
|
+ if (atlas) {
|
|
|
+ return (page.index >= 0) && (page.index < atlas->num_pages);
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL bool sspine_atlas_page_equal(sspine_atlas_page first, sspine_atlas_page second) {
|
|
|
+ return (first.atlas_id == second.atlas_id) && (first.index == second.index);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_atlas_page_info sspine_get_atlas_page_info(sspine_atlas_page page) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ sspine_atlas_page_info res;
|
|
|
+ _sspine_clear(&res, sizeof(res));
|
|
|
+ const spAtlasPage* sp_page = _sspine_lookup_atlas_page(page.atlas_id, page.index);
|
|
|
+ if (sp_page) {
|
|
|
+ // at this point, atlas is guaranteed to be valid
|
|
|
+ const _sspine_atlas_t* atlas = _sspine_lookup_atlas(page.atlas_id);
|
|
|
+ res.valid = true;
|
|
|
+ res.atlas.id = page.atlas_id;
|
|
|
+ // write image info without overrides
|
|
|
+ _sspine_init_image_info(atlas, page.index, &res.image, false);
|
|
|
+ // ...and provide the overrides separately
|
|
|
+ res.overrides = atlas->overrides;
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_set_position(sspine_instance instance_id, sspine_vec2 position) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
|
|
|
+ if (_sspine_instance_and_deps_valid(instance)) {
|
|
|
+ SOKOL_ASSERT(instance->sp_skel);
|
|
|
+ instance->sp_skel->x = position.x;
|
|
|
+ instance->sp_skel->y = position.y;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_set_scale(sspine_instance instance_id, sspine_vec2 scale) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
|
|
|
+ if (instance) {
|
|
|
+ SOKOL_ASSERT(instance->sp_skel);
|
|
|
+ instance->sp_skel->scaleX = scale.x;
|
|
|
+ instance->sp_skel->scaleY = scale.y;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_set_color(sspine_instance instance_id, sspine_color color) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
|
|
|
+ if (instance) {
|
|
|
+ SOKOL_ASSERT(instance->sp_skel);
|
|
|
+ instance->sp_skel->color.r = color.r;
|
|
|
+ instance->sp_skel->color.g = color.g;
|
|
|
+ instance->sp_skel->color.b = color.b;
|
|
|
+ instance->sp_skel->color.a = color.a;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_vec2 sspine_get_position(sspine_instance instance_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
|
|
|
+ sspine_vec2 v = { 0.0f, 0.0f };
|
|
|
+ if (instance) {
|
|
|
+ SOKOL_ASSERT(instance->sp_skel);
|
|
|
+ v.x = instance->sp_skel->x;
|
|
|
+ v.y = instance->sp_skel->y;
|
|
|
+ }
|
|
|
+ return v;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_vec2 sspine_get_scale(sspine_instance instance_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
|
|
|
+ sspine_vec2 v = { 0.0f, 0.0f };
|
|
|
+ if (instance) {
|
|
|
+ SOKOL_ASSERT(instance->sp_skel);
|
|
|
+ v.x = instance->sp_skel->scaleX;
|
|
|
+ v.y = instance->sp_skel->scaleY;
|
|
|
+ }
|
|
|
+ return v;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_color sspine_get_color(sspine_instance instance_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
|
|
|
+ sspine_color c = { 0.0f, 0.0f, 0.0f, 0.0f };
|
|
|
+ if (instance) {
|
|
|
+ SOKOL_ASSERT(instance->sp_skel);
|
|
|
+ c.r = instance->sp_skel->color.r;
|
|
|
+ c.g = instance->sp_skel->color.g;
|
|
|
+ c.b = instance->sp_skel->color.b;
|
|
|
+ c.a = instance->sp_skel->color.a;
|
|
|
+ }
|
|
|
+ return c;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL int sspine_num_anims(sspine_skeleton skeleton_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
|
|
|
+ if (_sspine_skeleton_and_deps_valid(skeleton)) {
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data);
|
|
|
+ return skeleton->sp_skel_data->animationsCount;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_anim sspine_anim_by_name(sspine_skeleton skeleton_id, const char* name) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ SOKOL_ASSERT(name);
|
|
|
+ _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
|
|
|
+ if (_sspine_skeleton_and_deps_valid(skeleton)) {
|
|
|
+ // NOTE: there's a spSkeletonData_findAnimation function, but that doesn't
|
|
|
+ // give us access to the index, so we'll need to do the loop ourselves
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data);
|
|
|
+ const spSkeletonData* sp_skel_data = skeleton->sp_skel_data;
|
|
|
+ const int num_anims = sp_skel_data->animationsCount;
|
|
|
+ SOKOL_ASSERT(sp_skel_data->animations);
|
|
|
+ for (int i = 0; i < num_anims; i++) {
|
|
|
+ SOKOL_ASSERT(sp_skel_data->animations[i]);
|
|
|
+ SOKOL_ASSERT(sp_skel_data->animations[i]->name);
|
|
|
+ if (0 == strcmp(sp_skel_data->animations[i]->name, name)) {
|
|
|
+ return _sspine_anim(skeleton_id.id, i);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return _sspine_anim(0, 0);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_anim sspine_anim_by_index(sspine_skeleton skeleton_id, int index) {
|
|
|
+ return _sspine_anim(skeleton_id.id, index);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL bool sspine_anim_valid(sspine_anim anim) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(anim.skeleton_id);
|
|
|
+ if (_sspine_skeleton_and_deps_valid(skeleton)) {
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data);
|
|
|
+ return (anim.index >= 0) && (anim.index < skeleton->sp_skel_data->animationsCount);
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL bool sspine_anim_equal(sspine_anim first, sspine_anim second) {
|
|
|
+ return (first.skeleton_id == second.skeleton_id) && (first.index == second.index);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_anim_info sspine_get_anim_info(sspine_anim anim) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ sspine_anim_info res;
|
|
|
+ _sspine_clear(&res, sizeof(res));
|
|
|
+ const spAnimation* sp_anim = _sspine_lookup_skeleton_anim(anim.skeleton_id, anim.index);
|
|
|
+ if (sp_anim) {
|
|
|
+ res.valid = true;
|
|
|
+ res.index = anim.index;
|
|
|
+ res.duration = sp_anim->duration;
|
|
|
+ res.name = _sspine_string(sp_anim->name);
|
|
|
+ if (res.name.truncated) {
|
|
|
+ _SSPINE_WARN(STRING_TRUNCATED);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_clear_animation_tracks(sspine_instance instance_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
|
|
|
+ if (_sspine_instance_and_deps_valid(instance)) {
|
|
|
+ SOKOL_ASSERT(instance->sp_anim_state);
|
|
|
+ spAnimationState_clearTracks(instance->sp_anim_state);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_clear_animation_track(sspine_instance instance_id, int track_index) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
|
|
|
+ if (_sspine_instance_and_deps_valid(instance)) {
|
|
|
+ SOKOL_ASSERT(instance->sp_anim_state);
|
|
|
+ spAnimationState_clearTrack(instance->sp_anim_state, track_index);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_set_animation(sspine_instance instance_id, sspine_anim anim, int track_index, bool loop) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ spAnimation* sp_anim = _sspine_lookup_instance_anim(instance_id.id, anim.skeleton_id, anim.index);
|
|
|
+ if (sp_anim) {
|
|
|
+ // NOTE: at this point, instance is guaranteed to be valid
|
|
|
+ _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
|
|
|
+ SOKOL_ASSERT(instance);
|
|
|
+ spAnimationState_setAnimation(instance->sp_anim_state, track_index, sp_anim, loop?1:0);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_add_animation(sspine_instance instance_id, sspine_anim anim, int track_index, bool loop, float delay) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ spAnimation* sp_anim = _sspine_lookup_instance_anim(instance_id.id, anim.skeleton_id, anim.index);
|
|
|
+ if (sp_anim) {
|
|
|
+ // NOTE: at this point, instance is guaranteed to be valid
|
|
|
+ _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
|
|
|
+ SOKOL_ASSERT(instance);
|
|
|
+ SOKOL_ASSERT(instance->sp_anim_state);
|
|
|
+ spAnimationState_addAnimation(instance->sp_anim_state, track_index, sp_anim, loop?1:0, delay);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_set_empty_animation(sspine_instance instance_id, int track_index, float mix_duration) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
|
|
|
+ if (_sspine_instance_and_deps_valid(instance)) {
|
|
|
+ SOKOL_ASSERT(instance->sp_anim_state);
|
|
|
+ spAnimationState_setEmptyAnimation(instance->sp_anim_state, track_index, mix_duration);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_add_empty_animation(sspine_instance instance_id, int track_index, float mix_duration, float delay) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
|
|
|
+ if (_sspine_instance_and_deps_valid(instance)) {
|
|
|
+ SOKOL_ASSERT(instance->sp_anim_state);
|
|
|
+ spAnimationState_addEmptyAnimation(instance->sp_anim_state, track_index, mix_duration, delay);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL int sspine_num_bones(sspine_skeleton skeleton_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
|
|
|
+ if (_sspine_skeleton_and_deps_valid(skeleton)) {
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data);
|
|
|
+ return skeleton->sp_skel_data->bonesCount;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_bone sspine_bone_by_name(sspine_skeleton skeleton_id, const char* name) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ SOKOL_ASSERT(name);
|
|
|
+ _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
|
|
|
+ if (_sspine_skeleton_and_deps_valid(skeleton)) {
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data);
|
|
|
+ spBoneData* sp_bone_data = spSkeletonData_findBone(skeleton->sp_skel_data, name);
|
|
|
+ if (sp_bone_data) {
|
|
|
+ return _sspine_bone(skeleton_id.id, sp_bone_data->index);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return _sspine_bone(0, 0);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_bone sspine_bone_by_index(sspine_skeleton skeleton_id, int index) {
|
|
|
+ return _sspine_bone(skeleton_id.id, index);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL bool sspine_bone_valid(sspine_bone bone) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(bone.skeleton_id);
|
|
|
+ if (_sspine_skeleton_and_deps_valid(skeleton)) {
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data);
|
|
|
+ return (bone.index >= 0) && (bone.index < skeleton->sp_skel_data->bonesCount);
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL bool sspine_bone_equal(sspine_bone first, sspine_bone second) {
|
|
|
+ return (first.skeleton_id == second.skeleton_id) && (first.index == second.index);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_bone_info sspine_get_bone_info(sspine_bone bone) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ sspine_bone_info res;
|
|
|
+ _sspine_clear(&res, sizeof(res));
|
|
|
+ const spBoneData* sp_bone_data = _sspine_lookup_bone_data(bone.skeleton_id, bone.index);
|
|
|
+ if (sp_bone_data) {
|
|
|
+ SOKOL_ASSERT(sp_bone_data->index == bone.index);
|
|
|
+ SOKOL_ASSERT(sp_bone_data->name);
|
|
|
+ res.valid = true;
|
|
|
+ res.index = sp_bone_data->index;
|
|
|
+ if (sp_bone_data->parent) {
|
|
|
+ res.parent_bone = _sspine_bone(bone.skeleton_id, sp_bone_data->parent->index);
|
|
|
+ }
|
|
|
+ res.length = sp_bone_data->length;
|
|
|
+ res.pose.position.x = sp_bone_data->x;
|
|
|
+ res.pose.position.y = sp_bone_data->y;
|
|
|
+ res.pose.rotation = sp_bone_data->rotation;
|
|
|
+ res.pose.scale.x = sp_bone_data->scaleX;
|
|
|
+ res.pose.scale.y = sp_bone_data->scaleY;
|
|
|
+ res.pose.shear.x = sp_bone_data->shearX;
|
|
|
+ res.pose.shear.y = sp_bone_data->shearY;
|
|
|
+ res.color.r = sp_bone_data->color.r;
|
|
|
+ res.color.g = sp_bone_data->color.g;
|
|
|
+ res.color.b = sp_bone_data->color.b;
|
|
|
+ res.color.a = sp_bone_data->color.a;
|
|
|
+ res.name = _sspine_string(sp_bone_data->name);
|
|
|
+ if (res.name.truncated) {
|
|
|
+ _SSPINE_WARN(STRING_TRUNCATED);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_set_bone_transform(sspine_instance instance_id, sspine_bone bone, const sspine_bone_transform* transform) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ SOKOL_ASSERT(transform);
|
|
|
+ spBone* sp_bone = _sspine_lookup_bone(instance_id.id, bone.skeleton_id, bone.index);
|
|
|
+ if (sp_bone) {
|
|
|
+ sp_bone->x = transform->position.x;
|
|
|
+ sp_bone->y = transform->position.y;
|
|
|
+ sp_bone->rotation = transform->rotation;
|
|
|
+ sp_bone->scaleX = transform->scale.x;
|
|
|
+ sp_bone->scaleY = transform->scale.y;
|
|
|
+ sp_bone->shearX = transform->shear.x;
|
|
|
+ sp_bone->shearY = transform->shear.y;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_set_bone_position(sspine_instance instance_id, sspine_bone bone, sspine_vec2 position) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ spBone* sp_bone = _sspine_lookup_bone(instance_id.id, bone.skeleton_id, bone.index);
|
|
|
+ if (sp_bone) {
|
|
|
+ sp_bone->x = position.x;
|
|
|
+ sp_bone->y = position.y;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_set_bone_rotation(sspine_instance instance_id, sspine_bone bone, float rotation) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ spBone* sp_bone = _sspine_lookup_bone(instance_id.id, bone.skeleton_id, bone.index);
|
|
|
+ if (sp_bone) {
|
|
|
+ sp_bone->rotation = rotation;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_set_bone_scale(sspine_instance instance_id, sspine_bone bone, sspine_vec2 scale) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ spBone* sp_bone = _sspine_lookup_bone(instance_id.id, bone.skeleton_id, bone.index);
|
|
|
+ if (sp_bone) {
|
|
|
+ sp_bone->scaleX = scale.x;
|
|
|
+ sp_bone->scaleY = scale.y;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_set_bone_shear(sspine_instance instance_id, sspine_bone bone, sspine_vec2 shear) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ spBone* sp_bone = _sspine_lookup_bone(instance_id.id, bone.skeleton_id, bone.index);
|
|
|
+ if (sp_bone) {
|
|
|
+ sp_bone->shearX = shear.x;
|
|
|
+ sp_bone->shearY = shear.y;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_bone_transform sspine_get_bone_transform(sspine_instance instance_id, sspine_bone bone) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ sspine_bone_transform res;
|
|
|
+ _sspine_clear(&res, sizeof(res));
|
|
|
+ spBone* sp_bone = _sspine_lookup_bone(instance_id.id, bone.skeleton_id, bone.index);
|
|
|
+ if (sp_bone) {
|
|
|
+ res.position.x = sp_bone->x;
|
|
|
+ res.position.y = sp_bone->y;
|
|
|
+ res.rotation = sp_bone->rotation;
|
|
|
+ res.scale.x = sp_bone->scaleX;
|
|
|
+ res.scale.y = sp_bone->scaleY;
|
|
|
+ res.shear.x = sp_bone->shearX;
|
|
|
+ res.shear.y = sp_bone->shearY;
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_vec2 sspine_get_bone_position(sspine_instance instance_id, sspine_bone bone) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ sspine_vec2 res;
|
|
|
+ _sspine_clear(&res, sizeof(res));
|
|
|
+ spBone* sp_bone = _sspine_lookup_bone(instance_id.id, bone.skeleton_id, bone.index);
|
|
|
+ if (sp_bone) {
|
|
|
+ res.x = sp_bone->x;
|
|
|
+ res.y = sp_bone->y;
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL float sspine_get_bone_rotation(sspine_instance instance_id, sspine_bone bone) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ spBone* sp_bone = _sspine_lookup_bone(instance_id.id, bone.skeleton_id, bone.index);
|
|
|
+ if (sp_bone) {
|
|
|
+ return sp_bone->rotation;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ return 0.0f;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_vec2 sspine_get_bone_scale(sspine_instance instance_id, sspine_bone bone) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ sspine_vec2 res;
|
|
|
+ _sspine_clear(&res, sizeof(res));
|
|
|
+ spBone* sp_bone = _sspine_lookup_bone(instance_id.id, bone.skeleton_id, bone.index);
|
|
|
+ if (sp_bone) {
|
|
|
+ res.x = sp_bone->scaleX;
|
|
|
+ res.y = sp_bone->scaleY;
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_vec2 sspine_get_bone_shear(sspine_instance instance_id, sspine_bone bone) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ sspine_vec2 res;
|
|
|
+ _sspine_clear(&res, sizeof(res));
|
|
|
+ spBone* sp_bone = _sspine_lookup_bone(instance_id.id, bone.skeleton_id, bone.index);
|
|
|
+ if (sp_bone) {
|
|
|
+ res.x = sp_bone->shearX;
|
|
|
+ res.y = sp_bone->shearY;
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_vec2 sspine_get_bone_world_position(sspine_instance instance_id, sspine_bone bone) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ sspine_vec2 res;
|
|
|
+ _sspine_clear(&res, sizeof(res));
|
|
|
+ spBone* sp_bone = _sspine_lookup_bone(instance_id.id, bone.skeleton_id, bone.index);
|
|
|
+ if (sp_bone) {
|
|
|
+ res.x = sp_bone->worldX;
|
|
|
+ res.y = sp_bone->worldY;
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_vec2 sspine_bone_local_to_world(sspine_instance instance_id, sspine_bone bone, sspine_vec2 local_pos) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ sspine_vec2 res;
|
|
|
+ _sspine_clear(&res, sizeof(res));
|
|
|
+ spBone* sp_bone = _sspine_lookup_bone(instance_id.id, bone.skeleton_id, bone.index);
|
|
|
+ if (sp_bone) {
|
|
|
+ spBone_localToWorld(sp_bone, local_pos.x, local_pos.y, &res.x, &res.y);
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_vec2 sspine_bone_world_to_local(sspine_instance instance_id, sspine_bone bone, sspine_vec2 world_pos) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ sspine_vec2 res;
|
|
|
+ _sspine_clear(&res, sizeof(res));
|
|
|
+ spBone* sp_bone = _sspine_lookup_bone(instance_id.id, bone.skeleton_id, bone.index);
|
|
|
+ if (sp_bone) {
|
|
|
+ spBone_worldToLocal(sp_bone, world_pos.x, world_pos.y, &res.x, &res.y);
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL int sspine_num_slots(sspine_skeleton skeleton_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
|
|
|
+ if (_sspine_skeleton_and_deps_valid(skeleton)) {
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data);
|
|
|
+ return skeleton->sp_skel_data->slotsCount;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_slot sspine_slot_by_name(sspine_skeleton skeleton_id, const char* name) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ SOKOL_ASSERT(name);
|
|
|
+ _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
|
|
|
+ if (_sspine_skeleton_and_deps_valid(skeleton)) {
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data);
|
|
|
+ spSlotData* sp_slot_data = spSkeletonData_findSlot(skeleton->sp_skel_data, name);
|
|
|
+ if (sp_slot_data) {
|
|
|
+ return _sspine_slot(skeleton_id.id, sp_slot_data->index);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return _sspine_slot(0, 0);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_slot sspine_slot_by_index(sspine_skeleton skeleton_id, int index) {
|
|
|
+ return _sspine_slot(skeleton_id.id, index);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL bool sspine_slot_valid(sspine_slot slot) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(slot.skeleton_id);
|
|
|
+ if (_sspine_skeleton_and_deps_valid(skeleton)) {
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data);
|
|
|
+ return (slot.index >= 0) && (slot.index < skeleton->sp_skel_data->slotsCount);
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL bool sspine_slot_equal(sspine_slot first, sspine_slot second) {
|
|
|
+ return (first.skeleton_id == second.skeleton_id) && (first.index == second.index);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_slot_info sspine_get_slot_info(sspine_slot slot) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ sspine_slot_info res;
|
|
|
+ _sspine_clear(&res, sizeof(res));
|
|
|
+ const spSlotData* sp_slot_data = _sspine_lookup_slot_data(slot.skeleton_id, slot.index);
|
|
|
+ if (sp_slot_data) {
|
|
|
+ SOKOL_ASSERT(sp_slot_data->index == slot.index);
|
|
|
+ SOKOL_ASSERT(sp_slot_data->name);
|
|
|
+ SOKOL_ASSERT(sp_slot_data->boneData);
|
|
|
+ res.valid = true;
|
|
|
+ res.index = sp_slot_data->index;
|
|
|
+ res.bone = _sspine_bone(slot.skeleton_id, sp_slot_data->boneData->index);
|
|
|
+ res.color.r = sp_slot_data->color.r;
|
|
|
+ res.color.g = sp_slot_data->color.g;
|
|
|
+ res.color.b = sp_slot_data->color.b;
|
|
|
+ res.color.a = sp_slot_data->color.a;
|
|
|
+ res.attachment_name = _sspine_string(sp_slot_data->attachmentName);
|
|
|
+ if (res.attachment_name.truncated) {
|
|
|
+ _SSPINE_WARN(STRING_TRUNCATED);
|
|
|
+ }
|
|
|
+ res.name = _sspine_string(sp_slot_data->name);
|
|
|
+ if (res.name.truncated) {
|
|
|
+ _SSPINE_WARN(STRING_TRUNCATED);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_set_slot_color(sspine_instance instance_id, sspine_slot slot, sspine_color color) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ spSlot* sp_slot = _sspine_lookup_slot(instance_id.id, slot.skeleton_id, slot.index);
|
|
|
+ if (sp_slot) {
|
|
|
+ sp_slot->color.r = color.r;
|
|
|
+ sp_slot->color.g = color.g;
|
|
|
+ sp_slot->color.b = color.b;
|
|
|
+ sp_slot->color.a = color.a;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_color sspine_get_slot_color(sspine_instance instance_id, sspine_slot slot) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ sspine_color color;
|
|
|
+ _sspine_clear(&color, sizeof(color));
|
|
|
+ spSlot* sp_slot = _sspine_lookup_slot(instance_id.id, slot.skeleton_id, slot.index);
|
|
|
+ if (sp_slot) {
|
|
|
+ color.r = sp_slot->color.r;
|
|
|
+ color.g = sp_slot->color.g;
|
|
|
+ color.b = sp_slot->color.b;
|
|
|
+ color.a = sp_slot->color.a;
|
|
|
+ }
|
|
|
+ return color;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL int sspine_num_events(sspine_skeleton skeleton_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
|
|
|
+ if (_sspine_skeleton_and_deps_valid(skeleton)) {
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data);
|
|
|
+ return skeleton->sp_skel_data->eventsCount;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_event sspine_event_by_name(sspine_skeleton skeleton_id, const char* name) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ SOKOL_ASSERT(name);
|
|
|
+ _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
|
|
|
+ if (_sspine_skeleton_and_deps_valid(skeleton)) {
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data);
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data->events);
|
|
|
+ // spEventData has no embedded index, so we need to loop over the events
|
|
|
+ for (int i = 0; i < skeleton->sp_skel_data->eventsCount; i++) {
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data->events[i]);
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data->events[i]->name);
|
|
|
+ if (0 == strcmp(skeleton->sp_skel_data->events[i]->name, name)) {
|
|
|
+ return _sspine_event(skeleton_id.id, i);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return _sspine_event(0, 0);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_event sspine_event_by_index(sspine_skeleton skeleton_id, int index) {
|
|
|
+ return _sspine_event(skeleton_id.id, index);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL bool sspine_event_valid(sspine_event event) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(event.skeleton_id);
|
|
|
+ if (_sspine_skeleton_and_deps_valid(skeleton)) {
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data);
|
|
|
+ return (event.index >= 0) && (event.index < skeleton->sp_skel_data->eventsCount);
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL bool sspine_event_equal(sspine_event first, sspine_event second) {
|
|
|
+ return (first.skeleton_id == second.skeleton_id) && (first.index == second.index);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_event_info sspine_get_event_info(sspine_event event) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ sspine_event_info res;
|
|
|
+ _sspine_clear(&res, sizeof(res));
|
|
|
+ const spEventData* sp_event_data = _sspine_lookup_event_data(event.skeleton_id, event.index);
|
|
|
+ if (sp_event_data) {
|
|
|
+ res.valid = true;
|
|
|
+ res.index = event.index;
|
|
|
+ res.int_value = sp_event_data->intValue;
|
|
|
+ res.float_value = sp_event_data->floatValue;
|
|
|
+ res.volume = sp_event_data->volume;
|
|
|
+ res.balance = sp_event_data->balance;
|
|
|
+ res.name = _sspine_string(sp_event_data->name);
|
|
|
+ if (res.name.truncated) {
|
|
|
+ _SSPINE_WARN(STRING_TRUNCATED);
|
|
|
+ }
|
|
|
+ res.string_value = _sspine_string(sp_event_data->stringValue);
|
|
|
+ if (res.string_value.truncated) {
|
|
|
+ _SSPINE_WARN(STRING_TRUNCATED);
|
|
|
+ }
|
|
|
+ res.audio_path = _sspine_string(sp_event_data->audioPath);
|
|
|
+ if (res.audio_path.truncated) {
|
|
|
+ _SSPINE_WARN(STRING_TRUNCATED);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL int sspine_num_iktargets(sspine_skeleton skeleton_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
|
|
|
+ if (_sspine_skeleton_and_deps_valid(skeleton)) {
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data);
|
|
|
+ return skeleton->sp_skel_data->ikConstraintsCount;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_iktarget sspine_iktarget_by_name(sspine_skeleton skeleton_id, const char* name) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ SOKOL_ASSERT(name);
|
|
|
+ _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
|
|
|
+ if (_sspine_skeleton_and_deps_valid(skeleton)) {
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data);
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data->ikConstraints);
|
|
|
+ // spIkConstraintData has no embedded index, so we need to loop over the events
|
|
|
+ for (int i = 0; i < skeleton->sp_skel_data->ikConstraintsCount; i++) {
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data->ikConstraints[i]);
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data->ikConstraints[i]->name);
|
|
|
+ if (0 == strcmp(skeleton->sp_skel_data->ikConstraints[i]->name, name)) {
|
|
|
+ return _sspine_iktarget(skeleton_id.id, i);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return _sspine_iktarget(0, 0);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_iktarget sspine_iktarget_by_index(sspine_skeleton skeleton_id, int index) {
|
|
|
+ return _sspine_iktarget(skeleton_id.id, index);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL bool sspine_iktarget_valid(sspine_iktarget iktarget) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(iktarget.skeleton_id);
|
|
|
+ if (_sspine_skeleton_and_deps_valid(skeleton)) {
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data);
|
|
|
+ return (iktarget.index >= 0) && (iktarget.index < skeleton->sp_skel_data->ikConstraintsCount);
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL bool sspine_iktarget_equal(sspine_iktarget first, sspine_iktarget second) {
|
|
|
+ return (first.skeleton_id == second.skeleton_id) && (first.index == second.index);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_iktarget_info sspine_get_iktarget_info(sspine_iktarget iktarget) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ sspine_iktarget_info res;
|
|
|
+ _sspine_clear(&res, sizeof(res));
|
|
|
+ const spIkConstraintData* ik_data = _sspine_lookup_ikconstraint_data(iktarget.skeleton_id, iktarget.index);
|
|
|
+ if (ik_data) {
|
|
|
+ res.valid = true;
|
|
|
+ res.index = iktarget.index;
|
|
|
+ res.target_bone = _sspine_bone(iktarget.skeleton_id, ik_data->target->index);
|
|
|
+ res.name = _sspine_string(ik_data->name);
|
|
|
+ if (res.name.truncated) {
|
|
|
+ _SSPINE_WARN(STRING_TRUNCATED);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL void sspine_set_iktarget_world_pos(sspine_instance instance_id, sspine_iktarget iktarget, sspine_vec2 world_pos) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ spIkConstraint* ik_data = _sspine_lookup_ikconstraint(instance_id.id, iktarget.skeleton_id, iktarget.index);
|
|
|
+ if (ik_data) {
|
|
|
+ spBone* bone = ik_data->target;
|
|
|
+ spBone* parent_bone = bone->parent;
|
|
|
+ if (parent_bone) {
|
|
|
+ spBone_worldToLocal(parent_bone, world_pos.x, world_pos.y, &bone->x, &bone->y);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL int sspine_num_skins(sspine_skeleton skeleton_id) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
|
|
|
+ if (_sspine_skeleton_and_deps_valid(skeleton)) {
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data);
|
|
|
+ return skeleton->sp_skel_data->skinsCount;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_skin sspine_skin_by_name(sspine_skeleton skeleton_id, const char* name) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ SOKOL_ASSERT(name);
|
|
|
+ _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
|
|
|
+ if (_sspine_skeleton_and_deps_valid(skeleton)) {
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data);
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data->skins);
|
|
|
+ // spSkin has no embedded index, so we need to loop over the skins
|
|
|
+ for (int i = 0; i < skeleton->sp_skel_data->skinsCount; i++) {
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data->skins[i]);
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data->skins[i]->name);
|
|
|
+ if (0 == strcmp(skeleton->sp_skel_data->skins[i]->name, name)) {
|
|
|
+ return _sspine_skin(skeleton_id.id, i);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return _sspine_skin(0, 0);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_skin sspine_skin_by_index(sspine_skeleton skeleton_id, int index) {
|
|
|
+ return _sspine_skin(skeleton_id.id, index);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL bool sspine_skin_valid(sspine_skin skin) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skin.skeleton_id);
|
|
|
+ if (_sspine_skeleton_and_deps_valid(skeleton)) {
|
|
|
+ SOKOL_ASSERT(skeleton->sp_skel_data);
|
|
|
+ return (skin.index >= 0) && (skin.index < skeleton->sp_skel_data->skinsCount);
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL bool sspine_skin_equal(sspine_skin first, sspine_skin second) {
|
|
|
+ return (first.skeleton_id == second.skeleton_id) && (first.index == second.index);
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_API_IMPL sspine_skin_info sspine_get_skin_info(sspine_skin skin) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ sspine_skin_info res;
|
|
|
+ _sspine_clear(&res, sizeof(res));
|
|
|
+ const spSkin* sp_skin = _sspine_lookup_skin(skin.skeleton_id, skin.index);
|
|
|
+ if (sp_skin) {
|
|
|
+ res.valid = true;
|
|
|
+ res.index = skin.index;
|
|
|
+ res.name = _sspine_string(sp_skin->name);
|
|
|
+ if (res.name.truncated) {
|
|
|
+ _SSPINE_WARN(STRING_TRUNCATED);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+SOKOL_SPINE_API_DECL void sspine_set_skin(sspine_instance instance_id, sspine_skin skin) {
|
|
|
+ SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
|
|
|
+ _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
|
|
|
+ if (_sspine_instance_and_deps_valid(instance) && (instance->skel.id == skin.skeleton_id)) {
|
|
|
+ SOKOL_ASSERT(instance->sp_skel);
|
|
|
+ SOKOL_ASSERT(instance->sp_anim_state);
|
|
|
+ // clear any currently set skinset
|
|
|
+ instance->skinset.id = SSPINE_INVALID_ID;
|
|
|
+ instance->skinset.ptr = 0;
|
|
|
+ spSkin* sp_skin = _sspine_lookup_skin(skin.skeleton_id, skin.index);
|
|
|
+ if (sp_skin) {
|
|
|
+ spSkeleton_setSkin(instance->sp_skel, 0);
|
|
|
+ spSkeleton_setSkin(instance->sp_skel, sp_skin);
|
|
|
+ spSkeleton_setSlotsToSetupPose(instance->sp_skel);
|
|
|
+ spAnimationState_apply(instance->sp_anim_state, instance->sp_skel);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#endif // SOKOL_SPINE_IMPL
|
|
|
+#endif // SOKOL_SPINE_INCLUDED
|