sprite rework

This commit is contained in:
2025-05-04 11:28:45 -05:00
parent 446ad080e1
commit a85b1873dd
8 changed files with 190 additions and 171 deletions

View File

@@ -3034,8 +3034,6 @@ JSC_CCALL(renderer_coords,
JSC_CCALL(renderer_camera,
renderer_ctx *ctx = js2renderer_ctx(js,self);
JSValue camera = argv[0];
ctx->cam = camera_globals(js, argv[0]);
)
@@ -3115,25 +3113,15 @@ JSC_CCALL(renderer_make_sprite_mesh,
JS_SetProperty(js, ret, count, number2js(js, count));
)
JSC_CCALL(renderer_texture_9grid,
renderer_ctx *ctx = js2renderer_ctx(js, self);
SDL_Renderer *r = ctx->sdl;
SDL_Texture *tex = js2SDL_Texture(js, argv[0]);
rect src = js2rect(js, argv[1]);
lrtb extents = js2lrtb(js, argv[2]);
float scale = 1;
rect dst = js2rect(js,argv[3]);
dst = renderer_worldrect_to_screen(ctx, dst);
if (!SDL_RenderTexture9Grid(r, tex, &src,
extents.l, extents.r, extents.t, extents.b,
scale, &dst))
return JS_ThrowReferenceError(js, "SDL_RenderTexture9Grid: %s", SDL_GetError());
)
static sprite js_getsprite(JSContext *js, JSValue sp)
{
sprite *s = js2sprite(js, sp);
if (s)
return *s;
sprite pp = {0};
return pp;
}
JSC_CCALL(renderer_texture,
renderer_ctx *ctx = js2renderer_ctx(js, self);
@@ -3156,24 +3144,26 @@ JSC_CCALL(renderer_texture,
JSC_CCALL(renderer_sprite,
renderer_ctx *ctx = js2renderer_ctx(js, self);
sprite *sp = js2sprite(js,argv[0]);
sprite sp = js_getsprite(js, argv[0]);
SDL_Texture *tex;
JS_GETATOM(js, tex, sp->image, texture, SDL_Texture);
JS_GETATOM(js, tex, sp.image, texture, SDL_Texture);
// rect dst = renderer_worldrect_to_screen(ctx, sp->affine);
rect dst = sp->affine;
rect uv = {x:0,y:0,w:48,h:24};
SDL_RenderTexture(ctx->sdl, tex, &uv, &dst);
)
float w = sp.uv.w, h = sp.uv.h;
JSC_CCALL(renderer_slice9,
renderer_ctx *ctx = js2renderer_ctx(js, self);
SDL_Texture *tex = js2SDL_Texture(js,argv[0]);
rect src = js2rect(js, argv[1]);
lrtb exts = js2lrtb(js, argv[2]);
rect dst = renderer_worldrect_to_screen(ctx, js2rect(js, argv[3]));
SDL_RenderTexture9Grid(ctx->sdl, tex, &src, exts.l, exts.r, exts.t, exts.b, 0.0f, &dst);
HMM_Vec2 tl_local = { -sp.center.X, -sp.center.Y };
HMM_Vec2 tr_local = { -sp.center.X + w, -sp.center.Y };
HMM_Vec2 bl_local = { -sp.center.X, -sp.center.Y + h };
HMM_Vec2 world_tl = HMM_AddV2(sp.pos, HMM_MulM2V2(sp.affine, tl_local));
HMM_Vec2 world_tr = HMM_AddV2(sp.pos, HMM_MulM2V2(sp.affine, tr_local));
HMM_Vec2 world_bl = HMM_AddV2(sp.pos, HMM_MulM2V2(sp.affine, bl_local));
SDL_FPoint origin = renderer_world_to_screen(ctx, world_tl);
SDL_FPoint right = renderer_world_to_screen(ctx, world_tr);
SDL_FPoint down = renderer_world_to_screen(ctx, world_bl);
if (!SDL_RenderTextureAffine(ctx->sdl, tex, &sp.uv, &origin, &right, &down))
return JS_ThrowInternalError(js, "Render sprite error: %s", SDL_GetError());
)
static const JSCFunctionListEntry js_renderer_ctx_funcs[] = {
@@ -3189,7 +3179,6 @@ static const JSCFunctionListEntry js_renderer_ctx_funcs[] = {
MIST_FUNC_DEF(renderer, sprite, 1),
MIST_FUNC_DEF(renderer, load_texture, 1),
MIST_FUNC_DEF(renderer, get_image, 1),
MIST_FUNC_DEF(renderer, slice9, 4),
MIST_FUNC_DEF(renderer, scale, 1),
MIST_FUNC_DEF(renderer, logical_size,1),
@@ -3263,11 +3252,11 @@ static SDL_AudioSpec js2audiospec(JSContext *js, JSValue obj)
JS_FreeValue(js, v);
v = JS_GetPropertyStr(js, obj, "channels");
if (!JS_IsUndefined(v)) JS_ToUint32(js, &spec.channels, v);
if (!JS_IsUndefined(v)) JS_ToInt32(js, &spec.channels, v);
JS_FreeValue(js, v);
v = JS_GetPropertyStr(js, obj, "samplerate");
if (!JS_IsUndefined(v)) JS_ToUint32(js, &spec.freq, v);
if (!JS_IsUndefined(v)) JS_ToInt32(js, &spec.freq, v);
JS_FreeValue(js, v);
return spec;
@@ -3294,7 +3283,7 @@ JSC_CCALL(sdl_audio_devices,
)
JSC_CCALL(sdl_audio_open_stream,
char *type = JS_IsString(argv[0]) ? JS_ToCString(js, argv[0]) : NULL;
const char *type = JS_IsString(argv[0]) ? JS_ToCString(js, argv[0]) : NULL;
SDL_AudioDeviceID devid = !strcmp(type, "capture") ? SDL_AUDIO_DEVICE_DEFAULT_RECORDING : SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK;
if (type)
@@ -4042,11 +4031,11 @@ typedef struct {
static inline int sprite_compare(const sprite *a, const sprite *b) {
if (a->layer != b->layer) return a->layer - b->layer;
if (a->affine.y != b->affine.y)
return (b->affine.y - a->affine.y);
if (a->pos.Y != b->pos.Y)
return (b->pos.Y - a->pos.Y);
if (a->tex != b->tex)
return (a->tex < b->tex) ? -1 : 1;
if (JS_VALUE_GET_PTR(a->image) != JS_VALUE_GET_PTR(b->image))
return JS_VALUE_GET_PTR(a->image) < JS_VALUE_GET_PTR(b->image) ? -1 : 1;
return 0;
}
@@ -4087,28 +4076,35 @@ void better_sort_sprites(sprite *arr, size_t length) {
int sort_sprite_backtofront(const sprite *a, const sprite *b)
{
if (a->layer != b->layer) return a->layer - b->layer;
if (a->tex != b->tex) return ((uintptr_t)a->tex < (uintptr_t)b->tex) ? -1 : 1;
if (JS_VALUE_GET_PTR(a->image) != JS_VALUE_GET_PTR(b->image))
return JS_VALUE_GET_PTR(a->image) < JS_VALUE_GET_PTR(b->image) ? -1 : 1;
return 0;
}
int sort_sprite_fronttoback(const sprite *a, const sprite *b)
{
if (a->layer != b->layer) return b->layer - a->layer;
if (a->tex != b->tex) return ((uintptr_t)a->tex < (uintptr_t)b->tex) ? -1 : 1;
if (JS_VALUE_GET_PTR(a->image) != JS_VALUE_GET_PTR(b->image))
return JS_VALUE_GET_PTR(a->image) < JS_VALUE_GET_PTR(b->image) ? -1 : 1;
return 0;
}
int sort_sprite_texture(const sprite *a, const sprite *b)
{
if (a->tex != b->tex) return ((uintptr_t)a->tex < (uintptr_t)b->tex) ? -1 : 1;
if (JS_VALUE_GET_PTR(a->image) != JS_VALUE_GET_PTR(b->image))
return JS_VALUE_GET_PTR(a->image) < JS_VALUE_GET_PTR(b->image) ? -1 : 1;
return 0;
}
int sort_sprite(const sprite *a, const sprite *b)
{
if (a->layer != b->layer) return a->layer - b->layer;
if (a->affine.y != b->affine.y) return b->affine.y - a->affine.y;
if (a->tex != b->tex) return ((uintptr_t)a->tex < (uintptr_t)b->tex) ? -1 : 1;
if (a->pos.Y != b->pos.Y)
return (b->pos.Y - a->pos.Y);
if (JS_VALUE_GET_PTR(a->image) != JS_VALUE_GET_PTR(b->image))
return JS_VALUE_GET_PTR(a->image) < JS_VALUE_GET_PTR(b->image) ? -1 : 1;
return 0;
}
@@ -4139,7 +4135,6 @@ JSC_CCALL(gpu_make_sprite_queue,
sprite *sprites = NULL;
size_t quads = 0;
int needfree = 1;
int sort = js2number(js,argv[3]);
if (JS_IsArrayBuffer(js, argv[0])) {
// test for fastest
@@ -4162,26 +4157,26 @@ JSC_CCALL(gpu_make_sprite_queue,
}
else {
sprite sp = {0};
JS_GETATOM(js,sp.affine, sub, rect, rect)
JS_GETATOM(js, sp.pos, sub, pos, vec2)
JS_GETATOM(js, sp.center, sub, center, vec2)
JS_GETATOM(js, sp.skew, sub, skew, vec2)
JS_GETATOM(js, sp.scale, sub, scale, vec2)
JS_GETATOM(js,sp.color,sub,color,color)
JS_GETATOM(js,sp.layer,sub,layer,number)
JS_GETATOM(js,sp.uv,sub,src,rect)
sp.image = JS_GetProperty(js,sub,image);
JS_GETATOM(js,sp.tex,sp.image,texture,SDL_GPUTexture)
arrput(sprites,sp);
}
JS_FreeValue(js, sub);
}
}
if (sort) qsort(sprites, quads, sizeof(sprite), sort_sprite);
// else qsort(sprites, quads, sizeof(sprite), sort_sprite_texture);
qsort(sprites, quads, sizeof(sprite), sort_sprite);
struct quad_buffers buffers = quad_buffers_new(quads*4);
for (int i = 0; i < quads; i++) {
rect pr = sprites[i].affine;
rect pr = {0};
rect uv = sprites[i].uv;
HMM_Vec4 c = sprites[i].color;
@@ -6826,36 +6821,6 @@ JSC_CCALL(os_make_rtree,
return rtree2js(js,tree);
)
JSC_CCALL(os_rects_to_sprites,
ret = JS_NewArray(js);
JSValue image = argv[0];
JSValue jstex = JS_GetProperty(js,image,texture);
double w, h = 0;
JS_GETATOM(js,w,jstex,width,number)
JS_GETATOM(js,h,jstex,height,number)
SDL_GPUTexture *tex = js2SDL_GPUTexture(js,jstex);
JS_FreeValue(js,jstex);
JSValue rects = argv[1];
rect uv;
JS_GETATOM(js,uv,image,rect,rect)
ret = JS_NewArray(js);
int n = js_arrlen(js,rects);
for (int i = 0; i < n; i++) {
JSValue sub = JS_GetPropertyUint32(js,rects,i);
sprite *s = make_sprite();
s->affine = js2rect(js,sub);
s->affine.w = w;
s->affine.h = h;
s->image = JS_DupValue(js,image);
s->tex = tex;
s->uv = uv;
JS_SetPropertyUint32(js,ret,i,sprite2js(js,s));
JS_FreeValue(js,sub);
}
)
JSC_CCALL(os_on,
prosperon_rt *rt = JS_GetContextOpaque(js);
JS_FreeValue(js, rt->on_exception);
@@ -6995,7 +6960,7 @@ JSC_CCALL(os_createactor,
for (int i = 0; i < margc; i++) {
JSValue val = JS_GetPropertyUint32(js, argv[0], i);
char *cstr = JS_ToCString(js,val);
const char *cstr = JS_ToCString(js,val);
margv[i] = strdup(cstr);
JS_FreeCString(js,cstr);
JS_FreeValue(js,val);
@@ -7018,7 +6983,7 @@ JSC_CCALL(os_mailbox_push,
void *data = value2wota(js, argv[1], JS_UNDEFINED);
char *err = send_message(id, data);
const char *err = send_message(id, data);
if (err) {
free(data);
return JS_ThrowInternalError(js, "Could not send message: %s", err);
@@ -7027,8 +6992,8 @@ JSC_CCALL(os_mailbox_push,
JSC_CCALL(os_register_actor,
prosperon_rt *rt = JS_GetContextOpaque(js);
char *id = JS_ToCString(js, argv[0]);
char *err = register_actor(id, rt, JS_ToBool(js, argv[2]));
const char *id = JS_ToCString(js, argv[0]);
const char *err = register_actor(id, rt, JS_ToBool(js, argv[2]));
if (err) return JS_ThrowInternalError(js, "Could not register actor: %s", err);
rt->message_handle = JS_DupValue(js, argv[1]);
rt->context = js;
@@ -7184,7 +7149,6 @@ static const JSCFunctionListEntry js_graphics_funcs[] = {
MIST_FUNC_DEF(os, make_gif, 1),
MIST_FUNC_DEF(os, make_aseprite, 1),
MIST_FUNC_DEF(os, cull_sprites, 2),
MIST_FUNC_DEF(os, rects_to_sprites,2),
MIST_FUNC_DEF(os, make_surface, 1),
MIST_FUNC_DEF(os, make_cursor, 1),
MIST_FUNC_DEF(os, make_font, 2),
@@ -7390,19 +7354,17 @@ static const JSCFunctionListEntry js_rtree_funcs[] = {
MIST_FUNC_DEF(rtree,values,0),
};
JSC_GETSET(sprite, pos, vec2)
JSC_GETSET(sprite, center, vec2)
JSC_GETSET(sprite, layer, number)
JSC_GETSET(sprite, color, color)
JSC_GETSET(sprite, skew, vec2)
JSC_GETSET(sprite, scale, vec2)
JSC_GETSET(sprite, rotation, number)
JSC_CCALL(sprite_set_affine,
sprite *sp = js2sprite(js,self);
transform *t = js2transform(js,argv[0]);
if (t)
sp->affine = transform2rect(t);
)
JSC_CCALL(sprite_set_rect,
sprite *sp = js2sprite(js,self);
sp->affine = js2rect(js,argv[0]);
sprite_apply(sp);
)
JSC_CCALL(sprite_set_image,
@@ -7413,13 +7375,15 @@ JSC_CCALL(sprite_set_image,
if (JS_IsUndefined(sp->image)) return JS_UNDEFINED;
JSValue img = sp->image;
JS_GETATOM(js, sp->uv, img, rect, rect)
JS_GETATOM(js, sp->tex, img, texture, SDL_GPUTexture);
)
static const JSCFunctionListEntry js_sprite_funcs[] = {
MIST_FUNC_DEF(sprite, set_affine, 1),
MIST_FUNC_DEF(sprite, set_rect, 1),
MIST_FUNC_DEF(sprite, set_affine, 0),
MIST_FUNC_DEF(sprite, set_image, 1),
CGETSET_ADD(sprite, skew),
CGETSET_ADD(sprite, rotation),
CGETSET_ADD(sprite, pos),
CGETSET_ADD(sprite, center),
CGETSET_ADD(sprite, layer),
CGETSET_ADD(sprite, color),
};
@@ -7563,8 +7527,8 @@ void ffi_load(JSContext *js)
JS_SetPropertyUint32(js,args, i, JS_NewString(js,rt->cmd.argv[i]));
JS_SetPropertyStr(js,prosp,"argv", args);
JS_SetPropertyStr(js,prosp, "version", JS_NewString(js,PROSPERON_VERSION));
JS_SetPropertyStr(js,prosp,"revision",JS_NewString(js,PROSPERON_COMMIT));
//JS_SetPropertyStr(js,prosp, "version", JS_NewString(js,PROSPERON_VERSION));
//JS_SetPropertyStr(js,prosp,"revision",JS_NewString(js,PROSPERON_COMMIT));
JS_SetPropertyStr(js,prosp,"engine_start", JS_NewCFunction(js,js_os_engine_start, "engine_start", 1));
JS_FreeValue(js,globalThis);