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