animations
This commit is contained in:
@@ -1078,28 +1078,16 @@ JSC_CCALL(os_make_gif,
|
||||
int height;
|
||||
void *pixels = stbi_load_gif_from_memory(raw, rawlen, &delays, &width, &height, &frames, &n, 4);
|
||||
|
||||
JSValue gif = JS_NewObject(js);
|
||||
ret = gif;
|
||||
|
||||
if (frames == 1) {
|
||||
// still image, so return surface data object
|
||||
JSValue surfData = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, surfData, "width", JS_NewInt32(js, width));
|
||||
JS_SetPropertyStr(js, surfData, "height", JS_NewInt32(js, height));
|
||||
JS_SetPropertyStr(js, surfData, "format", JS_NewString(js, "rgba32"));
|
||||
JS_SetPropertyStr(js, surfData, "pitch", JS_NewInt32(js, width*4));
|
||||
JS_SetPropertyStr(js, surfData, "pixels", js_new_blob_stoned_copy(js, pixels, width*height*4));
|
||||
JS_SetPropertyStr(js, gif, "surface", surfData);
|
||||
return gif;
|
||||
if (!pixels) {
|
||||
return JS_ThrowReferenceError(js, "Failed to decode GIF: %s", stbi_failure_reason());
|
||||
}
|
||||
|
||||
JSValue delay_arr = JS_NewArray(js);
|
||||
// Always return an array of surfaces, even for single frame
|
||||
JSValue surface_array = JS_NewArray(js);
|
||||
ret = surface_array;
|
||||
|
||||
for (int i = 0; i < frames; i++) {
|
||||
JSValue frame = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, frame, "time", number2js(js,(float)delays[i]/1000.0));
|
||||
|
||||
// Create surface data object instead of SDL_Surface
|
||||
// Create surface data object
|
||||
JSValue surfData = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, surfData, "width", JS_NewInt32(js, width));
|
||||
JS_SetPropertyStr(js, surfData, "height", JS_NewInt32(js, height));
|
||||
@@ -1109,15 +1097,17 @@ JSC_CCALL(os_make_gif,
|
||||
void *frame_pixels = (unsigned char*)pixels+(width*height*4*i);
|
||||
JS_SetPropertyStr(js, surfData, "pixels", js_new_blob_stoned_copy(js, frame_pixels, width*height*4));
|
||||
|
||||
JS_SetPropertyStr(js, frame, "surface", surfData);
|
||||
JS_SetPropertyUint32(js, delay_arr, i, frame);
|
||||
// Add time property for animation frames
|
||||
if (frames > 1 && delays) {
|
||||
JS_SetPropertyStr(js, surfData, "time", number2js(js,(float)delays[i]/1000.0));
|
||||
}
|
||||
|
||||
JS_SetPropertyUint32(js, surface_array, i, surfData);
|
||||
}
|
||||
|
||||
JS_SetPropertyStr(js, gif, "frames", delay_arr);
|
||||
|
||||
CLEANUP:
|
||||
free(delays);
|
||||
free(pixels);
|
||||
if (delays) free(delays);
|
||||
if (pixels) free(pixels);
|
||||
)
|
||||
|
||||
JSValue aseframe2js(JSContext *js, ase_frame_t aframe)
|
||||
@@ -1153,6 +1143,19 @@ JSC_CCALL(os_make_aseprite,
|
||||
JSValue obj = aseframe2js(js,ase->frames[0]);
|
||||
cute_aseprite_free(ase);
|
||||
return obj;
|
||||
} else {
|
||||
// Multiple frames but no tags - create a simple animation
|
||||
JSValue obj = JS_NewObject(js);
|
||||
JSValue frames = JS_NewArray(js);
|
||||
for (int f = 0; f < ase->frame_count; f++) {
|
||||
JSValue frame = aseframe2js(js,ase->frames[f]);
|
||||
JS_SetPropertyUint32(js, frames, f, frame);
|
||||
}
|
||||
JS_SetPropertyStr(js, obj, "frames", frames);
|
||||
JS_SetPropertyStr(js, obj, "loop", JS_NewBool(js, true));
|
||||
ret = obj;
|
||||
cute_aseprite_free(ase);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1242,6 +1242,82 @@ JSC_CCALL(geometry_transform_xy_blob,
|
||||
ret = transformed_blob;
|
||||
)
|
||||
|
||||
// RENDERITEM SYSTEM
|
||||
typedef struct {
|
||||
int layer;
|
||||
float y;
|
||||
JSValue val;
|
||||
} RenderItem;
|
||||
|
||||
#define MAX_RENDER_ITEMS 64000
|
||||
static RenderItem render_items[MAX_RENDER_ITEMS];
|
||||
static int render_item_count = 0;
|
||||
|
||||
JSC_CCALL(geometry_renderitem_push,
|
||||
if (argc < 3) {
|
||||
return JS_ThrowTypeError(js, "renderitem_push requires 3 arguments: layer, y, val");
|
||||
}
|
||||
|
||||
if (render_item_count >= MAX_RENDER_ITEMS) {
|
||||
return JS_ThrowTypeError(js, "Maximum render items exceeded");
|
||||
}
|
||||
|
||||
int layer;
|
||||
double y;
|
||||
|
||||
if (JS_ToInt32(js, &layer, argv[0]) < 0) {
|
||||
return JS_ThrowTypeError(js, "layer must be a number");
|
||||
}
|
||||
|
||||
if (JS_ToFloat64(js, &y, argv[1]) < 0) {
|
||||
return JS_ThrowTypeError(js, "y must be a number");
|
||||
}
|
||||
|
||||
render_items[render_item_count].layer = layer;
|
||||
render_items[render_item_count].y = (float)y;
|
||||
render_items[render_item_count].val = JS_DupValue(js, argv[2]);
|
||||
render_item_count++;
|
||||
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
static int compare_render_items(const void *a, const void *b)
|
||||
{
|
||||
const RenderItem *item_a = (const RenderItem *)a;
|
||||
const RenderItem *item_b = (const RenderItem *)b;
|
||||
|
||||
if (item_a->layer != item_b->layer) {
|
||||
return item_a->layer - item_b->layer;
|
||||
}
|
||||
|
||||
// if (item_a->y != item_b->y) {
|
||||
// return (item_b->y > item_a->y) ? 1 : -1;
|
||||
// }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
JSC_CCALL(geometry_renderitem_sort,
|
||||
qsort(render_items, render_item_count, sizeof(RenderItem), compare_render_items);
|
||||
|
||||
JSValue result = JS_NewArray(js);
|
||||
|
||||
for (int i = 0; i < render_item_count; i++) {
|
||||
JS_SetPropertyUint32(js, result, i, JS_DupValue(js, render_items[i].val));
|
||||
}
|
||||
|
||||
return result;
|
||||
)
|
||||
|
||||
JSC_CCALL(geometry_renderitem_clear,
|
||||
for (int i = 0; i < render_item_count; i++) {
|
||||
JS_FreeValue(js, render_items[i].val);
|
||||
}
|
||||
render_item_count = 0;
|
||||
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
static const JSCFunctionListEntry js_geometry_funcs[] = {
|
||||
MIST_FUNC_DEF(geometry, rect_intersection, 2),
|
||||
MIST_FUNC_DEF(geometry, rect_intersects, 2),
|
||||
@@ -1260,6 +1336,9 @@ static const JSCFunctionListEntry js_geometry_funcs[] = {
|
||||
MIST_FUNC_DEF(gpu, slice9, 3),
|
||||
MIST_FUNC_DEF(gpu, make_sprite_mesh, 2),
|
||||
MIST_FUNC_DEF(gpu, make_sprite_queue, 4),
|
||||
MIST_FUNC_DEF(geometry, renderitem_push, 3),
|
||||
MIST_FUNC_DEF(geometry, renderitem_sort, 0),
|
||||
MIST_FUNC_DEF(geometry, renderitem_clear, 0),
|
||||
};
|
||||
|
||||
JSValue js_geometry_use(JSContext *js) {
|
||||
|
||||
Reference in New Issue
Block a user