From 6460f786efda69beebf0ca63d088db9420f8ae2c Mon Sep 17 00:00:00 2001 From: Tom Black Date: Fri, 17 Feb 2017 01:17:38 -0500 Subject: Update native extension Improvements for both MRuby and CRuby, support new features of Ruby 2D classes, performance enhancements. --- ext/ruby2d/ruby2d.c | 478 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 366 insertions(+), 112 deletions(-) (limited to 'ext') diff --git a/ext/ruby2d/ruby2d.c b/ext/ruby2d/ruby2d.c index 2ae03c4..9b032d5 100644 --- a/ext/ruby2d/ruby2d.c +++ b/ext/ruby2d/ruby2d.c @@ -45,10 +45,11 @@ // 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_VAL mrb_value + #define R_NIL (mrb_nil_value()) + #define R_TRUE (mrb_true_value()) + #define R_FALSE (mrb_false_value()) + #define R_CLASS struct RClass * #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__) @@ -57,12 +58,18 @@ #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) + #define r_define_module(name) mrb_module_get(mrb, name) + #define r_define_class(module, name) mrb_class_get_under(mrb, module, name); + #define r_define_method(class, name, function, args) mrb_define_method(mrb, class, name, function, args) + #define r_args_none (MRB_ARGS_NONE()) + #define r_args_req(n) MRB_ARGS_REQ(n) #else // Ruby - #define RVAL VALUE - #define RNIL Qnil - #define RTRUE Qtrue - #define RFALSE Qfalse + #define R_VAL VALUE + #define R_NIL Qnil + #define R_TRUE Qtrue + #define R_FALSE Qfalse + #define R_CLASS R_VAL #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__) @@ -71,6 +78,11 @@ #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) + #define r_define_module(name) rb_define_module(name) + #define r_define_class(module, name) rb_define_class_under(module, name, rb_cObject); + #define r_define_method(class, name, function, args) rb_define_method(class, name, function, args) + #define r_args_none 0 + #define r_args_req(n) n #endif // @type_id values for rendering @@ -86,21 +98,11 @@ #endif // Ruby 2D window -static RVAL self; +static R_VAL ruby2d_window; // Simple 2D window static S2D_Window *window; -// Ruby data types -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 @@ -116,10 +118,20 @@ static RVAL ruby2d_window_class; static const struct mrb_data_type text_data_type = { "text", free_text }; + static void free_sound(mrb_state *mrb, void *p_); + static const struct mrb_data_type sound_data_type = { + "sound", free_sound + }; + static void free_music(mrb_state *mrb, void *p_); + static const struct mrb_data_type music_data_type = { + "music", free_music + }; #else static void free_image(S2D_Image *img); static void free_sprite(S2D_Sprite *spr); static void free_text(S2D_Text *txt); + static void free_sound(S2D_Sound *snd); + static void free_music(S2D_Music *mus); #endif @@ -132,13 +144,21 @@ static void free_window() { /* -* Initialize image structure data -*/ -static RVAL init_image(char *path) { - sprintf(S2D_msg, "init image: %s", path); + * Ruby2D::Image#init + * Initialize image structure data + */ +#if MRUBY +static R_VAL ruby2d_image_init(mrb_state* mrb, R_VAL self) { + mrb_value path; + mrb_get_args(mrb, "o", &path); +#else +static R_VAL ruby2d_image_init(R_VAL self, R_VAL path) { +#endif + sprintf(S2D_msg, "Init image: %s", RSTRING_PTR(path)); S2D_Log(S2D_msg, S2D_INFO); - S2D_Image *img = S2D_CreateImage(path); - return r_data_wrap_struct(image, img); + S2D_Image *img = S2D_CreateImage(RSTRING_PTR(path)); + r_iv_set(self, "@data", r_data_wrap_struct(image, img)); + return R_NIL; } @@ -151,20 +171,28 @@ static void free_image(mrb_state *mrb, void *p_) { #else static void free_image(S2D_Image *img) { #endif - sprintf(S2D_msg, "free image: %i, %i", img->x, img->y); + sprintf(S2D_msg, "Free image: %i, %i", img->x, img->y); S2D_Log(S2D_msg, S2D_INFO); S2D_FreeImage(img); } /* + * Ruby2D::Sprite#init * Initialize sprite structure data */ -static RVAL init_sprite(char *path) { - sprintf(S2D_msg, "init sprite: %s", path); +#if MRUBY +static R_VAL ruby2d_sprite_init(mrb_state* mrb, R_VAL self) { + mrb_value path; + mrb_get_args(mrb, "o", &path); +#else +static R_VAL ruby2d_sprite_init(R_VAL self, R_VAL path) { +#endif + sprintf(S2D_msg, "Init sprite: %s", RSTRING_PTR(path)); S2D_Log(S2D_msg, S2D_INFO); - S2D_Sprite *spr = S2D_CreateSprite(path); - return r_data_wrap_struct(sprite, spr); + S2D_Sprite *spr = S2D_CreateSprite(RSTRING_PTR(path)); + r_iv_set(self, "@data", r_data_wrap_struct(sprite, spr)); + return R_NIL; } @@ -177,20 +205,55 @@ static void free_sprite(mrb_state *mrb, void *p_) { #else static void free_sprite(S2D_Sprite *spr) { #endif - sprintf(S2D_msg, "free sprite: %i, %i", spr->x, spr->y); + sprintf(S2D_msg, "Free sprite: %i, %i", spr->x, spr->y); S2D_Log(S2D_msg, S2D_INFO); S2D_FreeSprite(spr); } /* + * Ruby2D::Text#init * Initialize text structure data */ -static RVAL init_text(char *font, char *msg, int size) { - sprintf(S2D_msg, "init text: %s", msg); +#if MRUBY +static R_VAL ruby2d_text_init(mrb_state* mrb, R_VAL self) { +#else +static R_VAL ruby2d_text_init(R_VAL self) { +#endif + sprintf(S2D_msg, "Init text: %s", RSTRING_PTR(r_iv_get(self, "@text"))); S2D_Log(S2D_msg, S2D_INFO); - S2D_Text *txt = S2D_CreateText(font, msg, size); - return r_data_wrap_struct(text, txt); + + S2D_Text *txt = S2D_CreateText( + RSTRING_PTR(r_iv_get(self, "@font")), + RSTRING_PTR(r_iv_get(self, "@text")), + NUM2DBL(r_iv_get(self, "@size")) + ); + + r_iv_set(self, "@data", r_data_wrap_struct(text, txt)); + return R_NIL; +} + + +/* + * Ruby2D::Text#text= + */ +#if MRUBY +static R_VAL ruby2d_text_equals(mrb_state* mrb, R_VAL self) { + mrb_value text; + mrb_get_args(mrb, "o", &text); +#else +static R_VAL ruby2d_text_equals(R_VAL self, R_VAL text) { + r_iv_set(self, "@text", text); +#endif + + // If called before window is shown, return + if (!r_test(ruby2d_window)) return R_NIL; + + S2D_Text *txt; + r_data_get_struct(self, "@data", &text_data_type, S2D_Text, txt); + + S2D_SetText(txt, RSTRING_PTR(text)); + return R_NIL; } @@ -203,27 +266,179 @@ static void free_text(mrb_state *mrb, void *p_) { #else static void free_text(S2D_Text *txt) { #endif - sprintf(S2D_msg, "free text: %s", txt->msg); + sprintf(S2D_msg, "Free text: %s", txt->msg); S2D_Log(S2D_msg, S2D_INFO); S2D_FreeText(txt); } +/* + * Ruby2D::Sound#init + * Initialize sound structure data + */ +#if MRUBY +static R_VAL ruby2d_sound_init(mrb_state* mrb, R_VAL self) { + mrb_value path; + mrb_get_args(mrb, "o", &path); +#else +static R_VAL ruby2d_sound_init(R_VAL self, R_VAL path) { +#endif + sprintf(S2D_msg, "Init sound: %s", RSTRING_PTR(path)); + S2D_Log(S2D_msg, S2D_INFO); + S2D_Sound *snd = S2D_CreateSound(RSTRING_PTR(path)); + r_iv_set(self, "@data", r_data_wrap_struct(sound, snd)); + return R_NIL; +} + + +/* + * Ruby2D::Sound#play + */ +#if MRUBY +static R_VAL ruby2d_sound_play(mrb_state* mrb, R_VAL self) { +#else +static R_VAL ruby2d_sound_play(R_VAL self) { +#endif + S2D_Sound *snd; + r_data_get_struct(self, "@data", &sound_data_type, S2D_Sound, snd); + S2D_PlaySound(snd); + return R_NIL; +} + + +/* + * Free sound structure attached to Ruby 2D `Sound` class + */ +#if MRUBY +static void free_sound(mrb_state *mrb, void *p_) { + S2D_Sound *snd = (S2D_Sound *)p_; +#else +static void free_sound(S2D_Sound *snd) { +#endif + sprintf(S2D_msg, "Free sound"); + S2D_Log(S2D_msg, S2D_INFO); + S2D_FreeSound(snd); +} + + +/* + * Ruby2D::Music#init + * Initialize music structure data + */ +#if MRUBY +static R_VAL ruby2d_music_init(mrb_state* mrb, R_VAL self) { + mrb_value path; + mrb_get_args(mrb, "o", &path); +#else +static R_VAL ruby2d_music_init(R_VAL self, R_VAL path) { +#endif + sprintf(S2D_msg, "Init music: %s", RSTRING_PTR(path)); + S2D_Log(S2D_msg, S2D_INFO); + S2D_Music *mus = S2D_CreateMusic(RSTRING_PTR(path)); + r_iv_set(self, "@data", r_data_wrap_struct(music, mus)); + return R_NIL; +} + + +/* + * Ruby2D::Music#play + */ +#if MRUBY +static R_VAL ruby2d_music_play(mrb_state* mrb, R_VAL self) { +#else +static R_VAL ruby2d_music_play(R_VAL self) { +#endif + S2D_Music *mus; + r_data_get_struct(self, "@data", &music_data_type, S2D_Music, mus); + S2D_PlayMusic(mus, r_test(r_iv_get(self, "@loop"))); + return R_NIL; +} + + +/* + * Ruby2D::Music#pause + */ +#if MRUBY +static R_VAL ruby2d_music_pause(mrb_state* mrb, R_VAL self) { +#else +static R_VAL ruby2d_music_pause(R_VAL self) { +#endif + S2D_PauseMusic(); + return R_NIL; +} + + +/* + * Ruby2D::Music#resume + */ +#if MRUBY +static R_VAL ruby2d_music_resume(mrb_state* mrb, R_VAL self) { +#else +static R_VAL ruby2d_music_resume(R_VAL self) { +#endif + S2D_ResumeMusic(); + return R_NIL; +} + + +/* + * Ruby2D::Music#stop + */ +#if MRUBY +static R_VAL ruby2d_music_stop(mrb_state* mrb, R_VAL self) { +#else +static R_VAL ruby2d_music_stop(R_VAL self) { +#endif + S2D_StopMusic(); + return R_NIL; +} + + +/* + * Ruby2D::Music#fadeout + */ +#if MRUBY +static R_VAL ruby2d_music_fadeout(mrb_state* mrb, R_VAL self) { + mrb_value ms; + mrb_get_args(mrb, "o", &ms); +#else +static R_VAL ruby2d_music_fadeout(R_VAL self, R_VAL ms) { +#endif + S2D_FadeOutMusic(NUM2INT(ms)); + return R_NIL; +} + + +/* + * Free sound structure attached to Ruby 2D `Sound` class + */ +#if MRUBY +static void free_music(mrb_state *mrb, void *p_) { + S2D_Music *mus = (S2D_Music *)p_; +#else +static void free_music(S2D_Music *mus) { +#endif + sprintf(S2D_msg, "Free music"); + S2D_Log(S2D_msg, S2D_INFO); + S2D_FreeMusic(mus); +} + + /* * Simple 2D `on_key` input callback function */ 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)); + r_funcall(ruby2d_window, "key_down_callback", 1, r_str_new(key)); break; case S2D_KEY: - r_funcall(self, "key_callback", 1, r_str_new(key)); + r_funcall(ruby2d_window, "key_callback", 1, r_str_new(key)); break; case S2D_KEYUP: - r_funcall(self, "key_up_callback", 1, r_str_new(key)); + r_funcall(ruby2d_window, "key_up_callback", 1, r_str_new(key)); break; } } @@ -233,7 +448,7 @@ static void on_key(S2D_Event e, const char *key) { * Simple 2D `on_mouse` input callback function */ void on_mouse(int x, int y) { - printf("Mouse down at: %i, %i\n", x, y); + r_funcall(ruby2d_window, "mouse_callback", 3, r_str_new("any"), INT2NUM(x), INT2NUM(y)); } @@ -241,10 +456,10 @@ void on_mouse(int x, int 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, bool pressed) { - r_funcall(self, "controller_callback", 6, + r_funcall(ruby2d_window, "controller_callback", 6, INT2NUM(which), - is_axis ? RTRUE : RFALSE, INT2NUM(axis), INT2NUM(val), - is_btn ? RTRUE : RFALSE, INT2NUM(btn) + is_axis ? R_TRUE : R_FALSE, INT2NUM(axis), INT2NUM(val), + is_btn ? R_TRUE : R_FALSE, INT2NUM(btn) ); } @@ -255,14 +470,17 @@ static void on_controller(int which, bool is_axis, int axis, int val, bool is_bt static void update() { // Set the cursor - r_iv_set(self, "@mouse_x", INT2NUM(window->mouse.x)); - r_iv_set(self, "@mouse_y", INT2NUM(window->mouse.y)); + r_iv_set(ruby2d_window, "@mouse_x", INT2NUM(window->mouse.x)); + r_iv_set(ruby2d_window, "@mouse_y", INT2NUM(window->mouse.y)); + + // Store frames + r_iv_set(ruby2d_window, "@frames", DBL2NUM(window->frames)); // Store frame rate - r_iv_set(self, "@fps", DBL2NUM(window->fps)); + r_iv_set(ruby2d_window, "@fps", DBL2NUM(window->fps)); // Call update proc, `window.update` - r_funcall(self, "update_callback", 0); + r_funcall(ruby2d_window, "update_callback", 0); } @@ -272,29 +490,29 @@ static void update() { static void render() { // Set background color - RVAL bc = r_iv_get(self, "@background"); + R_VAL bc = r_iv_get(ruby2d_window, "@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 - RVAL objects = r_iv_get(self, "@objects"); + R_VAL objects = r_iv_get(ruby2d_window, "@objects"); int num_objects = NUM2INT(r_funcall(objects, "length", 0)); // Switch on each object type for (int i = 0; i < num_objects; ++i) { - RVAL el = r_ary_entry(objects, i); + R_VAL 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: { - RVAL c1 = r_iv_get(el, "@c1"); - RVAL c2 = r_iv_get(el, "@c2"); - RVAL c3 = r_iv_get(el, "@c3"); + R_VAL c1 = r_iv_get(el, "@c1"); + R_VAL c2 = r_iv_get(el, "@c2"); + R_VAL c3 = r_iv_get(el, "@c3"); S2D_DrawTriangle( NUM2DBL(r_iv_get(el, "@x1")), @@ -322,10 +540,10 @@ static void render() { break; case R2D_QUAD: { - 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"); + R_VAL c1 = r_iv_get(el, "@c1"); + R_VAL c2 = r_iv_get(el, "@c2"); + R_VAL c3 = r_iv_get(el, "@c3"); + R_VAL c4 = r_iv_get(el, "@c4"); S2D_DrawQuad( NUM2DBL(r_iv_get(el, "@x1")), @@ -360,30 +578,28 @@ static void render() { break; case R2D_IMAGE: { - if (!r_test(r_iv_get(el, "@data"))) { - r_iv_set(el, "@data", init_image(RSTRING_PTR(r_iv_get(el, "@path")))); - } - S2D_Image *img; r_data_get_struct(el, "@data", &image_data_type, S2D_Image, 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"); + R_VAL w = r_iv_get(el, "@width"); + R_VAL h = r_iv_get(el, "@height"); if (r_test(w)) img->width = NUM2INT(w); if (r_test(h)) img->height = NUM2INT(h); + R_VAL c = r_iv_get(el, "@color"); + img->color.r = NUM2DBL(r_iv_get(c, "@r")); + img->color.g = NUM2DBL(r_iv_get(c, "@g")); + img->color.b = NUM2DBL(r_iv_get(c, "@b")); + img->color.a = NUM2DBL(r_iv_get(c, "@a")); + S2D_DrawImage(img); } break; case R2D_SPRITE: { - if (!r_test(r_iv_get(el, "@data"))) { - r_iv_set(el, "@data", init_sprite(RSTRING_PTR(r_iv_get(el, "@path")))); - } - S2D_Sprite *spr; r_data_get_struct(el, "@data", &sprite_data_type, S2D_Sprite, spr); @@ -403,21 +619,18 @@ static void render() { break; case R2D_TEXT: { - 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")) - )); - } - 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")); - S2D_SetText(txt, RSTRING_PTR(r_iv_get(el, "@text"))); + R_VAL c = r_iv_get(el, "@color"); + txt->color.r = NUM2DBL(r_iv_get(c, "@r")); + txt->color.g = NUM2DBL(r_iv_get(c, "@g")); + txt->color.b = NUM2DBL(r_iv_get(c, "@b")); + txt->color.a = NUM2DBL(r_iv_get(c, "@a")); + S2D_DrawText(txt); } break; @@ -429,8 +642,12 @@ static void render() { /* * Ruby2D::Window#show */ -static RVAL ruby2d_show(RVAL s) { - self = s; +#if MRUBY +static R_VAL ruby2d_show(mrb_state* mrb, R_VAL self) { +#else +static R_VAL ruby2d_show(R_VAL self) { +#endif + ruby2d_window = self; if (r_test(r_iv_get(self, "@diagnostics"))) { S2D_Diagnostics(true); @@ -459,7 +676,7 @@ static RVAL ruby2d_show(RVAL s) { // Check viewport size and set int viewport_width; - RVAL vp_w = r_iv_get(self, "@viewport_width"); + R_VAL vp_w = r_iv_get(self, "@viewport_width"); if (r_test(vp_w)) { viewport_width = NUM2INT(vp_w); } else { @@ -467,7 +684,7 @@ static RVAL ruby2d_show(RVAL s) { } int viewport_height; - RVAL vp_h = r_iv_get(self, "@viewport_height"); + R_VAL vp_h = r_iv_get(self, "@viewport_height"); if (r_test(vp_h)) { viewport_height = NUM2INT(vp_h); } else { @@ -487,68 +704,105 @@ static RVAL ruby2d_show(RVAL s) { S2D_Show(window); atexit(free_window); - return RNIL; + return R_NIL; } /* * Ruby2D::Window#close */ -static RVAL ruby2d_close() { +static R_VAL ruby2d_close() { S2D_Close(window); - return RNIL; + return R_NIL; } -/* -* MRuby entry point -*/ #if MRUBY +/* + * MRuby entry point + */ 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); +#else +/* + * Ruby C extension init + */ +void Init_ruby2d() { +#endif // Ruby2D - struct RClass *ruby2d_module = mrb_module_get(mrb, "Ruby2D"); + R_CLASS ruby2d_module = r_define_module("Ruby2D"); - // Ruby2D::Window - struct RClass *ruby2d_window_class = mrb_class_get_under(mrb, ruby2d_module, "Window"); + // Ruby2D::Image + R_CLASS ruby2d_image_class = r_define_class(ruby2d_module, "Image"); - // Ruby2D::Window#show - mrb_define_method(mrb, ruby2d_window_class, "show", ruby2d_show, MRB_ARGS_NONE()); + // Ruby2D::Image#init + r_define_method(ruby2d_image_class, "init", ruby2d_image_init, r_args_req(1)); - // Ruby2D::Window#close - mrb_define_method(mrb, ruby2d_window_class, "close", ruby2d_close, MRB_ARGS_NONE()); + // Ruby2D::Sprite + R_CLASS ruby2d_sprite_class = r_define_class(ruby2d_module, "Sprite"); - // Load the Ruby 2D app - mrb_load_irep(mrb, ruby2d_app); + // Ruby2D::Sprite#init + r_define_method(ruby2d_sprite_class, "init", ruby2d_sprite_init, r_args_req(1)); - // Close the MRuby environment - mrb_close(mrb); -} - - -/* -* Ruby C extension init -*/ -#else -void Init_ruby2d() { + // Ruby2D::Text + R_CLASS ruby2d_text_class = r_define_class(ruby2d_module, "Text"); - // Ruby2D - ruby2d_module = rb_define_module("Ruby2D"); + // Ruby2D::Text#init + r_define_method(ruby2d_text_class, "init", ruby2d_text_init, r_args_none); + + // Ruby2D::Text#text= + r_define_method(ruby2d_text_class, "text=", ruby2d_text_equals, r_args_req(1)); + + // Ruby2D::Sound + R_CLASS ruby2d_sound_class = r_define_class(ruby2d_module, "Sound"); + + // Ruby2D::Sound#init + r_define_method(ruby2d_sound_class, "init", ruby2d_sound_init, r_args_req(1)); + + // Ruby2D::Sound#play + r_define_method(ruby2d_sound_class, "play", ruby2d_sound_play, r_args_none); + + // Ruby2D::Music + R_CLASS ruby2d_music_class = r_define_class(ruby2d_module, "Music"); + + // Ruby2D::Music#init + r_define_method(ruby2d_music_class, "init", ruby2d_music_init, r_args_req(1)); + + // Ruby2D::Music#play + r_define_method(ruby2d_music_class, "play", ruby2d_music_play, r_args_none); + + // Ruby2D::Music#pause + r_define_method(ruby2d_music_class, "pause", ruby2d_music_pause, r_args_none); + + // Ruby2D::Music#resume + r_define_method(ruby2d_music_class, "resume", ruby2d_music_resume, r_args_none); + + // Ruby2D::Music#stop + r_define_method(ruby2d_music_class, "stop", ruby2d_music_stop, r_args_none); + + // Ruby2D::Music#fadeout + r_define_method(ruby2d_music_class, "fadeout", ruby2d_music_fadeout, r_args_req(1)); // Ruby2D::Window - ruby2d_window_class = rb_define_class_under(ruby2d_module, "Window", rb_cObject); + R_CLASS ruby2d_window_class = r_define_class(ruby2d_module, "Window"); // Ruby2D::Window#show - rb_define_method(ruby2d_window_class, "show", ruby2d_show, 0); + r_define_method(ruby2d_window_class, "show", ruby2d_show, r_args_none); // Ruby2D::Window#close - rb_define_method(ruby2d_window_class, "close", ruby2d_close, 0); -} + r_define_method(ruby2d_window_class, "close", ruby2d_close, r_args_none); + +#if MRUBY + // Load the Ruby 2D app + mrb_load_irep(mrb, ruby2d_app); + + // Close the MRuby environment + mrb_close(mrb); #endif +} -- cgit v1.2.3