#include "cell.h" #include "sdl.h" #include colorf js2color(JSContext *js,JSValue v) { if (JS_IsNull(v)) return (colorf){1,1,1,1}; colorf color = {1,1,1,1}; // Default to white if (JS_IsArray(js, v)) { // Handle array format: [r, g, b, a] JSValue c[4]; for (int i = 0; i < 4; i++) c[i] = JS_GetPropertyUint32(js,v,i); color.x = js2number(js,c[0]); color.y = js2number(js,c[1]); color.z = js2number(js,c[2]); color.w = JS_IsNull(c[3]) ? 1.0 : js2number(js,c[3]); for (int i = 0; i < 4; i++) JS_FreeValue(js,c[i]); } else if (JS_IsObject(v)) { JS_GETPROP(js, color.x, v, r, number) JS_GETPROP(js, color.y, v, g, number) JS_GETPROP(js, color.z, v, b, number) JS_GETPROP(js, color.w, v, a, number) } return color; } JSValue color2js(JSContext *js, colorf color) { JSValue arr = JS_NewArray(js); JS_SetPropertyUint32(js, arr,0,number2js(js,(double)color.x)); JS_SetPropertyUint32(js, arr,1,number2js(js,(double)color.y)); JS_SetPropertyUint32(js, arr,2,number2js(js,(double)color.z)); JS_SetPropertyUint32(js, arr,3,number2js(js,(double)color.w)); return arr; } vec2 js2vec2(JSContext *js,JSValue v) { vec2 v2; // Check if it's an array if (JS_IsArray(js, v)) { { JSValue val = JS_GetPropertyUint32(js,v,0); v2.x = js2number(js, val); JS_FreeValue(js,val); } { JSValue val = JS_GetPropertyUint32(js,v,1); v2.y = js2number(js, val); JS_FreeValue(js,val); } } else { // Try to get x,y properties from object JSValue x_val = JS_GetPropertyStr(js, v, "x"); JSValue y_val = JS_GetPropertyStr(js, v, "y"); v2.x = js2number(js, x_val); v2.y = js2number(js, y_val); JS_FreeValue(js, x_val); JS_FreeValue(js, y_val); } return v2; } vec3 js2vec3(JSContext *js,JSValue v) { vec3 v3; { JSValue val = JS_GetPropertyUint32(js, v,0); v3.x = js2number(js, val); JS_FreeValue(js,val); } { JSValue val = JS_GetPropertyUint32(js, v,1); v3.y = js2number(js, val); JS_FreeValue(js,val); } { JSValue val = JS_GetPropertyUint32(js, v,2); v3.z = js2number(js, val); JS_FreeValue(js,val); } return v3; } float *js2floats(JSContext *js, JSValue v, size_t *len) { *len = JS_ArrayLength(js,v); float *arr = malloc(sizeof(float)* *len); for (int i = 0; i < *len; i++) { JSValue val = JS_GetPropertyUint32(js,v,i); arr[i] = js2number(js, val); JS_FreeValue(js,val); } return arr; } double *js2doubles(JSContext *js, JSValue v, size_t *len) { *len = JS_ArrayLength(js,v); double *arr = malloc(sizeof(double)* *len); for (int i = 0; i < *len; i++) { JSValue val = JS_GetPropertyUint32(js,v,i); arr[i] = js2number(js, val); JS_FreeValue(js,val); } return arr; } vec3 js2vec3f(JSContext *js, JSValue v) { vec3 vec; if (JS_IsArray(js, v)) return js2vec3(js,v); else vec.x = vec.y = vec.z = js2number(js,v); return vec; } JSValue vec32js(JSContext *js, vec3 v) { JSValue array = JS_NewArray(js); JS_SetPropertyUint32(js, array,0,number2js(js,v.x)); JS_SetPropertyUint32(js, array,1,number2js(js,v.y)); JS_SetPropertyUint32(js, array,2,number2js(js,v.z)); return array; } JSValue vec3f2js(JSContext *js, vec3 v) { return vec32js(js,v); } JSValue quat2js(JSContext *js, quat q) { JSValue arr = JS_NewArray(js); JS_SetPropertyUint32(js, arr, 0, number2js(js,q.x)); JS_SetPropertyUint32(js, arr,1,number2js(js,q.y)); JS_SetPropertyUint32(js, arr,2,number2js(js,q.z)); JS_SetPropertyUint32(js, arr,3,number2js(js,q.w)); return arr; } vec4 js2vec4(JSContext *js, JSValue v) { vec4_union v4; for (int i = 0; i < 4; i++) { JSValue val = JS_GetPropertyUint32(js, v,i); v4.e[i] = js2number(js, val); JS_FreeValue(js,val); } return (vec4){v4.x, v4.y, v4.z, v4.w}; } double arr_vec_length(JSContext *js,JSValue v) { int len = JS_ArrayLength(js,v); switch(len) { case 2: { vec2 v2 = js2vec2(js,v); return sqrt(v2.x*v2.x + v2.y*v2.y); } case 3: { vec3 v3 = js2vec3(js,v); return sqrt(v3.x*v3.x + v3.y*v3.y + v3.z*v3.z); } case 4: { vec4 v4 = js2vec4(js,v); return sqrt(v4.x*v4.x + v4.y*v4.y + v4.z*v4.z + v4.w*v4.w); } } double sum = 0; for (int i = 0; i < len; i++) { JSValue val = JS_GetPropertyUint32(js, v, i); double num = js2number(js, val); JS_FreeValue(js,val); sum += pow(num, 2); } return sqrt(sum); } quat js2quat(JSContext *js,JSValue v) { vec4_union v4; for (int i = 0; i < 4; i++) { JSValue val = JS_GetPropertyUint32(js, v,i); v4.e[i] = js2number(js, val); JS_FreeValue(js,val); } return (quat){v4.x, v4.y, v4.z, v4.w}; } JSValue vec42js(JSContext *js, vec4 v) { JSValue array = JS_NewArray(js); JS_SetPropertyUint32(js, array,0,number2js(js,v.x)); JS_SetPropertyUint32(js, array,1,number2js(js,v.y)); JS_SetPropertyUint32(js, array,2,number2js(js,v.z)); JS_SetPropertyUint32(js, array,3,number2js(js,v.w)); return array; } vec2 *js2cpvec2arr(JSContext *js,JSValue v) { int n = JS_ArrayLength(js,v); vec2 *arr = malloc(sizeof(vec2) * n); for (int i = 0; i < n; i++) { JSValue ii = JS_GetPropertyUint32(js,v,i); arr[i] = js2vec2(js,ii); JS_FreeValue(js,ii); } return arr; } rect js2rect(JSContext *js,JSValue v) { if (JS_IsNull(v)) return (rect){0,0,1,1}; rect rect; JS_GETATOM(js,rect.x,v,x,number) JS_GETATOM(js,rect.y,v,y,number) JS_GETATOM(js,rect.w,v,width,number) JS_GETATOM(js,rect.h,v,height,number) float anchor_x, anchor_y; JS_GETATOM(js, anchor_x, v, anchor_x, number) JS_GETATOM(js, anchor_y, v, anchor_y, number) rect.y -= anchor_y*rect.h; rect.x -= anchor_x*rect.w; return rect; } static JSValue floats2array(JSContext *js, float *vals, size_t len) { JSValue arr = JS_NewArray(js); for (size_t i = 0; i < len; i++) { JS_SetPropertyUint32(js, arr, i, number2js(js, vals[i])); } return arr; } lrtb js2lrtb(JSContext *js, JSValue v) { lrtb ret = {0}; JS_GETATOM(js,ret.l,v,l,number) JS_GETATOM(js,ret.r,v,r,number) JS_GETATOM(js,ret.b,v,b,number) JS_GETATOM(js,ret.t,v,t,number) return ret; } JSValue vec22js(JSContext *js,vec2 v) { JSValue array = JS_NewArray(js); JS_SetPropertyUint32(js, array,0,number2js(js,v.x)); JS_SetPropertyUint32(js, array,1,number2js(js,v.y)); return array; } JSValue vecarr2js(JSContext *js,vec2 *points, int n) { JSValue array = JS_NewArray(js); for (int i = 0; i < n; i++) JS_SetPropertyUint32(js, array,i,vec22js(js,points[i])); return array; } JSValue rect2js(JSContext *js,rect rect) { JSValue obj = JS_NewObject(js); JS_SetPropertyStr(js, obj, "x", number2js(js, rect.x)); JS_SetPropertyStr(js, obj, "y", number2js(js, rect.y)); JS_SetPropertyStr(js, obj, "width", number2js(js, rect.w)); JS_SetPropertyStr(js, obj, "height", number2js(js, rect.h)); return obj; } float *rgba2floats(float *r, struct rgba c) { r[0] = (float)c.r / RGBA_MAX; r[1] = (float)c.g / RGBA_MAX; r[2] = (float)c.b / RGBA_MAX; r[3] = (float)c.a / RGBA_MAX; return r; } JSValue angle2js(JSContext *js, double angle) { return number2js(js, angle); } double js2angle(JSContext *js, JSValue v) { return js2number(js, v); } // Pixel format enum conversion using the new system ENUM_MAPPING_TABLE(SDL_PixelFormat) = { {SDL_PIXELFORMAT_UNKNOWN, "unknown"}, {SDL_PIXELFORMAT_INDEX1LSB, "index1lsb"}, {SDL_PIXELFORMAT_INDEX1MSB, "index1msb"}, {SDL_PIXELFORMAT_INDEX2LSB, "index2lsb"}, {SDL_PIXELFORMAT_INDEX2MSB, "index2msb"}, {SDL_PIXELFORMAT_INDEX4LSB, "index4lsb"}, {SDL_PIXELFORMAT_INDEX4MSB, "index4msb"}, {SDL_PIXELFORMAT_INDEX8, "index8"}, {SDL_PIXELFORMAT_RGB332, "rgb332"}, {SDL_PIXELFORMAT_XRGB4444, "xrgb4444"}, {SDL_PIXELFORMAT_XBGR4444, "xbgr4444"}, {SDL_PIXELFORMAT_XRGB1555, "xrgb1555"}, {SDL_PIXELFORMAT_XBGR1555, "xbgr1555"}, {SDL_PIXELFORMAT_ARGB4444, "argb4444"}, {SDL_PIXELFORMAT_RGBA4444, "rgba4444"}, {SDL_PIXELFORMAT_ABGR4444, "abgr4444"}, {SDL_PIXELFORMAT_BGRA4444, "bgra4444"}, {SDL_PIXELFORMAT_ARGB1555, "argb1555"}, {SDL_PIXELFORMAT_RGBA5551, "rgba5551"}, {SDL_PIXELFORMAT_ABGR1555, "abgr1555"}, {SDL_PIXELFORMAT_BGRA5551, "bgra5551"}, {SDL_PIXELFORMAT_RGB565, "rgb565"}, {SDL_PIXELFORMAT_BGR565, "bgr565"}, {SDL_PIXELFORMAT_RGB24, "rgb24"}, {SDL_PIXELFORMAT_BGR24, "bgr24"}, {SDL_PIXELFORMAT_XRGB8888, "xrgb8888"}, {SDL_PIXELFORMAT_RGBX8888, "rgbx8888"}, {SDL_PIXELFORMAT_XBGR8888, "xbgr8888"}, {SDL_PIXELFORMAT_BGRX8888, "bgrx8888"}, {SDL_PIXELFORMAT_ARGB8888, "argb8888"}, {SDL_PIXELFORMAT_RGBA8888, "rgba8888"}, {SDL_PIXELFORMAT_ABGR8888, "abgr8888"}, {SDL_PIXELFORMAT_BGRA8888, "bgra8888"}, {SDL_PIXELFORMAT_XRGB2101010, "xrgb2101010"}, {SDL_PIXELFORMAT_XBGR2101010, "xbgr2101010"}, {SDL_PIXELFORMAT_ARGB2101010, "argb2101010"}, {SDL_PIXELFORMAT_ABGR2101010, "abgr2101010"}, {SDL_PIXELFORMAT_RGB48, "rgb48"}, {SDL_PIXELFORMAT_BGR48, "bgr48"}, {SDL_PIXELFORMAT_RGBA64, "rgba64"}, {SDL_PIXELFORMAT_ARGB64, "argb64"}, {SDL_PIXELFORMAT_BGRA64, "bgra64"}, {SDL_PIXELFORMAT_ABGR64, "abgr64"}, {SDL_PIXELFORMAT_RGB48_FLOAT, "rgb48_float"}, {SDL_PIXELFORMAT_BGR48_FLOAT, "bgr48_float"}, {SDL_PIXELFORMAT_RGBA64_FLOAT, "rgba64_float"}, {SDL_PIXELFORMAT_ARGB64_FLOAT, "argb64_float"}, {SDL_PIXELFORMAT_BGRA64_FLOAT, "bgra64_float"}, {SDL_PIXELFORMAT_ABGR64_FLOAT, "abgr64_float"}, {SDL_PIXELFORMAT_RGB96_FLOAT, "rgb96_float"}, {SDL_PIXELFORMAT_BGR96_FLOAT, "bgr96_float"}, {SDL_PIXELFORMAT_RGBA128_FLOAT, "rgba128_float"}, {SDL_PIXELFORMAT_ARGB128_FLOAT, "argb128_float"}, {SDL_PIXELFORMAT_BGRA128_FLOAT, "bgra128_float"}, {SDL_PIXELFORMAT_ABGR128_FLOAT, "abgr128_float"}, {SDL_PIXELFORMAT_YV12, "yv12"}, {SDL_PIXELFORMAT_IYUV, "iyuv"}, {SDL_PIXELFORMAT_YUY2, "yuy2"}, {SDL_PIXELFORMAT_UYVY, "uyvy"}, {SDL_PIXELFORMAT_YVYU, "yvyu"}, {SDL_PIXELFORMAT_NV12, "nv12"}, {SDL_PIXELFORMAT_NV21, "nv21"}, {SDL_PIXELFORMAT_P010, "p010"}, {SDL_PIXELFORMAT_RGBA32, "rgba32"} }; JS2ENUM(SDL_PixelFormat)