Mercurial > molko
changeset 338:94828af916bb
js: add more core bindings
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 14 Oct 2021 21:21:28 +0200 |
parents | 68b9d010e081 |
children | 979960e65f76 |
files | src/libmlk-core-js/CMakeLists.txt src/libmlk-core-js/core/js-clock.c src/libmlk-core-js/core/js-clock.h src/libmlk-core-js/core/js-event.c src/libmlk-core-js/core/js-event.h src/libmlk-core-js/core/js-painter.c src/libmlk-core-js/core/js-painter.h src/libmlk-core-js/core/js-texture.c src/libmlk-core-js/core/js-texture.h src/libmlk-core-js/core/js-window.c src/mlk-run/main.c |
diffstat | 11 files changed, 927 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/src/libmlk-core-js/CMakeLists.txt Thu Oct 14 12:52:41 2021 +0200 +++ b/src/libmlk-core-js/CMakeLists.txt Thu Oct 14 21:21:28 2021 +0200 @@ -20,6 +20,14 @@ set( SOURCES + ${libmlk-core-js_SOURCE_DIR}/core/js-clock.c + ${libmlk-core-js_SOURCE_DIR}/core/js-clock.h + ${libmlk-core-js_SOURCE_DIR}/core/js-event.c + ${libmlk-core-js_SOURCE_DIR}/core/js-event.h + ${libmlk-core-js_SOURCE_DIR}/core/js-painter.c + ${libmlk-core-js_SOURCE_DIR}/core/js-painter.h + ${libmlk-core-js_SOURCE_DIR}/core/js-texture.c + ${libmlk-core-js_SOURCE_DIR}/core/js-texture.h ${libmlk-core-js_SOURCE_DIR}/core/js-window.c ${libmlk-core-js_SOURCE_DIR}/core/js-window.h )
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/libmlk-core-js/core/js-clock.c Thu Oct 14 21:21:28 2021 +0200 @@ -0,0 +1,107 @@ +/* + * js-clock.c -- core clock binding + * + * Copyright (c) 2020-2021 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <assert.h> + +#include <core/alloc.h> +#include <core/clock.h> + +#include "js-clock.h" + +#define SIGNATURE DUK_HIDDEN_SYMBOL("Mlk.Clock") + +static struct clock * +self(duk_context *ctx) +{ + struct clock *clk; + + duk_push_this(ctx); + duk_get_prop_string(ctx, -1, SIGNATURE); + clk = duk_to_pointer(ctx, -1); + duk_pop_2(ctx); + + if (!clk) + duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a Clock object"); + + return clk; +} + +static duk_ret_t +Clock_elapsed(duk_context *ctx) +{ + duk_push_number(ctx, clock_elapsed(self(ctx))); + + return 1; +} + +static duk_ret_t +Clock_constructor(duk_context *ctx) +{ + struct clock *clk; + + clk = alloc_new(sizeof (*clk)); + clock_start(clk); + + duk_push_this(ctx); + duk_push_pointer(ctx, clk); + duk_put_prop_string(ctx, -2, SIGNATURE); + duk_push_string(ctx, "elapsed"); + duk_push_c_function(ctx, Clock_elapsed, 0); + duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_GETTER); + duk_pop(ctx); + + return 0; +} + +static duk_ret_t +Clock_start(duk_context *ctx) +{ + clock_start(self(ctx)); + + return 0; +} + +static duk_ret_t +Clock_destructor(duk_context *ctx) +{ + duk_get_prop_string(ctx, 0, SIGNATURE); + free(duk_to_pointer(ctx, -1)); + duk_pop(ctx); + duk_del_prop_string(ctx, 0, SIGNATURE); + + return 0; +} + +static const duk_function_list_entry methods[] = { + { "start", Clock_start, 0 }, + { NULL, NULL, 0 } +}; + +void +js_clock_bind(duk_context *ctx) +{ + assert(ctx); + + duk_push_c_function(ctx, Clock_constructor, 0); + duk_push_object(ctx); + duk_put_function_list(ctx, -1, methods); + duk_push_c_function(ctx, Clock_destructor, 1); + duk_set_finalizer(ctx, -2); + duk_put_prop_string(ctx, -2, "prototype"); + duk_put_global_string(ctx, "Clock"); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/libmlk-core-js/core/js-clock.h Thu Oct 14 21:21:28 2021 +0200 @@ -0,0 +1,27 @@ +/* + * js-clock.h -- core clock binding + * + * Copyright (c) 2020-2021 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MLK_CORE_JS_CLOCK_H +#define MLK_CORE_JS_CLOCK_H + +#include <duktape.h> + +void +js_clock_bind(duk_context *); + +#endif /* !MLK_CORE_JS_CLOCK_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/libmlk-core-js/core/js-event.c Thu Oct 14 21:21:28 2021 +0200 @@ -0,0 +1,291 @@ +/* + * js-event.c -- core event binding + * + * Copyright (c) 2020-2021 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <assert.h> + +#include <core/event.h> + +#include "js-event.h" + +static void +push_click(duk_context *ctx, const union event *ev) +{ + duk_push_int(ctx, ev->click.button); + duk_put_prop_string(ctx, -2, "button"); + duk_push_int(ctx, ev->click.x); + duk_put_prop_string(ctx, -2, "x"); + duk_push_int(ctx, ev->click.y); + duk_put_prop_string(ctx, -2, "y"); + duk_push_int(ctx, ev->click.clicks); + duk_put_prop_string(ctx, -2, "clicks"); +} + +static void +push_key(duk_context *ctx, const union event *ev) +{ + duk_push_int(ctx, ev->key.key); + duk_put_prop_string(ctx, -2, "key"); +} + +static void +push_mouse(duk_context *ctx, const union event *ev) +{ + duk_push_int(ctx, ev->mouse.buttons); + duk_put_prop_string(ctx, -2, "buttons"); + duk_push_int(ctx, ev->mouse.x); + duk_put_prop_string(ctx, -2, "x"); + duk_push_int(ctx, ev->mouse.y); + duk_put_prop_string(ctx, -2, "y"); +} + +static void +push_quit(duk_context *ctx, const union event *ev) +{ + (void)ctx; + (void)ev; +} + +static void (*push[])(duk_context *, const union event *) = { + [EVENT_CLICKDOWN] = push_click, + [EVENT_CLICKUP] = push_click, + [EVENT_KEYDOWN] = push_key, + [EVENT_KEYUP] = push_key, + [EVENT_MOUSE] = push_mouse, + [EVENT_QUIT] = push_quit, +}; + +static duk_ret_t +Event_poll(duk_context *ctx) +{ + (void)ctx; + + union event ev; + + if (!event_poll(&ev)) + duk_push_null(ctx); + else { + duk_push_object(ctx); + duk_push_int(ctx, ev.type); + duk_put_prop_string(ctx, -2, "type"); + push[ev.type](ctx, &ev); + } + + return 1; +} + +static const duk_function_list_entry functions[] = { + { "poll", Event_poll, 0 }, + { NULL, NULL, 0 } +}; + +static const duk_number_list_entry types[] = { + { "CLICKDOWN", EVENT_CLICKDOWN }, + { "CLICKUP", EVENT_CLICKUP }, + { "KEYDOWN", EVENT_KEYDOWN }, + { "KEYUP", EVENT_KEYUP }, + { "MOUSE", EVENT_MOUSE }, + { "QUIT", EVENT_QUIT }, + { NULL, 0 } +}; + +static const duk_number_list_entry keys[] = { + { "UNKNOWN", KEY_UNKNOWN }, + { "ENTER", KEY_ENTER }, + { "ESCAPE", KEY_ESCAPE }, + { "BACKSPACE", KEY_BACKSPACE }, + { "TAB", KEY_TAB }, + { "SPACE", KEY_SPACE }, + { "EXCLAIM", KEY_EXCLAIM }, + { "DOUBLE_QUOTE", KEY_DOUBLE_QUOTE }, + { "HASH", KEY_HASH }, + { "PERCENT", KEY_PERCENT }, + { "DOLLAR", KEY_DOLLAR }, + { "AMPERSAND", KEY_AMPERSAND }, + { "QUOTE", KEY_QUOTE }, + { "LEFT_PAREN", KEY_LEFT_PAREN }, + { "RIGHT_PAREN", KEY_RIGHT_PAREN }, + { "ASTERISK", KEY_ASTERISK }, + { "PLUS", KEY_PLUS }, + { "COMMA", KEY_COMMA }, + { "MINUS", KEY_MINUS }, + { "PERIOD", KEY_PERIOD }, + { "SLASH", KEY_SLASH }, + { "0", KEY_0 }, + { "1", KEY_1 }, + { "2", KEY_2 }, + { "3", KEY_3 }, + { "4", KEY_4 }, + { "5", KEY_5 }, + { "6", KEY_6 }, + { "7", KEY_7 }, + { "8", KEY_8 }, + { "9", KEY_9 }, + { "COLON", KEY_COLON }, + { "SEMICOLON", KEY_SEMICOLON }, + { "LESS", KEY_LESS }, + { "EQUALS", KEY_EQUALS }, + { "GREATER", KEY_GREATER }, + { "QUESTION", KEY_QUESTION }, + { "AT", KEY_AT }, + { "LEFT_BRACKET", KEY_LEFT_BRACKET }, + { "BACKSLASH", KEY_BACKSLASH }, + { "RIGHT_BRACKET", KEY_RIGHT_BRACKET }, + { "CARET", KEY_CARET }, + { "UNDERSCORE", KEY_UNDERSCORE }, + { "BACKQUOTE", KEY_BACKQUOTE }, + { "a", KEY_a }, + { "b", KEY_b }, + { "c", KEY_c }, + { "d", KEY_d }, + { "e", KEY_e }, + { "f", KEY_f }, + { "g", KEY_g }, + { "h", KEY_h }, + { "i", KEY_i }, + { "j", KEY_j }, + { "k", KEY_k }, + { "l", KEY_l }, + { "m", KEY_m }, + { "n", KEY_n }, + { "o", KEY_o }, + { "p", KEY_p }, + { "q", KEY_q }, + { "r", KEY_r }, + { "s", KEY_s }, + { "t", KEY_t }, + { "u", KEY_u }, + { "v", KEY_v }, + { "w", KEY_w }, + { "x", KEY_x }, + { "y", KEY_y }, + { "z", KEY_z }, + { "CAPSLOCK", KEY_CAPSLOCK }, + { "F1", KEY_F1 }, + { "F2", KEY_F2 }, + { "F3", KEY_F3 }, + { "F4", KEY_F4 }, + { "F5", KEY_F5 }, + { "F6", KEY_F6 }, + { "F7", KEY_F7 }, + { "F8", KEY_F8 }, + { "F9", KEY_F9 }, + { "F10", KEY_F10 }, + { "F11", KEY_F11 }, + { "F12", KEY_F12 }, + { "F13", KEY_F13 }, + { "F14", KEY_F14 }, + { "F15", KEY_F15 }, + { "F16", KEY_F16 }, + { "F17", KEY_F17 }, + { "F18", KEY_F18 }, + { "F19", KEY_F19 }, + { "F20", KEY_F20 }, + { "F21", KEY_F21 }, + { "F22", KEY_F22 }, + { "F23", KEY_F23 }, + { "F24", KEY_F24 }, + { "PRINTSCREEN", KEY_PRINTSCREEN }, + { "SCROLL_LOCK", KEY_SCROLL_LOCK }, + { "PAUSE", KEY_PAUSE }, + { "INSERT", KEY_INSERT }, + { "HOME", KEY_HOME }, + { "PAGEUP", KEY_PAGEUP }, + { "DELETE", KEY_DELETE }, + { "END", KEY_END }, + { "PAGEDOWN", KEY_PAGEDOWN }, + { "RIGHT", KEY_RIGHT }, + { "LEFT", KEY_LEFT }, + { "DOWN", KEY_DOWN }, + { "UP", KEY_UP }, + { "NUMLOCKCLEAR", KEY_NUMLOCKCLEAR }, + { "KP_DIVIDE", KEY_KP_DIVIDE }, + { "KP_MULTIPLY", KEY_KP_MULTIPLY }, + { "KP_MINUS", KEY_KP_MINUS }, + { "KP_PLUS", KEY_KP_PLUS }, + { "KP_ENTER", KEY_KP_ENTER }, + { "KP_00", KEY_KP_00 }, + { "KP_000", KEY_KP_000 }, + { "KP_1", KEY_KP_1 }, + { "KP_2", KEY_KP_2 }, + { "KP_3", KEY_KP_3 }, + { "KP_4", KEY_KP_4 }, + { "KP_5", KEY_KP_5 }, + { "KP_6", KEY_KP_6 }, + { "KP_7", KEY_KP_7 }, + { "KP_8", KEY_KP_8 }, + { "KP_9", KEY_KP_9 }, + { "KP_0", KEY_KP_0 }, + { "KP_PERIOD", KEY_KP_PERIOD }, + { "KP_COMMA", KEY_KP_COMMA }, + { "MENU", KEY_MENU }, + { "MUTE", KEY_MUTE }, + { "VOLUME_UP", KEY_VOLUME_UP }, + { "VOLUME_DOWN", KEY_VOLUME_DOWN }, + { "LCTRL", KEY_LCTRL }, + { "LSHIFT", KEY_LSHIFT }, + { "LALT", KEY_LALT }, + { "LSUPER", KEY_LSUPER }, + { "RCTRL", KEY_RCTRL }, + { "RSHIFT", KEY_RSHIFT }, + { "RALT", KEY_RALT }, + { "RSUPER", KEY_RSUPER }, + { NULL, 0 } +}; + +static const duk_number_list_entry keymods[] = { + { "LSHIFT", KEYMOD_LSHIFT }, + { "LCTRL", KEYMOD_LCTRL }, + { "LALT", KEYMOD_LALT }, + { "LSUPER", KEYMOD_LSUPER }, + { "RSHIFT", KEYMOD_RSHIFT }, + { "RTCRL", KEYMOD_RCTRL }, + { "RALT", KEYMOD_RALT }, + { "RSUPER", KEYMOD_RSUPER }, + { NULL, 0 } +}; + +static const duk_number_list_entry buttons[] = { + { "LEFT", MOUSE_BUTTON_LEFT }, + { "MIDDLE", MOUSE_BUTTON_MIDDLE }, + { "RIGHT", MOUSE_BUTTON_RIGHT }, + { NULL, 0 } +}; + +void +js_event_bind(duk_context *ctx) +{ + assert(ctx); + + duk_push_global_object(ctx); + duk_push_object(ctx); + duk_put_function_list(ctx, -1, functions); + duk_push_object(ctx); + duk_put_number_list(ctx, -1, types); + duk_put_prop_string(ctx, -2, "type"); + duk_push_object(ctx); + duk_put_number_list(ctx, -1, keys); + duk_put_prop_string(ctx, -2, "key"); + duk_push_object(ctx); + duk_put_number_list(ctx, -1, keymods); + duk_put_prop_string(ctx, -2, "keymod"); + duk_push_object(ctx); + duk_put_number_list(ctx, -1, buttons); + duk_put_prop_string(ctx, -2, "button"); + duk_put_prop_string(ctx, -2, "Event"); + duk_pop(ctx); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/libmlk-core-js/core/js-event.h Thu Oct 14 21:21:28 2021 +0200 @@ -0,0 +1,27 @@ +/* + * js-event.h -- core event binding + * + * Copyright (c) 2020-2021 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MLK_CORE_JS_EVENT_H +#define MLK_CORE_JS_EVENT_H + +#include <duktape.h> + +void +js_event_bind(duk_context *); + +#endif /* !MLK_CORE_JS_EVENT_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/libmlk-core-js/core/js-painter.c Thu Oct 14 21:21:28 2021 +0200 @@ -0,0 +1,165 @@ +/* + * js-painter.c -- core painter binding + * + * Copyright (c) 2020-2021 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <assert.h> + +#include <core/painter.h> + +#include "js-painter.h" +#include "js-texture.h" + +static duk_ret_t +Painter_getTarget(duk_context *ctx) +{ + struct texture *tex; + + if (!(tex = painter_get_target())) + duk_push_null(ctx); + else + js_texture_push(ctx, tex); + + return 1; +} + +static duk_ret_t +Painter_setTarget(duk_context *ctx) +{ + if (duk_is_null(ctx, 0)) + painter_set_target(NULL); + else + painter_set_target(js_texture_require(ctx, 0)); + + return 0; +} + +static duk_ret_t +Painter_getColor(duk_context *ctx) +{ + duk_push_number(ctx, painter_get_color()); + + return 1; +} + +static duk_ret_t +Painter_setColor(duk_context *ctx) +{ + const unsigned long color = duk_require_number(ctx, 0); + + painter_set_color(color); + + return 0; +} + +static duk_ret_t +Painter_drawLine(duk_context *ctx) +{ + const int x1 = duk_require_int(ctx, 0); + const int y1 = duk_require_int(ctx, 1); + const int x2 = duk_require_int(ctx, 2); + const int y2 = duk_require_int(ctx, 3); + + painter_draw_line(x1, y1, x2, y2); + + return 0; +} + +static duk_ret_t +Painter_drawPoint(duk_context *ctx) +{ + const int x = duk_require_int(ctx, 0); + const int y = duk_require_int(ctx, 1); + + painter_draw_point(x, y); + + return 0; +} + +static duk_ret_t +Painter_drawRectangle(duk_context *ctx) +{ + const int x = duk_require_int(ctx, 0); + const int y = duk_require_int(ctx, 1); + const unsigned int w = duk_require_uint(ctx, 2); + const unsigned int h = duk_require_uint(ctx, 3); + + painter_draw_rectangle(x, y, w, h); + + return 0; +} + +static duk_ret_t +Painter_drawCircle(duk_context *ctx) +{ + const int x = duk_require_int(ctx, 0); + const int y = duk_require_int(ctx, 1); + const int r = duk_require_int(ctx, 2); + + painter_draw_circle(x, y, r); + + return 0; +} + +static duk_ret_t +Painter_clear(duk_context *ctx) +{ + (void)ctx; + + painter_clear(); + + return 0; +} + +static duk_ret_t +Painter_present(duk_context *ctx) +{ + (void)ctx; + + painter_present(); + + return 0; +} + +static const duk_function_list_entry functions[] = { + { "drawLine", Painter_drawLine, 4 }, + { "drawPoint", Painter_drawPoint, 2 }, + { "drawRectangle", Painter_drawRectangle, 4 }, + { "drawCircle", Painter_drawCircle, 3 }, + { "clear", Painter_clear, 0 }, + { "present", Painter_present, 0 }, + { NULL, NULL, 0 } +}; + +void +js_painter_bind(duk_context *ctx) +{ + assert(ctx); + + duk_push_global_object(ctx); + duk_push_object(ctx); + duk_put_function_list(ctx, -1, functions); + duk_push_string(ctx, "color"); + duk_push_c_function(ctx, Painter_getColor, 0); + duk_push_c_function(ctx, Painter_setColor, 1); + duk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_SETTER | DUK_DEFPROP_HAVE_GETTER); + duk_push_string(ctx, "target"); + duk_push_c_function(ctx, Painter_getTarget, 0); + duk_push_c_function(ctx, Painter_setTarget, 1); + duk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_SETTER | DUK_DEFPROP_HAVE_GETTER); + duk_put_prop_string(ctx, -2, "Painter"); + duk_pop(ctx); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/libmlk-core-js/core/js-painter.h Thu Oct 14 21:21:28 2021 +0200 @@ -0,0 +1,27 @@ +/* + * js-painter.h -- core painter binding + * + * Copyright (c) 2020-2021 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MLK_CORE_JS_PAINTER_H +#define MLK_CORE_JS_PAINTER_H + +#include <duktape.h> + +void +js_painter_bind(duk_context *); + +#endif /* !MLK_CORE_JS_PAINTER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/libmlk-core-js/core/js-texture.c Thu Oct 14 21:21:28 2021 +0200 @@ -0,0 +1,216 @@ +/* + * js-texture.c -- core texture binding + * + * Copyright (c) 2020-2021 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <assert.h> + +#include <core/alloc.h> +#include <core/error.h> +#include <core/texture.h> + +#include "js-texture.h" + +#define SIGNATURE DUK_HIDDEN_SYMBOL("Mlk.Texture") +#define PROTOTYPE DUK_HIDDEN_SYMBOL("Mlk.Texture.Prototype") + +static inline struct texture * +self(duk_context *ctx) +{ + struct texture *tex; + + duk_push_this(ctx); + duk_get_prop_string(ctx, -1, SIGNATURE); + tex = duk_to_pointer(ctx, -1); + duk_pop_2(ctx); + + if (!tex) + duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a Texture object"); + + return tex; +} + +static duk_ret_t +Texture_constructor(duk_context *ctx) +{ + const unsigned int w = duk_require_uint(ctx, 0); + const unsigned int h = duk_require_uint(ctx, 1); + struct texture *tex; + + tex = alloc_new(sizeof (*tex)); + + if (texture_new(tex, w, h) < 0) + duk_error(ctx, DUK_ERR_ERROR, "%s", error()); + + duk_push_this(ctx); + duk_push_pointer(ctx, tex); + duk_put_prop_string(ctx, -2, SIGNATURE); + duk_pop(ctx); + + return 0; +} + +static duk_ret_t +Texture_setBlendMode(duk_context *ctx) +{ + const int blend = duk_require_uint(ctx, 0); + struct texture *tex = self(ctx); + + if (blend < 0 || blend >= TEXTURE_BLEND_LAST) + duk_error(ctx, DUK_ERR_ERROR, "invalid blend"); + if (texture_set_blend_mode(tex, blend) < 0) + duk_error(ctx, DUK_ERR_ERROR, "%s", error()); + + return 0; +} + +static duk_ret_t +Texture_setAlphaMod(duk_context *ctx) +{ + const unsigned int alpha = duk_require_uint(ctx, 0); + struct texture *tex = self(ctx); + + if (texture_set_alpha_mod(tex, alpha) < 0) + duk_error(ctx, DUK_ERR_ERROR, "%s", error()); + + return 0; +} + +static duk_ret_t +Texture_setColorMod(duk_context *ctx) +{ + const unsigned long color = duk_require_uint(ctx, 0); + struct texture *tex = self(ctx); + + if (texture_set_color_mod(tex, color) < 0) + duk_error(ctx, DUK_ERR_ERROR, "%s", error()); + + return 0; +} + +static duk_ret_t +Texture_draw(duk_context *ctx) +{ + const int x = duk_require_int(ctx, 0); + const int y = duk_require_int(ctx, 1); + struct texture *tex = self(ctx); + + if (texture_draw(tex, x, y) < 0) + duk_error(ctx, DUK_ERR_ERROR, "%s", error()); + + return 0; +} + +static duk_ret_t +Texture_scale(duk_context *ctx) +{ + const int srcx = duk_require_int(ctx, 0); + const int srcy = duk_require_int(ctx, 1); + const unsigned srcw = duk_require_uint(ctx, 2); + const unsigned srch = duk_require_uint(ctx, 3); + const int dstx = duk_require_int(ctx, 4); + const int dsty = duk_require_int(ctx, 5); + const unsigned dstw = duk_require_uint(ctx, 6); + const unsigned dsth = duk_require_uint(ctx, 7); + const double angle = duk_get_number_default(ctx, 8, .0); + struct texture *tex = self(ctx); + + if (texture_scale(tex, srcx, srcy, srcw, srch, dstx, dsty, dstw, dsth, angle) < 0) + duk_error(ctx, DUK_ERR_ERROR, "%s", error()); + + return 0; +} + +static duk_ret_t +Texture_destructor(duk_context *ctx) +{ + struct texture *tex; + + duk_get_prop_string(ctx, 0, SIGNATURE); + + if ((tex = duk_to_pointer(ctx, -1))) + texture_finish(tex); + + duk_pop(ctx); + duk_del_prop_string(ctx, 0, SIGNATURE); + + return 0; +} + +static const struct duk_function_list_entry methods[] = { + { "setBlendMode", Texture_setBlendMode, 1 }, + { "setAlphaMod", Texture_setAlphaMod, 1 }, + { "setColorMod", Texture_setColorMod, 1 }, + { "draw", Texture_draw, 2 }, + { "scale", Texture_scale, DUK_VARARGS }, + { NULL, NULL, 0 } +}; + +static const duk_number_list_entry blend[] = { + { "NONE", TEXTURE_BLEND_NONE }, + { "BLEND", TEXTURE_BLEND_BLEND }, + { "ADD", TEXTURE_BLEND_ADD }, + { "MODULATE", TEXTURE_BLEND_MODULATE }, + { NULL, 0 } +}; + +void +js_texture_bind(duk_context *ctx) +{ + assert(ctx); + + duk_push_global_object(ctx); + duk_push_c_function(ctx, Texture_constructor, 2); + duk_push_object(ctx); + duk_put_function_list(ctx, -1, methods); + duk_push_c_function(ctx, Texture_destructor, 1); + duk_set_finalizer(ctx, -2); + duk_push_object(ctx); + duk_put_number_list(ctx, -1, blend); + duk_put_prop_string(ctx, -2, "Blend"); + duk_dup(ctx, -1); + duk_put_global_string(ctx, PROTOTYPE); + duk_put_prop_string(ctx, -2, "prototype"); + duk_pop(ctx); +} + +struct texture * +js_texture_require(duk_context *ctx, duk_idx_t idx) +{ + struct texture *tex; + + duk_get_prop_string(ctx, idx, SIGNATURE); + tex = duk_to_pointer(ctx, -1); + duk_pop(ctx); + + if (!tex) + duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a Texture object"); + + return tex; +} + +void +js_texture_push(duk_context *ctx, struct texture *tex) +{ + assert(ctx); + assert(tex); + + duk_push_object(ctx); + duk_push_pointer(ctx, tex); + duk_put_prop_string(ctx, -2, SIGNATURE); + duk_get_global_string(ctx, PROTOTYPE); + duk_set_prototype(ctx, -2); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/libmlk-core-js/core/js-texture.h Thu Oct 14 21:21:28 2021 +0200 @@ -0,0 +1,35 @@ +/* + * js-texture.h -- core texture binding + * + * Copyright (c) 2020-2021 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MLK_CORE_JS_TEXTURE_H +#define MLK_CORE_JS_TEXTURE_H + +#include <duktape.h> + +struct texture; + +void +js_texture_bind(duk_context *); + +struct texture * +js_texture_require(duk_context *, duk_idx_t); + +void +js_texture_push(duk_context *, struct texture *); + +#endif /* !MLK_CORE_JS_TEXTURE_H */
--- a/src/libmlk-core-js/core/js-window.c Thu Oct 14 12:52:41 2021 +0200 +++ b/src/libmlk-core-js/core/js-window.c Thu Oct 14 21:21:28 2021 +0200 @@ -18,11 +18,11 @@ #include <assert.h> -#include <duktape.h> - #include <core/error.h> #include <core/window.h> +#include "js-window.h" + #define SIGNATURE DUK_HIDDEN_SYMBOL("Mlk.Window") static duk_ret_t
--- a/src/mlk-run/main.c Thu Oct 14 12:52:41 2021 +0200 +++ b/src/mlk-run/main.c Thu Oct 14 21:21:28 2021 +0200 @@ -26,6 +26,10 @@ #include <core/vfs-zip.h> #include <core/vfs.h> +#include <core/js-clock.h> +#include <core/js-event.h> +#include <core/js-painter.h> +#include <core/js-texture.h> #include <core/js-window.h> /* VFS loader to support zip and directories when loading game. */ @@ -34,9 +38,21 @@ /* Javascript context. */ static duk_context *ctx; +static duk_ret_t +print(duk_context *ctx) +{ + puts(duk_require_string(ctx, 0)); + + return 0; +} + static void core_bind(duk_context *ctx) { + js_clock_bind(ctx); + js_event_bind(ctx); + js_painter_bind(ctx); + js_texture_bind(ctx); js_window_bind(ctx); } @@ -50,6 +66,12 @@ /* Fireup Javascript. */ ctx = duk_create_heap_default(); core_bind(ctx); + + /* Setup some convenient global functions. */ + duk_push_global_object(ctx); + duk_push_c_function(ctx, print, 1); + duk_put_prop_string(ctx, -2, "print"); + duk_pop(ctx); } static char *