ruby-sdl2 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.dir-locals.el +2 -0
- data/.gitignore +17 -0
- data/COPYING.txt +165 -0
- data/README.md +30 -0
- data/Rakefile +95 -0
- data/clipboard.c +37 -0
- data/doc/po/ja.po +1160 -0
- data/event.c +1027 -0
- data/extconf.rb +53 -0
- data/filesystem.c +36 -0
- data/gamecontroller.c +194 -0
- data/gl.c.m4 +201 -0
- data/hint.c +56 -0
- data/joystick.c +316 -0
- data/key.c.m4 +794 -0
- data/lib/sdl2.rb +3 -0
- data/lib/sdl2/version.rb +6 -0
- data/main.c +244 -0
- data/messagebox.c +231 -0
- data/mixer.c +1079 -0
- data/mouse.c +286 -0
- data/rubysdl2_internal.h +125 -0
- data/sample/chunk_destroy.rb +16 -0
- data/sample/icon.bmp +0 -0
- data/sample/memory_test/m1.rb +28 -0
- data/sample/memory_test/m2.rb +18 -0
- data/sample/memory_test/m3.rb +12 -0
- data/sample/message_box.rb +33 -0
- data/sample/music_player.rb +133 -0
- data/sample/playwave.rb +19 -0
- data/sample/primitives.rb +32 -0
- data/sample/test_clipboard.rb +11 -0
- data/sample/test_controller.rb +57 -0
- data/sample/test_joystick.rb +48 -0
- data/sample/test_keyboard.rb +44 -0
- data/sample/test_mouse.rb +44 -0
- data/sample/test_surface.rb +8 -0
- data/sample/test_ttf.rb +77 -0
- data/sample/test_video.rb +53 -0
- data/sample/testgl.rb +175 -0
- data/sample/testsprite.rb +296 -0
- data/sample/testspriteminimal.rb +75 -0
- data/sample/timer.rb +11 -0
- data/sample/version.rb +12 -0
- data/sample/video_info.rb +65 -0
- data/timer.c +63 -0
- data/ttf.c +196 -0
- data/video.c.m4 +2935 -0
- metadata +102 -0
@@ -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
|
data/sample/timer.rb
ADDED
data/sample/version.rb
ADDED
@@ -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
|
+
|
data/video.c.m4
ADDED
@@ -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
|