diff options
| author | Tom Black <[email protected]> | 2016-11-27 22:41:51 -0500 |
|---|---|---|
| committer | Tom Black <[email protected]> | 2016-11-27 22:41:51 -0500 |
| commit | 31c23832be4de103bea840dffd86942fc7697b66 (patch) | |
| tree | b09906034937466a0f546ce675b36909cae3c942 /ext | |
| parent | 010bdcd5d44127b615a97bf99735dfc3e3f95d63 (diff) | |
| download | ruby2d-31c23832be4de103bea840dffd86942fc7697b66.tar.gz ruby2d-31c23832be4de103bea840dffd86942fc7697b66.zip | |
Initial MRuby support
Diffstat (limited to 'ext')
| -rw-r--r-- | ext/ruby2d/ruby2d.c | 535 |
1 files changed, 344 insertions, 191 deletions
diff --git a/ext/ruby2d/ruby2d.c b/ext/ruby2d/ruby2d.c index 183709d..2ae03c4 100644 --- a/ext/ruby2d/ruby2d.c +++ b/ext/ruby2d/ruby2d.c @@ -1,6 +1,78 @@ -#include <ruby.h> +// ruby2d.c – Native C extension for Ruby and MRuby + +// Simple 2D includes #include <simple2d.h> +// Ruby includes +#if MRUBY + #include <mruby.h> + #include <mruby/array.h> + #include <mruby/string.h> + #include <mruby/variable.h> + #include <mruby/numeric.h> + #include <mruby/data.h> + #include <mruby/irep.h> +#else + #include <ruby.h> +#endif + +// Define Ruby type conversions in MRuby +#if MRUBY + // C to MRuby types + #define INT2FIX(val) (mrb_fixnum_value(val)) + #define INT2NUM(val) (mrb_fixnum_value((mrb_int)(val))) + #define UINT2NUM(val) (INT2NUM((unsigned mrb_int)(val))) + #define LL2NUM(val) (INT2NUM(val)) + #define ULL2NUM(val) (INT2NUM((unsigned __int64)(val))) + #define DBL2NUM(val) (mrb_float_value(mrb, (mrb_float)(val))) + // MRuby to C types + #define TO_PDT(val) ((mrb_type(val) == MRB_TT_FLOAT) ? mrb_float(val) : mrb_int(mrb, (val))) + #define FIX2INT(val) (mrb_fixnum(val)) + #define NUM2INT(val) ((mrb_int)TO_PDT(val)) + #define NUM2UINT(val) ((unsigned mrb_int)TO_PDT(val)) + #define NUM2LONG(val) (mrb_int(mrb, (val))) + #define NUM2LL(val) ((__int64)(TO_PDT(val))) + #define NUM2ULL(val) ((unsigned __int64)(TO_PDT(val))) + #define NUM2DBL(val) (mrb_to_flo(mrb, (val))) + #define NUM2CHR(val) ((mrb_string_p(val) && (RSTRING_LEN(val)>=1)) ? RSTRING_PTR(val)[0] : (char)(NUM2INT(val) & 0xff)) + // Memory management + #define ALLOC(type) ((type *)mrb_malloc(mrb, sizeof(type))) + #define ALLOC_N(type, n) ((type *)mrb_malloc(mrb, sizeof(type) * (n))) + #define ALLOCA_N(type, n) ((type *)alloca(sizeof(type) * (n))) + #define MEMCMP(p1, p2, type, n) (memcmp((p1), (p2), sizeof(type)*(n))) +#endif + +// Define common types and API calls, mapping to both Ruby and MRuby APIs +#if MRUBY + // MRuby + #define RVAL mrb_value + #define RNIL (mrb_nil_value()) + #define RTRUE (mrb_true_value()) + #define RFALSE (mrb_false_value()) + #define r_iv_get(self, var) mrb_iv_get(mrb, self, mrb_intern_lit(mrb, var)) + #define r_iv_set(self, var, val) mrb_iv_set(mrb, self, mrb_intern_lit(mrb, var), val) + #define r_funcall(self, method, num_args, ...) mrb_funcall(mrb, self, method, num_args, ##__VA_ARGS__) + #define r_str_new(str) mrb_str_new(mrb, str, strlen(str)) + #define r_test(val) (mrb_test(val) == true) + #define r_ary_entry(ary, pos) mrb_ary_entry(ary, pos) + #define r_data_wrap_struct(name, data) mrb_obj_value(Data_Wrap_Struct(mrb, mrb->object_class, &name##_data_type, data)) + #define r_data_get_struct(self, var, mrb_type, rb_type, data) Data_Get_Struct(mrb, r_iv_get(self, var), mrb_type, data) +#else + // Ruby + #define RVAL VALUE + #define RNIL Qnil + #define RTRUE Qtrue + #define RFALSE Qfalse + #define r_iv_get(self, var) rb_iv_get(self, var) + #define r_iv_set(self, var, val) rb_iv_set(self, var, val) + #define r_funcall(self, method, num_args, ...) rb_funcall(self, rb_intern(method), num_args, ##__VA_ARGS__) + #define r_str_new(str) rb_str_new2(str) + #define r_test(val) (val != Qfalse && val != Qnil) + #define r_ary_entry(ary, pos) rb_ary_entry(ary, pos) + #define r_data_wrap_struct(name, data) Data_Wrap_Struct(rb_cObject, NULL, (free_##name), data) + #define r_data_get_struct(self, var, mrb_type, rb_type, data) Data_Get_Struct(r_iv_get(self, var), rb_type, data) +#endif + // @type_id values for rendering #define R2D_TRIANGLE 1 #define R2D_QUAD 2 @@ -8,30 +80,47 @@ #define R2D_SPRITE 4 #define R2D_TEXT 5 +// Create the MRuby context +#if MRUBY + static mrb_state *mrb; +#endif + // Ruby 2D window -static VALUE self; +static RVAL self; // Simple 2D window static S2D_Window *window; // Ruby data types -static VALUE ruby2d_module; -static VALUE ruby2d_window_klass; -static VALUE c_data_klass; - -// Structures for Ruby 2D classes -struct image_data { - S2D_Image *img; -}; -struct sprite_data { - S2D_Sprite *spr; -}; -struct text_data { - S2D_Text *txt; -}; -struct sound_data { - S2D_Sound *snd; -}; +static RVAL ruby2d_module; +static RVAL ruby2d_window_class; + +#if MRUBY + #define ruby2d_show(self) ruby2d_show(mrb_state* mrb, self) +#else + #define ruby2d_show(self) ruby2d_show(self) +#endif + + +// Method signatures and structures for Ruby 2D classes +#if MRUBY + static void free_image(mrb_state *mrb, void *p_); + static const struct mrb_data_type image_data_type = { + "image", free_image + }; + static void free_sprite(mrb_state *mrb, void *p_); + static const struct mrb_data_type sprite_data_type = { + "sprite", free_sprite + }; + static void free_text(mrb_state *mrb, void *p_); + static const struct mrb_data_type text_data_type = { + "text", free_text + }; +#else + static void free_image(S2D_Image *img); + static void free_sprite(S2D_Sprite *spr); + static void free_text(S2D_Text *txt); +#endif /* @@ -43,94 +132,119 @@ static void free_window() { /* - * Free image structure attached to Ruby 2D `Image` class - */ -static void free_image(struct image_data *data) { - S2D_FreeImage(data->img); - xfree(data); +* Initialize image structure data +*/ +static RVAL init_image(char *path) { + sprintf(S2D_msg, "init image: %s", path); + S2D_Log(S2D_msg, S2D_INFO); + S2D_Image *img = S2D_CreateImage(path); + return r_data_wrap_struct(image, img); } /* - * Initialize image structure data - */ -static VALUE init_image(char *path) { - struct image_data *data = ALLOC(struct image_data); - data->img = S2D_CreateImage(path); - return Data_Wrap_Struct(c_data_klass, NULL, free_image, data); -} - - -/* - * Free sprite structure attached to Ruby 2D `Sprite` class + * Free image structure attached to Ruby 2D `Image` class */ -static void free_sprite(struct sprite_data *data) { - S2D_FreeSprite(data->spr); - xfree(data); +#if MRUBY +static void free_image(mrb_state *mrb, void *p_) { + S2D_Image *img = (S2D_Image *)p_; +#else +static void free_image(S2D_Image *img) { +#endif + sprintf(S2D_msg, "free image: %i, %i", img->x, img->y); + S2D_Log(S2D_msg, S2D_INFO); + S2D_FreeImage(img); } /* * Initialize sprite structure data */ -static VALUE init_sprite(char *path) { - struct sprite_data *data = ALLOC(struct sprite_data); - data->spr = S2D_CreateSprite(path); - return Data_Wrap_Struct(c_data_klass, NULL, free_sprite, data); +static RVAL init_sprite(char *path) { + sprintf(S2D_msg, "init sprite: %s", path); + S2D_Log(S2D_msg, S2D_INFO); + S2D_Sprite *spr = S2D_CreateSprite(path); + return r_data_wrap_struct(sprite, spr); } /* - * Free text structure attached to Ruby 2D `Text` class + * Free sprite structure attached to Ruby 2D `Sprite` class */ -static void free_text(struct text_data *data) { - S2D_FreeText(data->txt); - xfree(data); +#if MRUBY +static void free_sprite(mrb_state *mrb, void *p_) { + S2D_Sprite *spr = (S2D_Sprite *)p_; +#else +static void free_sprite(S2D_Sprite *spr) { +#endif + sprintf(S2D_msg, "free sprite: %i, %i", spr->x, spr->y); + S2D_Log(S2D_msg, S2D_INFO); + S2D_FreeSprite(spr); } /* * Initialize text structure data */ -static VALUE init_text(char *font, char *msg, int size) { - struct text_data *data = ALLOC(struct text_data); - data->txt = S2D_CreateText(font, msg, size); - return Data_Wrap_Struct(c_data_klass, NULL, free_text, data); +static RVAL init_text(char *font, char *msg, int size) { + sprintf(S2D_msg, "init text: %s", msg); + S2D_Log(S2D_msg, S2D_INFO); + S2D_Text *txt = S2D_CreateText(font, msg, size); + return r_data_wrap_struct(text, txt); } /* - * Simple 2D `on_key` input callback function + * Free text structure attached to Ruby 2D `Text` class */ -static void on_key(const char *key) { - rb_funcall(self, rb_intern("key_callback"), 1, rb_str_new2(key)); +#if MRUBY +static void free_text(mrb_state *mrb, void *p_) { + S2D_Text *txt = (S2D_Text *)p_; +#else +static void free_text(S2D_Text *txt) { +#endif + sprintf(S2D_msg, "free text: %s", txt->msg); + S2D_Log(S2D_msg, S2D_INFO); + S2D_FreeText(txt); } /* - * Simple 2D `on_key_up` input callback function + * Simple 2D `on_key` input callback function */ -static void on_key_up(const char *key) { - rb_funcall(self, rb_intern("key_up_callback"), 1, rb_str_new2(key)); +static void on_key(S2D_Event e, const char *key) { + switch (e) { + case S2D_KEYDOWN: + r_funcall(self, "key_down_callback", 1, r_str_new(key)); + break; + + case S2D_KEY: + r_funcall(self, "key_callback", 1, r_str_new(key)); + break; + + case S2D_KEYUP: + r_funcall(self, "key_up_callback", 1, r_str_new(key)); + break; + } } /* - * Simple 2D `on_key_down` input callback function + * Simple 2D `on_mouse` input callback function */ -static void on_key_down(const char *key) { - rb_funcall(self, rb_intern("key_down_callback"), 1, rb_str_new2(key)); +void on_mouse(int x, int y) { + printf("Mouse down at: %i, %i\n", x, y); } /* * Simple 2D `on_controller` input callback function */ -static void on_controller(int which, bool is_axis, int axis, int val, bool is_btn, int btn) { - rb_funcall(self, rb_intern("controller_callback"), 6, +static void on_controller(int which, bool is_axis, int axis, int val, bool is_btn, int btn, bool pressed) { + r_funcall(self, "controller_callback", 6, INT2NUM(which), - is_axis ? Qtrue : Qfalse, INT2NUM(axis), INT2NUM(val), - is_btn ? Qtrue : Qfalse, INT2NUM(btn) + is_axis ? RTRUE : RFALSE, INT2NUM(axis), INT2NUM(val), + is_btn ? RTRUE : RFALSE, INT2NUM(btn) ); } @@ -141,14 +255,14 @@ static void on_controller(int which, bool is_axis, int axis, int val, bool is_bt static void update() { // Set the cursor - rb_iv_set(self, "@mouse_x", INT2NUM(window->mouse.x)); - rb_iv_set(self, "@mouse_y", INT2NUM(window->mouse.y)); + r_iv_set(self, "@mouse_x", INT2NUM(window->mouse.x)); + r_iv_set(self, "@mouse_y", INT2NUM(window->mouse.y)); // Store frame rate - rb_iv_set(self, "@fps", DBL2NUM(window->fps)); + r_iv_set(self, "@fps", DBL2NUM(window->fps)); // Call update proc, `window.update` - rb_funcall(self, rb_intern("update_callback"), 0); + r_funcall(self, "update_callback", 0); } @@ -158,149 +272,153 @@ static void update() { static void render() { // Set background color - VALUE bc = rb_iv_get(self, "@background"); - window->background.r = NUM2DBL(rb_iv_get(bc, "@r")); - window->background.g = NUM2DBL(rb_iv_get(bc, "@g")); - window->background.b = NUM2DBL(rb_iv_get(bc, "@b")); - window->background.a = NUM2DBL(rb_iv_get(bc, "@a")); + RVAL bc = r_iv_get(self, "@background"); + window->background.r = NUM2DBL(r_iv_get(bc, "@r")); + window->background.g = NUM2DBL(r_iv_get(bc, "@g")); + window->background.b = NUM2DBL(r_iv_get(bc, "@b")); + window->background.a = NUM2DBL(r_iv_get(bc, "@a")); // Read window objects - VALUE objects = rb_iv_get(self, "@objects"); - int num_objects = NUM2INT(rb_funcall(objects, rb_intern("count"), 0)); + RVAL objects = r_iv_get(self, "@objects"); + int num_objects = NUM2INT(r_funcall(objects, "length", 0)); // Switch on each object type for (int i = 0; i < num_objects; ++i) { - VALUE el = rb_ary_entry(objects, i); - int type_id = NUM2INT(rb_iv_get(el, "@type_id")); + RVAL el = r_ary_entry(objects, i); + int type_id = NUM2INT(r_iv_get(el, "@type_id")); // Switch on the object's type_id switch(type_id) { case R2D_TRIANGLE: { - VALUE c1 = rb_iv_get(el, "@c1"); - VALUE c2 = rb_iv_get(el, "@c2"); - VALUE c3 = rb_iv_get(el, "@c3"); + RVAL c1 = r_iv_get(el, "@c1"); + RVAL c2 = r_iv_get(el, "@c2"); + RVAL c3 = r_iv_get(el, "@c3"); S2D_DrawTriangle( - NUM2DBL(rb_iv_get(el, "@x1")), - NUM2DBL(rb_iv_get(el, "@y1")), - NUM2DBL(rb_iv_get(c1, "@r")), - NUM2DBL(rb_iv_get(c1, "@g")), - NUM2DBL(rb_iv_get(c1, "@b")), - NUM2DBL(rb_iv_get(c1, "@a")), + NUM2DBL(r_iv_get(el, "@x1")), + NUM2DBL(r_iv_get(el, "@y1")), + NUM2DBL(r_iv_get(c1, "@r")), + NUM2DBL(r_iv_get(c1, "@g")), + NUM2DBL(r_iv_get(c1, "@b")), + NUM2DBL(r_iv_get(c1, "@a")), - NUM2DBL(rb_iv_get(el, "@x2")), - NUM2DBL(rb_iv_get(el, "@y2")), - NUM2DBL(rb_iv_get(c2, "@r")), - NUM2DBL(rb_iv_get(c2, "@g")), - NUM2DBL(rb_iv_get(c2, "@b")), - NUM2DBL(rb_iv_get(c2, "@a")), + NUM2DBL(r_iv_get(el, "@x2")), + NUM2DBL(r_iv_get(el, "@y2")), + NUM2DBL(r_iv_get(c2, "@r")), + NUM2DBL(r_iv_get(c2, "@g")), + NUM2DBL(r_iv_get(c2, "@b")), + NUM2DBL(r_iv_get(c2, "@a")), - NUM2DBL(rb_iv_get(el, "@x3")), - NUM2DBL(rb_iv_get(el, "@y3")), - NUM2DBL(rb_iv_get(c3, "@r")), - NUM2DBL(rb_iv_get(c3, "@g")), - NUM2DBL(rb_iv_get(c3, "@b")), - NUM2DBL(rb_iv_get(c3, "@a")) + NUM2DBL(r_iv_get(el, "@x3")), + NUM2DBL(r_iv_get(el, "@y3")), + NUM2DBL(r_iv_get(c3, "@r")), + NUM2DBL(r_iv_get(c3, "@g")), + NUM2DBL(r_iv_get(c3, "@b")), + NUM2DBL(r_iv_get(c3, "@a")) ); } break; case R2D_QUAD: { - VALUE c1 = rb_iv_get(el, "@c1"); - VALUE c2 = rb_iv_get(el, "@c2"); - VALUE c3 = rb_iv_get(el, "@c3"); - VALUE c4 = rb_iv_get(el, "@c4"); + RVAL c1 = r_iv_get(el, "@c1"); + RVAL c2 = r_iv_get(el, "@c2"); + RVAL c3 = r_iv_get(el, "@c3"); + RVAL c4 = r_iv_get(el, "@c4"); S2D_DrawQuad( - NUM2DBL(rb_iv_get(el, "@x1")), - NUM2DBL(rb_iv_get(el, "@y1")), - NUM2DBL(rb_iv_get(c1, "@r")), - NUM2DBL(rb_iv_get(c1, "@g")), - NUM2DBL(rb_iv_get(c1, "@b")), - NUM2DBL(rb_iv_get(c1, "@a")), - - NUM2DBL(rb_iv_get(el, "@x2")), - NUM2DBL(rb_iv_get(el, "@y2")), - NUM2DBL(rb_iv_get(c2, "@r")), - NUM2DBL(rb_iv_get(c2, "@g")), - NUM2DBL(rb_iv_get(c2, "@b")), - NUM2DBL(rb_iv_get(c2, "@a")), - - NUM2DBL(rb_iv_get(el, "@x3")), - NUM2DBL(rb_iv_get(el, "@y3")), - NUM2DBL(rb_iv_get(c3, "@r")), - NUM2DBL(rb_iv_get(c3, "@g")), - NUM2DBL(rb_iv_get(c3, "@b")), - NUM2DBL(rb_iv_get(c3, "@a")), - - NUM2DBL(rb_iv_get(el, "@x4")), - NUM2DBL(rb_iv_get(el, "@y4")), - NUM2DBL(rb_iv_get(c4, "@r")), - NUM2DBL(rb_iv_get(c4, "@g")), - NUM2DBL(rb_iv_get(c4, "@b")), - NUM2DBL(rb_iv_get(c4, "@a")) + NUM2DBL(r_iv_get(el, "@x1")), + NUM2DBL(r_iv_get(el, "@y1")), + NUM2DBL(r_iv_get(c1, "@r")), + NUM2DBL(r_iv_get(c1, "@g")), + NUM2DBL(r_iv_get(c1, "@b")), + NUM2DBL(r_iv_get(c1, "@a")), + + NUM2DBL(r_iv_get(el, "@x2")), + NUM2DBL(r_iv_get(el, "@y2")), + NUM2DBL(r_iv_get(c2, "@r")), + NUM2DBL(r_iv_get(c2, "@g")), + NUM2DBL(r_iv_get(c2, "@b")), + NUM2DBL(r_iv_get(c2, "@a")), + + NUM2DBL(r_iv_get(el, "@x3")), + NUM2DBL(r_iv_get(el, "@y3")), + NUM2DBL(r_iv_get(c3, "@r")), + NUM2DBL(r_iv_get(c3, "@g")), + NUM2DBL(r_iv_get(c3, "@b")), + NUM2DBL(r_iv_get(c3, "@a")), + + NUM2DBL(r_iv_get(el, "@x4")), + NUM2DBL(r_iv_get(el, "@y4")), + NUM2DBL(r_iv_get(c4, "@r")), + NUM2DBL(r_iv_get(c4, "@g")), + NUM2DBL(r_iv_get(c4, "@b")), + NUM2DBL(r_iv_get(c4, "@a")) ); } break; case R2D_IMAGE: { - if (rb_iv_get(el, "@data") == Qnil) { - VALUE data = init_image(RSTRING_PTR(rb_iv_get(el, "@path"))); - rb_iv_set(el, "@data", data); + if (!r_test(r_iv_get(el, "@data"))) { + r_iv_set(el, "@data", init_image(RSTRING_PTR(r_iv_get(el, "@path")))); } - struct image_data *data; - Data_Get_Struct(rb_iv_get(el, "@data"), struct image_data, data); + S2D_Image *img; + r_data_get_struct(el, "@data", &image_data_type, S2D_Image, img); - data->img->x = NUM2DBL(rb_iv_get(el, "@x")); - data->img->y = NUM2DBL(rb_iv_get(el, "@y")); - S2D_DrawImage(data->img); + img->x = NUM2DBL(r_iv_get(el, "@x")); + img->y = NUM2DBL(r_iv_get(el, "@y")); + + RVAL w = r_iv_get(el, "@width"); + RVAL h = r_iv_get(el, "@height"); + if (r_test(w)) img->width = NUM2INT(w); + if (r_test(h)) img->height = NUM2INT(h); + + S2D_DrawImage(img); } break; case R2D_SPRITE: { - if (rb_iv_get(el, "@data") == Qnil) { - VALUE data = init_sprite(RSTRING_PTR(rb_iv_get(el, "@path"))); - rb_iv_set(el, "@data", data); + if (!r_test(r_iv_get(el, "@data"))) { + r_iv_set(el, "@data", init_sprite(RSTRING_PTR(r_iv_get(el, "@path")))); } - struct sprite_data *data; - Data_Get_Struct(rb_iv_get(el, "@data"), struct sprite_data, data); + S2D_Sprite *spr; + r_data_get_struct(el, "@data", &sprite_data_type, S2D_Sprite, spr); - data->spr->x = NUM2DBL(rb_iv_get(el, "@x")); - data->spr->y = NUM2DBL(rb_iv_get(el, "@y")); + spr->x = NUM2DBL(r_iv_get(el, "@x")); + spr->y = NUM2DBL(r_iv_get(el, "@y")); S2D_ClipSprite( - data->spr, - NUM2INT(rb_iv_get(el, "@clip_x")), - NUM2INT(rb_iv_get(el, "@clip_y")), - NUM2INT(rb_iv_get(el, "@clip_w")), - NUM2INT(rb_iv_get(el, "@clip_h")) + spr, + NUM2INT(r_iv_get(el, "@clip_x")), + NUM2INT(r_iv_get(el, "@clip_y")), + NUM2INT(r_iv_get(el, "@clip_w")), + NUM2INT(r_iv_get(el, "@clip_h")) ); - S2D_DrawSprite(data->spr); + S2D_DrawSprite(spr); } break; case R2D_TEXT: { - if (rb_iv_get(el, "@data") == Qnil) { - VALUE data = init_text( - RSTRING_PTR(rb_iv_get(el, "@font")), - RSTRING_PTR(rb_iv_get(el, "@text")), - NUM2DBL(rb_iv_get(el, "@size")) - ); - rb_iv_set(el, "@data", data); + if (!r_test(r_iv_get(el, "@data"))) { + r_iv_set(el, "@data", init_text( + RSTRING_PTR(r_iv_get(el, "@font")), + RSTRING_PTR(r_iv_get(el, "@text")), + NUM2DBL(r_iv_get(el, "@size")) + )); } - struct text_data *data; - Data_Get_Struct(rb_iv_get(el, "@data"), struct text_data, data); + S2D_Text *txt; + r_data_get_struct(el, "@data", &text_data_type, S2D_Text, txt); + + txt->x = NUM2DBL(r_iv_get(el, "@x")); + txt->y = NUM2DBL(r_iv_get(el, "@y")); - data->txt->x = NUM2DBL(rb_iv_get(el, "@x")); - data->txt->y = NUM2DBL(rb_iv_get(el, "@y")); - S2D_SetText(data->txt, RSTRING_PTR(rb_iv_get(el, "@text"))); - S2D_DrawText(data->txt); + S2D_SetText(txt, RSTRING_PTR(r_iv_get(el, "@text"))); + S2D_DrawText(txt); } break; } @@ -311,45 +429,49 @@ static void render() { /* * Ruby2D::Window#show */ -static VALUE ruby2d_show(VALUE s) { +static RVAL ruby2d_show(RVAL s) { self = s; + if (r_test(r_iv_get(self, "@diagnostics"))) { + S2D_Diagnostics(true); + } + // Get window attributes - char *title = RSTRING_PTR(rb_iv_get(self, "@title")); - int width = NUM2INT(rb_iv_get(self, "@width")); - int height = NUM2INT(rb_iv_get(self, "@height")); + char *title = RSTRING_PTR(r_iv_get(self, "@title")); + int width = NUM2INT(r_iv_get(self, "@width")); + int height = NUM2INT(r_iv_get(self, "@height")); int flags = 0; // Get window flags - if (rb_iv_get(self, "@resizable") == Qtrue) { + if (r_test(r_iv_get(self, "@resizable"))) { flags = flags | S2D_RESIZABLE; } - if (rb_iv_get(self, "@borderless") == Qtrue) { + if (r_test(r_iv_get(self, "@borderless"))) { flags = flags | S2D_BORDERLESS; } - if (rb_iv_get(self, "@fullscreen") == Qtrue) { + if (r_test(r_iv_get(self, "@fullscreen"))) { flags = flags | S2D_FULLSCREEN; } - if (rb_iv_get(self, "@highdpi") == Qtrue) { + if (r_test(r_iv_get(self, "@highdpi"))) { flags = flags | S2D_HIGHDPI; } // Check viewport size and set int viewport_width; - VALUE vp_w = rb_iv_get(self, "@viewport_width"); - if (vp_w == Qnil) { - viewport_width = width; - } else { + RVAL vp_w = r_iv_get(self, "@viewport_width"); + if (r_test(vp_w)) { viewport_width = NUM2INT(vp_w); + } else { + viewport_width = width; } int viewport_height; - VALUE vp_h = rb_iv_get(self, "@viewport_height"); - if (vp_h == Qnil) { - viewport_height = height; - } else { + RVAL vp_h = r_iv_get(self, "@viewport_height"); + if (r_test(vp_h)) { viewport_height = NUM2INT(vp_h); + } else { + viewport_height = height; } window = S2D_CreateWindow( @@ -359,43 +481,74 @@ static VALUE ruby2d_show(VALUE s) { window->viewport.width = viewport_width; window->viewport.height = viewport_height; window->on_key = on_key; - window->on_key_up = on_key_up; - window->on_key_down = on_key_down; + window->on_mouse = on_mouse; window->on_controller = on_controller; S2D_Show(window); atexit(free_window); - return Qnil; + return RNIL; } /* * Ruby2D::Window#close */ -static VALUE ruby2d_close() { +static RVAL ruby2d_close() { S2D_Close(window); - return Qnil; + return RNIL; } /* - * Ruby C extension init - */ +* MRuby entry point +*/ +#if MRUBY +int main(void) { + + // Open the MRuby environment + mrb = mrb_open(); + if (!mrb) { /* handle error */ } + + // Load the Ruby 2D library + mrb_load_irep(mrb, ruby2d_lib); + + // Ruby2D + struct RClass *ruby2d_module = mrb_module_get(mrb, "Ruby2D"); + + // Ruby2D::Window + struct RClass *ruby2d_window_class = mrb_class_get_under(mrb, ruby2d_module, "Window"); + + // Ruby2D::Window#show + mrb_define_method(mrb, ruby2d_window_class, "show", ruby2d_show, MRB_ARGS_NONE()); + + // Ruby2D::Window#close + mrb_define_method(mrb, ruby2d_window_class, "close", ruby2d_close, MRB_ARGS_NONE()); + + // Load the Ruby 2D app + mrb_load_irep(mrb, ruby2d_app); + + // Close the MRuby environment + mrb_close(mrb); +} + + +/* +* Ruby C extension init +*/ +#else void Init_ruby2d() { // Ruby2D ruby2d_module = rb_define_module("Ruby2D"); // Ruby2D::Window - ruby2d_window_klass = rb_define_class_under(ruby2d_module, "Window", rb_cObject); + ruby2d_window_class = rb_define_class_under(ruby2d_module, "Window", rb_cObject); // Ruby2D::Window#show - rb_define_method(ruby2d_window_klass, "show", ruby2d_show, 0); + rb_define_method(ruby2d_window_class, "show", ruby2d_show, 0); // Ruby2D::Window#close - rb_define_method(ruby2d_window_klass, "close", ruby2d_close, 0); - - // Ruby2D::CData - c_data_klass = rb_define_class_under(ruby2d_module, "CData", rb_cObject); + rb_define_method(ruby2d_window_class, "close", ruby2d_close, 0); } +#endif |
