sdl2-win93 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +7 -0
  2. data/.dir-locals.el +2 -0
  3. data/.github/workflows/gempush.yml +29 -0
  4. data/.gitignore +14 -0
  5. data/COPYING.txt +165 -0
  6. data/Gemfile +4 -0
  7. data/Gemfile.lock +24 -0
  8. data/Makefile +4 -0
  9. data/README.md +36 -0
  10. data/Rakefile +51 -0
  11. data/doc/po/ja.po +10357 -0
  12. data/ext/sdl2_ext/clipboard.c +61 -0
  13. data/ext/sdl2_ext/color.c +103 -0
  14. data/ext/sdl2_ext/color.h +4 -0
  15. data/ext/sdl2_ext/event.c +1298 -0
  16. data/ext/sdl2_ext/extconf.rb +22 -0
  17. data/ext/sdl2_ext/filesystem.c +63 -0
  18. data/ext/sdl2_ext/gamecontroller.c +408 -0
  19. data/ext/sdl2_ext/gamecontroller.c.m4 +408 -0
  20. data/ext/sdl2_ext/gl.c +351 -0
  21. data/ext/sdl2_ext/gl.c.m4 +351 -0
  22. data/ext/sdl2_ext/hint.c +99 -0
  23. data/ext/sdl2_ext/joystick.c +339 -0
  24. data/ext/sdl2_ext/joystick.c.m4 +339 -0
  25. data/ext/sdl2_ext/key.c +1302 -0
  26. data/ext/sdl2_ext/key.c.m4 +833 -0
  27. data/ext/sdl2_ext/main.c +258 -0
  28. data/ext/sdl2_ext/messagebox.c +233 -0
  29. data/ext/sdl2_ext/mixer.c +1205 -0
  30. data/ext/sdl2_ext/mixer.c.m4 +1205 -0
  31. data/ext/sdl2_ext/mouse.c +286 -0
  32. data/ext/sdl2_ext/rubysdl2_internal.h +127 -0
  33. data/ext/sdl2_ext/timer.c +63 -0
  34. data/ext/sdl2_ext/ttf.c +376 -0
  35. data/ext/sdl2_ext/ttf.c.m4 +376 -0
  36. data/ext/sdl2_ext/video.c +4093 -0
  37. data/ext/sdl2_ext/video.c.m4 +3867 -0
  38. data/lib/sdl2.rb +3 -0
  39. data/lib/sdl2/event.rb +55 -0
  40. data/lib/sdl2/version.rb +8 -0
  41. data/sample/chunk_destroy.rb +16 -0
  42. data/sample/gfxprimitives.rb +54 -0
  43. data/sample/icon.bmp +0 -0
  44. data/sample/memory_test/m1.rb +28 -0
  45. data/sample/memory_test/m2.rb +18 -0
  46. data/sample/memory_test/m3.rb +12 -0
  47. data/sample/message_box.rb +33 -0
  48. data/sample/music_player.rb +137 -0
  49. data/sample/playwave.rb +19 -0
  50. data/sample/primitives.rb +32 -0
  51. data/sample/test_clipboard.rb +16 -0
  52. data/sample/test_controller.rb +62 -0
  53. data/sample/test_joystick.rb +53 -0
  54. data/sample/test_keyboard.rb +52 -0
  55. data/sample/test_mouse.rb +50 -0
  56. data/sample/test_surface.rb +13 -0
  57. data/sample/test_ttf.rb +82 -0
  58. data/sample/test_video.rb +59 -0
  59. data/sample/testgl.rb +175 -0
  60. data/sample/testsprite.rb +296 -0
  61. data/sample/testspriteminimal.rb +75 -0
  62. data/sample/timer.rb +11 -0
  63. data/sample/version.rb +12 -0
  64. data/sample/video_info.rb +64 -0
  65. data/sdl2-win93.gemspec +31 -0
  66. 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