switch to blobs from arraybuffers
Some checks failed
Build and Deploy / build-linux (push) Failing after 1m29s
Build and Deploy / build-macos (push) Failing after 7s
Build and Deploy / build-windows (CLANG64) (push) Has been cancelled
Build and Deploy / package-dist (push) Has been cancelled
Build and Deploy / deploy-itch (push) Has been cancelled
Build and Deploy / deploy-gitea (push) Has been cancelled
Some checks failed
Build and Deploy / build-linux (push) Failing after 1m29s
Build and Deploy / build-macos (push) Failing after 7s
Build and Deploy / build-windows (CLANG64) (push) Has been cancelled
Build and Deploy / package-dist (push) Has been cancelled
Build and Deploy / deploy-itch (push) Has been cancelled
Build and Deploy / deploy-gitea (push) Has been cancelled
This commit is contained in:
@@ -4,6 +4,19 @@ var json = use('json')
|
||||
var os = use('os')
|
||||
var draw2d = use('draw2d')
|
||||
|
||||
var blob = use('blob')
|
||||
|
||||
var myblob = new blob
|
||||
myblob.write_bit(1)
|
||||
myblob.write_bit(0)
|
||||
myblob.__proto__.toString = function() {
|
||||
return `[${this.length} bit blob]`
|
||||
}
|
||||
console.log(myblob.toString())
|
||||
console.log(myblob)
|
||||
console.log(myblob.length)
|
||||
|
||||
|
||||
var input = use('input')
|
||||
|
||||
input.watch($_)
|
||||
|
||||
@@ -238,6 +238,7 @@ globalThis.use = function use(file, ...args) {
|
||||
globalThis.json = use('json')
|
||||
var time = use('time')
|
||||
|
||||
use('blob')
|
||||
var DOCPATH = 'scripts/core/doc.js'
|
||||
var script = io.slurp(DOCPATH)
|
||||
var fnname = "doc"
|
||||
|
||||
@@ -156,6 +156,8 @@ function decode_image(bytes, ext)
|
||||
function create_image(path){
|
||||
try{
|
||||
const bytes = io.slurpbytes(path);
|
||||
console.log(bytes)
|
||||
console.log(bytes.length)
|
||||
let raw = decode_image(bytes, path.ext());
|
||||
|
||||
/* ── Case A: static image ─────────────────────────────────── */
|
||||
|
||||
@@ -57,6 +57,8 @@ int blob_write_kim(blob *b, int64_t value);
|
||||
int blob_write_pad(blob *b, int block_size);
|
||||
int blob_write_text(blob *b, const char *text);
|
||||
|
||||
int blob_write_bytes(blob *b, void *data, size_t length);
|
||||
|
||||
// Read operations (only work on stone blobs)
|
||||
int blob_read_bit(const blob *b, size_t pos, int *out_bit);
|
||||
blob *blob_read_blob(const blob *b, size_t from, size_t to);
|
||||
@@ -332,7 +334,7 @@ int blob_write_kim(blob *b, int64_t value) {
|
||||
|
||||
// Write the kim bytes as bits
|
||||
for (int i = 0; i < bytes; i++) {
|
||||
for (int j = 0; j < 8; b++) {
|
||||
for (int j = 0; j < 8; j++) {
|
||||
if (blob_write_bit(b, (kim_bytes[i] >> j) & 1) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "cgltf.h"
|
||||
#include "prosperon.h"
|
||||
|
||||
#include "qjs_blob.h"
|
||||
#include "qjs_dmon.h"
|
||||
#include "qjs_nota.h"
|
||||
#include "qjs_wota.h"
|
||||
@@ -262,10 +263,8 @@ JSValue make_gpu_buffer(JSContext *js, void *data, size_t size, int type, int el
|
||||
JSValue tstack[3];
|
||||
tstack[1] = JS_UNDEFINED;
|
||||
tstack[2] = JS_UNDEFINED;
|
||||
if (copy)
|
||||
tstack[0] = JS_NewArrayBufferCopy(js,data,size);//, make_gpu_buffer, NULL, 1);
|
||||
else
|
||||
tstack[0] = JS_NewArrayBuffer(js,data,size,free_gpu_buffer, NULL, 0);
|
||||
// TODO: always copying; implement "takeover"
|
||||
tstack[0] = js_new_blob_stoned_copy(js,data,size);//, make_gpu_buffer, NULL, 1);
|
||||
JSValue ret = JS_NewTypedArray(js, 3, tstack, type);
|
||||
JS_SetPropertyStr(js,ret,"stride", number2js(js,typed_array_bytes(type)*elements));
|
||||
JS_SetPropertyStr(js,ret,"elen", number2js(js,typed_array_bytes(type)));
|
||||
@@ -278,7 +277,7 @@ void *get_gpu_buffer(JSContext *js, JSValue argv, size_t *stride, size_t *size)
|
||||
{
|
||||
size_t o, len, bytes, msize;
|
||||
JSValue buf = JS_GetTypedArrayBuffer(js, argv, &o, &len, &bytes);
|
||||
void *data = JS_GetArrayBuffer(js, &msize, buf);
|
||||
void *data = js_get_blob_data(js, &msize, buf);
|
||||
JS_FreeValue(js,buf);
|
||||
if (stride) *stride = js_getnum_str(js, argv, "stride");
|
||||
if (size) *size = msize;
|
||||
@@ -755,15 +754,15 @@ JSValue js_util_camera_globals(JSContext *js, JSValue self, int argc, JSValue *a
|
||||
);
|
||||
|
||||
JS_SetPropertyStr(js, data, "world_to_projection",
|
||||
JS_NewArrayBufferCopy(js, world_to_projection.em,
|
||||
js_new_blob_stoned_copy(js, world_to_projection.em,
|
||||
sizeof(float)*16));
|
||||
JS_SetPropertyStr(js, data, "projection_to_world",
|
||||
JS_NewArrayBufferCopy(js, projection_to_world.em,
|
||||
js_new_blob_stoned_copy(js, projection_to_world.em,
|
||||
sizeof(float)*16));
|
||||
JS_SetPropertyStr(js, data, "world_to_view",
|
||||
JS_NewArrayBufferCopy(js, view.em, sizeof(float)*16));
|
||||
js_new_blob_stoned_copy(js, view.em, sizeof(float)*16));
|
||||
JS_SetPropertyStr(js, data, "view_to_projection",
|
||||
JS_NewArrayBufferCopy(js, proj.em, sizeof(float)*16));
|
||||
js_new_blob_stoned_copy(js, proj.em, sizeof(float)*16));
|
||||
|
||||
JS_SetPropertyStr(js, data, "camera_pos_world", vec32js(js, pos));
|
||||
JS_SetPropertyStr(js, data, "camera_dir_world", vec32js(js, camera_dir_world));
|
||||
@@ -1003,7 +1002,7 @@ static const JSCFunctionListEntry js_font_funcs[] = {
|
||||
// input: (encoded image data of jpg, png, bmp, tiff)
|
||||
JSC_CCALL(os_make_texture,
|
||||
size_t len;
|
||||
void *raw = JS_GetArrayBuffer(js, &len, argv[0]);
|
||||
void *raw = js_get_blob_data(js, &len, argv[0]);
|
||||
if (!raw) return JS_ThrowReferenceError(js, "could not load texture with array buffer");
|
||||
|
||||
int n, width, height;
|
||||
@@ -1026,7 +1025,7 @@ JSC_CCALL(os_make_texture,
|
||||
JS_SetPropertyStr(js, obj, "height", JS_NewInt32(js, height));
|
||||
JS_SetPropertyStr(js, obj, "format", JS_NewString(js, "rgba32"));
|
||||
JS_SetPropertyStr(js, obj, "pitch", JS_NewInt32(js, pitch));
|
||||
JS_SetPropertyStr(js, obj, "pixels", JS_NewArrayBufferCopy(js, data, pixels_size));
|
||||
JS_SetPropertyStr(js, obj, "pixels", js_new_blob_stoned_copy(js, data, pixels_size));
|
||||
|
||||
free(data);
|
||||
ret = obj;
|
||||
@@ -1036,7 +1035,7 @@ JSC_CCALL(os_make_texture,
|
||||
// input: (gif image data)
|
||||
JSC_CCALL(os_make_gif,
|
||||
size_t rawlen;
|
||||
void *raw = JS_GetArrayBuffer(js, &rawlen, argv[0]);
|
||||
void *raw = js_get_blob_data(js, &rawlen, argv[0]);
|
||||
if (!raw) return JS_ThrowReferenceError(js, "could not load gif from supplied array buffer");
|
||||
|
||||
int n;
|
||||
@@ -1056,7 +1055,7 @@ JSC_CCALL(os_make_gif,
|
||||
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_NewArrayBufferCopy(js, pixels, width*height*4));
|
||||
JS_SetPropertyStr(js, surfData, "pixels", js_new_blob_stoned_copy(js, pixels, width*height*4));
|
||||
JS_SetPropertyStr(js, gif, "surface", surfData);
|
||||
return gif;
|
||||
}
|
||||
@@ -1075,7 +1074,7 @@ JSC_CCALL(os_make_gif,
|
||||
JS_SetPropertyStr(js, surfData, "pitch", JS_NewInt32(js, width*4));
|
||||
|
||||
void *frame_pixels = (unsigned char*)pixels+(width*height*4*i);
|
||||
JS_SetPropertyStr(js, surfData, "pixels", JS_NewArrayBufferCopy(js, frame_pixels, width*height*4));
|
||||
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);
|
||||
@@ -1098,7 +1097,7 @@ JSValue aseframe2js(JSContext *js, ase_frame_t aframe)
|
||||
JS_SetPropertyStr(js, surfData, "height", JS_NewInt32(js, aframe.ase->h));
|
||||
JS_SetPropertyStr(js, surfData, "format", JS_NewString(js, "rgba32"));
|
||||
JS_SetPropertyStr(js, surfData, "pitch", JS_NewInt32(js, aframe.ase->w*4));
|
||||
JS_SetPropertyStr(js, surfData, "pixels", JS_NewArrayBufferCopy(js, aframe.pixels, aframe.ase->w*aframe.ase->h*4));
|
||||
JS_SetPropertyStr(js, surfData, "pixels", js_new_blob_stoned_copy(js, aframe.pixels, aframe.ase->w*aframe.ase->h*4));
|
||||
|
||||
JS_SetPropertyStr(js, frame, "surface", surfData);
|
||||
JS_SetPropertyStr(js, frame, "time", number2js(js,(float)aframe.duration_milliseconds/1000.0));
|
||||
@@ -1108,7 +1107,7 @@ JSValue aseframe2js(JSContext *js, ase_frame_t aframe)
|
||||
// input: (aseprite data)
|
||||
JSC_CCALL(os_make_aseprite,
|
||||
size_t rawlen;
|
||||
void *raw = JS_GetArrayBuffer(js,&rawlen,argv[0]);
|
||||
void *raw = js_get_blob_data(js,&rawlen,argv[0]);
|
||||
|
||||
ase_t *ase = cute_aseprite_load_from_memory(raw, rawlen, NULL);
|
||||
|
||||
@@ -1160,7 +1159,7 @@ JSC_CCALL(os_make_aseprite,
|
||||
|
||||
JSC_CCALL(os_make_font,
|
||||
size_t len;
|
||||
void *data = JS_GetArrayBuffer(js,&len,argv[0]);
|
||||
void *data = js_get_blob_data(js,&len,argv[0]);
|
||||
if (!data) return JS_ThrowReferenceError(js, "could not get array buffer data");
|
||||
font *f = MakeFont(data, len, js2number(js,argv[1]));
|
||||
if (!f) return JS_ThrowReferenceError(js, "could not create font");
|
||||
@@ -1183,7 +1182,7 @@ JSC_CCALL(os_make_font,
|
||||
}
|
||||
|
||||
size_t byte_size = f->surface->pitch * f->surface->h;
|
||||
JS_SetPropertyStr(js, surfData, "pixels", JS_NewArrayBufferCopy(js, f->surface->pixels, byte_size));
|
||||
JS_SetPropertyStr(js, surfData, "pixels", js_new_blob_stoned_copy(js, f->surface->pixels, byte_size));
|
||||
|
||||
if (locked)
|
||||
SDL_UnlockSurface(f->surface);
|
||||
@@ -1256,7 +1255,7 @@ static void render_frame(plm_t *mpeg, plm_frame_t *frame, datastream *ds) {
|
||||
JS_SetPropertyStr(ds->js, surfData, "height", JS_NewInt32(ds->js, frame->height));
|
||||
JS_SetPropertyStr(ds->js, surfData, "format", JS_NewString(ds->js, "rgba32"));
|
||||
JS_SetPropertyStr(ds->js, surfData, "pitch", JS_NewInt32(ds->js, frame->width*4));
|
||||
JS_SetPropertyStr(ds->js, surfData, "pixels", JS_NewArrayBufferCopy(ds->js, rgb, frame->height*frame->width*4));
|
||||
JS_SetPropertyStr(ds->js, surfData, "pixels", js_new_blob_stoned_copy(ds->js, rgb, frame->height*frame->width*4));
|
||||
|
||||
JSValue s[1];
|
||||
s[0] = surfData;
|
||||
@@ -1269,7 +1268,7 @@ static void render_frame(plm_t *mpeg, plm_frame_t *frame, datastream *ds) {
|
||||
|
||||
JSC_CCALL(os_make_video,
|
||||
size_t len;
|
||||
void *data = JS_GetArrayBuffer(js,&len,argv[0]);
|
||||
void *data = js_get_blob_data(js,&len,argv[0]);
|
||||
datastream *ds = ds_openvideo(data, len);
|
||||
if (!ds) return JS_ThrowReferenceError(js, "Video file was not valid.");
|
||||
ds->js = js;
|
||||
@@ -1420,7 +1419,7 @@ JSC_CCALL(graphics_save_png,
|
||||
JS_ToInt32(js, &h, argv[2]);
|
||||
JS_ToInt32(js, &pitch, argv[4]);
|
||||
size_t size;
|
||||
void *data = JS_GetArrayBuffer(js, &size, argv[3]);
|
||||
void *data = js_get_blob_data(js, &size, argv[3]);
|
||||
|
||||
if (!stbi_write_png(file, w, h, 4, data, pitch))
|
||||
return JS_ThrowInternalError(js, "Could not write png");
|
||||
@@ -1435,7 +1434,7 @@ JSC_CCALL(graphics_save_jpg,
|
||||
JS_ToInt32(js, &quality, argv[5]);
|
||||
if (!quality) quality = 80;
|
||||
size_t size;
|
||||
void *data = JS_GetArrayBuffer(js, &size, argv[3]);
|
||||
void *data = js_get_blob_data(js, &size, argv[3]);
|
||||
|
||||
if (!stbi_write_jpg(file, w, h, 4, data, quality))
|
||||
return JS_ThrowInternalError(js, "Could not write png");
|
||||
@@ -1525,7 +1524,6 @@ JSC_CCALL(os_value_id,
|
||||
|
||||
#include "qjs_crypto.h"
|
||||
#include "qjs_time.h"
|
||||
#include "qjs_blob.h"
|
||||
#include "qjs_http.h"
|
||||
|
||||
//JSValue js_imgui_use(JSContext *js);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
#include "quickjs.h"
|
||||
#include "qjs_blob.h"
|
||||
|
||||
#define STATE_VECTOR_LENGTH 624
|
||||
#define STATE_VECTOR_M 397
|
||||
|
||||
@@ -598,4 +598,31 @@ JSValue js_blob_use(JSContext *js) {
|
||||
JS_NewCFunction(js, js_blob_kim_length, "kim_length", 1));
|
||||
|
||||
return ctor;
|
||||
}
|
||||
}
|
||||
|
||||
JSValue js_new_blob_stoned_copy(JSContext *js, void *data, size_t bytes)
|
||||
{
|
||||
printf("Making blob from %p with %u bytes\n", data, bytes);
|
||||
blob *b = blob_new(bytes*8);
|
||||
memcpy(b->data, data, bytes);
|
||||
blob_make_stone(b);
|
||||
|
||||
return blob2js(js, b);
|
||||
}
|
||||
|
||||
void *js_get_blob_data(JSContext *js, size_t *size, JSValue v)
|
||||
{
|
||||
blob *b = js2blob(js, v);
|
||||
if (!b || !b->is_stone)
|
||||
return NULL;
|
||||
|
||||
*size = b->bit_capacity/8;
|
||||
return b->data;
|
||||
}
|
||||
|
||||
int js_is_blob(JSContext *js, JSValue v)
|
||||
{
|
||||
blob *b = js2blob(js,v);
|
||||
if (b) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -5,4 +5,13 @@
|
||||
|
||||
JSValue js_blob_use(JSContext *ctx);
|
||||
|
||||
// makes a new stone blob from data, copying the data over
|
||||
JSValue js_new_blob_stoned_copy(JSContext *js, void *data, size_t bytes);
|
||||
|
||||
// returns undefined if the blob is not stone
|
||||
void *js_get_blob_data(JSContext *js, size_t *size, JSValue v);
|
||||
|
||||
int js_is_blob(JSContext *js, JSValue v);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -151,7 +151,7 @@ static JSValue js_enet_host_service(JSContext *ctx, JSValueConst this_val, int a
|
||||
|
||||
// Pass raw data as string or ArrayBuffer
|
||||
if (event.packet->dataLength > 0) {
|
||||
JSValue data_val = JS_NewArrayBufferCopy(ctx, event.packet->data, event.packet->dataLength);
|
||||
JSValue data_val = js_new_blob_stoned_copy(ctx, event.packet->data, event.packet->dataLength);
|
||||
JS_SetPropertyStr(ctx, event_obj, "data", data_val);
|
||||
}
|
||||
enet_packet_destroy(event.packet);
|
||||
@@ -220,8 +220,8 @@ static JSValue js_enet_host_broadcast(JSContext *ctx, JSValueConst this_val, int
|
||||
if (JS_IsString(argv[0])) {
|
||||
data_str = JS_ToCStringLen(ctx, &data_len, argv[0]);
|
||||
if (!data_str) return JS_EXCEPTION;
|
||||
} else if (JS_IsArrayBuffer(ctx,argv[0])) {
|
||||
buf = JS_GetArrayBuffer(ctx, &data_len, argv[0]);
|
||||
} else if (js_is_blob(ctx,argv[0])) {
|
||||
buf = js_get_blob_data(ctx, &data_len, argv[0]);
|
||||
if (!buf) return JS_EXCEPTION;
|
||||
} else {
|
||||
return JS_ThrowTypeError(ctx, "broadcast() only accepts a string or ArrayBuffer");
|
||||
@@ -283,8 +283,8 @@ static JSValue js_enet_peer_send(JSContext *ctx, JSValueConst this_val, int argc
|
||||
if (JS_IsString(argv[0])) {
|
||||
data_str = JS_ToCStringLen(ctx, &data_len, argv[0]);
|
||||
if (!data_str) return JS_EXCEPTION;
|
||||
} else if (JS_IsArrayBuffer(ctx,argv[0])) {
|
||||
buf = JS_GetArrayBuffer(ctx, &data_len, argv[0]);
|
||||
} else if (js_is_blob(ctx,argv[0])) {
|
||||
buf = js_get_blob_data(ctx, &data_len, argv[0]);
|
||||
if (!buf) return JS_EXCEPTION;
|
||||
} else {
|
||||
return JS_ThrowTypeError(ctx, "send() only accepts a string or ArrayBuffer");
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include "wildmatch.h"
|
||||
#include "prosperon.h"
|
||||
|
||||
// File descriptor wrapper structure
|
||||
typedef struct {
|
||||
@@ -69,7 +70,7 @@ static ssize_t js_fd_write_helper(JSContext *js, int fd, JSValue val)
|
||||
wrote = write(fd, data, len);
|
||||
JS_FreeCString(js, data);
|
||||
} else {
|
||||
unsigned char *data = JS_GetArrayBuffer(js, &len, val);
|
||||
unsigned char *data = js_get_blob_data(js, &len, val);
|
||||
wrote = write(fd, data, len);
|
||||
}
|
||||
return wrote;
|
||||
@@ -200,7 +201,7 @@ JSC_SCALL(fd_slurpbytes,
|
||||
goto END;
|
||||
}
|
||||
|
||||
ret = JS_NewArrayBufferCopy(js, data, st.st_size);
|
||||
ret = js_new_blob_stoned_copy(js, data, st.st_size);
|
||||
free(data);
|
||||
|
||||
END:
|
||||
@@ -408,7 +409,7 @@ JSC_CCALL(file_read,
|
||||
return JS_ThrowReferenceError(js, "read failed: %s", strerror(errno));
|
||||
}
|
||||
|
||||
ret = JS_NewArrayBufferCopy(js, buf, bytes_read);
|
||||
ret = js_new_blob_stoned_copy(js, buf, bytes_read);
|
||||
free(buf);
|
||||
return ret;
|
||||
)
|
||||
|
||||
@@ -642,10 +642,10 @@ JSC_CCALL(gpu_make_sprite_queue,
|
||||
size_t quads = 0;
|
||||
int needfree = 1;
|
||||
|
||||
if (JS_IsArrayBuffer(js, argv[0])) {
|
||||
if (js_is_blob(js, argv[0])) {
|
||||
// test for fastest
|
||||
size_t size;
|
||||
sprite *sprites = JS_GetArrayBuffer(js, &size, argv[0]);
|
||||
sprite *sprites = js_get_blob_data(js, &size, argv[0]);
|
||||
quads = size/sizeof(*sprites);
|
||||
needfree = 0;
|
||||
for (int i = 0; i < quads; i++)
|
||||
@@ -778,7 +778,7 @@ JSC_CCALL(geometry_rect_transform,
|
||||
rect r = js2rect(js, argv[0]);
|
||||
// argv[1] = world_to_projection (16 floats)
|
||||
size_t byte_len;
|
||||
float *data12 = JS_GetArrayBuffer(js, &byte_len, argv[1]);
|
||||
float *data12 = js_get_blob_data(js, &byte_len, argv[1]);
|
||||
HMM_Mat4 wp; memcpy(wp.Elements, data12, sizeof(wp.Elements));
|
||||
|
||||
// make our two corners at z=0
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <mbedtls/ctr_drbg.h>
|
||||
#include <mbedtls/error.h>
|
||||
#include <ctype.h>
|
||||
#include "prosperon.h"
|
||||
|
||||
typedef struct {
|
||||
char *data;
|
||||
@@ -647,7 +648,7 @@ static JSValue js_fetch_read_chunk(JSContext *ctx, JSValueConst this_val, int ar
|
||||
}
|
||||
|
||||
// Return chunk as ArrayBuffer
|
||||
result = JS_NewArrayBufferCopy(ctx, buf, actual_len);
|
||||
result = js_new_blob_stoned_copy(ctx, buf, actual_len);
|
||||
js_free(ctx, buf);
|
||||
|
||||
return result;
|
||||
@@ -795,7 +796,7 @@ static JSValue js_fetch(JSContext *ctx, JSValueConst this_val, int argc, JSValue
|
||||
|
||||
if (body) {
|
||||
// Return body as ArrayBuffer
|
||||
result = JS_NewArrayBufferCopy(ctx, (uint8_t *)body, body_len);
|
||||
result = js_new_blob_stoned_copy(ctx, (uint8_t *)body, body_len);
|
||||
} else {
|
||||
result = JS_ThrowInternalError(ctx, "Failed to parse HTTP response");
|
||||
}
|
||||
|
||||
@@ -202,7 +202,7 @@ JSC_SCALL(imgui_barplot,
|
||||
JSC_SCALL(imgui_histogramplot,
|
||||
size_t offset, len, per_e;
|
||||
JSValue typed = JS_GetTypedArrayBuffer(js, argv[1], &offset, &len, &per_e);
|
||||
ImPlot::PlotHistogram(str, JS_GetArrayBuffer(js, NULL, typed), JS_ArrayLength(js, argv[1]));
|
||||
ImPlot::PlotHistogram(str, js_get_blob_data(js, NULL, typed), JS_ArrayLength(js, argv[1]));
|
||||
JS_FreeValue(js, typed);
|
||||
)
|
||||
|
||||
@@ -312,7 +312,7 @@ JSC_SCALL(imgui_intslider,
|
||||
JSValue arr = JS_NewTypedArray(js, 1, &argv[1], JS_TYPED_ARRAY_INT32);
|
||||
size_t len;
|
||||
JSValue buf = JS_GetTypedArrayBuffer(js, arr, NULL, &len, NULL);
|
||||
int *data = (int*)JS_GetArrayBuffer(js, NULL, buf);
|
||||
int *data = (int*)js_get_blob_data(js, NULL, buf);
|
||||
|
||||
switch(len) {
|
||||
case 2:
|
||||
|
||||
@@ -30,7 +30,7 @@ static size_t js_physfs_write(JSContext *js, PHYSFS_File *f, JSValue val)
|
||||
wrote = PHYSFS_writeBytes(f,data,len);
|
||||
JS_FreeCString(js,data);
|
||||
} else {
|
||||
unsigned char *data = JS_GetArrayBuffer(js,&len,val);
|
||||
unsigned char *data = js_get_blob_data(js,&len,val);
|
||||
wrote = PHYSFS_writeBytes(f,data,len);
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ JSC_SCALL(io_slurpbytes,
|
||||
void *data = malloc(stat.filesize);
|
||||
PHYSFS_readBytes(f,data,stat.filesize);
|
||||
PHYSFS_close(f);
|
||||
ret = JS_NewArrayBufferCopy(js,data,stat.filesize);
|
||||
ret = js_new_blob_stoned_copy(js,data,stat.filesize);
|
||||
|
||||
END:
|
||||
)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "quickjs.h"
|
||||
#include "prosperon.h"
|
||||
|
||||
#define KIM_IMPLEMENTATION
|
||||
#define NOTA_IMPLEMENTATION
|
||||
@@ -67,7 +68,7 @@ char *js_do_nota_decode(JSContext *js, JSValue *tmp, char *nota, JSValue holder,
|
||||
switch(type) {
|
||||
case NOTA_BLOB:
|
||||
nota = nota_read_blob(&n, (char**)&blob, nota);
|
||||
*tmp = JS_NewArrayBufferCopy(js, blob, n);
|
||||
*tmp = js_new_blob_stoned_copy(js, blob, n);
|
||||
free(blob);
|
||||
break;
|
||||
case NOTA_TEXT:
|
||||
@@ -164,9 +165,9 @@ static void nota_encode_value(NotaEncodeContext *enc, JSValueConst val, JSValueC
|
||||
nota_write_sym(&enc->nb, NOTA_NULL);
|
||||
break;
|
||||
case JS_TAG_OBJECT: {
|
||||
if (JS_IsArrayBuffer(ctx, replaced)) {
|
||||
if (js_is_blob(ctx, replaced)) {
|
||||
size_t buf_len;
|
||||
void *buf_data = JS_GetArrayBuffer(ctx, &buf_len, replaced);
|
||||
void *buf_data = js_get_blob_data(ctx, &buf_len, replaced);
|
||||
nota_write_blob(&enc->nb, (unsigned long long)buf_len * 8, (const char*)buf_data);
|
||||
break;
|
||||
}
|
||||
@@ -304,7 +305,7 @@ static JSValue js_nota_encode(JSContext *ctx, JSValueConst this_val, int argc, J
|
||||
JS_FreeValue(ctx, enc->visitedStack);
|
||||
size_t total_len = enc->nb.size;
|
||||
void *data_ptr = enc->nb.data;
|
||||
JSValue ret = JS_NewArrayBufferCopy(ctx, (uint8_t*)data_ptr, total_len);
|
||||
JSValue ret = js_new_blob_stoned_copy(ctx, (uint8_t*)data_ptr, total_len);
|
||||
|
||||
nota_buffer_free(&enc->nb);
|
||||
return ret;
|
||||
@@ -314,7 +315,7 @@ static JSValue js_nota_decode(JSContext *js, JSValueConst self, int argc, JSValu
|
||||
if (argc < 1) return JS_UNDEFINED;
|
||||
|
||||
size_t len;
|
||||
unsigned char *nota = JS_GetArrayBuffer(js, &len, argv[0]);
|
||||
unsigned char *nota = js_get_blob_data(js, &len, argv[0]);
|
||||
if (!nota) return JS_UNDEFINED;
|
||||
|
||||
JSValue reviver = (argc > 1 && JS_IsFunction(js, argv[1])) ? argv[1] : JS_UNDEFINED;
|
||||
|
||||
@@ -182,7 +182,7 @@ JSC_CCALL(os_buffer2string,
|
||||
}
|
||||
|
||||
size_t len;
|
||||
uint8_t *buf = JS_GetArrayBuffer(js, &len, argv[0]);
|
||||
uint8_t *buf = js_get_blob_data(js, &len, argv[0]);
|
||||
if (!buf) {
|
||||
return JS_ThrowTypeError(js, "First argument must be an ArrayBuffer");
|
||||
}
|
||||
@@ -262,7 +262,7 @@ JSC_CCALL(os_trace_img,
|
||||
double width, height;
|
||||
JS_ToFloat64(js,&width,argv[1]);
|
||||
JS_ToFloat64(js,&height,argv[2]);
|
||||
___tracy_emit_frame_image(JS_GetArrayBuffer(js, &len, argv[0]), width, height, 0, 0);
|
||||
___tracy_emit_frame_image(js_get_blob_data(js, &len, argv[0]), width, height, 0, 0);
|
||||
)
|
||||
|
||||
JSC_CCALL(os_trace_message,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "quickjs.h"
|
||||
#include "quirc.h"
|
||||
#include "qrencode.h"
|
||||
#include "prosperon.h"
|
||||
|
||||
#include <math.h> // for sqrt
|
||||
#include <stdlib.h> // for size_t, etc.
|
||||
@@ -102,7 +103,7 @@ static JSValue js_qr_encode(JSContext *js, JSValueConst this_val, int argc, JSVa
|
||||
} else {
|
||||
/* treat everything else as raw bytes */
|
||||
use_byte_mode = 1;
|
||||
uint8_t *buf = JS_GetArrayBuffer(js, &data_len, argv[0]);
|
||||
uint8_t *buf = js_get_blob_data(js, &data_len, argv[0]);
|
||||
if (!buf) {
|
||||
return JS_ThrowTypeError(js, "encode expects a string or ArrayBuffer");
|
||||
}
|
||||
@@ -160,7 +161,7 @@ static JSValue js_qr_decode(JSContext *js, JSValueConst this_val, int argc, JSVa
|
||||
size_t data_len;
|
||||
uint8_t *src;
|
||||
int w, h, pitch;
|
||||
src = JS_GetArrayBuffer(js, &data_len, argv[0]);
|
||||
src = js_get_blob_data(js, &data_len, argv[0]);
|
||||
|
||||
if (!src)
|
||||
return JS_ThrowTypeError(js, "decode expects an ArrayBuffer");
|
||||
@@ -213,7 +214,7 @@ static JSValue js_qr_decode(JSContext *js, JSValueConst this_val, int argc, JSVa
|
||||
quirc_extract(qr, i, &code);
|
||||
int err = quirc_decode(&code, &qdata);
|
||||
if (err == QUIRC_SUCCESS) {
|
||||
JSValue item = JS_NewArrayBufferCopy(js, qdata.payload, qdata.payload_len);
|
||||
JSValue item = js_new_blob_stoned_copy(js, qdata.payload, qdata.payload_len);
|
||||
JS_SetPropertyUint32(js, result, i, item);
|
||||
} else {
|
||||
printf("QR error: %s\n", quirc_strerror(err));
|
||||
@@ -272,7 +273,7 @@ static JSValue js_qr_rgba(JSContext *js, JSValueConst self, int argc, JSValueCon
|
||||
}
|
||||
}
|
||||
|
||||
JSValue ab = JS_NewArrayBufferCopy(js, tmp, bytes); /* GC owns copy */
|
||||
JSValue ab = js_new_blob_stoned_copy(js, tmp, bytes); /* GC owns copy */
|
||||
js_free(js, tmp);
|
||||
JS_FreeValue(js, js_bits); /* done with src */
|
||||
|
||||
|
||||
107
source/qjs_sdl.c
107
source/qjs_sdl.c
@@ -6,6 +6,8 @@
|
||||
#include "qjs_actor.h"
|
||||
#include "qjs_sdl_surface.h"
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
// SDL Free functions
|
||||
void SDL_Camera_free(JSRuntime *rt, SDL_Camera *cam)
|
||||
{
|
||||
@@ -46,7 +48,15 @@ static JSValue js_keymod(JSContext *js)
|
||||
}
|
||||
|
||||
// INPUT FUNCTIONS
|
||||
// Thread-safe keyboard functions remain here
|
||||
JSC_CCALL(input_mouse_lock, SDL_CaptureMouse(JS_ToBool(js,argv[0])))
|
||||
|
||||
JSC_CCALL(input_mouse_show,
|
||||
if (JS_ToBool(js,argv[0]))
|
||||
SDL_ShowCursor();
|
||||
else
|
||||
SDL_HideCursor();
|
||||
)
|
||||
|
||||
JSC_CCALL(input_keyname,
|
||||
return JS_NewString(js, SDL_GetKeyName(js2number(js,argv[0])));
|
||||
)
|
||||
@@ -55,7 +65,30 @@ JSC_CCALL(input_keymod,
|
||||
return js_keymod(js);
|
||||
)
|
||||
|
||||
JSC_CCALL(input_mousestate,
|
||||
float x,y;
|
||||
SDL_MouseButtonFlags flags = SDL_GetMouseState(&x,&y);
|
||||
JSValue m = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js,m,"x", number2js(js,x));
|
||||
JS_SetPropertyStr(js,m,"y", number2js(js,y));
|
||||
|
||||
if (flags & SDL_BUTTON_LMASK)
|
||||
JS_SetPropertyStr(js, m, "left", JS_NewBool(js, 1));
|
||||
if (flags & SDL_BUTTON_MMASK)
|
||||
JS_SetPropertyStr(js, m, "middle", JS_NewBool(js, 1));
|
||||
if (flags & SDL_BUTTON_RMASK)
|
||||
JS_SetPropertyStr(js, m, "right", JS_NewBool(js, 1));
|
||||
if (flags & SDL_BUTTON_X1MASK)
|
||||
JS_SetPropertyStr(js, m, "x1", JS_NewBool(js, 1));
|
||||
if (flags & SDL_BUTTON_X2MASK)
|
||||
JS_SetPropertyStr(js, m, "x2", JS_NewBool(js, 1));
|
||||
|
||||
return m;
|
||||
)
|
||||
|
||||
// watch events
|
||||
extern char **event_watchers;
|
||||
extern SDL_Mutex *event_watchers_mutex;
|
||||
|
||||
JSC_CCALL(input_watch,
|
||||
/* Use js2actor to get the actor from the JS object */
|
||||
@@ -106,8 +139,11 @@ JSC_CCALL(input_unwatch,
|
||||
)
|
||||
|
||||
static const JSCFunctionListEntry js_input_funcs[] = {
|
||||
MIST_FUNC_DEF(input, mouse_show, 1),
|
||||
MIST_FUNC_DEF(input, mouse_lock, 1),
|
||||
MIST_FUNC_DEF(input, keyname, 1),
|
||||
MIST_FUNC_DEF(input, keymod, 0),
|
||||
MIST_FUNC_DEF(input, mousestate, 0),
|
||||
MIST_FUNC_DEF(input, watch, 1),
|
||||
MIST_FUNC_DEF(input, unwatch, 1),
|
||||
};
|
||||
@@ -115,6 +151,11 @@ static const JSCFunctionListEntry js_input_funcs[] = {
|
||||
JSValue js_input_use(JSContext *js) {
|
||||
JSValue mod = JS_NewObject(js);
|
||||
JS_SetPropertyFunctionList(js,mod,js_input_funcs,countof(js_input_funcs));
|
||||
|
||||
// Initialize SDL cursor class (no functions)
|
||||
JSValue c_types = JS_GetPropertyStr(js, JS_GetGlobalObject(js), "c_types");
|
||||
JS_FreeValue(js, c_types);
|
||||
|
||||
return mod;
|
||||
}
|
||||
|
||||
@@ -254,50 +295,14 @@ SDL_PixelFormat str2pixelformat(const char *str) {
|
||||
if (!strcmp(str, "nv12")) return SDL_PIXELFORMAT_NV12;
|
||||
if (!strcmp(str, "nv21")) return SDL_PIXELFORMAT_NV21;
|
||||
if (!strcmp(str, "p010")) return SDL_PIXELFORMAT_P010;
|
||||
if (!strcmp(str, "rgba32")) return SDL_PIXELFORMAT_RGBA32;
|
||||
return SDL_PIXELFORMAT_UNKNOWN;
|
||||
}
|
||||
|
||||
const char *colorspace2str(SDL_Colorspace colorspace) {
|
||||
switch(colorspace) {
|
||||
case SDL_COLORSPACE_UNKNOWN: return "unknown";
|
||||
case SDL_COLORSPACE_SRGB: return "srgb";
|
||||
case SDL_COLORSPACE_SRGB_LINEAR: return "srgb_linear";
|
||||
case SDL_COLORSPACE_HDR10: return "hdr10";
|
||||
case SDL_COLORSPACE_JPEG: return "jpeg";
|
||||
case SDL_COLORSPACE_BT601_LIMITED: return "bt601_limited";
|
||||
case SDL_COLORSPACE_BT601_FULL: return "bt601_full";
|
||||
case SDL_COLORSPACE_BT709_LIMITED: return "bt709_limited";
|
||||
case SDL_COLORSPACE_BT709_FULL: return "bt709_full";
|
||||
case SDL_COLORSPACE_BT2020_LIMITED: return "bt2020_limited";
|
||||
case SDL_COLORSPACE_BT2020_FULL: return "bt2020_full";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Colorspace str2colorspace(const char *str) {
|
||||
if (!str) return SDL_COLORSPACE_UNKNOWN;
|
||||
|
||||
if (!strcmp(str, "unknown")) return SDL_COLORSPACE_UNKNOWN;
|
||||
if (!strcmp(str, "srgb")) return SDL_COLORSPACE_SRGB;
|
||||
if (!strcmp(str, "srgb_linear")) return SDL_COLORSPACE_SRGB_LINEAR;
|
||||
if (!strcmp(str, "hdr10")) return SDL_COLORSPACE_HDR10;
|
||||
if (!strcmp(str, "jpeg")) return SDL_COLORSPACE_JPEG;
|
||||
if (!strcmp(str, "bt601_limited")) return SDL_COLORSPACE_BT601_LIMITED;
|
||||
if (!strcmp(str, "bt601_full")) return SDL_COLORSPACE_BT601_FULL;
|
||||
if (!strcmp(str, "bt709_limited")) return SDL_COLORSPACE_BT709_LIMITED;
|
||||
if (!strcmp(str, "bt709_full")) return SDL_COLORSPACE_BT709_FULL;
|
||||
if (!strcmp(str, "bt2020_limited")) return SDL_COLORSPACE_BT2020_LIMITED;
|
||||
if (!strcmp(str, "bt2020_full")) return SDL_COLORSPACE_BT2020_FULL;
|
||||
|
||||
return SDL_COLORSPACE_UNKNOWN;
|
||||
}
|
||||
|
||||
static JSValue cameraspec2js(JSContext *js, const SDL_CameraSpec *spec) {
|
||||
JSValue obj = JS_NewObject(js);
|
||||
|
||||
JS_SetPropertyStr(js, obj, "format", JS_NewString(js, pixelformat2str(spec->format)));
|
||||
JS_SetPropertyStr(js, obj, "colorspace", JS_NewString(js, colorspace2str(spec->colorspace)));
|
||||
JS_SetPropertyStr(js, obj, "colorspace", JS_NewInt32(js, spec->colorspace));
|
||||
JS_SetPropertyStr(js, obj, "width", JS_NewInt32(js, spec->width));
|
||||
JS_SetPropertyStr(js, obj, "height", JS_NewInt32(js, spec->height));
|
||||
JS_SetPropertyStr(js, obj, "framerate_numerator", JS_NewInt32(js, spec->framerate_numerator));
|
||||
@@ -320,11 +325,7 @@ static SDL_CameraSpec js2cameraspec(JSContext *js, JSValue obj) {
|
||||
JS_FreeValue(js, v);
|
||||
|
||||
v = JS_GetPropertyStr(js, obj, "colorspace");
|
||||
if (!JS_IsUndefined(v)) {
|
||||
const char *s = JS_ToCString(js, v);
|
||||
spec.colorspace = str2colorspace(s);
|
||||
JS_FreeCString(js, s);
|
||||
}
|
||||
if (!JS_IsUndefined(v)) JS_ToInt32(js, &spec.colorspace, v);
|
||||
JS_FreeValue(js, v);
|
||||
|
||||
v = JS_GetPropertyStr(js, obj, "width");
|
||||
@@ -437,10 +438,24 @@ JSC_CCALL(camera_capture,
|
||||
}
|
||||
|
||||
// Create a copy of the surface
|
||||
SDL_Surface *newsurf = SDL_DuplicateSurface(surf);
|
||||
SDL_Surface *newsurf = SDL_CreateSurface(surf->w, surf->h, surf->format);
|
||||
|
||||
if (!newsurf) {
|
||||
SDL_ReleaseCameraFrame(cam, surf);
|
||||
return JS_ThrowReferenceError(js, "Could not create surface: %s", SDL_GetError());
|
||||
}
|
||||
|
||||
// Copy the surface data
|
||||
int result = SDL_BlitSurface(surf, NULL, newsurf, NULL);
|
||||
|
||||
// Release the camera frame
|
||||
SDL_ReleaseCameraFrame(cam, surf);
|
||||
|
||||
if (result != 0) {
|
||||
SDL_DestroySurface(newsurf);
|
||||
return JS_ThrowReferenceError(js, "Could not blit surface: %s", SDL_GetError());
|
||||
}
|
||||
|
||||
return SDL_Surface2js(js,newsurf);
|
||||
)
|
||||
|
||||
@@ -675,7 +690,7 @@ JSC_CCALL(sdl_audiostream_queued,
|
||||
JSC_CCALL(sdl_audiostream_put,
|
||||
SDL_AudioStream *as=js2SDL_AudioStream(js,self);
|
||||
size_t len;
|
||||
void *buf = JS_GetArrayBuffer(js, &len, argv[0]);
|
||||
void *buf = js_get_blob_data(js, &len, argv[0]);
|
||||
if (!buf)
|
||||
return JS_ThrowInternalError(js, "Requires array buffer.");
|
||||
|
||||
@@ -696,7 +711,7 @@ JSC_CCALL(sdl_audiostream_get,
|
||||
return JS_ThrowInternalError(js,"%s",SDL_GetError());
|
||||
}
|
||||
|
||||
JSValue ab = JS_NewArrayBufferCopy(js, data, got);
|
||||
JSValue ab = js_new_blob_stoned_copy(js, data, got);
|
||||
free(data);
|
||||
|
||||
return ab;
|
||||
|
||||
@@ -752,7 +752,7 @@ void *gpu_buffer_unpack(JSContext *js, SDL_GPUDevice *device, JSValue buffer, si
|
||||
{
|
||||
size_t o, len, bytes, msize;
|
||||
JSValue buf = JS_GetTypedArrayBuffer(js, buffer, &o, &len, &bytes);
|
||||
void *data = JS_GetArrayBuffer(js, &msize, buf);
|
||||
void *data = js_get_blob_data(js, &msize, buf);
|
||||
JS_FreeValue(js,buf);
|
||||
if (size) *size = msize;
|
||||
if (send_gpu) {
|
||||
@@ -1494,7 +1494,7 @@ static JSValue js_gpu_make_shader(JSContext *js, JSValueConst self, int argc, JS
|
||||
// code
|
||||
JSValue code_val = JS_GetPropertyStr(js, obj, "code");
|
||||
size_t code_size;
|
||||
void *code_data = JS_GetArrayBuffer(js, &code_size, code_val);
|
||||
void *code_data = js_get_blob_data(js, &code_size, code_val);
|
||||
JS_FreeValue(js, code_val);
|
||||
if (!code_data)
|
||||
return JS_ThrowTypeError(js, "shader.code must be an ArrayBuffer");
|
||||
@@ -1709,7 +1709,7 @@ JSC_CCALL(gpu_compute_pipeline,
|
||||
|
||||
|
||||
JSValue shader = JS_GetPropertyStr(js,pipe,"shader");
|
||||
info.code = JS_GetArrayBuffer(js,&info.code_size, shader);
|
||||
info.code = js_get_blob_data(js,&info.code_size, shader);
|
||||
JS_FreeValue(js,shader);
|
||||
|
||||
SDL_GPUComputePipeline *pipeline = SDL_CreateGPUComputePipeline(gpu, &info);
|
||||
@@ -1941,7 +1941,7 @@ JSC_CCALL(cmd_push_vertex_uniform_data,
|
||||
int slot;
|
||||
JS_ToInt32(js, &slot, argv[0]);
|
||||
size_t buf_size;
|
||||
void *data = JS_GetArrayBuffer(js, &buf_size, argv[1]);
|
||||
void *data = js_get_blob_data(js, &buf_size, argv[1]);
|
||||
SDL_PushGPUVertexUniformData(cmds, slot, data, buf_size);
|
||||
)
|
||||
|
||||
@@ -1950,7 +1950,7 @@ JSC_CCALL(cmd_push_fragment_uniform_data,
|
||||
int slot;
|
||||
JS_ToInt32(js, &slot, argv[0]);
|
||||
size_t buf_size;
|
||||
void *data = JS_GetArrayBuffer(js, &buf_size, argv[1]);
|
||||
void *data = js_get_blob_data(js, &buf_size, argv[1]);
|
||||
SDL_PushGPUFragmentUniformData(cmds, slot, data, buf_size);
|
||||
)
|
||||
|
||||
@@ -1959,7 +1959,7 @@ JSC_CCALL(cmd_push_compute_uniform_data,
|
||||
int slot;
|
||||
JS_ToInt32(js, &slot, argv[0]);
|
||||
size_t buf_size;
|
||||
void *data = JS_GetArrayBuffer(js, &buf_size, argv[1]);
|
||||
void *data = js_get_blob_data(js, &buf_size, argv[1]);
|
||||
SDL_PushGPUComputeUniformData(cmds, slot, data, buf_size);
|
||||
)
|
||||
|
||||
@@ -2183,7 +2183,7 @@ JSValue make_gpu_buffer(JSContext *js, void *data, size_t size, int type, int el
|
||||
{
|
||||
JSValue tstack[2];
|
||||
if (copy) {
|
||||
tstack[0] = JS_NewArrayBufferCopy(js,data,size);//, make_gpu_buffer, NULL, 1);
|
||||
tstack[0] = js_new_blob_stoned_copy(js,data,size);//, make_gpu_buffer, NULL, 1);
|
||||
} else {
|
||||
tstack[0] = JS_NewArrayBuffer(js,data,size,free_gpu_buffer, NULL, 0);
|
||||
}
|
||||
@@ -2211,7 +2211,7 @@ void *get_gpu_buffer(JSContext *js, JSValue argv, size_t *stride, size_t *size)
|
||||
}
|
||||
|
||||
JSValue buffer = JS_GetPropertyStr(js,argv,"buffer");
|
||||
void *data = JS_GetArrayBuffer(js,NULL,buffer);
|
||||
void *data = js_get_blob_data(js,NULL,buffer);
|
||||
JS_FreeValue(js,buffer);
|
||||
|
||||
JSValue typeval = JS_GetPropertyStr(js,argv,"type");
|
||||
|
||||
@@ -1,20 +1,29 @@
|
||||
#include "qjs_sdl_surface.h"
|
||||
#include "qjs_macros.h"
|
||||
#include "jsffi.h"
|
||||
#include "qjs_common.h"
|
||||
#include "qjs_sdl.h"
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_gpu.h>
|
||||
#include <SDL3/SDL_surface.h>
|
||||
#include "prosperon.h"
|
||||
#include <string.h>
|
||||
|
||||
// Helper functions from jsffi.c that need to be declared
|
||||
extern JSValue number2js(JSContext *js, double g);
|
||||
extern double js2number(JSContext *js, JSValue v);
|
||||
extern rect js2rect(JSContext *js, JSValue v);
|
||||
extern irect js2irect(JSContext *js, JSValue v);
|
||||
extern colorf js2color(JSContext *js, JSValue v);
|
||||
extern HMM_Vec2 js2vec2(JSContext *js, JSValue v);
|
||||
extern SDL_PixelFormat str2pixelformat(const char *str);
|
||||
extern const char *pixelformat2str(SDL_PixelFormat fmt);
|
||||
|
||||
JSValue pixelformat2js(JSContext *js, SDL_PixelFormat fmt)
|
||||
{
|
||||
const char *str = pixelformat2str(fmt);
|
||||
return JS_NewString(js, str);
|
||||
}
|
||||
|
||||
SDL_PixelFormat js2pixelformat(JSContext *js, JSValue v)
|
||||
static SDL_PixelFormat js2pixelformat(JSContext *js, JSValue v)
|
||||
{
|
||||
if (JS_IsUndefined(v)) return SDL_PIXELFORMAT_UNKNOWN;
|
||||
const char *s = JS_ToCString(js, v);
|
||||
@@ -25,17 +34,6 @@ SDL_PixelFormat js2pixelformat(JSContext *js, JSValue v)
|
||||
return fmt;
|
||||
}
|
||||
|
||||
SDL_Colorspace js2colorspace(JSContext *js, JSValue v)
|
||||
{
|
||||
if (JS_IsUndefined(v)) return SDL_COLORSPACE_UNKNOWN;
|
||||
const char *s = JS_ToCString(js, v);
|
||||
if (!s) return SDL_COLORSPACE_UNKNOWN;
|
||||
|
||||
SDL_Colorspace cs = str2colorspace(s);
|
||||
JS_FreeCString(js,s);
|
||||
return cs;
|
||||
}
|
||||
|
||||
typedef struct { const char *name; SDL_ScaleMode mode; } scale_entry;
|
||||
|
||||
static const scale_entry k_scale_table[] = {
|
||||
@@ -44,7 +42,7 @@ static const scale_entry k_scale_table[] = {
|
||||
{ NULL, SDL_SCALEMODE_LINEAR } /* fallback */
|
||||
};
|
||||
|
||||
JSValue SDL_ScaleMode2js(JSContext *js, SDL_ScaleMode mode){
|
||||
static JSValue scalemode2js(JSContext *js, SDL_ScaleMode mode){
|
||||
const scale_entry *it;
|
||||
for(it = k_scale_table; it->name; ++it)
|
||||
if(it->mode == mode) break;
|
||||
@@ -142,18 +140,7 @@ JSC_CCALL(surface_rect,
|
||||
JSC_CCALL(surface_convert,
|
||||
SDL_Surface *surf = js2SDL_Surface(js,self);
|
||||
SDL_PixelFormat fmt = js2pixelformat(js, argv[0]);
|
||||
|
||||
SDL_Surface *dst;
|
||||
if (argc > 1 && !JS_IsUndefined(argv[1])) {
|
||||
// Colorspace provided, use SDL_ConvertSurfaceAndColorspace
|
||||
SDL_Colorspace colorspace = js2colorspace(js, argv[1]);
|
||||
SDL_PropertiesID props = 0; // No additional properties needed
|
||||
dst = SDL_ConvertSurfaceAndColorspace(surf, fmt, NULL, colorspace, props);
|
||||
} else {
|
||||
// No colorspace, use regular convert
|
||||
dst = SDL_ConvertSurface(surf, fmt);
|
||||
}
|
||||
|
||||
SDL_Surface *dst = SDL_ConvertSurface(surf, fmt);
|
||||
if (!dst) return JS_ThrowInternalError(js, "Convert failed: %s", SDL_GetError());
|
||||
|
||||
return SDL_Surface2js(js, dst);
|
||||
@@ -168,32 +155,25 @@ JSC_CCALL(surface_dup,
|
||||
return SDL_Surface2js(js,conv);
|
||||
)
|
||||
|
||||
void *surface_pixel_dup(SDL_Surface *surf, size_t *size)
|
||||
{
|
||||
JSC_CCALL(surface_pixels,
|
||||
SDL_Surface *surf = js2SDL_Surface(js, self);
|
||||
|
||||
int locked = 0;
|
||||
if (SDL_MUSTLOCK(surf))
|
||||
if (SDL_LockSurface(surf) < 0)
|
||||
return NULL;
|
||||
return JS_ThrowReferenceError(js, "Lock surface failed: %s", SDL_GetError());
|
||||
|
||||
if (surf->format == SDL_PIXELFORMAT_NV12) {
|
||||
*size = surf->pitch * (surf->h*3.0/2.0);
|
||||
size_t byte_size;
|
||||
if (SDL_ISPIXELFORMAT_FOURCC(surf->format)) {
|
||||
/* Planar/YUV formats: use BitsPerPixel to compute true size */
|
||||
printf("FOURCC!!! Bits is %d\n", SDL_BYTESPERPIXEL(surf->format));
|
||||
byte_size = (size_t)surf->pitch * surf->h * SDL_BYTESPERPIXEL(surf->format);
|
||||
} else
|
||||
*size = (size_t)surf->pitch * surf->h;
|
||||
|
||||
void *data = malloc(*size);
|
||||
memcpy(data, surf->pixels, *size);
|
||||
|
||||
if (locked) SDL_UnlockSurface(surf);
|
||||
|
||||
return data;
|
||||
}
|
||||
byte_size = (size_t)surf->pitch * surf->h;
|
||||
|
||||
JSC_CCALL(surface_pixels,
|
||||
SDL_Surface *surf = js2SDL_Surface(js, self);
|
||||
|
||||
size_t size;
|
||||
void *data = surface_pixel_dup(surf, &size);
|
||||
return JS_NewArrayBufferCopy(js, data, size);
|
||||
ret = js_new_blob_stoned_copy(js, surf->pixels, byte_size);
|
||||
|
||||
if (locked) SDL_UnlockSurface(surf);
|
||||
)
|
||||
|
||||
JSC_CCALL(surface_get_width,
|
||||
@@ -232,10 +212,25 @@ JSC_CCALL(surface_toJSON,
|
||||
// Add pitch
|
||||
JS_SetPropertyStr(js, obj, "pitch", JS_NewInt32(js, surf->pitch));
|
||||
|
||||
size_t size;
|
||||
void *pixels = surface_pixel_dup(surf, &size);
|
||||
// Lock surface if needed
|
||||
int locked = 0;
|
||||
if (SDL_MUSTLOCK(surf)) {
|
||||
if (SDL_LockSurface(surf) < 0) {
|
||||
JS_FreeValue(js, obj);
|
||||
return JS_ThrowInternalError(js, "Lock surface failed: %s", SDL_GetError());
|
||||
}
|
||||
locked = 1;
|
||||
}
|
||||
|
||||
// Add pixels as ArrayBuffer
|
||||
size_t byte_size = surf->pitch * surf->h;
|
||||
JSValue pixels = js_new_blob_stoned_copy(js, surf->pixels, byte_size);
|
||||
JS_SetPropertyStr(js, obj, "pixels", pixels);
|
||||
|
||||
// Unlock if we locked
|
||||
if (locked)
|
||||
SDL_UnlockSurface(surf);
|
||||
|
||||
JS_SetPropertyStr(js, obj, "pixels", JS_NewArrayBufferCopy(js, pixels, size));
|
||||
return obj;
|
||||
)
|
||||
|
||||
@@ -265,7 +260,7 @@ JSC_CCALL(surface_constructor,
|
||||
if (!JS_IsUndefined(pixels_val)) {
|
||||
// Create surface from pixel data
|
||||
size_t len;
|
||||
void *raw = JS_GetArrayBuffer(js, &len, pixels_val);
|
||||
void *raw = js_get_blob_data(js, &len, pixels_val);
|
||||
|
||||
if (!raw) {
|
||||
JS_FreeValue(js, pixels_val);
|
||||
@@ -318,7 +313,7 @@ static const JSCFunctionListEntry js_SDL_Surface_funcs[] = {
|
||||
MIST_FUNC_DEF(surface, rect,2),
|
||||
MIST_FUNC_DEF(surface, dup, 0),
|
||||
MIST_FUNC_DEF(surface, pixels, 0),
|
||||
MIST_FUNC_DEF(surface, convert, 2),
|
||||
MIST_FUNC_DEF(surface, convert, 1),
|
||||
MIST_FUNC_DEF(surface, toJSON, 0),
|
||||
JS_CGETSET_DEF("width", js_surface_get_width, NULL),
|
||||
JS_CGETSET_DEF("height", js_surface_get_height, NULL),
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
#include "qjs_sdl_video.h"
|
||||
#include "jsffi.h"
|
||||
#include "qjs_macros.h"
|
||||
#include "qjs_common.h"
|
||||
#include "qjs_sdl_surface.h"
|
||||
#include "qjs_sdl.h"
|
||||
#include "qjs_actor.h"
|
||||
#include "prosperon.h"
|
||||
#include "sprite.h"
|
||||
@@ -53,6 +51,31 @@ void SDL_Cursor_free(JSRuntime *rt, SDL_Cursor *c)
|
||||
|
||||
QJSCLASS(SDL_Cursor,)
|
||||
|
||||
// External function declarations
|
||||
extern JSValue rect2js(JSContext *js, rect r);
|
||||
extern rect js2rect(JSContext *js, JSValue v);
|
||||
extern HMM_Vec2 js2vec2(JSContext *js, JSValue v);
|
||||
extern JSValue vec22js(JSContext *js, HMM_Vec2 v);
|
||||
extern colorf js2color(JSContext *js, JSValue v);
|
||||
extern double js2number(JSContext *js, JSValue v);
|
||||
extern JSValue number2js(JSContext *js, double n);
|
||||
extern SDL_Texture *js2SDL_Texture(JSContext *js, JSValue v);
|
||||
extern JSValue SDL_Texture2js(JSContext *js, SDL_Texture *t);
|
||||
extern SDL_Window *js2SDL_Window(JSContext *js, JSValue v);
|
||||
extern JSValue SDL_Window2js(JSContext *js, SDL_Window *w);
|
||||
extern SDL_Renderer *js2SDL_Renderer(JSContext *js, JSValue v);
|
||||
extern JSValue SDL_Renderer2js(JSContext *js, SDL_Renderer *r);
|
||||
extern void *get_gpu_buffer(JSContext *js, JSValue argv, size_t *stride, size_t *size);
|
||||
extern double js_getnum_str(JSContext *js, JSValue v, const char *str);
|
||||
extern sprite *js2sprite(JSContext *js, JSValue v);
|
||||
extern HMM_Vec3 js2vec3(JSContext *js, JSValue v);
|
||||
extern JSValue vec32js(JSContext *js, HMM_Vec3 v);
|
||||
extern HMM_Vec4 js2vec4(JSContext *js, JSValue v);
|
||||
extern JSValue vec42js(JSContext *js, HMM_Vec4 v);
|
||||
extern JSValue make_gpu_buffer(JSContext *js, void *data, size_t size, int type, int elements, int copy, int index);
|
||||
extern JSValue make_quad_indices_buffer(JSContext *js, int quads);
|
||||
extern JSClassID js_SDL_Surface_id;
|
||||
|
||||
// Forward declarations for blend mode helpers
|
||||
static JSValue blendmode2js(JSContext *js, SDL_BlendMode mode);
|
||||
static SDL_BlendMode js2blendmode(JSContext *js, JSValue v);
|
||||
@@ -1397,6 +1420,8 @@ static const JSCFunctionListEntry js_SDL_Renderer_funcs[] = {
|
||||
JS_CGETSET_DEF("safeArea", js_renderer_get_safeArea, NULL),
|
||||
};
|
||||
|
||||
extern SDL_ScaleMode js2SDL_ScaleMode(JSContext *js, JSValue v);
|
||||
|
||||
// Blend mode helper
|
||||
static JSValue blendmode2js(JSContext *js, SDL_BlendMode mode) {
|
||||
switch(mode) {
|
||||
@@ -1430,6 +1455,26 @@ static SDL_BlendMode js2blendmode(JSContext *js, JSValue v) {
|
||||
return mode;
|
||||
}
|
||||
|
||||
// Convert pixel format string to SDL_PixelFormat
|
||||
static SDL_PixelFormat js2pixelformat(JSContext *js, JSValue v) {
|
||||
if (JS_IsNumber(v)) {
|
||||
return js2number(js, v);
|
||||
}
|
||||
const char *str = JS_ToCString(js, v);
|
||||
SDL_PixelFormat fmt = SDL_PIXELFORMAT_RGBA8888;
|
||||
if (str) {
|
||||
if (strcmp(str, "rgba8888") == 0) fmt = SDL_PIXELFORMAT_RGBA8888;
|
||||
else if (strcmp(str, "bgra8888") == 0) fmt = SDL_PIXELFORMAT_BGRA8888;
|
||||
else if (strcmp(str, "argb8888") == 0) fmt = SDL_PIXELFORMAT_ARGB8888;
|
||||
else if (strcmp(str, "abgr8888") == 0) fmt = SDL_PIXELFORMAT_ABGR8888;
|
||||
else if (strcmp(str, "rgba32") == 0) fmt = SDL_PIXELFORMAT_RGBA32;
|
||||
else if (strcmp(str, "bgra32") == 0) fmt = SDL_PIXELFORMAT_BGRA32;
|
||||
else if (strcmp(str, "argb32") == 0) fmt = SDL_PIXELFORMAT_ARGB32;
|
||||
else if (strcmp(str, "abgr32") == 0) fmt = SDL_PIXELFORMAT_ABGR32;
|
||||
JS_FreeCString(js, str);
|
||||
}
|
||||
return fmt;
|
||||
}
|
||||
|
||||
// Texture constructor
|
||||
static JSValue js_texture_constructor(JSContext *js, JSValueConst new_target, int argc, JSValueConst *argv)
|
||||
@@ -1468,7 +1513,7 @@ static JSValue js_texture_constructor(JSContext *js, JSValueConst new_target, in
|
||||
if (!JS_IsUndefined(pixels_val)) {
|
||||
// Create surface first, then texture
|
||||
size_t size;
|
||||
uint8_t *pixels = JS_GetArrayBuffer(js, &size, pixels_val);
|
||||
uint8_t *pixels = js_get_blob_data(js, &size, pixels_val);
|
||||
|
||||
if (!pixels) {
|
||||
JS_FreeValue(js, pixels_val);
|
||||
@@ -1638,7 +1683,7 @@ JSC_CCALL(texture_update,
|
||||
|
||||
if (argc >= 2) {
|
||||
size_t size;
|
||||
pixels = JS_GetArrayBuffer(js, &size, argv[1]);
|
||||
pixels = js_get_blob_data(js, &size, argv[1]);
|
||||
if (!pixels)
|
||||
return JS_ThrowTypeError(js, "Second argument must be an ArrayBuffer");
|
||||
}
|
||||
@@ -1666,17 +1711,6 @@ JSC_CCALL(texture_lock,
|
||||
(lock_rect.w > 0 && lock_rect.h > 0) ? &lock_rect : NULL,
|
||||
&pixels, &pitch))
|
||||
return JS_ThrowReferenceError(js, "Failed to lock texture: %s", SDL_GetError());
|
||||
|
||||
// Create ArrayBuffer view of the locked pixels
|
||||
float w, h;
|
||||
SDL_GetTextureSize(tex, &w, &h);
|
||||
int height = lock_rect.h > 0 ? lock_rect.h : (int)h;
|
||||
size_t buffer_size = pitch * height;
|
||||
|
||||
ret = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, ret, "pixels", JS_NewArrayBuffer(js, pixels, buffer_size, NULL, NULL, 0));
|
||||
JS_SetPropertyStr(js, ret, "pitch", number2js(js, pitch));
|
||||
return ret;
|
||||
)
|
||||
|
||||
// Unlock texture
|
||||
@@ -1735,245 +1769,6 @@ JSC_CCALL(sdl_createWindowAndRenderer,
|
||||
return ret;
|
||||
)
|
||||
|
||||
// Mouse functions that must run on main thread
|
||||
JSC_CCALL(mouse_show,
|
||||
if (JS_ToBool(js,argv[0]))
|
||||
SDL_ShowCursor();
|
||||
else
|
||||
SDL_HideCursor();
|
||||
)
|
||||
|
||||
JSC_CCALL(mouse_capture,
|
||||
SDL_CaptureMouse(JS_ToBool(js,argv[0]));
|
||||
)
|
||||
|
||||
JSC_CCALL(mouse_get_state,
|
||||
float x,y;
|
||||
SDL_MouseButtonFlags flags = SDL_GetMouseState(&x,&y);
|
||||
JSValue m = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js,m,"x", number2js(js,x));
|
||||
JS_SetPropertyStr(js,m,"y", number2js(js,y));
|
||||
|
||||
if (flags & SDL_BUTTON_LMASK)
|
||||
JS_SetPropertyStr(js, m, "left", JS_NewBool(js, 1));
|
||||
if (flags & SDL_BUTTON_MMASK)
|
||||
JS_SetPropertyStr(js, m, "middle", JS_NewBool(js, 1));
|
||||
if (flags & SDL_BUTTON_RMASK)
|
||||
JS_SetPropertyStr(js, m, "right", JS_NewBool(js, 1));
|
||||
if (flags & SDL_BUTTON_X1MASK)
|
||||
JS_SetPropertyStr(js, m, "x1", JS_NewBool(js, 1));
|
||||
if (flags & SDL_BUTTON_X2MASK)
|
||||
JS_SetPropertyStr(js, m, "x2", JS_NewBool(js, 1));
|
||||
|
||||
return m;
|
||||
)
|
||||
|
||||
JSC_CCALL(mouse_get_global_state,
|
||||
float x,y;
|
||||
SDL_MouseButtonFlags flags = SDL_GetGlobalMouseState(&x,&y);
|
||||
JSValue m = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js,m,"x", number2js(js,x));
|
||||
JS_SetPropertyStr(js,m,"y", number2js(js,y));
|
||||
|
||||
if (flags & SDL_BUTTON_LMASK)
|
||||
JS_SetPropertyStr(js, m, "left", JS_NewBool(js, 1));
|
||||
if (flags & SDL_BUTTON_MMASK)
|
||||
JS_SetPropertyStr(js, m, "middle", JS_NewBool(js, 1));
|
||||
if (flags & SDL_BUTTON_RMASK)
|
||||
JS_SetPropertyStr(js, m, "right", JS_NewBool(js, 1));
|
||||
if (flags & SDL_BUTTON_X1MASK)
|
||||
JS_SetPropertyStr(js, m, "x1", JS_NewBool(js, 1));
|
||||
if (flags & SDL_BUTTON_X2MASK)
|
||||
JS_SetPropertyStr(js, m, "x2", JS_NewBool(js, 1));
|
||||
|
||||
return m;
|
||||
)
|
||||
|
||||
JSC_CCALL(mouse_get_relative_state,
|
||||
float x,y;
|
||||
SDL_MouseButtonFlags flags = SDL_GetRelativeMouseState(&x,&y);
|
||||
JSValue m = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js,m,"x", number2js(js,x));
|
||||
JS_SetPropertyStr(js,m,"y", number2js(js,y));
|
||||
|
||||
if (flags & SDL_BUTTON_LMASK)
|
||||
JS_SetPropertyStr(js, m, "left", JS_NewBool(js, 1));
|
||||
if (flags & SDL_BUTTON_MMASK)
|
||||
JS_SetPropertyStr(js, m, "middle", JS_NewBool(js, 1));
|
||||
if (flags & SDL_BUTTON_RMASK)
|
||||
JS_SetPropertyStr(js, m, "right", JS_NewBool(js, 1));
|
||||
if (flags & SDL_BUTTON_X1MASK)
|
||||
JS_SetPropertyStr(js, m, "x1", JS_NewBool(js, 1));
|
||||
if (flags & SDL_BUTTON_X2MASK)
|
||||
JS_SetPropertyStr(js, m, "x2", JS_NewBool(js, 1));
|
||||
|
||||
return m;
|
||||
)
|
||||
|
||||
JSC_CCALL(mouse_warp_global,
|
||||
HMM_Vec2 pos = js2vec2(js, argv[0]);
|
||||
SDL_WarpMouseGlobal(pos.x, pos.y);
|
||||
)
|
||||
|
||||
JSC_CCALL(mouse_warp_in_window,
|
||||
SDL_Window *window = js2SDL_Window(js, argv[0]);
|
||||
if (!window) return JS_ThrowReferenceError(js, "Invalid window");
|
||||
HMM_Vec2 pos = js2vec2(js, argv[1]);
|
||||
SDL_WarpMouseInWindow(window, pos.x, pos.y);
|
||||
)
|
||||
|
||||
JSC_CCALL(mouse_cursor_visible,
|
||||
return JS_NewBool(js, SDL_CursorVisible());
|
||||
)
|
||||
|
||||
JSC_CCALL(mouse_get_cursor,
|
||||
SDL_Cursor *cursor = SDL_GetCursor();
|
||||
if (!cursor) return JS_NULL;
|
||||
return SDL_Cursor2js(js, cursor);
|
||||
)
|
||||
|
||||
JSC_CCALL(mouse_get_default_cursor,
|
||||
SDL_Cursor *cursor = SDL_GetDefaultCursor();
|
||||
if (!cursor) return JS_NULL;
|
||||
return SDL_Cursor2js(js, cursor);
|
||||
)
|
||||
|
||||
JSC_CCALL(mouse_create_system_cursor,
|
||||
int id = js2number(js, argv[0]);
|
||||
SDL_Cursor *cursor = SDL_CreateSystemCursor(id);
|
||||
if (!cursor) return JS_ThrowReferenceError(js, "Failed to create system cursor: %s", SDL_GetError());
|
||||
return SDL_Cursor2js(js, cursor);
|
||||
)
|
||||
|
||||
JSC_CCALL(mouse_get_focus,
|
||||
SDL_Window *window = SDL_GetMouseFocus();
|
||||
if (!window) return JS_NULL;
|
||||
return SDL_Window2js(js, window);
|
||||
)
|
||||
|
||||
static const JSCFunctionListEntry js_mouse_funcs[] = {
|
||||
MIST_FUNC_DEF(mouse, show, 1),
|
||||
MIST_FUNC_DEF(mouse, capture, 1),
|
||||
MIST_FUNC_DEF(mouse, get_state, 0),
|
||||
MIST_FUNC_DEF(mouse, get_global_state, 0),
|
||||
MIST_FUNC_DEF(mouse, get_relative_state, 0),
|
||||
MIST_FUNC_DEF(mouse, warp_global, 1),
|
||||
MIST_FUNC_DEF(mouse, warp_in_window, 2),
|
||||
MIST_FUNC_DEF(mouse, cursor_visible, 0),
|
||||
MIST_FUNC_DEF(mouse, get_cursor, 0),
|
||||
MIST_FUNC_DEF(mouse, get_default_cursor, 0),
|
||||
MIST_FUNC_DEF(mouse, create_system_cursor, 1),
|
||||
MIST_FUNC_DEF(mouse, get_focus, 0),
|
||||
};
|
||||
|
||||
// Keyboard functions that must run on main thread
|
||||
JSC_CCALL(keyboard_get_state,
|
||||
int numkeys;
|
||||
const bool *keystate = SDL_GetKeyboardState(&numkeys);
|
||||
JSValue arr = JS_NewArray(js);
|
||||
for (int i = 0; i < numkeys; i++) {
|
||||
JS_SetPropertyUint32(js, arr, i, JS_NewBool(js, keystate[i]));
|
||||
}
|
||||
return arr;
|
||||
)
|
||||
|
||||
JSC_CCALL(keyboard_get_focus,
|
||||
SDL_Window *window = SDL_GetKeyboardFocus();
|
||||
if (!window) return JS_NULL;
|
||||
return SDL_Window2js(js, window);
|
||||
)
|
||||
|
||||
JSC_CCALL(keyboard_start_text_input,
|
||||
SDL_Window *window = NULL;
|
||||
if (argc > 0 && !JS_IsNull(argv[0]) && !JS_IsUndefined(argv[0])) {
|
||||
window = js2SDL_Window(js, argv[0]);
|
||||
if (!window) return JS_ThrowReferenceError(js, "Invalid window");
|
||||
}
|
||||
SDL_StartTextInput(window);
|
||||
)
|
||||
|
||||
JSC_CCALL(keyboard_stop_text_input,
|
||||
SDL_Window *window = NULL;
|
||||
if (argc > 0 && !JS_IsNull(argv[0]) && !JS_IsUndefined(argv[0])) {
|
||||
window = js2SDL_Window(js, argv[0]);
|
||||
if (!window) return JS_ThrowReferenceError(js, "Invalid window");
|
||||
}
|
||||
SDL_StopTextInput(window);
|
||||
)
|
||||
|
||||
JSC_CCALL(keyboard_text_input_active,
|
||||
SDL_Window *window = NULL;
|
||||
if (argc > 0 && !JS_IsNull(argv[0]) && !JS_IsUndefined(argv[0])) {
|
||||
window = js2SDL_Window(js, argv[0]);
|
||||
if (!window) return JS_ThrowReferenceError(js, "Invalid window");
|
||||
}
|
||||
return JS_NewBool(js, SDL_TextInputActive(window));
|
||||
)
|
||||
|
||||
JSC_CCALL(keyboard_get_text_input_area,
|
||||
SDL_Window *window = NULL;
|
||||
if (argc > 0 && !JS_IsNull(argv[0]) && !JS_IsUndefined(argv[0])) {
|
||||
window = js2SDL_Window(js, argv[0]);
|
||||
if (!window) return JS_ThrowReferenceError(js, "Invalid window");
|
||||
}
|
||||
SDL_Rect rect;
|
||||
int cursor;
|
||||
if (!SDL_GetTextInputArea(window, &rect, &cursor))
|
||||
return JS_ThrowReferenceError(js, "Failed to get text input area: %s", SDL_GetError());
|
||||
|
||||
JSValue obj = JS_NewObject(js);
|
||||
SDL_FRect frect;
|
||||
SDL_RectToFRect(&rect, &frect);
|
||||
JS_SetPropertyStr(js, obj, "rect", rect2js(js, frect));
|
||||
JS_SetPropertyStr(js, obj, "cursor", JS_NewInt32(js, cursor));
|
||||
return obj;
|
||||
)
|
||||
|
||||
JSC_CCALL(keyboard_set_text_input_area,
|
||||
SDL_Window *window = NULL;
|
||||
rect r = js2rect(js, argv[0]);
|
||||
int cursor = argc > 1 ? js2number(js, argv[1]) : 0;
|
||||
if (argc > 2 && !JS_IsNull(argv[2]) && !JS_IsUndefined(argv[2])) {
|
||||
window = js2SDL_Window(js, argv[2]);
|
||||
if (!window) return JS_ThrowReferenceError(js, "Invalid window");
|
||||
}
|
||||
if (!SDL_SetTextInputArea(window, &r, cursor))
|
||||
return JS_ThrowReferenceError(js, "Failed to set text input area: %s", SDL_GetError());
|
||||
)
|
||||
|
||||
JSC_CCALL(keyboard_clear_composition,
|
||||
SDL_Window *window = NULL;
|
||||
if (argc > 0 && !JS_IsNull(argv[0]) && !JS_IsUndefined(argv[0])) {
|
||||
window = js2SDL_Window(js, argv[0]);
|
||||
if (!window) return JS_ThrowReferenceError(js, "Invalid window");
|
||||
}
|
||||
if (!SDL_ClearComposition(window))
|
||||
return JS_ThrowReferenceError(js, "Failed to clear composition: %s", SDL_GetError());
|
||||
)
|
||||
|
||||
JSC_CCALL(keyboard_screen_keyboard_shown,
|
||||
SDL_Window *window = js2SDL_Window(js, argv[0]);
|
||||
if (!window) return JS_ThrowReferenceError(js, "Invalid window");
|
||||
return JS_NewBool(js, SDL_ScreenKeyboardShown(window));
|
||||
)
|
||||
|
||||
JSC_CCALL(keyboard_reset,
|
||||
SDL_ResetKeyboard();
|
||||
)
|
||||
|
||||
static const JSCFunctionListEntry js_keyboard_funcs[] = {
|
||||
MIST_FUNC_DEF(keyboard, get_state, 0),
|
||||
MIST_FUNC_DEF(keyboard, get_focus, 0),
|
||||
MIST_FUNC_DEF(keyboard, start_text_input, 1),
|
||||
MIST_FUNC_DEF(keyboard, stop_text_input, 1),
|
||||
MIST_FUNC_DEF(keyboard, text_input_active, 1),
|
||||
MIST_FUNC_DEF(keyboard, get_text_input_area, 1),
|
||||
MIST_FUNC_DEF(keyboard, set_text_input_area, 3),
|
||||
MIST_FUNC_DEF(keyboard, clear_composition, 1),
|
||||
MIST_FUNC_DEF(keyboard, screen_keyboard_shown, 1),
|
||||
MIST_FUNC_DEF(keyboard, reset, 0),
|
||||
};
|
||||
|
||||
// Hook function to set up endowments for the video actor
|
||||
static void video_actor_hook(JSContext *js) {
|
||||
// Get prosperon object
|
||||
@@ -2021,16 +1816,6 @@ static void video_actor_hook(JSContext *js) {
|
||||
JS_SetPropertyStr(js, endowments, "setCursor",
|
||||
JS_NewCFunction(js, js_sdl_set_cursor, "setCursor", 1));
|
||||
|
||||
// Create mouse module
|
||||
JSValue mouse_mod = JS_NewObject(js);
|
||||
JS_SetPropertyFunctionList(js, mouse_mod, js_mouse_funcs, countof(js_mouse_funcs));
|
||||
JS_SetPropertyStr(js, endowments, "mouse", mouse_mod);
|
||||
|
||||
// Create keyboard module
|
||||
JSValue keyboard_mod = JS_NewObject(js);
|
||||
JS_SetPropertyFunctionList(js, keyboard_mod, js_keyboard_funcs, countof(js_keyboard_funcs));
|
||||
JS_SetPropertyStr(js, endowments, "keyboard", keyboard_mod);
|
||||
|
||||
JS_FreeValue(js, endowments);
|
||||
JS_FreeValue(js, prosperon);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "soloud_c.h"
|
||||
#include "quickjs.h"
|
||||
#include <stdlib.h>
|
||||
#include "prosperon.h"
|
||||
|
||||
#define countof(x) (sizeof(x)/sizeof((x)[0]))
|
||||
|
||||
@@ -97,14 +98,14 @@ static JSValue js_soloud_mix(JSContext *js, JSValue self, int argc, JSValue *arg
|
||||
JS_ToInt32(js, &req, argv[0]);
|
||||
float *buf = malloc(2*req*sizeof(float));
|
||||
Soloud_mix(soloud, buf, req);
|
||||
return JS_NewArrayBufferCopy(js, buf, 2*req*sizeof(float));
|
||||
return js_new_blob_stoned_copy(js, buf, 2*req*sizeof(float));
|
||||
}
|
||||
|
||||
// Create a voice from a WAV file
|
||||
static JSValue js_load_wav_mem(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
{
|
||||
size_t len;
|
||||
void *data = JS_GetArrayBuffer(js, &len, argv[0]);
|
||||
void *data = js_get_blob_data(js, &len, argv[0]);
|
||||
Wav *wav = Wav_create();
|
||||
if (Wav_loadMemEx(wav, data, len, 1, 1)) {
|
||||
Wav_destroy(wav);
|
||||
@@ -117,7 +118,7 @@ static JSValue js_load_wav_mem(JSContext *js, JSValue self, int argc, JSValue *a
|
||||
static JSValue js_load_pwm(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
{
|
||||
size_t len;
|
||||
void *data = JS_GetArrayBuffer(js, &len, argv[0]);
|
||||
void *data = js_get_blob_data(js, &len, argv[0]);
|
||||
Wav *wav = Wav_create();
|
||||
Wav_loadRawWaveEx(wav, data, len, js2number(js,argv[1]), js2number(js,argv[2]), 1, 1);
|
||||
return Wav2js(js, wav);
|
||||
|
||||
@@ -342,7 +342,7 @@ JSC_CCALL(cloud_write,
|
||||
}
|
||||
data = (uint8_t*)str;
|
||||
} else {
|
||||
data = JS_GetArrayBuffer(js, &data_len, argv[1]);
|
||||
data = js_get_blob_data(js, &data_len, argv[1]);
|
||||
if (!data) {
|
||||
JS_FreeCString(js, filename);
|
||||
return JS_ThrowTypeError(js, "Second argument must be string or ArrayBuffer");
|
||||
@@ -385,7 +385,7 @@ JSC_CCALL(cloud_read,
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
JSValue result = JS_NewArrayBufferCopy(js, buffer, size);
|
||||
JSValue result = js_new_blob_stoned_copy(js, buffer, size);
|
||||
js_free(js, buffer);
|
||||
return result;
|
||||
)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "quickjs.h"
|
||||
#include "wota.h"
|
||||
#include <stdlib.h>
|
||||
#include "prosperon.h"
|
||||
|
||||
typedef struct WotaEncodeContext {
|
||||
JSContext *ctx;
|
||||
@@ -126,9 +127,9 @@ static void wota_encode_value(WotaEncodeContext *enc, JSValueConst val, JSValueC
|
||||
wota_write_sym(&enc->wb, WOTA_NULL);
|
||||
break;
|
||||
case JS_TAG_OBJECT: {
|
||||
if (JS_IsArrayBuffer(ctx, replaced)) {
|
||||
if (js_is_blob(ctx, replaced)) {
|
||||
size_t buf_len;
|
||||
void *buf_data = JS_GetArrayBuffer(ctx, &buf_len, replaced);
|
||||
void *buf_data = js_get_blob_data(ctx, &buf_len, replaced);
|
||||
wota_write_blob(&enc->wb, (unsigned long long)buf_len * 8, (const char *)buf_data);
|
||||
break;
|
||||
}
|
||||
@@ -209,7 +210,7 @@ static char *decode_wota_value(JSContext *ctx, char *data_ptr, JSValue *out_val,
|
||||
long long blen;
|
||||
char *bdata = NULL;
|
||||
data_ptr = wota_read_blob(&blen, &bdata, data_ptr);
|
||||
*out_val = bdata ? JS_NewArrayBufferCopy(ctx, (uint8_t *)bdata, (size_t)blen) : JS_NewArrayBufferCopy(ctx, NULL, 0);
|
||||
*out_val = bdata ? js_new_blob_stoned_copy(ctx, (uint8_t *)bdata, (size_t)blen) : js_new_blob_stoned_copy(ctx, NULL, 0);
|
||||
if (bdata) free(bdata);
|
||||
break;
|
||||
}
|
||||
@@ -316,7 +317,7 @@ static JSValue js_wota_encode(JSContext *ctx, JSValueConst this_val, int argc, J
|
||||
}
|
||||
JS_FreeValue(ctx, enc->visited_stack);
|
||||
size_t total_bytes = enc->wb.size * sizeof(uint64_t);
|
||||
JSValue ret = JS_NewArrayBufferCopy(ctx, (uint8_t *)enc->wb.data, total_bytes);
|
||||
JSValue ret = js_new_blob_stoned_copy(ctx, (uint8_t *)enc->wb.data, total_bytes);
|
||||
wota_buffer_free(&enc->wb);
|
||||
return ret;
|
||||
}
|
||||
@@ -325,7 +326,7 @@ static JSValue js_wota_decode(JSContext *ctx, JSValueConst this_val, int argc, J
|
||||
{
|
||||
if (argc < 1) return JS_UNDEFINED;
|
||||
size_t len;
|
||||
uint8_t *buf = JS_GetArrayBuffer(ctx, &len, argv[0]);
|
||||
uint8_t *buf = js_get_blob_data(ctx, &len, argv[0]);
|
||||
if (!buf) return JS_UNDEFINED;
|
||||
JSValue reviver = (argc > 1 && JS_IsFunction(ctx, argv[1])) ? argv[1] : JS_UNDEFINED;
|
||||
char *data_ptr = (char *)buf;
|
||||
|
||||
Reference in New Issue
Block a user