ruby-sdl2 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,75 @@
1
+ require 'sdl2'
2
+
3
+ SpriteMotion = Struct.new(:position, :velocity)
4
+ WINDOW_W = 640
5
+ WINDOW_H = 480
6
+ NUM_SPRITES = 100
7
+ MAX_SPEED = 1
8
+
9
+ def load_sprite(filename, renderer)
10
+ bitmap = SDL2::Surface.load_bmp(filename)
11
+ bitmap.color_key = bitmap.pixel(0, 0)
12
+ sprite = renderer.create_texture_from(bitmap)
13
+ bitmap.destroy
14
+
15
+ sprite
16
+ end
17
+
18
+ def move_sprite(motions, renderer, sprite)
19
+ # draw a gray background
20
+ renderer.draw_color = [0xA0, 0xA0, 0xA0]
21
+ renderer.clear
22
+
23
+ sprite_w = sprite.w; sprite_h = sprite.h
24
+
25
+ motions.each do |m|
26
+ m.position.x += m.velocity.x
27
+ if m.position.x < 0 || m.position.x >= WINDOW_W - sprite_w
28
+ m.velocity.x *= -1
29
+ m.position.x += m.velocity.x
30
+ end
31
+
32
+ m.position.y += m.velocity.y
33
+ if m.position.y < 0 || m.position.y >= WINDOW_H - sprite_h
34
+ m.velocity.y *= -1
35
+ m.position.y += m.velocity.y
36
+ end
37
+
38
+ renderer.copy(sprite, nil, m.position)
39
+ end
40
+
41
+ renderer.present
42
+ end
43
+
44
+ def random_position(sprite_w, sprite_h)
45
+ SDL2::Rect[rand(WINDOW_W - sprite_w), rand(WINDOW_H - sprite_h), sprite_w, sprite_h]
46
+ end
47
+
48
+ def random_velocity
49
+ loop do
50
+ x = rand(MAX_SPEED*2+1) - MAX_SPEED
51
+ y = rand(MAX_SPEED*2+1) - MAX_SPEED
52
+ return SDL2::Point.new(x, y) if x != 0 || y != 0
53
+ end
54
+ end
55
+
56
+ window = SDL2::Window.create("testspritesimple", 0, 0, WINDOW_W, WINDOW_H, 0)
57
+ renderer = window.create_renderer(-1, 0)
58
+ sprite = load_sprite("icon.bmp", renderer)
59
+ sprite_w = sprite.w; sprite_h = sprite.h
60
+
61
+ motions = Array.new(NUM_SPRITES) do
62
+ SpriteMotion.new(random_position(sprite_w, sprite_h), random_velocity)
63
+ end
64
+
65
+ loop do
66
+ while event = SDL2::Event.poll
67
+ case event
68
+ when SDL2::Event::Quit, SDL2::Event::KeyDown
69
+ exit
70
+ end
71
+ end
72
+
73
+ move_sprite(motions, renderer, sprite)
74
+ sleep 0.01
75
+ end
@@ -0,0 +1,11 @@
1
+ require 'sdl2'
2
+
3
+ SDL2.init(SDL2::INIT_TIMER)
4
+
5
+ p SDL2.get_ticks
6
+ p SDL2.get_performance_counter
7
+ p SDL2.get_performance_frequency
8
+ SDL2.delay 50
9
+ p SDL2.get_ticks
10
+ p SDL2.get_performance_counter
11
+ p SDL2.get_performance_frequency
@@ -0,0 +1,12 @@
1
+ require 'sdl2'
2
+
3
+ p SDL2::LIBSDL_VERSION
4
+ p SDL2::LIBSDL_VERSION_NUMBER
5
+ p SDL2::LIBSDL_REVISION
6
+ p SDL2::LIBSDL_REVISION_NUMBER
7
+ p SDL2::LIBSDL_IMAGE_VERSION
8
+ p SDL2::LIBSDL_IMAGE_VERSION_NUMBER
9
+ p SDL2::LIBSDL_MIXER_VERSION
10
+ p SDL2::LIBSDL_MIXER_VERSION_NUMBER
11
+ p SDL2::LIBSDL_TTF_VERSION
12
+ p SDL2::LIBSDL_TTF_VERSION_NUMBER
@@ -0,0 +1,65 @@
1
+ require 'sdl2'
2
+ require "pp"
3
+
4
+ SDL2.init(SDL2::INIT_VIDEO)
5
+
6
+ pp SDL2::PixelFormat::FORMATS.map{|f| f.name}
7
+ p SDL2::PixelFormat::RGBA8888
8
+
9
+ p SDL2::Display.displays
10
+ SDL2::Display.displays.each{|display| p display.modes }
11
+ display = SDL2::Display.displays.first
12
+ print "curent mode: "; p display.current_mode
13
+ print "desktop mode: "; p display.desktop_mode
14
+ search_mode = SDL2::Display::Mode.new(SDL2::PixelFormat::UNKNOWN, 640, 480, 60)
15
+ puts "The mode closest to #{search_mode.inspect} is #{display.closest_mode(search_mode).inspect}"
16
+ print "bounds: "; p display.bounds
17
+ puts "current video driver: #{SDL2.current_video_driver}"
18
+
19
+ window = SDL2::Window.create("video info", 10, 10, 640, 480, 0)
20
+ renderer = window.create_renderer(-1, 0)
21
+ texture = renderer.load_texture("icon.bmp")
22
+
23
+ puts "window id: #{window.window_id}"
24
+ p SDL2::Window.all_windows
25
+ p window.display_mode
26
+ p window.display
27
+ print "window brightness: "; p window.brightness
28
+ print "window input grabbing: "; p window.input_is_grabbed?
29
+ print "window maximum size: "; p window.maximum_size
30
+ print "window minimum size: "; p window.minimum_size
31
+ print "window position: "; p window.position
32
+ print "window size: "; p window.size
33
+ print "window title: "; p window.title
34
+ print "window bordered: "; p window.bordered
35
+
36
+ p window.renderer
37
+ p renderer
38
+
39
+ p SDL2.video_drivers
40
+ p SDL2::Renderer.drivers_info
41
+ p renderer.info
42
+ p renderer.clip_rect
43
+ p renderer.logical_size
44
+ p renderer.scale
45
+ p renderer.viewport
46
+ p renderer.support_render_target?
47
+ p renderer.output_size
48
+
49
+ p renderer.info.texture_formats
50
+ renderer.info.texture_formats.each do |format|
51
+ p [format.format, format.name, format.type, format.order, format.layout, format.bpp, format.bytes_per_pixel,
52
+ format.indexed?, format.alpha?, format.fourcc?]
53
+
54
+ end
55
+
56
+ p texture
57
+ texture.destroy
58
+ p texture
59
+
60
+ p SDL2::ScreenSaver.enabled?
61
+ SDL2::ScreenSaver.disable
62
+ p SDL2::ScreenSaver.enabled?
63
+
64
+ renderer.present
65
+
data/timer.c ADDED
@@ -0,0 +1,63 @@
1
+ #include "rubysdl2_internal.h"
2
+ #include <SDL_timer.h>
3
+
4
+ /*
5
+ * @overload delay(ms)
6
+ * @param [Integer] ms the number of milliseconds to delay
7
+ *
8
+ * Wait a specified milliseconds.
9
+ *
10
+ * This function stops all ruby threads. If you want to keep running other
11
+ * threads, you should use Kernel.sleep instead of this function.
12
+ *
13
+ * @return [nil]
14
+ */
15
+ static VALUE SDL_s_delay(VALUE self, VALUE ms)
16
+ {
17
+ SDL_Delay(NUM2UINT(ms));
18
+ return Qnil;
19
+ }
20
+
21
+ /*
22
+ * Return the number of milliseconds since {SDL2.init} is called.
23
+ *
24
+ * @return [Integer] milliseconds in 32bit unsigned value.
25
+ */
26
+ static VALUE SDL_s_get_ticks(VALUE self)
27
+ {
28
+ return UINT2NUM(SDL_GetTicks());
29
+ }
30
+
31
+ /*
32
+ * Return the current value of the high resolution counter.
33
+ *
34
+ * This method is typically used for profiling.
35
+ *
36
+ * @return [Integer] the current counter value
37
+ * @see SDL2.get_performance_frequency
38
+ */
39
+ static VALUE SDL_s_get_performance_counter(VALUE self)
40
+ {
41
+ return ULL2NUM(SDL_GetPerformanceCounter());
42
+ }
43
+
44
+ /*
45
+ * Return the frequency (count per second) of the high resolution counter.
46
+ *
47
+ * @return [Integer] a platform-specific count per second.
48
+ * @see SDL2.get_performance_counter
49
+ */
50
+ static VALUE SDL_s_get_performance_frequency(VALUE self)
51
+ {
52
+ return ULL2NUM(SDL_GetPerformanceFrequency());
53
+ }
54
+
55
+ void rubysdl2_init_timer(void)
56
+ {
57
+ rb_define_module_function(mSDL2, "delay", SDL_s_delay, 1);
58
+ rb_define_module_function(mSDL2, "get_ticks", SDL_s_get_ticks, 0);
59
+ rb_define_module_function(mSDL2, "get_performance_counter",
60
+ SDL_s_get_performance_counter, 0);
61
+ rb_define_module_function(mSDL2, "get_performance_frequency",
62
+ SDL_s_get_performance_frequency,0);
63
+ }
data/ttf.c ADDED
@@ -0,0 +1,196 @@
1
+ #ifdef HAVE_SDL_TTF_H
2
+ #include "rubysdl2_internal.h"
3
+ #include <SDL_ttf.h>
4
+ #include <ruby/encoding.h>
5
+
6
+ VALUE cTTF;
7
+
8
+ #define TTF_ERROR() do { HANDLE_ERROR(SDL_SetError(TTF_GetError())); } while (0)
9
+ #define HANDLE_TTF_ERROR(code) \
10
+ do { if ((code) < 0) { TTF_ERROR(); } } while (0)
11
+
12
+ typedef struct TTF {
13
+ TTF_Font* font;
14
+ } TTF;
15
+
16
+ #define TTF_ATTRIBUTE(attr, capitalized_attr, ruby2c, c2ruby) \
17
+ static VALUE TTF_##attr(VALUE self) \
18
+ { \
19
+ return c2ruby(TTF_Get##capitalized_attr(Get_TTF_Font(self))); \
20
+ } \
21
+ static VALUE TTF_set_##attr(VALUE self, VALUE val) \
22
+ { \
23
+ TTF_Set##capitalized_attr(Get_TTF_Font(self), ruby2c(val)); \
24
+ return Qnil; \
25
+ }
26
+
27
+ #define TTF_ATTRIBUTE_INT(attr, capitalized_attr) \
28
+ TTF_ATTRIBUTE(attr, capitalized_attr, NUM2INT, INT2NUM)
29
+
30
+ #define TTF_ATTR_READER(attr, capitalized_attr, c2ruby) \
31
+ static VALUE TTF_##attr(VALUE self) \
32
+ { \
33
+ return c2ruby(TTF_Font##capitalized_attr(Get_TTF_Font(self))); \
34
+ }
35
+
36
+ static void TTF_free(TTF* f)
37
+ {
38
+ if (rubysdl2_is_active() && f->font)
39
+ TTF_CloseFont(f->font);
40
+ free(f);
41
+ }
42
+
43
+ static VALUE TTF_new(TTF_Font* font)
44
+ {
45
+ TTF* f = ALLOC(TTF);
46
+ f->font = font;
47
+ return Data_Wrap_Struct(cTTF, 0, TTF_free, f);
48
+ }
49
+
50
+ DEFINE_WRAPPER(TTF_Font, TTF, font, cTTF, "SDL2::TTF");
51
+
52
+ static VALUE TTF_s_init(VALUE self)
53
+ {
54
+ HANDLE_TTF_ERROR(TTF_Init());
55
+ return Qnil;
56
+ }
57
+
58
+ static VALUE TTF_s_open(int argc, VALUE* argv, VALUE self)
59
+ {
60
+ TTF_Font* font;
61
+ VALUE fname, ptsize, index;
62
+ rb_scan_args(argc, argv, "21", &fname, &ptsize, &index);
63
+
64
+ font = TTF_OpenFontIndex(StringValueCStr(fname), NUM2INT(ptsize),
65
+ index == Qnil ? 0 : NUM2LONG(index));
66
+ if (!font)
67
+ TTF_ERROR();
68
+
69
+ return TTF_new(font);
70
+ }
71
+
72
+ static VALUE TTF_destroy(VALUE self)
73
+ {
74
+ TTF* f = Get_TTF(self);
75
+ if (f->font)
76
+ TTF_CloseFont(f->font);
77
+ f->font = NULL;
78
+ return Qnil;
79
+ }
80
+
81
+ TTF_ATTRIBUTE_INT(style, FontStyle);
82
+ TTF_ATTRIBUTE_INT(outline, FontOutline);
83
+ TTF_ATTRIBUTE_INT(hinting, FontHinting);
84
+ TTF_ATTRIBUTE(kerning, FontKerning, RTEST, INT2BOOL);
85
+ TTF_ATTR_READER(height, Height, INT2FIX);
86
+ TTF_ATTR_READER(ascent, Ascent, INT2FIX);
87
+ TTF_ATTR_READER(descent, Descent, INT2FIX);
88
+ TTF_ATTR_READER(line_skip, LineSkip, INT2FIX);
89
+ TTF_ATTR_READER(num_faces, Faces, LONG2NUM);
90
+ TTF_ATTR_READER(face_is_fixed_width_p, FaceIsFixedWidth, INT2BOOL);
91
+ TTF_ATTR_READER(face_family_name, FaceFamilyName, utf8str_new_cstr);
92
+ TTF_ATTR_READER(face_style_name, FaceStyleName, utf8str_new_cstr);
93
+
94
+ static VALUE TTF_size_text(VALUE self, VALUE text)
95
+ {
96
+ int w, h;
97
+ text = rb_str_export_to_enc(text, rb_utf8_encoding());
98
+ HANDLE_TTF_ERROR(TTF_SizeUTF8(Get_TTF_Font(self), StringValueCStr(text), &w, &h));
99
+ return rb_ary_new3(2, INT2NUM(w), INT2NUM(h));
100
+ }
101
+
102
+ static SDL_Surface* render_solid(TTF_Font* font, const char* text, SDL_Color fg, SDL_Color bg)
103
+ {
104
+ return TTF_RenderUTF8_Solid(font, text, fg);
105
+ }
106
+
107
+ static SDL_Surface* render_blended(TTF_Font* font, const char* text, SDL_Color fg, SDL_Color bg)
108
+ {
109
+ return TTF_RenderUTF8_Blended(font, text, fg);
110
+ }
111
+
112
+ static VALUE render(SDL_Surface* (*renderer)(TTF_Font*, const char*, SDL_Color, SDL_Color),
113
+ VALUE font, VALUE text, VALUE fg, VALUE bg)
114
+ {
115
+ SDL_Surface* surface;
116
+ text = rb_str_export_to_enc(text, rb_utf8_encoding());
117
+ surface = renderer(Get_TTF_Font(font), StringValueCStr(text),
118
+ Array_to_SDL_Color(fg), Array_to_SDL_Color(bg));
119
+ if (!surface)
120
+ TTF_ERROR();
121
+
122
+ return Surface_new(surface);
123
+ }
124
+
125
+ static VALUE TTF_render_solid(VALUE self, VALUE text, VALUE fg)
126
+ {
127
+ return render(render_solid, self, text, fg, Qnil);
128
+ }
129
+
130
+ static VALUE TTF_render_shaded(VALUE self, VALUE text, VALUE fg, VALUE bg)
131
+ {
132
+ return render(TTF_RenderUTF8_Shaded, self, text, fg, bg);
133
+ }
134
+
135
+ static VALUE TTF_render_blended(VALUE self, VALUE text, VALUE fg)
136
+ {
137
+ return render(render_blended, self, text, fg, Qnil);
138
+ }
139
+
140
+ void rubysdl2_init_ttf(void)
141
+ {
142
+ cTTF = rb_define_class_under(mSDL2, "TTF", rb_cObject);
143
+ rb_undef_alloc_func(cTTF);
144
+
145
+ rb_define_singleton_method(cTTF, "init", TTF_s_init, 0);
146
+ rb_define_singleton_method(cTTF, "open", TTF_s_open, -1);
147
+ rb_define_method(cTTF, "destroy?", TTF_destroy_p, 0);
148
+ rb_define_method(cTTF, "destroy", TTF_destroy, 0);
149
+
150
+ #define DEFINE_TTF_ATTRIBUTE(attr) do { \
151
+ rb_define_method(cTTF, #attr, TTF_##attr, 0); \
152
+ rb_define_method(cTTF, #attr "=", TTF_set_##attr, 1); \
153
+ } while (0)
154
+
155
+ DEFINE_TTF_ATTRIBUTE(style);
156
+ DEFINE_TTF_ATTRIBUTE(outline);
157
+ DEFINE_TTF_ATTRIBUTE(hinting);
158
+ DEFINE_TTF_ATTRIBUTE(kerning);
159
+
160
+ #define DEFINE_TTF_ATTR_READER(attr) \
161
+ rb_define_method(cTTF, #attr, TTF_##attr, 0)
162
+
163
+ DEFINE_TTF_ATTR_READER(height);
164
+ DEFINE_TTF_ATTR_READER(ascent);
165
+ DEFINE_TTF_ATTR_READER(descent);
166
+ DEFINE_TTF_ATTR_READER(line_skip);
167
+ DEFINE_TTF_ATTR_READER(num_faces);
168
+ rb_define_method(cTTF, "face_is_fixed_width?", TTF_face_is_fixed_width_p, 0);
169
+ DEFINE_TTF_ATTR_READER(face_family_name);
170
+ DEFINE_TTF_ATTR_READER(face_style_name);
171
+
172
+ rb_define_method(cTTF, "size_text", TTF_size_text, 1);
173
+ rb_define_method(cTTF, "render_solid", TTF_render_solid, 2);
174
+ rb_define_method(cTTF, "render_shaded", TTF_render_shaded, 3);
175
+ rb_define_method(cTTF, "render_blended", TTF_render_blended, 2);
176
+
177
+ #define DEFINE_TTF_CONST(name) \
178
+ rb_define_const(cTTF, #name, INT2NUM((TTF_##name)))
179
+ DEFINE_TTF_CONST(STYLE_NORMAL);
180
+ DEFINE_TTF_CONST(STYLE_BOLD);
181
+ DEFINE_TTF_CONST(STYLE_ITALIC);
182
+ DEFINE_TTF_CONST(STYLE_UNDERLINE);
183
+ DEFINE_TTF_CONST(STYLE_STRIKETHROUGH);
184
+
185
+ DEFINE_TTF_CONST(HINTING_NORMAL);
186
+ DEFINE_TTF_CONST(HINTING_LIGHT);
187
+ DEFINE_TTF_CONST(HINTING_MONO);
188
+ DEFINE_TTF_CONST(HINTING_NONE);
189
+ }
190
+
191
+ #else /* HAVE_SDL_TTF_H */
192
+ void rubysdl2_init_ttf(void)
193
+ {
194
+ }
195
+ #endif /* HAVE_SDL_TTF_H */
196
+
@@ -0,0 +1,2935 @@
1
+ /* -*- mode: C -*- */
2
+ #include "rubysdl2_internal.h"
3
+ #include <SDL_video.h>
4
+ #include <SDL_version.h>
5
+ #include <SDL_render.h>
6
+ #include <SDL_messagebox.h>
7
+ #include <SDL_endian.h>
8
+ #include <ruby/encoding.h>
9
+
10
+ static VALUE cWindow;
11
+ static VALUE cDisplay;
12
+ static VALUE cDisplayMode;
13
+ static VALUE cRenderer;
14
+ static VALUE cTexture;
15
+ static VALUE cRect;
16
+ static VALUE cPoint;
17
+ static VALUE cSurface;
18
+ static VALUE cRendererInfo;
19
+ static VALUE cPixelFormat; /* NOTE: This is related to SDL_PixelFormatEnum, not SDL_PixelFormat */
20
+ static VALUE mScreenSaver;
21
+
22
+ static VALUE hash_windowid_to_window = Qnil;
23
+
24
+ struct Window;
25
+ struct Renderer;
26
+ struct Texture;
27
+
28
+ #ifdef DEBUG_GC
29
+ #define GC_LOG(args) fprintf args
30
+ #else
31
+ #define GC_LOG(args)
32
+ #endif
33
+
34
+ typedef struct Window {
35
+ SDL_Window* window;
36
+ int num_renderers;
37
+ int max_renderers;
38
+ struct Renderer** renderers;
39
+ } Window;
40
+
41
+ typedef struct Renderer {
42
+ SDL_Renderer* renderer;
43
+ int num_textures;
44
+ int max_textures;
45
+ struct Texture** textures;
46
+ int refcount;
47
+ } Renderer;
48
+
49
+ typedef struct Texture {
50
+ SDL_Texture* texture;
51
+ int refcount;
52
+ } Texture;
53
+
54
+ typedef struct Surface {
55
+ SDL_Surface* surface;
56
+ int need_to_free_pixels;
57
+ } Surface;
58
+
59
+ static void Renderer_free(Renderer*);
60
+ static void Window_destroy_internal(Window* w)
61
+ {
62
+ int i;
63
+ for (i=0; i<w->num_renderers; ++i)
64
+ Renderer_free(w->renderers[i]);
65
+ w->num_renderers = w->max_renderers = 0;
66
+ free(w->renderers);
67
+ w->renderers = NULL;
68
+ }
69
+
70
+ static void Window_free(Window* w)
71
+ {
72
+
73
+ GC_LOG((stderr, "Window free: %p\n", w));
74
+ Window_destroy_internal(w);
75
+ if (w->window && rubysdl2_is_active())
76
+ SDL_DestroyWindow(w->window);
77
+
78
+ free(w);
79
+ }
80
+
81
+ static VALUE Window_new(SDL_Window* window)
82
+ {
83
+ Window* w = ALLOC(Window);
84
+ w->window = window;
85
+ w->num_renderers = 0;
86
+ w->max_renderers = 4;
87
+ w->renderers = ALLOC_N(struct Renderer*, 4);
88
+ return Data_Wrap_Struct(cWindow, 0, Window_free, w);
89
+ }
90
+
91
+ DEFINE_GETTER(static, Window, cWindow, "SDL2::Window");
92
+ DEFINE_WRAP_GETTER(, SDL_Window, Window, window, "SDL2::Window");
93
+ DEFINE_DESTROY_P(static, Window, window);
94
+
95
+ static VALUE Display_new(int index)
96
+ {
97
+ VALUE display = rb_obj_alloc(cDisplay);
98
+ rb_iv_set(display, "@index", INT2NUM(index));
99
+ rb_iv_set(display, "@name", utf8str_new_cstr(SDL_GetDisplayName(index)));
100
+ return display;
101
+ }
102
+
103
+ static VALUE DisplayMode_s_allocate(VALUE klass)
104
+ {
105
+ SDL_DisplayMode* mode = ALLOC(SDL_DisplayMode);
106
+ mode->format = mode->w = mode->h = mode->refresh_rate = 0;
107
+ mode->driverdata = NULL;
108
+ return Data_Wrap_Struct(klass, 0, free, mode);
109
+ }
110
+
111
+ static VALUE DisplayMode_new(SDL_DisplayMode* mode)
112
+ {
113
+ VALUE display_mode = DisplayMode_s_allocate(cDisplayMode);
114
+ SDL_DisplayMode* m;
115
+ Data_Get_Struct(display_mode, SDL_DisplayMode, m);
116
+ *m = *mode;
117
+ return display_mode;
118
+ }
119
+
120
+ DEFINE_GETTER(static, SDL_DisplayMode, cDisplayMode, "SDL2::Display::Mode");
121
+
122
+ static void Texture_free(Texture*);
123
+ static void Renderer_destroy_internal(Renderer* r)
124
+ {
125
+ int i;
126
+ for (i=0; i<r->num_textures; ++i)
127
+ Texture_free(r->textures[i]);
128
+ free(r->textures);
129
+ r->textures = NULL;
130
+ r->max_textures = r->num_textures = 0;
131
+
132
+ if (r->renderer && rubysdl2_is_active()) {
133
+ SDL_DestroyRenderer(r->renderer);
134
+ }
135
+ r->renderer = NULL;
136
+ }
137
+
138
+ static void Renderer_free(Renderer* r)
139
+ {
140
+ GC_LOG((stderr, "Renderer free: %p (refcount=%d)\n", r, r->refcount));
141
+ Renderer_destroy_internal(r);
142
+
143
+ r->refcount--;
144
+ if (r->refcount == 0) {
145
+ free(r);
146
+ }
147
+ }
148
+
149
+ static void Window_attach_renderer(Window* w, Renderer* r)
150
+ {
151
+ if (w->num_renderers == w->max_renderers) {
152
+ w->max_renderers *= 2;
153
+ REALLOC_N(w->renderers, Renderer*, w->max_renderers);
154
+ }
155
+ w->renderers[w->num_renderers++] = r;
156
+ ++r->refcount;
157
+ }
158
+
159
+ static VALUE Renderer_new(SDL_Renderer* renderer, Window* w)
160
+ {
161
+ Renderer* r = ALLOC(Renderer);
162
+ r->renderer = renderer;
163
+ r->num_textures = 0;
164
+ r->max_textures = 16;
165
+ r->textures = ALLOC_N(Texture*, 16);
166
+ r->refcount = 1;
167
+ Window_attach_renderer(w, r);
168
+ return Data_Wrap_Struct(cRenderer, 0, Renderer_free, r);
169
+ }
170
+
171
+ DEFINE_WRAPPER(SDL_Renderer, Renderer, renderer, cRenderer, "SDL2::Renderer");
172
+
173
+ static void Texture_destroy_internal(Texture* t)
174
+ {
175
+ if (t->texture && rubysdl2_is_active()) {
176
+ SDL_DestroyTexture(t->texture);
177
+ }
178
+ t->texture = NULL;
179
+ }
180
+
181
+ static void Texture_free(Texture* t)
182
+ {
183
+ GC_LOG((stderr, "Texture free: %p (refcount=%d)\n", t, t->refcount));
184
+ Texture_destroy_internal(t);
185
+ t->refcount--;
186
+ if (t->refcount == 0) {
187
+ free(t);
188
+ }
189
+ }
190
+
191
+ static void Renderer_attach_texture(Renderer* r, Texture* t)
192
+ {
193
+ if (r->max_textures == r->num_textures) {
194
+ r->max_textures *= 2;
195
+ REALLOC_N(r->textures, Texture*, r->max_textures);
196
+ }
197
+ r->textures[r->num_textures++] = t;
198
+ ++t->refcount;
199
+ }
200
+
201
+ static VALUE Texture_new(SDL_Texture* texture, Renderer* r)
202
+ {
203
+ Texture* t = ALLOC(Texture);
204
+ t->texture = texture;
205
+ t->refcount = 1;
206
+ Renderer_attach_texture(r, t);
207
+ return Data_Wrap_Struct(cTexture, 0, Texture_free, t);
208
+ }
209
+
210
+ DEFINE_WRAPPER(SDL_Texture, Texture, texture, cTexture, "SDL2::Texture");
211
+
212
+
213
+ static void Surface_free(Surface* s)
214
+ {
215
+ GC_LOG((stderr, "Surface free: %p\n", s));
216
+ if (s->need_to_free_pixels)
217
+ free(s->surface->pixels);
218
+ if (s->surface && rubysdl2_is_active())
219
+ SDL_FreeSurface(s->surface);
220
+ free(s);
221
+ }
222
+
223
+ VALUE Surface_new(SDL_Surface* surface)
224
+ {
225
+ Surface* s = ALLOC(Surface);
226
+ s->surface = surface;
227
+ s->need_to_free_pixels = 0;
228
+ return Data_Wrap_Struct(cSurface, 0, Surface_free, s);
229
+ }
230
+
231
+ DEFINE_WRAPPER(SDL_Surface, Surface, surface, cSurface, "SDL2::Surface");
232
+
233
+ DEFINE_GETTER(, SDL_Rect, cRect, "SDL2::Rect");
234
+
235
+ DEFINE_GETTER(static, SDL_Point, cPoint, "SDL2::Point");
236
+
237
+ static VALUE PixelFormat_new(Uint32 format)
238
+ {
239
+ VALUE fmt = UINT2NUM(format);
240
+ return rb_class_new_instance(1, &fmt, cPixelFormat);
241
+ }
242
+
243
+ static VALUE RendererInfo_new(SDL_RendererInfo* info)
244
+ {
245
+ VALUE rinfo = rb_obj_alloc(cRendererInfo);
246
+ VALUE texture_formats = rb_ary_new();
247
+ unsigned int i;
248
+
249
+ rb_iv_set(rinfo, "@name", rb_usascii_str_new_cstr(info->name));
250
+ rb_iv_set(rinfo, "@texture_formats", texture_formats);
251
+ for (i=0; i<info->num_texture_formats; ++i)
252
+ rb_ary_push(texture_formats, PixelFormat_new(info->texture_formats[i]));
253
+ rb_iv_set(rinfo, "@max_texture_width", INT2NUM(info->max_texture_width));
254
+ rb_iv_set(rinfo, "@max_texture_height", INT2NUM(info->max_texture_height));
255
+
256
+ return rinfo;
257
+ }
258
+
259
+ SDL_Color Array_to_SDL_Color(VALUE ary)
260
+ {
261
+ SDL_Color color;
262
+ VALUE a;
263
+ if (ary == Qnil) {
264
+ color.r = color.g = color.b = 0; color.a = 255;
265
+ return color;
266
+ }
267
+
268
+ Check_Type(ary, T_ARRAY);
269
+ if (RARRAY_LEN(ary) != 3 && RARRAY_LEN(ary) != 4)
270
+ rb_raise(rb_eArgError, "wrong number of Array elements (%ld for 3 or 4)",
271
+ RARRAY_LEN(ary));
272
+ color.r = NUM2UCHAR(rb_ary_entry(ary, 0));
273
+ color.g = NUM2UCHAR(rb_ary_entry(ary, 1));
274
+ color.b = NUM2UCHAR(rb_ary_entry(ary, 2));
275
+ a = rb_ary_entry(ary, 3);
276
+ if (a == Qnil)
277
+ color.a = 255;
278
+ else
279
+ color.a = NUM2UCHAR(a);
280
+ return color;
281
+ }
282
+
283
+ /*
284
+ * Get the names of all video drivers.
285
+ *
286
+ * You can use the name as an argument of {.video_init}.
287
+ *
288
+ * @return [Array<String>]
289
+ */
290
+ static VALUE SDL2_s_video_drivers(VALUE self)
291
+ {
292
+ int num_drivers = HANDLE_ERROR(SDL_GetNumVideoDrivers());
293
+ int i;
294
+ VALUE drivers = rb_ary_new();
295
+ for (i=0; i<num_drivers; ++i)
296
+ rb_ary_push(drivers, rb_usascii_str_new_cstr(SDL_GetVideoDriver(i)));
297
+ return drivers;
298
+ }
299
+
300
+ /*
301
+ * Get the name of current video driver
302
+ *
303
+ * @return [String] the name of the current video driver
304
+ * @return [nil] when the video is not initialized
305
+ */
306
+ static VALUE SDL2_s_current_video_driver(VALUE self)
307
+ {
308
+ const char* name = SDL_GetCurrentVideoDriver();
309
+ if (name)
310
+ return utf8str_new_cstr(name);
311
+ else
312
+ return Qnil;
313
+ }
314
+
315
+ /*
316
+ * @overload video_init(driver_name)
317
+ * Initialize the video subsystem, specifying a video driver.
318
+ *
319
+ * {.init} cannot specify a video driver, so you need to use
320
+ * this method to specify a driver.
321
+ *
322
+ * @param driver_name [String]
323
+ * @return [nil]
324
+ *
325
+ * @see .init
326
+ */
327
+ static VALUE SDL2_s_video_init(VALUE self, VALUE driver_name)
328
+ {
329
+ HANDLE_ERROR(SDL_VideoInit(StringValueCStr(driver_name)));
330
+ return Qnil;
331
+ }
332
+
333
+ /*
334
+ * Document-class: SDL2::Window
335
+ *
336
+ * This class represents a window.
337
+ *
338
+ * If you want to create graphical application using Ruby/SDL, first you need to
339
+ * create a window.
340
+ *
341
+ * All of methods/class methods are available only after initializing video
342
+ * subsystem by {SDL2.init}.
343
+ *
344
+ * # Window Flags
345
+ *
346
+ * OR'd bits of the following constants represents window states.
347
+ * You can see a window state using {#flags} and create a window with a specified
348
+ * state using flag parameter of {.create}.
349
+ *
350
+ * * {SDL2::Window::FULLSCREEN} - fullscreen window
351
+ * * {SDL2::Window::FULLSCREEN_DESKTOP} -
352
+ * fullscreen window at the current desktop resolution
353
+ * * {SDL2::Window::OPENGL} - window usable with OpenGL context
354
+ * * {SDL2::Window::SHOWN} - window is visible
355
+ * * {SDL2::Window::HIDDEN} - window is not visible
356
+ * * {SDL2::Window::BORDERLESS} - no window decoration
357
+ * * {SDL2::Window::RESIZABLE} - window is resizable
358
+ * * {SDL2::Window::MINIMIZDED} - window is minimized
359
+ * * {SDL2::Window::MAXIMIZED} - window is maximized
360
+ * * {SDL2::Window::INPUT_GRABBED} - window has grabbed input focus
361
+ * * {SDL2::Window::INPUT_FOCUS} - window has input focus
362
+ * * {SDL2::Window::MOUSE_FOCUS} - window has mouse focus
363
+ * * {SDL2::Window::FOREIGN} - window is not created by SDL
364
+ * * {SDL2::Window::ALLOW_HIGHDPI} - window should be created in high-DPI mode if supported
365
+ * * {SDL2::Window::MOUSE_CAPTURE} - window has mouse captured
366
+ *
367
+ *
368
+ * @!method destroy?
369
+ * Return true if the window is already destroyed.
370
+ */
371
+
372
+ /*
373
+ * @overload create(title, x, y, w, h, flags)
374
+ * Create a window with the specified position (x,y), dimensions (w,h) and flags.
375
+ *
376
+ * @param [Integer] x the x position of the left-top of the window
377
+ * @param [Integer] y the y position of the left-top of the window
378
+ * @param [Integer] w the width of the window
379
+ * @param [Integer] h the height of the window
380
+ * @param [Integer] flags 0, or one or more [Window flag masks](#label-Flags) OR'd together
381
+ *
382
+ * @return [SDL2::Window] created window
383
+ *
384
+ */
385
+ static VALUE Window_s_create(VALUE self, VALUE title, VALUE x, VALUE y, VALUE w, VALUE h,
386
+ VALUE flags)
387
+ {
388
+ SDL_Window* window;
389
+ VALUE win;
390
+ title = rb_str_export_to_enc(title, rb_utf8_encoding());
391
+ window = SDL_CreateWindow(StringValueCStr(title),
392
+ NUM2INT(x), NUM2INT(y), NUM2INT(w), NUM2INT(h),
393
+ NUM2UINT(flags));
394
+ if (window == NULL)
395
+ HANDLE_ERROR(-1);
396
+
397
+ win = Window_new(window);
398
+ rb_hash_aset(hash_windowid_to_window, UINT2NUM(SDL_GetWindowID(window)), win);
399
+ return win;
400
+ }
401
+
402
+ /*
403
+ * Get all windows under SDL.
404
+ *
405
+ * @return [Hash<Integer => SDL2::Window>]
406
+ * the hash from window id to the {SDL2::Window} objects.
407
+ */
408
+ static VALUE Window_s_all_windows(VALUE self)
409
+ {
410
+ return rb_hash_dup(hash_windowid_to_window);
411
+ }
412
+
413
+ /*
414
+ * @overload find_by_id(id)
415
+ * Get the window from ID.
416
+ *
417
+ * @param id [Integer] the window id you want to find
418
+ * @return [SDL2::Window] the window associated with **id**
419
+ * @return [nil] when no window is associated with **id**
420
+ *
421
+ */
422
+ static VALUE Window_s_find_by_id(VALUE self, VALUE id)
423
+ {
424
+ return rb_hash_aref(hash_windowid_to_window, id);
425
+ }
426
+
427
+ VALUE find_window_by_id(Uint32 id)
428
+ {
429
+ return Window_s_find_by_id(Qnil, UINT2NUM(id));
430
+ }
431
+
432
+ /*
433
+ * @overload destroy
434
+ * Destroy window.
435
+ *
436
+ * You cannot call almost all methods after calling this method.
437
+ * The exception is {#destroy?}.
438
+ *
439
+ * @return [void]
440
+ */
441
+ static VALUE Window_destroy(VALUE self)
442
+ {
443
+ Window_destroy_internal(Get_Window(self));
444
+ return Qnil;
445
+ }
446
+
447
+ /*
448
+ * @overload create_renderer(index, flags)
449
+ * Create a 2D rendering context for a window.
450
+ *
451
+ * @param [Integer] index the index of the rendering driver to initialize,
452
+ * or -1 to initialize the first one supporting the requested flags
453
+ * @param [Integer] flags 0, or one or more [Renderer flag masks](SDL2) OR'd together;
454
+ *
455
+ * @return [SDL2::Renderer] the created renderer (rendering context)
456
+ */
457
+ static VALUE Window_create_renderer(VALUE self, VALUE index, VALUE flags)
458
+ {
459
+ SDL_Renderer* sdl_renderer;
460
+ VALUE renderer;
461
+ sdl_renderer = SDL_CreateRenderer(Get_SDL_Window(self), NUM2INT(index), NUM2UINT(flags));
462
+
463
+ if (sdl_renderer == NULL)
464
+ HANDLE_ERROR(-1);
465
+
466
+ renderer = Renderer_new(sdl_renderer, Get_Window(self));
467
+ rb_iv_set(self, "renderer", renderer);
468
+ return renderer;
469
+ }
470
+
471
+ /*
472
+ * @overload renderer
473
+ * Return the renderer associate with the window
474
+ *
475
+ * @return [SDL2::Renderer] the associated renderer
476
+ * @return [nil] if no renderer is created yet
477
+ */
478
+ static VALUE Window_renderer(VALUE self)
479
+ {
480
+ return rb_iv_get(self, "renderer");
481
+ }
482
+
483
+ /*
484
+ * Get the numeric ID of the window.
485
+ *
486
+ * @return [Integer]
487
+ */
488
+ static VALUE Window_window_id(VALUE self)
489
+ {
490
+ return UINT2NUM(SDL_GetWindowID(Get_SDL_Window(self)));
491
+ }
492
+
493
+ /*
494
+ * Get information about the window.
495
+ *
496
+ * @return [SDL2::Window::Mode]
497
+ */
498
+ static VALUE Window_display_mode(VALUE self)
499
+ {
500
+ SDL_DisplayMode mode;
501
+ HANDLE_ERROR(SDL_GetWindowDisplayMode(Get_SDL_Window(self), &mode));
502
+ return DisplayMode_new(&mode);
503
+ }
504
+
505
+ /*
506
+ * Get the display associated with the window.
507
+ *
508
+ * @return [SDL2::Display]
509
+ */
510
+ static VALUE Window_display(VALUE self)
511
+ {
512
+ int display_index = HANDLE_ERROR(SDL_GetWindowDisplayIndex(Get_SDL_Window(self)));
513
+ return Display_new(display_index);
514
+ }
515
+
516
+ /*
517
+ * Get the brightness (gamma correction) of the window.
518
+ *
519
+ * @return [Float] the brightness
520
+ * @see #brightness=
521
+ */
522
+ static VALUE Window_brightness(VALUE self)
523
+ {
524
+ return DBL2NUM(SDL_GetWindowBrightness(Get_SDL_Window(self)));
525
+ }
526
+
527
+ /*
528
+ * @overload brightness=(brightness)
529
+ * Set the brightness (gamma correction) of the window.
530
+ *
531
+ * @param brightness [Float] the brightness, 0.0 means complete dark and 1.0 means
532
+ * normal brightness.
533
+ * @return [brightness]
534
+ *
535
+ * @see #brightness
536
+ */
537
+ static VALUE Window_set_brightness(VALUE self, VALUE brightness)
538
+ {
539
+ HANDLE_ERROR(SDL_SetWindowBrightness(Get_SDL_Window(self), NUM2DBL(brightness)));
540
+ return brightness;
541
+ }
542
+
543
+ /*
544
+ * Get the [Window flag masks](#label-Window+Flags) of the window.
545
+ *
546
+ * @return [Integer] flags
547
+ * @see .create
548
+ */
549
+ static VALUE Window_flags(VALUE self)
550
+ {
551
+ return UINT2NUM(SDL_GetWindowFlags(Get_SDL_Window(self)));
552
+ }
553
+
554
+ static VALUE gamma_table_to_Array(Uint16 r[])
555
+ {
556
+ int i;
557
+ VALUE ary = rb_ary_new2(256);
558
+ for (i=0; i<256; ++i)
559
+ rb_ary_push(ary, UINT2NUM(r[i]));
560
+ return ary;
561
+ }
562
+
563
+ /*
564
+ * Get the gamma ramp for a window
565
+ *
566
+ * @return [Array<Array<Integer>>] the gamma ramp,
567
+ * return value is red, green, and blue gamma tables and each gamma table
568
+ * has 256 Integers of 0-65535.
569
+ *
570
+ */
571
+ static VALUE Window_gamma_ramp(VALUE self)
572
+ {
573
+ Uint16 r[256], g[256], b[256];
574
+ HANDLE_ERROR(SDL_GetWindowGammaRamp(Get_SDL_Window(self), r, g, b));
575
+ return rb_ary_new3(3,
576
+ gamma_table_to_Array(r),
577
+ gamma_table_to_Array(g),
578
+ gamma_table_to_Array(b));
579
+ }
580
+
581
+ /*
582
+ * @overload icon=(icon)
583
+ *
584
+ * Set the window icon.
585
+ *
586
+ * @param icon [SDL2::Surface] the icon for the window
587
+ * @return [icon]
588
+ */
589
+ static VALUE Window_set_icon(VALUE self, VALUE icon)
590
+ {
591
+ SDL_SetWindowIcon(Get_SDL_Window(self), Get_SDL_Surface(icon));
592
+ return icon;
593
+ }
594
+
595
+ /*
596
+ * Return true if the input is grabbed to the window.
597
+ *
598
+ * @see #input_is_grabbed=
599
+ */
600
+ static VALUE Window_input_is_grabbed_p(VALUE self)
601
+ {
602
+ return INT2BOOL(SDL_GetWindowGrab(Get_SDL_Window(self)));
603
+ }
604
+
605
+ /*
606
+ * @overload input_is_grabbed=(grabbed)
607
+ * Set the window's input grab mode.
608
+ *
609
+ * @param grabbed [Boolean] true to grub input, and false to release input
610
+ * @return [grabbed]
611
+ *
612
+ * @see #input_is_grabbed?
613
+ */
614
+ static VALUE Window_set_input_is_grabbed(VALUE self, VALUE grabbed)
615
+ {
616
+ SDL_SetWindowGrab(Get_SDL_Window(self), RTEST(grabbed));
617
+ return grabbed;
618
+ }
619
+
620
+ static VALUE Window_get_int_int(void (*func)(SDL_Window*, int*, int*), VALUE window)
621
+ {
622
+ int n, m;
623
+ func(Get_SDL_Window(window), &n, &m);
624
+ return rb_ary_new3(2, INT2NUM(n), INT2NUM(m));
625
+ }
626
+
627
+ static VALUE Window_set_int_int(void (*func)(SDL_Window*, int, int), VALUE window, VALUE val)
628
+ {
629
+ Check_Type(val, T_ARRAY);
630
+ if (RARRAY_LEN(val) != 2)
631
+ rb_raise(rb_eArgError, "Wrong array size (%ld for 2)", RARRAY_LEN(val));
632
+ func(Get_SDL_Window(window), NUM2INT(rb_ary_entry(val, 0)), NUM2INT(rb_ary_entry(val, 1)));
633
+ return Qnil;
634
+ }
635
+
636
+ /*
637
+ * Get the maximum size of the window's client area.
638
+ *
639
+ * @return [Integer,Integer] maximum width and maximum height.
640
+ *
641
+ * @see #maximum_size=
642
+ */
643
+ static VALUE Window_maximum_size(VALUE self)
644
+ {
645
+ return Window_get_int_int(SDL_GetWindowMaximumSize, self);
646
+ }
647
+
648
+ /*
649
+ * @overload maximum_size=(size)
650
+ * Set the maximum size of the window's client area.
651
+ *
652
+ * @param size [[Integer, Integer]] maximum width and maximum height,
653
+ * the both must be positive.
654
+ *
655
+ * @return [size]
656
+ *
657
+ * @see #maximum_size
658
+ */
659
+ static VALUE Window_set_maximum_size(VALUE self, VALUE max_size)
660
+ {
661
+ return Window_set_int_int(SDL_SetWindowMaximumSize, self, max_size);
662
+ }
663
+
664
+ /*
665
+ * Get the minimum size of the window's client area.
666
+ *
667
+ * @return [Integer,Integer] minimum width and minimum height.
668
+ *
669
+ * @see #minimum_size=
670
+ */
671
+ static VALUE Window_minimum_size(VALUE self)
672
+ {
673
+ return Window_get_int_int(SDL_GetWindowMinimumSize, self);
674
+ }
675
+
676
+ /*
677
+ * @overload minimum_size=(size)
678
+ * Set the minimum size of the window's client area.
679
+ *
680
+ * @param size [[Integer, Integer]] minimum width and minimum height,
681
+ * the both must be positive.
682
+ *
683
+ * @return [size]
684
+ *
685
+ * @see #minimum_size
686
+ */
687
+ static VALUE Window_set_minimum_size(VALUE self, VALUE min_size)
688
+ {
689
+ return Window_set_int_int(SDL_SetWindowMinimumSize, self, min_size);
690
+ }
691
+
692
+ /*
693
+ * Get the position of the window.
694
+ *
695
+ * @return [Integer,Integer] the x position and the y position
696
+ *
697
+ * @see #position=
698
+ */
699
+ static VALUE Window_position(VALUE self)
700
+ {
701
+ return Window_get_int_int(SDL_GetWindowPosition, self);
702
+ }
703
+
704
+ /*
705
+ * @overload position=(xy)
706
+ * Set the position of the window
707
+ *
708
+ * @param xy [[Integer, Integer]] the x position and the y position,
709
+ * {SDL2::Window::POS_CENTERED} and {SDL2::Window::POS_UNDEFINED}
710
+ * are available.
711
+ *
712
+ * @return [size]
713
+ *
714
+ * @see #position
715
+ */
716
+ static VALUE Window_set_position(VALUE self, VALUE xy)
717
+ {
718
+ return Window_set_int_int(SDL_SetWindowPosition, self, xy);
719
+ }
720
+
721
+ /*
722
+ * Get the size of the window.
723
+ *
724
+ * @return [[Integer, Integer]] the width and the height
725
+ *
726
+ * @see size=
727
+ */
728
+ static VALUE Window_size(VALUE self)
729
+ {
730
+ return Window_get_int_int(SDL_GetWindowSize, self);
731
+ }
732
+
733
+ /*
734
+ * @overload size=(size)
735
+ * Set the size of the window.
736
+ *
737
+ * @param wh [[Integer, Integer]] new width and new height
738
+ *
739
+ * @return [size]
740
+ *
741
+ * @see #size
742
+ */
743
+ static VALUE Window_set_size(VALUE self, VALUE size)
744
+ {
745
+ return Window_set_int_int(SDL_SetWindowSize, self, size);
746
+ }
747
+
748
+ /*
749
+ * Get the title of the window
750
+ *
751
+ * @return [String] the title, in UTF-8 encoding
752
+ *
753
+ * @see #title=
754
+ */
755
+ static VALUE Window_title(VALUE self)
756
+ {
757
+ return utf8str_new_cstr(SDL_GetWindowTitle(Get_SDL_Window(self)));
758
+ }
759
+
760
+ /*
761
+ * Return true if the window is bordered
762
+ *
763
+ * @return [Boolean]
764
+ *
765
+ * @see #bordered=
766
+ */
767
+ static VALUE Window_bordered(VALUE self)
768
+ {
769
+ return INT2BOOL(!(SDL_GetWindowFlags(Get_SDL_Window(self)) & SDL_WINDOW_BORDERLESS));
770
+ }
771
+
772
+ /*
773
+ * @overload bordered=(bordered)
774
+ * Set the border state of the window.
775
+ *
776
+ * @param bordered [Boolean] true for bordered window, anad false for
777
+ * borderless window
778
+ *
779
+ * @return [bordered]
780
+ *
781
+ * @see #bordered
782
+ */
783
+ static VALUE Window_set_bordered(VALUE self, VALUE bordered)
784
+ {
785
+ SDL_SetWindowBordered(Get_SDL_Window(self), RTEST(bordered));
786
+ return bordered;
787
+ }
788
+
789
+ /*
790
+ * @overload title=(title)
791
+ * Set the title of the window.
792
+ *
793
+ * @param title [String] the title
794
+ * @return [title]
795
+ *
796
+ * @see #title
797
+ */
798
+ static VALUE Window_set_title(VALUE self, VALUE title)
799
+ {
800
+ title = rb_str_export_to_enc(title, rb_utf8_encoding());
801
+ SDL_SetWindowTitle(Get_SDL_Window(self), StringValueCStr(title));
802
+ return Qnil;
803
+ }
804
+
805
+ /*
806
+ define(`SIMPLE_WINDOW_METHOD',`static VALUE Window_$2(VALUE self)
807
+ {
808
+ SDL_$1Window(Get_SDL_Window(self)); return Qnil;
809
+ }')
810
+ */
811
+ /*
812
+ * Show the window.
813
+ *
814
+ * @return [nil]
815
+ * @see #hide
816
+ */
817
+ SIMPLE_WINDOW_METHOD(Show, show);
818
+
819
+ /*
820
+ * Hide the window.
821
+ *
822
+ * @return [nil]
823
+ * @see #show
824
+ */
825
+ SIMPLE_WINDOW_METHOD(Hide, hide);
826
+
827
+ /*
828
+ * Maximize the window.
829
+ *
830
+ * @return [nil]
831
+ * @see #minimize
832
+ * @see #restore
833
+ */
834
+ SIMPLE_WINDOW_METHOD(Maximize, maximize);
835
+
836
+ /*
837
+ * Minimize the window.
838
+ *
839
+ * @return [nil]
840
+ * @see #maximize
841
+ * @see #restore
842
+ */
843
+ SIMPLE_WINDOW_METHOD(Minimize, minimize);
844
+
845
+ /*
846
+ * Raise the window above other windows and set the input focus.
847
+ *
848
+ * @return [nil]
849
+ */
850
+ SIMPLE_WINDOW_METHOD(Raise, raise);
851
+
852
+ /*
853
+ * Restore the size and position of a minimized or maixmized window.
854
+ *
855
+ * @return [nil]
856
+ * @see #minimize
857
+ * @see #maximize
858
+ */
859
+ SIMPLE_WINDOW_METHOD(Restore, restore);
860
+
861
+ /*
862
+ * Get the fullscreen stete of the window
863
+ *
864
+ * @return [Integer] 0 for window mode, SDL2::Window::FULLSCREEN for
865
+ * fullscreen mode, and SDL2::Window::FULLSCREEN_DESKTOP for fullscreen
866
+ * at the current desktop resolution.
867
+ *
868
+ * @see #fullscreen_mode=
869
+ * @see #flags
870
+ */
871
+ static VALUE Window_fullscreen_mode(VALUE self)
872
+ {
873
+ Uint32 flags = SDL_GetWindowFlags(Get_SDL_Window(self));
874
+ return UINT2NUM(flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_FULLSCREEN_DESKTOP));
875
+ }
876
+
877
+ /*
878
+ * @overload fullscreen_mode=(flag)
879
+ * Set the fullscreen state of the window
880
+ *
881
+ * @param flag [Integer] 0 for window mode, SDL2::Window::FULLSCREEN for
882
+ * fullscreen mode, and SDL2::Window::FULLSCREEN_DESKTOP for fullscreen
883
+ * at the current desktop resolution.
884
+ * @return [flag]
885
+ *
886
+ * @see #fullscreen_mode
887
+ */
888
+ static VALUE Window_set_fullscreen_mode(VALUE self, VALUE flags)
889
+ {
890
+ HANDLE_ERROR(SDL_SetWindowFullscreen(Get_SDL_Window(self), NUM2UINT(flags)));
891
+ return flags;
892
+ }
893
+
894
+
895
+ /*
896
+ * Get the size of the drawable region.
897
+ *
898
+ * @return [[Integer, Integer]] the width and height of the region
899
+ */
900
+ #if SDL_VERSION_ATLEAST(2,0,1)
901
+ static VALUE Window_gl_drawable_size(VALUE self)
902
+ {
903
+ int w, h;
904
+ SDL_GL_GetDrawableSize(Get_SDL_Window(self), &w, &h);
905
+ return rb_ary_new3(2, INT2NUM(w), INT2NUM(h));
906
+ }
907
+ #endif
908
+
909
+ /*
910
+ * Swap the OpenGL buffers for the window, if double buffering
911
+ * is supported.
912
+ *
913
+ * @return [nil]
914
+ */
915
+ static VALUE Window_gl_swap(VALUE self)
916
+ {
917
+ SDL_GL_SwapWindow(Get_SDL_Window(self));
918
+ return Qnil;
919
+ }
920
+
921
+ /* @return [String] inspection string */
922
+ static VALUE Window_inspect(VALUE self)
923
+ {
924
+ Window* w = Get_Window(self);
925
+ if (w->window)
926
+ return rb_sprintf("<%s:%p window_id=%d>",
927
+ rb_obj_classname(self), (void*)self, SDL_GetWindowID(w->window));
928
+ else
929
+ return rb_sprintf("<%s:%p (destroyed)>", rb_obj_classname(self), (void*)self);
930
+ }
931
+
932
+ /* @return [Hash] (GC) debug information */
933
+ static VALUE Window_debug_info(VALUE self)
934
+ {
935
+ Window* w = Get_Window(self);
936
+ VALUE info = rb_hash_new();
937
+ int num_active_renderers = 0;
938
+ int i;
939
+ rb_hash_aset(info, rb_str_new2("destroy?"), INT2BOOL(w->window == NULL));
940
+ rb_hash_aset(info, rb_str_new2("max_renderers"), INT2NUM(w->max_renderers));
941
+ rb_hash_aset(info, rb_str_new2("num_renderers"), INT2NUM(w->num_renderers));
942
+ for (i=0; i<w->num_renderers; ++i)
943
+ if (w->renderers[i]->renderer)
944
+ ++num_active_renderers;
945
+ rb_hash_aset(info, rb_str_new2("num_active_renderers"), INT2NUM(num_active_renderers));
946
+
947
+ return info;
948
+ }
949
+
950
+ /*
951
+ * Document-class: SDL2::Display
952
+ *
953
+ * This class represents displays, screens, or monitors.
954
+ *
955
+ * This means that if you use dual screen, {.displays} returns two displays.
956
+ *
957
+ * This class handles color depth, resolution, and refresh rate of displays.
958
+ *
959
+ */
960
+
961
+ /*
962
+ * Get all connected displays.
963
+ *
964
+ * @return [Array<SDL2::Display>]
965
+ *
966
+ */
967
+ static VALUE Display_s_displays(VALUE self)
968
+ {
969
+ int i;
970
+ int num_displays = HANDLE_ERROR(SDL_GetNumVideoDisplays());
971
+ VALUE displays = rb_ary_new2(num_displays);
972
+ for (i=0; i<num_displays; ++i)
973
+ rb_ary_push(displays, Display_new(i));
974
+ return displays;
975
+ }
976
+
977
+ static int Display_index_int(VALUE display)
978
+ {
979
+ return NUM2INT(rb_iv_get(display, "@index"));
980
+ }
981
+
982
+ /*
983
+ * Get available display modes of the display.
984
+ *
985
+ * @return [Array<SDL2::Display::Mode>]
986
+ *
987
+ */
988
+ static VALUE Display_modes(VALUE self)
989
+ {
990
+ int i;
991
+ int index = Display_index_int(self);
992
+ int num_modes = SDL_GetNumDisplayModes(index);
993
+ VALUE modes = rb_ary_new2(num_modes);
994
+ for (i=0; i<num_modes; ++i) {
995
+ SDL_DisplayMode mode;
996
+ HANDLE_ERROR(SDL_GetDisplayMode(index, i, &mode));
997
+ rb_ary_push(modes, DisplayMode_new(&mode));
998
+ }
999
+ return modes;
1000
+ }
1001
+
1002
+ /*
1003
+ * Get the current display mode.
1004
+ *
1005
+ * @return [SDL2::Display::Mode]
1006
+ *
1007
+ * @see #desktop_mode
1008
+ */
1009
+ static VALUE Display_current_mode(VALUE self)
1010
+ {
1011
+ SDL_DisplayMode mode;
1012
+ HANDLE_ERROR(SDL_GetCurrentDisplayMode(Display_index_int(self), &mode));
1013
+ return DisplayMode_new(&mode);
1014
+ }
1015
+
1016
+ /*
1017
+ * Get the desktop display mode.
1018
+ *
1019
+ * Normally, the return value of this method is
1020
+ * same as {#current_mode}. However,
1021
+ * when you use fullscreen and chagne the resolution,
1022
+ * this method returns the previous native display mode,
1023
+ * and not the current mode.
1024
+ *
1025
+ * @return [SDL2::Display::Mode]
1026
+ */
1027
+ static VALUE Display_desktop_mode(VALUE self)
1028
+ {
1029
+ SDL_DisplayMode mode;
1030
+ HANDLE_ERROR(SDL_GetDesktopDisplayMode(Display_index_int(self), &mode));
1031
+ return DisplayMode_new(&mode);
1032
+ }
1033
+
1034
+ /*
1035
+ * @overload closest_mode(mode)
1036
+ * Get the available display mode closest match to **mode**.
1037
+ *
1038
+ * @param mode [SDL2::Display::Mode] the desired display mode
1039
+ * @return [SDL2::Display::Mode]
1040
+ *
1041
+ */
1042
+ static VALUE Display_closest_mode(VALUE self, VALUE mode)
1043
+ {
1044
+ SDL_DisplayMode closest;
1045
+ if (!SDL_GetClosestDisplayMode(Display_index_int(self), Get_SDL_DisplayMode(mode),
1046
+ &closest))
1047
+ SDL_ERROR();
1048
+ return DisplayMode_new(&closest);
1049
+ }
1050
+
1051
+ /*
1052
+ * Get the desktop area represented by the display, with the primary
1053
+ * display located at (0, 0).
1054
+ *
1055
+ * @return [Rect]
1056
+ */
1057
+ static VALUE Display_bounds(VALUE self)
1058
+ {
1059
+ VALUE rect = rb_obj_alloc(cRect);
1060
+ HANDLE_ERROR(SDL_GetDisplayBounds(Display_index_int(self), Get_SDL_Rect(rect)));
1061
+ return rect;
1062
+ }
1063
+
1064
+ static Uint32 uint32_for_format(VALUE format)
1065
+ {
1066
+ if (rb_obj_is_kind_of(format, cPixelFormat))
1067
+ return NUM2UINT(rb_iv_get(format, "@format"));
1068
+ else
1069
+ return NUM2UINT(format);
1070
+ }
1071
+
1072
+ /*
1073
+ * Document-class: SDL2::Display::Mode
1074
+ *
1075
+ * This class represents the display mode.
1076
+ *
1077
+ * An object of this class has information about color depth, refresh rate,
1078
+ * and resolution of a display.
1079
+ *
1080
+ */
1081
+
1082
+ /*
1083
+ * @overload initialze(format, w, h, refresh_rate)
1084
+ * Create a new Display::Mode object.
1085
+ *
1086
+ * @param format [SDL2::PixelFormat, Integer] pixel format
1087
+ * @param w [Integer] the width
1088
+ * @param h [Integer] the height
1089
+ * @param refresh_rate [Integer] refresh rate
1090
+ */
1091
+ static VALUE DisplayMode_initialize(VALUE self, VALUE format, VALUE w, VALUE h,
1092
+ VALUE refresh_rate)
1093
+ {
1094
+ SDL_DisplayMode* mode = Get_SDL_DisplayMode(self);
1095
+ mode->format = uint32_for_format(format);
1096
+ mode->w = NUM2INT(w); mode->h = NUM2INT(h);
1097
+ mode->refresh_rate = NUM2INT(refresh_rate);
1098
+ return Qnil;
1099
+ }
1100
+
1101
+ /* @return [String] inspection string */
1102
+ static VALUE DisplayMode_inspect(VALUE self)
1103
+ {
1104
+ SDL_DisplayMode* mode = Get_SDL_DisplayMode(self);
1105
+ return rb_sprintf("<%s: format=%s w=%d h=%d refresh_rate=%d>",
1106
+ rb_obj_classname(self), SDL_GetPixelFormatName(mode->format),
1107
+ mode->w, mode->h, mode->refresh_rate);
1108
+
1109
+ }
1110
+
1111
+ /* @return [SDL2::PixelFormat] the pixel format of the display mode */
1112
+ static VALUE DisplayMode_format(VALUE self)
1113
+ {
1114
+ return PixelFormat_new(Get_SDL_DisplayMode(self)->format);
1115
+ }
1116
+
1117
+ /* @return [Integer] the width of the screen of the display mode */
1118
+ static VALUE DisplayMode_w(VALUE self)
1119
+ {
1120
+ return INT2NUM(Get_SDL_DisplayMode(self)->w);
1121
+ }
1122
+
1123
+ /* @return [Integer] the height of the screen of the display mode */
1124
+ static VALUE DisplayMode_h(VALUE self)
1125
+ {
1126
+ return INT2NUM(Get_SDL_DisplayMode(self)->h);
1127
+ }
1128
+
1129
+ /* @return [Integer] the refresh rate of the display mode */
1130
+ static VALUE DisplayMode_refresh_rate(VALUE self)
1131
+ {
1132
+ return INT2NUM(Get_SDL_DisplayMode(self)->refresh_rate);
1133
+ }
1134
+
1135
+ /*
1136
+ * Document-class: SDL2::Renderer
1137
+ *
1138
+ * This class represents a 2D rendering context for a window.
1139
+ *
1140
+ * You can create a renderer using {SDL2::Window#create_renderer} and
1141
+ * use it to draw figures on the window.
1142
+ *
1143
+ * # Flags
1144
+ * You can specify the OR'd bits of the following constants
1145
+ * {SDL2::Window#create_renderer when you create a new renderer}.
1146
+ *
1147
+ * * SDL2::Renderer::SOFTWARE - the renderer is a software fallback
1148
+ * * SDL2::Renderer::ACCELERATED - the renderer uses hardware acceleration
1149
+ * * SDL2::Renderer::PRESENTVSYNC - present is synchronized with the refresh rate
1150
+ * * SDL2::Renderer::TARGETTEXTURE - the renderer supports rendering to texture
1151
+ *
1152
+ * No flags(==0) gives priority to available ACCELERATED renderers
1153
+ *
1154
+ * # Blending modes
1155
+ * You can use 4 types of blending mode for rendering graphics
1156
+ * using Renderer class.
1157
+ *
1158
+ * You can change the blending mode using
1159
+ * {#draw_blend_mode=} and {SDL2::Texture#blend_mode=}.
1160
+ *
1161
+ * In the backend of SDL, opengl or direct3d blending
1162
+ * mechanism is used for blending operations.
1163
+ *
1164
+ * * SDL2::BLENDMODE_NONE - no blending (dstRGBA = srcRGBA)
1165
+ * * SDL2::BLENDMODE_BLEND - alpha blending
1166
+ * (dstRGB = (srcRGB * srcA) + (dstRGB * (1-srcA)),
1167
+ * dstA = srcA + (dstA * (1-srcA)))
1168
+ * * SDL2::BLENDMODE_ADD - additive blending
1169
+ * (dstRGB = (srcRGB * srcA) + dstRGB,
1170
+ * dstA = dstA)
1171
+ * * SDL2::BLENDMODE_MUL - color modulate
1172
+ * (dstRGB = srcRGB * dstRGB,
1173
+ * dstA = dstA)
1174
+ *
1175
+ * @!method destroy?
1176
+ * Return true if the renderer is {#destroy destroyed}.
1177
+ *
1178
+ */
1179
+
1180
+
1181
+ /*
1182
+ * @overload drivers_info
1183
+ * Return information of all available rendering contexts.
1184
+ * @return [Array<SDL2::Renderer::Info>] information about rendering contexts
1185
+ *
1186
+ */
1187
+ static VALUE Renderer_s_drivers_info(VALUE self)
1188
+ {
1189
+ int num_drivers = SDL_GetNumRenderDrivers();
1190
+ VALUE info_ary = rb_ary_new();
1191
+ int i;
1192
+ for (i=0; i<num_drivers; ++i) {
1193
+ SDL_RendererInfo info;
1194
+ HANDLE_ERROR(SDL_GetRenderDriverInfo(i, &info));
1195
+ rb_ary_push(info_ary, RendererInfo_new(&info));
1196
+ }
1197
+ return info_ary;
1198
+ }
1199
+
1200
+ /*
1201
+ * Destroy the rendering context and free associated textures.
1202
+ *
1203
+ * @return [nil]
1204
+ * @see #destroy?
1205
+ */
1206
+ static VALUE Renderer_destroy(VALUE self)
1207
+ {
1208
+ Renderer_destroy_internal(Get_Renderer(self));
1209
+ return Qnil;
1210
+ }
1211
+
1212
+ /*
1213
+ * @overload create_texture(format, access, w, h)
1214
+ * Create a new texture for the rendering context.
1215
+ *
1216
+ * You can use the following constants to specify access pattern
1217
+ *
1218
+ * * SDL2::Texture::ACCESS_STATIC - changes rarely, not lockable
1219
+ * * SDL2::Texture::ACCESS_STREAMING - changes frequently, lockable
1220
+ * * SDL2::Texture::ACCESS_TARGET - can be used as a render target
1221
+ *
1222
+ * @param [SDL2::PixelFormat,Integer] format format of the texture
1223
+ * @param [Integer] access texture access pattern
1224
+ * @param [Integer] w the width ofthe texture in pixels
1225
+ * @param [Integer] h the height ofthe texture in pixels
1226
+ *
1227
+ * @return [SDL2::Texture] the created texture
1228
+ *
1229
+ * @raise [SDL2::Error] raised when the texture cannot be created
1230
+ *
1231
+ * @see #create_texture_from
1232
+ */
1233
+ static VALUE Renderer_create_texture(VALUE self, VALUE format, VALUE access,
1234
+ VALUE w, VALUE h)
1235
+ {
1236
+ SDL_Texture* texture = SDL_CreateTexture(Get_SDL_Renderer(self),
1237
+ uint32_for_format(format),
1238
+ NUM2INT(access), NUM2INT(w), NUM2INT(h));
1239
+ if (!texture)
1240
+ SDL_ERROR();
1241
+ return Texture_new(texture, Get_Renderer(self));
1242
+ }
1243
+
1244
+ /*
1245
+ * @overload create_texture_from(surface)
1246
+ * Create a texture from an existing surface.
1247
+ *
1248
+ * @param [SDL2::Surface] surface the surface containing pixels for the texture
1249
+ * @return [SDL2::Texture] the created texture
1250
+ *
1251
+ * @raise [SDL2::Error] raised when the texture cannot be created
1252
+ *
1253
+ * @see #create_texture
1254
+ */
1255
+ static VALUE Renderer_create_texture_from(VALUE self, VALUE surface)
1256
+ {
1257
+ SDL_Texture* texture = SDL_CreateTextureFromSurface(Get_SDL_Renderer(self),
1258
+ Get_SDL_Surface(surface));
1259
+ if (texture == NULL)
1260
+ SDL_ERROR();
1261
+
1262
+ return Texture_new(texture, Get_Renderer(self));
1263
+ }
1264
+
1265
+ static SDL_Rect* Get_SDL_Rect_or_NULL(VALUE rect)
1266
+ {
1267
+ return rect == Qnil ? NULL : Get_SDL_Rect(rect);
1268
+ }
1269
+
1270
+ static SDL_Point* Get_SDL_Point_or_NULL(VALUE point)
1271
+ {
1272
+ return point == Qnil ? NULL : Get_SDL_Point(point);
1273
+ }
1274
+
1275
+ /*
1276
+ * @overload copy(texture, srcrect, dstrect)
1277
+ * Copy a portion of the texture to the current rendering target.
1278
+ *
1279
+ * @param [SDL2::Texture] texture the source texture
1280
+ * @param [SDL2::Rect,nil] srcrect the source rectangle, or nil for the entire texture
1281
+ * @param [SDL2::Rect,nil] dstrect the destination rectangle, or nil for the entire
1282
+ * rendering target; the texture will be stretched to fill the given rectangle
1283
+ *
1284
+ * @return [void]
1285
+ *
1286
+ * @see #copy_ex
1287
+ */
1288
+ static VALUE Renderer_copy(VALUE self, VALUE texture, VALUE srcrect, VALUE dstrect)
1289
+ {
1290
+ HANDLE_ERROR(SDL_RenderCopy(Get_SDL_Renderer(self),
1291
+ Get_SDL_Texture(texture),
1292
+ Get_SDL_Rect_or_NULL(srcrect),
1293
+ Get_SDL_Rect_or_NULL(dstrect)));
1294
+ return Qnil;
1295
+ }
1296
+
1297
+ /*
1298
+ * @overload copy_ex(texture, srcrect, dstrect, angle, center, flip)
1299
+ * Copy a portion of the texture to the current rendering target,
1300
+ * rotating it by angle around the given center and also flipping
1301
+ * it top-bottom and/or left-right.
1302
+ *
1303
+ * You can use the following constants to specify the horizontal/vertical flip:
1304
+ *
1305
+ * * SDL2::Renderer::FLIP_HORIZONTAL - flip horizontally
1306
+ * * SDL2::Renderer::FLIP_VERTICAL - flip vertically
1307
+ * * SDL2::Renderer::FLIP_NONE - do not flip, equal to zero
1308
+ *
1309
+ *
1310
+ * @param [SDL2::Texture] texture the source texture
1311
+ * @param [SDL2::Rect,nil] srcrect the source rectangle, or nil for the entire texture
1312
+ * @param [SDL2::Rect,nil] dstrect the destination rectangle, or nil for the entire
1313
+ * rendering target; the texture will be stretched to fill the given rectangle
1314
+ * @param [Float] angle an angle in degree indicating the rotation
1315
+ * that will be applied to dstrect
1316
+ * @param [SDL2::Point,nil] center the point around which dstrect will be rotated,
1317
+ * (if nil, rotation will be done around the center of dstrect)
1318
+ * @param [Integer] flip bits OR'd of the flip consntants
1319
+ *
1320
+ * @return [void]
1321
+ *
1322
+ * @see #copy
1323
+ */
1324
+ static VALUE Renderer_copy_ex(VALUE self, VALUE texture, VALUE srcrect, VALUE dstrect,
1325
+ VALUE angle, VALUE center, VALUE flip)
1326
+ {
1327
+ HANDLE_ERROR(SDL_RenderCopyEx(Get_SDL_Renderer(self),
1328
+ Get_SDL_Texture(texture),
1329
+ Get_SDL_Rect_or_NULL(srcrect),
1330
+ Get_SDL_Rect_or_NULL(dstrect),
1331
+ NUM2DBL(angle),
1332
+ Get_SDL_Point_or_NULL(center),
1333
+ NUM2INT(flip)));
1334
+ return Qnil;
1335
+ }
1336
+
1337
+ /*
1338
+ * Update the screen with rendering performed
1339
+ * @return [nil]
1340
+ */
1341
+ static VALUE Renderer_present(VALUE self)
1342
+ {
1343
+ SDL_RenderPresent(Get_SDL_Renderer(self));
1344
+ return Qnil;
1345
+ }
1346
+
1347
+ /*
1348
+ * Crear the rendering target with the drawing color.
1349
+ * @return [nil]
1350
+ *
1351
+ * @see #draw_color=
1352
+ */
1353
+ static VALUE Renderer_clear(VALUE self)
1354
+ {
1355
+ HANDLE_ERROR(SDL_RenderClear(Get_SDL_Renderer(self)));
1356
+ return Qnil;
1357
+ }
1358
+
1359
+ /*
1360
+ * Get the color used for drawing operations
1361
+ * @return [[Integer,Integer,Integer,Integer]]
1362
+ * red, green, blue, and alpha components of the drawing color
1363
+ * (all components are more than or equal to 0 and less than and equal to 255)
1364
+ *
1365
+ * @see #draw_color=
1366
+ */
1367
+ static VALUE Renderer_draw_color(VALUE self)
1368
+ {
1369
+ Uint8 r, g, b, a;
1370
+ HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self), &r, &g, &b, &a));
1371
+ return rb_ary_new3(4, INT2FIX(r), INT2FIX(g), INT2FIX(b), INT2FIX(a));
1372
+ }
1373
+
1374
+ /*
1375
+ * @overload draw_color=(color)
1376
+ * Set the color used for drawing operations
1377
+ *
1378
+ * All color components (including alpha) must be more than or equal to 0
1379
+ * and less than and equal to 255
1380
+ *
1381
+ * This method effects the following methods.
1382
+ *
1383
+ * * {#draw_line}
1384
+ * * {#draw_point}
1385
+ * * {#draw_rect}
1386
+ * * {#fill_rect}
1387
+ * * {#clear}
1388
+ *
1389
+ * @param [[Integer, Integer, Integer]] color
1390
+ * red, green, and blue components used for drawing
1391
+ * @param [[Integer, Integer, Integer, Integer]] color
1392
+ * red, green, blue, and alpha components used for drawing
1393
+ *
1394
+ * @return [color]
1395
+ *
1396
+ * @see #draw_color
1397
+ */
1398
+ static VALUE Renderer_set_draw_color(VALUE self, VALUE rgba)
1399
+ {
1400
+ SDL_Color color = Array_to_SDL_Color(rgba);
1401
+
1402
+ HANDLE_ERROR(SDL_SetRenderDrawColor(Get_SDL_Renderer(self),
1403
+ color.r, color.g, color.b, color.a));
1404
+
1405
+ return rgba;
1406
+ }
1407
+
1408
+ /*
1409
+ * @overload draw_line(x1, y1, x2, y2)
1410
+ * Draw a line from (x1, y1) to (x2, y2) using drawing color given by
1411
+ * {#draw_color=}.
1412
+ *
1413
+ * @param [Integer] x1 the x coordinate of the start point
1414
+ * @param [Integer] y1 the y coordinate of the start point
1415
+ * @param [Integer] x2 the x coordinate of the end point
1416
+ * @param [Integer] y2 the y coordinate of the end point
1417
+ * @return [nil]
1418
+ */
1419
+ static VALUE Renderer_draw_line(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2)
1420
+ {
1421
+ HANDLE_ERROR(SDL_RenderDrawLine(Get_SDL_Renderer(self),
1422
+ NUM2INT(x1), NUM2INT(y1), NUM2INT(x2), NUM2INT(y2)));
1423
+ return Qnil;
1424
+ }
1425
+
1426
+ /*
1427
+ * @overload draw_point(x, y)
1428
+ * Draw a point at (x, y) using drawing color given by {#draw_color=}.
1429
+ *
1430
+ * @param [Integer] x the x coordinate of the point
1431
+ * @param [Integer] y the y coordinate of the point
1432
+ *
1433
+ * @return [nil]
1434
+ */
1435
+ static VALUE Renderer_draw_point(VALUE self, VALUE x, VALUE y)
1436
+ {
1437
+ HANDLE_ERROR(SDL_RenderDrawPoint(Get_SDL_Renderer(self), NUM2INT(x), NUM2INT(y)));
1438
+ return Qnil;
1439
+ }
1440
+
1441
+ /*
1442
+ * @overload draw_rect(rect)
1443
+ * Draw a rectangle using drawing color given by {#draw_color=}.
1444
+ *
1445
+ * @param [SDL2::Rect] rect the drawing rectangle
1446
+ *
1447
+ * @return [nil]
1448
+ */
1449
+ static VALUE Renderer_draw_rect(VALUE self, VALUE rect)
1450
+ {
1451
+ HANDLE_ERROR(SDL_RenderDrawRect(Get_SDL_Renderer(self), Get_SDL_Rect(rect)));
1452
+ return Qnil;
1453
+ }
1454
+
1455
+ /*
1456
+ * @overload fill_rect(rect)
1457
+ * Draw a filled rectangle using drawing color given by {#draw_color=}.
1458
+ *
1459
+ * @param [SDL2::Rect] rect the drawing rectangle
1460
+ *
1461
+ * @return [nil]
1462
+ */
1463
+ static VALUE Renderer_fill_rect(VALUE self, VALUE rect)
1464
+ {
1465
+ HANDLE_ERROR(SDL_RenderFillRect(Get_SDL_Renderer(self), Get_SDL_Rect(rect)));
1466
+ return Qnil;
1467
+ }
1468
+
1469
+ /*
1470
+ * Get information about _self_ rendering context .
1471
+ *
1472
+ * @return [SDL2::Renderer::Info] rendering information
1473
+ */
1474
+ static VALUE Renderer_info(VALUE self)
1475
+ {
1476
+ SDL_RendererInfo info;
1477
+ HANDLE_ERROR(SDL_GetRendererInfo(Get_SDL_Renderer(self), &info));
1478
+ return RendererInfo_new(&info);
1479
+ }
1480
+
1481
+ /*
1482
+ * Get the blend mode used for drawing operations like
1483
+ * {#fill_rect} and {#draw_line}.
1484
+ *
1485
+ * For the blending modes, see [blending modes](#label-Blending+modes)
1486
+ *
1487
+ * @return [Integer]
1488
+ *
1489
+ * @see #draw_blend_mode=
1490
+ */
1491
+ static VALUE Renderer_draw_blend_mode(VALUE self)
1492
+ {
1493
+ SDL_BlendMode mode;
1494
+ HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &mode));
1495
+ return INT2FIX(mode);
1496
+ }
1497
+
1498
+ /*
1499
+ * @overload draw_blend_mode=(mode)
1500
+ * Set the blend mode used for drawing operations.
1501
+ *
1502
+ * This method effects the following methods.
1503
+ *
1504
+ * * {#draw_line}
1505
+ * * {#draw_point}
1506
+ * * {#draw_rect}
1507
+ * * {#fill_rect}
1508
+ * * {#clear}
1509
+ *
1510
+ * @param mode [Integer] the blending mode
1511
+ * @return mode
1512
+ *
1513
+ * @see #draw_blend_mode
1514
+ *
1515
+ */
1516
+ static VALUE Renderer_set_draw_blend_mode(VALUE self, VALUE mode)
1517
+ {
1518
+ HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), NUM2INT(mode)));
1519
+ return mode;
1520
+ }
1521
+
1522
+ /*
1523
+ * Get the clip rectangle for the current target.
1524
+ *
1525
+ * @return [SDL2::Rect] the current clip rectangle
1526
+ *
1527
+ */
1528
+ static VALUE Renderer_clip_rect(VALUE self)
1529
+ {
1530
+ VALUE rect = rb_obj_alloc(cRect);
1531
+ SDL_RenderGetClipRect(Get_SDL_Renderer(self), Get_SDL_Rect(rect));
1532
+ return rect;
1533
+ }
1534
+
1535
+ #if SDL_VERSION_ATLEAST(2,0,4)
1536
+ static VALUE Render_clip_enabled_p(VALUE self)
1537
+ {
1538
+ return INT2BOOL(SDL_RenderIsClipEnabled(Get_SDL_Renderer(self)));
1539
+ }
1540
+ #endif
1541
+
1542
+ static VALUE Renderer_logical_size(VALUE self)
1543
+ {
1544
+ int w, h;
1545
+ SDL_RenderGetLogicalSize(Get_SDL_Renderer(self), &w, &h);
1546
+ return rb_ary_new3(2, INT2FIX(w), INT2FIX(h));
1547
+ }
1548
+
1549
+ static VALUE Renderer_scale(VALUE self)
1550
+ {
1551
+ float scaleX, scaleY;
1552
+ SDL_RenderGetScale(Get_SDL_Renderer(self), &scaleX, &scaleY);
1553
+ return rb_ary_new3(2, DBL2NUM(scaleX), DBL2NUM(scaleY));
1554
+ }
1555
+
1556
+ static VALUE Renderer_viewport(VALUE self)
1557
+ {
1558
+ VALUE rect = rb_obj_alloc(cRect);
1559
+ SDL_RenderGetViewport(Get_SDL_Renderer(self), Get_SDL_Rect(rect));
1560
+ return rect;
1561
+ }
1562
+
1563
+ /*
1564
+ * Return true if the renderer supports render target.
1565
+ *
1566
+ * @see #render_target=
1567
+ */
1568
+ static VALUE Renderer_support_render_target_p(VALUE self)
1569
+ {
1570
+ return INT2BOOL(SDL_RenderTargetSupported(Get_SDL_Renderer(self)));
1571
+ }
1572
+
1573
+ static VALUE Renderer_output_size(VALUE self)
1574
+ {
1575
+ int w, h;
1576
+ HANDLE_ERROR(SDL_GetRendererOutputSize(Get_SDL_Renderer(self), &w, &h));
1577
+ return rb_ary_new3(2, INT2FIX(w), INT2FIX(h));
1578
+ }
1579
+
1580
+ /*
1581
+ * @overload render_target=(target)
1582
+ * Set a texture as the current render target.
1583
+ *
1584
+ * Some renderers have ability to render to a texture instead of a screen.
1585
+ * You can judge whether your renderer has this ability using
1586
+ * {#support_render_target?}.
1587
+ *
1588
+ * The target texture musbe be {#create_texture created} with the
1589
+ * SDL2::Texture::ACCESS_TARGET flag.
1590
+ *
1591
+ * @param [SDL2::Texture,nil] target the targeted texture, or nil
1592
+ * for the default render target(i.e. screen)
1593
+ *
1594
+ * @return [target]
1595
+ *
1596
+ * @see #render_target
1597
+ */
1598
+ static VALUE Renderer_set_render_target(VALUE self, VALUE target)
1599
+ {
1600
+ HANDLE_ERROR(SDL_SetRenderTarget(Get_SDL_Renderer(self),
1601
+ (target == Qnil) ? NULL : Get_SDL_Texture(target)));
1602
+ rb_iv_set(self, "render_target", target);
1603
+ return target;
1604
+ }
1605
+
1606
+ /*
1607
+ * Get the current render target.
1608
+ *
1609
+ * @return [SDL2::Texture] the current rendering target
1610
+ * @return [nil] for the default render target (i.e. screen)
1611
+ *
1612
+ * @see #render_target=
1613
+ * @see #support_render_target?
1614
+ */
1615
+ static VALUE Renderer_render_target(VALUE self)
1616
+ {
1617
+ return rb_iv_get(self, "render_target");
1618
+ }
1619
+
1620
+ /*
1621
+ * Reset the render target to the screen.
1622
+ *
1623
+ * @return [nil]
1624
+ */
1625
+ static VALUE Renderer_reset_render_target(VALUE self)
1626
+ {
1627
+ return Renderer_set_render_target(self, Qnil);
1628
+ }
1629
+
1630
+ /* @return [Hash<String=>Object>] (GC) debug information */
1631
+ static VALUE Renderer_debug_info(VALUE self)
1632
+ {
1633
+ Renderer* r = Get_Renderer(self);
1634
+ VALUE info = rb_hash_new();
1635
+ int num_active_textures = 0;
1636
+ int i;
1637
+ rb_hash_aset(info, rb_str_new2("destroy?"), INT2BOOL(r->renderer == NULL));
1638
+ rb_hash_aset(info, rb_str_new2("max_textures"), INT2NUM(r->max_textures));
1639
+ rb_hash_aset(info, rb_str_new2("num_textures"), INT2NUM(r->num_textures));
1640
+ for (i=0; i<r->num_textures; ++i)
1641
+ if (r->textures[i]->texture)
1642
+ ++num_active_textures;
1643
+ rb_hash_aset(info, rb_str_new2("num_active_textures"), INT2NUM(num_active_textures));
1644
+ rb_hash_aset(info, rb_str_new2("refcount"), INT2NUM(r->refcount));
1645
+
1646
+ return info;
1647
+ }
1648
+
1649
+ /*
1650
+ * Document-class: SDL2::Texture
1651
+ *
1652
+ * This class represents the texture associated with a renderer.
1653
+ *
1654
+ *
1655
+ * @!method destroy?
1656
+ * Return true if the texture is {#destroy destroyed}.
1657
+ */
1658
+
1659
+ /*
1660
+ * Destroy the texture and deallocate memory.
1661
+ *
1662
+ * @see #destroy?
1663
+ */
1664
+ static VALUE Texture_destroy(VALUE self)
1665
+ {
1666
+ Texture_destroy_internal(Get_Texture(self));
1667
+ return Qnil;
1668
+ }
1669
+
1670
+ /*
1671
+ * Get the blending mode of the texture.
1672
+ *
1673
+ * @return [Integer] blend mode
1674
+ *
1675
+ * @see #blend_mode=
1676
+ */
1677
+ static VALUE Texture_blend_mode(VALUE self)
1678
+ {
1679
+ SDL_BlendMode mode;
1680
+ HANDLE_ERROR(SDL_GetTextureBlendMode(Get_SDL_Texture(self), &mode));
1681
+ return INT2FIX(mode);
1682
+ }
1683
+
1684
+ /*
1685
+ * @overload blend_mode=(mode)
1686
+ * Set the blending model of the texture.
1687
+ *
1688
+ * @param mode [Integer] blending mode
1689
+ * @return [mode]
1690
+ *
1691
+ * @see #blend_mode
1692
+ */
1693
+ static VALUE Texture_set_blend_mode(VALUE self, VALUE mode)
1694
+ {
1695
+ HANDLE_ERROR(SDL_SetTextureBlendMode(Get_SDL_Texture(self), NUM2INT(mode)));
1696
+ return mode;
1697
+ }
1698
+
1699
+ /*
1700
+ * Get an additional alpha value used in render copy operations.
1701
+ *
1702
+ * @return [Integer] the current alpha value
1703
+ *
1704
+ * @see #alpha_mod=
1705
+ */
1706
+ static VALUE Texture_alpha_mod(VALUE self)
1707
+ {
1708
+ Uint8 alpha;
1709
+ HANDLE_ERROR(SDL_GetTextureAlphaMod(Get_SDL_Texture(self), &alpha));
1710
+ return INT2FIX(alpha);
1711
+ }
1712
+
1713
+ /*
1714
+ * @overload alpha_mod=(alpha)
1715
+ * Set an additional alpha value used in render copy operations.
1716
+ *
1717
+ * @param alpha [Integer] the alpha value multiplied into copy operation,
1718
+ * from 0 to 255
1719
+ * @return [alpha]
1720
+ *
1721
+ * @see #alpha_mod
1722
+ */
1723
+ static VALUE Texture_set_alpha_mod(VALUE self, VALUE alpha)
1724
+ {
1725
+ HANDLE_ERROR(SDL_SetTextureAlphaMod(Get_SDL_Texture(self), NUM2UCHAR(alpha)));
1726
+ return alpha;
1727
+ }
1728
+
1729
+ /*
1730
+ * Get an additional color value used in render copy operations.
1731
+ *
1732
+ * @return [[Integer, Integer, Integer]] the current red, green, and blue
1733
+ * color value.
1734
+ */
1735
+ static VALUE Texture_color_mod(VALUE self)
1736
+ {
1737
+ Uint8 r, g, b;
1738
+ HANDLE_ERROR(SDL_GetTextureColorMod(Get_SDL_Texture(self), &r, &g, &b));
1739
+ return rb_ary_new3(3, INT2FIX(r), INT2FIX(g), INT2FIX(b));
1740
+ }
1741
+
1742
+ /*
1743
+ * @overload color_mod=(rgb)
1744
+ * Set an additional color value used in render copy operations.
1745
+ *
1746
+ * @param rgb [[Integer, Integer, Integer]] the red, green, and blue
1747
+ * color value multiplied into copy operations.
1748
+ * @return [rgb]
1749
+ */
1750
+ static VALUE Texture_set_color_mod(VALUE self, VALUE rgb)
1751
+ {
1752
+ SDL_Color color = Array_to_SDL_Color(rgb);
1753
+ HANDLE_ERROR(SDL_SetTextureColorMod(Get_SDL_Texture(self),
1754
+ color.r, color.g, color.b));
1755
+ return rgb;
1756
+ }
1757
+
1758
+ /*
1759
+ * Get the format of the texture.
1760
+ *
1761
+ * @return [SDL2::PixelFormat]
1762
+ */
1763
+ static VALUE Texture_format(VALUE self)
1764
+ {
1765
+ Uint32 format;
1766
+ HANDLE_ERROR(SDL_QueryTexture(Get_SDL_Texture(self), &format, NULL, NULL, NULL));
1767
+ return PixelFormat_new(format);
1768
+ }
1769
+
1770
+ /*
1771
+ * Get the access pattern allowed for the texture.
1772
+ *
1773
+ * The return value is one of the following:
1774
+ *
1775
+ * * SDL2::Texture::ACCESS_STATIC - changes rarely, not lockable
1776
+ * * SDL2::Texture::ACCESS_STREAMING - changes frequently, lockable
1777
+ * * SDL2::Texture::ACCESS_TARGET - can be used as a render target
1778
+ *
1779
+ * @return [Integer]
1780
+ *
1781
+ * @see SDL2::Renderer#create_texture
1782
+ */
1783
+ static VALUE Texture_access_pattern(VALUE self)
1784
+ {
1785
+ int access;
1786
+ HANDLE_ERROR(SDL_QueryTexture(Get_SDL_Texture(self), NULL, &access, NULL, NULL));
1787
+ return INT2FIX(access);
1788
+ }
1789
+
1790
+ /*
1791
+ * Get the width of the texture.
1792
+ *
1793
+ * @return [Integer]
1794
+ *
1795
+ * @see SDL2::Renderer#create_texture
1796
+ */
1797
+ static VALUE Texture_w(VALUE self)
1798
+ {
1799
+ int w;
1800
+ HANDLE_ERROR(SDL_QueryTexture(Get_SDL_Texture(self), NULL, NULL, &w, NULL));
1801
+ return INT2FIX(w);
1802
+ }
1803
+
1804
+ /*
1805
+ * Get the height of the texture.
1806
+ *
1807
+ * @return [Integer]
1808
+ *
1809
+ * @see SDL2::Renderer#create_texture
1810
+ */
1811
+ static VALUE Texture_h(VALUE self)
1812
+ {
1813
+ int h;
1814
+ HANDLE_ERROR(SDL_QueryTexture(Get_SDL_Texture(self), NULL, NULL, NULL, &h));
1815
+ return INT2FIX(h);
1816
+ }
1817
+
1818
+ /* @return [String] inspection string */
1819
+ static VALUE Texture_inspect(VALUE self)
1820
+ {
1821
+ Texture* t = Get_Texture(self);
1822
+ Uint32 format;
1823
+ int access, w, h;
1824
+ if (!t->texture)
1825
+ return rb_sprintf("<%s: (destroyed)>", rb_obj_classname(self));
1826
+
1827
+ HANDLE_ERROR(SDL_QueryTexture(t->texture, &format, &access, &w, &h));
1828
+ return rb_sprintf("<%s:%p format=%s access=%d w=%d h=%d>",
1829
+ rb_obj_classname(self), (void*)self, SDL_GetPixelFormatName(format),
1830
+ access, w, h);
1831
+ }
1832
+
1833
+ /* @return [Hash<String=>Object>] (GC) debugging information */
1834
+ static VALUE Texture_debug_info(VALUE self)
1835
+ {
1836
+ Texture* t = Get_Texture(self);
1837
+ VALUE info = rb_hash_new();
1838
+ rb_hash_aset(info, rb_str_new2("destroy?"), INT2BOOL(t->texture == NULL));
1839
+ rb_hash_aset(info, rb_str_new2("refcount"), INT2NUM(t->refcount));
1840
+ return info;
1841
+ }
1842
+
1843
+ /*
1844
+ * Document-class: SDL2::Surface
1845
+ *
1846
+ * This class represents bitmap images (collection of pixels).
1847
+ *
1848
+ * Normally in SDL2, this class is not used for drawing a image
1849
+ * on a window. {SDL2::Texture} is used for the purpose.
1850
+ *
1851
+ * Mainly this class is for compatibility with SDL1, but the class
1852
+ * is useful for simple pixel manipulation.
1853
+ * For example, {SDL2::TTF} can create only surfaces, not textures.
1854
+ * You can convert a surface to texture with
1855
+ * {SDL2::Renderer#create_texture_from}.
1856
+ *
1857
+ * @!method destroy?
1858
+ * Return true if the surface is {#destroy destroyed}.
1859
+ *
1860
+ */
1861
+
1862
+ /*
1863
+ * @overload load_bmp(path)
1864
+ * Load a surface from bmp file.
1865
+ *
1866
+ * @param path [String] bmp file path
1867
+ * @return [SDL2::Surface]
1868
+ * @raise [SDL2::Error] raised when an error occurs.
1869
+ * For example, if there is no file or the file file
1870
+ * format is not Windows BMP.
1871
+ *
1872
+ */
1873
+ static VALUE Surface_s_load_bmp(VALUE self, VALUE fname)
1874
+ {
1875
+ SDL_Surface* surface = SDL_LoadBMP(StringValueCStr(fname));
1876
+
1877
+ if (surface == NULL)
1878
+ HANDLE_ERROR(-1);
1879
+
1880
+ return Surface_new(surface);
1881
+ }
1882
+
1883
+ /*
1884
+ * @overload from_string(string, width, heigth, depth, pitch=nil, rmask=nil, gmask=nil, bmask=nil, amask=nil)
1885
+ *
1886
+ * Create a RGB surface from pixel data as String object.
1887
+ *
1888
+ * If rmask, gmask, bmask are omitted, the default masks are used.
1889
+ * If amask is omitted, alpha mask is considered to be zero.
1890
+ *
1891
+ * @param string [String] the pixel data
1892
+ * @param width [Integer] the width of the creating surface
1893
+ * @param height [Integer] the height of the creating surface
1894
+ * @param depth [Integer] the color depth (in bits) of the creating surface
1895
+ * @param pitch [Integer] the number of bytes of one scanline
1896
+ * if this argument is omitted, width*depth/8 is used.
1897
+ * @param rmask [Integer] the red mask of a pixel
1898
+ * @param gmask [Integer] the green mask of a pixel
1899
+ * @param bmask [Integer] the blue mask of a pixel
1900
+ * @param amask [Integer] the alpha mask of a pixel
1901
+ * @return [SDL2::Surface] a new surface
1902
+ * @raise [SDL2::Error] raised when an error occurs in C SDL library
1903
+ *
1904
+ */
1905
+ static VALUE Surface_s_from_string(int argc, VALUE* argv, VALUE self)
1906
+ {
1907
+ VALUE string, width, height, depth, pitch, Rmask, Gmask, Bmask, Amask;
1908
+ int w, h, d, p, r, g, b, a;
1909
+ SDL_Surface* surface;
1910
+ void* pixels;
1911
+ Surface* s;
1912
+
1913
+ rb_scan_args(argc, argv, "45", &string, &width, &height, &depth,
1914
+ &pitch, &Rmask, &Gmask, &Bmask, &Amask);
1915
+ StringValue(string);
1916
+ w = NUM2INT(width);
1917
+ h = NUM2INT(height);
1918
+ d = NUM2INT(depth);
1919
+ p = (pitch == Qnil) ? d*w/8 : NUM2INT(pitch);
1920
+ r = (Rmask == Qnil) ? 0 : NUM2UINT(Rmask);
1921
+ g = (Gmask == Qnil) ? 0 : NUM2UINT(Gmask);
1922
+ b = (Bmask == Qnil) ? 0 : NUM2UINT(Bmask);
1923
+ a = (Amask == Qnil) ? 0 : NUM2UINT(Amask);
1924
+
1925
+ if (RSTRING_LEN(string) < p*h)
1926
+ rb_raise(rb_eArgError, "String too short");
1927
+ if (p < d*w/8 )
1928
+ rb_raise(rb_eArgError, "pitch too small");
1929
+
1930
+ pixels = ruby_xmalloc(RSTRING_LEN(string));
1931
+ memcpy(pixels, RSTRING_PTR(string), RSTRING_LEN(string));
1932
+ surface = SDL_CreateRGBSurfaceFrom(pixels, w, h, d, p, r, g, b, a);
1933
+ if (!surface)
1934
+ SDL_ERROR();
1935
+
1936
+ RB_GC_GUARD(string);
1937
+
1938
+ s = ALLOC(Surface);
1939
+ s->surface = surface;
1940
+ s->need_to_free_pixels = 1;
1941
+ return Data_Wrap_Struct(cSurface, 0, Surface_free, s);
1942
+ }
1943
+
1944
+ /*
1945
+ * Destroy the surface and deallocate the memory for pixels.
1946
+ *
1947
+ * @return [nil]
1948
+ * @see #destroy?
1949
+ */
1950
+ static VALUE Surface_destroy(VALUE self)
1951
+ {
1952
+ Surface* s = Get_Surface(self);
1953
+ if (s->need_to_free_pixels)
1954
+ free(s->surface->pixels);
1955
+ s->need_to_free_pixels = 0;
1956
+ if (s->surface)
1957
+ SDL_FreeSurface(s->surface);
1958
+ s->surface = NULL;
1959
+ return Qnil;
1960
+ }
1961
+
1962
+ /*
1963
+ * Get the blending mode of the surface used for blit operations.
1964
+ *
1965
+ * @return [Integer]
1966
+ * @see #blend_mode=
1967
+ */
1968
+ static VALUE Surface_blend_mode(VALUE self)
1969
+ {
1970
+ SDL_BlendMode mode;
1971
+ HANDLE_ERROR(SDL_GetSurfaceBlendMode(Get_SDL_Surface(self), &mode));
1972
+ return INT2FIX(mode);
1973
+ }
1974
+
1975
+ /*
1976
+ * @overload blend_mode=(mode)
1977
+ * Set the blending mode of the surface used for blit operations.
1978
+ *
1979
+ * @param mode [Integer] the blending mode
1980
+ * @return [mode]
1981
+ * @see #blend_mode
1982
+ */
1983
+ static VALUE Surface_set_blend_mode(VALUE self, VALUE mode)
1984
+ {
1985
+ HANDLE_ERROR(SDL_SetSurfaceBlendMode(Get_SDL_Surface(self), NUM2INT(mode)));
1986
+ return mode;
1987
+ }
1988
+
1989
+ /*
1990
+ * Return true if the surface need to lock when you get access to the
1991
+ * pixel data of the surface.
1992
+ *
1993
+ * @see #lock
1994
+ */
1995
+ static VALUE Surface_must_lock_p(VALUE self)
1996
+ {
1997
+ return INT2BOOL(SDL_MUSTLOCK(Get_SDL_Surface(self)));
1998
+ }
1999
+
2000
+ /*
2001
+ * Lock the surface.
2002
+ *
2003
+ * @return [nil]
2004
+ *
2005
+ * @see #unlock
2006
+ * @see #must_lock?
2007
+ */
2008
+ static VALUE Surface_lock(VALUE self)
2009
+ {
2010
+ HANDLE_ERROR(SDL_LockSurface(Get_SDL_Surface(self)));
2011
+ return Qnil;
2012
+ }
2013
+
2014
+ /*
2015
+ * Unlock the surface.
2016
+ *
2017
+ * @return [nil]
2018
+ *
2019
+ * @see #lock
2020
+ */
2021
+ static VALUE Surface_unlock(VALUE self)
2022
+ {
2023
+ SDL_UnlockSurface(Get_SDL_Surface(self));
2024
+ return Qnil;
2025
+ }
2026
+
2027
+ /*
2028
+ * @overload pixel(x, y)
2029
+ * Get a pixel data at (**x**, **y**)
2030
+ *
2031
+ * @param x [Integer] the x coordinate
2032
+ * @param y [Integer] the y coordinate
2033
+ * @return [Integer] pixel data
2034
+ *
2035
+ * @see #pixel_color
2036
+ *
2037
+ */
2038
+ static VALUE Surface_pixel(VALUE self, VALUE x_coord, VALUE y_coord)
2039
+ {
2040
+ int x = NUM2INT(x_coord);
2041
+ int y = NUM2INT(y_coord);
2042
+ SDL_Surface* surface = Get_SDL_Surface(self);
2043
+ int offset;
2044
+ Uint32 pixel = 0;
2045
+ int i;
2046
+
2047
+ if (x < 0 || x >= surface->w || y < 0 || y >= surface->h)
2048
+ rb_raise(rb_eArgError, "(%d, %d) out of range for %dx%d",
2049
+ x, y, surface->w, surface->h);
2050
+ offset = surface->pitch * y + surface->format->BytesPerPixel * x;
2051
+ for (i=0; i<surface->format->BytesPerPixel; ++i) {
2052
+ pixel += *((Uint8*)surface->pixels + offset + i) << (8*i);
2053
+ }
2054
+
2055
+ return UINT2NUM(SDL_SwapLE32(pixel));
2056
+ }
2057
+
2058
+ /*
2059
+ * Get all pixel data of the surface as a string.
2060
+ *
2061
+ * @return [String]
2062
+ *
2063
+ */
2064
+ static VALUE Surface_pixels(VALUE self)
2065
+ {
2066
+ SDL_Surface* surface = Get_SDL_Surface(self);
2067
+ int size = surface->h * surface->pitch;
2068
+ return rb_str_new(surface->pixels, size);
2069
+ }
2070
+
2071
+ /*
2072
+ * Get the pitch (bytes per horizontal line) of the surface.
2073
+ *
2074
+ * @return [Integer]
2075
+ */
2076
+ static VALUE Surface_pitch(VALUE self)
2077
+ {
2078
+ return UINT2NUM(Get_SDL_Surface(self)->pitch);
2079
+ }
2080
+
2081
+ /*
2082
+ * Get bits per pixel of the surface.
2083
+ *
2084
+ * @return [Integer]
2085
+ */
2086
+ static VALUE Surface_bits_per_pixel(VALUE self)
2087
+ {
2088
+ return UCHAR2NUM(Get_SDL_Surface(self)->format->BitsPerPixel);
2089
+ }
2090
+
2091
+ /*
2092
+ * Get bytes per pixel of the surface.
2093
+ *
2094
+ * @return [Integer]
2095
+ */
2096
+ static VALUE Surface_bytes_per_pixel(VALUE self)
2097
+ {
2098
+ return UCHAR2NUM(Get_SDL_Surface(self)->format->BytesPerPixel);
2099
+ }
2100
+
2101
+ /*
2102
+ * @overload pixel_color(x, y)
2103
+ * Get the pixel color (r,g,b and a) at (**x**, **y**) of the surface.
2104
+ *
2105
+ * @param x [Integer] the x coordinate
2106
+ * @param y [Integer] the y coordinate
2107
+ * @return [[Integer, Integer, Integer, Integer]]
2108
+ * the red, green, blue, and alpha component of the specified pixel.
2109
+ *
2110
+ */
2111
+ static VALUE Surface_pixel_color(VALUE self, VALUE x, VALUE y)
2112
+ {
2113
+ Uint32 pixel = NUM2UINT(Surface_pixel(self, x, y));
2114
+ SDL_Surface* surface = Get_SDL_Surface(self);
2115
+ Uint8 r, g, b, a;
2116
+ SDL_GetRGBA(pixel, surface->format, &r, &g, &b, &a);
2117
+
2118
+ return rb_ary_new3(4, UCHAR2NUM(r), UCHAR2NUM(g), UCHAR2NUM(b), UCHAR2NUM(a));
2119
+ }
2120
+
2121
+ static Uint32 pixel_value(VALUE val, SDL_PixelFormat* format)
2122
+ {
2123
+ if (RTEST(rb_funcall(val, rb_intern("integer?"), 0, 0))) {
2124
+ return NUM2UINT(val);
2125
+ } else {
2126
+ long len;
2127
+ Uint8 r, g, b, a;
2128
+ Check_Type(val, T_ARRAY);
2129
+ len = RARRAY_LEN(val);
2130
+ if (len == 3 || len == 4) {
2131
+ r = NUM2UCHAR(rb_ary_entry(val, 0));
2132
+ g = NUM2UCHAR(rb_ary_entry(val, 1));
2133
+ b = NUM2UCHAR(rb_ary_entry(val, 2));
2134
+ if (len == 3)
2135
+ a = 255;
2136
+ else
2137
+ a = NUM2UCHAR(rb_ary_entry(val, 3));
2138
+ return SDL_MapRGBA(format, r, g, b, a);
2139
+ } else {
2140
+ rb_raise(rb_eArgError, "Wrong length of array (%ld for 3..4)", len);
2141
+ }
2142
+ }
2143
+ return 0;
2144
+ }
2145
+
2146
+ /*
2147
+ * Unset the color key of the surface.
2148
+ *
2149
+ * @return [nil]
2150
+ *
2151
+ * @see #color_key=
2152
+ */
2153
+ static VALUE Surface_unset_color_key(VALUE self)
2154
+ {
2155
+ HANDLE_ERROR(SDL_SetColorKey(Get_SDL_Surface(self), SDL_FALSE, 0));
2156
+ return Qnil;
2157
+ }
2158
+
2159
+ /*
2160
+ * @overload color_key=(key)
2161
+ * Set the color key of the surface
2162
+ *
2163
+ * @param key [Integer, Array<Integer>]
2164
+ * the color key, pixel value (see {#pixel}) or pixel color (array of
2165
+ * three or four integer elements).
2166
+ *
2167
+ * @return [key]
2168
+ *
2169
+ * @see #color_key
2170
+ * @see #unset_color_key
2171
+ */
2172
+ static VALUE Surface_set_color_key(VALUE self, VALUE key)
2173
+ {
2174
+ SDL_Surface* surface = Get_SDL_Surface(self);
2175
+ if (key == Qnil)
2176
+ return Surface_unset_color_key(self);
2177
+
2178
+ HANDLE_ERROR(SDL_SetColorKey(surface, SDL_TRUE, pixel_value(key, surface->format)));
2179
+
2180
+ return key;
2181
+ }
2182
+
2183
+ /*
2184
+ * Get the color key of the surface
2185
+ *
2186
+ * @return [Integer] the color key, as pixel value (see {#pixel})
2187
+ *
2188
+ * @see #color_key=
2189
+ * @see #unset_color_key
2190
+ */
2191
+ static VALUE Surface_color_key(VALUE self)
2192
+ {
2193
+ Uint32 key;
2194
+ if (SDL_GetColorKey(Get_SDL_Surface(self), &key) < 0)
2195
+ return Qnil;
2196
+ else
2197
+ return UINT2NUM(key);
2198
+ }
2199
+
2200
+ /*
2201
+ * Get the width of the surface.
2202
+ *
2203
+ * @return [Integer]
2204
+ */
2205
+ static VALUE Surface_w(VALUE self)
2206
+ {
2207
+ return INT2NUM(Get_SDL_Surface(self)->w);
2208
+ }
2209
+
2210
+ /*
2211
+ * Get the height of the surface.
2212
+ *
2213
+ * @return [Integer]
2214
+ */
2215
+ static VALUE Surface_h(VALUE self)
2216
+ {
2217
+ return INT2NUM(Get_SDL_Surface(self)->h);
2218
+ }
2219
+
2220
+
2221
+ /*
2222
+ * @overload blit(src, srcrect, dst, dstrect)
2223
+ * Perform a fast blit from **src** surface to **dst** surface.
2224
+ *
2225
+ * @param src [SDL2::Surface] the source surface
2226
+ * @param srcrect [SDL2::Rect,nil] the region in the source surface,
2227
+ * if nil is given, the whole source is used
2228
+ * @param dst [SDL2::Surface] the destination surface
2229
+ * @param dstrect [SDL2::Rect,nil] the region in the destination surface
2230
+ * if nil is given, the source image is copied to (0, 0) on
2231
+ * the destination surface.
2232
+ * **dstrect** is changed by this method to store the
2233
+ * actually copied region (since the surface has clipping functionality,
2234
+ * actually copied region may be different from given **dstrect**).
2235
+ * @return [nil]
2236
+ */
2237
+ static VALUE Surface_s_blit(VALUE self, VALUE src, VALUE srcrect, VALUE dst, VALUE dstrect)
2238
+ {
2239
+ HANDLE_ERROR(SDL_BlitSurface(Get_SDL_Surface(src),
2240
+ Get_SDL_Rect_or_NULL(srcrect),
2241
+ Get_SDL_Surface(dst),
2242
+ Get_SDL_Rect_or_NULL(dstrect)));
2243
+ return Qnil;
2244
+ }
2245
+
2246
+ /*
2247
+ * @overload new(width, height, depth)
2248
+ * @overload new(width, height, depth, amask)
2249
+ * @overload new(width, heigth, depth, rmask, gmask, bmask, amask)
2250
+ *
2251
+ * @param width [Integer]
2252
+ * @return [SDL2::Surface]
2253
+ */
2254
+ static VALUE Surface_s_new(int argc, VALUE* argv, VALUE self)
2255
+ {
2256
+ VALUE width, height, depth;
2257
+ Uint32 Rmask, Gmask, Bmask, Amask;
2258
+ SDL_Surface * surface;
2259
+
2260
+ if (argc == 3) {
2261
+ rb_scan_args(argc, argv, "30", &width, &height, &depth);
2262
+ Rmask = Gmask = Bmask = Amask = 0;
2263
+ } else if (argc == 7) {
2264
+ VALUE rm, gm, bm, am;
2265
+ rb_scan_args(argc, argv, "70", &width, &height, &depth, &rm, &gm, &bm, &am);
2266
+ Rmask = NUM2UINT(rm); Gmask = NUM2UINT(gm);
2267
+ Bmask = NUM2UINT(bm); Amask = NUM2UINT(am);
2268
+ } else {
2269
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 4 or 7)", argc);
2270
+ }
2271
+
2272
+ surface = SDL_CreateRGBSurface(0, NUM2INT(width), NUM2INT(height), NUM2INT(depth),
2273
+ Rmask, Gmask, Bmask, Amask);
2274
+ if (!surface)
2275
+ SDL_ERROR();
2276
+
2277
+ return Surface_new(surface);
2278
+ }
2279
+
2280
+ #define FIELD_ACCESSOR(classname, typename, field) \
2281
+ static VALUE classname##_##field(VALUE self) \
2282
+ { \
2283
+ typename* r; Data_Get_Struct(self, typename, r); \
2284
+ return INT2NUM(r->field); \
2285
+ } \
2286
+ static VALUE classname##_set_##field(VALUE self, VALUE val) \
2287
+ { \
2288
+ typename* r; Data_Get_Struct(self, typename, r); \
2289
+ r->field = NUM2INT(val); return val; \
2290
+ }
2291
+
2292
+
2293
+ /* Document-class: SDL2::Rect
2294
+ *
2295
+ * This class represents a rectangle in SDL2.
2296
+ *
2297
+ * Any rectanle is represented by four attributes x, y, w, and h,
2298
+ * and these four attributes must be integer.
2299
+ *
2300
+ * @!attribute [rw] x
2301
+ * X coordiante of the left-top point of the rectangle
2302
+ * @return [Integer]
2303
+ *
2304
+ * @!attribute [rw] y
2305
+ * Y coordiante of the left-top point of the rectangle
2306
+ * @return [Integer]
2307
+ *
2308
+ * @!attribute [rw] w
2309
+ * Width of the rectangle
2310
+ * @return [Integer]
2311
+ *
2312
+ * @!attribute [rw] h
2313
+ * Height of the rectangle
2314
+ * @return [Integer]
2315
+ *
2316
+ * @!method self.[](*args)
2317
+ * Alias of new. See {#initialize}.
2318
+ * @return [SDL2::Rect]
2319
+ */
2320
+ static VALUE Rect_s_allocate(VALUE klass)
2321
+ {
2322
+ SDL_Rect* rect = ALLOC(SDL_Rect);
2323
+ rect->x = rect->y = rect->w = rect->h = 0;
2324
+
2325
+ return Data_Wrap_Struct(cRect, 0, free, rect);
2326
+ }
2327
+
2328
+ /*
2329
+ * Create a new SDL2::Rect object
2330
+ *
2331
+ * @return [SDL2::Rect]
2332
+ *
2333
+ * @overload initialze(x, y, w, h)
2334
+ * Create a new SDL2::Rect object
2335
+ *
2336
+ * @param x [Integer] X coordiante of the left-top point of the rectangle
2337
+ * @param y [Integer] Y coordiante of the left-top point of the rectangle
2338
+ * @param w [Integer] Width of the rectangle
2339
+ * @param h [Integer] Height of the rectangle
2340
+ *
2341
+ * @overload initialize
2342
+ * Create a new SDL2::Rect object whose x, w, w, and h are all
2343
+ * zero.
2344
+ */
2345
+ static VALUE Rect_initialize(int argc, VALUE* argv, VALUE self)
2346
+ {
2347
+ VALUE x, y, w, h;
2348
+ rb_scan_args(argc, argv, "04", &x, &y, &w, &h);
2349
+ if (argc == 0) {
2350
+ /* do nothing*/
2351
+ } else if (argc == 4) {
2352
+ SDL_Rect* rect;
2353
+ Data_Get_Struct(self, SDL_Rect, rect);
2354
+ rect->x = NUM2INT(x); rect->y = NUM2INT(y);
2355
+ rect->w = NUM2INT(w); rect->h = NUM2INT(h);
2356
+ } else {
2357
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 or 4)", argc);
2358
+ }
2359
+ return Qnil;
2360
+ }
2361
+
2362
+ /*
2363
+ * Inspection string for debug
2364
+ * @return [String]
2365
+ */
2366
+ static VALUE Rect_inspect(VALUE self)
2367
+ {
2368
+ SDL_Rect* rect = Get_SDL_Rect(self);
2369
+ return rb_sprintf("<SDL2::Rect: x=%d y=%d w=%d h=%d>",
2370
+ rect->x, rect->y, rect->w, rect->h);
2371
+ }
2372
+
2373
+ FIELD_ACCESSOR(Rect, SDL_Rect, x);
2374
+ FIELD_ACCESSOR(Rect, SDL_Rect, y);
2375
+ FIELD_ACCESSOR(Rect, SDL_Rect, w);
2376
+ FIELD_ACCESSOR(Rect, SDL_Rect, h);
2377
+
2378
+ /*
2379
+ * @overload intersection(other)
2380
+ * Returns the intersection rect of self and other.
2381
+ *
2382
+ * If there is no intersection, returns nil.
2383
+ *
2384
+ * @return [SDL2::Rect, nil]
2385
+ * @param [SDL2::Rect] other rectangle
2386
+ */
2387
+ static VALUE Rect_intersection(VALUE self, VALUE other)
2388
+ {
2389
+ VALUE result = Rect_s_allocate(cRect);
2390
+ if (SDL_IntersectRect(Get_SDL_Rect(self), Get_SDL_Rect(other), Get_SDL_Rect(result))) {
2391
+ return result;
2392
+ } else {
2393
+ return Qnil;
2394
+ }
2395
+ }
2396
+
2397
+ /*
2398
+ * @overload union(other)
2399
+ * Returns the minimal rect containing self and other
2400
+ *
2401
+ * @return [SDL2::Rect]
2402
+ * @param [SDL2::Rect] other rectangle
2403
+ */
2404
+ static VALUE Rect_union(VALUE self, VALUE other)
2405
+ {
2406
+ VALUE result = Rect_s_allocate(cRect);
2407
+ SDL_UnionRect(Get_SDL_Rect(self), Get_SDL_Rect(other), Get_SDL_Rect(result));
2408
+ return result;
2409
+ }
2410
+
2411
+ /*
2412
+ * Document-class: SDL2::Point
2413
+ *
2414
+ * This class represents a point in SDL library.
2415
+ * Some method requires this method.
2416
+ *
2417
+ * @!attribute [rw] x
2418
+ * X coordiante of the point.
2419
+ * @return [Integer]
2420
+ *
2421
+ * @!attribute [rw] y
2422
+ * Y coordiante of the point.
2423
+ * @return [Integer]
2424
+ */
2425
+ static VALUE Point_s_allocate(VALUE klass)
2426
+ {
2427
+ SDL_Point* point;
2428
+ return Data_Make_Struct(klass, SDL_Point, 0, free, point);
2429
+ }
2430
+
2431
+ /*
2432
+ * Create a new point object.
2433
+ *
2434
+ * @overload initialize(x, y)
2435
+ * @param x the x coordinate of the point
2436
+ * @param y the y coordinate of the point
2437
+ *
2438
+ * @overload initialize
2439
+ * x and y of the created point object are initialized by 0
2440
+ *
2441
+ * @return [SDL2::Point]
2442
+ *
2443
+ */
2444
+ static VALUE Point_initialize(int argc, VALUE* argv, VALUE self)
2445
+ {
2446
+ VALUE x, y;
2447
+ SDL_Point* point = Get_SDL_Point(self);
2448
+ rb_scan_args(argc, argv, "02", &x, &y);
2449
+ point->x = (x == Qnil) ? 0 : NUM2INT(x);
2450
+ point->y = (y == Qnil) ? 0 : NUM2INT(y);
2451
+ return Qnil;
2452
+ }
2453
+
2454
+ /*
2455
+ * Return inspection string.
2456
+ * @return [String]
2457
+ */
2458
+ static VALUE Point_inspect(VALUE self)
2459
+ {
2460
+ SDL_Point* point = Get_SDL_Point(self);
2461
+ return rb_sprintf("<SDL2::Point x=%d y=%d>", point->x, point->y);
2462
+ }
2463
+
2464
+ FIELD_ACCESSOR(Point, SDL_Point, x);
2465
+ FIELD_ACCESSOR(Point, SDL_Point, y);
2466
+
2467
+ static VALUE PixelForamt_initialize(VALUE self, VALUE format)
2468
+ {
2469
+ rb_iv_set(self, "@format", format);
2470
+ return Qnil;
2471
+ }
2472
+
2473
+ static VALUE PixelFormat_type(VALUE self)
2474
+ {
2475
+ return UINT2NUM(SDL_PIXELTYPE(NUM2UINT(rb_iv_get(self, "@format"))));
2476
+ }
2477
+
2478
+ #define PIXELFORMAT_ATTR_READER(field, extractor, c2ruby) \
2479
+ static VALUE PixelFormat_##field(VALUE self) \
2480
+ { \
2481
+ return c2ruby(extractor(NUM2UINT(rb_iv_get(self, "@format")))); \
2482
+ }
2483
+
2484
+ PIXELFORMAT_ATTR_READER(name, SDL_GetPixelFormatName, utf8str_new_cstr);
2485
+ PIXELFORMAT_ATTR_READER(order, SDL_PIXELORDER, UINT2NUM);
2486
+ PIXELFORMAT_ATTR_READER(layout, SDL_PIXELLAYOUT, UINT2NUM);
2487
+ PIXELFORMAT_ATTR_READER(bits_per_pixel, SDL_BITSPERPIXEL, INT2NUM);
2488
+ PIXELFORMAT_ATTR_READER(bytes_per_pixel, SDL_BYTESPERPIXEL, INT2NUM);
2489
+ PIXELFORMAT_ATTR_READER(indexed_p, SDL_ISPIXELFORMAT_INDEXED, INT2BOOL);
2490
+ PIXELFORMAT_ATTR_READER(alpha_p, SDL_ISPIXELFORMAT_ALPHA, INT2BOOL);
2491
+ PIXELFORMAT_ATTR_READER(fourcc_p, SDL_ISPIXELFORMAT_FOURCC, INT2BOOL);
2492
+
2493
+ static VALUE PixelFormat_eq(VALUE self, VALUE other)
2494
+ {
2495
+ if (!rb_obj_is_kind_of(other, cPixelFormat))
2496
+ return Qfalse;
2497
+
2498
+ return INT2BOOL(rb_iv_get(self, "@format") == rb_iv_get(other, "@format"));
2499
+ }
2500
+
2501
+ static VALUE PixelFormat_inspect(VALUE self)
2502
+ {
2503
+ Uint32 format = NUM2UINT(rb_iv_get(self, "@format"));
2504
+ return rb_sprintf("<%s: %s type=%d order=%d layout=%d"
2505
+ " bits=%d bytes=%d indexed=%s alpha=%s fourcc=%s>",
2506
+ rb_obj_classname(self),
2507
+ SDL_GetPixelFormatName(format),
2508
+ SDL_PIXELTYPE(format), SDL_PIXELORDER(format), SDL_PIXELLAYOUT(format),
2509
+ SDL_BITSPERPIXEL(format), SDL_BYTESPERPIXEL(format),
2510
+ INT2BOOLCSTR(SDL_ISPIXELFORMAT_INDEXED(format)),
2511
+ INT2BOOLCSTR(SDL_ISPIXELFORMAT_ALPHA(format)),
2512
+ INT2BOOLCSTR(SDL_ISPIXELFORMAT_FOURCC(format)));
2513
+ }
2514
+
2515
+ static VALUE ScreenSaver_enable(VALUE self)
2516
+ {
2517
+ SDL_EnableScreenSaver();
2518
+ return Qnil;
2519
+ }
2520
+
2521
+ static VALUE ScreenSaver_disable(VALUE self)
2522
+ {
2523
+ SDL_DisableScreenSaver();
2524
+ return Qnil;
2525
+ }
2526
+
2527
+ static VALUE ScreenSaver_enabled_p(VALUE self)
2528
+ {
2529
+ return INT2BOOL(SDL_IsScreenSaverEnabled());
2530
+ }
2531
+
2532
+ /*
2533
+ define(`DEFINE_C_ACCESSOR',`rb_define_method($2, "$3", $1_$3, 0);
2534
+ rb_define_method($2, "$3=", $1_set_$3, 1)')
2535
+ */
2536
+
2537
+ void rubysdl2_init_video(void)
2538
+ {
2539
+ rb_define_module_function(mSDL2, "video_drivers", SDL2_s_video_drivers, 0);
2540
+ rb_define_module_function(mSDL2, "current_video_driver", SDL2_s_current_video_driver, 0);
2541
+ rb_define_module_function(mSDL2, "video_init", SDL2_s_video_init, 1);
2542
+
2543
+ cWindow = rb_define_class_under(mSDL2, "Window", rb_cObject);
2544
+
2545
+ rb_undef_alloc_func(cWindow);
2546
+ rb_define_singleton_method(cWindow, "create", Window_s_create, 6);
2547
+ rb_define_singleton_method(cWindow, "all_windows", Window_s_all_windows, 0);
2548
+ rb_define_singleton_method(cWindow, "find_by_id", Window_s_find_by_id, 1);
2549
+ rb_define_method(cWindow, "destroy?", Window_destroy_p, 0);
2550
+ rb_define_method(cWindow, "destroy", Window_destroy, 0);
2551
+ rb_define_method(cWindow, "create_renderer", Window_create_renderer, 2);
2552
+ rb_define_method(cWindow, "renderer", Window_renderer, 0);
2553
+ rb_define_method(cWindow, "window_id", Window_window_id, 0);
2554
+ rb_define_method(cWindow, "inspect", Window_inspect, 0);
2555
+ rb_define_method(cWindow, "display_mode", Window_display_mode, 0);
2556
+ rb_define_method(cWindow, "display", Window_display, 0);
2557
+ rb_define_method(cWindow, "debug_info", Window_debug_info, 0);
2558
+ DEFINE_C_ACCESSOR(Window, cWindow, brightness);
2559
+ rb_define_method(cWindow, "flags", Window_flags, 0);
2560
+ rb_define_method(cWindow, "gamma_ramp", Window_gamma_ramp, 0);
2561
+ rb_define_method(cWindow, "input_is_grabbed?", Window_input_is_grabbed_p, 0);
2562
+ rb_define_method(cWindow, "input_is_grabbed=", Window_set_input_is_grabbed, 1);
2563
+ DEFINE_C_ACCESSOR(Window, cWindow, maximum_size);
2564
+ DEFINE_C_ACCESSOR(Window, cWindow, minimum_size);
2565
+ DEFINE_C_ACCESSOR(Window, cWindow, position);
2566
+ DEFINE_C_ACCESSOR(Window, cWindow, size);
2567
+ DEFINE_C_ACCESSOR(Window, cWindow, title);
2568
+ DEFINE_C_ACCESSOR(Window, cWindow, bordered);
2569
+ rb_define_method(cWindow, "icon=", Window_set_icon, 1);
2570
+ rb_define_method(cWindow, "show", Window_show, 0);
2571
+ rb_define_method(cWindow, "hide", Window_hide, 0);
2572
+ rb_define_method(cWindow, "maximize", Window_maximize, 0);
2573
+ rb_define_method(cWindow, "minimize", Window_minimize, 0);
2574
+ rb_define_method(cWindow, "raise", Window_raise, 0);
2575
+ rb_define_method(cWindow, "restore", Window_restore, 0);
2576
+ rb_define_method(cWindow, "fullscreen_mode", Window_fullscreen_mode, 0);
2577
+ rb_define_method(cWindow, "fullscreen_mode=", Window_set_fullscreen_mode, 1);
2578
+ #if SDL_VERSION_ATLEAST(2,0,1)
2579
+ rb_define_method(cWindow, "gl_drawable_size", Window_gl_drawable_size, 0);
2580
+ #endif
2581
+ rb_define_method(cWindow, "gl_swap", Window_gl_swap, 0);
2582
+ rb_define_const(cWindow, "POS_CENTERED", INT2NUM(SDL_WINDOWPOS_CENTERED));
2583
+ rb_define_const(cWindow, "POS_UNDEFINED", INT2NUM(SDL_WINDOWPOS_UNDEFINED));
2584
+ #define DEFINE_SDL_WINDOW_FLAGS_CONST(n) \
2585
+ rb_define_const(cWindow, #n, UINT2NUM(SDL_WINDOW_##n));
2586
+ DEFINE_SDL_WINDOW_FLAGS_CONST(FULLSCREEN);
2587
+ DEFINE_SDL_WINDOW_FLAGS_CONST(FULLSCREEN_DESKTOP);
2588
+ DEFINE_SDL_WINDOW_FLAGS_CONST(OPENGL);
2589
+ DEFINE_SDL_WINDOW_FLAGS_CONST(SHOWN);
2590
+ DEFINE_SDL_WINDOW_FLAGS_CONST(HIDDEN);
2591
+ DEFINE_SDL_WINDOW_FLAGS_CONST(BORDERLESS);
2592
+ DEFINE_SDL_WINDOW_FLAGS_CONST(RESIZABLE);
2593
+ DEFINE_SDL_WINDOW_FLAGS_CONST(MINIMIZED);
2594
+ DEFINE_SDL_WINDOW_FLAGS_CONST(MAXIMIZED);
2595
+ DEFINE_SDL_WINDOW_FLAGS_CONST(INPUT_GRABBED);
2596
+ DEFINE_SDL_WINDOW_FLAGS_CONST(INPUT_FOCUS);
2597
+ DEFINE_SDL_WINDOW_FLAGS_CONST(MOUSE_FOCUS);
2598
+ DEFINE_SDL_WINDOW_FLAGS_CONST(FOREIGN);
2599
+ #ifdef SDL_WINDOW_ALLOW_HIGHDPI
2600
+ DEFINE_SDL_WINDOW_FLAGS_CONST(ALLOW_HIGHDPI);
2601
+ #endif
2602
+
2603
+
2604
+ cDisplay = rb_define_class_under(mSDL2, "Display", rb_cObject);
2605
+
2606
+ rb_define_module_function(cDisplay, "displays", Display_s_displays, 0);
2607
+ rb_define_attr(cDisplay, "index", 1, 0);
2608
+ rb_define_attr(cDisplay, "name", 1, 0);
2609
+ rb_define_method(cDisplay, "modes", Display_modes, 0);
2610
+ rb_define_method(cDisplay, "current_mode", Display_current_mode, 0);
2611
+ rb_define_method(cDisplay, "desktop_mode", Display_desktop_mode, 0);
2612
+ rb_define_method(cDisplay, "closest_mode", Display_closest_mode, 1);
2613
+ rb_define_method(cDisplay, "bounds", Display_bounds, 0);
2614
+
2615
+ cDisplayMode = rb_define_class_under(cDisplay, "Mode", rb_cObject);
2616
+
2617
+ rb_define_alloc_func(cDisplayMode, DisplayMode_s_allocate);
2618
+ rb_define_method(cDisplayMode, "initialize", DisplayMode_initialize, 4);
2619
+ rb_define_method(cDisplayMode, "inspect", DisplayMode_inspect, 0);
2620
+ rb_define_method(cDisplayMode, "format", DisplayMode_format, 0);
2621
+ rb_define_method(cDisplayMode, "w", DisplayMode_w, 0);
2622
+ rb_define_method(cDisplayMode, "h", DisplayMode_h, 0);
2623
+ rb_define_method(cDisplayMode, "refresh_rate", DisplayMode_refresh_rate, 0);
2624
+ /* attr format, w, h, refresh_rate */
2625
+
2626
+ cRenderer = rb_define_class_under(mSDL2, "Renderer", rb_cObject);
2627
+
2628
+ rb_undef_alloc_func(cRenderer);
2629
+ rb_define_singleton_method(cRenderer, "drivers_info", Renderer_s_drivers_info, 0);
2630
+ rb_define_method(cRenderer, "destroy?", Renderer_destroy_p, 0);
2631
+ rb_define_method(cRenderer, "destroy", Renderer_destroy, 0);
2632
+ rb_define_method(cRenderer, "debug_info", Renderer_debug_info, 0);
2633
+ rb_define_method(cRenderer, "create_texture", Renderer_create_texture, 4);
2634
+ rb_define_method(cRenderer, "create_texture_from", Renderer_create_texture_from, 1);
2635
+ rb_define_method(cRenderer, "copy", Renderer_copy, 3);
2636
+ rb_define_method(cRenderer, "copy_ex", Renderer_copy_ex, 6);
2637
+ rb_define_method(cRenderer, "present", Renderer_present, 0);
2638
+ rb_define_method(cRenderer, "draw_color",Renderer_draw_color, 0);
2639
+ rb_define_method(cRenderer, "draw_color=",Renderer_set_draw_color, 1);
2640
+ rb_define_method(cRenderer, "clear", Renderer_clear, 0);
2641
+ rb_define_method(cRenderer, "draw_line",Renderer_draw_line, 4);
2642
+ rb_define_method(cRenderer, "draw_point",Renderer_draw_point, 2);
2643
+ rb_define_method(cRenderer, "draw_rect", Renderer_draw_rect, 1);
2644
+ rb_define_method(cRenderer, "fill_rect", Renderer_fill_rect, 1);
2645
+ rb_define_method(cRenderer, "draw_blend_mode", Renderer_draw_blend_mode, 0);
2646
+ rb_define_method(cRenderer, "draw_blend_mode=", Renderer_set_draw_blend_mode, 1);
2647
+ rb_define_method(cRenderer, "clip_rect", Renderer_clip_rect, 0);
2648
+ #if SDL_VERSION_ATLEAST(2,0,4)
2649
+ rb_define_method(cRenderer, "clip_enabled?", Render_clip_enabled_p, 0);
2650
+ #endif
2651
+ rb_define_method(cRenderer, "logical_size", Renderer_logical_size, 0);
2652
+ rb_define_method(cRenderer, "scale", Renderer_scale, 0);
2653
+ rb_define_method(cRenderer, "viewport", Renderer_viewport, 0);
2654
+ rb_define_method(cRenderer, "support_render_target?", Renderer_support_render_target_p, 0);
2655
+ rb_define_method(cRenderer, "output_size", Renderer_output_size, 0);
2656
+ rb_define_method(cRenderer, "render_target", Renderer_render_target, 0);
2657
+ rb_define_method(cRenderer, "render_target=", Renderer_set_render_target, 1);
2658
+ rb_define_method(cRenderer, "reset_render_target", Renderer_reset_render_target, 0);
2659
+
2660
+ rb_define_method(cRenderer, "info", Renderer_info, 0);
2661
+ #define DEFINE_SDL_RENDERER_FLAGS_CONST(n) \
2662
+ rb_define_const(cRenderer, #n, UINT2NUM(SDL_RENDERER_##n))
2663
+ DEFINE_SDL_RENDERER_FLAGS_CONST(SOFTWARE);
2664
+ DEFINE_SDL_RENDERER_FLAGS_CONST(ACCELERATED);
2665
+ #ifdef SDL_RENDERER_PRESENTVSYNC
2666
+ DEFINE_SDL_RENDERER_FLAGS_CONST(PRESENTVSYNC);
2667
+ #endif
2668
+ DEFINE_SDL_RENDERER_FLAGS_CONST(TARGETTEXTURE);
2669
+ #define DEFINE_SDL_FLIP_CONST(t) \
2670
+ rb_define_const(cRenderer, "FLIP_" #t, INT2FIX(SDL_FLIP_##t))
2671
+ DEFINE_SDL_FLIP_CONST(NONE);
2672
+ DEFINE_SDL_FLIP_CONST(HORIZONTAL);
2673
+ DEFINE_SDL_FLIP_CONST(VERTICAL);
2674
+ #define DEFINE_BLENDMODE_CONST(t) \
2675
+ rb_define_const(mSDL2, "BLENDMODE_" #t, INT2FIX(SDL_BLENDMODE_##t))
2676
+ DEFINE_BLENDMODE_CONST(NONE);
2677
+ DEFINE_BLENDMODE_CONST(BLEND);
2678
+ DEFINE_BLENDMODE_CONST(ADD);
2679
+ DEFINE_BLENDMODE_CONST(MOD);
2680
+
2681
+ cTexture = rb_define_class_under(mSDL2, "Texture", rb_cObject);
2682
+
2683
+ rb_undef_alloc_func(cTexture);
2684
+ rb_define_method(cTexture, "destroy?", Texture_destroy_p, 0);
2685
+ rb_define_method(cTexture, "destroy", Texture_destroy, 0);
2686
+ DEFINE_C_ACCESSOR(Texture, cTexture, blend_mode);
2687
+ DEFINE_C_ACCESSOR(Texture, cTexture, color_mod);
2688
+ DEFINE_C_ACCESSOR(Texture, cTexture, alpha_mod);
2689
+ rb_define_method(cTexture, "format", Texture_format, 0);
2690
+ rb_define_method(cTexture, "access_pattern", Texture_access_pattern, 0);
2691
+ rb_define_method(cTexture, "w", Texture_w, 0);
2692
+ rb_define_method(cTexture, "h", Texture_h, 0);
2693
+ rb_define_method(cTexture, "inspect", Texture_inspect, 0);
2694
+ rb_define_method(cTexture, "debug_info", Texture_debug_info, 0);
2695
+ #define DEFINE_TEXTUREAH_ACCESS_CONST(t) \
2696
+ rb_define_const(cTexture, "ACCESS_" #t, INT2NUM(SDL_TEXTUREACCESS_##t))
2697
+ DEFINE_TEXTUREAH_ACCESS_CONST(STATIC);
2698
+ DEFINE_TEXTUREAH_ACCESS_CONST(STREAMING);
2699
+ DEFINE_TEXTUREAH_ACCESS_CONST(TARGET);
2700
+
2701
+
2702
+ cSurface = rb_define_class_under(mSDL2, "Surface", rb_cObject);
2703
+
2704
+ rb_undef_alloc_func(cSurface);
2705
+ rb_define_singleton_method(cSurface, "load_bmp", Surface_s_load_bmp, 1);
2706
+ rb_define_singleton_method(cSurface, "blit", Surface_s_blit, 4);
2707
+ rb_define_singleton_method(cSurface, "new", Surface_s_new, -1);
2708
+ rb_define_singleton_method(cSurface, "from_string", Surface_s_from_string, -1);
2709
+ rb_define_method(cSurface, "destroy?", Surface_destroy_p, 0);
2710
+ rb_define_method(cSurface, "destroy", Surface_destroy, 0);
2711
+ DEFINE_C_ACCESSOR(Surface, cSurface, blend_mode);
2712
+ rb_define_method(cSurface, "must_lock?", Surface_must_lock_p, 0);
2713
+ rb_define_method(cSurface, "lock", Surface_lock, 0);
2714
+ rb_define_method(cSurface, "unlock", Surface_unlock, 0);
2715
+ rb_define_method(cSurface, "w", Surface_w, 0);
2716
+ rb_define_method(cSurface, "h", Surface_h, 0);
2717
+ rb_define_method(cSurface, "pixel", Surface_pixel, 2);
2718
+ rb_define_method(cSurface, "pixel_color", Surface_pixel_color, 2);
2719
+ rb_define_method(cSurface, "color_key", Surface_color_key, 0);
2720
+ rb_define_method(cSurface, "color_key=", Surface_set_color_key, 1);
2721
+ rb_define_method(cSurface, "unset_color_key", Surface_set_color_key, 0);
2722
+ rb_define_method(cSurface, "pixels", Surface_pixels, 0);
2723
+ rb_define_method(cSurface, "pitch", Surface_pitch, 0);
2724
+ rb_define_method(cSurface, "bits_per_pixel", Surface_bits_per_pixel, 0);
2725
+ rb_define_method(cSurface, "bytes_per_pixel", Surface_bytes_per_pixel, 0);
2726
+
2727
+ cRect = rb_define_class_under(mSDL2, "Rect", rb_cObject);
2728
+
2729
+ rb_define_alloc_func(cRect, Rect_s_allocate);
2730
+ rb_define_method(cRect, "initialize", Rect_initialize, -1);
2731
+ rb_define_alias(rb_singleton_class(cRect), "[]", "new");
2732
+ rb_define_method(cRect, "inspect", Rect_inspect, 0);
2733
+ DEFINE_C_ACCESSOR(Rect, cRect, x);
2734
+ DEFINE_C_ACCESSOR(Rect, cRect, y);
2735
+ DEFINE_C_ACCESSOR(Rect, cRect, w);
2736
+ DEFINE_C_ACCESSOR(Rect, cRect, h);
2737
+ rb_define_method(cRect, "union", Rect_union, 1);
2738
+ rb_define_method(cRect, "intersection", Rect_intersection, 1);
2739
+
2740
+ cPoint = rb_define_class_under(mSDL2, "Point", rb_cObject);
2741
+
2742
+ rb_define_alloc_func(cPoint, Point_s_allocate);
2743
+ rb_define_method(cPoint, "initialize", Point_initialize, -1);
2744
+ rb_define_alias(rb_singleton_class(cPoint), "[]", "new");
2745
+ rb_define_method(cPoint, "inspect", Point_inspect, 0);
2746
+ DEFINE_C_ACCESSOR(Point, cPoint, x);
2747
+ DEFINE_C_ACCESSOR(Point, cPoint, y);
2748
+
2749
+
2750
+ cRendererInfo = rb_define_class_under(cRenderer, "Info", rb_cObject);
2751
+ define_attr_readers(cRendererInfo, "name", "flags", "texture_formats",
2752
+ "max_texture_width", "max_texture_height", NULL);
2753
+
2754
+
2755
+ cPixelFormat = rb_define_class_under(mSDL2, "PixelFormat", rb_cObject);
2756
+
2757
+ rb_define_method(cPixelFormat, "initialize", PixelForamt_initialize, 1);
2758
+ rb_define_attr(cPixelFormat, "format", 1, 0);
2759
+ rb_define_method(cPixelFormat, "name", PixelFormat_name, 0);
2760
+ rb_define_method(cPixelFormat, "inspect", PixelFormat_inspect, 0);
2761
+ rb_define_method(cPixelFormat, "type", PixelFormat_type, 0);
2762
+ rb_define_method(cPixelFormat, "order", PixelFormat_order, 0);
2763
+ rb_define_method(cPixelFormat, "layout", PixelFormat_layout, 0);
2764
+ rb_define_method(cPixelFormat, "bits_per_pixel", PixelFormat_bits_per_pixel, 0);
2765
+ rb_define_alias(cPixelFormat, "bpp", "bits_per_pixel");
2766
+ rb_define_method(cPixelFormat, "bytes_per_pixel", PixelFormat_bytes_per_pixel, 0);
2767
+ rb_define_method(cPixelFormat, "indexed?", PixelFormat_indexed_p, 0);
2768
+ rb_define_method(cPixelFormat, "alpha?", PixelFormat_alpha_p, 0);
2769
+ rb_define_method(cPixelFormat, "fourcc?", PixelFormat_fourcc_p, 0);
2770
+ rb_define_method(cPixelFormat, "==", PixelFormat_eq, 1);
2771
+
2772
+ {
2773
+ VALUE formats = rb_ary_new();
2774
+ rb_define_const(cPixelFormat, "FORMATS", formats);
2775
+ #define DEFINE_PIXELFORMAT_CONST(t) \
2776
+ do { \
2777
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_##t); \
2778
+ rb_define_const(cPixelFormat, #t, format); \
2779
+ rb_ary_push(formats, format); \
2780
+ } while (0)
2781
+ DEFINE_PIXELFORMAT_CONST(UNKNOWN);
2782
+ DEFINE_PIXELFORMAT_CONST(INDEX1LSB);
2783
+ DEFINE_PIXELFORMAT_CONST(INDEX1MSB);
2784
+ DEFINE_PIXELFORMAT_CONST(INDEX4LSB);
2785
+ DEFINE_PIXELFORMAT_CONST(INDEX4MSB);
2786
+ DEFINE_PIXELFORMAT_CONST(INDEX8);
2787
+ DEFINE_PIXELFORMAT_CONST(RGB332);
2788
+ DEFINE_PIXELFORMAT_CONST(RGB444);
2789
+ DEFINE_PIXELFORMAT_CONST(RGB555);
2790
+ DEFINE_PIXELFORMAT_CONST(BGR555);
2791
+ DEFINE_PIXELFORMAT_CONST(ARGB4444);
2792
+ DEFINE_PIXELFORMAT_CONST(RGBA4444);
2793
+ DEFINE_PIXELFORMAT_CONST(ABGR4444);
2794
+ DEFINE_PIXELFORMAT_CONST(BGRA4444);
2795
+ DEFINE_PIXELFORMAT_CONST(ARGB1555);
2796
+ DEFINE_PIXELFORMAT_CONST(RGBA5551);
2797
+ DEFINE_PIXELFORMAT_CONST(ABGR1555);
2798
+ DEFINE_PIXELFORMAT_CONST(BGRA5551);
2799
+ DEFINE_PIXELFORMAT_CONST(RGB565);
2800
+ DEFINE_PIXELFORMAT_CONST(BGR565);
2801
+ DEFINE_PIXELFORMAT_CONST(RGB24);
2802
+ DEFINE_PIXELFORMAT_CONST(BGR24);
2803
+ DEFINE_PIXELFORMAT_CONST(RGB888);
2804
+ DEFINE_PIXELFORMAT_CONST(RGBX8888);
2805
+ DEFINE_PIXELFORMAT_CONST(BGR888);
2806
+ DEFINE_PIXELFORMAT_CONST(BGRX8888);
2807
+ DEFINE_PIXELFORMAT_CONST(ARGB8888);
2808
+ DEFINE_PIXELFORMAT_CONST(RGBA8888);
2809
+ DEFINE_PIXELFORMAT_CONST(ABGR8888);
2810
+ DEFINE_PIXELFORMAT_CONST(BGRA8888);
2811
+ DEFINE_PIXELFORMAT_CONST(ARGB2101010);
2812
+ DEFINE_PIXELFORMAT_CONST(YV12);
2813
+ DEFINE_PIXELFORMAT_CONST(IYUV);
2814
+ DEFINE_PIXELFORMAT_CONST(YUY2);
2815
+ DEFINE_PIXELFORMAT_CONST(UYVY);
2816
+ DEFINE_PIXELFORMAT_CONST(YVYU);
2817
+ rb_obj_freeze(formats);
2818
+ }
2819
+
2820
+ mScreenSaver = rb_define_module_under(mSDL2, "ScreenSaver");
2821
+ rb_define_module_function(mScreenSaver, "enable", ScreenSaver_enable, 0);
2822
+ rb_define_module_function(mScreenSaver, "disable", ScreenSaver_disable, 0);
2823
+ rb_define_module_function(mScreenSaver, "enabled?", ScreenSaver_enabled_p, 0);
2824
+
2825
+
2826
+ rb_gc_register_address(&hash_windowid_to_window);
2827
+ hash_windowid_to_window = rb_hash_new();
2828
+ }
2829
+
2830
+ #ifdef HAVE_SDL_IMAGE_H
2831
+ #include <SDL_image.h>
2832
+
2833
+ static VALUE mIMG;
2834
+
2835
+ /*
2836
+ * @overload init(flags)
2837
+ * Initialize SDL_image.
2838
+ *
2839
+ * You can specify the supporting image formats by bitwise OR'd of the
2840
+ * following constants.
2841
+ *
2842
+ * * {SDL2::IMG::INIT_JPG}
2843
+ * * {SDL2::IMG::INIT_PNG}
2844
+ * * {SDL2::IMG::INIT_TIF}
2845
+ *
2846
+ * You need to initialize SDL_image to check whether specified format
2847
+ * is supported by your environment. If your environment does not
2848
+ * support required support format, you have a {SDL2::Error} exception.
2849
+ *
2850
+ * @param [Integer] flags submodule bits
2851
+ * @return [nil]
2852
+ *
2853
+ * @raise [SDL2::Error] raised when initializing is failed.
2854
+ */
2855
+ static VALUE IMG_s_init(VALUE self, VALUE f)
2856
+ {
2857
+ int flags = NUM2INT(f);
2858
+ if (IMG_Init(flags) & flags != flags)
2859
+ rb_raise(eSDL2Error, "Couldn't initialze SDL_image");
2860
+ return Qnil;
2861
+ }
2862
+
2863
+ /*
2864
+ * @overload load(file)
2865
+ * Load file and create a new {SDL2::Surface}.
2866
+ *
2867
+ * This method uses SDL_image. SDL_image supports following formats:
2868
+ * BMP, CUR, GIF, ICO, JPG, LBP, PCX, PNG, PNM, TGA, TIF, XCF, XPM, and XV.
2869
+ *
2870
+ * @param [String] file the image file name to load a surface from
2871
+ * @return [SDL2::Surface] Created surface
2872
+ *
2873
+ * @raise [SDL2::Error] raised when you fail to load (for example,
2874
+ * you have a wrong file name, or the file is broken)
2875
+ *
2876
+ * @see SDL2::IMG.init
2877
+ * @see SDL2::Renderer#load_texture
2878
+ */
2879
+ static VALUE Surface_s_load(VALUE self, VALUE fname)
2880
+ {
2881
+ SDL_Surface* surface = IMG_Load(StringValueCStr(fname));
2882
+ if (!surface) {
2883
+ SDL_SetError(IMG_GetError());
2884
+ SDL_ERROR();
2885
+ }
2886
+ return Surface_new(surface);
2887
+ }
2888
+
2889
+ /*
2890
+ * @overload load_texture(file)
2891
+ *
2892
+ * Load file and create a new {SDL2::Texture}.
2893
+ *
2894
+ * This method uses SDL_image. SDL_image supports following formats:
2895
+ * BMP, CUR, GIF, ICO, JPG, LBP, PCX, PNG, PNM, TGA, TIF, XCF, XPM, and XV.
2896
+ *
2897
+ * @param [String] file the image file name to load a texture from
2898
+ * @return [SDL2::Texture] Created texture
2899
+ *
2900
+ * @raise [SDL2::Error] raised when you fail to load (for example,
2901
+ * you have a wrong file name, or the file is broken)
2902
+ *
2903
+ * @see SDL2::IMG.init
2904
+ * @see SDL2::Surface.load
2905
+ */
2906
+ static VALUE Renderer_load_texture(VALUE self, VALUE fname)
2907
+ {
2908
+ SDL_Texture* texture = IMG_LoadTexture(Get_SDL_Renderer(self), StringValueCStr(fname));
2909
+ if (!texture) {
2910
+ SDL_SetError(IMG_GetError());
2911
+ SDL_ERROR();
2912
+ }
2913
+ return Texture_new(texture, Get_Renderer(self));
2914
+ }
2915
+
2916
+ void rubysdl2_init_image(void)
2917
+ {
2918
+ mIMG = rb_define_module_under(mSDL2, "IMG");
2919
+ rb_define_module_function(mIMG, "init", IMG_s_init, 1);
2920
+
2921
+ rb_define_singleton_method(cSurface, "load", Surface_s_load, 1);
2922
+ rb_define_method(cRenderer, "load_texture", Renderer_load_texture, 1);
2923
+
2924
+
2925
+ rb_define_const(mIMG, "INIT_JPG", INT2NUM(IMG_INIT_JPG));
2926
+ rb_define_const(mIMG, "INIT_PNG", INT2NUM(IMG_INIT_PNG));
2927
+ rb_define_const(mIMG, "INIT_TIF", INT2NUM(IMG_INIT_TIF));
2928
+ rb_define_const(mIMG, "INIT_WEBP", INT2NUM(IMG_INIT_WEBP));
2929
+ }
2930
+
2931
+ #else /* HAVE_SDL_IMAGE_H */
2932
+ void rubysdl2_init_image(void)
2933
+ {
2934
+ }
2935
+ #endif