sdl2-win93 1.0.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/.github/workflows/gempush.yml +29 -0
- data/.gitignore +14 -0
- data/COPYING.txt +165 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +24 -0
- data/Makefile +4 -0
- data/README.md +36 -0
- data/Rakefile +51 -0
- data/doc/po/ja.po +10357 -0
- data/ext/sdl2_ext/clipboard.c +61 -0
- data/ext/sdl2_ext/color.c +103 -0
- data/ext/sdl2_ext/color.h +4 -0
- data/ext/sdl2_ext/event.c +1298 -0
- data/ext/sdl2_ext/extconf.rb +22 -0
- data/ext/sdl2_ext/filesystem.c +63 -0
- data/ext/sdl2_ext/gamecontroller.c +408 -0
- data/ext/sdl2_ext/gamecontroller.c.m4 +408 -0
- data/ext/sdl2_ext/gl.c +351 -0
- data/ext/sdl2_ext/gl.c.m4 +351 -0
- data/ext/sdl2_ext/hint.c +99 -0
- data/ext/sdl2_ext/joystick.c +339 -0
- data/ext/sdl2_ext/joystick.c.m4 +339 -0
- data/ext/sdl2_ext/key.c +1302 -0
- data/ext/sdl2_ext/key.c.m4 +833 -0
- data/ext/sdl2_ext/main.c +258 -0
- data/ext/sdl2_ext/messagebox.c +233 -0
- data/ext/sdl2_ext/mixer.c +1205 -0
- data/ext/sdl2_ext/mixer.c.m4 +1205 -0
- data/ext/sdl2_ext/mouse.c +286 -0
- data/ext/sdl2_ext/rubysdl2_internal.h +127 -0
- data/ext/sdl2_ext/timer.c +63 -0
- data/ext/sdl2_ext/ttf.c +376 -0
- data/ext/sdl2_ext/ttf.c.m4 +376 -0
- data/ext/sdl2_ext/video.c +4093 -0
- data/ext/sdl2_ext/video.c.m4 +3867 -0
- data/lib/sdl2.rb +3 -0
- data/lib/sdl2/event.rb +55 -0
- data/lib/sdl2/version.rb +8 -0
- data/sample/chunk_destroy.rb +16 -0
- data/sample/gfxprimitives.rb +54 -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 +137 -0
- data/sample/playwave.rb +19 -0
- data/sample/primitives.rb +32 -0
- data/sample/test_clipboard.rb +16 -0
- data/sample/test_controller.rb +62 -0
- data/sample/test_joystick.rb +53 -0
- data/sample/test_keyboard.rb +52 -0
- data/sample/test_mouse.rb +50 -0
- data/sample/test_surface.rb +13 -0
- data/sample/test_ttf.rb +82 -0
- data/sample/test_video.rb +59 -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 +64 -0
- data/sdl2-win93.gemspec +31 -0
- metadata +158 -0
@@ -0,0 +1,3867 @@
|
|
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
|
+
#ifdef HAVE_SDL2_GFXPRIMITIVES_H
|
9
|
+
#include <SDL2_gfxPrimitives.h>
|
10
|
+
#endif
|
11
|
+
#include <ruby/encoding.h>
|
12
|
+
#include <assert.h>
|
13
|
+
|
14
|
+
static VALUE cWindow;
|
15
|
+
static VALUE mWindowFlags;
|
16
|
+
static VALUE cDisplay;
|
17
|
+
static VALUE cDisplayMode;
|
18
|
+
static VALUE cRenderer;
|
19
|
+
static VALUE mRendererFlags;
|
20
|
+
static VALUE mBlendMode;
|
21
|
+
static VALUE cTexture;
|
22
|
+
static VALUE cRect;
|
23
|
+
static VALUE cPoint;
|
24
|
+
static VALUE cSurface;
|
25
|
+
static VALUE cRendererInfo;
|
26
|
+
static VALUE cPixelFormat; /* NOTE: This is related to SDL_PixelFormatEnum, not SDL_PixelFormat */
|
27
|
+
static VALUE mPixelType;
|
28
|
+
static VALUE mBitmapOrder;
|
29
|
+
static VALUE mPackedOrder;
|
30
|
+
static VALUE mArrayOrder;
|
31
|
+
static VALUE mPackedLayout;
|
32
|
+
|
33
|
+
static VALUE mScreenSaver;
|
34
|
+
|
35
|
+
static VALUE hash_windowid_to_window = Qnil;
|
36
|
+
|
37
|
+
struct Window;
|
38
|
+
struct Renderer;
|
39
|
+
struct Texture;
|
40
|
+
|
41
|
+
#ifdef DEBUG_GC
|
42
|
+
#define GC_LOG(args) fprintf args
|
43
|
+
#else
|
44
|
+
#define GC_LOG(args)
|
45
|
+
#endif
|
46
|
+
|
47
|
+
typedef struct Window {
|
48
|
+
SDL_Window* window;
|
49
|
+
int num_renderers;
|
50
|
+
int max_renderers;
|
51
|
+
struct Renderer** renderers;
|
52
|
+
} Window;
|
53
|
+
|
54
|
+
typedef struct Renderer {
|
55
|
+
SDL_Renderer* renderer;
|
56
|
+
int num_textures;
|
57
|
+
int max_textures;
|
58
|
+
struct Texture** textures;
|
59
|
+
int refcount;
|
60
|
+
} Renderer;
|
61
|
+
|
62
|
+
typedef struct Texture {
|
63
|
+
SDL_Texture* texture;
|
64
|
+
int refcount;
|
65
|
+
} Texture;
|
66
|
+
|
67
|
+
typedef struct Surface {
|
68
|
+
SDL_Surface* surface;
|
69
|
+
int need_to_free_pixels;
|
70
|
+
} Surface;
|
71
|
+
|
72
|
+
static void Renderer_free(Renderer*);
|
73
|
+
static void Window_destroy_internal(Window* w)
|
74
|
+
{
|
75
|
+
int i;
|
76
|
+
for (i=0; i<w->num_renderers; ++i)
|
77
|
+
Renderer_free(w->renderers[i]);
|
78
|
+
w->num_renderers = w->max_renderers = 0;
|
79
|
+
free(w->renderers);
|
80
|
+
w->renderers = NULL;
|
81
|
+
}
|
82
|
+
|
83
|
+
static void Window_free(Window* w)
|
84
|
+
{
|
85
|
+
|
86
|
+
GC_LOG((stderr, "Window free: %p\n", w));
|
87
|
+
Window_destroy_internal(w);
|
88
|
+
if (w->window && rubysdl2_is_active())
|
89
|
+
SDL_DestroyWindow(w->window);
|
90
|
+
|
91
|
+
free(w);
|
92
|
+
}
|
93
|
+
|
94
|
+
static VALUE Window_new(SDL_Window* window)
|
95
|
+
{
|
96
|
+
Window* w = ALLOC(Window);
|
97
|
+
w->window = window;
|
98
|
+
w->num_renderers = 0;
|
99
|
+
w->max_renderers = 4;
|
100
|
+
w->renderers = ALLOC_N(struct Renderer*, 4);
|
101
|
+
return Data_Wrap_Struct(cWindow, 0, Window_free, w);
|
102
|
+
}
|
103
|
+
|
104
|
+
DEFINE_GETTER(static, Window, cWindow, "SDL2::Window");
|
105
|
+
DEFINE_WRAP_GETTER(, SDL_Window, Window, window, "SDL2::Window");
|
106
|
+
DEFINE_DESTROY_P(static, Window, window);
|
107
|
+
|
108
|
+
static VALUE Display_new(int index)
|
109
|
+
{
|
110
|
+
VALUE display = rb_obj_alloc(cDisplay);
|
111
|
+
rb_iv_set(display, "@index", INT2NUM(index));
|
112
|
+
rb_iv_set(display, "@name", utf8str_new_cstr(SDL_GetDisplayName(index)));
|
113
|
+
return display;
|
114
|
+
}
|
115
|
+
|
116
|
+
static VALUE DisplayMode_s_allocate(VALUE klass)
|
117
|
+
{
|
118
|
+
SDL_DisplayMode* mode = ALLOC(SDL_DisplayMode);
|
119
|
+
mode->format = mode->w = mode->h = mode->refresh_rate = 0;
|
120
|
+
mode->driverdata = NULL;
|
121
|
+
return Data_Wrap_Struct(klass, 0, free, mode);
|
122
|
+
}
|
123
|
+
|
124
|
+
static VALUE DisplayMode_new(SDL_DisplayMode* mode)
|
125
|
+
{
|
126
|
+
VALUE display_mode = DisplayMode_s_allocate(cDisplayMode);
|
127
|
+
SDL_DisplayMode* m;
|
128
|
+
Data_Get_Struct(display_mode, SDL_DisplayMode, m);
|
129
|
+
*m = *mode;
|
130
|
+
return display_mode;
|
131
|
+
}
|
132
|
+
|
133
|
+
DEFINE_GETTER(static, SDL_DisplayMode, cDisplayMode, "SDL2::Display::Mode");
|
134
|
+
|
135
|
+
static void Texture_free(Texture*);
|
136
|
+
static void Renderer_destroy_internal(Renderer* r)
|
137
|
+
{
|
138
|
+
int i;
|
139
|
+
for (i=0; i<r->num_textures; ++i)
|
140
|
+
Texture_free(r->textures[i]);
|
141
|
+
free(r->textures);
|
142
|
+
r->textures = NULL;
|
143
|
+
r->max_textures = r->num_textures = 0;
|
144
|
+
|
145
|
+
if (r->renderer && rubysdl2_is_active()) {
|
146
|
+
SDL_DestroyRenderer(r->renderer);
|
147
|
+
}
|
148
|
+
r->renderer = NULL;
|
149
|
+
}
|
150
|
+
|
151
|
+
static void Renderer_free(Renderer* r)
|
152
|
+
{
|
153
|
+
GC_LOG((stderr, "Renderer free: %p (refcount=%d)\n", r, r->refcount));
|
154
|
+
Renderer_destroy_internal(r);
|
155
|
+
|
156
|
+
r->refcount--;
|
157
|
+
if (r->refcount == 0) {
|
158
|
+
free(r);
|
159
|
+
}
|
160
|
+
}
|
161
|
+
|
162
|
+
static void Window_attach_renderer(Window* w, Renderer* r)
|
163
|
+
{
|
164
|
+
if (w->num_renderers == w->max_renderers) {
|
165
|
+
w->max_renderers *= 2;
|
166
|
+
REALLOC_N(w->renderers, Renderer*, w->max_renderers);
|
167
|
+
}
|
168
|
+
w->renderers[w->num_renderers++] = r;
|
169
|
+
++r->refcount;
|
170
|
+
}
|
171
|
+
|
172
|
+
static VALUE Renderer_new(SDL_Renderer* renderer, Window* w)
|
173
|
+
{
|
174
|
+
Renderer* r = ALLOC(Renderer);
|
175
|
+
r->renderer = renderer;
|
176
|
+
r->num_textures = 0;
|
177
|
+
r->max_textures = 16;
|
178
|
+
r->textures = ALLOC_N(Texture*, 16);
|
179
|
+
r->refcount = 1;
|
180
|
+
Window_attach_renderer(w, r);
|
181
|
+
return Data_Wrap_Struct(cRenderer, 0, Renderer_free, r);
|
182
|
+
}
|
183
|
+
|
184
|
+
DEFINE_WRAPPER(SDL_Renderer, Renderer, renderer, cRenderer, "SDL2::Renderer");
|
185
|
+
|
186
|
+
static void Texture_destroy_internal(Texture* t)
|
187
|
+
{
|
188
|
+
if (t->texture && rubysdl2_is_active()) {
|
189
|
+
SDL_DestroyTexture(t->texture);
|
190
|
+
}
|
191
|
+
t->texture = NULL;
|
192
|
+
}
|
193
|
+
|
194
|
+
static void Texture_free(Texture* t)
|
195
|
+
{
|
196
|
+
GC_LOG((stderr, "Texture free: %p (refcount=%d)\n", t, t->refcount));
|
197
|
+
Texture_destroy_internal(t);
|
198
|
+
t->refcount--;
|
199
|
+
if (t->refcount == 0) {
|
200
|
+
free(t);
|
201
|
+
}
|
202
|
+
}
|
203
|
+
|
204
|
+
static void Renderer_attach_texture(Renderer* r, Texture* t)
|
205
|
+
{
|
206
|
+
if (r->max_textures == r->num_textures) {
|
207
|
+
r->max_textures *= 2;
|
208
|
+
REALLOC_N(r->textures, Texture*, r->max_textures);
|
209
|
+
}
|
210
|
+
r->textures[r->num_textures++] = t;
|
211
|
+
++t->refcount;
|
212
|
+
}
|
213
|
+
|
214
|
+
static VALUE Texture_new(SDL_Texture* texture, Renderer* r)
|
215
|
+
{
|
216
|
+
Texture* t = ALLOC(Texture);
|
217
|
+
t->texture = texture;
|
218
|
+
t->refcount = 1;
|
219
|
+
Renderer_attach_texture(r, t);
|
220
|
+
return Data_Wrap_Struct(cTexture, 0, Texture_free, t);
|
221
|
+
}
|
222
|
+
|
223
|
+
DEFINE_WRAPPER(SDL_Texture, Texture, texture, cTexture, "SDL2::Texture");
|
224
|
+
|
225
|
+
|
226
|
+
static void Surface_free(Surface* s)
|
227
|
+
{
|
228
|
+
GC_LOG((stderr, "Surface free: %p\n", s));
|
229
|
+
if (s->need_to_free_pixels)
|
230
|
+
free(s->surface->pixels);
|
231
|
+
if (s->surface && rubysdl2_is_active())
|
232
|
+
SDL_FreeSurface(s->surface);
|
233
|
+
free(s);
|
234
|
+
}
|
235
|
+
|
236
|
+
VALUE Surface_new(SDL_Surface* surface)
|
237
|
+
{
|
238
|
+
Surface* s = ALLOC(Surface);
|
239
|
+
s->surface = surface;
|
240
|
+
s->need_to_free_pixels = 0;
|
241
|
+
return Data_Wrap_Struct(cSurface, 0, Surface_free, s);
|
242
|
+
}
|
243
|
+
|
244
|
+
DEFINE_WRAPPER(SDL_Surface, Surface, surface, cSurface, "SDL2::Surface");
|
245
|
+
|
246
|
+
DEFINE_GETTER(, SDL_Rect, cRect, "SDL2::Rect");
|
247
|
+
|
248
|
+
DEFINE_GETTER(static, SDL_Point, cPoint, "SDL2::Point");
|
249
|
+
|
250
|
+
static VALUE PixelFormat_new(Uint32 format)
|
251
|
+
{
|
252
|
+
VALUE fmt = UINT2NUM(format);
|
253
|
+
return rb_class_new_instance(1, &fmt, cPixelFormat);
|
254
|
+
}
|
255
|
+
|
256
|
+
static VALUE RendererInfo_new(SDL_RendererInfo* info)
|
257
|
+
{
|
258
|
+
VALUE rinfo = rb_obj_alloc(cRendererInfo);
|
259
|
+
VALUE texture_formats = rb_ary_new();
|
260
|
+
unsigned int i;
|
261
|
+
|
262
|
+
rb_iv_set(rinfo, "@name", rb_usascii_str_new_cstr(info->name));
|
263
|
+
rb_iv_set(rinfo, "@texture_formats", texture_formats);
|
264
|
+
for (i=0; i<info->num_texture_formats; ++i)
|
265
|
+
rb_ary_push(texture_formats, PixelFormat_new(info->texture_formats[i]));
|
266
|
+
rb_iv_set(rinfo, "@max_texture_width", INT2NUM(info->max_texture_width));
|
267
|
+
rb_iv_set(rinfo, "@max_texture_height", INT2NUM(info->max_texture_height));
|
268
|
+
|
269
|
+
return rinfo;
|
270
|
+
}
|
271
|
+
|
272
|
+
|
273
|
+
/*
|
274
|
+
* Get the names of all video drivers.
|
275
|
+
*
|
276
|
+
* You can use the name as an argument of {.video_init}.
|
277
|
+
*
|
278
|
+
* @return [Array<String>]
|
279
|
+
*/
|
280
|
+
static VALUE SDL2_s_video_drivers(VALUE self)
|
281
|
+
{
|
282
|
+
int num_drivers = HANDLE_ERROR(SDL_GetNumVideoDrivers());
|
283
|
+
int i;
|
284
|
+
VALUE drivers = rb_ary_new();
|
285
|
+
for (i=0; i<num_drivers; ++i)
|
286
|
+
rb_ary_push(drivers, rb_usascii_str_new_cstr(SDL_GetVideoDriver(i)));
|
287
|
+
return drivers;
|
288
|
+
}
|
289
|
+
|
290
|
+
/*
|
291
|
+
* Get the name of current video driver
|
292
|
+
*
|
293
|
+
* @return [String] the name of the current video driver
|
294
|
+
* @return [nil] when the video is not initialized
|
295
|
+
*/
|
296
|
+
static VALUE SDL2_s_current_video_driver(VALUE self)
|
297
|
+
{
|
298
|
+
const char* name = SDL_GetCurrentVideoDriver();
|
299
|
+
if (name)
|
300
|
+
return utf8str_new_cstr(name);
|
301
|
+
else
|
302
|
+
return Qnil;
|
303
|
+
}
|
304
|
+
|
305
|
+
/*
|
306
|
+
* @overload video_init(driver_name)
|
307
|
+
* Initialize the video subsystem, specifying a video driver.
|
308
|
+
*
|
309
|
+
* {.init} cannot specify a video driver, so you need to use
|
310
|
+
* this method to specify a driver.
|
311
|
+
*
|
312
|
+
* @param driver_name [String]
|
313
|
+
* @return [nil]
|
314
|
+
*
|
315
|
+
* @see .init
|
316
|
+
*/
|
317
|
+
static VALUE SDL2_s_video_init(VALUE self, VALUE driver_name)
|
318
|
+
{
|
319
|
+
HANDLE_ERROR(SDL_VideoInit(StringValueCStr(driver_name)));
|
320
|
+
return Qnil;
|
321
|
+
}
|
322
|
+
|
323
|
+
/*
|
324
|
+
* Document-class: SDL2::Window
|
325
|
+
*
|
326
|
+
* This class represents a window.
|
327
|
+
*
|
328
|
+
* If you want to create graphical application using Ruby/SDL, first you need to
|
329
|
+
* create a window.
|
330
|
+
*
|
331
|
+
* All of methods/class methods are available only after initializing video
|
332
|
+
* subsystem by {SDL2.init}.
|
333
|
+
*
|
334
|
+
*
|
335
|
+
* @!method destroy?
|
336
|
+
* Return true if the window is already destroyed.
|
337
|
+
*/
|
338
|
+
|
339
|
+
/*
|
340
|
+
* @overload create(title, x, y, w, h, flags)
|
341
|
+
* Create a window with the specified position (x,y), dimensions (w,h) and flags.
|
342
|
+
*
|
343
|
+
* @param [Integer] x the x position of the left-top of the window
|
344
|
+
* @param [Integer] y the y position of the left-top of the window
|
345
|
+
* @param [Integer] w the width of the window
|
346
|
+
* @param [Integer] h the height of the window
|
347
|
+
* @param [Integer] flags 0, or one or more {Flags} OR'd together
|
348
|
+
*
|
349
|
+
* @return [SDL2::Window] created window
|
350
|
+
*
|
351
|
+
*/
|
352
|
+
static VALUE Window_s_create(VALUE self, VALUE title, VALUE x, VALUE y, VALUE w, VALUE h,
|
353
|
+
VALUE flags)
|
354
|
+
{
|
355
|
+
SDL_Window* window;
|
356
|
+
VALUE win;
|
357
|
+
title = rb_str_export_to_enc(title, rb_utf8_encoding());
|
358
|
+
window = SDL_CreateWindow(StringValueCStr(title),
|
359
|
+
NUM2INT(x), NUM2INT(y), NUM2INT(w), NUM2INT(h),
|
360
|
+
NUM2UINT(flags));
|
361
|
+
if (window == NULL)
|
362
|
+
HANDLE_ERROR(-1);
|
363
|
+
|
364
|
+
win = Window_new(window);
|
365
|
+
rb_hash_aset(hash_windowid_to_window, UINT2NUM(SDL_GetWindowID(window)), win);
|
366
|
+
return win;
|
367
|
+
}
|
368
|
+
|
369
|
+
/*
|
370
|
+
* Get all windows under SDL.
|
371
|
+
*
|
372
|
+
* @return [Hash<Integer => SDL2::Window>]
|
373
|
+
* the hash from window id to the {SDL2::Window} objects.
|
374
|
+
*/
|
375
|
+
static VALUE Window_s_all_windows(VALUE self)
|
376
|
+
{
|
377
|
+
return rb_hash_dup(hash_windowid_to_window);
|
378
|
+
}
|
379
|
+
|
380
|
+
/*
|
381
|
+
* @overload find_by_id(id)
|
382
|
+
* Get the window from ID.
|
383
|
+
*
|
384
|
+
* @param id [Integer] the window id you want to find
|
385
|
+
* @return [SDL2::Window] the window associated with **id**
|
386
|
+
* @return [nil] when no window is associated with **id**
|
387
|
+
*
|
388
|
+
*/
|
389
|
+
static VALUE Window_s_find_by_id(VALUE self, VALUE id)
|
390
|
+
{
|
391
|
+
return rb_hash_aref(hash_windowid_to_window, id);
|
392
|
+
}
|
393
|
+
|
394
|
+
VALUE find_window_by_id(Uint32 id)
|
395
|
+
{
|
396
|
+
return Window_s_find_by_id(Qnil, UINT2NUM(id));
|
397
|
+
}
|
398
|
+
|
399
|
+
/*
|
400
|
+
* @overload destroy
|
401
|
+
* Destroy window.
|
402
|
+
*
|
403
|
+
* You cannot call almost all methods after calling this method.
|
404
|
+
* The exception is {#destroy?}.
|
405
|
+
*
|
406
|
+
* @return [void]
|
407
|
+
*/
|
408
|
+
static VALUE Window_destroy(VALUE self)
|
409
|
+
{
|
410
|
+
Window* w = Get_Window(self);
|
411
|
+
Window_destroy_internal(w);
|
412
|
+
SDL_DestroyWindow(w->window);
|
413
|
+
w->window = NULL;
|
414
|
+
return Qnil;
|
415
|
+
}
|
416
|
+
|
417
|
+
/*
|
418
|
+
* @overload create_renderer(index, flags)
|
419
|
+
* Create a 2D rendering context for a window.
|
420
|
+
*
|
421
|
+
* @param [Integer] index the index of the rendering driver to initialize,
|
422
|
+
* or -1 to initialize the first one supporting the requested flags
|
423
|
+
* @param [Integer] flags 0, or one or more [Renderer flag masks](SDL2) OR'd together;
|
424
|
+
*
|
425
|
+
* @return [SDL2::Renderer] the created renderer (rendering context)
|
426
|
+
*/
|
427
|
+
static VALUE Window_create_renderer(VALUE self, VALUE index, VALUE flags)
|
428
|
+
{
|
429
|
+
SDL_Renderer* sdl_renderer;
|
430
|
+
VALUE renderer;
|
431
|
+
sdl_renderer = SDL_CreateRenderer(Get_SDL_Window(self), NUM2INT(index), NUM2UINT(flags));
|
432
|
+
|
433
|
+
if (sdl_renderer == NULL)
|
434
|
+
HANDLE_ERROR(-1);
|
435
|
+
|
436
|
+
renderer = Renderer_new(sdl_renderer, Get_Window(self));
|
437
|
+
rb_iv_set(self, "renderer", renderer);
|
438
|
+
return renderer;
|
439
|
+
}
|
440
|
+
|
441
|
+
/*
|
442
|
+
* @overload renderer
|
443
|
+
* Return the renderer associate with the window
|
444
|
+
*
|
445
|
+
* @return [SDL2::Renderer] the associated renderer
|
446
|
+
* @return [nil] if no renderer is created yet
|
447
|
+
*/
|
448
|
+
static VALUE Window_renderer(VALUE self)
|
449
|
+
{
|
450
|
+
return rb_iv_get(self, "renderer");
|
451
|
+
}
|
452
|
+
|
453
|
+
/*
|
454
|
+
* Get the numeric ID of the window.
|
455
|
+
*
|
456
|
+
* @return [Integer]
|
457
|
+
*/
|
458
|
+
static VALUE Window_window_id(VALUE self)
|
459
|
+
{
|
460
|
+
return UINT2NUM(SDL_GetWindowID(Get_SDL_Window(self)));
|
461
|
+
}
|
462
|
+
|
463
|
+
/*
|
464
|
+
* Get information about the window.
|
465
|
+
*
|
466
|
+
* @return [SDL2::Window::Mode]
|
467
|
+
*/
|
468
|
+
static VALUE Window_display_mode(VALUE self)
|
469
|
+
{
|
470
|
+
SDL_DisplayMode mode;
|
471
|
+
HANDLE_ERROR(SDL_GetWindowDisplayMode(Get_SDL_Window(self), &mode));
|
472
|
+
return DisplayMode_new(&mode);
|
473
|
+
}
|
474
|
+
|
475
|
+
/*
|
476
|
+
* Get the display associated with the window.
|
477
|
+
*
|
478
|
+
* @return [SDL2::Display]
|
479
|
+
*/
|
480
|
+
static VALUE Window_display(VALUE self)
|
481
|
+
{
|
482
|
+
int display_index = HANDLE_ERROR(SDL_GetWindowDisplayIndex(Get_SDL_Window(self)));
|
483
|
+
return Display_new(display_index);
|
484
|
+
}
|
485
|
+
|
486
|
+
/*
|
487
|
+
* Get the brightness (gamma correction) of the window.
|
488
|
+
*
|
489
|
+
* @return [Float] the brightness
|
490
|
+
* @see #brightness=
|
491
|
+
*/
|
492
|
+
static VALUE Window_brightness(VALUE self)
|
493
|
+
{
|
494
|
+
return DBL2NUM(SDL_GetWindowBrightness(Get_SDL_Window(self)));
|
495
|
+
}
|
496
|
+
|
497
|
+
/*
|
498
|
+
* @overload brightness=(brightness)
|
499
|
+
* Set the brightness (gamma correction) of the window.
|
500
|
+
*
|
501
|
+
* @param brightness [Float] the brightness, 0.0 means complete dark and 1.0 means
|
502
|
+
* normal brightness.
|
503
|
+
* @return [brightness]
|
504
|
+
*
|
505
|
+
* @see #brightness
|
506
|
+
*/
|
507
|
+
static VALUE Window_set_brightness(VALUE self, VALUE brightness)
|
508
|
+
{
|
509
|
+
HANDLE_ERROR(SDL_SetWindowBrightness(Get_SDL_Window(self), NUM2DBL(brightness)));
|
510
|
+
return brightness;
|
511
|
+
}
|
512
|
+
|
513
|
+
/*
|
514
|
+
* Get the {SDL2::Window::Flags Window flag masks} of the window.
|
515
|
+
*
|
516
|
+
* @return [Integer] flags
|
517
|
+
* @see .create
|
518
|
+
*/
|
519
|
+
static VALUE Window_flags(VALUE self)
|
520
|
+
{
|
521
|
+
return UINT2NUM(SDL_GetWindowFlags(Get_SDL_Window(self)));
|
522
|
+
}
|
523
|
+
|
524
|
+
static VALUE gamma_table_to_Array(Uint16 r[])
|
525
|
+
{
|
526
|
+
int i;
|
527
|
+
VALUE ary = rb_ary_new2(256);
|
528
|
+
for (i=0; i<256; ++i)
|
529
|
+
rb_ary_push(ary, UINT2NUM(r[i]));
|
530
|
+
return ary;
|
531
|
+
}
|
532
|
+
|
533
|
+
/*
|
534
|
+
* Get the gamma ramp for a window
|
535
|
+
*
|
536
|
+
* @return [Array<Array<Integer>>] the gamma ramp,
|
537
|
+
* return value is red, green, and blue gamma tables and each gamma table
|
538
|
+
* has 256 Integers of 0-65535.
|
539
|
+
*
|
540
|
+
*/
|
541
|
+
static VALUE Window_gamma_ramp(VALUE self)
|
542
|
+
{
|
543
|
+
Uint16 r[256], g[256], b[256];
|
544
|
+
HANDLE_ERROR(SDL_GetWindowGammaRamp(Get_SDL_Window(self), r, g, b));
|
545
|
+
return rb_ary_new3(3,
|
546
|
+
gamma_table_to_Array(r),
|
547
|
+
gamma_table_to_Array(g),
|
548
|
+
gamma_table_to_Array(b));
|
549
|
+
}
|
550
|
+
|
551
|
+
/*
|
552
|
+
* @overload icon=(icon)
|
553
|
+
*
|
554
|
+
* Set the window icon.
|
555
|
+
*
|
556
|
+
* @param icon [SDL2::Surface] the icon for the window
|
557
|
+
* @return [icon]
|
558
|
+
*/
|
559
|
+
static VALUE Window_set_icon(VALUE self, VALUE icon)
|
560
|
+
{
|
561
|
+
SDL_SetWindowIcon(Get_SDL_Window(self), Get_SDL_Surface(icon));
|
562
|
+
return icon;
|
563
|
+
}
|
564
|
+
|
565
|
+
/*
|
566
|
+
* Return true if the input is grabbed to the window.
|
567
|
+
*
|
568
|
+
* @see #input_is_grabbed=
|
569
|
+
*/
|
570
|
+
static VALUE Window_input_is_grabbed_p(VALUE self)
|
571
|
+
{
|
572
|
+
return INT2BOOL(SDL_GetWindowGrab(Get_SDL_Window(self)));
|
573
|
+
}
|
574
|
+
|
575
|
+
/*
|
576
|
+
* @overload input_is_grabbed=(grabbed)
|
577
|
+
* Set the window's input grab mode.
|
578
|
+
*
|
579
|
+
* @param grabbed [Boolean] true to grub input, and false to release input
|
580
|
+
* @return [grabbed]
|
581
|
+
*
|
582
|
+
* @see #input_is_grabbed?
|
583
|
+
*/
|
584
|
+
static VALUE Window_set_input_is_grabbed(VALUE self, VALUE grabbed)
|
585
|
+
{
|
586
|
+
SDL_SetWindowGrab(Get_SDL_Window(self), RTEST(grabbed));
|
587
|
+
return grabbed;
|
588
|
+
}
|
589
|
+
|
590
|
+
static VALUE Window_get_int_int(void (*func)(SDL_Window*, int*, int*), VALUE window)
|
591
|
+
{
|
592
|
+
int n, m;
|
593
|
+
func(Get_SDL_Window(window), &n, &m);
|
594
|
+
return rb_ary_new3(2, INT2NUM(n), INT2NUM(m));
|
595
|
+
}
|
596
|
+
|
597
|
+
static VALUE Window_set_int_int(void (*func)(SDL_Window*, int, int), VALUE window, VALUE val)
|
598
|
+
{
|
599
|
+
Check_Type(val, T_ARRAY);
|
600
|
+
if (RARRAY_LEN(val) != 2)
|
601
|
+
rb_raise(rb_eArgError, "Wrong array size (%ld for 2)", RARRAY_LEN(val));
|
602
|
+
func(Get_SDL_Window(window), NUM2INT(rb_ary_entry(val, 0)), NUM2INT(rb_ary_entry(val, 1)));
|
603
|
+
return Qnil;
|
604
|
+
}
|
605
|
+
|
606
|
+
/*
|
607
|
+
* Get the maximum size of the window's client area.
|
608
|
+
*
|
609
|
+
* @return [Integer,Integer] maximum width and maximum height.
|
610
|
+
*
|
611
|
+
* @see #maximum_size=
|
612
|
+
*/
|
613
|
+
static VALUE Window_maximum_size(VALUE self)
|
614
|
+
{
|
615
|
+
return Window_get_int_int(SDL_GetWindowMaximumSize, self);
|
616
|
+
}
|
617
|
+
|
618
|
+
/*
|
619
|
+
* @overload maximum_size=(size)
|
620
|
+
* Set the maximum size of the window's client area.
|
621
|
+
*
|
622
|
+
* @param size [[Integer, Integer]] maximum width and maximum height,
|
623
|
+
* the both must be positive.
|
624
|
+
*
|
625
|
+
* @return [size]
|
626
|
+
*
|
627
|
+
* @see #maximum_size
|
628
|
+
*/
|
629
|
+
static VALUE Window_set_maximum_size(VALUE self, VALUE max_size)
|
630
|
+
{
|
631
|
+
return Window_set_int_int(SDL_SetWindowMaximumSize, self, max_size);
|
632
|
+
}
|
633
|
+
|
634
|
+
/*
|
635
|
+
* Get the minimum size of the window's client area.
|
636
|
+
*
|
637
|
+
* @return [Integer,Integer] minimum width and minimum height.
|
638
|
+
*
|
639
|
+
* @see #minimum_size=
|
640
|
+
*/
|
641
|
+
static VALUE Window_minimum_size(VALUE self)
|
642
|
+
{
|
643
|
+
return Window_get_int_int(SDL_GetWindowMinimumSize, self);
|
644
|
+
}
|
645
|
+
|
646
|
+
/*
|
647
|
+
* @overload minimum_size=(size)
|
648
|
+
* Set the minimum size of the window's client area.
|
649
|
+
*
|
650
|
+
* @param size [[Integer, Integer]] minimum width and minimum height,
|
651
|
+
* the both must be positive.
|
652
|
+
*
|
653
|
+
* @return [size]
|
654
|
+
*
|
655
|
+
* @see #minimum_size
|
656
|
+
*/
|
657
|
+
static VALUE Window_set_minimum_size(VALUE self, VALUE min_size)
|
658
|
+
{
|
659
|
+
return Window_set_int_int(SDL_SetWindowMinimumSize, self, min_size);
|
660
|
+
}
|
661
|
+
|
662
|
+
/*
|
663
|
+
* Get the position of the window.
|
664
|
+
*
|
665
|
+
* @return [Integer,Integer] the x position and the y position
|
666
|
+
*
|
667
|
+
* @see #position=
|
668
|
+
*/
|
669
|
+
static VALUE Window_position(VALUE self)
|
670
|
+
{
|
671
|
+
return Window_get_int_int(SDL_GetWindowPosition, self);
|
672
|
+
}
|
673
|
+
|
674
|
+
/*
|
675
|
+
* @overload position=(xy)
|
676
|
+
* Set the position of the window
|
677
|
+
*
|
678
|
+
* @param xy [[Integer, Integer]] the x position and the y position,
|
679
|
+
* {SDL2::Window::POS_CENTERED} and {SDL2::Window::POS_UNDEFINED}
|
680
|
+
* are available.
|
681
|
+
*
|
682
|
+
* @return [size]
|
683
|
+
*
|
684
|
+
* @see #position
|
685
|
+
*/
|
686
|
+
static VALUE Window_set_position(VALUE self, VALUE xy)
|
687
|
+
{
|
688
|
+
return Window_set_int_int(SDL_SetWindowPosition, self, xy);
|
689
|
+
}
|
690
|
+
|
691
|
+
/*
|
692
|
+
* Get the size of the window.
|
693
|
+
*
|
694
|
+
* @return [[Integer, Integer]] the width and the height
|
695
|
+
*
|
696
|
+
* @see size=
|
697
|
+
*/
|
698
|
+
static VALUE Window_size(VALUE self)
|
699
|
+
{
|
700
|
+
return Window_get_int_int(SDL_GetWindowSize, self);
|
701
|
+
}
|
702
|
+
|
703
|
+
/*
|
704
|
+
* @overload size=(size)
|
705
|
+
* Set the size of the window.
|
706
|
+
*
|
707
|
+
* @param wh [[Integer, Integer]] new width and new height
|
708
|
+
*
|
709
|
+
* @return [size]
|
710
|
+
*
|
711
|
+
* @see #size
|
712
|
+
*/
|
713
|
+
static VALUE Window_set_size(VALUE self, VALUE size)
|
714
|
+
{
|
715
|
+
return Window_set_int_int(SDL_SetWindowSize, self, size);
|
716
|
+
}
|
717
|
+
|
718
|
+
/*
|
719
|
+
* Get the title of the window
|
720
|
+
*
|
721
|
+
* @return [String] the title, in UTF-8 encoding
|
722
|
+
*
|
723
|
+
* @see #title=
|
724
|
+
*/
|
725
|
+
static VALUE Window_title(VALUE self)
|
726
|
+
{
|
727
|
+
return utf8str_new_cstr(SDL_GetWindowTitle(Get_SDL_Window(self)));
|
728
|
+
}
|
729
|
+
|
730
|
+
/*
|
731
|
+
* Return true if the window is bordered
|
732
|
+
*
|
733
|
+
* @return [Boolean]
|
734
|
+
*
|
735
|
+
* @see #bordered=
|
736
|
+
*/
|
737
|
+
static VALUE Window_bordered(VALUE self)
|
738
|
+
{
|
739
|
+
return INT2BOOL(!(SDL_GetWindowFlags(Get_SDL_Window(self)) & SDL_WINDOW_BORDERLESS));
|
740
|
+
}
|
741
|
+
|
742
|
+
/*
|
743
|
+
* @overload bordered=(bordered)
|
744
|
+
* Set the border state of the window.
|
745
|
+
*
|
746
|
+
* @param bordered [Boolean] true for bordered window, anad false for
|
747
|
+
* borderless window
|
748
|
+
*
|
749
|
+
* @return [bordered]
|
750
|
+
*
|
751
|
+
* @see #bordered
|
752
|
+
*/
|
753
|
+
static VALUE Window_set_bordered(VALUE self, VALUE bordered)
|
754
|
+
{
|
755
|
+
SDL_SetWindowBordered(Get_SDL_Window(self), RTEST(bordered));
|
756
|
+
return bordered;
|
757
|
+
}
|
758
|
+
|
759
|
+
/*
|
760
|
+
* @overload title=(title)
|
761
|
+
* Set the title of the window.
|
762
|
+
*
|
763
|
+
* @param title [String] the title
|
764
|
+
* @return [title]
|
765
|
+
*
|
766
|
+
* @see #title
|
767
|
+
*/
|
768
|
+
static VALUE Window_set_title(VALUE self, VALUE title)
|
769
|
+
{
|
770
|
+
title = rb_str_export_to_enc(title, rb_utf8_encoding());
|
771
|
+
SDL_SetWindowTitle(Get_SDL_Window(self), StringValueCStr(title));
|
772
|
+
return Qnil;
|
773
|
+
}
|
774
|
+
|
775
|
+
/*
|
776
|
+
* @overload surface
|
777
|
+
* Get the window surface.
|
778
|
+
*
|
779
|
+
* @return [SDL2::Surface]
|
780
|
+
*
|
781
|
+
*/
|
782
|
+
static VALUE Window_surface(VALUE self)
|
783
|
+
{
|
784
|
+
SDL_Surface *surface = SDL_GetWindowSurface(Get_SDL_Window(self));
|
785
|
+
if(surface == NULL) {
|
786
|
+
SDL_ERROR();
|
787
|
+
return Qnil;
|
788
|
+
} else {
|
789
|
+
return Surface_new(surface);
|
790
|
+
}
|
791
|
+
}
|
792
|
+
|
793
|
+
/*
|
794
|
+
* @overload update
|
795
|
+
* Copy window surface to the screen.
|
796
|
+
*
|
797
|
+
* @return [nil]
|
798
|
+
*
|
799
|
+
*/
|
800
|
+
static VALUE Window_update(VALUE self)
|
801
|
+
{
|
802
|
+
HANDLE_ERROR(SDL_UpdateWindowSurface(Get_SDL_Window(self)));
|
803
|
+
return Qnil;
|
804
|
+
}
|
805
|
+
|
806
|
+
/*
|
807
|
+
define(`SIMPLE_WINDOW_METHOD',`static VALUE Window_$2(VALUE self)
|
808
|
+
{
|
809
|
+
SDL_$1Window(Get_SDL_Window(self)); return Qnil;
|
810
|
+
}')
|
811
|
+
*/
|
812
|
+
/*
|
813
|
+
* Show the window.
|
814
|
+
*
|
815
|
+
* @return [nil]
|
816
|
+
* @see #hide
|
817
|
+
*/
|
818
|
+
SIMPLE_WINDOW_METHOD(Show, show);
|
819
|
+
|
820
|
+
/*
|
821
|
+
* Hide the window.
|
822
|
+
*
|
823
|
+
* @return [nil]
|
824
|
+
* @see #show
|
825
|
+
*/
|
826
|
+
SIMPLE_WINDOW_METHOD(Hide, hide);
|
827
|
+
|
828
|
+
/*
|
829
|
+
* Maximize the window.
|
830
|
+
*
|
831
|
+
* @return [nil]
|
832
|
+
* @see #minimize
|
833
|
+
* @see #restore
|
834
|
+
*/
|
835
|
+
SIMPLE_WINDOW_METHOD(Maximize, maximize);
|
836
|
+
|
837
|
+
/*
|
838
|
+
* Minimize the window.
|
839
|
+
*
|
840
|
+
* @return [nil]
|
841
|
+
* @see #maximize
|
842
|
+
* @see #restore
|
843
|
+
*/
|
844
|
+
SIMPLE_WINDOW_METHOD(Minimize, minimize);
|
845
|
+
|
846
|
+
/*
|
847
|
+
* Raise the window above other windows and set the input focus.
|
848
|
+
*
|
849
|
+
* @return [nil]
|
850
|
+
*/
|
851
|
+
SIMPLE_WINDOW_METHOD(Raise, raise);
|
852
|
+
|
853
|
+
/*
|
854
|
+
* Restore the size and position of a minimized or maixmized window.
|
855
|
+
*
|
856
|
+
* @return [nil]
|
857
|
+
* @see #minimize
|
858
|
+
* @see #maximize
|
859
|
+
*/
|
860
|
+
SIMPLE_WINDOW_METHOD(Restore, restore);
|
861
|
+
|
862
|
+
/*
|
863
|
+
* Get the fullscreen stete of the window
|
864
|
+
*
|
865
|
+
* @return [Integer] 0 for window mode, {SDL2::Window::Flags::FULLSCREEN} for
|
866
|
+
* fullscreen mode, and {SDL2::Window::Flags::FULLSCREEN_DESKTOP} for fullscreen
|
867
|
+
* at the current desktop resolution.
|
868
|
+
*
|
869
|
+
* @see #fullscreen_mode=
|
870
|
+
* @see #flags
|
871
|
+
*/
|
872
|
+
static VALUE Window_fullscreen_mode(VALUE self)
|
873
|
+
{
|
874
|
+
Uint32 flags = SDL_GetWindowFlags(Get_SDL_Window(self));
|
875
|
+
return UINT2NUM(flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_FULLSCREEN_DESKTOP));
|
876
|
+
}
|
877
|
+
|
878
|
+
/*
|
879
|
+
* @overload fullscreen_mode=(flag)
|
880
|
+
* Set the fullscreen state of the window
|
881
|
+
*
|
882
|
+
* @param flag [Integer] 0 for window mode, {SDL2::Window::Flags::FULLSCREEN} for
|
883
|
+
* fullscreen mode, and {SDL2::Flags::Window::FULLSCREEN_DESKTOP} for fullscreen
|
884
|
+
* at the current desktop resolution.
|
885
|
+
* @return [flag]
|
886
|
+
*
|
887
|
+
* @see #fullscreen_mode
|
888
|
+
*/
|
889
|
+
static VALUE Window_set_fullscreen_mode(VALUE self, VALUE flags)
|
890
|
+
{
|
891
|
+
HANDLE_ERROR(SDL_SetWindowFullscreen(Get_SDL_Window(self), NUM2UINT(flags)));
|
892
|
+
return flags;
|
893
|
+
}
|
894
|
+
|
895
|
+
#if SDL_VERSION_ATLEAST(2,0,1)
|
896
|
+
/*
|
897
|
+
* Get the size of the drawable region.
|
898
|
+
*
|
899
|
+
* @return [[Integer, Integer]] the width and height of the region
|
900
|
+
*/
|
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-module: SDL2::Window::Flags
|
952
|
+
*
|
953
|
+
* OR'd bits of the constants of this module represents window states.
|
954
|
+
*
|
955
|
+
* You can see a window state using {SDL2::Window#flags}
|
956
|
+
* and create a window with a specified
|
957
|
+
* state using flag parameter of {SDL2::Window.create}.
|
958
|
+
*
|
959
|
+
*/
|
960
|
+
|
961
|
+
/*
|
962
|
+
* Document-class: SDL2::Display
|
963
|
+
*
|
964
|
+
* This class represents displays, screens, or monitors.
|
965
|
+
*
|
966
|
+
* This means that if you use dual screen, {.displays} returns two displays.
|
967
|
+
*
|
968
|
+
* This class handles color depth, resolution, and refresh rate of displays.
|
969
|
+
*
|
970
|
+
*
|
971
|
+
* @!attribute [r] index
|
972
|
+
* The index of the display, 0 origin
|
973
|
+
* @return [Integer]
|
974
|
+
*
|
975
|
+
* @!attribute [r] name
|
976
|
+
* The name of the display
|
977
|
+
* @return [Stirng]
|
978
|
+
*
|
979
|
+
*/
|
980
|
+
|
981
|
+
/*
|
982
|
+
* Get all connected displays.
|
983
|
+
*
|
984
|
+
* @return [Array<SDL2::Display>]
|
985
|
+
*
|
986
|
+
*/
|
987
|
+
static VALUE Display_s_displays(VALUE self)
|
988
|
+
{
|
989
|
+
int i;
|
990
|
+
int num_displays = HANDLE_ERROR(SDL_GetNumVideoDisplays());
|
991
|
+
VALUE displays = rb_ary_new2(num_displays);
|
992
|
+
for (i=0; i<num_displays; ++i)
|
993
|
+
rb_ary_push(displays, Display_new(i));
|
994
|
+
return displays;
|
995
|
+
}
|
996
|
+
|
997
|
+
static int Display_index_int(VALUE display)
|
998
|
+
{
|
999
|
+
return NUM2INT(rb_iv_get(display, "@index"));
|
1000
|
+
}
|
1001
|
+
|
1002
|
+
/*
|
1003
|
+
* Get available display modes of the display.
|
1004
|
+
*
|
1005
|
+
* @return [Array<SDL2::Display::Mode>]
|
1006
|
+
*
|
1007
|
+
*/
|
1008
|
+
static VALUE Display_modes(VALUE self)
|
1009
|
+
{
|
1010
|
+
int i;
|
1011
|
+
int index = Display_index_int(self);
|
1012
|
+
int num_modes = SDL_GetNumDisplayModes(index);
|
1013
|
+
VALUE modes = rb_ary_new2(num_modes);
|
1014
|
+
for (i=0; i<num_modes; ++i) {
|
1015
|
+
SDL_DisplayMode mode;
|
1016
|
+
HANDLE_ERROR(SDL_GetDisplayMode(index, i, &mode));
|
1017
|
+
rb_ary_push(modes, DisplayMode_new(&mode));
|
1018
|
+
}
|
1019
|
+
return modes;
|
1020
|
+
}
|
1021
|
+
|
1022
|
+
/*
|
1023
|
+
* Get the current display mode.
|
1024
|
+
*
|
1025
|
+
* @return [SDL2::Display::Mode]
|
1026
|
+
*
|
1027
|
+
* @see #desktop_mode
|
1028
|
+
*/
|
1029
|
+
static VALUE Display_current_mode(VALUE self)
|
1030
|
+
{
|
1031
|
+
SDL_DisplayMode mode;
|
1032
|
+
HANDLE_ERROR(SDL_GetCurrentDisplayMode(Display_index_int(self), &mode));
|
1033
|
+
return DisplayMode_new(&mode);
|
1034
|
+
}
|
1035
|
+
|
1036
|
+
/*
|
1037
|
+
* Get the desktop display mode.
|
1038
|
+
*
|
1039
|
+
* Normally, the return value of this method is
|
1040
|
+
* same as {#current_mode}. However,
|
1041
|
+
* when you use fullscreen and chagne the resolution,
|
1042
|
+
* this method returns the previous native display mode,
|
1043
|
+
* and not the current mode.
|
1044
|
+
*
|
1045
|
+
* @return [SDL2::Display::Mode]
|
1046
|
+
*/
|
1047
|
+
static VALUE Display_desktop_mode(VALUE self)
|
1048
|
+
{
|
1049
|
+
SDL_DisplayMode mode;
|
1050
|
+
HANDLE_ERROR(SDL_GetDesktopDisplayMode(Display_index_int(self), &mode));
|
1051
|
+
return DisplayMode_new(&mode);
|
1052
|
+
}
|
1053
|
+
|
1054
|
+
/*
|
1055
|
+
* @overload closest_mode(mode)
|
1056
|
+
* Get the available display mode closest match to **mode**.
|
1057
|
+
*
|
1058
|
+
* @param mode [SDL2::Display::Mode] the desired display mode
|
1059
|
+
* @return [SDL2::Display::Mode]
|
1060
|
+
*
|
1061
|
+
*/
|
1062
|
+
static VALUE Display_closest_mode(VALUE self, VALUE mode)
|
1063
|
+
{
|
1064
|
+
SDL_DisplayMode closest;
|
1065
|
+
if (!SDL_GetClosestDisplayMode(Display_index_int(self), Get_SDL_DisplayMode(mode),
|
1066
|
+
&closest))
|
1067
|
+
SDL_ERROR();
|
1068
|
+
return DisplayMode_new(&closest);
|
1069
|
+
}
|
1070
|
+
|
1071
|
+
/*
|
1072
|
+
* Get the desktop area represented by the display, with the primary
|
1073
|
+
* display located at (0, 0).
|
1074
|
+
*
|
1075
|
+
* @return [Rect]
|
1076
|
+
*/
|
1077
|
+
static VALUE Display_bounds(VALUE self)
|
1078
|
+
{
|
1079
|
+
VALUE rect = rb_obj_alloc(cRect);
|
1080
|
+
HANDLE_ERROR(SDL_GetDisplayBounds(Display_index_int(self), Get_SDL_Rect(rect)));
|
1081
|
+
return rect;
|
1082
|
+
}
|
1083
|
+
|
1084
|
+
static Uint32 uint32_for_format(VALUE format)
|
1085
|
+
{
|
1086
|
+
if (rb_obj_is_kind_of(format, cPixelFormat))
|
1087
|
+
return NUM2UINT(rb_iv_get(format, "@format"));
|
1088
|
+
else
|
1089
|
+
return NUM2UINT(format);
|
1090
|
+
}
|
1091
|
+
|
1092
|
+
/*
|
1093
|
+
* Document-class: SDL2::Display::Mode
|
1094
|
+
*
|
1095
|
+
* This class represents the display mode.
|
1096
|
+
*
|
1097
|
+
* An object of this class has information about color depth, refresh rate,
|
1098
|
+
* and resolution of a display.
|
1099
|
+
*
|
1100
|
+
*
|
1101
|
+
*/
|
1102
|
+
|
1103
|
+
/*
|
1104
|
+
* @overload initialize(format, w, h, refresh_rate)
|
1105
|
+
* Create a new Display::Mode object.
|
1106
|
+
*
|
1107
|
+
* @param format [SDL2::PixelFormat, Integer] pixel format
|
1108
|
+
* @param w [Integer] the width
|
1109
|
+
* @param h [Integer] the height
|
1110
|
+
* @param refresh_rate [Integer] refresh rate
|
1111
|
+
*/
|
1112
|
+
static VALUE DisplayMode_initialize(VALUE self, VALUE format, VALUE w, VALUE h,
|
1113
|
+
VALUE refresh_rate)
|
1114
|
+
{
|
1115
|
+
SDL_DisplayMode* mode = Get_SDL_DisplayMode(self);
|
1116
|
+
mode->format = uint32_for_format(format);
|
1117
|
+
mode->w = NUM2INT(w); mode->h = NUM2INT(h);
|
1118
|
+
mode->refresh_rate = NUM2INT(refresh_rate);
|
1119
|
+
return Qnil;
|
1120
|
+
}
|
1121
|
+
|
1122
|
+
/* @return [String] inspection string */
|
1123
|
+
static VALUE DisplayMode_inspect(VALUE self)
|
1124
|
+
{
|
1125
|
+
SDL_DisplayMode* mode = Get_SDL_DisplayMode(self);
|
1126
|
+
return rb_sprintf("<%s: format=%s w=%d h=%d refresh_rate=%d>",
|
1127
|
+
rb_obj_classname(self), SDL_GetPixelFormatName(mode->format),
|
1128
|
+
mode->w, mode->h, mode->refresh_rate);
|
1129
|
+
|
1130
|
+
}
|
1131
|
+
|
1132
|
+
/* @return [SDL2::PixelFormat] the pixel format of the display mode */
|
1133
|
+
static VALUE DisplayMode_format(VALUE self)
|
1134
|
+
{
|
1135
|
+
return PixelFormat_new(Get_SDL_DisplayMode(self)->format);
|
1136
|
+
}
|
1137
|
+
|
1138
|
+
/* @return [Integer] the width of the screen of the display mode */
|
1139
|
+
static VALUE DisplayMode_w(VALUE self)
|
1140
|
+
{
|
1141
|
+
return INT2NUM(Get_SDL_DisplayMode(self)->w);
|
1142
|
+
}
|
1143
|
+
|
1144
|
+
/* @return [Integer] the height of the screen of the display mode */
|
1145
|
+
static VALUE DisplayMode_h(VALUE self)
|
1146
|
+
{
|
1147
|
+
return INT2NUM(Get_SDL_DisplayMode(self)->h);
|
1148
|
+
}
|
1149
|
+
|
1150
|
+
/* @return [Integer] the refresh rate of the display mode */
|
1151
|
+
static VALUE DisplayMode_refresh_rate(VALUE self)
|
1152
|
+
{
|
1153
|
+
return INT2NUM(Get_SDL_DisplayMode(self)->refresh_rate);
|
1154
|
+
}
|
1155
|
+
|
1156
|
+
/*
|
1157
|
+
* Document-class: SDL2::Renderer
|
1158
|
+
*
|
1159
|
+
* This class represents a 2D rendering context for a window.
|
1160
|
+
*
|
1161
|
+
* You can create a renderer using {SDL2::Window#create_renderer} and
|
1162
|
+
* use it to draw figures on the window.
|
1163
|
+
*
|
1164
|
+
*
|
1165
|
+
* @!method destroy?
|
1166
|
+
* Return true if the renderer is {#destroy destroyed}.
|
1167
|
+
*
|
1168
|
+
*/
|
1169
|
+
|
1170
|
+
|
1171
|
+
/*
|
1172
|
+
* @overload drivers_info
|
1173
|
+
* Return information of all available rendering contexts.
|
1174
|
+
* @return [Array<SDL2::Renderer::Info>] information about rendering contexts
|
1175
|
+
*
|
1176
|
+
*/
|
1177
|
+
static VALUE Renderer_s_drivers_info(VALUE self)
|
1178
|
+
{
|
1179
|
+
int num_drivers = SDL_GetNumRenderDrivers();
|
1180
|
+
VALUE info_ary = rb_ary_new();
|
1181
|
+
int i;
|
1182
|
+
for (i=0; i<num_drivers; ++i) {
|
1183
|
+
SDL_RendererInfo info;
|
1184
|
+
HANDLE_ERROR(SDL_GetRenderDriverInfo(i, &info));
|
1185
|
+
rb_ary_push(info_ary, RendererInfo_new(&info));
|
1186
|
+
}
|
1187
|
+
return info_ary;
|
1188
|
+
}
|
1189
|
+
|
1190
|
+
/*
|
1191
|
+
* Destroy the rendering context and free associated textures.
|
1192
|
+
*
|
1193
|
+
* @return [nil]
|
1194
|
+
* @see #destroy?
|
1195
|
+
*/
|
1196
|
+
static VALUE Renderer_destroy(VALUE self)
|
1197
|
+
{
|
1198
|
+
Renderer_destroy_internal(Get_Renderer(self));
|
1199
|
+
return Qnil;
|
1200
|
+
}
|
1201
|
+
|
1202
|
+
/*
|
1203
|
+
* @overload create_texture(format, access, w, h)
|
1204
|
+
* Create a new texture for the rendering context.
|
1205
|
+
*
|
1206
|
+
* You can use the following constants to specify access pattern
|
1207
|
+
*
|
1208
|
+
* * {SDL2::Texture::ACCESS_STATIC}
|
1209
|
+
* * {SDL2::Texture::ACCESS_STREAMING}
|
1210
|
+
* * {SDL2::Texture::ACCESS_TARGET}
|
1211
|
+
*
|
1212
|
+
* @param [SDL2::PixelFormat,Integer] format format of the texture
|
1213
|
+
* @param [Integer] access texture access pattern
|
1214
|
+
* @param [Integer] w the width ofthe texture in pixels
|
1215
|
+
* @param [Integer] h the height ofthe texture in pixels
|
1216
|
+
*
|
1217
|
+
* @return [SDL2::Texture] the created texture
|
1218
|
+
*
|
1219
|
+
* @raise [SDL2::Error] raised when the texture cannot be created
|
1220
|
+
*
|
1221
|
+
* @see #create_texture_from
|
1222
|
+
*/
|
1223
|
+
static VALUE Renderer_create_texture(VALUE self, VALUE format, VALUE access,
|
1224
|
+
VALUE w, VALUE h)
|
1225
|
+
{
|
1226
|
+
SDL_Texture* texture = SDL_CreateTexture(Get_SDL_Renderer(self),
|
1227
|
+
uint32_for_format(format),
|
1228
|
+
NUM2INT(access), NUM2INT(w), NUM2INT(h));
|
1229
|
+
if (!texture)
|
1230
|
+
SDL_ERROR();
|
1231
|
+
return Texture_new(texture, Get_Renderer(self));
|
1232
|
+
}
|
1233
|
+
|
1234
|
+
/*
|
1235
|
+
* @overload create_texture_from(surface)
|
1236
|
+
* Create a texture from an existing surface.
|
1237
|
+
*
|
1238
|
+
* @param [SDL2::Surface] surface the surface containing pixels for the texture
|
1239
|
+
* @return [SDL2::Texture] the created texture
|
1240
|
+
*
|
1241
|
+
* @raise [SDL2::Error] raised when the texture cannot be created
|
1242
|
+
*
|
1243
|
+
* @see #create_texture
|
1244
|
+
*/
|
1245
|
+
static VALUE Renderer_create_texture_from(VALUE self, VALUE surface)
|
1246
|
+
{
|
1247
|
+
SDL_Texture* texture = SDL_CreateTextureFromSurface(Get_SDL_Renderer(self),
|
1248
|
+
Get_SDL_Surface(surface));
|
1249
|
+
if (texture == NULL)
|
1250
|
+
SDL_ERROR();
|
1251
|
+
|
1252
|
+
return Texture_new(texture, Get_Renderer(self));
|
1253
|
+
}
|
1254
|
+
|
1255
|
+
static SDL_Rect* Get_SDL_Rect_or_NULL(VALUE rect)
|
1256
|
+
{
|
1257
|
+
return rect == Qnil ? NULL : Get_SDL_Rect(rect);
|
1258
|
+
}
|
1259
|
+
|
1260
|
+
static SDL_Point* Get_SDL_Point_or_NULL(VALUE point)
|
1261
|
+
{
|
1262
|
+
return point == Qnil ? NULL : Get_SDL_Point(point);
|
1263
|
+
}
|
1264
|
+
|
1265
|
+
/*
|
1266
|
+
* @overload copy(texture, srcrect, dstrect)
|
1267
|
+
* Copy a portion of the texture to the current rendering target.
|
1268
|
+
*
|
1269
|
+
* @param [SDL2::Texture] texture the source texture
|
1270
|
+
* @param [SDL2::Rect,nil] srcrect the source rectangle, or nil for the entire texture
|
1271
|
+
* @param [SDL2::Rect,nil] dstrect the destination rectangle, or nil for the entire
|
1272
|
+
* rendering target; the texture will be stretched to fill the given rectangle
|
1273
|
+
*
|
1274
|
+
* @return [void]
|
1275
|
+
*
|
1276
|
+
* @see #copy_ex
|
1277
|
+
*/
|
1278
|
+
static VALUE Renderer_copy(VALUE self, VALUE texture, VALUE srcrect, VALUE dstrect)
|
1279
|
+
{
|
1280
|
+
HANDLE_ERROR(SDL_RenderCopy(Get_SDL_Renderer(self),
|
1281
|
+
Get_SDL_Texture(texture),
|
1282
|
+
Get_SDL_Rect_or_NULL(srcrect),
|
1283
|
+
Get_SDL_Rect_or_NULL(dstrect)));
|
1284
|
+
return Qnil;
|
1285
|
+
}
|
1286
|
+
|
1287
|
+
/*
|
1288
|
+
* @overload copy_ex(texture, srcrect, dstrect, angle, center, flip)
|
1289
|
+
* Copy a portion of the texture to the current rendering target,
|
1290
|
+
* rotating it by angle around the given center and also flipping
|
1291
|
+
* it top-bottom and/or left-right.
|
1292
|
+
*
|
1293
|
+
* You can use the following constants to specify the horizontal/vertical flip:
|
1294
|
+
*
|
1295
|
+
* * {SDL2::Renderer::FLIP_HORIZONTAL} - flip horizontally
|
1296
|
+
* * {SDL2::Renderer::FLIP_VERTICAL} - flip vertically
|
1297
|
+
* * {SDL2::Renderer::FLIP_NONE} - do not flip, equal to zero
|
1298
|
+
*
|
1299
|
+
*
|
1300
|
+
* @param [SDL2::Texture] texture the source texture
|
1301
|
+
* @param [SDL2::Rect,nil] srcrect the source rectangle, or nil for the entire texture
|
1302
|
+
* @param [SDL2::Rect,nil] dstrect the destination rectangle, or nil for the entire
|
1303
|
+
* rendering target; the texture will be stretched to fill the given rectangle
|
1304
|
+
* @param [Float] angle an angle in degree indicating the rotation
|
1305
|
+
* that will be applied to dstrect
|
1306
|
+
* @param [SDL2::Point,nil] center the point around which dstrect will be rotated,
|
1307
|
+
* (if nil, rotation will be done around the center of dstrect)
|
1308
|
+
* @param [Integer] flip bits OR'd of the flip consntants
|
1309
|
+
*
|
1310
|
+
* @return [void]
|
1311
|
+
*
|
1312
|
+
* @see #copy
|
1313
|
+
*/
|
1314
|
+
static VALUE Renderer_copy_ex(VALUE self, VALUE texture, VALUE srcrect, VALUE dstrect,
|
1315
|
+
VALUE angle, VALUE center, VALUE flip)
|
1316
|
+
{
|
1317
|
+
HANDLE_ERROR(SDL_RenderCopyEx(Get_SDL_Renderer(self),
|
1318
|
+
Get_SDL_Texture(texture),
|
1319
|
+
Get_SDL_Rect_or_NULL(srcrect),
|
1320
|
+
Get_SDL_Rect_or_NULL(dstrect),
|
1321
|
+
NUM2DBL(angle),
|
1322
|
+
Get_SDL_Point_or_NULL(center),
|
1323
|
+
NUM2INT(flip)));
|
1324
|
+
return Qnil;
|
1325
|
+
}
|
1326
|
+
|
1327
|
+
/*
|
1328
|
+
* Update the screen with rendering performed
|
1329
|
+
* @return [nil]
|
1330
|
+
*/
|
1331
|
+
static VALUE Renderer_present(VALUE self)
|
1332
|
+
{
|
1333
|
+
SDL_RenderPresent(Get_SDL_Renderer(self));
|
1334
|
+
return Qnil;
|
1335
|
+
}
|
1336
|
+
|
1337
|
+
/*
|
1338
|
+
* Crear the rendering target with the drawing color.
|
1339
|
+
* @return [nil]
|
1340
|
+
*
|
1341
|
+
* @see #draw_color=
|
1342
|
+
*/
|
1343
|
+
static VALUE Renderer_clear(VALUE self)
|
1344
|
+
{
|
1345
|
+
HANDLE_ERROR(SDL_RenderClear(Get_SDL_Renderer(self)));
|
1346
|
+
return Qnil;
|
1347
|
+
}
|
1348
|
+
|
1349
|
+
/*
|
1350
|
+
* Get the color used for drawing operations
|
1351
|
+
* @return [[Integer,Integer,Integer,Integer]]
|
1352
|
+
* red, green, blue, and alpha components of the drawing color
|
1353
|
+
* (all components are more than or equal to 0 and less than and equal to 255)
|
1354
|
+
*
|
1355
|
+
* @see #draw_color=
|
1356
|
+
*/
|
1357
|
+
static VALUE Renderer_draw_color(VALUE self)
|
1358
|
+
{
|
1359
|
+
Uint8 r, g, b, a;
|
1360
|
+
HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self), &r, &g, &b, &a));
|
1361
|
+
return rb_ary_new3(4, INT2FIX(r), INT2FIX(g), INT2FIX(b), INT2FIX(a));
|
1362
|
+
}
|
1363
|
+
|
1364
|
+
/*
|
1365
|
+
* @overload draw_color=(color)
|
1366
|
+
* Set the color used for drawing operations
|
1367
|
+
*
|
1368
|
+
* All color components (including alpha) must be more than or equal to 0
|
1369
|
+
* and less than and equal to 255
|
1370
|
+
*
|
1371
|
+
* This method effects the following methods.
|
1372
|
+
*
|
1373
|
+
* * {#draw_line}
|
1374
|
+
* * {#draw_point}
|
1375
|
+
* * {#draw_rect}
|
1376
|
+
* * {#fill_rect}
|
1377
|
+
* * {#clear}
|
1378
|
+
*
|
1379
|
+
* @param [Integer] color
|
1380
|
+
* red, green, and blue components used for drawing
|
1381
|
+
* @param [[Integer, Integer, Integer, Integer]] color
|
1382
|
+
* red, green, blue, and alpha components used for drawing
|
1383
|
+
*
|
1384
|
+
* @return [color]
|
1385
|
+
*
|
1386
|
+
* @see #draw_color
|
1387
|
+
*/
|
1388
|
+
static VALUE Renderer_set_draw_color(VALUE self, VALUE rgba)
|
1389
|
+
{
|
1390
|
+
SDL_Color color = Color_to_SDL_Color(rgba);
|
1391
|
+
|
1392
|
+
HANDLE_ERROR(SDL_SetRenderDrawColor(Get_SDL_Renderer(self),
|
1393
|
+
color.r, color.g, color.b, color.a));
|
1394
|
+
|
1395
|
+
return rgba;
|
1396
|
+
}
|
1397
|
+
|
1398
|
+
/*
|
1399
|
+
* @overload draw_line(x1, y1, x2, y2)
|
1400
|
+
* Draw a line from (x1, y1) to (x2, y2) using drawing color given by
|
1401
|
+
* {#draw_color=}.
|
1402
|
+
*
|
1403
|
+
* @param [Integer] x1 the x coordinate of the start point
|
1404
|
+
* @param [Integer] y1 the y coordinate of the start point
|
1405
|
+
* @param [Integer] x2 the x coordinate of the end point
|
1406
|
+
* @param [Integer] y2 the y coordinate of the end point
|
1407
|
+
* @return [nil]
|
1408
|
+
*/
|
1409
|
+
static VALUE Renderer_draw_line(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2)
|
1410
|
+
{
|
1411
|
+
HANDLE_ERROR(SDL_RenderDrawLine(Get_SDL_Renderer(self),
|
1412
|
+
NUM2INT(x1), NUM2INT(y1), NUM2INT(x2), NUM2INT(y2)));
|
1413
|
+
return Qnil;
|
1414
|
+
}
|
1415
|
+
|
1416
|
+
/*
|
1417
|
+
* @overload draw_point(x, y)
|
1418
|
+
* Draw a point at (x, y) using drawing color given by {#draw_color=}.
|
1419
|
+
*
|
1420
|
+
* @param [Integer] x the x coordinate of the point
|
1421
|
+
* @param [Integer] y the y coordinate of the point
|
1422
|
+
*
|
1423
|
+
* @return [nil]
|
1424
|
+
*/
|
1425
|
+
static VALUE Renderer_draw_point(VALUE self, VALUE x, VALUE y)
|
1426
|
+
{
|
1427
|
+
HANDLE_ERROR(SDL_RenderDrawPoint(Get_SDL_Renderer(self), NUM2INT(x), NUM2INT(y)));
|
1428
|
+
return Qnil;
|
1429
|
+
}
|
1430
|
+
|
1431
|
+
/*
|
1432
|
+
* @overload draw_rect(rect)
|
1433
|
+
* Draw a rectangle using drawing color given by {#draw_color=}.
|
1434
|
+
*
|
1435
|
+
* @param [SDL2::Rect] rect the drawing rectangle
|
1436
|
+
*
|
1437
|
+
* @return [nil]
|
1438
|
+
*/
|
1439
|
+
static VALUE Renderer_draw_rect(VALUE self, VALUE rect)
|
1440
|
+
{
|
1441
|
+
HANDLE_ERROR(SDL_RenderDrawRect(Get_SDL_Renderer(self), Get_SDL_Rect(rect)));
|
1442
|
+
return Qnil;
|
1443
|
+
}
|
1444
|
+
|
1445
|
+
/*
|
1446
|
+
* @overload fill_rect(rect)
|
1447
|
+
* Draw a filled rectangle using drawing color given by {#draw_color=}.
|
1448
|
+
*
|
1449
|
+
* @param [SDL2::Rect] rect the drawing rectangle
|
1450
|
+
*
|
1451
|
+
* @return [nil]
|
1452
|
+
*/
|
1453
|
+
static VALUE Renderer_fill_rect(VALUE self, VALUE rect)
|
1454
|
+
{
|
1455
|
+
HANDLE_ERROR(SDL_RenderFillRect(Get_SDL_Renderer(self), Get_SDL_Rect(rect)));
|
1456
|
+
return Qnil;
|
1457
|
+
}
|
1458
|
+
|
1459
|
+
/*
|
1460
|
+
* Get information about _self_ rendering context .
|
1461
|
+
*
|
1462
|
+
* @return [SDL2::Renderer::Info] rendering information
|
1463
|
+
*/
|
1464
|
+
static VALUE Renderer_info(VALUE self)
|
1465
|
+
{
|
1466
|
+
SDL_RendererInfo info;
|
1467
|
+
HANDLE_ERROR(SDL_GetRendererInfo(Get_SDL_Renderer(self), &info));
|
1468
|
+
return RendererInfo_new(&info);
|
1469
|
+
}
|
1470
|
+
|
1471
|
+
/*
|
1472
|
+
* Get the blend mode used for drawing operations like
|
1473
|
+
* {#fill_rect} and {#draw_line}.
|
1474
|
+
*
|
1475
|
+
* @return [Integer]
|
1476
|
+
*
|
1477
|
+
* @see #draw_blend_mode=
|
1478
|
+
* @see SDL2::BlendMode
|
1479
|
+
*/
|
1480
|
+
static VALUE Renderer_draw_blend_mode(VALUE self)
|
1481
|
+
{
|
1482
|
+
SDL_BlendMode mode;
|
1483
|
+
HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &mode));
|
1484
|
+
return INT2FIX(mode);
|
1485
|
+
}
|
1486
|
+
|
1487
|
+
/*
|
1488
|
+
* @overload draw_blend_mode=(mode)
|
1489
|
+
* Set the blend mode used for drawing operations.
|
1490
|
+
*
|
1491
|
+
* This method effects the following methods.
|
1492
|
+
*
|
1493
|
+
* * {#draw_line}
|
1494
|
+
* * {#draw_point}
|
1495
|
+
* * {#draw_rect}
|
1496
|
+
* * {#fill_rect}
|
1497
|
+
* * {#clear}
|
1498
|
+
*
|
1499
|
+
* @param mode [Integer] the blending mode
|
1500
|
+
* @return mode
|
1501
|
+
*
|
1502
|
+
* @see #draw_blend_mode
|
1503
|
+
* @see SDL2::BlendMode
|
1504
|
+
*/
|
1505
|
+
static VALUE Renderer_set_draw_blend_mode(VALUE self, VALUE mode)
|
1506
|
+
{
|
1507
|
+
HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), NUM2INT(mode)));
|
1508
|
+
return mode;
|
1509
|
+
}
|
1510
|
+
|
1511
|
+
/*
|
1512
|
+
* Get the clip rectangle for the current target.
|
1513
|
+
*
|
1514
|
+
* @return [SDL2::Rect] the current clip rectangle
|
1515
|
+
* @see {#clip_rect=}
|
1516
|
+
*/
|
1517
|
+
static VALUE Renderer_clip_rect(VALUE self)
|
1518
|
+
{
|
1519
|
+
VALUE rect = rb_obj_alloc(cRect);
|
1520
|
+
SDL_RenderGetClipRect(Get_SDL_Renderer(self), Get_SDL_Rect(rect));
|
1521
|
+
return rect;
|
1522
|
+
}
|
1523
|
+
|
1524
|
+
/*
|
1525
|
+
* @overload clip_rect=(rect)
|
1526
|
+
*
|
1527
|
+
* Set the clip rectangle for the current target.
|
1528
|
+
*
|
1529
|
+
* @return [rect]
|
1530
|
+
* @see #clip_rect
|
1531
|
+
*/
|
1532
|
+
static VALUE Renderer_set_clip_rect(VALUE self, VALUE rect)
|
1533
|
+
{
|
1534
|
+
HANDLE_ERROR(SDL_RenderSetClipRect(Get_SDL_Renderer(self), Get_SDL_Rect(rect)));
|
1535
|
+
return rect;
|
1536
|
+
}
|
1537
|
+
|
1538
|
+
#if SDL_VERSION_ATLEAST(2,0,4)
|
1539
|
+
/*
|
1540
|
+
* Get whether clipping is enabled on the renderer.
|
1541
|
+
*
|
1542
|
+
* @note This method is available since SDL 2.0.4.
|
1543
|
+
*/
|
1544
|
+
static VALUE Render_clip_enabled_p(VALUE self)
|
1545
|
+
{
|
1546
|
+
return INT2BOOL(SDL_RenderIsClipEnabled(Get_SDL_Renderer(self)));
|
1547
|
+
}
|
1548
|
+
#endif
|
1549
|
+
|
1550
|
+
/*
|
1551
|
+
* Get device indepndent resolution for rendering.
|
1552
|
+
*
|
1553
|
+
* @return [[Integer, Integer]] the logical width and height
|
1554
|
+
* @see #logical_size=
|
1555
|
+
*/
|
1556
|
+
static VALUE Renderer_logical_size(VALUE self)
|
1557
|
+
{
|
1558
|
+
int w, h;
|
1559
|
+
SDL_RenderGetLogicalSize(Get_SDL_Renderer(self), &w, &h);
|
1560
|
+
return rb_ary_new3(2, INT2FIX(w), INT2FIX(h));
|
1561
|
+
}
|
1562
|
+
|
1563
|
+
/*
|
1564
|
+
* @overload logical_size=(w_and_h)
|
1565
|
+
*
|
1566
|
+
* Set a device indepndent resolution for rendering.
|
1567
|
+
*
|
1568
|
+
* @param w_and_h [[Integer, Integer]] the width and height of the logical resolution
|
1569
|
+
* @return [w_and_h]
|
1570
|
+
* @see #logical_size
|
1571
|
+
*/
|
1572
|
+
static VALUE Renderer_set_logical_size(VALUE self, VALUE wh)
|
1573
|
+
{
|
1574
|
+
HANDLE_ERROR(SDL_RenderSetLogicalSize(Get_SDL_Renderer(self),
|
1575
|
+
NUM2DBL(rb_ary_entry(wh, 0)),
|
1576
|
+
NUM2DBL(rb_ary_entry(wh, 1))));
|
1577
|
+
return wh;
|
1578
|
+
}
|
1579
|
+
|
1580
|
+
/*
|
1581
|
+
* Get the drawing scale for the current target.
|
1582
|
+
*
|
1583
|
+
* @return [[Integer, Integer]] horizontal and vertical scale factor
|
1584
|
+
* @see #scale=
|
1585
|
+
*/
|
1586
|
+
static VALUE Renderer_scale(VALUE self)
|
1587
|
+
{
|
1588
|
+
float scaleX, scaleY;
|
1589
|
+
SDL_RenderGetScale(Get_SDL_Renderer(self), &scaleX, &scaleY);
|
1590
|
+
return rb_ary_new3(2, DBL2NUM(scaleX), DBL2NUM(scaleY));
|
1591
|
+
}
|
1592
|
+
|
1593
|
+
/*
|
1594
|
+
* @overload scale=(scaleX_and_scaleY)
|
1595
|
+
*
|
1596
|
+
* Set the drawing scale for rendering.
|
1597
|
+
*
|
1598
|
+
* The drawing coordinates are scaled by the x/y scaling factors before they are used by the renderer.
|
1599
|
+
* This allows resolution independent drawing with a single coordinate system.
|
1600
|
+
*
|
1601
|
+
* If this results in scaling or subpixel drawing by the rendering backend,
|
1602
|
+
* it will be handled using the appropriate
|
1603
|
+
* quality hints. For best results use integer scaling factors.
|
1604
|
+
*
|
1605
|
+
* @param scaleX_and_scaleY [[Float, Float]] the horizontal and vertical scaling factors
|
1606
|
+
* @return [scaleX_and_scaleY]
|
1607
|
+
* @see #scale
|
1608
|
+
*/
|
1609
|
+
static VALUE Renderer_set_scale(VALUE self, VALUE xy)
|
1610
|
+
{
|
1611
|
+
float scaleX, scaleY;
|
1612
|
+
scaleX = NUM2DBL(rb_ary_entry(xy, 0));
|
1613
|
+
scaleY = NUM2DBL(rb_ary_entry(xy, 1));
|
1614
|
+
HANDLE_ERROR(SDL_RenderSetScale(Get_SDL_Renderer(self), scaleX, scaleY));
|
1615
|
+
return xy;
|
1616
|
+
}
|
1617
|
+
|
1618
|
+
/*
|
1619
|
+
* Get the drawing area for the current target.
|
1620
|
+
*
|
1621
|
+
* @return [SDL2::Rect] the current drawing area
|
1622
|
+
* @see #viewport=
|
1623
|
+
*/
|
1624
|
+
static VALUE Renderer_viewport(VALUE self)
|
1625
|
+
{
|
1626
|
+
VALUE rect = rb_obj_alloc(cRect);
|
1627
|
+
SDL_RenderGetViewport(Get_SDL_Renderer(self), Get_SDL_Rect(rect));
|
1628
|
+
return rect;
|
1629
|
+
}
|
1630
|
+
|
1631
|
+
/*
|
1632
|
+
* @overload viewport=(area)
|
1633
|
+
* Set the drawing area for rendering on the current target.
|
1634
|
+
*
|
1635
|
+
* @param area [SDL2::Rect,nil] the drawing area, or nil to set the viewport to the entire target
|
1636
|
+
* @return [area]
|
1637
|
+
* @see #viewport
|
1638
|
+
*/
|
1639
|
+
static VALUE Renderer_set_viewport(VALUE self, VALUE rect)
|
1640
|
+
{
|
1641
|
+
HANDLE_ERROR(SDL_RenderSetClipRect(Get_SDL_Renderer(self), Get_SDL_Rect_or_NULL(rect)));
|
1642
|
+
return rect;
|
1643
|
+
}
|
1644
|
+
|
1645
|
+
/*
|
1646
|
+
* Return true if the renderer supports render target.
|
1647
|
+
*
|
1648
|
+
* @see #render_target=
|
1649
|
+
*/
|
1650
|
+
static VALUE Renderer_support_render_target_p(VALUE self)
|
1651
|
+
{
|
1652
|
+
return INT2BOOL(SDL_RenderTargetSupported(Get_SDL_Renderer(self)));
|
1653
|
+
}
|
1654
|
+
|
1655
|
+
/*
|
1656
|
+
* Get the output size of a rendering context.
|
1657
|
+
*
|
1658
|
+
* @return [[Integer, Integer]] the width and the height
|
1659
|
+
*/
|
1660
|
+
static VALUE Renderer_output_size(VALUE self)
|
1661
|
+
{
|
1662
|
+
int w, h;
|
1663
|
+
HANDLE_ERROR(SDL_GetRendererOutputSize(Get_SDL_Renderer(self), &w, &h));
|
1664
|
+
return rb_ary_new3(2, INT2FIX(w), INT2FIX(h));
|
1665
|
+
}
|
1666
|
+
|
1667
|
+
/*
|
1668
|
+
* @overload render_target=(target)
|
1669
|
+
* Set a texture as the current render target.
|
1670
|
+
*
|
1671
|
+
* Some renderers have ability to render to a texture instead of a screen.
|
1672
|
+
* You can judge whether your renderer has this ability using
|
1673
|
+
* {#support_render_target?}.
|
1674
|
+
*
|
1675
|
+
* The target texture musbe be {#create_texture created} with the
|
1676
|
+
* {SDL2::Texture::ACCESS_TARGET} flag.
|
1677
|
+
*
|
1678
|
+
* @param [SDL2::Texture,nil] target the targeted texture, or nil
|
1679
|
+
* for the default render target(i.e. screen)
|
1680
|
+
*
|
1681
|
+
* @return [target]
|
1682
|
+
*
|
1683
|
+
* @see #render_target
|
1684
|
+
*/
|
1685
|
+
static VALUE Renderer_set_render_target(VALUE self, VALUE target)
|
1686
|
+
{
|
1687
|
+
HANDLE_ERROR(SDL_SetRenderTarget(Get_SDL_Renderer(self),
|
1688
|
+
(target == Qnil) ? NULL : Get_SDL_Texture(target)));
|
1689
|
+
rb_iv_set(self, "render_target", target);
|
1690
|
+
return target;
|
1691
|
+
}
|
1692
|
+
|
1693
|
+
/*
|
1694
|
+
* Get the current render target.
|
1695
|
+
*
|
1696
|
+
* @return [SDL2::Texture] the current rendering target
|
1697
|
+
* @return [nil] for the default render target (i.e. screen)
|
1698
|
+
*
|
1699
|
+
* @see #render_target=
|
1700
|
+
* @see #support_render_target?
|
1701
|
+
*/
|
1702
|
+
static VALUE Renderer_render_target(VALUE self)
|
1703
|
+
{
|
1704
|
+
return rb_iv_get(self, "render_target");
|
1705
|
+
}
|
1706
|
+
|
1707
|
+
/*
|
1708
|
+
* Reset the render target to the screen.
|
1709
|
+
*
|
1710
|
+
* @return [nil]
|
1711
|
+
*/
|
1712
|
+
static VALUE Renderer_reset_render_target(VALUE self)
|
1713
|
+
{
|
1714
|
+
return Renderer_set_render_target(self, Qnil);
|
1715
|
+
}
|
1716
|
+
|
1717
|
+
/* @return [Hash<String=>Object>] (GC) debug information */
|
1718
|
+
static VALUE Renderer_debug_info(VALUE self)
|
1719
|
+
{
|
1720
|
+
Renderer* r = Get_Renderer(self);
|
1721
|
+
VALUE info = rb_hash_new();
|
1722
|
+
int num_active_textures = 0;
|
1723
|
+
int i;
|
1724
|
+
rb_hash_aset(info, rb_str_new2("destroy?"), INT2BOOL(r->renderer == NULL));
|
1725
|
+
rb_hash_aset(info, rb_str_new2("max_textures"), INT2NUM(r->max_textures));
|
1726
|
+
rb_hash_aset(info, rb_str_new2("num_textures"), INT2NUM(r->num_textures));
|
1727
|
+
for (i=0; i<r->num_textures; ++i)
|
1728
|
+
if (r->textures[i]->texture)
|
1729
|
+
++num_active_textures;
|
1730
|
+
rb_hash_aset(info, rb_str_new2("num_active_textures"), INT2NUM(num_active_textures));
|
1731
|
+
rb_hash_aset(info, rb_str_new2("refcount"), INT2NUM(r->refcount));
|
1732
|
+
|
1733
|
+
return info;
|
1734
|
+
}
|
1735
|
+
|
1736
|
+
// Draw anti-aliased line with alpha blending.
|
1737
|
+
static VALUE Renderer_draw_line_aa(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2)
|
1738
|
+
{
|
1739
|
+
SDL_BlendMode mode;
|
1740
|
+
Uint8 r, g, b, a;
|
1741
|
+
HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &mode));
|
1742
|
+
HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self), &r, &g, &b, &a));
|
1743
|
+
HANDLE_ERROR(aalineRGBA(Get_SDL_Renderer(self), NUM2INT(x1), NUM2INT(y1), NUM2INT(x2), NUM2INT(y2), r, g, b, a));
|
1744
|
+
HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), mode));
|
1745
|
+
return Qnil;
|
1746
|
+
}
|
1747
|
+
|
1748
|
+
// Draw a thick line with alpha blending.
|
1749
|
+
static VALUE Renderer_draw_line_thick(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2, VALUE width)
|
1750
|
+
{
|
1751
|
+
SDL_BlendMode mode;
|
1752
|
+
Uint8 r, g, b, a;
|
1753
|
+
HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &mode));
|
1754
|
+
HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self), &r, &g, &b, &a));
|
1755
|
+
HANDLE_ERROR(thickLineRGBA(Get_SDL_Renderer(self), NUM2INT(x1), NUM2INT(y1), NUM2INT(x2), NUM2INT(y2), NUM2INT(width), r, g, b, a));
|
1756
|
+
HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), mode));
|
1757
|
+
return Qnil;
|
1758
|
+
}
|
1759
|
+
|
1760
|
+
// Draw trigon (triangle outline) with alpha blending.
|
1761
|
+
static VALUE Renderer_draw_triangle(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2, VALUE x3, VALUE y3)
|
1762
|
+
{
|
1763
|
+
SDL_BlendMode mode;
|
1764
|
+
Uint8 r, g, b, a;
|
1765
|
+
HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &mode));
|
1766
|
+
HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self), &r, &g, &b, &a));
|
1767
|
+
HANDLE_ERROR(trigonRGBA(Get_SDL_Renderer(self), NUM2INT(x1), NUM2INT(y1), NUM2INT(x2), NUM2INT(y2), NUM2INT(x3), NUM2INT(y3), r, g, b, a));
|
1768
|
+
HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), mode));
|
1769
|
+
return Qnil;
|
1770
|
+
}
|
1771
|
+
|
1772
|
+
// Draw anti-aliased trigon (triangle outline) with alpha blending.
|
1773
|
+
static VALUE Renderer_draw_triangle_aa(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2, VALUE x3, VALUE y3)
|
1774
|
+
{
|
1775
|
+
SDL_BlendMode mode;
|
1776
|
+
Uint8 r, g, b, a;
|
1777
|
+
HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &mode));
|
1778
|
+
HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self), &r, &g, &b, &a));
|
1779
|
+
HANDLE_ERROR(aatrigonRGBA(Get_SDL_Renderer(self), NUM2INT(x1), NUM2INT(y1), NUM2INT(x2), NUM2INT(y2), NUM2INT(x3), NUM2INT(y3), r, g, b, a));
|
1780
|
+
HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), mode));
|
1781
|
+
return Qnil;
|
1782
|
+
}
|
1783
|
+
|
1784
|
+
// Draw filled trigon (triangle) with alpha blending.
|
1785
|
+
static VALUE Renderer_fill_triangle(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2, VALUE x3, VALUE y3)
|
1786
|
+
{
|
1787
|
+
SDL_BlendMode mode;
|
1788
|
+
Uint8 r, g, b, a;
|
1789
|
+
HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &mode));
|
1790
|
+
HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self), &r, &g, &b, &a));
|
1791
|
+
HANDLE_ERROR(filledTrigonRGBA(Get_SDL_Renderer(self), NUM2INT(x1), NUM2INT(y1), NUM2INT(x2), NUM2INT(y2), NUM2INT(x3), NUM2INT(y3), r, g, b, a));
|
1792
|
+
HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), mode));
|
1793
|
+
return Qnil;
|
1794
|
+
}
|
1795
|
+
|
1796
|
+
typedef int (*polygon_gfxFunction)(SDL_Renderer *, const Sint16 *, const Sint16 *, int, Uint8, Uint8, Uint8, Uint8);
|
1797
|
+
struct draw_polygon_closure
|
1798
|
+
{
|
1799
|
+
polygon_gfxFunction gfxFunction;
|
1800
|
+
SDL_Renderer *renderer;
|
1801
|
+
Sint16 *vx, *vy;
|
1802
|
+
long point_count;
|
1803
|
+
Uint8 r, g, b, a;
|
1804
|
+
SDL_BlendMode blend_mode;
|
1805
|
+
};
|
1806
|
+
|
1807
|
+
static VALUE draw_polygon_generic(VALUE argv)
|
1808
|
+
{
|
1809
|
+
const struct draw_polygon_closure *closure = (const struct draw_polygon_closure *) argv;
|
1810
|
+
HANDLE_ERROR(closure->gfxFunction(closure->renderer, closure->vx, closure->vy, closure->point_count,
|
1811
|
+
closure->r, closure->g, closure->b, closure->a));
|
1812
|
+
return Qnil;
|
1813
|
+
}
|
1814
|
+
|
1815
|
+
static VALUE draw_polygon_generic_cleanup(VALUE argv)
|
1816
|
+
{
|
1817
|
+
const struct draw_polygon_closure *closure = (const struct draw_polygon_closure *) argv;
|
1818
|
+
HANDLE_ERROR(SDL_SetRenderDrawBlendMode(closure->renderer, closure->blend_mode));
|
1819
|
+
free(closure->vx);
|
1820
|
+
free(closure->vy);
|
1821
|
+
return Qnil;
|
1822
|
+
}
|
1823
|
+
|
1824
|
+
static VALUE Renderer_draw_polygon_generic(VALUE self, VALUE vertices_x, VALUE vertices_y, polygon_gfxFunction polygon_gfxFunction)
|
1825
|
+
{
|
1826
|
+
struct draw_polygon_closure closure;
|
1827
|
+
|
1828
|
+
Check_Type(vertices_x, T_ARRAY);
|
1829
|
+
Check_Type(vertices_y, T_ARRAY);
|
1830
|
+
|
1831
|
+
HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &closure.blend_mode));
|
1832
|
+
HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self),
|
1833
|
+
&closure.r, &closure.g, &closure.b, &closure.a));
|
1834
|
+
closure.gfxFunction = polygon_gfxFunction;
|
1835
|
+
closure.renderer = Get_SDL_Renderer(self);
|
1836
|
+
closure.point_count = RARRAY_LEN(vertices_x);
|
1837
|
+
if (RARRAY_LEN(vertices_y) == closure.point_count)
|
1838
|
+
rb_raise(rb_eArgError, "Both arrays must be of same size");
|
1839
|
+
closure.vx = ruby_xmalloc2(closure.point_count, sizeof(*closure.vx));
|
1840
|
+
closure.vy = ruby_xmalloc2(closure.point_count, sizeof(*closure.vy));
|
1841
|
+
for (long i = 0; i < closure.point_count; i++) {
|
1842
|
+
closure.vx[i] = NUM2INT(rb_ary_entry(vertices_x, i));
|
1843
|
+
closure.vy[i] = NUM2INT(rb_ary_entry(vertices_y, i));
|
1844
|
+
}
|
1845
|
+
|
1846
|
+
return rb_ensure(draw_polygon_generic, (VALUE) &closure, draw_polygon_generic_cleanup, (VALUE) &closure);
|
1847
|
+
}
|
1848
|
+
|
1849
|
+
// Draw polygon with the currently set color and blend mode.
|
1850
|
+
static VALUE Renderer_draw_polygon(VALUE self, VALUE vertices_x, VALUE vertices_y)
|
1851
|
+
{
|
1852
|
+
return Renderer_draw_polygon_generic(self, vertices_x, vertices_y, polygonRGBA);
|
1853
|
+
}
|
1854
|
+
|
1855
|
+
// Draw anti-aliased polygon with alpha blending.
|
1856
|
+
static VALUE Renderer_draw_polygon_aa(VALUE self, VALUE vertices_x, VALUE vertices_y)
|
1857
|
+
{
|
1858
|
+
return Renderer_draw_polygon_generic(self, vertices_x, vertices_y, aapolygonRGBA);
|
1859
|
+
}
|
1860
|
+
|
1861
|
+
// Draw filled polygon with alpha blending.
|
1862
|
+
static VALUE Renderer_fill_polygon(VALUE self, VALUE vertices_x, VALUE vertices_y)
|
1863
|
+
{
|
1864
|
+
return Renderer_draw_polygon_generic(self, vertices_x, vertices_y, filledPolygonRGBA);
|
1865
|
+
}
|
1866
|
+
|
1867
|
+
struct draw_polygon_textured_closure
|
1868
|
+
{
|
1869
|
+
SDL_Renderer *renderer;
|
1870
|
+
Sint16 *vx, *vy;
|
1871
|
+
long point_count;
|
1872
|
+
SDL_Surface *texture;
|
1873
|
+
int texture_dx, texture_dy;
|
1874
|
+
};
|
1875
|
+
|
1876
|
+
static VALUE draw_polygon_textured(VALUE argv)
|
1877
|
+
{
|
1878
|
+
const struct draw_polygon_textured_closure *closure =
|
1879
|
+
(const struct draw_polygon_textured_closure *) argv;
|
1880
|
+
HANDLE_ERROR(texturedPolygon(closure->renderer, closure->vx, closure->vy, closure->point_count,
|
1881
|
+
closure->texture, closure->texture_dx, closure->texture_dy));
|
1882
|
+
return Qnil;
|
1883
|
+
}
|
1884
|
+
|
1885
|
+
static VALUE draw_polygon_textured_cleanup(VALUE argv)
|
1886
|
+
{
|
1887
|
+
const struct draw_polygon_textured_closure *closure =
|
1888
|
+
(const struct draw_polygon_textured_closure *) argv;
|
1889
|
+
free(closure->vx);
|
1890
|
+
free(closure->vy);
|
1891
|
+
return Qnil;
|
1892
|
+
}
|
1893
|
+
|
1894
|
+
// Draws a polygon filled with the given texture.
|
1895
|
+
static VALUE Renderer_fill_polygon_textured(VALUE self, VALUE vertices_x, VALUE vertices_y, VALUE surface, VALUE surface_dx, VALUE surface_dy)
|
1896
|
+
{
|
1897
|
+
struct draw_polygon_textured_closure closure;
|
1898
|
+
|
1899
|
+
Check_Type(vertices_x, T_ARRAY);
|
1900
|
+
Check_Type(vertices_y, T_ARRAY);
|
1901
|
+
|
1902
|
+
closure.renderer = Get_SDL_Renderer(self);
|
1903
|
+
closure.texture = Get_SDL_Surface(surface);
|
1904
|
+
closure.texture_dx = NUM2INT(surface_dx);
|
1905
|
+
closure.texture_dy = NUM2INT(surface_dy);
|
1906
|
+
|
1907
|
+
closure.point_count = RARRAY_LEN(vertices_x);
|
1908
|
+
if (RARRAY_LEN(vertices_y) == closure.point_count)
|
1909
|
+
rb_raise(rb_eArgError, "Both arrays must be of same size");
|
1910
|
+
closure.vx = ruby_xmalloc2(closure.point_count, sizeof(*closure.vx));
|
1911
|
+
closure.vy = ruby_xmalloc2(closure.point_count, sizeof(*closure.vy));
|
1912
|
+
for (long i = 0; i < closure.point_count; i++) {
|
1913
|
+
closure.vx[i] = NUM2INT(rb_ary_entry(vertices_x, i));
|
1914
|
+
closure.vy[i] = NUM2INT(rb_ary_entry(vertices_y, i));
|
1915
|
+
}
|
1916
|
+
|
1917
|
+
return rb_ensure(draw_polygon_textured, (VALUE) &closure, draw_polygon_textured_cleanup, (VALUE) &closure);
|
1918
|
+
}
|
1919
|
+
|
1920
|
+
// Arc with blending.
|
1921
|
+
static VALUE Renderer_draw_arc(VALUE self, VALUE x, VALUE y, VALUE rad, VALUE start, VALUE end)
|
1922
|
+
{
|
1923
|
+
SDL_BlendMode mode;
|
1924
|
+
Uint8 r, g, b, a;
|
1925
|
+
HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &mode));
|
1926
|
+
HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self), &r, &g, &b, &a));
|
1927
|
+
HANDLE_ERROR(arcRGBA(Get_SDL_Renderer(self), NUM2INT(x), NUM2INT(y), NUM2INT(rad), NUM2INT(start), NUM2INT(end), r, g, b, a));
|
1928
|
+
HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), mode));
|
1929
|
+
return Qnil;
|
1930
|
+
}
|
1931
|
+
|
1932
|
+
// Draw ellipse with blending.
|
1933
|
+
static VALUE Renderer_draw_ellipse(VALUE self, VALUE x, VALUE y, VALUE rx, VALUE ry)
|
1934
|
+
{
|
1935
|
+
SDL_BlendMode mode;
|
1936
|
+
Uint8 r, g, b, a;
|
1937
|
+
HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &mode));
|
1938
|
+
HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self), &r, &g, &b, &a));
|
1939
|
+
HANDLE_ERROR(ellipseRGBA(Get_SDL_Renderer(self), NUM2INT(x), NUM2INT(y), NUM2INT(rx), NUM2INT(ry), r, g, b, a));
|
1940
|
+
HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), mode));
|
1941
|
+
return Qnil;
|
1942
|
+
}
|
1943
|
+
|
1944
|
+
// Draw anti-aliased ellipse with blending.
|
1945
|
+
static VALUE Renderer_draw_ellipse_aa(VALUE self, VALUE x, VALUE y, VALUE rx, VALUE ry)
|
1946
|
+
{
|
1947
|
+
SDL_BlendMode mode;
|
1948
|
+
Uint8 r, g, b, a;
|
1949
|
+
HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &mode));
|
1950
|
+
HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self), &r, &g, &b, &a));
|
1951
|
+
HANDLE_ERROR(aaellipseRGBA(Get_SDL_Renderer(self), NUM2INT(x), NUM2INT(y), NUM2INT(rx), NUM2INT(ry), r, g, b, a));
|
1952
|
+
HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), mode));
|
1953
|
+
return Qnil;
|
1954
|
+
}
|
1955
|
+
|
1956
|
+
// Draw filled ellipse with blending.
|
1957
|
+
static VALUE Renderer_fill_ellipse(VALUE self, VALUE x, VALUE y, VALUE rx, VALUE ry)
|
1958
|
+
{
|
1959
|
+
SDL_BlendMode mode;
|
1960
|
+
Uint8 r, g, b, a;
|
1961
|
+
HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &mode));
|
1962
|
+
HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self), &r, &g, &b, &a));
|
1963
|
+
HANDLE_ERROR(filledEllipseRGBA(Get_SDL_Renderer(self), NUM2INT(x), NUM2INT(y), NUM2INT(rx), NUM2INT(ry), r, g, b, a));
|
1964
|
+
HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), mode));
|
1965
|
+
return Qnil;
|
1966
|
+
}
|
1967
|
+
|
1968
|
+
// Draw pie (outline) with alpha blending.
|
1969
|
+
static VALUE Renderer_draw_pie(VALUE self, VALUE x, VALUE y, VALUE rad, VALUE start, VALUE end)
|
1970
|
+
{
|
1971
|
+
SDL_BlendMode mode;
|
1972
|
+
Uint8 r, g, b, a;
|
1973
|
+
HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &mode));
|
1974
|
+
HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self), &r, &g, &b, &a));
|
1975
|
+
HANDLE_ERROR(pieRGBA(Get_SDL_Renderer(self), NUM2INT(x), NUM2INT(y), NUM2INT(rad), NUM2INT(start), NUM2INT(end), r, g, b, a));
|
1976
|
+
HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), mode));
|
1977
|
+
return Qnil;
|
1978
|
+
}
|
1979
|
+
|
1980
|
+
// Draw filled pie with alpha blending.
|
1981
|
+
static VALUE Renderer_fill_pie(VALUE self, VALUE x, VALUE y, VALUE rad, VALUE start, VALUE end)
|
1982
|
+
{
|
1983
|
+
SDL_BlendMode mode;
|
1984
|
+
Uint8 r, g, b, a;
|
1985
|
+
HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &mode));
|
1986
|
+
HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self), &r, &g, &b, &a));
|
1987
|
+
HANDLE_ERROR(filledPieRGBA(Get_SDL_Renderer(self), NUM2INT(x), NUM2INT(y), NUM2INT(rad), NUM2INT(start), NUM2INT(end), r, g, b, a));
|
1988
|
+
HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), mode));
|
1989
|
+
return Qnil;
|
1990
|
+
return Qnil;
|
1991
|
+
}
|
1992
|
+
|
1993
|
+
int internal_roundedRectangleRGBA(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
|
1994
|
+
|
1995
|
+
// Draw rounded-corner rectangle with blending.
|
1996
|
+
static VALUE Renderer_draw_rounded_rect(VALUE self, VALUE x, VALUE y, VALUE w, VALUE h, VALUE rad)
|
1997
|
+
{
|
1998
|
+
SDL_BlendMode mode;
|
1999
|
+
Uint8 r, g, b, a;
|
2000
|
+
HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &mode));
|
2001
|
+
HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self), &r, &g, &b, &a));
|
2002
|
+
HANDLE_ERROR(internal_roundedRectangleRGBA(Get_SDL_Renderer(self),
|
2003
|
+
NUM2INT(x), NUM2INT(y),
|
2004
|
+
NUM2INT(x) + NUM2INT(w), NUM2INT(y) + NUM2INT(h),
|
2005
|
+
NUM2INT(rad), r, g, b, a));
|
2006
|
+
HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), mode));
|
2007
|
+
return Qnil;
|
2008
|
+
}
|
2009
|
+
|
2010
|
+
// From: https://github.com/rtrussell/BBCSDL/blob/033203c/src/SDL2_gfxPrimitives.c
|
2011
|
+
// With modifications so that the draw domain is x:[x1, x2) and y:[y1,y2)
|
2012
|
+
// and fixup other off by one errors.
|
2013
|
+
int internal_roundedRectangleRGBA(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a) {
|
2014
|
+
int result = 0;
|
2015
|
+
Sint16 w, h;
|
2016
|
+
Sint16 xx1, xx2;
|
2017
|
+
Sint16 yy1, yy2;
|
2018
|
+
|
2019
|
+
if (renderer == NULL)
|
2020
|
+
return -1;
|
2021
|
+
|
2022
|
+
if (rad < 0) // Check radius for valid range
|
2023
|
+
return -1;
|
2024
|
+
|
2025
|
+
if (rad <= 1) //Special case - no rounding
|
2026
|
+
return rectangleRGBA(renderer, x1, y1, x2, y2, r, g, b, a);
|
2027
|
+
|
2028
|
+
// Test for special cases of straight lines or single point
|
2029
|
+
if (x1 == x2) {
|
2030
|
+
if (y1 == y2)
|
2031
|
+
return (pixelRGBA(renderer, x1, y1, r, g, b, a));
|
2032
|
+
else
|
2033
|
+
return (vlineRGBA(renderer, x1, y1, y2, r, g, b, a));
|
2034
|
+
} else if (y1 == y2)
|
2035
|
+
return (hlineRGBA(renderer, x1, x2, y1, r, g, b, a));
|
2036
|
+
|
2037
|
+
// Swap x1, x2 and/or y1, y2 if required
|
2038
|
+
if (x1 > x2) {
|
2039
|
+
Sint16 tmp = x1;
|
2040
|
+
x1 = x2;
|
2041
|
+
x2 = tmp;
|
2042
|
+
}
|
2043
|
+
if (y1 > y2) {
|
2044
|
+
Sint16 tmp = y1;
|
2045
|
+
y1 = y2;
|
2046
|
+
y2 = tmp;
|
2047
|
+
}
|
2048
|
+
|
2049
|
+
//Calculate width & height
|
2050
|
+
w = x2 - x1;
|
2051
|
+
h = y2 - y1;
|
2052
|
+
|
2053
|
+
//Maybe adjust radius
|
2054
|
+
if ((rad * 2) > w)
|
2055
|
+
rad = w / 2;
|
2056
|
+
if ((rad * 2) > h)
|
2057
|
+
rad = h / 2;
|
2058
|
+
|
2059
|
+
// Draw corners
|
2060
|
+
xx1 = x1 + rad;
|
2061
|
+
xx2 = x2 - rad;
|
2062
|
+
yy1 = y1 + rad;
|
2063
|
+
yy2 = y2 - rad;
|
2064
|
+
result |= arcRGBA(renderer, xx1, yy1, rad, 180, 270, r, g, b, a);
|
2065
|
+
result |= arcRGBA(renderer, xx2 - 1, yy1, rad, 270, 360, r, g, b, a);
|
2066
|
+
result |= arcRGBA(renderer, xx1, yy2 - 1, rad, 90, 180, r, g, b, a);
|
2067
|
+
result |= arcRGBA(renderer, xx2 - 1, yy2 - 1, rad, 0, 90, r, g, b, a);
|
2068
|
+
|
2069
|
+
// Draw lines
|
2070
|
+
if (xx1 <= xx2) {
|
2071
|
+
result |= hlineRGBA(renderer, xx1, xx2, y1, r, g, b, a);
|
2072
|
+
result |= hlineRGBA(renderer, xx1, xx2, y2 - 1, r, g, b, a);
|
2073
|
+
}
|
2074
|
+
if (yy1 <= yy2) {
|
2075
|
+
result |= vlineRGBA(renderer, x1, yy1, yy2, r, g, b, a);
|
2076
|
+
result |= vlineRGBA(renderer, x2 - 1, yy1, yy2, r, g, b, a);
|
2077
|
+
}
|
2078
|
+
|
2079
|
+
return result;
|
2080
|
+
}
|
2081
|
+
|
2082
|
+
int internal_roundedBoxRGBA(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2,
|
2083
|
+
Sint16 y2, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
|
2084
|
+
|
2085
|
+
// Draw rounded-corner box (filled rectangle) with blending.
|
2086
|
+
static VALUE Renderer_fill_rounded_rect(VALUE self, VALUE x, VALUE y, VALUE w, VALUE h, VALUE rad)
|
2087
|
+
{
|
2088
|
+
SDL_BlendMode mode;
|
2089
|
+
Uint8 r, g, b, a;
|
2090
|
+
HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &mode));
|
2091
|
+
HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self), &r, &g, &b, &a));
|
2092
|
+
HANDLE_ERROR(internal_roundedBoxRGBA(Get_SDL_Renderer(self),
|
2093
|
+
NUM2INT(x), NUM2INT(y),
|
2094
|
+
NUM2INT(x) + NUM2INT(w), NUM2INT(y) + NUM2INT(h),
|
2095
|
+
NUM2INT(rad), r, g, b, a));
|
2096
|
+
HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), mode));
|
2097
|
+
return Qnil;
|
2098
|
+
}
|
2099
|
+
|
2100
|
+
// From: https://github.com/rtrussell/BBCSDL/blob/033203c/src/SDL2_gfxPrimitives.c
|
2101
|
+
// Threw out old code that actually does round corners in favor of a midpoint circle algorithm
|
2102
|
+
// From: https://rosettacode.org/wiki/Bitmap/Midpoint_circle_algorithm#C
|
2103
|
+
int internal_roundedBoxRGBA(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2,
|
2104
|
+
Sint16 y2, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
|
2105
|
+
{
|
2106
|
+
int result = 0;
|
2107
|
+
Sint16 w, h;
|
2108
|
+
Sint16 cx1, cy1, cx2, cy2;
|
2109
|
+
|
2110
|
+
if (renderer == NULL)
|
2111
|
+
return -1;
|
2112
|
+
|
2113
|
+
//Check radius for valid range
|
2114
|
+
if (rad < 0)
|
2115
|
+
return -1;
|
2116
|
+
|
2117
|
+
// Special case - no round corner at all
|
2118
|
+
if (rad <= 1)
|
2119
|
+
return boxRGBA(renderer, x1, y1, x2, y2, r, g, b, a);
|
2120
|
+
|
2121
|
+
// Test for special cases of straight lines or single point
|
2122
|
+
if (x1 == x2) {
|
2123
|
+
if (y1 == y2)
|
2124
|
+
return (pixelRGBA(renderer, x1, y1, r, g, b, a));
|
2125
|
+
else
|
2126
|
+
return (vlineRGBA(renderer, x1, y1, y2, r, g, b, a));
|
2127
|
+
} else if (y1 == y2)
|
2128
|
+
return (hlineRGBA(renderer, x1, x2, y1, r, g, b, a));
|
2129
|
+
|
2130
|
+
// Swap x1, x2 and/or y1, y2 if required
|
2131
|
+
if (x1 > x2) {
|
2132
|
+
Sint16 tmp = x1;
|
2133
|
+
x1 = x2;
|
2134
|
+
x2 = tmp;
|
2135
|
+
}
|
2136
|
+
if (y1 > y2) {
|
2137
|
+
Sint16 tmp = y1;
|
2138
|
+
y1 = y2;
|
2139
|
+
y2 = tmp;
|
2140
|
+
}
|
2141
|
+
|
2142
|
+
// Calculate width & height
|
2143
|
+
w = x2 - x1;
|
2144
|
+
h = y2 - y1;
|
2145
|
+
|
2146
|
+
// Maybe adjust radius
|
2147
|
+
if (rad + rad > w)
|
2148
|
+
rad = w / 2;
|
2149
|
+
if (rad + rad > h)
|
2150
|
+
rad = h / 2;
|
2151
|
+
|
2152
|
+
//Calculate the four centers
|
2153
|
+
cx1 = x1 + rad;
|
2154
|
+
cy1 = y1 + rad;
|
2155
|
+
cx2 = x2 - rad;
|
2156
|
+
cy2 = y2 - rad;
|
2157
|
+
|
2158
|
+
// Draw corners and north/south wedge
|
2159
|
+
// Theory: two calls through the midpoint circle algorithm will gives bounds
|
2160
|
+
// for a drawn horizontal line.
|
2161
|
+
//
|
2162
|
+
// at end of while loop: outline is (x0 +/- x, y0 +/- y) and (x0 +/- y, y0 +/- x)
|
2163
|
+
// 8 octants in total, draw between two each line, therefore 4 calls
|
2164
|
+
{
|
2165
|
+
int f = 1 - rad;
|
2166
|
+
int ddF_x = 0;
|
2167
|
+
int ddF_y = -2 * rad;
|
2168
|
+
int x = 0;
|
2169
|
+
int y = rad;
|
2170
|
+
|
2171
|
+
while(x < y) {
|
2172
|
+
if (f >= 0) {
|
2173
|
+
if (x < y - 1) {
|
2174
|
+
result |= hlineRGBA(renderer, cx1 - x, cx2 + x, cy1 - y, r, g, b, a);
|
2175
|
+
result |= hlineRGBA(renderer, cx1 - x, cx2 + x, cy2 + y - 1, r, g, b, a);
|
2176
|
+
}
|
2177
|
+
y--;
|
2178
|
+
ddF_y += 2;
|
2179
|
+
f += ddF_y;
|
2180
|
+
}
|
2181
|
+
|
2182
|
+
x++;
|
2183
|
+
ddF_x += 2;
|
2184
|
+
f += ddF_x + 1;
|
2185
|
+
result |= hlineRGBA(renderer, cx1 - y, cx2 + y, cy1 - x, r, g, b, a);
|
2186
|
+
result |= hlineRGBA(renderer, cx1 - y, cx2 + y, cy2 + x - 1, r, g, b, a);
|
2187
|
+
}
|
2188
|
+
}
|
2189
|
+
|
2190
|
+
|
2191
|
+
// east/west and center wedge
|
2192
|
+
if (x2 - x1 - rad - rad > 0 && x2 - x1 - rad - rad > 0) { //TODO: check math
|
2193
|
+
struct SDL_Rect rect = {x1, y1 + rad, x2 - x1, y2 - y1 - rad - rad};
|
2194
|
+
result |= SDL_RenderFillRect(renderer, &rect);
|
2195
|
+
}
|
2196
|
+
|
2197
|
+
return result;
|
2198
|
+
}
|
2199
|
+
|
2200
|
+
// Draw a cubic bezier curve with alpha blending.
|
2201
|
+
static VALUE Renderer_draw_quad_bezier(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2, VALUE x3, VALUE y3, VALUE x4, VALUE y4, VALUE resolution)
|
2202
|
+
{
|
2203
|
+
SDL_BlendMode mode;
|
2204
|
+
Uint8 r, g, b, a;
|
2205
|
+
Sint16 vx[] = { NUM2INT(x1), NUM2INT(x2), NUM2INT(x3), NUM2INT(x4) };
|
2206
|
+
Sint16 vy[] = { NUM2INT(y1), NUM2INT(y2), NUM2INT(y3), NUM2INT(y4) };
|
2207
|
+
HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &mode));
|
2208
|
+
HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self), &r, &g, &b, &a));
|
2209
|
+
HANDLE_ERROR(bezierRGBA(Get_SDL_Renderer(self), vx, vy, 4, NUM2INT(resolution), r, g, b, a));
|
2210
|
+
HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), mode));
|
2211
|
+
return Qnil;
|
2212
|
+
}
|
2213
|
+
|
2214
|
+
/*
|
2215
|
+
* Document-class: SDL2::Renderer::Info
|
2216
|
+
*
|
2217
|
+
* This class contains information of a rendering context.
|
2218
|
+
*
|
2219
|
+
* @!attribute [r] name
|
2220
|
+
* @return [String] the name of the renderer
|
2221
|
+
*
|
2222
|
+
* @!attribute [r] texture_formats
|
2223
|
+
* @return [Array<SDL2::PixelFormat>] available texture formats
|
2224
|
+
*
|
2225
|
+
* @!attribute [r] max_texture_width
|
2226
|
+
* @return [Integer] maximum texture width
|
2227
|
+
*
|
2228
|
+
* @!attribute [r] max_texture_height
|
2229
|
+
* @return [Integer] maximum texture height
|
2230
|
+
*/
|
2231
|
+
|
2232
|
+
/*
|
2233
|
+
* Document-module: SDL2::Renderer::Flags
|
2234
|
+
*
|
2235
|
+
* The OR'd bits of the constants of this module represents
|
2236
|
+
* the state of renderers.
|
2237
|
+
*
|
2238
|
+
* You can use this flag
|
2239
|
+
* {SDL2::Window#create_renderer when you create a new renderer}.
|
2240
|
+
* No flags(==0) gives priority to available ACCELERATED renderers.
|
2241
|
+
*/
|
2242
|
+
|
2243
|
+
/*
|
2244
|
+
* Document-module: SDL2::BlendMode
|
2245
|
+
*
|
2246
|
+
* Constants represent blend mode for {SDL2::Renderer.copy} and
|
2247
|
+
* drawing operations.
|
2248
|
+
*
|
2249
|
+
* You can change the blending mode using
|
2250
|
+
* {SDL2::Renderer#draw_blend_mode=} and {SDL2::Texture#blend_mode=}.
|
2251
|
+
*
|
2252
|
+
* In the backend of SDL, opengl or direct3d blending
|
2253
|
+
* mechanism is used for blending operations.
|
2254
|
+
*/
|
2255
|
+
|
2256
|
+
/*
|
2257
|
+
* Document-class: SDL2::Texture
|
2258
|
+
*
|
2259
|
+
* This class represents the texture associated with a renderer.
|
2260
|
+
*
|
2261
|
+
*
|
2262
|
+
* @!method destroy?
|
2263
|
+
* Return true if the texture is {#destroy destroyed}.
|
2264
|
+
*/
|
2265
|
+
|
2266
|
+
/*
|
2267
|
+
* Destroy the texture and deallocate memory.
|
2268
|
+
*
|
2269
|
+
* @see #destroy?
|
2270
|
+
*/
|
2271
|
+
static VALUE Texture_destroy(VALUE self)
|
2272
|
+
{
|
2273
|
+
Texture_destroy_internal(Get_Texture(self));
|
2274
|
+
return Qnil;
|
2275
|
+
}
|
2276
|
+
|
2277
|
+
/*
|
2278
|
+
* Get the blending mode of the texture.
|
2279
|
+
*
|
2280
|
+
* @return [Integer] blend mode
|
2281
|
+
*
|
2282
|
+
* @see #blend_mode=
|
2283
|
+
*/
|
2284
|
+
static VALUE Texture_blend_mode(VALUE self)
|
2285
|
+
{
|
2286
|
+
SDL_BlendMode mode;
|
2287
|
+
HANDLE_ERROR(SDL_GetTextureBlendMode(Get_SDL_Texture(self), &mode));
|
2288
|
+
return INT2FIX(mode);
|
2289
|
+
}
|
2290
|
+
|
2291
|
+
/*
|
2292
|
+
* @overload blend_mode=(mode)
|
2293
|
+
* Set the blending model of the texture.
|
2294
|
+
*
|
2295
|
+
* @param mode [Integer] blending mode
|
2296
|
+
* @return [mode]
|
2297
|
+
*
|
2298
|
+
* @see #blend_mode
|
2299
|
+
*/
|
2300
|
+
static VALUE Texture_set_blend_mode(VALUE self, VALUE mode)
|
2301
|
+
{
|
2302
|
+
HANDLE_ERROR(SDL_SetTextureBlendMode(Get_SDL_Texture(self), NUM2INT(mode)));
|
2303
|
+
return mode;
|
2304
|
+
}
|
2305
|
+
|
2306
|
+
/*
|
2307
|
+
* Get an additional alpha value used in render copy operations.
|
2308
|
+
*
|
2309
|
+
* @return [Integer] the current alpha value
|
2310
|
+
*
|
2311
|
+
* @see #alpha_mod=
|
2312
|
+
*/
|
2313
|
+
static VALUE Texture_alpha_mod(VALUE self)
|
2314
|
+
{
|
2315
|
+
Uint8 alpha;
|
2316
|
+
HANDLE_ERROR(SDL_GetTextureAlphaMod(Get_SDL_Texture(self), &alpha));
|
2317
|
+
return INT2FIX(alpha);
|
2318
|
+
}
|
2319
|
+
|
2320
|
+
/*
|
2321
|
+
* @overload alpha_mod=(alpha)
|
2322
|
+
* Set an additional alpha value used in render copy operations.
|
2323
|
+
*
|
2324
|
+
* @param alpha [Integer] the alpha value multiplied into copy operation,
|
2325
|
+
* from 0 to 255
|
2326
|
+
* @return [alpha]
|
2327
|
+
*
|
2328
|
+
* @see #alpha_mod
|
2329
|
+
*/
|
2330
|
+
static VALUE Texture_set_alpha_mod(VALUE self, VALUE alpha)
|
2331
|
+
{
|
2332
|
+
HANDLE_ERROR(SDL_SetTextureAlphaMod(Get_SDL_Texture(self), NUM2UCHAR(alpha)));
|
2333
|
+
return alpha;
|
2334
|
+
}
|
2335
|
+
|
2336
|
+
/*
|
2337
|
+
* Get an additional color value used in render copy operations.
|
2338
|
+
*
|
2339
|
+
* @return [Integer] the current red, green, and blue
|
2340
|
+
* color value.
|
2341
|
+
*/
|
2342
|
+
static VALUE Texture_color_mod(VALUE self)
|
2343
|
+
{
|
2344
|
+
Uint8 r, g, b;
|
2345
|
+
HANDLE_ERROR(SDL_GetTextureColorMod(Get_SDL_Texture(self), &r, &g, &b));
|
2346
|
+
return rb_ary_new3(3, INT2FIX(r), INT2FIX(g), INT2FIX(b));
|
2347
|
+
}
|
2348
|
+
|
2349
|
+
/*
|
2350
|
+
* @overload color_mod=(rgb)
|
2351
|
+
* Set an additional color value used in render copy operations.
|
2352
|
+
*
|
2353
|
+
* @param rgb [Integer] the red, green, and blue
|
2354
|
+
* color value multiplied into copy operations.
|
2355
|
+
* @return [rgb]
|
2356
|
+
*/
|
2357
|
+
static VALUE Texture_set_color_mod(VALUE self, VALUE rgb)
|
2358
|
+
{
|
2359
|
+
SDL_Color color = Color_to_SDL_Color(rgb);
|
2360
|
+
HANDLE_ERROR(SDL_SetTextureColorMod(Get_SDL_Texture(self),
|
2361
|
+
color.r, color.g, color.b));
|
2362
|
+
return rgb;
|
2363
|
+
}
|
2364
|
+
|
2365
|
+
/*
|
2366
|
+
* Get the format of the texture.
|
2367
|
+
*
|
2368
|
+
* @return [SDL2::PixelFormat]
|
2369
|
+
*/
|
2370
|
+
static VALUE Texture_format(VALUE self)
|
2371
|
+
{
|
2372
|
+
Uint32 format;
|
2373
|
+
HANDLE_ERROR(SDL_QueryTexture(Get_SDL_Texture(self), &format, NULL, NULL, NULL));
|
2374
|
+
return PixelFormat_new(format);
|
2375
|
+
}
|
2376
|
+
|
2377
|
+
/*
|
2378
|
+
* Get the access pattern allowed for the texture.
|
2379
|
+
*
|
2380
|
+
* The return value is one of the following:
|
2381
|
+
*
|
2382
|
+
* * {SDL2::Texture::ACCESS_STATIC}
|
2383
|
+
* * {SDL2::Texture::ACCESS_STREAMING}
|
2384
|
+
* * {SDL2::Texture::ACCESS_TARGET}
|
2385
|
+
*
|
2386
|
+
* @return [Integer]
|
2387
|
+
*
|
2388
|
+
* @see SDL2::Renderer#create_texture
|
2389
|
+
*/
|
2390
|
+
static VALUE Texture_access_pattern(VALUE self)
|
2391
|
+
{
|
2392
|
+
int access;
|
2393
|
+
HANDLE_ERROR(SDL_QueryTexture(Get_SDL_Texture(self), NULL, &access, NULL, NULL));
|
2394
|
+
return INT2FIX(access);
|
2395
|
+
}
|
2396
|
+
|
2397
|
+
/*
|
2398
|
+
* Get the width of the texture.
|
2399
|
+
*
|
2400
|
+
* @return [Integer]
|
2401
|
+
*
|
2402
|
+
* @see SDL2::Renderer#create_texture
|
2403
|
+
*/
|
2404
|
+
static VALUE Texture_w(VALUE self)
|
2405
|
+
{
|
2406
|
+
int w;
|
2407
|
+
HANDLE_ERROR(SDL_QueryTexture(Get_SDL_Texture(self), NULL, NULL, &w, NULL));
|
2408
|
+
return INT2FIX(w);
|
2409
|
+
}
|
2410
|
+
|
2411
|
+
/*
|
2412
|
+
* Get the height of the texture.
|
2413
|
+
*
|
2414
|
+
* @return [Integer]
|
2415
|
+
*
|
2416
|
+
* @see SDL2::Renderer#create_texture
|
2417
|
+
*/
|
2418
|
+
static VALUE Texture_h(VALUE self)
|
2419
|
+
{
|
2420
|
+
int h;
|
2421
|
+
HANDLE_ERROR(SDL_QueryTexture(Get_SDL_Texture(self), NULL, NULL, NULL, &h));
|
2422
|
+
return INT2FIX(h);
|
2423
|
+
}
|
2424
|
+
|
2425
|
+
/* @return [String] inspection string */
|
2426
|
+
static VALUE Texture_inspect(VALUE self)
|
2427
|
+
{
|
2428
|
+
Texture* t = Get_Texture(self);
|
2429
|
+
Uint32 format;
|
2430
|
+
int access, w, h;
|
2431
|
+
if (!t->texture)
|
2432
|
+
return rb_sprintf("<%s: (destroyed)>", rb_obj_classname(self));
|
2433
|
+
|
2434
|
+
HANDLE_ERROR(SDL_QueryTexture(t->texture, &format, &access, &w, &h));
|
2435
|
+
return rb_sprintf("<%s:%p format=%s access=%d w=%d h=%d>",
|
2436
|
+
rb_obj_classname(self), (void*)self, SDL_GetPixelFormatName(format),
|
2437
|
+
access, w, h);
|
2438
|
+
}
|
2439
|
+
|
2440
|
+
/* @return [Hash<String=>Object>] (GC) debugging information */
|
2441
|
+
static VALUE Texture_debug_info(VALUE self)
|
2442
|
+
{
|
2443
|
+
Texture* t = Get_Texture(self);
|
2444
|
+
VALUE info = rb_hash_new();
|
2445
|
+
rb_hash_aset(info, rb_str_new2("destroy?"), INT2BOOL(t->texture == NULL));
|
2446
|
+
rb_hash_aset(info, rb_str_new2("refcount"), INT2NUM(t->refcount));
|
2447
|
+
return info;
|
2448
|
+
}
|
2449
|
+
|
2450
|
+
/*
|
2451
|
+
* Document-class: SDL2::Surface
|
2452
|
+
*
|
2453
|
+
* This class represents bitmap images (collection of pixels).
|
2454
|
+
*
|
2455
|
+
* Normally in SDL2, this class is not used for drawing a image
|
2456
|
+
* on a window. {SDL2::Texture} is used for the purpose.
|
2457
|
+
*
|
2458
|
+
* Mainly this class is for compatibility with SDL1, but the class
|
2459
|
+
* is useful for simple pixel manipulation.
|
2460
|
+
* For example, {SDL2::TTF} can create only surfaces, not textures.
|
2461
|
+
* You can convert a surface to texture with
|
2462
|
+
* {SDL2::Renderer#create_texture_from}.
|
2463
|
+
*
|
2464
|
+
* @!method destroy?
|
2465
|
+
* Return true if the surface is {#destroy destroyed}.
|
2466
|
+
*
|
2467
|
+
*/
|
2468
|
+
|
2469
|
+
/*
|
2470
|
+
* @overload load_bmp(path)
|
2471
|
+
* Load a surface from bmp file.
|
2472
|
+
*
|
2473
|
+
* @param path [String] bmp file path
|
2474
|
+
* @return [SDL2::Surface]
|
2475
|
+
* @raise [SDL2::Error] raised when an error occurs.
|
2476
|
+
* For example, if there is no file or the file file
|
2477
|
+
* format is not Windows BMP.
|
2478
|
+
*
|
2479
|
+
*/
|
2480
|
+
static VALUE Surface_s_load_bmp(VALUE self, VALUE fname)
|
2481
|
+
{
|
2482
|
+
SDL_Surface* surface = SDL_LoadBMP(StringValueCStr(fname));
|
2483
|
+
|
2484
|
+
if (surface == NULL)
|
2485
|
+
HANDLE_ERROR(-1);
|
2486
|
+
|
2487
|
+
return Surface_new(surface);
|
2488
|
+
}
|
2489
|
+
|
2490
|
+
/*
|
2491
|
+
* @overload from_string(string, width, heigth, depth, pitch=nil, rmask=nil, gmask=nil, bmask=nil, amask=nil)
|
2492
|
+
*
|
2493
|
+
* Create a RGB surface from pixel data as String object.
|
2494
|
+
*
|
2495
|
+
* If rmask, gmask, bmask are omitted, the default masks are used.
|
2496
|
+
* If amask is omitted, alpha mask is considered to be zero.
|
2497
|
+
*
|
2498
|
+
* @param string [String] the pixel data
|
2499
|
+
* @param width [Integer] the width of the creating surface
|
2500
|
+
* @param height [Integer] the height of the creating surface
|
2501
|
+
* @param depth [Integer] the color depth (in bits) of the creating surface
|
2502
|
+
* @param pitch [Integer] the number of bytes of one scanline
|
2503
|
+
* if this argument is omitted, width*depth/8 is used.
|
2504
|
+
* @param rmask [Integer] the red mask of a pixel
|
2505
|
+
* @param gmask [Integer] the green mask of a pixel
|
2506
|
+
* @param bmask [Integer] the blue mask of a pixel
|
2507
|
+
* @param amask [Integer] the alpha mask of a pixel
|
2508
|
+
* @return [SDL2::Surface] a new surface
|
2509
|
+
* @raise [SDL2::Error] raised when an error occurs in C SDL library
|
2510
|
+
*
|
2511
|
+
*/
|
2512
|
+
static VALUE Surface_s_from_string(int argc, VALUE* argv, VALUE self)
|
2513
|
+
{
|
2514
|
+
VALUE string, width, height, depth, pitch, Rmask, Gmask, Bmask, Amask;
|
2515
|
+
int w, h, d, p, r, g, b, a;
|
2516
|
+
SDL_Surface* surface;
|
2517
|
+
void* pixels;
|
2518
|
+
Surface* s;
|
2519
|
+
|
2520
|
+
rb_scan_args(argc, argv, "45", &string, &width, &height, &depth,
|
2521
|
+
&pitch, &Rmask, &Gmask, &Bmask, &Amask);
|
2522
|
+
StringValue(string);
|
2523
|
+
w = NUM2INT(width);
|
2524
|
+
h = NUM2INT(height);
|
2525
|
+
d = NUM2INT(depth);
|
2526
|
+
p = (pitch == Qnil) ? d*w/8 : NUM2INT(pitch);
|
2527
|
+
r = (Rmask == Qnil) ? 0 : NUM2UINT(Rmask);
|
2528
|
+
g = (Gmask == Qnil) ? 0 : NUM2UINT(Gmask);
|
2529
|
+
b = (Bmask == Qnil) ? 0 : NUM2UINT(Bmask);
|
2530
|
+
a = (Amask == Qnil) ? 0 : NUM2UINT(Amask);
|
2531
|
+
|
2532
|
+
if (RSTRING_LEN(string) < p*h)
|
2533
|
+
rb_raise(rb_eArgError, "String too short");
|
2534
|
+
if (p < d*w/8 )
|
2535
|
+
rb_raise(rb_eArgError, "pitch too small");
|
2536
|
+
|
2537
|
+
pixels = ruby_xmalloc(RSTRING_LEN(string));
|
2538
|
+
memcpy(pixels, RSTRING_PTR(string), RSTRING_LEN(string));
|
2539
|
+
surface = SDL_CreateRGBSurfaceFrom(pixels, w, h, d, p, r, g, b, a);
|
2540
|
+
if (!surface)
|
2541
|
+
SDL_ERROR();
|
2542
|
+
|
2543
|
+
RB_GC_GUARD(string);
|
2544
|
+
|
2545
|
+
s = ALLOC(Surface);
|
2546
|
+
s->surface = surface;
|
2547
|
+
s->need_to_free_pixels = 1;
|
2548
|
+
return Data_Wrap_Struct(cSurface, 0, Surface_free, s);
|
2549
|
+
}
|
2550
|
+
|
2551
|
+
/*
|
2552
|
+
* Destroy the surface and deallocate the memory for pixels.
|
2553
|
+
*
|
2554
|
+
* @return [nil]
|
2555
|
+
* @see #destroy?
|
2556
|
+
*/
|
2557
|
+
static VALUE Surface_destroy(VALUE self)
|
2558
|
+
{
|
2559
|
+
Surface* s = Get_Surface(self);
|
2560
|
+
if (s->need_to_free_pixels)
|
2561
|
+
free(s->surface->pixels);
|
2562
|
+
s->need_to_free_pixels = 0;
|
2563
|
+
if (s->surface)
|
2564
|
+
SDL_FreeSurface(s->surface);
|
2565
|
+
s->surface = NULL;
|
2566
|
+
return Qnil;
|
2567
|
+
}
|
2568
|
+
|
2569
|
+
/*
|
2570
|
+
* Get the blending mode of the surface used for blit operations.
|
2571
|
+
*
|
2572
|
+
* @return [Integer]
|
2573
|
+
* @see #blend_mode=
|
2574
|
+
*/
|
2575
|
+
static VALUE Surface_blend_mode(VALUE self)
|
2576
|
+
{
|
2577
|
+
SDL_BlendMode mode;
|
2578
|
+
HANDLE_ERROR(SDL_GetSurfaceBlendMode(Get_SDL_Surface(self), &mode));
|
2579
|
+
return INT2FIX(mode);
|
2580
|
+
}
|
2581
|
+
|
2582
|
+
/*
|
2583
|
+
* @overload blend_mode=(mode)
|
2584
|
+
* Set the blending mode of the surface used for blit operations.
|
2585
|
+
*
|
2586
|
+
* @param mode [Integer] the blending mode
|
2587
|
+
* @return [mode]
|
2588
|
+
* @see #blend_mode
|
2589
|
+
*/
|
2590
|
+
static VALUE Surface_set_blend_mode(VALUE self, VALUE mode)
|
2591
|
+
{
|
2592
|
+
HANDLE_ERROR(SDL_SetSurfaceBlendMode(Get_SDL_Surface(self), NUM2INT(mode)));
|
2593
|
+
return mode;
|
2594
|
+
}
|
2595
|
+
|
2596
|
+
/*
|
2597
|
+
* Return true if the surface need to lock when you get access to the
|
2598
|
+
* pixel data of the surface.
|
2599
|
+
*
|
2600
|
+
* @see #lock
|
2601
|
+
*/
|
2602
|
+
static VALUE Surface_must_lock_p(VALUE self)
|
2603
|
+
{
|
2604
|
+
return INT2BOOL(SDL_MUSTLOCK(Get_SDL_Surface(self)));
|
2605
|
+
}
|
2606
|
+
|
2607
|
+
/*
|
2608
|
+
* Lock the surface.
|
2609
|
+
*
|
2610
|
+
* @return [nil]
|
2611
|
+
*
|
2612
|
+
* @see #unlock
|
2613
|
+
* @see #must_lock?
|
2614
|
+
*/
|
2615
|
+
static VALUE Surface_lock(VALUE self)
|
2616
|
+
{
|
2617
|
+
HANDLE_ERROR(SDL_LockSurface(Get_SDL_Surface(self)));
|
2618
|
+
return Qnil;
|
2619
|
+
}
|
2620
|
+
|
2621
|
+
/*
|
2622
|
+
* Unlock the surface.
|
2623
|
+
*
|
2624
|
+
* @return [nil]
|
2625
|
+
*
|
2626
|
+
* @see #lock
|
2627
|
+
*/
|
2628
|
+
static VALUE Surface_unlock(VALUE self)
|
2629
|
+
{
|
2630
|
+
SDL_UnlockSurface(Get_SDL_Surface(self));
|
2631
|
+
return Qnil;
|
2632
|
+
}
|
2633
|
+
|
2634
|
+
/*
|
2635
|
+
* @overload pixel(x, y)
|
2636
|
+
* Get a pixel data at (**x**, **y**)
|
2637
|
+
*
|
2638
|
+
* @param x [Integer] the x coordinate
|
2639
|
+
* @param y [Integer] the y coordinate
|
2640
|
+
* @return [Integer] pixel data
|
2641
|
+
*
|
2642
|
+
* @see #pixel_color
|
2643
|
+
*
|
2644
|
+
*/
|
2645
|
+
static VALUE Surface_pixel(VALUE self, VALUE x_coord, VALUE y_coord)
|
2646
|
+
{
|
2647
|
+
int x = NUM2INT(x_coord);
|
2648
|
+
int y = NUM2INT(y_coord);
|
2649
|
+
SDL_Surface* surface = Get_SDL_Surface(self);
|
2650
|
+
int offset;
|
2651
|
+
Uint32 pixel = 0;
|
2652
|
+
int i;
|
2653
|
+
|
2654
|
+
if (x < 0 || x >= surface->w || y < 0 || y >= surface->h)
|
2655
|
+
rb_raise(rb_eArgError, "(%d, %d) out of range for %dx%d",
|
2656
|
+
x, y, surface->w, surface->h);
|
2657
|
+
offset = surface->pitch * y + surface->format->BytesPerPixel * x;
|
2658
|
+
for (i=0; i<surface->format->BytesPerPixel; ++i) {
|
2659
|
+
pixel += *((Uint8*)surface->pixels + offset + i) << (8*i);
|
2660
|
+
}
|
2661
|
+
|
2662
|
+
return UINT2NUM(SDL_SwapLE32(pixel));
|
2663
|
+
}
|
2664
|
+
|
2665
|
+
/*
|
2666
|
+
* Get all pixel data of the surface as a string.
|
2667
|
+
*
|
2668
|
+
* @return [String]
|
2669
|
+
*
|
2670
|
+
*/
|
2671
|
+
static VALUE Surface_pixels(VALUE self)
|
2672
|
+
{
|
2673
|
+
SDL_Surface* surface = Get_SDL_Surface(self);
|
2674
|
+
int size = surface->h * surface->pitch;
|
2675
|
+
return rb_str_new(surface->pixels, size);
|
2676
|
+
}
|
2677
|
+
|
2678
|
+
/*
|
2679
|
+
* Get the pitch (bytes per horizontal line) of the surface.
|
2680
|
+
*
|
2681
|
+
* @return [Integer]
|
2682
|
+
*/
|
2683
|
+
static VALUE Surface_pitch(VALUE self)
|
2684
|
+
{
|
2685
|
+
return UINT2NUM(Get_SDL_Surface(self)->pitch);
|
2686
|
+
}
|
2687
|
+
|
2688
|
+
/*
|
2689
|
+
* Get bits per pixel of the surface.
|
2690
|
+
*
|
2691
|
+
* @return [Integer]
|
2692
|
+
*/
|
2693
|
+
static VALUE Surface_bits_per_pixel(VALUE self)
|
2694
|
+
{
|
2695
|
+
return UCHAR2NUM(Get_SDL_Surface(self)->format->BitsPerPixel);
|
2696
|
+
}
|
2697
|
+
|
2698
|
+
/*
|
2699
|
+
* Get bytes per pixel of the surface.
|
2700
|
+
*
|
2701
|
+
* @return [Integer]
|
2702
|
+
*/
|
2703
|
+
static VALUE Surface_bytes_per_pixel(VALUE self)
|
2704
|
+
{
|
2705
|
+
return UCHAR2NUM(Get_SDL_Surface(self)->format->BytesPerPixel);
|
2706
|
+
}
|
2707
|
+
|
2708
|
+
/*
|
2709
|
+
* @overload pixel_color(x, y)
|
2710
|
+
* Get the pixel color (r,g,b and a) at (**x**, **y**) of the surface.
|
2711
|
+
*
|
2712
|
+
* @param x [Integer] the x coordinate
|
2713
|
+
* @param y [Integer] the y coordinate
|
2714
|
+
* @return [[Integer, Integer, Integer, Integer]]
|
2715
|
+
* the red, green, blue, and alpha component of the specified pixel.
|
2716
|
+
*
|
2717
|
+
*/
|
2718
|
+
static VALUE Surface_pixel_color(VALUE self, VALUE x, VALUE y)
|
2719
|
+
{
|
2720
|
+
Uint32 pixel = NUM2UINT(Surface_pixel(self, x, y));
|
2721
|
+
SDL_Surface* surface = Get_SDL_Surface(self);
|
2722
|
+
Uint8 r, g, b, a;
|
2723
|
+
SDL_GetRGBA(pixel, surface->format, &r, &g, &b, &a);
|
2724
|
+
|
2725
|
+
return rb_ary_new3(4, UCHAR2NUM(r), UCHAR2NUM(g), UCHAR2NUM(b), UCHAR2NUM(a));
|
2726
|
+
}
|
2727
|
+
|
2728
|
+
static Uint32 pixel_value(VALUE val, SDL_PixelFormat* format)
|
2729
|
+
{
|
2730
|
+
if (RTEST(rb_funcall(val, rb_intern("integer?"), 0, 0))) {
|
2731
|
+
return NUM2UINT(val);
|
2732
|
+
} else {
|
2733
|
+
long len;
|
2734
|
+
Uint8 r, g, b, a;
|
2735
|
+
Check_Type(val, T_ARRAY);
|
2736
|
+
len = RARRAY_LEN(val);
|
2737
|
+
if (len == 3 || len == 4) {
|
2738
|
+
r = NUM2UCHAR(rb_ary_entry(val, 0));
|
2739
|
+
g = NUM2UCHAR(rb_ary_entry(val, 1));
|
2740
|
+
b = NUM2UCHAR(rb_ary_entry(val, 2));
|
2741
|
+
if (len == 3)
|
2742
|
+
a = 255;
|
2743
|
+
else
|
2744
|
+
a = NUM2UCHAR(rb_ary_entry(val, 3));
|
2745
|
+
return SDL_MapRGBA(format, r, g, b, a);
|
2746
|
+
} else {
|
2747
|
+
rb_raise(rb_eArgError, "Wrong length of array (%ld for 3..4)", len);
|
2748
|
+
}
|
2749
|
+
}
|
2750
|
+
return 0;
|
2751
|
+
}
|
2752
|
+
|
2753
|
+
/*
|
2754
|
+
* Unset the color key of the surface.
|
2755
|
+
*
|
2756
|
+
* @return [nil]
|
2757
|
+
*
|
2758
|
+
* @see #color_key=
|
2759
|
+
*/
|
2760
|
+
static VALUE Surface_unset_color_key(VALUE self)
|
2761
|
+
{
|
2762
|
+
HANDLE_ERROR(SDL_SetColorKey(Get_SDL_Surface(self), SDL_FALSE, 0));
|
2763
|
+
return Qnil;
|
2764
|
+
}
|
2765
|
+
|
2766
|
+
/*
|
2767
|
+
* @overload color_key=(key)
|
2768
|
+
* Set the color key of the surface
|
2769
|
+
*
|
2770
|
+
* @param key [Integer, Array<Integer>]
|
2771
|
+
* the color key, pixel value (see {#pixel}) or pixel color (array of
|
2772
|
+
* three or four integer elements).
|
2773
|
+
*
|
2774
|
+
* @return [key]
|
2775
|
+
*
|
2776
|
+
* @see #color_key
|
2777
|
+
* @see #unset_color_key
|
2778
|
+
*/
|
2779
|
+
static VALUE Surface_set_color_key(VALUE self, VALUE key)
|
2780
|
+
{
|
2781
|
+
SDL_Surface* surface = Get_SDL_Surface(self);
|
2782
|
+
if (key == Qnil)
|
2783
|
+
return Surface_unset_color_key(self);
|
2784
|
+
|
2785
|
+
HANDLE_ERROR(SDL_SetColorKey(surface, SDL_TRUE, pixel_value(key, surface->format)));
|
2786
|
+
|
2787
|
+
return key;
|
2788
|
+
}
|
2789
|
+
|
2790
|
+
/*
|
2791
|
+
* Get the color key of the surface
|
2792
|
+
*
|
2793
|
+
* @return [Integer] the color key, as pixel value (see {#pixel})
|
2794
|
+
*
|
2795
|
+
* @see #color_key=
|
2796
|
+
* @see #unset_color_key
|
2797
|
+
*/
|
2798
|
+
static VALUE Surface_color_key(VALUE self)
|
2799
|
+
{
|
2800
|
+
Uint32 key;
|
2801
|
+
if (SDL_GetColorKey(Get_SDL_Surface(self), &key) < 0)
|
2802
|
+
return Qnil;
|
2803
|
+
else
|
2804
|
+
return UINT2NUM(key);
|
2805
|
+
}
|
2806
|
+
|
2807
|
+
/*
|
2808
|
+
* Get the width of the surface.
|
2809
|
+
*
|
2810
|
+
* @return [Integer]
|
2811
|
+
*/
|
2812
|
+
static VALUE Surface_w(VALUE self)
|
2813
|
+
{
|
2814
|
+
return INT2NUM(Get_SDL_Surface(self)->w);
|
2815
|
+
}
|
2816
|
+
|
2817
|
+
/*
|
2818
|
+
* Get the height of the surface.
|
2819
|
+
*
|
2820
|
+
* @return [Integer]
|
2821
|
+
*/
|
2822
|
+
static VALUE Surface_h(VALUE self)
|
2823
|
+
{
|
2824
|
+
return INT2NUM(Get_SDL_Surface(self)->h);
|
2825
|
+
}
|
2826
|
+
|
2827
|
+
/*
|
2828
|
+
* @overload blit_to(dst, x, y)
|
2829
|
+
* Perform a fast blit to **dst** surface.
|
2830
|
+
*
|
2831
|
+
* @param dst [SDL2::Surface] the destination surface
|
2832
|
+
* @param x [Integer]
|
2833
|
+
* @param y [Integer]
|
2834
|
+
* Blits this surface onto the given destination surface at the given
|
2835
|
+
* coordinates.
|
2836
|
+
*
|
2837
|
+
* @return [self]
|
2838
|
+
*/
|
2839
|
+
static VALUE Surface_blit_to(VALUE self, VALUE dst, VALUE x, VALUE y)
|
2840
|
+
{
|
2841
|
+
SDL_Surface *surface = Get_SDL_Surface(self);
|
2842
|
+
SDL_Rect rect;
|
2843
|
+
|
2844
|
+
rect.x = FIX2INT(x);
|
2845
|
+
rect.y = FIX2INT(y);
|
2846
|
+
rect.w = surface->w;
|
2847
|
+
rect.h = surface->h;
|
2848
|
+
|
2849
|
+
HANDLE_ERROR(SDL_BlitSurface(surface,
|
2850
|
+
NULL,
|
2851
|
+
Get_SDL_Surface(dst),
|
2852
|
+
&rect));
|
2853
|
+
return self;
|
2854
|
+
}
|
2855
|
+
|
2856
|
+
|
2857
|
+
/*
|
2858
|
+
* @overload fill_rect(rect, color)
|
2859
|
+
* Draw a filled rectangle using the given color.
|
2860
|
+
*
|
2861
|
+
* @param rect [SDL2::Rect] the drawing rectangle
|
2862
|
+
* @param color [Integer]
|
2863
|
+
*
|
2864
|
+
* @return [nil]
|
2865
|
+
*/
|
2866
|
+
static VALUE Surface_fill_rect(VALUE self, VALUE rect, VALUE rgba)
|
2867
|
+
{
|
2868
|
+
/* Remove alpha channel */
|
2869
|
+
Uint32 color = NUM2UINT(rgba) >> 8;
|
2870
|
+
HANDLE_ERROR(SDL_FillRect(Get_SDL_Surface(self), Get_SDL_Rect_or_NULL(rect), color));
|
2871
|
+
return Qnil;
|
2872
|
+
}
|
2873
|
+
|
2874
|
+
/*
|
2875
|
+
* @overload blit(src, srcrect, dst, dstrect)
|
2876
|
+
* Perform a fast blit from **src** surface to **dst** surface.
|
2877
|
+
*
|
2878
|
+
* @param src [SDL2::Surface] the source surface
|
2879
|
+
* @param srcrect [SDL2::Rect,nil] the region in the source surface,
|
2880
|
+
* if nil is given, the whole source is used
|
2881
|
+
* @param dst [SDL2::Surface] the destination surface
|
2882
|
+
* @param dstrect [SDL2::Rect,nil] the region in the destination surface
|
2883
|
+
* if nil is given, the source image is copied to (0, 0) on
|
2884
|
+
* the destination surface.
|
2885
|
+
* **dstrect** is changed by this method to store the
|
2886
|
+
* actually copied region (since the surface has clipping functionality,
|
2887
|
+
* actually copied region may be different from given **dstrect**).
|
2888
|
+
* @return [nil]
|
2889
|
+
*/
|
2890
|
+
static VALUE Surface_s_blit(VALUE self, VALUE src, VALUE srcrect, VALUE dst, VALUE dstrect)
|
2891
|
+
{
|
2892
|
+
HANDLE_ERROR(SDL_BlitSurface(Get_SDL_Surface(src),
|
2893
|
+
Get_SDL_Rect_or_NULL(srcrect),
|
2894
|
+
Get_SDL_Surface(dst),
|
2895
|
+
Get_SDL_Rect_or_NULL(dstrect)));
|
2896
|
+
return Qnil;
|
2897
|
+
}
|
2898
|
+
|
2899
|
+
/*
|
2900
|
+
* @overload blit_scaled(src, srcrect, dst, dstrect)
|
2901
|
+
* Perform a fast scaling blit from **src** surface to **dst** surface.
|
2902
|
+
*
|
2903
|
+
* @param src [SDL2::Surface] the source surface
|
2904
|
+
* @param srcrect [SDL2::Rect,nil] the region in the source surface,
|
2905
|
+
* if nil is given, the whole source is used
|
2906
|
+
* @param dst [SDL2::Surface] the destination surface
|
2907
|
+
* @param dstrect [SDL2::Rect,nil] the region in the destination surface
|
2908
|
+
* if nil is given, the source image is copied to (0, 0) on
|
2909
|
+
* the destination surface.
|
2910
|
+
* **dstrect** is changed by this method to store the
|
2911
|
+
* actually copied region (since the surface has clipping functionality,
|
2912
|
+
* actually copied region may be different from given **dstrect**).
|
2913
|
+
* @return [nil]
|
2914
|
+
*/
|
2915
|
+
static VALUE Surface_s_blit_scaled(VALUE self, VALUE src, VALUE srcrect, VALUE dst, VALUE dstrect)
|
2916
|
+
{
|
2917
|
+
HANDLE_ERROR(SDL_BlitScaled(Get_SDL_Surface(src),
|
2918
|
+
Get_SDL_Rect_or_NULL(srcrect),
|
2919
|
+
Get_SDL_Surface(dst),
|
2920
|
+
Get_SDL_Rect_or_NULL(dstrect)));
|
2921
|
+
return Qnil;
|
2922
|
+
}
|
2923
|
+
|
2924
|
+
/*
|
2925
|
+
* Create an empty RGB surface.
|
2926
|
+
*
|
2927
|
+
* If rmask, gmask, bmask are omitted, the default masks are used.
|
2928
|
+
* If amask is omitted, alpha mask is considered to be zero.
|
2929
|
+
*
|
2930
|
+
* @overload new(width, height, depth)
|
2931
|
+
* @overload new(width, height, depth, amask)
|
2932
|
+
* @overload new(width, heigth, depth, rmask, gmask, bmask, amask)
|
2933
|
+
*
|
2934
|
+
* @param width [Integer] the width of the new surface
|
2935
|
+
* @param height [Integer] the height of the new surface
|
2936
|
+
* @param depth [Integer] the bit depth of the new surface
|
2937
|
+
* @param rmask [Integer] the red mask of a pixel
|
2938
|
+
* @param gmask [Integer] the green mask of a pixel
|
2939
|
+
* @param bmask [Integer] the blue mask of a pixel
|
2940
|
+
* @param amask [Integer] the alpha mask of a pixel
|
2941
|
+
*
|
2942
|
+
* @return [SDL2::Surface]
|
2943
|
+
*/
|
2944
|
+
static VALUE Surface_s_new(int argc, VALUE* argv, VALUE self)
|
2945
|
+
{
|
2946
|
+
VALUE width, height, depth;
|
2947
|
+
Uint32 Rmask, Gmask, Bmask, Amask;
|
2948
|
+
SDL_Surface * surface;
|
2949
|
+
|
2950
|
+
if (argc == 3) {
|
2951
|
+
rb_scan_args(argc, argv, "30", &width, &height, &depth);
|
2952
|
+
Rmask = Gmask = Bmask = Amask = 0;
|
2953
|
+
} else if (argc == 7) {
|
2954
|
+
VALUE rm, gm, bm, am;
|
2955
|
+
rb_scan_args(argc, argv, "70", &width, &height, &depth, &rm, &gm, &bm, &am);
|
2956
|
+
Rmask = NUM2UINT(rm); Gmask = NUM2UINT(gm);
|
2957
|
+
Bmask = NUM2UINT(bm); Amask = NUM2UINT(am);
|
2958
|
+
} else {
|
2959
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%d for 4 or 7)", argc);
|
2960
|
+
}
|
2961
|
+
surface = SDL_CreateRGBSurface(0, NUM2INT(width), NUM2INT(height), NUM2INT(depth),
|
2962
|
+
Rmask, Gmask, Bmask, Amask);
|
2963
|
+
if (!surface)
|
2964
|
+
SDL_ERROR();
|
2965
|
+
|
2966
|
+
return Surface_new(surface);
|
2967
|
+
}
|
2968
|
+
|
2969
|
+
#define FIELD_ACCESSOR(classname, typename, field) \
|
2970
|
+
static VALUE classname##_##field(VALUE self) \
|
2971
|
+
{ \
|
2972
|
+
typename* r; Data_Get_Struct(self, typename, r); \
|
2973
|
+
return INT2NUM(r->field); \
|
2974
|
+
} \
|
2975
|
+
static VALUE classname##_set_##field(VALUE self, VALUE val) \
|
2976
|
+
{ \
|
2977
|
+
typename* r; Data_Get_Struct(self, typename, r); \
|
2978
|
+
r->field = NUM2INT(val); return val; \
|
2979
|
+
}
|
2980
|
+
|
2981
|
+
|
2982
|
+
/* Document-class: SDL2::Rect
|
2983
|
+
*
|
2984
|
+
* This class represents a rectangle in SDL2.
|
2985
|
+
*
|
2986
|
+
* Any rectangle is represented by four attributes x, y, w, and h,
|
2987
|
+
* and these four attributes must be integer.
|
2988
|
+
*
|
2989
|
+
* @!attribute [rw] x
|
2990
|
+
* X coordinate of the left-top point of the rectangle
|
2991
|
+
* @return [Integer]
|
2992
|
+
*
|
2993
|
+
* @!attribute [rw] y
|
2994
|
+
* Y coordinate of the left-top point of the rectangle
|
2995
|
+
* @return [Integer]
|
2996
|
+
*
|
2997
|
+
* @!attribute [rw] w
|
2998
|
+
* Width of the rectangle
|
2999
|
+
* @return [Integer]
|
3000
|
+
*
|
3001
|
+
* @!attribute [rw] h
|
3002
|
+
* Height of the rectangle
|
3003
|
+
* @return [Integer]
|
3004
|
+
*
|
3005
|
+
* @!method self.[](*args)
|
3006
|
+
* Alias of new. See {#initialize}.
|
3007
|
+
* @return [SDL2::Rect]
|
3008
|
+
*/
|
3009
|
+
static VALUE Rect_s_allocate(VALUE klass)
|
3010
|
+
{
|
3011
|
+
SDL_Rect* rect = ALLOC(SDL_Rect);
|
3012
|
+
rect->x = rect->y = rect->w = rect->h = 0;
|
3013
|
+
|
3014
|
+
return Data_Wrap_Struct(cRect, 0, free, rect);
|
3015
|
+
}
|
3016
|
+
|
3017
|
+
/*
|
3018
|
+
* Create a new SDL2::Rect object
|
3019
|
+
*
|
3020
|
+
* @return [SDL2::Rect]
|
3021
|
+
*
|
3022
|
+
* @overload initialize(x, y, w, h)
|
3023
|
+
* Create a new SDL2::Rect object
|
3024
|
+
*
|
3025
|
+
* @param x [Integer] X coordinate of the left-top point of the rectangle
|
3026
|
+
* @param y [Integer] Y coordinate of the left-top point of the rectangle
|
3027
|
+
* @param w [Integer] Width of the rectangle
|
3028
|
+
* @param h [Integer] Height of the rectangle
|
3029
|
+
*
|
3030
|
+
* @overload initialize
|
3031
|
+
* Create a new SDL2::Rect object whose x, w, w, and h are all
|
3032
|
+
* zero.
|
3033
|
+
*/
|
3034
|
+
static VALUE Rect_initialize(int argc, VALUE* argv, VALUE self)
|
3035
|
+
{
|
3036
|
+
VALUE x, y, w, h;
|
3037
|
+
rb_scan_args(argc, argv, "04", &x, &y, &w, &h);
|
3038
|
+
if (argc == 0) {
|
3039
|
+
/* do nothing*/
|
3040
|
+
} else if (argc == 4) {
|
3041
|
+
SDL_Rect* rect;
|
3042
|
+
Data_Get_Struct(self, SDL_Rect, rect);
|
3043
|
+
rect->x = NUM2INT(x); rect->y = NUM2INT(y);
|
3044
|
+
rect->w = NUM2INT(w); rect->h = NUM2INT(h);
|
3045
|
+
} else {
|
3046
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 or 4)", argc);
|
3047
|
+
}
|
3048
|
+
return Qnil;
|
3049
|
+
}
|
3050
|
+
|
3051
|
+
/*
|
3052
|
+
* Inspection string for debug
|
3053
|
+
* @return [String]
|
3054
|
+
*/
|
3055
|
+
static VALUE Rect_inspect(VALUE self)
|
3056
|
+
{
|
3057
|
+
SDL_Rect* rect = Get_SDL_Rect(self);
|
3058
|
+
return rb_sprintf("<SDL2::Rect: x=%d y=%d w=%d h=%d>",
|
3059
|
+
rect->x, rect->y, rect->w, rect->h);
|
3060
|
+
}
|
3061
|
+
|
3062
|
+
FIELD_ACCESSOR(Rect, SDL_Rect, x);
|
3063
|
+
FIELD_ACCESSOR(Rect, SDL_Rect, y);
|
3064
|
+
FIELD_ACCESSOR(Rect, SDL_Rect, w);
|
3065
|
+
FIELD_ACCESSOR(Rect, SDL_Rect, h);
|
3066
|
+
|
3067
|
+
/*
|
3068
|
+
* @overload intersection(other)
|
3069
|
+
* Returns the intersection rect of self and other.
|
3070
|
+
*
|
3071
|
+
* If there is no intersection, returns nil.
|
3072
|
+
*
|
3073
|
+
* @return [SDL2::Rect, nil]
|
3074
|
+
* @param [SDL2::Rect] other rectangle
|
3075
|
+
*/
|
3076
|
+
static VALUE Rect_intersection(VALUE self, VALUE other)
|
3077
|
+
{
|
3078
|
+
VALUE result = Rect_s_allocate(cRect);
|
3079
|
+
if (SDL_IntersectRect(Get_SDL_Rect(self), Get_SDL_Rect(other), Get_SDL_Rect(result))) {
|
3080
|
+
return result;
|
3081
|
+
} else {
|
3082
|
+
return Qnil;
|
3083
|
+
}
|
3084
|
+
}
|
3085
|
+
|
3086
|
+
/*
|
3087
|
+
* @overload union(other)
|
3088
|
+
* Returns the minimal rect containing self and other
|
3089
|
+
*
|
3090
|
+
* @return [SDL2::Rect]
|
3091
|
+
* @param [SDL2::Rect] other rectangle
|
3092
|
+
*/
|
3093
|
+
static VALUE Rect_union(VALUE self, VALUE other)
|
3094
|
+
{
|
3095
|
+
VALUE result = Rect_s_allocate(cRect);
|
3096
|
+
SDL_UnionRect(Get_SDL_Rect(self), Get_SDL_Rect(other), Get_SDL_Rect(result));
|
3097
|
+
return result;
|
3098
|
+
}
|
3099
|
+
|
3100
|
+
/*
|
3101
|
+
* Document-class: SDL2::Point
|
3102
|
+
*
|
3103
|
+
* This class represents a point in SDL library.
|
3104
|
+
* Some method requires this method.
|
3105
|
+
*
|
3106
|
+
* @!attribute [rw] x
|
3107
|
+
* X coordinate of the point.
|
3108
|
+
* @return [Integer]
|
3109
|
+
*
|
3110
|
+
* @!attribute [rw] y
|
3111
|
+
* Y coordinate of the point.
|
3112
|
+
* @return [Integer]
|
3113
|
+
*/
|
3114
|
+
static VALUE Point_s_allocate(VALUE klass)
|
3115
|
+
{
|
3116
|
+
SDL_Point* point;
|
3117
|
+
return Data_Make_Struct(klass, SDL_Point, 0, free, point);
|
3118
|
+
}
|
3119
|
+
|
3120
|
+
/*
|
3121
|
+
* Create a new point object.
|
3122
|
+
*
|
3123
|
+
* @overload initialize(x, y)
|
3124
|
+
* @param x the x coordinate of the point
|
3125
|
+
* @param y the y coordinate of the point
|
3126
|
+
*
|
3127
|
+
* @overload initialize
|
3128
|
+
* x and y of the created point object are initialized by 0
|
3129
|
+
*
|
3130
|
+
* @return [SDL2::Point]
|
3131
|
+
*
|
3132
|
+
*/
|
3133
|
+
static VALUE Point_initialize(int argc, VALUE* argv, VALUE self)
|
3134
|
+
{
|
3135
|
+
VALUE x, y;
|
3136
|
+
SDL_Point* point = Get_SDL_Point(self);
|
3137
|
+
rb_scan_args(argc, argv, "02", &x, &y);
|
3138
|
+
point->x = (x == Qnil) ? 0 : NUM2INT(x);
|
3139
|
+
point->y = (y == Qnil) ? 0 : NUM2INT(y);
|
3140
|
+
return Qnil;
|
3141
|
+
}
|
3142
|
+
|
3143
|
+
/*
|
3144
|
+
* Return inspection string.
|
3145
|
+
* @return [String]
|
3146
|
+
*/
|
3147
|
+
static VALUE Point_inspect(VALUE self)
|
3148
|
+
{
|
3149
|
+
SDL_Point* point = Get_SDL_Point(self);
|
3150
|
+
return rb_sprintf("<SDL2::Point x=%d y=%d>", point->x, point->y);
|
3151
|
+
}
|
3152
|
+
|
3153
|
+
FIELD_ACCESSOR(Point, SDL_Point, x);
|
3154
|
+
FIELD_ACCESSOR(Point, SDL_Point, y);
|
3155
|
+
|
3156
|
+
|
3157
|
+
/*
|
3158
|
+
* Document-class: SDL2::PixelFormat
|
3159
|
+
*
|
3160
|
+
* This class represents pixel format of textures, windows, and displays.
|
3161
|
+
*
|
3162
|
+
* In C level, SDL use unsigned integers as pixel formats. This class
|
3163
|
+
* wraps these integers. You can get the integers from {#format}.
|
3164
|
+
*
|
3165
|
+
* @!attribute [r] format
|
3166
|
+
* An integer representing the pixel format.
|
3167
|
+
*
|
3168
|
+
* @return [Integer]
|
3169
|
+
*/
|
3170
|
+
|
3171
|
+
/*
|
3172
|
+
* @overload initialize(format)
|
3173
|
+
*
|
3174
|
+
* Initialize pixel format from the given integer representing a fomrmat.
|
3175
|
+
*
|
3176
|
+
* @param format [Integer] an unsigned integer as a pixel formats
|
3177
|
+
*/
|
3178
|
+
static VALUE PixelForamt_initialize(VALUE self, VALUE format)
|
3179
|
+
{
|
3180
|
+
rb_iv_set(self, "@format", format);
|
3181
|
+
return Qnil;
|
3182
|
+
}
|
3183
|
+
|
3184
|
+
/*
|
3185
|
+
* Get the type of the format.
|
3186
|
+
*
|
3187
|
+
* @return [Integer] One of the constants of {Type} module.
|
3188
|
+
*/
|
3189
|
+
static VALUE PixelFormat_type(VALUE self)
|
3190
|
+
{
|
3191
|
+
return UINT2NUM(SDL_PIXELTYPE(NUM2UINT(rb_iv_get(self, "@format"))));
|
3192
|
+
}
|
3193
|
+
|
3194
|
+
/*
|
3195
|
+
define(`PIXELFORMAT_ATTR_READER',
|
3196
|
+
`static VALUE PixelFormat_$1(VALUE self)
|
3197
|
+
{
|
3198
|
+
return $3($2(NUM2UINT(rb_iv_get(self, "@format"))));
|
3199
|
+
}')
|
3200
|
+
*/
|
3201
|
+
|
3202
|
+
/*
|
3203
|
+
* Get the human readable name of the pixel format
|
3204
|
+
*
|
3205
|
+
* @return [String]
|
3206
|
+
*/
|
3207
|
+
PIXELFORMAT_ATTR_READER(name, SDL_GetPixelFormatName, utf8str_new_cstr);
|
3208
|
+
|
3209
|
+
/*
|
3210
|
+
* Get the ordering of channels or bits in the pixel format.
|
3211
|
+
*
|
3212
|
+
* @return [Integer] One of the constants of {BitmapOrder} module or {PackedOrder} module.
|
3213
|
+
*/
|
3214
|
+
PIXELFORMAT_ATTR_READER(order, SDL_PIXELORDER, UINT2NUM);
|
3215
|
+
|
3216
|
+
/*
|
3217
|
+
* Get the channel bit pattern of the pixel format.
|
3218
|
+
*
|
3219
|
+
* @return [Integer] One of the constants of {PackedLayout} module.
|
3220
|
+
*/
|
3221
|
+
PIXELFORMAT_ATTR_READER(layout, SDL_PIXELLAYOUT, UINT2NUM);
|
3222
|
+
|
3223
|
+
/*
|
3224
|
+
* Get the number of bits per pixel.
|
3225
|
+
*
|
3226
|
+
* @return [Integer]
|
3227
|
+
*/
|
3228
|
+
PIXELFORMAT_ATTR_READER(bits_per_pixel, SDL_BITSPERPIXEL, INT2NUM);
|
3229
|
+
|
3230
|
+
/*
|
3231
|
+
* Get the number of bytes per pixel.
|
3232
|
+
*
|
3233
|
+
* @return [Integer]
|
3234
|
+
*/
|
3235
|
+
PIXELFORMAT_ATTR_READER(bytes_per_pixel, SDL_BYTESPERPIXEL, INT2NUM);
|
3236
|
+
|
3237
|
+
/*
|
3238
|
+
* Return true if the pixel format have a palette.
|
3239
|
+
*/
|
3240
|
+
PIXELFORMAT_ATTR_READER(indexed_p, SDL_ISPIXELFORMAT_INDEXED, INT2BOOL);
|
3241
|
+
|
3242
|
+
/*
|
3243
|
+
* Return true if the pixel format have an alpha channel.
|
3244
|
+
*/
|
3245
|
+
PIXELFORMAT_ATTR_READER(alpha_p, SDL_ISPIXELFORMAT_ALPHA, INT2BOOL);
|
3246
|
+
|
3247
|
+
/*
|
3248
|
+
* Return true if the pixel format is not indexed, and not RGB(A),
|
3249
|
+
* for example, the pixel format is YUV.
|
3250
|
+
*/
|
3251
|
+
PIXELFORMAT_ATTR_READER(fourcc_p, SDL_ISPIXELFORMAT_FOURCC, INT2BOOL);
|
3252
|
+
|
3253
|
+
/*
|
3254
|
+
* @overload ==(other)
|
3255
|
+
* Return true if two pixel format is the same format.
|
3256
|
+
*
|
3257
|
+
* @return [Boolean]
|
3258
|
+
*/
|
3259
|
+
static VALUE PixelFormat_eq(VALUE self, VALUE other)
|
3260
|
+
{
|
3261
|
+
if (!rb_obj_is_kind_of(other, cPixelFormat))
|
3262
|
+
return Qfalse;
|
3263
|
+
|
3264
|
+
return INT2BOOL(rb_iv_get(self, "@format") == rb_iv_get(other, "@format"));
|
3265
|
+
}
|
3266
|
+
|
3267
|
+
/* @return [String] inspection string */
|
3268
|
+
static VALUE PixelFormat_inspect(VALUE self)
|
3269
|
+
{
|
3270
|
+
Uint32 format = NUM2UINT(rb_iv_get(self, "@format"));
|
3271
|
+
return rb_sprintf("<%s: %s type=%d order=%d layout=%d"
|
3272
|
+
" bits=%d bytes=%d indexed=%s alpha=%s fourcc=%s>",
|
3273
|
+
rb_obj_classname(self),
|
3274
|
+
SDL_GetPixelFormatName(format),
|
3275
|
+
SDL_PIXELTYPE(format), SDL_PIXELORDER(format), SDL_PIXELLAYOUT(format),
|
3276
|
+
SDL_BITSPERPIXEL(format), SDL_BYTESPERPIXEL(format),
|
3277
|
+
INT2BOOLCSTR(SDL_ISPIXELFORMAT_INDEXED(format)),
|
3278
|
+
INT2BOOLCSTR(SDL_ISPIXELFORMAT_ALPHA(format)),
|
3279
|
+
INT2BOOLCSTR(SDL_ISPIXELFORMAT_FOURCC(format)));
|
3280
|
+
}
|
3281
|
+
|
3282
|
+
/*
|
3283
|
+
* Document-module: SDL2::ScreenSaver
|
3284
|
+
*
|
3285
|
+
* This module provides functions to disable and enable a screensaver.
|
3286
|
+
*/
|
3287
|
+
|
3288
|
+
/*
|
3289
|
+
* Enable screensaver.
|
3290
|
+
*
|
3291
|
+
* @return [nil]
|
3292
|
+
* @see .disable
|
3293
|
+
* @see .enabled?
|
3294
|
+
*/
|
3295
|
+
static VALUE ScreenSaver_enable(VALUE self)
|
3296
|
+
{
|
3297
|
+
SDL_EnableScreenSaver();
|
3298
|
+
return Qnil;
|
3299
|
+
}
|
3300
|
+
|
3301
|
+
/*
|
3302
|
+
* Disable screensaver.
|
3303
|
+
*
|
3304
|
+
* @return [nil]
|
3305
|
+
* @see .enable
|
3306
|
+
* @see .enabled?
|
3307
|
+
*/
|
3308
|
+
static VALUE ScreenSaver_disable(VALUE self)
|
3309
|
+
{
|
3310
|
+
SDL_DisableScreenSaver();
|
3311
|
+
return Qnil;
|
3312
|
+
}
|
3313
|
+
|
3314
|
+
/*
|
3315
|
+
* Return true if the screensaver is enabled.
|
3316
|
+
*
|
3317
|
+
* @see .enable
|
3318
|
+
* @see .disable
|
3319
|
+
*/
|
3320
|
+
static VALUE ScreenSaver_enabled_p(VALUE self)
|
3321
|
+
{
|
3322
|
+
return INT2BOOL(SDL_IsScreenSaverEnabled());
|
3323
|
+
}
|
3324
|
+
|
3325
|
+
/*
|
3326
|
+
define(`DEFINE_C_ACCESSOR',`rb_define_method($2, "$3", $1_$3, 0);
|
3327
|
+
rb_define_method($2, "$3=", $1_set_$3, 1)')
|
3328
|
+
*/
|
3329
|
+
|
3330
|
+
void rubysdl2_init_video(void)
|
3331
|
+
{
|
3332
|
+
rb_define_module_function(mSDL2, "video_drivers", SDL2_s_video_drivers, 0);
|
3333
|
+
rb_define_module_function(mSDL2, "current_video_driver", SDL2_s_current_video_driver, 0);
|
3334
|
+
rb_define_module_function(mSDL2, "video_init", SDL2_s_video_init, 1);
|
3335
|
+
|
3336
|
+
cWindow = rb_define_class_under(mSDL2, "Window", rb_cObject);
|
3337
|
+
|
3338
|
+
rb_undef_alloc_func(cWindow);
|
3339
|
+
rb_define_singleton_method(cWindow, "create", Window_s_create, 6);
|
3340
|
+
rb_define_singleton_method(cWindow, "all_windows", Window_s_all_windows, 0);
|
3341
|
+
rb_define_singleton_method(cWindow, "find_by_id", Window_s_find_by_id, 1);
|
3342
|
+
rb_define_method(cWindow, "destroy?", Window_destroy_p, 0);
|
3343
|
+
rb_define_method(cWindow, "destroy", Window_destroy, 0);
|
3344
|
+
rb_define_method(cWindow, "create_renderer", Window_create_renderer, 2);
|
3345
|
+
rb_define_method(cWindow, "renderer", Window_renderer, 0);
|
3346
|
+
rb_define_method(cWindow, "window_id", Window_window_id, 0);
|
3347
|
+
rb_define_method(cWindow, "inspect", Window_inspect, 0);
|
3348
|
+
rb_define_method(cWindow, "display_mode", Window_display_mode, 0);
|
3349
|
+
rb_define_method(cWindow, "display", Window_display, 0);
|
3350
|
+
rb_define_method(cWindow, "debug_info", Window_debug_info, 0);
|
3351
|
+
DEFINE_C_ACCESSOR(Window, cWindow, brightness);
|
3352
|
+
rb_define_method(cWindow, "flags", Window_flags, 0);
|
3353
|
+
rb_define_method(cWindow, "gamma_ramp", Window_gamma_ramp, 0);
|
3354
|
+
rb_define_method(cWindow, "input_is_grabbed?", Window_input_is_grabbed_p, 0);
|
3355
|
+
rb_define_method(cWindow, "input_is_grabbed=", Window_set_input_is_grabbed, 1);
|
3356
|
+
DEFINE_C_ACCESSOR(Window, cWindow, maximum_size);
|
3357
|
+
DEFINE_C_ACCESSOR(Window, cWindow, minimum_size);
|
3358
|
+
DEFINE_C_ACCESSOR(Window, cWindow, position);
|
3359
|
+
DEFINE_C_ACCESSOR(Window, cWindow, size);
|
3360
|
+
DEFINE_C_ACCESSOR(Window, cWindow, title);
|
3361
|
+
DEFINE_C_ACCESSOR(Window, cWindow, bordered);
|
3362
|
+
rb_define_method(cWindow, "icon=", Window_set_icon, 1);
|
3363
|
+
rb_define_method(cWindow, "show", Window_show, 0);
|
3364
|
+
rb_define_method(cWindow, "hide", Window_hide, 0);
|
3365
|
+
rb_define_method(cWindow, "maximize", Window_maximize, 0);
|
3366
|
+
rb_define_method(cWindow, "minimize", Window_minimize, 0);
|
3367
|
+
rb_define_method(cWindow, "raise", Window_raise, 0);
|
3368
|
+
rb_define_method(cWindow, "restore", Window_restore, 0);
|
3369
|
+
rb_define_method(cWindow, "fullscreen_mode", Window_fullscreen_mode, 0);
|
3370
|
+
rb_define_method(cWindow, "fullscreen_mode=", Window_set_fullscreen_mode, 1);
|
3371
|
+
#if SDL_VERSION_ATLEAST(2,0,1)
|
3372
|
+
rb_define_method(cWindow, "gl_drawable_size", Window_gl_drawable_size, 0);
|
3373
|
+
#endif
|
3374
|
+
rb_define_method(cWindow, "gl_swap", Window_gl_swap, 0);
|
3375
|
+
rb_define_method(cWindow, "surface", Window_surface, 0);
|
3376
|
+
rb_define_method(cWindow, "update", Window_update, 0);
|
3377
|
+
|
3378
|
+
/* Indicate that you don't care what the window position is */
|
3379
|
+
rb_define_const(cWindow, "POS_CENTERED", INT2NUM(SDL_WINDOWPOS_CENTERED));
|
3380
|
+
/* Indicate that the window position should be centered */
|
3381
|
+
rb_define_const(cWindow, "POS_UNDEFINED", INT2NUM(SDL_WINDOWPOS_UNDEFINED));
|
3382
|
+
|
3383
|
+
mWindowFlags = rb_define_module_under(cWindow, "Flags");
|
3384
|
+
/* define(`DEFINE_WINDOW_FLAGS_CONST',`rb_define_const(mWindowFlags, "$1", UINT2NUM(SDL_WINDOW_$1))') */
|
3385
|
+
/* fullscreen window */
|
3386
|
+
DEFINE_WINDOW_FLAGS_CONST(FULLSCREEN);
|
3387
|
+
/* fullscreen window at the current desktop resolution */
|
3388
|
+
DEFINE_WINDOW_FLAGS_CONST(FULLSCREEN_DESKTOP);
|
3389
|
+
/* window usable with OpenGL context */
|
3390
|
+
DEFINE_WINDOW_FLAGS_CONST(OPENGL);
|
3391
|
+
/* window is visible */
|
3392
|
+
DEFINE_WINDOW_FLAGS_CONST(SHOWN);
|
3393
|
+
/* window is not visible */
|
3394
|
+
DEFINE_WINDOW_FLAGS_CONST(HIDDEN);
|
3395
|
+
/* no window decoration */
|
3396
|
+
DEFINE_WINDOW_FLAGS_CONST(BORDERLESS);
|
3397
|
+
/* window is resizable */
|
3398
|
+
DEFINE_WINDOW_FLAGS_CONST(RESIZABLE);
|
3399
|
+
/* window is minimized */
|
3400
|
+
DEFINE_WINDOW_FLAGS_CONST(MINIMIZED);
|
3401
|
+
/* window is maximized */
|
3402
|
+
DEFINE_WINDOW_FLAGS_CONST(MAXIMIZED);
|
3403
|
+
/* window has grabbed input focus */
|
3404
|
+
DEFINE_WINDOW_FLAGS_CONST(INPUT_GRABBED);
|
3405
|
+
/* window has input focus */
|
3406
|
+
DEFINE_WINDOW_FLAGS_CONST(INPUT_FOCUS);
|
3407
|
+
/* window has mouse focus */
|
3408
|
+
DEFINE_WINDOW_FLAGS_CONST(MOUSE_FOCUS);
|
3409
|
+
/* window is not created by SDL */
|
3410
|
+
DEFINE_WINDOW_FLAGS_CONST(FOREIGN);
|
3411
|
+
#ifdef HAVE_CONST_SDL_WINDOW_ALLOW_HIGHDPI
|
3412
|
+
/* window should be created in high-DPI mode if supported (>= SDL 2.0.1)*/
|
3413
|
+
DEFINE_WINDOW_FLAGS_CONST(ALLOW_HIGHDPI);
|
3414
|
+
#endif
|
3415
|
+
#ifdef HAVE_CONST_SDL_WINDOW_MOSUE_CAPTURE
|
3416
|
+
/* window has mouse caputred (>= SDL 2.0.4) */
|
3417
|
+
DEFINE_WINDOW_FLAGS_CONST(MOUSE_CAPTURE);
|
3418
|
+
#endif
|
3419
|
+
|
3420
|
+
cDisplay = rb_define_class_under(mSDL2, "Display", rb_cObject);
|
3421
|
+
|
3422
|
+
rb_define_module_function(cDisplay, "displays", Display_s_displays, 0);
|
3423
|
+
rb_define_attr(cDisplay, "index", 1, 0);
|
3424
|
+
rb_define_attr(cDisplay, "name", 1, 0);
|
3425
|
+
rb_define_method(cDisplay, "modes", Display_modes, 0);
|
3426
|
+
rb_define_method(cDisplay, "current_mode", Display_current_mode, 0);
|
3427
|
+
rb_define_method(cDisplay, "desktop_mode", Display_desktop_mode, 0);
|
3428
|
+
rb_define_method(cDisplay, "closest_mode", Display_closest_mode, 1);
|
3429
|
+
rb_define_method(cDisplay, "bounds", Display_bounds, 0);
|
3430
|
+
|
3431
|
+
|
3432
|
+
cDisplayMode = rb_define_class_under(cDisplay, "Mode", rb_cObject);
|
3433
|
+
|
3434
|
+
rb_define_alloc_func(cDisplayMode, DisplayMode_s_allocate);
|
3435
|
+
rb_define_method(cDisplayMode, "initialize", DisplayMode_initialize, 4);
|
3436
|
+
rb_define_method(cDisplayMode, "inspect", DisplayMode_inspect, 0);
|
3437
|
+
rb_define_method(cDisplayMode, "format", DisplayMode_format, 0);
|
3438
|
+
rb_define_method(cDisplayMode, "w", DisplayMode_w, 0);
|
3439
|
+
rb_define_method(cDisplayMode, "h", DisplayMode_h, 0);
|
3440
|
+
rb_define_method(cDisplayMode, "refresh_rate", DisplayMode_refresh_rate, 0);
|
3441
|
+
|
3442
|
+
|
3443
|
+
cRenderer = rb_define_class_under(mSDL2, "Renderer", rb_cObject);
|
3444
|
+
|
3445
|
+
rb_undef_alloc_func(cRenderer);
|
3446
|
+
rb_define_singleton_method(cRenderer, "drivers_info", Renderer_s_drivers_info, 0);
|
3447
|
+
rb_define_method(cRenderer, "destroy?", Renderer_destroy_p, 0);
|
3448
|
+
rb_define_method(cRenderer, "destroy", Renderer_destroy, 0);
|
3449
|
+
rb_define_method(cRenderer, "debug_info", Renderer_debug_info, 0);
|
3450
|
+
rb_define_method(cRenderer, "create_texture", Renderer_create_texture, 4);
|
3451
|
+
rb_define_method(cRenderer, "create_texture_from", Renderer_create_texture_from, 1);
|
3452
|
+
rb_define_method(cRenderer, "copy", Renderer_copy, 3);
|
3453
|
+
rb_define_method(cRenderer, "copy_ex", Renderer_copy_ex, 6);
|
3454
|
+
rb_define_method(cRenderer, "present", Renderer_present, 0);
|
3455
|
+
rb_define_method(cRenderer, "draw_color",Renderer_draw_color, 0);
|
3456
|
+
rb_define_method(cRenderer, "draw_color=",Renderer_set_draw_color, 1);
|
3457
|
+
rb_define_method(cRenderer, "clear", Renderer_clear, 0);
|
3458
|
+
rb_define_method(cRenderer, "draw_line",Renderer_draw_line, 4);
|
3459
|
+
rb_define_method(cRenderer, "draw_point",Renderer_draw_point, 2);
|
3460
|
+
rb_define_method(cRenderer, "draw_rect", Renderer_draw_rect, 1);
|
3461
|
+
rb_define_method(cRenderer, "fill_rect", Renderer_fill_rect, 1);
|
3462
|
+
rb_define_method(cRenderer, "draw_blend_mode", Renderer_draw_blend_mode, 0);
|
3463
|
+
rb_define_method(cRenderer, "draw_blend_mode=", Renderer_set_draw_blend_mode, 1);
|
3464
|
+
rb_define_method(cRenderer, "clip_rect", Renderer_clip_rect, 0);
|
3465
|
+
rb_define_method(cRenderer, "clip_rect=", Renderer_set_clip_rect, 1);
|
3466
|
+
#if SDL_VERSION_ATLEAST(2,0,4)
|
3467
|
+
rb_define_method(cRenderer, "clip_enabled?", Render_clip_enabled_p, 0);
|
3468
|
+
#endif
|
3469
|
+
rb_define_method(cRenderer, "logical_size", Renderer_logical_size, 0);
|
3470
|
+
rb_define_method(cRenderer, "logical_size=", Renderer_set_logical_size, 1);
|
3471
|
+
rb_define_method(cRenderer, "scale", Renderer_scale, 0);
|
3472
|
+
rb_define_method(cRenderer, "scale=", Renderer_set_scale, 1);
|
3473
|
+
rb_define_method(cRenderer, "viewport", Renderer_viewport, 0);
|
3474
|
+
rb_define_method(cRenderer, "viewport=", Renderer_set_viewport, 1);
|
3475
|
+
rb_define_method(cRenderer, "support_render_target?", Renderer_support_render_target_p, 0);
|
3476
|
+
rb_define_method(cRenderer, "output_size", Renderer_output_size, 0);
|
3477
|
+
rb_define_method(cRenderer, "render_target", Renderer_render_target, 0);
|
3478
|
+
rb_define_method(cRenderer, "render_target=", Renderer_set_render_target, 1);
|
3479
|
+
rb_define_method(cRenderer, "reset_render_target", Renderer_reset_render_target, 0);
|
3480
|
+
|
3481
|
+
rb_define_method(cRenderer, "info", Renderer_info, 0);
|
3482
|
+
|
3483
|
+
#ifdef HAVE_SDL2_GFXPRIMITIVES_H
|
3484
|
+
rb_define_method(cRenderer, "draw_line_aa", Renderer_draw_line_aa, 4);
|
3485
|
+
rb_define_method(cRenderer, "draw_line_thick", Renderer_draw_line_thick, 5);
|
3486
|
+
rb_define_method(cRenderer, "draw_triangle", Renderer_draw_triangle, 6);
|
3487
|
+
rb_define_method(cRenderer, "draw_triangle_aa", Renderer_draw_triangle_aa, 6);
|
3488
|
+
rb_define_method(cRenderer, "fill_triangle", Renderer_fill_triangle, 6);
|
3489
|
+
rb_define_method(cRenderer, "draw_polygon", Renderer_draw_polygon, 2);
|
3490
|
+
rb_define_method(cRenderer, "draw_polygon_aa", Renderer_draw_polygon_aa, 2);
|
3491
|
+
rb_define_method(cRenderer, "fill_polygon", Renderer_fill_polygon, 2);
|
3492
|
+
rb_define_method(cRenderer, "fill_polygon_textured", Renderer_fill_polygon_textured, 5);
|
3493
|
+
rb_define_method(cRenderer, "draw_arc", Renderer_draw_arc, 5);
|
3494
|
+
rb_define_method(cRenderer, "draw_ellipse", Renderer_draw_ellipse, 4);
|
3495
|
+
rb_define_method(cRenderer, "draw_ellipse_aa", Renderer_draw_ellipse_aa, 4);
|
3496
|
+
rb_define_method(cRenderer, "fill_ellipse", Renderer_fill_ellipse, 4);
|
3497
|
+
rb_define_method(cRenderer, "draw_pie", Renderer_draw_pie, 5);
|
3498
|
+
rb_define_method(cRenderer, "fill_pie", Renderer_fill_pie, 5);
|
3499
|
+
rb_define_method(cRenderer, "draw_rounded_rect", Renderer_draw_rounded_rect, 5);
|
3500
|
+
rb_define_method(cRenderer, "fill_rounded_rect", Renderer_fill_rounded_rect, 5);
|
3501
|
+
rb_define_method(cRenderer, "draw_quad_bezier", Renderer_draw_quad_bezier, 9);
|
3502
|
+
#endif
|
3503
|
+
|
3504
|
+
mRendererFlags = rb_define_module_under(cRenderer, "Flags");
|
3505
|
+
|
3506
|
+
/* define(`DEFINE_RENDERER_FLAGS_CONST',`rb_define_const(mRendererFlags, "$1", UINT2NUM(SDL_RENDERER_$1))') */
|
3507
|
+
/* the renderer is a software fallback */
|
3508
|
+
DEFINE_RENDERER_FLAGS_CONST(SOFTWARE);
|
3509
|
+
/* the renderer uses hardware acceleration */
|
3510
|
+
DEFINE_RENDERER_FLAGS_CONST(ACCELERATED);
|
3511
|
+
#ifdef HAVE_CONST_SDL_RENDERER_PRESENTVSYNC
|
3512
|
+
/* present is synchronized with the refresh rate */
|
3513
|
+
DEFINE_RENDERER_FLAGS_CONST(PRESENTVSYNC);
|
3514
|
+
#endif
|
3515
|
+
/* the renderer supports rendering to texture */
|
3516
|
+
DEFINE_RENDERER_FLAGS_CONST(TARGETTEXTURE);
|
3517
|
+
/* define(`DEFINE_SDL_FLIP_CONST',`rb_define_const(cRenderer, "FLIP_$1", INT2FIX(SDL_FLIP_$1))') */
|
3518
|
+
/* Do not flip, used in {Renderer#copy_ex} */
|
3519
|
+
DEFINE_SDL_FLIP_CONST(NONE);
|
3520
|
+
/* Flip horizontally, used in {Renderer#copy_ex} */
|
3521
|
+
DEFINE_SDL_FLIP_CONST(HORIZONTAL);
|
3522
|
+
/* Flip vertically, used in {Renderer#copy_ex} */
|
3523
|
+
DEFINE_SDL_FLIP_CONST(VERTICAL);
|
3524
|
+
|
3525
|
+
mBlendMode = rb_define_module_under(mSDL2, "BlendMode");
|
3526
|
+
/* define(`DEFINE_BLENDMODE_CONST',`rb_define_const(mBlendMode, "$1", INT2FIX(SDL_BLENDMODE_$1))') */
|
3527
|
+
/* no blending (dstRGBA = srcRGBA) */
|
3528
|
+
DEFINE_BLENDMODE_CONST(NONE);
|
3529
|
+
/* alpha blending (dstRGB = (srcRGB * srcA) + (dstRGB * (1-srcA), dstA = srcA + (dstA * (1-srcA)))*/
|
3530
|
+
DEFINE_BLENDMODE_CONST(BLEND);
|
3531
|
+
/* additive blending (dstRGB = (srcRGB * srcA) + dstRGB, dstA = dstA) */
|
3532
|
+
DEFINE_BLENDMODE_CONST(ADD);
|
3533
|
+
/* color modulate (multiplicative) (dstRGB = srcRGB * dstRGB, dstA = dstA) */
|
3534
|
+
DEFINE_BLENDMODE_CONST(MOD);
|
3535
|
+
|
3536
|
+
cTexture = rb_define_class_under(mSDL2, "Texture", rb_cObject);
|
3537
|
+
|
3538
|
+
rb_undef_alloc_func(cTexture);
|
3539
|
+
rb_define_method(cTexture, "destroy?", Texture_destroy_p, 0);
|
3540
|
+
rb_define_method(cTexture, "destroy", Texture_destroy, 0);
|
3541
|
+
DEFINE_C_ACCESSOR(Texture, cTexture, blend_mode);
|
3542
|
+
DEFINE_C_ACCESSOR(Texture, cTexture, color_mod);
|
3543
|
+
DEFINE_C_ACCESSOR(Texture, cTexture, alpha_mod);
|
3544
|
+
rb_define_method(cTexture, "format", Texture_format, 0);
|
3545
|
+
rb_define_method(cTexture, "access_pattern", Texture_access_pattern, 0);
|
3546
|
+
rb_define_method(cTexture, "w", Texture_w, 0);
|
3547
|
+
rb_define_method(cTexture, "h", Texture_h, 0);
|
3548
|
+
rb_define_method(cTexture, "inspect", Texture_inspect, 0);
|
3549
|
+
rb_define_method(cTexture, "debug_info", Texture_debug_info, 0);
|
3550
|
+
/* define(`DEFINE_TEXTUREAH_ACCESS_CONST', `rb_define_const(cTexture, "ACCESS_$1", INT2NUM(SDL_TEXTUREACCESS_$1))') */
|
3551
|
+
/* texture access pattern - changes rarely, not lockable */
|
3552
|
+
DEFINE_TEXTUREAH_ACCESS_CONST(STATIC);
|
3553
|
+
/* texture access pattern - changes frequently, lockable */
|
3554
|
+
DEFINE_TEXTUREAH_ACCESS_CONST(STREAMING);
|
3555
|
+
/* texture access pattern - can be used as a render target */
|
3556
|
+
DEFINE_TEXTUREAH_ACCESS_CONST(TARGET);
|
3557
|
+
|
3558
|
+
|
3559
|
+
cSurface = rb_define_class_under(mSDL2, "Surface", rb_cObject);
|
3560
|
+
|
3561
|
+
rb_undef_alloc_func(cSurface);
|
3562
|
+
rb_define_singleton_method(cSurface, "load_bmp", Surface_s_load_bmp, 1);
|
3563
|
+
rb_define_singleton_method(cSurface, "blit", Surface_s_blit, 4);
|
3564
|
+
rb_define_singleton_method(cSurface, "blit_scaled", Surface_s_blit_scaled, 4);
|
3565
|
+
rb_define_singleton_method(cSurface, "new", Surface_s_new, -1);
|
3566
|
+
rb_define_singleton_method(cSurface, "from_string", Surface_s_from_string, -1);
|
3567
|
+
rb_define_method(cSurface, "destroy?", Surface_destroy_p, 0);
|
3568
|
+
rb_define_method(cSurface, "destroy", Surface_destroy, 0);
|
3569
|
+
DEFINE_C_ACCESSOR(Surface, cSurface, blend_mode);
|
3570
|
+
rb_define_method(cSurface, "must_lock?", Surface_must_lock_p, 0);
|
3571
|
+
rb_define_method(cSurface, "lock", Surface_lock, 0);
|
3572
|
+
rb_define_method(cSurface, "unlock", Surface_unlock, 0);
|
3573
|
+
rb_define_method(cSurface, "w", Surface_w, 0);
|
3574
|
+
rb_define_method(cSurface, "h", Surface_h, 0);
|
3575
|
+
rb_define_method(cSurface, "pixel", Surface_pixel, 2);
|
3576
|
+
rb_define_method(cSurface, "pixel_color", Surface_pixel_color, 2);
|
3577
|
+
rb_define_method(cSurface, "color_key", Surface_color_key, 0);
|
3578
|
+
rb_define_method(cSurface, "color_key=", Surface_set_color_key, 1);
|
3579
|
+
rb_define_method(cSurface, "unset_color_key", Surface_unset_color_key, 0);
|
3580
|
+
rb_define_method(cSurface, "pixels", Surface_pixels, 0);
|
3581
|
+
rb_define_method(cSurface, "pitch", Surface_pitch, 0);
|
3582
|
+
rb_define_method(cSurface, "bits_per_pixel", Surface_bits_per_pixel, 0);
|
3583
|
+
rb_define_method(cSurface, "bytes_per_pixel", Surface_bytes_per_pixel, 0);
|
3584
|
+
rb_define_method(cSurface, "blit_to", Surface_blit_to, 3);
|
3585
|
+
rb_define_method(cSurface, "fill_rect", Surface_fill_rect, 2);
|
3586
|
+
|
3587
|
+
cRect = rb_define_class_under(mSDL2, "Rect", rb_cObject);
|
3588
|
+
|
3589
|
+
rb_define_alloc_func(cRect, Rect_s_allocate);
|
3590
|
+
rb_define_method(cRect, "initialize", Rect_initialize, -1);
|
3591
|
+
rb_define_alias(rb_singleton_class(cRect), "[]", "new");
|
3592
|
+
rb_define_method(cRect, "inspect", Rect_inspect, 0);
|
3593
|
+
DEFINE_C_ACCESSOR(Rect, cRect, x);
|
3594
|
+
DEFINE_C_ACCESSOR(Rect, cRect, y);
|
3595
|
+
DEFINE_C_ACCESSOR(Rect, cRect, w);
|
3596
|
+
DEFINE_C_ACCESSOR(Rect, cRect, h);
|
3597
|
+
rb_define_method(cRect, "union", Rect_union, 1);
|
3598
|
+
rb_define_method(cRect, "intersection", Rect_intersection, 1);
|
3599
|
+
|
3600
|
+
cPoint = rb_define_class_under(mSDL2, "Point", rb_cObject);
|
3601
|
+
|
3602
|
+
rb_define_alloc_func(cPoint, Point_s_allocate);
|
3603
|
+
rb_define_method(cPoint, "initialize", Point_initialize, -1);
|
3604
|
+
rb_define_alias(rb_singleton_class(cPoint), "[]", "new");
|
3605
|
+
rb_define_method(cPoint, "inspect", Point_inspect, 0);
|
3606
|
+
DEFINE_C_ACCESSOR(Point, cPoint, x);
|
3607
|
+
DEFINE_C_ACCESSOR(Point, cPoint, y);
|
3608
|
+
|
3609
|
+
|
3610
|
+
cRendererInfo = rb_define_class_under(cRenderer, "Info", rb_cObject);
|
3611
|
+
define_attr_readers(cRendererInfo, "name", "flags", "texture_formats",
|
3612
|
+
"max_texture_width", "max_texture_height", NULL);
|
3613
|
+
|
3614
|
+
|
3615
|
+
cPixelFormat = rb_define_class_under(mSDL2, "PixelFormat", rb_cObject);
|
3616
|
+
|
3617
|
+
rb_define_method(cPixelFormat, "initialize", PixelForamt_initialize, 1);
|
3618
|
+
rb_define_attr(cPixelFormat, "format", 1, 0);
|
3619
|
+
rb_define_method(cPixelFormat, "name", PixelFormat_name, 0);
|
3620
|
+
rb_define_method(cPixelFormat, "inspect", PixelFormat_inspect, 0);
|
3621
|
+
rb_define_method(cPixelFormat, "type", PixelFormat_type, 0);
|
3622
|
+
rb_define_method(cPixelFormat, "order", PixelFormat_order, 0);
|
3623
|
+
rb_define_method(cPixelFormat, "layout", PixelFormat_layout, 0);
|
3624
|
+
rb_define_method(cPixelFormat, "bits_per_pixel", PixelFormat_bits_per_pixel, 0);
|
3625
|
+
rb_define_alias(cPixelFormat, "bpp", "bits_per_pixel");
|
3626
|
+
rb_define_method(cPixelFormat, "bytes_per_pixel", PixelFormat_bytes_per_pixel, 0);
|
3627
|
+
rb_define_method(cPixelFormat, "indexed?", PixelFormat_indexed_p, 0);
|
3628
|
+
rb_define_method(cPixelFormat, "alpha?", PixelFormat_alpha_p, 0);
|
3629
|
+
rb_define_method(cPixelFormat, "fourcc?", PixelFormat_fourcc_p, 0);
|
3630
|
+
rb_define_method(cPixelFormat, "==", PixelFormat_eq, 1);
|
3631
|
+
|
3632
|
+
mPixelType = rb_define_module_under(cPixelFormat, "Type");
|
3633
|
+
/* define(`DEFINE_PIXELTYPE_CONST',`rb_define_const(mPixelType, "$1", UINT2NUM(SDL_PIXELTYPE_$1))') */
|
3634
|
+
DEFINE_PIXELTYPE_CONST(UNKNOWN);
|
3635
|
+
DEFINE_PIXELTYPE_CONST(INDEX1);
|
3636
|
+
DEFINE_PIXELTYPE_CONST(INDEX4);
|
3637
|
+
DEFINE_PIXELTYPE_CONST(INDEX8);
|
3638
|
+
DEFINE_PIXELTYPE_CONST(PACKED8);
|
3639
|
+
DEFINE_PIXELTYPE_CONST(PACKED16);
|
3640
|
+
DEFINE_PIXELTYPE_CONST(PACKED32);
|
3641
|
+
DEFINE_PIXELTYPE_CONST(ARRAYU8);
|
3642
|
+
DEFINE_PIXELTYPE_CONST(ARRAYU16);
|
3643
|
+
DEFINE_PIXELTYPE_CONST(ARRAYU32);
|
3644
|
+
DEFINE_PIXELTYPE_CONST(ARRAYF16);
|
3645
|
+
DEFINE_PIXELTYPE_CONST(ARRAYF32);
|
3646
|
+
|
3647
|
+
mBitmapOrder = rb_define_module_under(cPixelFormat, "BitmapOrder");
|
3648
|
+
rb_define_const(mBitmapOrder, "NONE", UINT2NUM(SDL_BITMAPORDER_NONE));
|
3649
|
+
rb_define_const(mBitmapOrder, "O_1234", UINT2NUM(SDL_BITMAPORDER_1234));
|
3650
|
+
rb_define_const(mBitmapOrder, "O_4321", UINT2NUM(SDL_BITMAPORDER_4321));
|
3651
|
+
|
3652
|
+
mPackedOrder = rb_define_module_under(cPixelFormat, "PackedOrder");
|
3653
|
+
/* define(`DEFINE_PACKEDORDER_CONST',`rb_define_const(mPackedOrder, "$1", UINT2NUM(SDL_PACKEDORDER_$1))') */
|
3654
|
+
DEFINE_PACKEDORDER_CONST(NONE);
|
3655
|
+
DEFINE_PACKEDORDER_CONST(XRGB);
|
3656
|
+
DEFINE_PACKEDORDER_CONST(RGBX);
|
3657
|
+
DEFINE_PACKEDORDER_CONST(ARGB);
|
3658
|
+
DEFINE_PACKEDORDER_CONST(RGBA);
|
3659
|
+
DEFINE_PACKEDORDER_CONST(XBGR);
|
3660
|
+
DEFINE_PACKEDORDER_CONST(BGRX);
|
3661
|
+
DEFINE_PACKEDORDER_CONST(ABGR);
|
3662
|
+
DEFINE_PACKEDORDER_CONST(BGRA);
|
3663
|
+
|
3664
|
+
mArrayOrder = rb_define_module_under(cPixelFormat, "ArrayOrder");
|
3665
|
+
/* define(`DEFINE_ARRAYORDER_CONST',`rb_define_const(mArrayOrder, "$1", UINT2NUM(SDL_ARRAYORDER_$1))') */
|
3666
|
+
DEFINE_ARRAYORDER_CONST(NONE);
|
3667
|
+
DEFINE_ARRAYORDER_CONST(RGB);
|
3668
|
+
DEFINE_ARRAYORDER_CONST(RGBA);
|
3669
|
+
DEFINE_ARRAYORDER_CONST(ARGB);
|
3670
|
+
DEFINE_ARRAYORDER_CONST(BGR);
|
3671
|
+
DEFINE_ARRAYORDER_CONST(BGRA);
|
3672
|
+
DEFINE_ARRAYORDER_CONST(ABGR);
|
3673
|
+
|
3674
|
+
mPackedLayout = rb_define_module_under(cPixelFormat, "PackedLayout");
|
3675
|
+
/* define(`DEFINE_PACKEDLAYOUT_CONST',`rb_define_const(mPackedLayout, "L_$1", UINT2NUM(SDL_PACKEDLAYOUT_$1))') */
|
3676
|
+
rb_define_const(mPackedLayout, "NONE", UINT2NUM(SDL_PACKEDLAYOUT_NONE));
|
3677
|
+
DEFINE_PACKEDLAYOUT_CONST(332);
|
3678
|
+
DEFINE_PACKEDLAYOUT_CONST(4444);
|
3679
|
+
DEFINE_PACKEDLAYOUT_CONST(1555);
|
3680
|
+
DEFINE_PACKEDLAYOUT_CONST(5551);
|
3681
|
+
DEFINE_PACKEDLAYOUT_CONST(565);
|
3682
|
+
DEFINE_PACKEDLAYOUT_CONST(8888);
|
3683
|
+
DEFINE_PACKEDLAYOUT_CONST(2101010);
|
3684
|
+
DEFINE_PACKEDLAYOUT_CONST(1010102);
|
3685
|
+
|
3686
|
+
{
|
3687
|
+
VALUE formats = rb_ary_new();
|
3688
|
+
/* -: Array of all available formats */
|
3689
|
+
rb_define_const(cPixelFormat, "FORMATS", formats);
|
3690
|
+
/* define(`DEFINE_PIXELFORMAT_CONST',`do {
|
3691
|
+
VALUE format = PixelFormat_new(SDL_PIXELFORMAT_$1);
|
3692
|
+
$2
|
3693
|
+
rb_define_const(cPixelFormat, "$1", format);
|
3694
|
+
rb_ary_push(formats, format);
|
3695
|
+
} while (0)')
|
3696
|
+
*/
|
3697
|
+
|
3698
|
+
DEFINE_PIXELFORMAT_CONST(UNKNOWN, /* -: PixelFormat: Unused - reserved by SDL */);
|
3699
|
+
DEFINE_PIXELFORMAT_CONST(INDEX1LSB);
|
3700
|
+
DEFINE_PIXELFORMAT_CONST(INDEX1MSB);
|
3701
|
+
DEFINE_PIXELFORMAT_CONST(INDEX4LSB);
|
3702
|
+
DEFINE_PIXELFORMAT_CONST(INDEX4MSB);
|
3703
|
+
DEFINE_PIXELFORMAT_CONST(INDEX8);
|
3704
|
+
DEFINE_PIXELFORMAT_CONST(RGB332);
|
3705
|
+
DEFINE_PIXELFORMAT_CONST(RGB444);
|
3706
|
+
DEFINE_PIXELFORMAT_CONST(RGB555);
|
3707
|
+
DEFINE_PIXELFORMAT_CONST(BGR555);
|
3708
|
+
DEFINE_PIXELFORMAT_CONST(ARGB4444);
|
3709
|
+
DEFINE_PIXELFORMAT_CONST(RGBA4444);
|
3710
|
+
DEFINE_PIXELFORMAT_CONST(ABGR4444);
|
3711
|
+
DEFINE_PIXELFORMAT_CONST(BGRA4444);
|
3712
|
+
DEFINE_PIXELFORMAT_CONST(ARGB1555);
|
3713
|
+
DEFINE_PIXELFORMAT_CONST(RGBA5551);
|
3714
|
+
DEFINE_PIXELFORMAT_CONST(ABGR1555);
|
3715
|
+
DEFINE_PIXELFORMAT_CONST(BGRA5551);
|
3716
|
+
DEFINE_PIXELFORMAT_CONST(RGB565);
|
3717
|
+
DEFINE_PIXELFORMAT_CONST(BGR565);
|
3718
|
+
DEFINE_PIXELFORMAT_CONST(RGB24);
|
3719
|
+
DEFINE_PIXELFORMAT_CONST(BGR24);
|
3720
|
+
DEFINE_PIXELFORMAT_CONST(RGB888);
|
3721
|
+
DEFINE_PIXELFORMAT_CONST(RGBX8888);
|
3722
|
+
DEFINE_PIXELFORMAT_CONST(BGR888);
|
3723
|
+
DEFINE_PIXELFORMAT_CONST(BGRX8888);
|
3724
|
+
DEFINE_PIXELFORMAT_CONST(ARGB8888);
|
3725
|
+
DEFINE_PIXELFORMAT_CONST(RGBA8888);
|
3726
|
+
DEFINE_PIXELFORMAT_CONST(ABGR8888);
|
3727
|
+
DEFINE_PIXELFORMAT_CONST(BGRA8888);
|
3728
|
+
DEFINE_PIXELFORMAT_CONST(ARGB2101010);
|
3729
|
+
DEFINE_PIXELFORMAT_CONST(YV12);
|
3730
|
+
DEFINE_PIXELFORMAT_CONST(IYUV);
|
3731
|
+
DEFINE_PIXELFORMAT_CONST(YUY2);
|
3732
|
+
DEFINE_PIXELFORMAT_CONST(UYVY);
|
3733
|
+
DEFINE_PIXELFORMAT_CONST(YVYU);
|
3734
|
+
rb_obj_freeze(formats);
|
3735
|
+
}
|
3736
|
+
|
3737
|
+
mScreenSaver = rb_define_module_under(mSDL2, "ScreenSaver");
|
3738
|
+
rb_define_module_function(mScreenSaver, "enable", ScreenSaver_enable, 0);
|
3739
|
+
rb_define_module_function(mScreenSaver, "disable", ScreenSaver_disable, 0);
|
3740
|
+
rb_define_module_function(mScreenSaver, "enabled?", ScreenSaver_enabled_p, 0);
|
3741
|
+
|
3742
|
+
|
3743
|
+
rb_gc_register_address(&hash_windowid_to_window);
|
3744
|
+
hash_windowid_to_window = rb_hash_new();
|
3745
|
+
}
|
3746
|
+
|
3747
|
+
#ifdef HAVE_SDL_IMAGE_H
|
3748
|
+
#include <SDL_image.h>
|
3749
|
+
|
3750
|
+
static VALUE mIMG;
|
3751
|
+
|
3752
|
+
/*
|
3753
|
+
* Document-module: SDL2::IMG
|
3754
|
+
*
|
3755
|
+
* This module provides the interface to SDL_image. You can load
|
3756
|
+
* many kinds of image files using this modules.
|
3757
|
+
*
|
3758
|
+
* This module provides only initialization interface {SDL2::IMG.init}.
|
3759
|
+
* After calling init, you can load image files using {SDL2::Surface.load}.
|
3760
|
+
*/
|
3761
|
+
|
3762
|
+
/*
|
3763
|
+
* @overload init(flags)
|
3764
|
+
* Initialize SDL_image.
|
3765
|
+
*
|
3766
|
+
* You can specify the supporting image formats by bitwise OR'd of the
|
3767
|
+
* following constants.
|
3768
|
+
*
|
3769
|
+
* * {SDL2::IMG::INIT_JPG}
|
3770
|
+
* * {SDL2::IMG::INIT_PNG}
|
3771
|
+
* * {SDL2::IMG::INIT_TIF}
|
3772
|
+
* * {SDL2::IMG::INIT_WEBP}
|
3773
|
+
*
|
3774
|
+
* You need to initialize SDL_image to check whether specified format
|
3775
|
+
* is supported by your environment. If your environment does not
|
3776
|
+
* support required support format, you have a {SDL2::Error} exception.
|
3777
|
+
*
|
3778
|
+
* @param [Integer] flags submodule bits
|
3779
|
+
* @return [nil]
|
3780
|
+
*
|
3781
|
+
* @raise [SDL2::Error] raised when initializing is failed.
|
3782
|
+
*/
|
3783
|
+
static VALUE IMG_s_init(VALUE self, VALUE f)
|
3784
|
+
{
|
3785
|
+
int flags = NUM2INT(f);
|
3786
|
+
if ((IMG_Init(flags) & flags) != flags)
|
3787
|
+
rb_raise(eSDL2Error, "Couldn't initialize SDL_image");
|
3788
|
+
return Qnil;
|
3789
|
+
}
|
3790
|
+
|
3791
|
+
/*
|
3792
|
+
* @overload load(file)
|
3793
|
+
* Load file and create a new {SDL2::Surface}.
|
3794
|
+
*
|
3795
|
+
* This method uses SDL_image. SDL_image supports following formats:
|
3796
|
+
* BMP, CUR, GIF, ICO, JPG, LBP, PCX, PNG, PNM, TGA, TIF, XCF, XPM, and XV.
|
3797
|
+
*
|
3798
|
+
* @param [String] file the image file name to load a surface from
|
3799
|
+
* @return [SDL2::Surface] Created surface
|
3800
|
+
*
|
3801
|
+
* @raise [SDL2::Error] raised when you fail to load (for example,
|
3802
|
+
* you have a wrong file name, or the file is broken)
|
3803
|
+
*
|
3804
|
+
* @see SDL2::IMG.init
|
3805
|
+
* @see SDL2::Renderer#load_texture
|
3806
|
+
*/
|
3807
|
+
static VALUE Surface_s_load(VALUE self, VALUE fname)
|
3808
|
+
{
|
3809
|
+
SDL_Surface* surface = IMG_Load(StringValueCStr(fname));
|
3810
|
+
if (!surface) {
|
3811
|
+
SDL_SetError("%s", IMG_GetError());
|
3812
|
+
SDL_ERROR();
|
3813
|
+
}
|
3814
|
+
return Surface_new(surface);
|
3815
|
+
}
|
3816
|
+
|
3817
|
+
/*
|
3818
|
+
* @overload load_texture(file)
|
3819
|
+
*
|
3820
|
+
* Load file and create a new {SDL2::Texture}.
|
3821
|
+
*
|
3822
|
+
* This method uses SDL_image. SDL_image supports following formats:
|
3823
|
+
* BMP, CUR, GIF, ICO, JPG, LBP, PCX, PNG, PNM, TGA, TIF, XCF, XPM, and XV.
|
3824
|
+
*
|
3825
|
+
* @param [String] file the image file name to load a texture from
|
3826
|
+
* @return [SDL2::Texture] Created texture
|
3827
|
+
*
|
3828
|
+
* @raise [SDL2::Error] raised when you fail to load (for example,
|
3829
|
+
* you have a wrong file name, or the file is broken)
|
3830
|
+
*
|
3831
|
+
* @see SDL2::IMG.init
|
3832
|
+
* @see SDL2::Surface.load
|
3833
|
+
*/
|
3834
|
+
static VALUE Renderer_load_texture(VALUE self, VALUE fname)
|
3835
|
+
{
|
3836
|
+
SDL_Texture* texture = IMG_LoadTexture(Get_SDL_Renderer(self), StringValueCStr(fname));
|
3837
|
+
if (!texture) {
|
3838
|
+
SDL_SetError("%s", IMG_GetError());
|
3839
|
+
SDL_ERROR();
|
3840
|
+
}
|
3841
|
+
return Texture_new(texture, Get_Renderer(self));
|
3842
|
+
}
|
3843
|
+
|
3844
|
+
void rubysdl2_init_image(void)
|
3845
|
+
{
|
3846
|
+
mIMG = rb_define_module_under(mSDL2, "IMG");
|
3847
|
+
rb_define_module_function(mIMG, "init", IMG_s_init, 1);
|
3848
|
+
|
3849
|
+
rb_define_singleton_method(cSurface, "load", Surface_s_load, 1);
|
3850
|
+
rb_define_method(cRenderer, "load_texture", Renderer_load_texture, 1);
|
3851
|
+
|
3852
|
+
|
3853
|
+
/* Initialize the JPEG loader */
|
3854
|
+
rb_define_const(mIMG, "INIT_JPG", INT2NUM(IMG_INIT_JPG));
|
3855
|
+
/* Initialize the PNG loader */
|
3856
|
+
rb_define_const(mIMG, "INIT_PNG", INT2NUM(IMG_INIT_PNG));
|
3857
|
+
/* Initialize the TIF loader */
|
3858
|
+
rb_define_const(mIMG, "INIT_TIF", INT2NUM(IMG_INIT_TIF));
|
3859
|
+
/* Initialize the WEBP loader */
|
3860
|
+
rb_define_const(mIMG, "INIT_WEBP", INT2NUM(IMG_INIT_WEBP));
|
3861
|
+
}
|
3862
|
+
|
3863
|
+
#else /* HAVE_SDL_IMAGE_H */
|
3864
|
+
void rubysdl2_init_image(void)
|
3865
|
+
{
|
3866
|
+
}
|
3867
|
+
#endif
|