Add more error checking to sandbox bindings

* Added checks for when an incorrect number of arguments is passed to a
  function
* Added checks for when an argument of object type has mismatching type
  (arguments of numeric and string types were already checked for type
  mismatches before this commit)
* Added checks for trying to read certain properties of a disposed
  object
This commit is contained in:
刘皓 2025-08-18 14:04:09 -04:00
parent 0307f2ed18
commit b55f6dd1f4
No known key found for this signature in database
GPG key ID: 7901753DB465B711
17 changed files with 299 additions and 81 deletions

View file

@ -38,6 +38,8 @@ static VALUE bgm_play(int32_t argc, wasm_ptr_t argv, VALUE self) {
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
SANDBOX_AWAIT(check_arity, argc, 1, -1);
SANDBOX_SLOT(0) = 0.0;
SANDBOX_SLOT(2) = 100;
SANDBOX_SLOT(3) = 100;
@ -92,6 +94,8 @@ static VALUE bgm_fade(int32_t argc, wasm_ptr_t argv, VALUE self) {
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
SANDBOX_AWAIT(check_arity, argc, 1, -1);
SANDBOX_SLOT(1) = -127;
SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref<VALUE>(argv, 0));
if (argc >= 2) {
@ -155,6 +159,8 @@ static VALUE bgm_set_volume(int32_t argc, wasm_ptr_t argv, VALUE self) {
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
SANDBOX_AWAIT(check_arity, argc, 1, -1);
SANDBOX_SLOT(1) = -127;
SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref<VALUE>(argv, 0));
if (argc >= 2) {
@ -176,6 +182,8 @@ static VALUE bgs_play(int32_t argc, wasm_ptr_t argv, VALUE self) {
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
SANDBOX_AWAIT(check_arity, argc, 1, -1);
SANDBOX_SLOT(0) = 0.0;
SANDBOX_SLOT(2) = 100;
SANDBOX_SLOT(3) = 100;
@ -246,6 +254,8 @@ static VALUE me_play(int32_t argc, wasm_ptr_t argv, VALUE self) {
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
SANDBOX_AWAIT(check_arity, argc, 1, -1);
SANDBOX_SLOT(1) = 100;
SANDBOX_SLOT(2) = 100;
@ -295,6 +305,8 @@ static VALUE se_play(int32_t argc, wasm_ptr_t argv, VALUE self) {
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
SANDBOX_AWAIT(check_arity, argc, 1, -1);
SANDBOX_SLOT(1) = 100;
SANDBOX_SLOT(2) = 100;

View file

@ -118,3 +118,41 @@ void exception_raise::operator()(const Exception &exception) {
SANDBOX_AWAIT(rb_exc_raise, SANDBOX_SLOT(0));
}
}
void check_arity::operator()(int32_t argc, int32_t min_argc, int32_t max_argc) {
BOOST_ASIO_CORO_REENTER (this) {
if (argc < min_argc || (max_argc != -1 && argc > max_argc)) {
SANDBOX_AWAIT(rb_error_arity, argc, min_argc, max_argc);
}
}
}
void check_type::operator()(VALUE obj, VALUE klass) {
BOOST_ASIO_CORO_REENTER (this) {
SANDBOX_AWAIT_S(0, rb_obj_is_kind_of, obj, klass);
if (!SANDBOX_VALUE_TO_BOOL(SANDBOX_SLOT(0))) {
SANDBOX_AWAIT_S(0, rb_str_new_cstr, "no implicit conversion of ");
SANDBOX_AWAIT_S(1, rb_obj_class, obj);
SANDBOX_AWAIT_S(1, rb_class_name, SANDBOX_SLOT(1));
SANDBOX_AWAIT(rb_str_append, SANDBOX_SLOT(0), SANDBOX_SLOT(1));
SANDBOX_AWAIT(rb_str_cat_cstr, SANDBOX_SLOT(0), " into ");
SANDBOX_AWAIT_S(1, rb_class_name, klass);
SANDBOX_AWAIT(rb_str_append, SANDBOX_SLOT(0), SANDBOX_SLOT(1));
SANDBOX_AWAIT_S(0, rb_class_new_instance, 1, &SANDBOX_SLOT(0), sb()->rb_eTypeError());
SANDBOX_AWAIT(rb_exc_raise, SANDBOX_SLOT(0));
}
}
}
void raise_disposed_access::operator()(VALUE obj) {
BOOST_ASIO_CORO_REENTER (this) {
SANDBOX_AWAIT_S(1, rb_obj_class, obj);
SANDBOX_AWAIT_S(1, rb_class_name, SANDBOX_SLOT(1));
SANDBOX_AWAIT_S(2, rb_intern, "downcase!");
SANDBOX_AWAIT(rb_funcall, SANDBOX_SLOT(1), SANDBOX_SLOT(2), 0);
SANDBOX_AWAIT_S(0, rb_str_new_cstr, "disposed ");
SANDBOX_AWAIT(rb_str_append, SANDBOX_SLOT(0), SANDBOX_SLOT(1));
SANDBOX_AWAIT_S(0, rb_class_new_instance, 1, &SANDBOX_SLOT(0), rgss_error_class);
SANDBOX_AWAIT(rb_exc_raise, SANDBOX_SLOT(0));
}
}

View file

@ -136,7 +136,7 @@
#define SANDBOX_DEF_CLASS_PROP_F(S, prop, name) SANDBOX_DEF_CLASS_PROP(float, rb_float_new, rb_num2dbl, S, prop, name)
#define SANDBOX_DEF_CLASS_PROP_D(S, prop, name) SANDBOX_DEF_CLASS_PROP(double, rb_float_new, rb_num2dbl, S, prop, name)
#define SANDBOX_DEF_CLASS_PROP_OBJ_REF(S, V, prop, name) \
#define SANDBOX_DEF_CLASS_PROP_OBJ_REF(S, V, klass, prop, name) \
static VALUE get_##name(VALUE self) { \
using namespace ::mkxp_sandbox; \
return sb()->bind<struct rb_iv_get>()()(self, #name); \
@ -146,6 +146,9 @@
struct coro : boost::asio::coroutine { \
VALUE operator()(VALUE self, VALUE value) { \
BOOST_ASIO_CORO_REENTER (this) { \
if (value != SANDBOX_NIL) { \
SANDBOX_AWAIT(check_type, value, klass); \
} \
{ \
V *v = value == SANDBOX_NIL ? nullptr : get_private_data<V>(value); \
S::set##prop(v); \
@ -158,16 +161,24 @@
return sb()->bind<struct coro>()()(self, value); \
}
#define SANDBOX_DEF_CLASS_PROP_OBJ_VAL(S, V, prop, name) \
#define SANDBOX_DEF_CLASS_PROP_OBJ_VAL(S, V, klass, prop, name) \
static VALUE get_##name(VALUE self) { \
using namespace ::mkxp_sandbox; \
return sb()->bind<struct rb_iv_get>()()(self, #name); \
} \
static VALUE set_##name(VALUE self, VALUE value) { \
using namespace ::mkxp_sandbox; \
V *v = get_private_data<V>(value); \
S::set##prop(*v); \
return value; \
struct coro : boost::asio::coroutine { \
VALUE operator()(VALUE self, VALUE value) { \
BOOST_ASIO_CORO_REENTER (this) { \
SANDBOX_AWAIT(check_type, value, klass); \
V *v = get_private_data<V>(value); \
S::set##prop(*v); \
} \
return value; \
} \
}; \
return sb()->bind<struct coro>()()(self, value); \
}
#define SANDBOX_DEF_PROP_B(S, prop, name) \
@ -209,7 +220,7 @@
#define SANDBOX_DEF_PROP_F(S, prop, name) SANDBOX_DEF_PROP(float, rb_float_new, rb_num2dbl, S, prop, name)
#define SANDBOX_DEF_PROP_D(S, prop, name) SANDBOX_DEF_PROP(double, rb_float_new, rb_num2dbl, S, prop, name)
#define SANDBOX_DEF_PROP_OBJ_REF(S, V, prop, name) \
#define SANDBOX_DEF_PROP_OBJ_REF(S, V, klass, prop, name) \
static VALUE get_##name(VALUE self) { \
using namespace ::mkxp_sandbox; \
return sb()->bind<struct rb_iv_get>()()(self, #name); \
@ -219,6 +230,9 @@
struct coro : boost::asio::coroutine { \
VALUE operator()(VALUE self, VALUE value) { \
BOOST_ASIO_CORO_REENTER (this) { \
if (value != SANDBOX_NIL) { \
SANDBOX_AWAIT(check_type, value, klass); \
} \
{ \
S *s = get_private_data<S>(self); \
V *v = value == SANDBOX_NIL ? nullptr : get_private_data<V>(value); \
@ -232,17 +246,25 @@
return sb()->bind<struct coro>()()(self, value); \
}
#define SANDBOX_DEF_PROP_OBJ_VAL(S, V, prop, name) \
#define SANDBOX_DEF_PROP_OBJ_VAL(S, V, klass, prop, name) \
static VALUE get_##name(VALUE self) { \
using namespace ::mkxp_sandbox; \
return sb()->bind<struct rb_iv_get>()()(self, #name); \
} \
static VALUE set_##name(VALUE self, VALUE value) { \
using namespace ::mkxp_sandbox; \
S *s = get_private_data<S>(self); \
V *v = get_private_data<V>(value); \
s->set##prop(*v); \
return value; \
struct coro : boost::asio::coroutine { \
VALUE operator()(VALUE self, VALUE value) { \
BOOST_ASIO_CORO_REENTER (this) { \
SANDBOX_AWAIT(check_type, value, klass); \
S *s = get_private_data<S>(self); \
V *v = get_private_data<V>(value); \
s->set##prop(*v); \
} \
return value; \
} \
}; \
return sb()->bind<struct coro>()()(self, value); \
}
#define SANDBOX_DEF_GFX_PROP_B(S, prop, name) \
@ -305,7 +327,7 @@
#define SANDBOX_DEF_GFX_PROP_F(S, prop, name) SANDBOX_DEF_GFX_PROP(float, rb_float_new, rb_num2dbl, S, prop, name)
#define SANDBOX_DEF_GFX_PROP_D(S, prop, name) SANDBOX_DEF_GFX_PROP(double, rb_float_new, rb_num2dbl, S, prop, name)
#define SANDBOX_DEF_GFX_PROP_OBJ_REF(S, V, prop, name) \
#define SANDBOX_DEF_GFX_PROP_OBJ_REF(S, V, klass, prop, name) \
static VALUE get_##name(VALUE self) { \
using namespace ::mkxp_sandbox; \
return sb()->bind<struct rb_iv_get>()()(self, #name); \
@ -315,6 +337,9 @@
struct coro : boost::asio::coroutine { \
VALUE operator()(VALUE self, VALUE value) { \
BOOST_ASIO_CORO_REENTER (this) { \
if (value != SANDBOX_NIL) { \
SANDBOX_AWAIT(check_type, value, klass); \
} \
SANDBOX_GUARD_L(get_private_data<S>(self)->set##prop(sb().e, value == SANDBOX_NIL ? nullptr : get_private_data<V>(value))); \
SANDBOX_AWAIT(rb_iv_set, self, #name, value); \
} \
@ -324,7 +349,7 @@
return sb()->bind<struct coro>()()(self, value); \
}
#define SANDBOX_DEF_GFX_PROP_OBJ_VAL(S, V, prop, name) \
#define SANDBOX_DEF_GFX_PROP_OBJ_VAL(S, V, klass, prop, name) \
static VALUE get_##name(VALUE self) { \
using namespace ::mkxp_sandbox; \
return sb()->bind<struct rb_iv_get>()()(self, #name); \
@ -334,6 +359,7 @@
struct coro : boost::asio::coroutine { \
VALUE operator()(VALUE self, VALUE value) { \
BOOST_ASIO_CORO_REENTER (this) { \
SANDBOX_AWAIT(check_type, value, klass); \
SANDBOX_GUARD_L(get_private_data<S>(self)->set##prop(sb().e, *get_private_data<V>(value))); \
} \
return value; \
@ -382,7 +408,7 @@
#define SANDBOX_DEF_GRA_PROP_F(prop, name) SANDBOX_DEF_GRA_PROP(float, rb_float_new, rb_num2dbl, prop, name)
#define SANDBOX_DEF_GRA_PROP_D(prop, name) SANDBOX_DEF_GRA_PROP(double, rb_float_new, rb_num2dbl, prop, name)
#define SANDBOX_DEF_GRA_PROP_OBJ_REF(V, prop, name) \
#define SANDBOX_DEF_GRA_PROP_OBJ_REF(V, klass, prop, name) \
static VALUE get_##name(VALUE self) { \
using namespace ::mkxp_sandbox; \
return sb()->bind<struct rb_iv_get>()()(self, #name); \
@ -392,6 +418,9 @@
struct coro : boost::asio::coroutine { \
VALUE operator()(VALUE self, VALUE value) { \
BOOST_ASIO_CORO_REENTER (this) { \
if (value != SANDBOX_NIL) { \
SANDBOX_AWAIT(check_type, value, klass); \
} \
{ \
V *v = value == SANDBOX_NIL ? nullptr : get_private_data<V>(value); \
GFX_LOCK; \
@ -406,18 +435,26 @@
return sb()->bind<struct coro>()()(self, value); \
}
#define SANDBOX_DEF_GRA_PROP_OBJ_VAL(V, prop, name) \
#define SANDBOX_DEF_GRA_PROP_OBJ_VAL(V, klass, prop, name) \
static VALUE get_##name(VALUE self) { \
using namespace ::mkxp_sandbox; \
return sb()->bind<struct rb_iv_get>()()(self, #name); \
} \
static VALUE set_##name(VALUE self, VALUE value) { \
using namespace ::mkxp_sandbox; \
V *v = get_private_data<V>(value); \
GFX_LOCK; \
shState->graphics().set##prop(*v); \
GFX_UNLOCK; \
return value; \
struct coro : boost::asio::coroutine { \
VALUE operator()(VALUE self, VALUE value) { \
BOOST_ASIO_CORO_REENTER (this) { \
SANDBOX_AWAIT(check_type, value, klass); \
V *v = get_private_data<V>(value); \
GFX_LOCK; \
shState->graphics().set##prop(*v); \
GFX_UNLOCK; \
} \
return value; \
} \
}; \
return sb()->bind<struct coro>()()(self, value); \
}
#define SANDBOX_INIT_FUNC_PROP_BIND(func, target, name) do { \
@ -561,6 +598,20 @@ namespace mkxp_sandbox {
typedef decl_slots<VALUE> slots;
void operator()(const Exception &exception);
};
struct check_arity : boost::asio::coroutine {
void operator()(int32_t argc, int32_t min_argc, int32_t max_argc);
};
struct check_type : boost::asio::coroutine {
typedef decl_slots<VALUE, VALUE> slots;
void operator()(VALUE obj, VALUE klass);
};
struct raise_disposed_access : boost::asio::coroutine {
typedef decl_slots<VALUE, VALUE, ID> slots;
void operator()(VALUE klass);
};
}
#endif // MKXPZ_SANDBOX_BINDING_UTIL_H

View file

@ -19,7 +19,6 @@
** along with mkxp. If not, see <http://www.gnu.org/licenses/>.
*/
#include <algorithm>
#include "bitmap-binding.h"
#include "disposable-binding.h"
#include "etc-binding.h"
@ -62,6 +61,8 @@ static VALUE initialize(int32_t argc, wasm_ptr_t argv, VALUE self) {
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
SANDBOX_AWAIT(check_arity, argc, 1, -1);
if (argc == 1) {
SANDBOX_AWAIT_S(0, rb_string_value_cstr, &sb()->ref<VALUE>(argv, 0));
} else {
@ -142,7 +143,7 @@ static VALUE height(VALUE self) {
return sb()->bind<struct coro>()()(self);
}
SANDBOX_DEF_GFX_PROP_OBJ_REF(Bitmap, Bitmap, Hires, hires);
SANDBOX_DEF_GFX_PROP_OBJ_REF(Bitmap, Bitmap, bitmap_class, Hires, hires);
static VALUE rect(VALUE self) {
struct coro : boost::asio::coroutine {
@ -167,7 +168,8 @@ static VALUE blt(int32_t argc, wasm_ptr_t argv, VALUE self) {
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
// TODO: require at least 4 arguments
SANDBOX_AWAIT(check_arity, argc, 4, -1);
SANDBOX_AWAIT_S(2, rb_num2int, sb()->ref<VALUE>(argv, 0));
SANDBOX_AWAIT_S(3, rb_num2int, sb()->ref<VALUE>(argv, 1));
SANDBOX_SLOT(0) = sb()->ref<VALUE>(argv, 2);
@ -176,7 +178,9 @@ static VALUE blt(int32_t argc, wasm_ptr_t argv, VALUE self) {
SANDBOX_AWAIT_S(4, rb_num2int, sb()->ref<VALUE>(argv, 4));
}
SANDBOX_AWAIT(check_type, SANDBOX_SLOT(0), bitmap_class);
if (get_private_data<Bitmap>(SANDBOX_SLOT(0)) != nullptr) {
SANDBOX_AWAIT(check_type, SANDBOX_SLOT(1), rect_class);
if (argc > 4) {
SANDBOX_GUARD_L(get_private_data<Bitmap>(self)->blt(sb().e, SANDBOX_SLOT(2), SANDBOX_SLOT(3), *get_private_data<Bitmap>(SANDBOX_SLOT(0)), get_private_data<Rect>(SANDBOX_SLOT(1))->toIntRect(), SANDBOX_SLOT(4)));
} else {
@ -198,6 +202,8 @@ static VALUE stretch_blt(int32_t argc, wasm_ptr_t argv, VALUE self) {
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
SANDBOX_AWAIT(check_arity, argc, 3, -1);
SANDBOX_SLOT(0) = sb()->ref<VALUE>(argv, 0);
SANDBOX_SLOT(1) = sb()->ref<VALUE>(argv, 1);
SANDBOX_SLOT(2) = sb()->ref<VALUE>(argv, 2);
@ -205,7 +211,9 @@ static VALUE stretch_blt(int32_t argc, wasm_ptr_t argv, VALUE self) {
SANDBOX_AWAIT_S(3, rb_num2int, sb()->ref<VALUE>(argv, 3));
}
SANDBOX_AWAIT(check_type, SANDBOX_SLOT(1), bitmap_class);
if (get_private_data<Bitmap>(SANDBOX_SLOT(1)) != nullptr) {
SANDBOX_AWAIT(check_type, SANDBOX_SLOT(2), rect_class);
if (argc > 4) {
SANDBOX_GUARD_L(get_private_data<Bitmap>(self)->stretchBlt(sb().e, get_private_data<Rect>(SANDBOX_SLOT(0))->toIntRect(), *get_private_data<Bitmap>(SANDBOX_SLOT(1)), get_private_data<Rect>(SANDBOX_SLOT(2))->toIntRect(), SANDBOX_SLOT(3)););
} else {
@ -228,12 +236,17 @@ static VALUE fill_rect(int32_t argc, wasm_ptr_t argv, VALUE self) {
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
if (argc == 2) {
SANDBOX_AWAIT(check_type, sb()->ref<VALUE>(argv, 0), rect_class);
SANDBOX_AWAIT(check_type, sb()->ref<VALUE>(argv, 1), color_class);
SANDBOX_GUARD_L(get_private_data<Bitmap>(self)->fillRect(sb().e, get_private_data<Rect>(sb()->ref<VALUE>(argv, 0))->toIntRect(), get_private_data<Color>(sb()->ref<VALUE>(argv, 1))->norm));
} else {
SANDBOX_AWAIT(check_arity, argc, 5, -1);
SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref<VALUE>(argv, 0));
SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref<VALUE>(argv, 1));
SANDBOX_AWAIT_S(2, rb_num2int, sb()->ref<VALUE>(argv, 2));
SANDBOX_AWAIT_S(3, rb_num2int, sb()->ref<VALUE>(argv, 3));
SANDBOX_AWAIT(check_type, sb()->ref<VALUE>(argv, 4), color_class);
SANDBOX_GUARD_L(get_private_data<Bitmap>(self)->fillRect(sb().e, SANDBOX_SLOT(0), SANDBOX_SLOT(1), SANDBOX_SLOT(2), SANDBOX_SLOT(3), get_private_data<Color>(sb()->ref<VALUE>(argv, 4))->norm));
}
}
@ -298,6 +311,7 @@ static VALUE set_pixel(VALUE self, VALUE x, VALUE y, VALUE colorObj) {
SANDBOX_AWAIT_S(0, rb_num2int, x);
SANDBOX_AWAIT_S(1, rb_num2int, y);
SANDBOX_AWAIT(check_type, colorObj, color_class);
SANDBOX_GUARD_L(get_private_data<Bitmap>(self)->setPixel(sb().e, SANDBOX_SLOT(0), SANDBOX_SLOT(1), *get_private_data<Color>(colorObj)));
}
@ -339,6 +353,7 @@ static VALUE draw_text(int32_t argc, wasm_ptr_t argv, VALUE self) {
} else {
SANDBOX_AWAIT_S(0, rb_string_value_cstr, &sb()->ref<VALUE>(argv, 1));
}
SANDBOX_AWAIT(check_type, sb()->ref<VALUE>(argv, 0), rect_class);
if (argc == 2) {
SANDBOX_GUARD_L(get_private_data<Bitmap>(self)->drawText(sb().e, get_private_data<Rect>(sb()->ref<VALUE>(argv, 0))->toIntRect(), sb()->str(SANDBOX_SLOT(0))););
} else {
@ -346,6 +361,8 @@ static VALUE draw_text(int32_t argc, wasm_ptr_t argv, VALUE self) {
SANDBOX_GUARD_L(get_private_data<Bitmap>(self)->drawText(sb().e, get_private_data<Rect>(sb()->ref<VALUE>(argv, 0))->toIntRect(), sb()->str(SANDBOX_SLOT(0)), SANDBOX_SLOT(2)););
}
} else {
SANDBOX_AWAIT(check_arity, argc, 5, -1);
SANDBOX_AWAIT_S(3, rb_num2int, sb()->ref<VALUE>(argv, 0));
SANDBOX_AWAIT_S(4, rb_num2int, sb()->ref<VALUE>(argv, 1));
SANDBOX_AWAIT_S(5, rb_num2int, sb()->ref<VALUE>(argv, 2));
@ -474,12 +491,7 @@ static VALUE snap_to_bitmap(int32_t argc, wasm_ptr_t argv, VALUE self) {
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
// TODO: require at least 1 argument
if (argc < 1) {
SANDBOX_SLOT(1) = -1;
} else {
SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref<VALUE>(argv, 0));
}
SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref<VALUE>(argv, 0));
SANDBOX_AWAIT_S(0, rb_obj_alloc, bitmap_class);
@ -507,8 +519,13 @@ static VALUE gradient_fill_rect(int32_t argc, wasm_ptr_t argv, VALUE self) {
} else {
SANDBOX_SLOT(4) = false;
}
SANDBOX_AWAIT(check_type, sb()->ref<VALUE>(argv, 0), rect_class);
SANDBOX_AWAIT(check_type, sb()->ref<VALUE>(argv, 1), color_class);
SANDBOX_AWAIT(check_type, sb()->ref<VALUE>(argv, 2), color_class);
SANDBOX_GUARD_L(get_private_data<Bitmap>(self)->gradientFillRect(sb().e, get_private_data<Rect>(sb()->ref<VALUE>(argv, 0))->toIntRect(), get_private_data<Color>(sb()->ref<VALUE>(argv, 1))->norm, get_private_data<Color>(sb()->ref<VALUE>(argv, 2))->norm, SANDBOX_SLOT(4)));
} else {
SANDBOX_AWAIT(check_arity, argc, 6, -1);
SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref<VALUE>(argv, 0));
SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref<VALUE>(argv, 1));
SANDBOX_AWAIT_S(2, rb_num2int, sb()->ref<VALUE>(argv, 2));
@ -518,6 +535,8 @@ static VALUE gradient_fill_rect(int32_t argc, wasm_ptr_t argv, VALUE self) {
} else {
SANDBOX_SLOT(4) = false;
}
SANDBOX_AWAIT(check_type, sb()->ref<VALUE>(argv, 4), color_class);
SANDBOX_AWAIT(check_type, sb()->ref<VALUE>(argv, 5), color_class);
SANDBOX_GUARD_L(get_private_data<Bitmap>(self)->gradientFillRect(sb().e, SANDBOX_SLOT(0), SANDBOX_SLOT(1), SANDBOX_SLOT(2), SANDBOX_SLOT(3), get_private_data<Color>(sb()->ref<VALUE>(argv, 4))->norm, get_private_data<Color>(sb()->ref<VALUE>(argv, 5))->norm, SANDBOX_SLOT(4)));
}
}
@ -536,8 +555,11 @@ static VALUE clear_rect(int32_t argc, wasm_ptr_t argv, VALUE self) {
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
if (argc == 1) {
SANDBOX_AWAIT(check_type, sb()->ref<VALUE>(argv, 0), rect_class);
SANDBOX_GUARD_L(get_private_data<Bitmap>(self)->clearRect(sb().e, get_private_data<Rect>(sb()->ref<VALUE>(argv, 0))->toIntRect()));
} else {
SANDBOX_AWAIT(check_arity, argc, 4, -1);
SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref<VALUE>(argv, 0));
SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref<VALUE>(argv, 1));
SANDBOX_AWAIT_S(2, rb_num2int, sb()->ref<VALUE>(argv, 2));
@ -715,7 +737,7 @@ static VALUE add_frame(int32_t argc, wasm_ptr_t argv, VALUE self) {
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
// TODO: require at least 1 argument
SANDBOX_AWAIT(check_arity, argc, 1, -1);
if (argc < 2) {
SANDBOX_SLOT(1) = -1;
} else {
@ -725,6 +747,10 @@ static VALUE add_frame(int32_t argc, wasm_ptr_t argv, VALUE self) {
}
}
if (argc >= 1) {
SANDBOX_AWAIT(check_type, sb()->ref<VALUE>(argv, 0), bitmap_class);
if (!has_private_data<Bitmap>(sb()->ref<VALUE>(argv, 0))) {
SANDBOX_AWAIT(raise_disposed_access, sb()->ref<VALUE>(argv, 0));
}
SANDBOX_GUARD_L(SANDBOX_SLOT(1) = get_private_data<Bitmap>(self)->addFrame(sb().e, *get_private_data<Bitmap>(sb()->ref<VALUE>(argv, 0)), SANDBOX_SLOT(1)));
}
SANDBOX_AWAIT_S(0, rb_ll2inum, SANDBOX_SLOT(1));
@ -743,7 +769,7 @@ static VALUE remove_frame(int32_t argc, wasm_ptr_t argv, VALUE self) {
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
if (argc < 2) {
if (argc < 1) {
SANDBOX_SLOT(0) = -1;
} else {
SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref<VALUE>(argv, 0));
@ -795,7 +821,23 @@ SANDBOX_DEF_GFX_PROP_F(Bitmap, AnimationFPS, frame_rate);
SANDBOX_DEF_GFX_PROP_B(Bitmap, Looping, looping);
static VALUE get_font(VALUE self) {
return sb()->bind<struct rb_iv_get>()()(self, "font");
struct coro : boost::asio::coroutine {
typedef decl_slots<VALUE> slots;
VALUE operator()(VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
if (get_private_data<Bitmap>(self)->isDisposed()) {
SANDBOX_AWAIT(raise_disposed_access, self);
}
SANDBOX_AWAIT_S(0, rb_iv_get, self, "font");
}
return SANDBOX_SLOT(0);
}
};
return sb()->bind<struct coro>()()(self);
}
static VALUE set_font(VALUE self, VALUE value) {
@ -804,6 +846,7 @@ static VALUE set_font(VALUE self, VALUE value) {
VALUE operator()(VALUE self, VALUE value) {
BOOST_ASIO_CORO_REENTER (this) {
SANDBOX_AWAIT(check_type, value, font_class);
if (get_private_data<Font>(value) != nullptr) {
SANDBOX_GUARD_L(get_private_data<Bitmap>(self)->setFont(sb().e, *get_private_data<Font>(value)));

View file

@ -46,7 +46,7 @@ struct color_binding_init : boost::asio::coroutine {
if (argc == 0) {
set_private_data(self, new Color);
} else {
// TODO: make these optional
SANDBOX_AWAIT(check_arity, argc, 3, -1);
SANDBOX_AWAIT_S(0, rb_num2dbl, sb()->ref<VALUE>(argv, 0));
SANDBOX_AWAIT_S(1, rb_num2dbl, sb()->ref<VALUE>(argv, 1));
SANDBOX_AWAIT_S(2, rb_num2dbl, sb()->ref<VALUE>(argv, 2));
@ -90,9 +90,10 @@ struct color_binding_init : boost::asio::coroutine {
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
if (argc == 1) {
SANDBOX_AWAIT(check_type, sb()->ref<VALUE>(argv, 0), color_class);
*get_private_data<Color>(self) = *get_private_data<Color>(sb()->ref<VALUE>(argv, 0));
} else {
// TODO: make these optional
SANDBOX_AWAIT(check_arity, argc, 3, -1);
SANDBOX_AWAIT_S(0, rb_num2dbl, sb()->ref<VALUE>(argv, 0));
SANDBOX_AWAIT_S(1, rb_num2dbl, sb()->ref<VALUE>(argv, 1));
SANDBOX_AWAIT_S(2, rb_num2dbl, sb()->ref<VALUE>(argv, 2));
@ -179,7 +180,7 @@ struct tone_binding_init : boost::asio::coroutine {
if (argc == 0) {
set_private_data(self, new Tone);
} else {
// TODO: make these optional
SANDBOX_AWAIT(check_arity, argc, 3, -1);
SANDBOX_AWAIT_S(0, rb_num2dbl, sb()->ref<VALUE>(argv, 0));
SANDBOX_AWAIT_S(1, rb_num2dbl, sb()->ref<VALUE>(argv, 1));
SANDBOX_AWAIT_S(2, rb_num2dbl, sb()->ref<VALUE>(argv, 2));
@ -223,9 +224,10 @@ struct tone_binding_init : boost::asio::coroutine {
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
if (argc == 1) {
SANDBOX_AWAIT(check_type, sb()->ref<VALUE>(argv, 0), tone_class);
*get_private_data<Tone>(self) = *get_private_data<Tone>(sb()->ref<VALUE>(argv, 0));
} else {
// TODO: make these optional
SANDBOX_AWAIT(check_arity, argc, 3, -1);
SANDBOX_AWAIT_S(0, rb_num2dbl, sb()->ref<VALUE>(argv, 0));
SANDBOX_AWAIT_S(1, rb_num2dbl, sb()->ref<VALUE>(argv, 1));
SANDBOX_AWAIT_S(2, rb_num2dbl, sb()->ref<VALUE>(argv, 2));
@ -312,7 +314,7 @@ struct rect_binding_init : boost::asio::coroutine {
if (argc == 0) {
set_private_data(self, new Rect);
} else {
// TODO: make these optional
SANDBOX_AWAIT(check_arity, argc, 4, -1);
SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref<VALUE>(argv, 0));
SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref<VALUE>(argv, 1));
SANDBOX_AWAIT_S(2, rb_num2int, sb()->ref<VALUE>(argv, 2));
@ -352,9 +354,10 @@ struct rect_binding_init : boost::asio::coroutine {
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
if (argc == 1) {
SANDBOX_AWAIT(check_type, sb()->ref<VALUE>(argv, 0), rect_class);
*get_private_data<Rect>(self) = *get_private_data<Rect>(sb()->ref<VALUE>(argv, 0));
} else {
// TODO: make these optional
SANDBOX_AWAIT(check_arity, argc, 4, -1);
SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref<VALUE>(argv, 0));
SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref<VALUE>(argv, 1));
SANDBOX_AWAIT_S(2, rb_num2int, sb()->ref<VALUE>(argv, 2));

View file

@ -23,6 +23,7 @@
#define MKXPZ_SANDBOX_FLASHABLE_BINDING_H
#include "binding-util.h"
#include "etc-binding.h"
#include "etc.h"
namespace mkxp_sandbox {
@ -35,6 +36,9 @@ namespace mkxp_sandbox {
VALUE operator()(VALUE self, VALUE obj, VALUE value) {
BOOST_ASIO_CORO_REENTER (this) {
SANDBOX_AWAIT_S(0, rb_num2int, value);
if (obj != SANDBOX_NIL) {
SANDBOX_AWAIT(check_type, obj, color_class);
}
get_private_data<C>(self)->flash(obj == SANDBOX_NIL ? nullptr : &get_private_data<Color>(obj)->norm, SANDBOX_SLOT(0));
}

View file

@ -200,10 +200,10 @@ static VALUE set_size(VALUE self, VALUE value) {
SANDBOX_DEF_PROP_B(Font, Bold, bold);
SANDBOX_DEF_PROP_B(Font, Italic, italic);
SANDBOX_DEF_PROP_OBJ_VAL(Font, Color, Color, color);
SANDBOX_DEF_PROP_OBJ_VAL(Font, Color, color_class, Color, color);
SANDBOX_DEF_PROP_B(Font, Shadow, shadow);
SANDBOX_DEF_PROP_B(Font, Outline, outline);
SANDBOX_DEF_PROP_OBJ_VAL(Font, Color, OutColor, out_color);
SANDBOX_DEF_PROP_OBJ_VAL(Font, Color, color_class, OutColor, out_color);
static VALUE get_default_name(VALUE self) {
return sb()->bind<struct rb_iv_get>()()(self, "default_name");
@ -235,10 +235,10 @@ static VALUE set_default_name(VALUE self, VALUE value) {
SANDBOX_DEF_CLASS_PROP_I(Font, DefaultSize, default_size);
SANDBOX_DEF_CLASS_PROP_B(Font, DefaultBold, default_bold);
SANDBOX_DEF_CLASS_PROP_B(Font, DefaultItalic, default_italic);
SANDBOX_DEF_CLASS_PROP_OBJ_VAL(Font, Color, DefaultColor, default_color);
SANDBOX_DEF_CLASS_PROP_OBJ_VAL(Font, Color, color_class, DefaultColor, default_color);
SANDBOX_DEF_CLASS_PROP_B(Font, DefaultShadow, default_shadow);
SANDBOX_DEF_CLASS_PROP_B(Font, DefaultOutline, default_outline);
SANDBOX_DEF_CLASS_PROP_OBJ_VAL(Font, Color, DefaultOutColor, default_out_color);
SANDBOX_DEF_CLASS_PROP_OBJ_VAL(Font, Color, color_class, DefaultOutColor, default_out_color);
static VALUE exist(VALUE self, VALUE value) {
struct coro : boost::asio::coroutine {

View file

@ -315,7 +315,8 @@ static VALUE resize_window(int32_t argc, wasm_ptr_t argv, VALUE self) {
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
// TODO: require at least 2 arguments
SANDBOX_AWAIT(check_arity, argc, 2, -1);
SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref<VALUE>(argv, 0));
SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref<VALUE>(argv, 1));
GFX_LOCK;
@ -349,7 +350,8 @@ static VALUE play_movie(int32_t argc, wasm_ptr_t argv, VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
GFX_LOCK;
// TODO: require at least 1 argument
SANDBOX_AWAIT(check_arity, argc, 1, -1);
SANDBOX_AWAIT_S(0, rb_string_value_cstr, &sb()->ref<VALUE>(argv, 0));
if (argc >= 2) {
SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref<VALUE>(argv, 1));

View file

@ -20,6 +20,7 @@
*/
#include "plane-binding.h"
#include "bitmap-binding.h"
#include "disposable-binding.h"
#include "etc-binding.h"
#include "viewportelement-binding.h"
@ -55,9 +56,9 @@ static VALUE initialize(int32_t argc, wasm_ptr_t argv, VALUE self) {
return sb()->bind<struct coro>()()(argc, argv, self);
}
SANDBOX_DEF_GFX_PROP_OBJ_REF(Plane, Bitmap, Bitmap, bitmap);
SANDBOX_DEF_GFX_PROP_OBJ_VAL(Plane, Color, Color, color);
SANDBOX_DEF_GFX_PROP_OBJ_VAL(Plane, Tone, Tone, tone);
SANDBOX_DEF_GFX_PROP_OBJ_REF(Plane, Bitmap, bitmap_class, Bitmap, bitmap);
SANDBOX_DEF_GFX_PROP_OBJ_VAL(Plane, Color, color_class, Color, color);
SANDBOX_DEF_GFX_PROP_OBJ_VAL(Plane, Tone, tone_class, Tone, tone);
SANDBOX_DEF_GFX_PROP_I(Plane, OX, ox);
SANDBOX_DEF_GFX_PROP_I(Plane, OY, oy);
SANDBOX_DEF_GFX_PROP_F(Plane, ZoomX, zoom_x);

View file

@ -20,6 +20,7 @@
*/
#include "sprite-binding.h"
#include "bitmap-binding.h"
#include "disposable-binding.h"
#include "etc-binding.h"
#include "flashable-binding.h"
@ -56,8 +57,8 @@ static VALUE initialize(int32_t argc, wasm_ptr_t argv, VALUE self) {
return sb()->bind<struct coro>()()(argc, argv, self);
}
SANDBOX_DEF_GFX_PROP_OBJ_REF(Sprite, Bitmap, Bitmap, bitmap);
SANDBOX_DEF_GFX_PROP_OBJ_VAL(Sprite, Rect, SrcRect, src_rect);
SANDBOX_DEF_GFX_PROP_OBJ_REF(Sprite, Bitmap, bitmap_class, Bitmap, bitmap);
SANDBOX_DEF_GFX_PROP_OBJ_VAL(Sprite, Rect, rect_class, SrcRect, src_rect);
SANDBOX_DEF_GFX_PROP_I(Sprite, X, x);
SANDBOX_DEF_GFX_PROP_I(Sprite, Y, y);
SANDBOX_DEF_GFX_PROP_I(Sprite, OX, ox);
@ -69,8 +70,8 @@ SANDBOX_DEF_GFX_PROP_B(Sprite, Mirror, mirror);
SANDBOX_DEF_GFX_PROP_I(Sprite, BushDepth, bush_depth);
SANDBOX_DEF_GFX_PROP_I(Sprite, Opacity, opacity);
SANDBOX_DEF_GFX_PROP_I(Sprite, BlendType, blend_type);
SANDBOX_DEF_GFX_PROP_OBJ_VAL(Sprite, Color, Color, color);
SANDBOX_DEF_GFX_PROP_OBJ_VAL(Sprite, Tone, Tone, tone);
SANDBOX_DEF_GFX_PROP_OBJ_VAL(Sprite, Color, color_class, Color, color);
SANDBOX_DEF_GFX_PROP_OBJ_VAL(Sprite, Tone, tone_class, Tone, tone);
static VALUE width(VALUE self) {
struct coro : boost::asio::coroutine {
@ -106,7 +107,7 @@ static VALUE height(VALUE self) {
SANDBOX_DEF_GFX_PROP_I(Sprite, BushOpacity, bush_opacity);
SANDBOX_DEF_GFX_PROP_OBJ_REF(Sprite, Bitmap, Pattern, pattern);
SANDBOX_DEF_GFX_PROP_OBJ_REF(Sprite, Bitmap, bitmap_class, Pattern, pattern);
SANDBOX_DEF_GFX_PROP_I(Sprite, PatternBlendType, pattern_blend_type);
SANDBOX_DEF_GFX_PROP_B(Sprite, PatternTile, pattern_tile);
SANDBOX_DEF_GFX_PROP_I(Sprite, PatternOpacity, pattern_opacity);

View file

@ -36,9 +36,10 @@ static VALUE initialize(int32_t argc, wasm_ptr_t argv, VALUE self) {
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
SANDBOX_AWAIT(check_arity, argc, 1, 3);
SANDBOX_SLOT(1) = SANDBOX_SLOT(2) = 1;
// TODO: throw error if too many or too few arguments
SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref<VALUE>(argv, 0));
SANDBOX_SLOT(0) = std::max(SANDBOX_SLOT(0), (int32_t)0);
if (argc >= 2) {
@ -89,9 +90,10 @@ static VALUE resize(int32_t argc, wasm_ptr_t argv, VALUE self) {
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
SANDBOX_AWAIT(check_arity, argc, 1, 3);
SANDBOX_SLOT(1) = SANDBOX_SLOT(2) = 1;
// TODO: throw error if too many or too few arguments
SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref<VALUE>(argv, 0));
SANDBOX_SLOT(0) = std::max(SANDBOX_SLOT(0), (int32_t)0);
if (argc >= 2) {
@ -131,6 +133,8 @@ static VALUE get(int32_t argc, wasm_ptr_t argv, VALUE self) {
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
SANDBOX_AWAIT(check_arity, argc, 1, 3);
SANDBOX_SLOT(2) = SANDBOX_SLOT(3) = 0;
SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref<VALUE>(argv, 0));
@ -138,7 +142,6 @@ static VALUE get(int32_t argc, wasm_ptr_t argv, VALUE self) {
SANDBOX_AWAIT_S(2, rb_num2int, sb()->ref<VALUE>(argv, 1));
if (argc >= 3) {
SANDBOX_AWAIT_S(3, rb_num2int, sb()->ref<VALUE>(argv, 2));
// TODO: throw error if too many arguments
}
}
@ -162,9 +165,9 @@ static VALUE set(int32_t argc, wasm_ptr_t argv, VALUE self) {
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
SANDBOX_SLOT(1) = SANDBOX_SLOT(2) = 0;
SANDBOX_AWAIT(check_arity, argc, 2, 4);
// TODO: throw error if too few arguments
SANDBOX_SLOT(1) = SANDBOX_SLOT(2) = 0;
SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref<VALUE>(argv, 0));
if (argc >= 3) {

View file

@ -20,8 +20,11 @@
*/
#include "tilemap-binding.h"
#include "bitmap-binding.h"
#include "disposable-binding.h"
#include "etc-binding.h"
#include "table-binding.h"
#include "viewport-binding.h"
#include "tilemap.h"
using namespace mkxp_sandbox;
@ -62,6 +65,7 @@ struct tilemap_autotiles_binding_init : boost::asio::coroutine {
SANDBOX_AWAIT_S(0, rb_num2ulong, i);
SANDBOX_AWAIT(check_type, obj, bitmap_class);
get_private_data<Tilemap::Autotiles>(self)->set(SANDBOX_SLOT(0), get_private_data<Bitmap>(obj));
SANDBOX_AWAIT_S(1, rb_iv_get, self, "array");
SANDBOX_AWAIT(rb_ary_store, SANDBOX_SLOT(1), SANDBOX_SLOT(0), obj);
@ -100,6 +104,10 @@ static VALUE initialize(int32_t argc, wasm_ptr_t argv, VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
GFX_LOCK;
if (argc > 0) {
SANDBOX_AWAIT(check_type, sb()->ref<VALUE>(argv, 0), viewport_class);
}
{
SANDBOX_SLOT(0) = SANDBOX_NIL;
Viewport *viewport = nullptr;
@ -171,21 +179,37 @@ static VALUE update(VALUE self) {
}
static VALUE viewport(VALUE self) {
return sb()->bind<struct rb_iv_get>()()(self, "viewport");
struct coro : boost::asio::coroutine {
typedef decl_slots<VALUE> slots;
VALUE operator()(VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
if (get_private_data<Tilemap>(self)->isDisposed()) {
SANDBOX_AWAIT(raise_disposed_access, self);
}
SANDBOX_AWAIT_S(0, rb_iv_get, self, "viewport");
}
return SANDBOX_SLOT(0);
}
};
return sb()->bind<struct coro>()()(self);
}
SANDBOX_DEF_GFX_PROP_OBJ_REF(Tilemap, Bitmap, Tileset, tileset);
SANDBOX_DEF_GFX_PROP_OBJ_REF(Tilemap, Table, MapData, map_data);
SANDBOX_DEF_GFX_PROP_OBJ_REF(Tilemap, Table, FlashData, flash_data);
SANDBOX_DEF_GFX_PROP_OBJ_REF(Tilemap, Table, Priorities, priorities);
SANDBOX_DEF_GFX_PROP_OBJ_REF(Tilemap, Bitmap, bitmap_class, Tileset, tileset);
SANDBOX_DEF_GFX_PROP_OBJ_REF(Tilemap, Table, table_class, MapData, map_data);
SANDBOX_DEF_GFX_PROP_OBJ_REF(Tilemap, Table, table_class, FlashData, flash_data);
SANDBOX_DEF_GFX_PROP_OBJ_REF(Tilemap, Table, table_class, Priorities, priorities);
SANDBOX_DEF_GFX_PROP_B(Tilemap, Visible, visible);
SANDBOX_DEF_GFX_PROP_I(Tilemap, OX, ox);
SANDBOX_DEF_GFX_PROP_I(Tilemap, OY, oy);
SANDBOX_DEF_GFX_PROP_I(Tilemap, Opacity, opacity);
SANDBOX_DEF_GFX_PROP_I(Tilemap, BlendType, blend_type);
SANDBOX_DEF_GFX_PROP_OBJ_VAL(Tilemap, Color, Color, color);
SANDBOX_DEF_GFX_PROP_OBJ_VAL(Tilemap, Tone, Tone, tone);
SANDBOX_DEF_GFX_PROP_OBJ_VAL(Tilemap, Color, color_class, Color, color);
SANDBOX_DEF_GFX_PROP_OBJ_VAL(Tilemap, Tone, tone_class, Tone, tone);
void tilemap_binding_init::operator()() {
BOOST_ASIO_CORO_REENTER (this) {

View file

@ -20,7 +20,10 @@
*/
#include "tilemapvx-binding.h"
#include "bitmap-binding.h"
#include "disposable-binding.h"
#include "table-binding.h"
#include "viewport-binding.h"
#include "tilemapvx.h"
using namespace mkxp_sandbox;
@ -61,6 +64,7 @@ struct bitmap_array_binding_init : boost::asio::coroutine {
SANDBOX_AWAIT_S(0, rb_num2ulong, i);
SANDBOX_AWAIT(check_type, obj, bitmap_class);
get_private_data<TilemapVX::BitmapArray>(self)->set(SANDBOX_SLOT(0), get_private_data<Bitmap>(obj));
SANDBOX_AWAIT_S(1, rb_iv_get, self, "array");
SANDBOX_AWAIT(rb_ary_store, SANDBOX_SLOT(1), SANDBOX_SLOT(0), obj);
@ -97,6 +101,10 @@ static VALUE initialize(int32_t argc, wasm_ptr_t argv, VALUE self) {
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
if (argc > 0) {
SANDBOX_AWAIT(check_type, sb()->ref<VALUE>(argv, 0), viewport_class);
}
{
SANDBOX_SLOT(0) = SANDBOX_NIL;
Viewport *viewport = nullptr;
@ -159,15 +167,15 @@ static VALUE update(VALUE self) {
return sb()->bind<struct coro>()()(self);
}
SANDBOX_DEF_GFX_PROP_OBJ_REF(TilemapVX, Viewport, Viewport, viewport);
SANDBOX_DEF_GFX_PROP_OBJ_REF(TilemapVX, Table, MapData, map_data);
SANDBOX_DEF_GFX_PROP_OBJ_REF(TilemapVX, Table, FlashData, flash_data);
SANDBOX_DEF_GFX_PROP_OBJ_REF(TilemapVX, Viewport, viewport_class, Viewport, viewport);
SANDBOX_DEF_GFX_PROP_OBJ_REF(TilemapVX, Table, table_class, MapData, map_data);
SANDBOX_DEF_GFX_PROP_OBJ_REF(TilemapVX, Table, table_class, FlashData, flash_data);
SANDBOX_DEF_GFX_PROP_B(TilemapVX, Visible, visible);
SANDBOX_DEF_GFX_PROP_I(TilemapVX, OX, ox);
SANDBOX_DEF_GFX_PROP_I(TilemapVX, OY, oy);
SANDBOX_DEF_GFX_PROP_OBJ_REF(TilemapVX, Table, Flags, flags);
SANDBOX_DEF_GFX_PROP_OBJ_REF(TilemapVX, Table, Flags, passages);
SANDBOX_DEF_GFX_PROP_OBJ_REF(TilemapVX, Table, table_class, Flags, flags);
SANDBOX_DEF_GFX_PROP_OBJ_REF(TilemapVX, Table, table_class, Flags, passages);
void tilemapvx_binding_init::operator()() {
BOOST_ASIO_CORO_REENTER (this) {

View file

@ -47,6 +47,7 @@ static VALUE initialize(int32_t argc, wasm_ptr_t argv, VALUE self) {
viewport = new Viewport;
} else if (argc == 1) {
GFX_LOCK;
SANDBOX_AWAIT(check_type, sb()->ref<VALUE>(argv, 0), rect_class);
viewport = new Viewport(get_private_data<Rect>(sb()->ref<VALUE>(argv, 0)));
} else {
SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref<VALUE>(argv, 0));
@ -76,11 +77,11 @@ static VALUE initialize(int32_t argc, wasm_ptr_t argv, VALUE self) {
return sb()->bind<struct coro>()()(argc, argv, self);
}
SANDBOX_DEF_GFX_PROP_OBJ_VAL(Viewport, Rect, Rect, rect);
SANDBOX_DEF_GFX_PROP_OBJ_VAL(Viewport, Rect, rect_class, Rect, rect);
SANDBOX_DEF_GFX_PROP_I(Viewport, OX, ox);
SANDBOX_DEF_GFX_PROP_I(Viewport, OY, oy);
SANDBOX_DEF_GFX_PROP_OBJ_VAL(Viewport, Color, Color, color);
SANDBOX_DEF_GFX_PROP_OBJ_VAL(Viewport, Tone, Tone, tone);
SANDBOX_DEF_GFX_PROP_OBJ_VAL(Viewport, Color, color_class, Color, color);
SANDBOX_DEF_GFX_PROP_OBJ_VAL(Viewport, Tone, tone_class, Tone, tone);
void viewport_binding_init::operator()() {
BOOST_ASIO_CORO_REENTER (this) {

View file

@ -24,6 +24,7 @@
#include "binding-util.h"
#include "sceneelement-binding.h"
#include "viewport-binding.h"
#include "viewport.h"
namespace mkxp_sandbox {
@ -34,6 +35,10 @@ namespace mkxp_sandbox {
BOOST_ASIO_CORO_REENTER (this) {
SANDBOX_SLOT(0) = SANDBOX_NIL;
if (argc > 0) {
SANDBOX_AWAIT(check_type, sb()->ref<VALUE>(argv, 0), viewport_class);
}
{
Viewport *viewport = nullptr;
if (argc > 0) {
@ -59,13 +64,34 @@ namespace mkxp_sandbox {
template <class C> struct viewportelement_binding_init : boost::asio::coroutine {
private:
SANDBOX_DEF_PROP_OBJ_REF(C, Viewport, Viewport, viewport);
SANDBOX_DEF_PROP_OBJ_REF(C, Viewport, viewport_class, Viewport, viewport);
static VALUE viewport(VALUE self) {
struct coro : boost::asio::coroutine {
typedef decl_slots<VALUE> slots;
VALUE operator()(VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
if (get_private_data<Tilemap>(self)->isDisposed()) {
SANDBOX_AWAIT(raise_disposed_access, self);
}
SANDBOX_AWAIT_S(0, rb_iv_get, self, "viewport");
}
return SANDBOX_SLOT(0);
}
};
return sb()->bind<struct coro>()()(self);
}
public:
void operator()(VALUE klass) {
BOOST_ASIO_CORO_REENTER (this) {
SANDBOX_AWAIT(sceneelement_binding_init<C>, klass);
SANDBOX_INIT_PROP_BIND(klass, viewport);
SANDBOX_AWAIT(rb_define_method, klass, "viewport", (VALUE (*)(ANYARGS))viewport, 0); \
SANDBOX_AWAIT(rb_define_method, klass, "viewport=", (VALUE (*)(ANYARGS))set_viewport, 1); \
}
}
};

View file

@ -20,6 +20,7 @@
*/
#include "window-binding.h"
#include "bitmap-binding.h"
#include "disposable-binding.h"
#include "etc-binding.h"
#include "viewportelement-binding.h"
@ -67,10 +68,10 @@ static VALUE update(VALUE self) {
return sb()->bind<struct coro>()()(self);
}
SANDBOX_DEF_GFX_PROP_OBJ_REF(Window, Bitmap, Windowskin, windowskin);
SANDBOX_DEF_GFX_PROP_OBJ_REF(Window, Bitmap, Contents, contents);
SANDBOX_DEF_GFX_PROP_OBJ_REF(Window, Bitmap, bitmap_class, Windowskin, windowskin);
SANDBOX_DEF_GFX_PROP_OBJ_REF(Window, Bitmap, bitmap_class, Contents, contents);
SANDBOX_DEF_GFX_PROP_B(Window, Stretch, stretch);
SANDBOX_DEF_GFX_PROP_OBJ_VAL(Window, Rect, CursorRect, cursor_rect);
SANDBOX_DEF_GFX_PROP_OBJ_VAL(Window, Rect, rect_class, CursorRect, cursor_rect);
SANDBOX_DEF_GFX_PROP_B(Window, Active, active);
SANDBOX_DEF_GFX_PROP_B(Window, Pause, pause);
SANDBOX_DEF_GFX_PROP_I(Window, X, x);

View file

@ -95,9 +95,9 @@ static VALUE update(VALUE self) {
return sb()->bind<struct coro>()()(self);
}
SANDBOX_DEF_GFX_PROP_OBJ_REF(WindowVX, Bitmap, Windowskin, windowskin);
SANDBOX_DEF_GFX_PROP_OBJ_REF(WindowVX, Bitmap, Contents, contents);
SANDBOX_DEF_GFX_PROP_OBJ_VAL(WindowVX, Rect, CursorRect, cursor_rect);
SANDBOX_DEF_GFX_PROP_OBJ_REF(WindowVX, Bitmap, bitmap_class, Windowskin, windowskin);
SANDBOX_DEF_GFX_PROP_OBJ_REF(WindowVX, Bitmap, bitmap_class, Contents, contents);
SANDBOX_DEF_GFX_PROP_OBJ_VAL(WindowVX, Rect, rect_class, CursorRect, cursor_rect);
SANDBOX_DEF_GFX_PROP_B(WindowVX, Active, active);
SANDBOX_DEF_GFX_PROP_B(WindowVX, Pause, pause);
SANDBOX_DEF_GFX_PROP_I(WindowVX, X, x);
@ -166,7 +166,7 @@ static VALUE is_closed(VALUE self) {
SANDBOX_DEF_GFX_PROP_B(WindowVX, ArrowsVisible, arrows_visible);
SANDBOX_DEF_GFX_PROP_I(WindowVX, Padding, padding);
SANDBOX_DEF_GFX_PROP_I(WindowVX, PaddingBottom, padding_bottom);
SANDBOX_DEF_GFX_PROP_OBJ_VAL(WindowVX, Tone, Tone, tone);
SANDBOX_DEF_GFX_PROP_OBJ_VAL(WindowVX, Tone, tone_class, Tone, tone);
void windowvx_binding_init::operator()() {
BOOST_ASIO_CORO_REENTER (this) {