diff --git a/src/api/js.c b/src/api/js.c index 7879f9ec7..f00a3cddb 100644 --- a/src/api/js.c +++ b/src/api/js.c @@ -86,7 +86,7 @@ static void js_dump_obj(JSContext *ctx, FILE *f, JSValueConst val) } else { - core->data->error(core->data->data, "[exception]"); + core->data->error(core->data->data, "[exception]\n"); } } @@ -515,130 +515,120 @@ static JSValue js_mset(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueC static JSValue js_peek(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv) { -// s32 address = js_to_int(duk, 0); -// s32 bits = js_opt_int(duk, 1, BITS_IN_BYTE); + s32 address = getArgVal(ctx, argv[0]); + s32 bits = getArg(ctx, argv[1], BITS_IN_BYTE); -// tic_mem* tic = (tic_mem*)getCore(ctx); -// js_push_uint(duk, tic_api_peek(tic, address, bits)); -// return 1; - return JS_UNDEFINED; + tic_mem* tic = (tic_mem*)getCore(ctx); + + return JS_NewInt32(ctx, tic_api_peek(tic, address, bits)); } static JSValue js_poke(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv) { -// s32 address = js_to_int(duk, 0); -// u8 value = js_to_int(duk, 1); -// s32 bits = js_opt_int(duk, 2, BITS_IN_BYTE); + s32 address = getArgVal(ctx, argv[0]); + u8 value = getArgVal(ctx, argv[1]); + s32 bits = getArg(ctx, argv[2], BITS_IN_BYTE); -// tic_mem* tic = (tic_mem*)getCore(ctx); -// tic_api_poke(tic, address, value, bits); + tic_mem* tic = (tic_mem*)getCore(ctx); + tic_api_poke(tic, address, value, bits); -// return 0; return JS_UNDEFINED; } static JSValue js_peek1(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv) { -// s32 address = js_to_int(duk, 0); + s32 address = getArgVal(ctx, argv[0]); -// tic_mem* tic = (tic_mem*)getCore(ctx); -// js_push_uint(duk, tic_api_peek1(tic, address)); -// return 1; - return JS_UNDEFINED; + tic_mem* tic = (tic_mem*)getCore(ctx); + + return JS_NewInt32(ctx, tic_api_peek1(tic, address)); } static JSValue js_poke1(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv) { -// s32 address = js_to_int(duk, 0); -// u8 value = js_to_int(duk, 1); + s32 address = getArgVal(ctx, argv[0]); + u8 value = getArgVal(ctx, argv[1]); -// tic_mem* tic = (tic_mem*)getCore(ctx); -// tic_api_poke1(tic, address, value); + tic_mem* tic = (tic_mem*)getCore(ctx); + tic_api_poke1(tic, address, value); -// return 0; return JS_UNDEFINED; } static JSValue js_peek2(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv) { -// s32 address = js_to_int(duk, 0); + s32 address = getArgVal(ctx, argv[0]); -// tic_mem* tic = (tic_mem*)getCore(ctx); -// js_push_uint(duk, tic_api_peek2(tic, address)); -// return 1; - return JS_UNDEFINED; + tic_mem* tic = (tic_mem*)getCore(ctx); + + return JS_NewInt32(ctx, tic_api_peek2(tic, address)); } static JSValue js_poke2(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv) { -// s32 address = js_to_int(duk, 0); -// u8 value = js_to_int(duk, 1); + s32 address = getArgVal(ctx, argv[0]); + u8 value = getArgVal(ctx, argv[1]); -// tic_mem* tic = (tic_mem*)getCore(ctx); -// tic_api_poke2(tic, address, value); + tic_mem* tic = (tic_mem*)getCore(ctx); + tic_api_poke2(tic, address, value); -// return 0; return JS_UNDEFINED; } static JSValue js_peek4(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv) { -// s32 address = js_to_int(duk, 0); + s32 address = getArgVal(ctx, argv[0]); -// tic_mem* tic = (tic_mem*)getCore(ctx); -// js_push_uint(duk, tic_api_peek4(tic, address)); -// return 1; - return JS_UNDEFINED; + tic_mem* tic = (tic_mem*)getCore(ctx); + + return JS_NewInt32(ctx, tic_api_peek4(tic, address)); } static JSValue js_poke4(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv) { -// s32 address = js_to_int(duk, 0); -// u8 value = js_to_int(duk, 1); + s32 address = getArgVal(ctx, argv[0]); + u8 value = getArgVal(ctx, argv[1]); -// tic_mem* tic = (tic_mem*)getCore(ctx); -// tic_api_poke4(tic, address, value); + tic_mem* tic = (tic_mem*)getCore(ctx); + tic_api_poke4(tic, address, value); -// return 0; return JS_UNDEFINED; } static JSValue js_memcpy(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv) { -// s32 dest = js_to_int(duk, 0); -// s32 src = js_to_int(duk, 1); -// s32 size = js_to_int(duk, 2); + s32 dest = getArgVal(ctx, argv[0]); + s32 src = getArgVal(ctx, argv[1]); + s32 size = getArgVal(ctx, argv[2]); -// tic_mem* tic = (tic_mem*)getCore(ctx); -// tic_api_memcpy(tic, dest, src, size); + tic_mem* tic = (tic_mem*)getCore(ctx); + tic_api_memcpy(tic, dest, src, size); -// return 0; return JS_UNDEFINED; } static JSValue js_memset(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv) { -// s32 dest = js_to_int(duk, 0); -// u8 value = js_to_int(duk, 1); -// s32 size = js_to_int(duk, 2); + s32 dest = getArgVal(ctx, argv[0]); + u8 value = getArgVal(ctx, argv[1]); + s32 size = getArgVal(ctx, argv[2]); -// tic_mem* tic = (tic_mem*)getCore(ctx); -// tic_api_memset(tic, dest, value, size); + tic_mem* tic = (tic_mem*)getCore(ctx); + tic_api_memset(tic, dest, value, size); -// return 0; return JS_UNDEFINED; } static JSValue js_trace(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv) { -// tic_mem* tic = (tic_mem*)getCore(ctx); + tic_mem* tic = (tic_mem*)getCore(ctx); -// const char* text = js_opt_string(duk, 0, ""); -// u8 color = js_opt_int(duk, 1, TIC_DEFAULT_COLOR); + const char* text = JS_ToCString(ctx, argv[0]); + u8 color = getArg(ctx, argv[1], TIC_DEFAULT_COLOR); -// tic_api_trace(tic, text, color); + tic_api_trace(tic, text, color); -// return 0; + JS_FreeCString(ctx, text); return JS_UNDEFINED; } @@ -679,399 +669,343 @@ static JSValue js_tstamp(JSContext *ctx, JSValueConst this_val, s32 argc, JSValu static JSValue js_exit(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv) { -// tic_api_exit((tic_mem*)getCore(ctx)); + tic_api_exit((tic_mem*)getCore(ctx)); -// return 0; return JS_UNDEFINED; } static JSValue js_font(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv) { -// tic_mem* tic = (tic_mem*)getCore(ctx); - -// const char* text = js_to_string(duk, 0); -// s32 x = js_to_int(duk, 1); -// s32 y = js_to_int(duk, 2); -// u8 chromakey = js_to_int(duk, 3); -// s32 width = js_opt_int(duk, 4, TIC_SPRITESIZE); -// s32 height = js_opt_int(duk, 5, TIC_SPRITESIZE); -// bool fixed = js_opt_boolean(duk, 6, false); -// s32 scale = js_opt_int(duk, 7, 1); -// bool alt = js_opt_boolean(duk, 8, false); -// if(scale == 0) -// { -// js_push_int(duk, 0); -// return 1; -// } + tic_mem* tic = (tic_mem*)getCore(ctx); -// s32 size = tic_api_font(tic, text, x, y, &chromakey, 1, width, height, fixed, scale, alt); + const char* text = JS_ToCString(ctx, argv[0]); + s32 x = getArgVal(ctx, argv[1]); + s32 y = getArgVal(ctx, argv[2]); + u8 chromakey = getArgVal(ctx, argv[3]); + s32 width = getArg(ctx, argv[4], TIC_SPRITESIZE); + s32 height = getArg(ctx, argv[5], TIC_SPRITESIZE); + bool fixed = JS_ToBool(ctx, argv[6]); + s32 scale = getArg(ctx, argv[7], 1); + bool alt = JS_ToBool(ctx, argv[8]); + + if(scale == 0) + { + return JS_NewInt32(ctx, 0); + } -// js_push_int(duk, size); + s32 size = tic_api_font(tic, text, x, y, &chromakey, 1, width, height, fixed, scale, alt); -// return 1; - return JS_UNDEFINED; + JS_FreeCString(ctx, text); + return JS_NewInt32(ctx, size); } static JSValue js_mouse(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv) { -// tic_core* core = getCore(ctx); - -// const tic80_mouse* mouse = &core->memory.ram->input.mouse; + tic_core* core = getCore(ctx); -// js_idx_t idx = js_push_array(duk); + const tic80_mouse* mouse = &core->memory.ram->input.mouse; -// { -// tic_point pos = tic_api_mouse((tic_mem*)core); + JSValue arr = JS_NewArray(ctx); -// js_push_int(duk, pos.x); -// js_put_prop_index(duk, idx, 0); -// js_push_int(duk, pos.y); -// js_put_prop_index(duk, idx, 1); -// } + tic_point pos = tic_api_mouse((tic_mem*)core); -// js_push_boolean(duk, mouse->left); -// js_put_prop_index(duk, idx, 2); -// js_push_boolean(duk, mouse->middle); -// js_put_prop_index(duk, idx, 3); -// js_push_boolean(duk, mouse->right); -// js_put_prop_index(duk, idx, 4); -// js_push_int(duk, mouse->scrollx); -// js_put_prop_index(duk, idx, 5); -// js_push_int(duk, mouse->scrolly); -// js_put_prop_index(duk, idx, 6); + JS_SetPropertyUint32(ctx, arr, 0, JS_NewInt32(ctx, pos.x)); + JS_SetPropertyUint32(ctx, arr, 1, JS_NewInt32(ctx, pos.y)); + JS_SetPropertyUint32(ctx, arr, 2, JS_NewBool(ctx, mouse->left)); + JS_SetPropertyUint32(ctx, arr, 3, JS_NewBool(ctx, mouse->middle)); + JS_SetPropertyUint32(ctx, arr, 4, JS_NewBool(ctx, mouse->right)); + JS_SetPropertyUint32(ctx, arr, 5, JS_NewInt32(ctx, mouse->scrollx)); + JS_SetPropertyUint32(ctx, arr, 6, JS_NewInt32(ctx, mouse->scrolly)); -// return 1; - return JS_UNDEFINED; + return arr; } static JSValue js_circ(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv) { -// s32 x = js_to_int(duk, 0); -// s32 y = js_to_int(duk, 1); -// s32 radius = js_to_int(duk, 2); -// s32 color = js_to_int(duk, 3); + s32 x = getArgVal(ctx, argv[0]); + s32 y = getArgVal(ctx, argv[1]); + s32 radius = getArgVal(ctx, argv[2]); + s32 color = getArgVal(ctx, argv[3]); -// tic_mem* tic = (tic_mem*)getCore(ctx); + tic_mem* tic = (tic_mem*)getCore(ctx); -// tic_api_circ(tic, x, y, radius, color); + tic_api_circ(tic, x, y, radius, color); -// return 0; return JS_UNDEFINED; } static JSValue js_circb(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv) { -// s32 x = js_to_int(duk, 0); -// s32 y = js_to_int(duk, 1); -// s32 color = js_to_int(duk, 3); -// s32 radius = js_to_int(duk, 2); + s32 x = getArgVal(ctx, argv[0]); + s32 y = getArgVal(ctx, argv[1]); + s32 radius = getArgVal(ctx, argv[2]); + s32 color = getArgVal(ctx, argv[3]); -// tic_mem* tic = (tic_mem*)getCore(ctx); + tic_mem* tic = (tic_mem*)getCore(ctx); -// tic_api_circb(tic, x, y, radius, color); + tic_api_circb(tic, x, y, radius, color); -// return 0; return JS_UNDEFINED; } static JSValue js_elli(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv) { -// s32 x = js_to_int(duk, 0); -// s32 y = js_to_int(duk, 1); -// s32 a = js_to_int(duk, 2); -// s32 b = js_to_int(duk, 3); -// s32 color = js_to_int(duk, 4); + s32 x = getArgVal(ctx, argv[0]); + s32 y = getArgVal(ctx, argv[1]); + s32 a = getArgVal(ctx, argv[2]); + s32 b = getArgVal(ctx, argv[3]); + s32 color = getArgVal(ctx, argv[4]); -// tic_mem* tic = (tic_mem*)getCore(ctx); + tic_mem* tic = (tic_mem*)getCore(ctx); -// tic_api_elli(tic, x, y, a, b, color); + tic_api_elli(tic, x, y, a, b, color); -// return 0; return JS_UNDEFINED; } static JSValue js_ellib(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv) { -// s32 x = js_to_int(duk, 0); -// s32 y = js_to_int(duk, 1); -// s32 a = js_to_int(duk, 2); -// s32 b = js_to_int(duk, 3); -// s32 color = js_to_int(duk, 4); + s32 x = getArgVal(ctx, argv[0]); + s32 y = getArgVal(ctx, argv[1]); + s32 a = getArgVal(ctx, argv[2]); + s32 b = getArgVal(ctx, argv[3]); + s32 color = getArgVal(ctx, argv[4]); -// tic_mem* tic = (tic_mem*)getCore(ctx); + tic_mem* tic = (tic_mem*)getCore(ctx); -// tic_api_ellib(tic, x, y, a, b, color); + tic_api_ellib(tic, x, y, a, b, color); -// return 0; return JS_UNDEFINED; } static JSValue js_tri(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv) { -// float pt[6]; + float pt[6]; -// for(s32 i = 0; i < COUNT_OF(pt); i++) -// pt[i] = js_to_number(duk, i); + for(s32 i = 0; i < COUNT_OF(pt); i++) + pt[i] = getArgFloat(ctx, argv[i], 0.0f); -// s32 color = js_to_int(duk, 6); + s32 color = getArgVal(ctx, argv[6]); -// tic_mem* tic = (tic_mem*)getCore(ctx); + tic_mem* tic = (tic_mem*)getCore(ctx); -// tic_api_tri(tic, pt[0], pt[1], pt[2], pt[3], pt[4], pt[5], color); + tic_api_tri(tic, pt[0], pt[1], pt[2], pt[3], pt[4], pt[5], color); -// return 0; return JS_UNDEFINED; } static JSValue js_trib(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv) { -// float pt[6]; + float pt[6]; -// for(s32 i = 0; i < COUNT_OF(pt); i++) -// pt[i] = js_to_number(duk, i); + for(s32 i = 0; i < COUNT_OF(pt); i++) + pt[i] = getArgFloat(ctx, argv[i], 0.0f); -// s32 color = js_to_int(duk, 6); + s32 color = getArgVal(ctx, argv[6]); -// tic_mem* tic = (tic_mem*)getCore(ctx); + tic_mem* tic = (tic_mem*)getCore(ctx); -// tic_api_trib(tic, pt[0], pt[1], pt[2], pt[3], pt[4], pt[5], color); + tic_api_trib(tic, pt[0], pt[1], pt[2], pt[3], pt[4], pt[5], color); -// return 0; return JS_UNDEFINED; } -// #if defined(BUILD_DEPRECATED) +#if defined(BUILD_DEPRECATED) static JSValue js_textri(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv) { -// float pt[12]; - -// for (s32 i = 0; i < COUNT_OF(pt); i++) -// pt[i] = (float)js_to_number(duk, i); -// tic_mem* tic = (tic_mem*)getCore(ctx); -// bool use_map = js_to_boolean(duk, 12); - -// static u8 colors[TIC_PALETTE_SIZE]; -// s32 count = 0; -// { -// if(!js_is_null_or_undefined(duk, 13)) -// { -// if(js_is_array(duk, 13)) -// { -// for(s32 i = 0; i < TIC_PALETTE_SIZE; i++) -// { -// js_get_prop_index(duk, 13, i); -// if(js_is_null_or_undefined(duk, -1)) -// { -// js_pop(duk); -// break; -// } -// else -// { -// colors[i] = js_to_int(duk, -1); -// count++; -// js_pop(duk); -// } -// } -// } -// else -// { -// colors[0] = js_to_int(duk, 13); -// count = 1; -// } -// } -// } - -// tic_core_textri_dep(getCore(ctx), -// pt[0], pt[1], // xy 1 -// pt[2], pt[3], // xy 2 -// pt[4], pt[5], // xy 3 -// pt[6], pt[7], // uv 1 -// pt[8], pt[9], // uv 2 -// pt[10], pt[11], // uv 3 -// use_map, // use_map -// colors, count); // chroma - -// return 0; + float pt[12]; + + for (s32 i = 0; i < COUNT_OF(pt); i++) + pt[i] = getArgFloat(ctx, argv[i], 0.0f); + + tic_mem* tic = (tic_mem*)getCore(ctx); + bool use_map = JS_ToBool(ctx, argv[12]); + + static u8 colors[TIC_PALETTE_SIZE]; + s32 count = 0; + if(JS_IsArray(ctx, argv[13])) + { + for(s32 i = 0; i < TIC_PALETTE_SIZE; i++) + { + JSValue val = JS_GetPropertyUint32(ctx, argv[13], i); + colors[i] = getArg(ctx, val, -1); + count++; + } + } + else + { + colors[0] = getArg(ctx, argv[13], 0); + count = 1; + } + + tic_core_textri_dep(getCore(ctx), + pt[0], pt[1], // xy 1 + pt[2], pt[3], // xy 2 + pt[4], pt[5], // xy 3 + pt[6], pt[7], // uv 1 + pt[8], pt[9], // uv 2 + pt[10], pt[11], // uv 3 + use_map, // use_map + colors, count); // chroma + return JS_UNDEFINED; } -// #endif +#endif static JSValue js_ttri(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv) { -// float pt[12]; - -// for (s32 i = 0; i < COUNT_OF(pt); i++) -// pt[i] = (float)js_to_number(duk, i); -// tic_mem* tic = (tic_mem*)getCore(ctx); -// tic_texture_src src = js_to_int(duk, 12); - -// static u8 colors[TIC_PALETTE_SIZE]; -// s32 count = 0; -// { -// if(!js_is_null_or_undefined(duk, 13)) -// { -// if(js_is_array(duk, 13)) -// { -// for(s32 i = 0; i < TIC_PALETTE_SIZE; i++) -// { -// js_get_prop_index(duk, 13, i); -// if(js_is_null_or_undefined(duk, -1)) -// { -// js_pop(duk); -// break; -// } -// else -// { -// colors[i] = js_to_int(duk, -1); -// count++; -// js_pop(duk); -// } -// } -// } -// else -// { -// colors[0] = js_to_int(duk, 13); -// count = 1; -// } -// } -// } - -// float z[3]; -// bool depth = true; - -// for (s32 i = 0, index = 14; i < COUNT_OF(z); i++, index++) -// { -// if(js_is_null_or_undefined(duk, index)) depth = false; -// else z[i] = (float)js_to_number(duk, index); -// } - -// tic_api_ttri(tic, pt[0], pt[1], // xy 1 -// pt[2], pt[3], // xy 2 -// pt[4], pt[5], // xy 3 -// pt[6], pt[7], // uv 1 -// pt[8], pt[9], // uv 2 -// pt[10], pt[11], // uv 3 -// src, // texture source -// colors, count, // chroma -// z[0], z[1], z[2], depth); // depth - -// return 0; + float pt[12]; + + for (s32 i = 0; i < COUNT_OF(pt); i++) + pt[i] = getArgFloat(ctx, argv[i], 0.0f); + + tic_mem* tic = (tic_mem*)getCore(ctx); + tic_texture_src src = getArgVal(ctx, argv[12]); + + static u8 colors[TIC_PALETTE_SIZE]; + s32 count = 0; + if(JS_IsArray(ctx, argv[13])) + { + for(s32 i = 0; i < TIC_PALETTE_SIZE; i++) + { + JSValue val = JS_GetPropertyUint32(ctx, argv[13], i); + colors[i] = getArg(ctx, val, -1); + count++; + } + } + else + { + colors[0] = getArg(ctx, argv[13], 0); + count = 1; + } + + float z[3]; + bool depth = true; + + for (s32 i = 0, index = 14; i < COUNT_OF(z); i++, index++) + { + if(JS_IsUndefined(argv[index])) depth = false; + else z[i] = getArgFloat(ctx, argv[index], 0.0f); + } + + tic_api_ttri(tic, pt[0], pt[1], // xy 1 + pt[2], pt[3], // xy 2 + pt[4], pt[5], // xy 3 + pt[6], pt[7], // uv 1 + pt[8], pt[9], // uv 2 + pt[10], pt[11], // uv 3 + src, // texture source + colors, count, // chroma + z[0], z[1], z[2], depth); // depth + return JS_UNDEFINED; } static JSValue js_clip(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv) { -// s32 x = js_to_int(duk, 0); -// s32 y = js_to_int(duk, 1); -// s32 w = js_opt_int(duk, 2, TIC80_WIDTH); -// s32 h = js_opt_int(duk, 3, TIC80_HEIGHT); + s32 x = getArgVal(ctx, argv[0]); + s32 y = getArgVal(ctx, argv[1]); + s32 w = getArg(ctx, argv[2], TIC80_WIDTH); + s32 h = getArg(ctx, argv[3], TIC80_HEIGHT); -// tic_mem* tic = (tic_mem*)getCore(ctx); + tic_mem* tic = (tic_mem*)getCore(ctx); -// tic_api_clip(tic, x, y, w, h); + tic_api_clip(tic, x, y, w, h); -// return 0; return JS_UNDEFINED; } static JSValue js_music(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv) { -// tic_mem* tic = (tic_mem*)getCore(ctx); + tic_mem* tic = (tic_mem*)getCore(ctx); -// s32 track = js_opt_int(duk, 0, -1); -// tic_api_music(tic, -1, 0, 0, false, false, -1, -1); + s32 track = getArg(ctx, argv[0], -1); + tic_api_music(tic, -1, 0, 0, false, false, -1, -1); -// if(track >= 0) -// { -// if(track > MUSIC_TRACKS - 1) -// return js_error(duk, DUK_ERR_ERROR, "invalid music track index"); + if(track >= 0) + { + if(track > MUSIC_TRACKS - 1) + { + throwError(ctx, "invalid music track index"); + return JS_UNDEFINED; + } -// s32 frame = js_opt_int(duk, 1, -1); -// s32 row = js_opt_int(duk, 2, -1); -// bool loop = js_opt_boolean(duk, 3, true); -// bool sustain = js_opt_boolean(duk, 4, false); -// s32 tempo = js_opt_int(duk, 5, -1); -// s32 speed = js_opt_int(duk, 6, -1); + s32 frame = getArg(ctx, argv[1], -1); + s32 row = getArg(ctx, argv[2], -1); + bool loop = JS_IsUndefined(argv[3]) ? true : JS_ToBool(ctx, argv[3]); + bool sustain = JS_ToBool(ctx, argv[4]); + s32 tempo = getArg(ctx, argv[5], -1); + s32 speed = getArg(ctx, argv[6], -1); -// tic_api_music(tic, track, frame, row, loop, sustain, tempo, speed); -// } + tic_api_music(tic, track, frame, row, loop, sustain, tempo, speed); + } -// return 0; return JS_UNDEFINED; } static JSValue js_vbank(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv) { -// tic_core* core = getCore(ctx); -// tic_mem* tic = (tic_mem*)core; - -// s32 prev = core->state.vbank.id; + tic_core* core = getCore(ctx); + tic_mem* tic = (tic_mem*)core; -// if(!js_is_null_or_undefined(duk, 0)) -// tic_api_vbank(tic, js_opt_int(duk, 0, 0)); + s32 prev = core->state.vbank.id; -// js_push_uint(duk, prev); + if(!JS_IsUndefined(argv[0])) + tic_api_vbank(tic, getArg(ctx, argv[0], 0)); -// return 1; - return JS_UNDEFINED; + return JS_NewUint32(ctx, prev); } static JSValue js_sync(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv) { -// tic_mem* tic = (tic_mem*)getCore(ctx); + tic_mem* tic = (tic_mem*)getCore(ctx); -// u32 mask = js_opt_int(duk, 0, 0); -// s32 bank = js_opt_int(duk, 1, 0); -// bool toCart = js_opt_boolean(duk, 2, false); + u32 mask = getArg(ctx, argv[0], 0); + s32 bank = getArg(ctx, argv[1], 0); + bool toCart = JS_ToBool(ctx, argv[2]); -// if(bank >= 0 && bank < TIC_BANKS) -// tic_api_sync(tic, mask, bank, toCart); -// else -// return js_error(duk, DUK_ERR_ERROR, "sync() error, invalid bank"); + if(bank >= 0 && bank < TIC_BANKS) + tic_api_sync(tic, mask, bank, toCart); + else + throwError(ctx, "sync() error, invalid bank"); -// return 0; return JS_UNDEFINED; } static JSValue js_reset(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv) { -// tic_core* core = getCore(ctx); + tic_core* core = getCore(ctx); -// core->state.initialized = false; + core->state.initialized = false; -// return 0; return JS_UNDEFINED; } static JSValue js_fget(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv) { -// tic_mem* tic = (tic_mem*)getCore(ctx); - -// u32 index = js_opt_int(duk, 0, 0); -// u32 flag = js_opt_int(duk, 1, 0); + tic_mem* tic = (tic_mem*)getCore(ctx); -// bool value = tic_api_fget(tic, index, flag); + u32 index = getArg(ctx, argv[0], 0); + u32 flag = getArg(ctx, argv[1], 0); -// js_push_boolean(duk, value); + bool value = tic_api_fget(tic, index, flag); -// return 1; - return JS_UNDEFINED; + return JS_NewBool(ctx, value); } static JSValue js_fset(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv) { -// tic_mem* tic = (tic_mem*)getCore(ctx); + tic_mem* tic = (tic_mem*)getCore(ctx); -// u32 index = js_opt_int(duk, 0, 0); -// u32 flag = js_opt_int(duk, 1, 0); -// bool value = js_opt_boolean(duk, 2, false); + u32 index = getArg(ctx, argv[0], 0); + u32 flag = getArg(ctx, argv[1], 0); + bool value = JS_ToBool(ctx, argv[2]); -// tic_api_fset(tic, index, flag, value); + tic_api_fset(tic, index, flag, value); -// return 0; return JS_UNDEFINED; } @@ -1115,6 +1049,20 @@ static bool initJavascript(tic_mem* tic, const char* code) return true; } +static bool callFunc1(JSContext* ctx, JSValue func, JSValue this_val, JSValue value) +{ + JSValue ret = JS_Call(ctx, func, this_val, 1, (JSValueConst[]){value}); + if (JS_IsException(ret)) + { + js_std_dump_error(ctx); + return false; + } + else + JS_FreeValue(ctx, ret); + + return true; +} + static bool callFunc(JSContext* ctx, JSValue func, JSValue this_val) { JSValue ret = JS_Call(ctx, func, this_val, 0, NULL); @@ -1165,61 +1113,64 @@ static void callJavascriptTick(tic_mem* tic) } } -// static void callJavascriptIntCallback(tic_mem* tic, s32 value, void* data, const char* name) -// { -// tic_core* core = (tic_core*)tic; -// JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv = core->currentVM; +static void callJavascriptIntCallback(tic_mem* tic, s32 value, void* data, const char* name) +{ + tic_core* core = (tic_core*)tic; + JSContext* ctx = core->currentVM; -// if(js_get_global_string(duk, name)) -// { -// js_push_int(duk, value); + JSValue global = JS_GetGlobalObject(ctx); + JSValue func = JS_GetPropertyStr(ctx, global, name); -// if(js_pcall(duk, 1) != 0) -// core->data->error(core->data->data, js_safe_to_stacktrace(duk, -1)); -// } + if(JS_IsFunction(ctx, func)) + { + callFunc1(ctx, func, global, JS_NewInt32(ctx, value)); + } -// js_pop(duk); -// } + JS_FreeValue(ctx, global); +} static void callJavascriptScanline(tic_mem* tic, s32 row, void* data) { - // callJavascriptIntCallback(tic, row, data, SCN_FN); + callJavascriptIntCallback(tic, row, data, SCN_FN); - // // try to call old scanline - // callJavascriptIntCallback(tic, row, data, "scanline"); + // try to call old scanline + callJavascriptIntCallback(tic, row, data, "scanline"); } static void callJavascriptBorder(tic_mem* tic, s32 row, void* data) { - // callJavascriptIntCallback(tic, row, data, BDR_FN); + callJavascriptIntCallback(tic, row, data, BDR_FN); } static void callJavascriptMenu(tic_mem* tic, s32 index, void* data) { - // callJavascriptIntCallback(tic, index, data, MENU_FN); + callJavascriptIntCallback(tic, index, data, MENU_FN); } static void callJavascriptBoot(tic_mem* tic) { -// tic_core* core = (tic_core*)tic; -// JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv = core->currentVM; + tic_core* core = (tic_core*)tic; + JSContext* ctx = core->currentVM; -// if(js_get_global_string(duk, BOOT_FN)) -// { -// if(js_pcall(duk, 0) != 0) -// core->data->error(core->data->data, js_safe_to_stacktrace(duk, -1)); -// } + JSValue global = JS_GetGlobalObject(ctx); + JSValue func = JS_GetPropertyStr(ctx, global, BOOT_FN); -// js_pop(duk); + if(JS_IsFunction(ctx, func)) + { + callFunc(ctx, func, global); + } + + JS_FreeValue(ctx, global); } static const char* const JsKeywords [] = { - "break", "do", "instanceof", "typeof", "case", "else", "new", - "var", "catch", "finally", "return", "void", "continue", "for", - "switch", "while", "debugger", "function", "this", "with", - "default", "if", "throw", "delete", "in", "try", "const", - "true", "false" + "await", "break", "case", "catch", "class", "const", "continue", "debugger", + "default", "delete", "do", "else", "enum", "export", "extends", "false", + "finally", "for", "function", "if", "implements", "import", "in", "instanceof", + "interface", "let", "new", "null", "package", "private", "protected", + "public", "return", "super", "switch", "static", "this", "throw", "try", + "true", "typeof", "var", "void", "while", "with", "yield" }; static inline bool isalnum_(char c) {return isalnum(c) || c == '_';} @@ -1286,7 +1237,8 @@ static const tic_outline_item* getJsOutline(const char* code, s32* size) static void evalJs(tic_mem* tic, const char* code) { - //printf("TODO: JS eval not yet implemented\n."); + tic_core* core = (tic_core*)tic; + core->data->error(core->data->data, "TODO: JS eval not yet implemented\n."); } const tic_script_config JsSyntaxConfig =