ext/ruby2d/ruby2d.c in ruby2d-0.11.1 vs ext/ruby2d/ruby2d.c in ruby2d-0.11.2

- old
+ new

@@ -1,7 +1,11 @@ // Native C extension for Ruby and MRuby +#ifndef RUBY2D_IOS_TVOS +#define RUBY2D_IOS_TVOS 0 +#endif + // Ruby 2D includes #if RUBY2D_IOS_TVOS #else #include <ruby2d.h> #endif @@ -57,10 +61,12 @@ #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_ary_new() mrb_ary_new(mrb) + #define r_ary_push(self, val) mrb_ary_push(mrb, self, val) #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_define_module(mrb, name) #define r_define_class(module, name) mrb_define_class_under(mrb, module, name, mrb->object_class) #define r_define_method(class, name, function, args) mrb_define_method(mrb, class, name, function, args) @@ -80,10 +86,12 @@ #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_ary_new() rb_ary_new() + #define r_ary_push(self, val) rb_ary_push(self, val) #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) @@ -101,11 +109,11 @@ // Ruby 2D interpreter window static R_VAL ruby2d_window; // Ruby 2D native window -static R2D_Window *window; +static R2D_Window *ruby2d_c_window; // Method signatures and structures for Ruby 2D classes #if MRUBY static void free_sound(mrb_state *mrb, void *p_); @@ -114,23 +122,31 @@ }; static void free_music(mrb_state *mrb, void *p_); static const struct mrb_data_type music_data_type = { "music", free_music }; +static void free_font(mrb_state *mrb, void *p_); + static const struct mrb_data_type font_data_type = { + "font", free_font + }; +static void free_surface(mrb_state *mrb, void *p_); + static const struct mrb_data_type surface_data_type = { + "surface", free_surface + }; #else static void free_sound(R2D_Sound *snd); static void free_music(R2D_Music *mus); static void free_font(TTF_Font *font); - static void free_surface(SDL_Surface *font); + static void free_surface(SDL_Surface *surface); #endif /* * Function pointer to free the Ruby 2D native window */ static void free_window() { - R2D_FreeWindow(window); + R2D_FreeWindow(ruby2d_c_window); } /* * Normalize controller axis values to 0.0...1.0 @@ -356,57 +372,86 @@ /* * Ruby2D::Image#ext_load_image * Create an SDL surface from an image path, return the surface, width, and height */ +#if MRUBY +static R_VAL ruby2d_image_ext_load_image(mrb_state* mrb, R_VAL self) { + mrb_value path; + mrb_get_args(mrb, "o", &path); +#else static R_VAL ruby2d_image_ext_load_image(R_VAL self, R_VAL path) { +#endif R2D_Init(); - VALUE result = rb_ary_new2(3); + R_VAL result = r_ary_new(); SDL_Surface *surface = R2D_CreateImageSurface(RSTRING_PTR(path)); R2D_ImageConvertToRGB(surface); - rb_ary_push(result, r_data_wrap_struct(surface, surface)); - rb_ary_push(result, INT2NUM(surface->w)); - rb_ary_push(result, INT2NUM(surface->h)); + r_ary_push(result, r_data_wrap_struct(surface, surface)); + r_ary_push(result, INT2NUM(surface->w)); + r_ary_push(result, INT2NUM(surface->h)); return result; } /* * Ruby2D::Text#ext_load_text */ +#if MRUBY +static R_VAL ruby2d_text_ext_load_text(mrb_state* mrb, R_VAL self) { + mrb_value font, message; + mrb_get_args(mrb, "oo", &font, &message); +#else static R_VAL ruby2d_text_ext_load_text(R_VAL self, R_VAL font, R_VAL message) { +#endif R2D_Init(); - VALUE result = rb_ary_new2(3); + R_VAL result = r_ary_new(); TTF_Font *ttf_font; + +#if MRUBY + Data_Get_Struct(mrb, font, &font_data_type, ttf_font); +#else Data_Get_Struct(font, TTF_Font, ttf_font); +#endif SDL_Surface *surface = R2D_TextCreateSurface(ttf_font, RSTRING_PTR(message)); if (!surface) { return result; } - rb_ary_push(result, r_data_wrap_struct(surface, surface)); - rb_ary_push(result, INT2NUM(surface->w)); - rb_ary_push(result, INT2NUM(surface->h)); + r_ary_push(result, r_data_wrap_struct(surface, surface)); + r_ary_push(result, INT2NUM(surface->w)); + r_ary_push(result, INT2NUM(surface->h)); return result; } + /* * Ruby2D::Texture#ext_create */ +#if MRUBY +static R_VAL ruby2d_texture_ext_create(mrb_state* mrb, R_VAL self) { + mrb_value rubySurface, width, height; + mrb_get_args(mrb, "ooo", &rubySurface, &width, &height); +#else static R_VAL ruby2d_texture_ext_create(R_VAL self, R_VAL rubySurface, R_VAL width, R_VAL height) { +#endif GLuint texture_id = 0; SDL_Surface *surface; - Data_Get_Struct(rubySurface, SDL_Surface, surface); + #if MRUBY + Data_Get_Struct(mrb, rubySurface, &surface_data_type, surface); + #else + Data_Get_Struct(rubySurface, SDL_Surface, surface); + #endif + // Detect image mode GLint format = GL_RGB; if (surface->format->BytesPerPixel == 4) { format = GL_RGBA; } @@ -416,14 +461,21 @@ surface->pixels, GL_NEAREST); return INT2NUM(texture_id); } + /* * Ruby2D::Texture#ext_delete */ +#if MRUBY +static R_VAL ruby2d_texture_ext_delete(mrb_state* mrb, R_VAL self) { + mrb_value rubyTexture_id; + mrb_get_args(mrb, "o", &rubyTexture_id); +#else static R_VAL ruby2d_texture_ext_delete(R_VAL self, R_VAL rubyTexture_id) { +#endif GLuint texture_id = NUM2INT(rubyTexture_id); R2D_GL_FreeTexture(&texture_id); return R_NIL; @@ -464,11 +516,15 @@ /* * Ruby2D::Sound#ext_length */ +#if MRUBY +static R_VAL ruby2d_sound_ext_length(mrb_state* mrb, R_VAL self) { +#else static R_VAL ruby2d_sound_ext_length(R_VAL self) { +#endif R2D_Sound *snd; r_data_get_struct(self, "@data", &sound_data_type, R2D_Sound, snd); return INT2NUM(R2D_GetSoundLength(snd)); } @@ -483,10 +539,11 @@ static void free_sound(R2D_Sound *snd) { #endif R2D_FreeSound(snd); } + /* * Ruby2D::Sound#ext_get_volume */ #if MRUBY static R_VAL ruby2d_sound_ext_get_volume(mrb_state* mrb, R_VAL self) { @@ -496,10 +553,11 @@ R2D_Sound *snd; r_data_get_struct(self, "@data", &sound_data_type, R2D_Sound, snd); return INT2NUM(ceil(Mix_VolumeChunk(snd->data, -1) * (100.0 / MIX_MAX_VOLUME))); } + /* * Ruby2D::Music#ext_set_volume */ #if MRUBY static R_VAL ruby2d_sound_ext_set_volume(mrb_state* mrb, R_VAL self) { @@ -512,10 +570,11 @@ r_data_get_struct(self, "@data", &sound_data_type, R2D_Sound, snd); Mix_VolumeChunk(snd->data, (NUM2INT(volume) / 100.0) * MIX_MAX_VOLUME); return R_NIL; } + /* * Ruby2D::Sound#ext_get_mix_volume */ #if MRUBY static R_VAL ruby2d_sound_ext_get_mix_volume(mrb_state* mrb, R_VAL self) { @@ -523,10 +582,11 @@ static R_VAL ruby2d_sound_ext_get_mix_volume(R_VAL self) { #endif return INT2NUM(ceil(Mix_Volume(-1, -1) * (100.0 / MIX_MAX_VOLUME))); } + /* * Ruby2D::Music#ext_set_mix_volume */ #if MRUBY static R_VAL ruby2d_sound_ext_set_mix_volume(mrb_state* mrb, R_VAL self) { @@ -537,10 +597,11 @@ #endif Mix_Volume(-1, (NUM2INT(volume) / 100.0) * MIX_MAX_VOLUME); return R_NIL; } + /* * Ruby2D::Music#ext_init * Initialize music structure data */ #if MRUBY @@ -654,20 +715,31 @@ /* * Ruby2D::Music#ext_length */ +#if MRUBY +static R_VAL ruby2d_music_ext_length(mrb_state* mrb, R_VAL self) { +#else static R_VAL ruby2d_music_ext_length(R_VAL self) { +#endif R2D_Music *ms; r_data_get_struct(self, "@data", &music_data_type, R2D_Music, ms); return INT2NUM(R2D_GetMusicLength(ms)); } + /* * Ruby2D::Font#ext_load */ +#if MRUBY +static R_VAL ruby2d_font_ext_load(mrb_state* mrb, R_VAL self) { + mrb_value path, size, style; + mrb_get_args(mrb, "ooo", &path, &size, &style); +#else static R_VAL ruby2d_font_ext_load(R_VAL self, R_VAL path, R_VAL size, R_VAL style) { +#endif R2D_Init(); TTF_Font *font = R2D_FontCreateTTFFont(RSTRING_PTR(path), NUM2INT(size), RSTRING_PTR(style)); if (!font) { return R_NIL; @@ -678,11 +750,17 @@ /* * Ruby2D::Texture#ext_draw */ +#if MRUBY +static R_VAL ruby2d_texture_ext_draw(mrb_state* mrb, R_VAL self) { + mrb_value ruby_coordinates, ruby_texture_coordinates, ruby_color, texture_id; + mrb_get_args(mrb, "oooo", &ruby_coordinates, &ruby_texture_coordinates, &ruby_color, &texture_id); +#else static R_VAL ruby2d_texture_ext_draw(R_VAL self, R_VAL ruby_coordinates, R_VAL ruby_texture_coordinates, R_VAL ruby_color, R_VAL texture_id) { +#endif GLfloat coordinates[8]; GLfloat texture_coordinates[8]; GLfloat color[4]; for(int i = 0; i < 8; i++) { coordinates[i] = NUM2DBL(r_ary_entry(ruby_coordinates, i)); } @@ -692,21 +770,33 @@ R2D_GL_DrawTexture(coordinates, texture_coordinates, color, NUM2INT(texture_id)); return R_NIL; } + /* * Free font structure stored in the Ruby 2D `Font` class */ +#if MRUBY +static void free_font(mrb_state *mrb, void *p_) { + TTF_Font *font = (TTF_Font *)p_; +#else static void free_font(TTF_Font *font) { +#endif TTF_CloseFont(font); } + /* * Free surface structure used within the Ruby 2D `Texture` class */ +#if MRUBY +static void free_surface(mrb_state *mrb, void *p_) { + SDL_Surface *surface = (SDL_Surface *)p_; +#else static void free_surface(SDL_Surface *surface) { +#endif SDL_FreeSurface(surface); } /* @@ -900,18 +990,18 @@ * Ruby 2D native `update` callback function */ static void update() { // Set the cursor - r_iv_set(ruby2d_window, "@mouse_x", INT2NUM(window->mouse.x)); - r_iv_set(ruby2d_window, "@mouse_y", INT2NUM(window->mouse.y)); + r_iv_set(ruby2d_window, "@mouse_x", INT2NUM(ruby2d_c_window->mouse.x)); + r_iv_set(ruby2d_window, "@mouse_y", INT2NUM(ruby2d_c_window->mouse.y)); // Store frames - r_iv_set(ruby2d_window, "@frames", DBL2NUM(window->frames)); + r_iv_set(ruby2d_window, "@frames", DBL2NUM(ruby2d_c_window->frames)); // Store frame rate - r_iv_set(ruby2d_window, "@fps", DBL2NUM(window->fps)); + r_iv_set(ruby2d_window, "@fps", DBL2NUM(ruby2d_c_window->fps)); // Call update proc, `window.update` r_funcall(ruby2d_window, "update_callback", 0); } @@ -921,14 +1011,14 @@ */ static void render() { // Set background color 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")); + ruby2d_c_window->background.r = NUM2DBL(r_iv_get(bc, "@r")); + ruby2d_c_window->background.g = NUM2DBL(r_iv_get(bc, "@g")); + ruby2d_c_window->background.b = NUM2DBL(r_iv_get(bc, "@b")); + ruby2d_c_window->background.a = NUM2DBL(r_iv_get(bc, "@a")); // Read window objects R_VAL objects = r_iv_get(ruby2d_window, "@objects"); int num_objects = NUM2INT(r_funcall(objects, "length", 0)); @@ -1038,23 +1128,23 @@ R_VAL vp_h = r_iv_get(self, "@viewport_height"); int viewport_height = r_test(vp_h) ? NUM2INT(vp_h) : height; // Create and show window - window = R2D_CreateWindow( + ruby2d_c_window = R2D_CreateWindow( title, width, height, update, render, flags ); - window->viewport.width = viewport_width; - window->viewport.height = viewport_height; - window->fps_cap = fps_cap; - window->icon = icon; - window->on_key = on_key; - window->on_mouse = on_mouse; - window->on_controller = on_controller; + ruby2d_c_window->viewport.width = viewport_width; + ruby2d_c_window->viewport.height = viewport_height; + ruby2d_c_window->fps_cap = fps_cap; + ruby2d_c_window->icon = icon; + ruby2d_c_window->on_key = on_key; + ruby2d_c_window->on_mouse = on_mouse; + ruby2d_c_window->on_controller = on_controller; - R2D_Show(window); + R2D_Show(ruby2d_c_window); atexit(free_window); return R_NIL; } @@ -1067,23 +1157,27 @@ mrb_value path; mrb_get_args(mrb, "o", &path); #else static R_VAL ruby2d_ext_screenshot(R_VAL self, R_VAL path) { #endif - if (window) { - R2D_Screenshot(window, RSTRING_PTR(path)); + if (ruby2d_c_window) { + R2D_Screenshot(ruby2d_c_window, RSTRING_PTR(path)); return path; } else { return R_FALSE; } } /* * Ruby2D::Window#ext_close */ +#if MRUBY +static R_VAL ruby2d_window_ext_close(mrb_state* mrb, R_VAL self) { +#else static R_VAL ruby2d_window_ext_close() { - R2D_Close(window); +#endif + R2D_Close(ruby2d_c_window); return R_NIL; } #if MRUBY