sdl2-win93 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,4093 @@
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
+
808
+ */
809
+ /*
810
+ * Show the window.
811
+ *
812
+ * @return [nil]
813
+ * @see #hide
814
+ */
815
+ static VALUE Window_show(VALUE self)
816
+ {
817
+ SDL_ShowWindow(Get_SDL_Window(self)); return Qnil;
818
+ };
819
+
820
+ /*
821
+ * Hide the window.
822
+ *
823
+ * @return [nil]
824
+ * @see #show
825
+ */
826
+ static VALUE Window_hide(VALUE self)
827
+ {
828
+ SDL_HideWindow(Get_SDL_Window(self)); return Qnil;
829
+ };
830
+
831
+ /*
832
+ * Maximize the window.
833
+ *
834
+ * @return [nil]
835
+ * @see #minimize
836
+ * @see #restore
837
+ */
838
+ static VALUE Window_maximize(VALUE self)
839
+ {
840
+ SDL_MaximizeWindow(Get_SDL_Window(self)); return Qnil;
841
+ };
842
+
843
+ /*
844
+ * Minimize the window.
845
+ *
846
+ * @return [nil]
847
+ * @see #maximize
848
+ * @see #restore
849
+ */
850
+ static VALUE Window_minimize(VALUE self)
851
+ {
852
+ SDL_MinimizeWindow(Get_SDL_Window(self)); return Qnil;
853
+ };
854
+
855
+ /*
856
+ * Raise the window above other windows and set the input focus.
857
+ *
858
+ * @return [nil]
859
+ */
860
+ static VALUE Window_raise(VALUE self)
861
+ {
862
+ SDL_RaiseWindow(Get_SDL_Window(self)); return Qnil;
863
+ };
864
+
865
+ /*
866
+ * Restore the size and position of a minimized or maixmized window.
867
+ *
868
+ * @return [nil]
869
+ * @see #minimize
870
+ * @see #maximize
871
+ */
872
+ static VALUE Window_restore(VALUE self)
873
+ {
874
+ SDL_RestoreWindow(Get_SDL_Window(self)); return Qnil;
875
+ };
876
+
877
+ /*
878
+ * Get the fullscreen stete of the window
879
+ *
880
+ * @return [Integer] 0 for window mode, {SDL2::Window::Flags::FULLSCREEN} for
881
+ * fullscreen mode, and {SDL2::Window::Flags::FULLSCREEN_DESKTOP} for fullscreen
882
+ * at the current desktop resolution.
883
+ *
884
+ * @see #fullscreen_mode=
885
+ * @see #flags
886
+ */
887
+ static VALUE Window_fullscreen_mode(VALUE self)
888
+ {
889
+ Uint32 flags = SDL_GetWindowFlags(Get_SDL_Window(self));
890
+ return UINT2NUM(flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_FULLSCREEN_DESKTOP));
891
+ }
892
+
893
+ /*
894
+ * @overload fullscreen_mode=(flag)
895
+ * Set the fullscreen state of the window
896
+ *
897
+ * @param flag [Integer] 0 for window mode, {SDL2::Window::Flags::FULLSCREEN} for
898
+ * fullscreen mode, and {SDL2::Flags::Window::FULLSCREEN_DESKTOP} for fullscreen
899
+ * at the current desktop resolution.
900
+ * @return [flag]
901
+ *
902
+ * @see #fullscreen_mode
903
+ */
904
+ static VALUE Window_set_fullscreen_mode(VALUE self, VALUE flags)
905
+ {
906
+ HANDLE_ERROR(SDL_SetWindowFullscreen(Get_SDL_Window(self), NUM2UINT(flags)));
907
+ return flags;
908
+ }
909
+
910
+ #if SDL_VERSION_ATLEAST(2,0,1)
911
+ /*
912
+ * Get the size of the drawable region.
913
+ *
914
+ * @return [[Integer, Integer]] the width and height of the region
915
+ */
916
+ static VALUE Window_gl_drawable_size(VALUE self)
917
+ {
918
+ int w, h;
919
+ SDL_GL_GetDrawableSize(Get_SDL_Window(self), &w, &h);
920
+ return rb_ary_new3(2, INT2NUM(w), INT2NUM(h));
921
+ }
922
+ #endif
923
+
924
+ /*
925
+ * Swap the OpenGL buffers for the window, if double buffering
926
+ * is supported.
927
+ *
928
+ * @return [nil]
929
+ */
930
+ static VALUE Window_gl_swap(VALUE self)
931
+ {
932
+ SDL_GL_SwapWindow(Get_SDL_Window(self));
933
+ return Qnil;
934
+ }
935
+
936
+ /* @return [String] inspection string */
937
+ static VALUE Window_inspect(VALUE self)
938
+ {
939
+ Window* w = Get_Window(self);
940
+ if (w->window)
941
+ return rb_sprintf("<%s:%p window_id=%d>",
942
+ rb_obj_classname(self), (void*)self, SDL_GetWindowID(w->window));
943
+ else
944
+ return rb_sprintf("<%s:%p (destroyed)>", rb_obj_classname(self), (void*)self);
945
+ }
946
+
947
+ /* @return [Hash] (GC) debug information */
948
+ static VALUE Window_debug_info(VALUE self)
949
+ {
950
+ Window* w = Get_Window(self);
951
+ VALUE info = rb_hash_new();
952
+ int num_active_renderers = 0;
953
+ int i;
954
+ rb_hash_aset(info, rb_str_new2("destroy?"), INT2BOOL(w->window == NULL));
955
+ rb_hash_aset(info, rb_str_new2("max_renderers"), INT2NUM(w->max_renderers));
956
+ rb_hash_aset(info, rb_str_new2("num_renderers"), INT2NUM(w->num_renderers));
957
+ for (i=0; i<w->num_renderers; ++i)
958
+ if (w->renderers[i]->renderer)
959
+ ++num_active_renderers;
960
+ rb_hash_aset(info, rb_str_new2("num_active_renderers"), INT2NUM(num_active_renderers));
961
+
962
+ return info;
963
+ }
964
+
965
+ /*
966
+ * Document-module: SDL2::Window::Flags
967
+ *
968
+ * OR'd bits of the constants of this module represents window states.
969
+ *
970
+ * You can see a window state using {SDL2::Window#flags}
971
+ * and create a window with a specified
972
+ * state using flag parameter of {SDL2::Window.create}.
973
+ *
974
+ */
975
+
976
+ /*
977
+ * Document-class: SDL2::Display
978
+ *
979
+ * This class represents displays, screens, or monitors.
980
+ *
981
+ * This means that if you use dual screen, {.displays} returns two displays.
982
+ *
983
+ * This class handles color depth, resolution, and refresh rate of displays.
984
+ *
985
+ *
986
+ * @!attribute [r] index
987
+ * The index of the display, 0 origin
988
+ * @return [Integer]
989
+ *
990
+ * @!attribute [r] name
991
+ * The name of the display
992
+ * @return [Stirng]
993
+ *
994
+ */
995
+
996
+ /*
997
+ * Get all connected displays.
998
+ *
999
+ * @return [Array<SDL2::Display>]
1000
+ *
1001
+ */
1002
+ static VALUE Display_s_displays(VALUE self)
1003
+ {
1004
+ int i;
1005
+ int num_displays = HANDLE_ERROR(SDL_GetNumVideoDisplays());
1006
+ VALUE displays = rb_ary_new2(num_displays);
1007
+ for (i=0; i<num_displays; ++i)
1008
+ rb_ary_push(displays, Display_new(i));
1009
+ return displays;
1010
+ }
1011
+
1012
+ static int Display_index_int(VALUE display)
1013
+ {
1014
+ return NUM2INT(rb_iv_get(display, "@index"));
1015
+ }
1016
+
1017
+ /*
1018
+ * Get available display modes of the display.
1019
+ *
1020
+ * @return [Array<SDL2::Display::Mode>]
1021
+ *
1022
+ */
1023
+ static VALUE Display_modes(VALUE self)
1024
+ {
1025
+ int i;
1026
+ int index = Display_index_int(self);
1027
+ int num_modes = SDL_GetNumDisplayModes(index);
1028
+ VALUE modes = rb_ary_new2(num_modes);
1029
+ for (i=0; i<num_modes; ++i) {
1030
+ SDL_DisplayMode mode;
1031
+ HANDLE_ERROR(SDL_GetDisplayMode(index, i, &mode));
1032
+ rb_ary_push(modes, DisplayMode_new(&mode));
1033
+ }
1034
+ return modes;
1035
+ }
1036
+
1037
+ /*
1038
+ * Get the current display mode.
1039
+ *
1040
+ * @return [SDL2::Display::Mode]
1041
+ *
1042
+ * @see #desktop_mode
1043
+ */
1044
+ static VALUE Display_current_mode(VALUE self)
1045
+ {
1046
+ SDL_DisplayMode mode;
1047
+ HANDLE_ERROR(SDL_GetCurrentDisplayMode(Display_index_int(self), &mode));
1048
+ return DisplayMode_new(&mode);
1049
+ }
1050
+
1051
+ /*
1052
+ * Get the desktop display mode.
1053
+ *
1054
+ * Normally, the return value of this method is
1055
+ * same as {#current_mode}. However,
1056
+ * when you use fullscreen and chagne the resolution,
1057
+ * this method returns the previous native display mode,
1058
+ * and not the current mode.
1059
+ *
1060
+ * @return [SDL2::Display::Mode]
1061
+ */
1062
+ static VALUE Display_desktop_mode(VALUE self)
1063
+ {
1064
+ SDL_DisplayMode mode;
1065
+ HANDLE_ERROR(SDL_GetDesktopDisplayMode(Display_index_int(self), &mode));
1066
+ return DisplayMode_new(&mode);
1067
+ }
1068
+
1069
+ /*
1070
+ * @overload closest_mode(mode)
1071
+ * Get the available display mode closest match to **mode**.
1072
+ *
1073
+ * @param mode [SDL2::Display::Mode] the desired display mode
1074
+ * @return [SDL2::Display::Mode]
1075
+ *
1076
+ */
1077
+ static VALUE Display_closest_mode(VALUE self, VALUE mode)
1078
+ {
1079
+ SDL_DisplayMode closest;
1080
+ if (!SDL_GetClosestDisplayMode(Display_index_int(self), Get_SDL_DisplayMode(mode),
1081
+ &closest))
1082
+ SDL_ERROR();
1083
+ return DisplayMode_new(&closest);
1084
+ }
1085
+
1086
+ /*
1087
+ * Get the desktop area represented by the display, with the primary
1088
+ * display located at (0, 0).
1089
+ *
1090
+ * @return [Rect]
1091
+ */
1092
+ static VALUE Display_bounds(VALUE self)
1093
+ {
1094
+ VALUE rect = rb_obj_alloc(cRect);
1095
+ HANDLE_ERROR(SDL_GetDisplayBounds(Display_index_int(self), Get_SDL_Rect(rect)));
1096
+ return rect;
1097
+ }
1098
+
1099
+ static Uint32 uint32_for_format(VALUE format)
1100
+ {
1101
+ if (rb_obj_is_kind_of(format, cPixelFormat))
1102
+ return NUM2UINT(rb_iv_get(format, "@format"));
1103
+ else
1104
+ return NUM2UINT(format);
1105
+ }
1106
+
1107
+ /*
1108
+ * Document-class: SDL2::Display::Mode
1109
+ *
1110
+ * This class represents the display mode.
1111
+ *
1112
+ * An object of this class has information about color depth, refresh rate,
1113
+ * and resolution of a display.
1114
+ *
1115
+ *
1116
+ */
1117
+
1118
+ /*
1119
+ * @overload initialize(format, w, h, refresh_rate)
1120
+ * Create a new Display::Mode object.
1121
+ *
1122
+ * @param format [SDL2::PixelFormat, Integer] pixel format
1123
+ * @param w [Integer] the width
1124
+ * @param h [Integer] the height
1125
+ * @param refresh_rate [Integer] refresh rate
1126
+ */
1127
+ static VALUE DisplayMode_initialize(VALUE self, VALUE format, VALUE w, VALUE h,
1128
+ VALUE refresh_rate)
1129
+ {
1130
+ SDL_DisplayMode* mode = Get_SDL_DisplayMode(self);
1131
+ mode->format = uint32_for_format(format);
1132
+ mode->w = NUM2INT(w); mode->h = NUM2INT(h);
1133
+ mode->refresh_rate = NUM2INT(refresh_rate);
1134
+ return Qnil;
1135
+ }
1136
+
1137
+ /* @return [String] inspection string */
1138
+ static VALUE DisplayMode_inspect(VALUE self)
1139
+ {
1140
+ SDL_DisplayMode* mode = Get_SDL_DisplayMode(self);
1141
+ return rb_sprintf("<%s: format=%s w=%d h=%d refresh_rate=%d>",
1142
+ rb_obj_classname(self), SDL_GetPixelFormatName(mode->format),
1143
+ mode->w, mode->h, mode->refresh_rate);
1144
+
1145
+ }
1146
+
1147
+ /* @return [SDL2::PixelFormat] the pixel format of the display mode */
1148
+ static VALUE DisplayMode_format(VALUE self)
1149
+ {
1150
+ return PixelFormat_new(Get_SDL_DisplayMode(self)->format);
1151
+ }
1152
+
1153
+ /* @return [Integer] the width of the screen of the display mode */
1154
+ static VALUE DisplayMode_w(VALUE self)
1155
+ {
1156
+ return INT2NUM(Get_SDL_DisplayMode(self)->w);
1157
+ }
1158
+
1159
+ /* @return [Integer] the height of the screen of the display mode */
1160
+ static VALUE DisplayMode_h(VALUE self)
1161
+ {
1162
+ return INT2NUM(Get_SDL_DisplayMode(self)->h);
1163
+ }
1164
+
1165
+ /* @return [Integer] the refresh rate of the display mode */
1166
+ static VALUE DisplayMode_refresh_rate(VALUE self)
1167
+ {
1168
+ return INT2NUM(Get_SDL_DisplayMode(self)->refresh_rate);
1169
+ }
1170
+
1171
+ /*
1172
+ * Document-class: SDL2::Renderer
1173
+ *
1174
+ * This class represents a 2D rendering context for a window.
1175
+ *
1176
+ * You can create a renderer using {SDL2::Window#create_renderer} and
1177
+ * use it to draw figures on the window.
1178
+ *
1179
+ *
1180
+ * @!method destroy?
1181
+ * Return true if the renderer is {#destroy destroyed}.
1182
+ *
1183
+ */
1184
+
1185
+
1186
+ /*
1187
+ * @overload drivers_info
1188
+ * Return information of all available rendering contexts.
1189
+ * @return [Array<SDL2::Renderer::Info>] information about rendering contexts
1190
+ *
1191
+ */
1192
+ static VALUE Renderer_s_drivers_info(VALUE self)
1193
+ {
1194
+ int num_drivers = SDL_GetNumRenderDrivers();
1195
+ VALUE info_ary = rb_ary_new();
1196
+ int i;
1197
+ for (i=0; i<num_drivers; ++i) {
1198
+ SDL_RendererInfo info;
1199
+ HANDLE_ERROR(SDL_GetRenderDriverInfo(i, &info));
1200
+ rb_ary_push(info_ary, RendererInfo_new(&info));
1201
+ }
1202
+ return info_ary;
1203
+ }
1204
+
1205
+ /*
1206
+ * Destroy the rendering context and free associated textures.
1207
+ *
1208
+ * @return [nil]
1209
+ * @see #destroy?
1210
+ */
1211
+ static VALUE Renderer_destroy(VALUE self)
1212
+ {
1213
+ Renderer_destroy_internal(Get_Renderer(self));
1214
+ return Qnil;
1215
+ }
1216
+
1217
+ /*
1218
+ * @overload create_texture(format, access, w, h)
1219
+ * Create a new texture for the rendering context.
1220
+ *
1221
+ * You can use the following constants to specify access pattern
1222
+ *
1223
+ * * {SDL2::Texture::ACCESS_STATIC}
1224
+ * * {SDL2::Texture::ACCESS_STREAMING}
1225
+ * * {SDL2::Texture::ACCESS_TARGET}
1226
+ *
1227
+ * @param [SDL2::PixelFormat,Integer] format format of the texture
1228
+ * @param [Integer] access texture access pattern
1229
+ * @param [Integer] w the width ofthe texture in pixels
1230
+ * @param [Integer] h the height ofthe texture in pixels
1231
+ *
1232
+ * @return [SDL2::Texture] the created texture
1233
+ *
1234
+ * @raise [SDL2::Error] raised when the texture cannot be created
1235
+ *
1236
+ * @see #create_texture_from
1237
+ */
1238
+ static VALUE Renderer_create_texture(VALUE self, VALUE format, VALUE access,
1239
+ VALUE w, VALUE h)
1240
+ {
1241
+ SDL_Texture* texture = SDL_CreateTexture(Get_SDL_Renderer(self),
1242
+ uint32_for_format(format),
1243
+ NUM2INT(access), NUM2INT(w), NUM2INT(h));
1244
+ if (!texture)
1245
+ SDL_ERROR();
1246
+ return Texture_new(texture, Get_Renderer(self));
1247
+ }
1248
+
1249
+ /*
1250
+ * @overload create_texture_from(surface)
1251
+ * Create a texture from an existing surface.
1252
+ *
1253
+ * @param [SDL2::Surface] surface the surface containing pixels for the texture
1254
+ * @return [SDL2::Texture] the created texture
1255
+ *
1256
+ * @raise [SDL2::Error] raised when the texture cannot be created
1257
+ *
1258
+ * @see #create_texture
1259
+ */
1260
+ static VALUE Renderer_create_texture_from(VALUE self, VALUE surface)
1261
+ {
1262
+ SDL_Texture* texture = SDL_CreateTextureFromSurface(Get_SDL_Renderer(self),
1263
+ Get_SDL_Surface(surface));
1264
+ if (texture == NULL)
1265
+ SDL_ERROR();
1266
+
1267
+ return Texture_new(texture, Get_Renderer(self));
1268
+ }
1269
+
1270
+ static SDL_Rect* Get_SDL_Rect_or_NULL(VALUE rect)
1271
+ {
1272
+ return rect == Qnil ? NULL : Get_SDL_Rect(rect);
1273
+ }
1274
+
1275
+ static SDL_Point* Get_SDL_Point_or_NULL(VALUE point)
1276
+ {
1277
+ return point == Qnil ? NULL : Get_SDL_Point(point);
1278
+ }
1279
+
1280
+ /*
1281
+ * @overload copy(texture, srcrect, dstrect)
1282
+ * Copy a portion of the texture to the current rendering target.
1283
+ *
1284
+ * @param [SDL2::Texture] texture the source texture
1285
+ * @param [SDL2::Rect,nil] srcrect the source rectangle, or nil for the entire texture
1286
+ * @param [SDL2::Rect,nil] dstrect the destination rectangle, or nil for the entire
1287
+ * rendering target; the texture will be stretched to fill the given rectangle
1288
+ *
1289
+ * @return [void]
1290
+ *
1291
+ * @see #copy_ex
1292
+ */
1293
+ static VALUE Renderer_copy(VALUE self, VALUE texture, VALUE srcrect, VALUE dstrect)
1294
+ {
1295
+ HANDLE_ERROR(SDL_RenderCopy(Get_SDL_Renderer(self),
1296
+ Get_SDL_Texture(texture),
1297
+ Get_SDL_Rect_or_NULL(srcrect),
1298
+ Get_SDL_Rect_or_NULL(dstrect)));
1299
+ return Qnil;
1300
+ }
1301
+
1302
+ /*
1303
+ * @overload copy_ex(texture, srcrect, dstrect, angle, center, flip)
1304
+ * Copy a portion of the texture to the current rendering target,
1305
+ * rotating it by angle around the given center and also flipping
1306
+ * it top-bottom and/or left-right.
1307
+ *
1308
+ * You can use the following constants to specify the horizontal/vertical flip:
1309
+ *
1310
+ * * {SDL2::Renderer::FLIP_HORIZONTAL} - flip horizontally
1311
+ * * {SDL2::Renderer::FLIP_VERTICAL} - flip vertically
1312
+ * * {SDL2::Renderer::FLIP_NONE} - do not flip, equal to zero
1313
+ *
1314
+ *
1315
+ * @param [SDL2::Texture] texture the source texture
1316
+ * @param [SDL2::Rect,nil] srcrect the source rectangle, or nil for the entire texture
1317
+ * @param [SDL2::Rect,nil] dstrect the destination rectangle, or nil for the entire
1318
+ * rendering target; the texture will be stretched to fill the given rectangle
1319
+ * @param [Float] angle an angle in degree indicating the rotation
1320
+ * that will be applied to dstrect
1321
+ * @param [SDL2::Point,nil] center the point around which dstrect will be rotated,
1322
+ * (if nil, rotation will be done around the center of dstrect)
1323
+ * @param [Integer] flip bits OR'd of the flip consntants
1324
+ *
1325
+ * @return [void]
1326
+ *
1327
+ * @see #copy
1328
+ */
1329
+ static VALUE Renderer_copy_ex(VALUE self, VALUE texture, VALUE srcrect, VALUE dstrect,
1330
+ VALUE angle, VALUE center, VALUE flip)
1331
+ {
1332
+ HANDLE_ERROR(SDL_RenderCopyEx(Get_SDL_Renderer(self),
1333
+ Get_SDL_Texture(texture),
1334
+ Get_SDL_Rect_or_NULL(srcrect),
1335
+ Get_SDL_Rect_or_NULL(dstrect),
1336
+ NUM2DBL(angle),
1337
+ Get_SDL_Point_or_NULL(center),
1338
+ NUM2INT(flip)));
1339
+ return Qnil;
1340
+ }
1341
+
1342
+ /*
1343
+ * Update the screen with rendering performed
1344
+ * @return [nil]
1345
+ */
1346
+ static VALUE Renderer_present(VALUE self)
1347
+ {
1348
+ SDL_RenderPresent(Get_SDL_Renderer(self));
1349
+ return Qnil;
1350
+ }
1351
+
1352
+ /*
1353
+ * Crear the rendering target with the drawing color.
1354
+ * @return [nil]
1355
+ *
1356
+ * @see #draw_color=
1357
+ */
1358
+ static VALUE Renderer_clear(VALUE self)
1359
+ {
1360
+ HANDLE_ERROR(SDL_RenderClear(Get_SDL_Renderer(self)));
1361
+ return Qnil;
1362
+ }
1363
+
1364
+ /*
1365
+ * Get the color used for drawing operations
1366
+ * @return [[Integer,Integer,Integer,Integer]]
1367
+ * red, green, blue, and alpha components of the drawing color
1368
+ * (all components are more than or equal to 0 and less than and equal to 255)
1369
+ *
1370
+ * @see #draw_color=
1371
+ */
1372
+ static VALUE Renderer_draw_color(VALUE self)
1373
+ {
1374
+ Uint8 r, g, b, a;
1375
+ HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self), &r, &g, &b, &a));
1376
+ return rb_ary_new3(4, INT2FIX(r), INT2FIX(g), INT2FIX(b), INT2FIX(a));
1377
+ }
1378
+
1379
+ /*
1380
+ * @overload draw_color=(color)
1381
+ * Set the color used for drawing operations
1382
+ *
1383
+ * All color components (including alpha) must be more than or equal to 0
1384
+ * and less than and equal to 255
1385
+ *
1386
+ * This method effects the following methods.
1387
+ *
1388
+ * * {#draw_line}
1389
+ * * {#draw_point}
1390
+ * * {#draw_rect}
1391
+ * * {#fill_rect}
1392
+ * * {#clear}
1393
+ *
1394
+ * @param [Integer] color
1395
+ * red, green, and blue components used for drawing
1396
+ * @param [[Integer, Integer, Integer, Integer]] color
1397
+ * red, green, blue, and alpha components used for drawing
1398
+ *
1399
+ * @return [color]
1400
+ *
1401
+ * @see #draw_color
1402
+ */
1403
+ static VALUE Renderer_set_draw_color(VALUE self, VALUE rgba)
1404
+ {
1405
+ SDL_Color color = Color_to_SDL_Color(rgba);
1406
+
1407
+ HANDLE_ERROR(SDL_SetRenderDrawColor(Get_SDL_Renderer(self),
1408
+ color.r, color.g, color.b, color.a));
1409
+
1410
+ return rgba;
1411
+ }
1412
+
1413
+ /*
1414
+ * @overload draw_line(x1, y1, x2, y2)
1415
+ * Draw a line from (x1, y1) to (x2, y2) using drawing color given by
1416
+ * {#draw_color=}.
1417
+ *
1418
+ * @param [Integer] x1 the x coordinate of the start point
1419
+ * @param [Integer] y1 the y coordinate of the start point
1420
+ * @param [Integer] x2 the x coordinate of the end point
1421
+ * @param [Integer] y2 the y coordinate of the end point
1422
+ * @return [nil]
1423
+ */
1424
+ static VALUE Renderer_draw_line(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2)
1425
+ {
1426
+ HANDLE_ERROR(SDL_RenderDrawLine(Get_SDL_Renderer(self),
1427
+ NUM2INT(x1), NUM2INT(y1), NUM2INT(x2), NUM2INT(y2)));
1428
+ return Qnil;
1429
+ }
1430
+
1431
+ /*
1432
+ * @overload draw_point(x, y)
1433
+ * Draw a point at (x, y) using drawing color given by {#draw_color=}.
1434
+ *
1435
+ * @param [Integer] x the x coordinate of the point
1436
+ * @param [Integer] y the y coordinate of the point
1437
+ *
1438
+ * @return [nil]
1439
+ */
1440
+ static VALUE Renderer_draw_point(VALUE self, VALUE x, VALUE y)
1441
+ {
1442
+ HANDLE_ERROR(SDL_RenderDrawPoint(Get_SDL_Renderer(self), NUM2INT(x), NUM2INT(y)));
1443
+ return Qnil;
1444
+ }
1445
+
1446
+ /*
1447
+ * @overload draw_rect(rect)
1448
+ * Draw a rectangle using drawing color given by {#draw_color=}.
1449
+ *
1450
+ * @param [SDL2::Rect] rect the drawing rectangle
1451
+ *
1452
+ * @return [nil]
1453
+ */
1454
+ static VALUE Renderer_draw_rect(VALUE self, VALUE rect)
1455
+ {
1456
+ HANDLE_ERROR(SDL_RenderDrawRect(Get_SDL_Renderer(self), Get_SDL_Rect(rect)));
1457
+ return Qnil;
1458
+ }
1459
+
1460
+ /*
1461
+ * @overload fill_rect(rect)
1462
+ * Draw a filled rectangle using drawing color given by {#draw_color=}.
1463
+ *
1464
+ * @param [SDL2::Rect] rect the drawing rectangle
1465
+ *
1466
+ * @return [nil]
1467
+ */
1468
+ static VALUE Renderer_fill_rect(VALUE self, VALUE rect)
1469
+ {
1470
+ HANDLE_ERROR(SDL_RenderFillRect(Get_SDL_Renderer(self), Get_SDL_Rect(rect)));
1471
+ return Qnil;
1472
+ }
1473
+
1474
+ /*
1475
+ * Get information about _self_ rendering context .
1476
+ *
1477
+ * @return [SDL2::Renderer::Info] rendering information
1478
+ */
1479
+ static VALUE Renderer_info(VALUE self)
1480
+ {
1481
+ SDL_RendererInfo info;
1482
+ HANDLE_ERROR(SDL_GetRendererInfo(Get_SDL_Renderer(self), &info));
1483
+ return RendererInfo_new(&info);
1484
+ }
1485
+
1486
+ /*
1487
+ * Get the blend mode used for drawing operations like
1488
+ * {#fill_rect} and {#draw_line}.
1489
+ *
1490
+ * @return [Integer]
1491
+ *
1492
+ * @see #draw_blend_mode=
1493
+ * @see SDL2::BlendMode
1494
+ */
1495
+ static VALUE Renderer_draw_blend_mode(VALUE self)
1496
+ {
1497
+ SDL_BlendMode mode;
1498
+ HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &mode));
1499
+ return INT2FIX(mode);
1500
+ }
1501
+
1502
+ /*
1503
+ * @overload draw_blend_mode=(mode)
1504
+ * Set the blend mode used for drawing operations.
1505
+ *
1506
+ * This method effects the following methods.
1507
+ *
1508
+ * * {#draw_line}
1509
+ * * {#draw_point}
1510
+ * * {#draw_rect}
1511
+ * * {#fill_rect}
1512
+ * * {#clear}
1513
+ *
1514
+ * @param mode [Integer] the blending mode
1515
+ * @return mode
1516
+ *
1517
+ * @see #draw_blend_mode
1518
+ * @see SDL2::BlendMode
1519
+ */
1520
+ static VALUE Renderer_set_draw_blend_mode(VALUE self, VALUE mode)
1521
+ {
1522
+ HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), NUM2INT(mode)));
1523
+ return mode;
1524
+ }
1525
+
1526
+ /*
1527
+ * Get the clip rectangle for the current target.
1528
+ *
1529
+ * @return [SDL2::Rect] the current clip rectangle
1530
+ * @see {#clip_rect=}
1531
+ */
1532
+ static VALUE Renderer_clip_rect(VALUE self)
1533
+ {
1534
+ VALUE rect = rb_obj_alloc(cRect);
1535
+ SDL_RenderGetClipRect(Get_SDL_Renderer(self), Get_SDL_Rect(rect));
1536
+ return rect;
1537
+ }
1538
+
1539
+ /*
1540
+ * @overload clip_rect=(rect)
1541
+ *
1542
+ * Set the clip rectangle for the current target.
1543
+ *
1544
+ * @return [rect]
1545
+ * @see #clip_rect
1546
+ */
1547
+ static VALUE Renderer_set_clip_rect(VALUE self, VALUE rect)
1548
+ {
1549
+ HANDLE_ERROR(SDL_RenderSetClipRect(Get_SDL_Renderer(self), Get_SDL_Rect(rect)));
1550
+ return rect;
1551
+ }
1552
+
1553
+ #if SDL_VERSION_ATLEAST(2,0,4)
1554
+ /*
1555
+ * Get whether clipping is enabled on the renderer.
1556
+ *
1557
+ * @note This method is available since SDL 2.0.4.
1558
+ */
1559
+ static VALUE Render_clip_enabled_p(VALUE self)
1560
+ {
1561
+ return INT2BOOL(SDL_RenderIsClipEnabled(Get_SDL_Renderer(self)));
1562
+ }
1563
+ #endif
1564
+
1565
+ /*
1566
+ * Get device indepndent resolution for rendering.
1567
+ *
1568
+ * @return [[Integer, Integer]] the logical width and height
1569
+ * @see #logical_size=
1570
+ */
1571
+ static VALUE Renderer_logical_size(VALUE self)
1572
+ {
1573
+ int w, h;
1574
+ SDL_RenderGetLogicalSize(Get_SDL_Renderer(self), &w, &h);
1575
+ return rb_ary_new3(2, INT2FIX(w), INT2FIX(h));
1576
+ }
1577
+
1578
+ /*
1579
+ * @overload logical_size=(w_and_h)
1580
+ *
1581
+ * Set a device indepndent resolution for rendering.
1582
+ *
1583
+ * @param w_and_h [[Integer, Integer]] the width and height of the logical resolution
1584
+ * @return [w_and_h]
1585
+ * @see #logical_size
1586
+ */
1587
+ static VALUE Renderer_set_logical_size(VALUE self, VALUE wh)
1588
+ {
1589
+ HANDLE_ERROR(SDL_RenderSetLogicalSize(Get_SDL_Renderer(self),
1590
+ NUM2DBL(rb_ary_entry(wh, 0)),
1591
+ NUM2DBL(rb_ary_entry(wh, 1))));
1592
+ return wh;
1593
+ }
1594
+
1595
+ /*
1596
+ * Get the drawing scale for the current target.
1597
+ *
1598
+ * @return [[Integer, Integer]] horizontal and vertical scale factor
1599
+ * @see #scale=
1600
+ */
1601
+ static VALUE Renderer_scale(VALUE self)
1602
+ {
1603
+ float scaleX, scaleY;
1604
+ SDL_RenderGetScale(Get_SDL_Renderer(self), &scaleX, &scaleY);
1605
+ return rb_ary_new3(2, DBL2NUM(scaleX), DBL2NUM(scaleY));
1606
+ }
1607
+
1608
+ /*
1609
+ * @overload scale=(scaleX_and_scaleY)
1610
+ *
1611
+ * Set the drawing scale for rendering.
1612
+ *
1613
+ * The drawing coordinates are scaled by the x/y scaling factors before they are used by the renderer.
1614
+ * This allows resolution independent drawing with a single coordinate system.
1615
+ *
1616
+ * If this results in scaling or subpixel drawing by the rendering backend,
1617
+ * it will be handled using the appropriate
1618
+ * quality hints. For best results use integer scaling factors.
1619
+ *
1620
+ * @param scaleX_and_scaleY [[Float, Float]] the horizontal and vertical scaling factors
1621
+ * @return [scaleX_and_scaleY]
1622
+ * @see #scale
1623
+ */
1624
+ static VALUE Renderer_set_scale(VALUE self, VALUE xy)
1625
+ {
1626
+ float scaleX, scaleY;
1627
+ scaleX = NUM2DBL(rb_ary_entry(xy, 0));
1628
+ scaleY = NUM2DBL(rb_ary_entry(xy, 1));
1629
+ HANDLE_ERROR(SDL_RenderSetScale(Get_SDL_Renderer(self), scaleX, scaleY));
1630
+ return xy;
1631
+ }
1632
+
1633
+ /*
1634
+ * Get the drawing area for the current target.
1635
+ *
1636
+ * @return [SDL2::Rect] the current drawing area
1637
+ * @see #viewport=
1638
+ */
1639
+ static VALUE Renderer_viewport(VALUE self)
1640
+ {
1641
+ VALUE rect = rb_obj_alloc(cRect);
1642
+ SDL_RenderGetViewport(Get_SDL_Renderer(self), Get_SDL_Rect(rect));
1643
+ return rect;
1644
+ }
1645
+
1646
+ /*
1647
+ * @overload viewport=(area)
1648
+ * Set the drawing area for rendering on the current target.
1649
+ *
1650
+ * @param area [SDL2::Rect,nil] the drawing area, or nil to set the viewport to the entire target
1651
+ * @return [area]
1652
+ * @see #viewport
1653
+ */
1654
+ static VALUE Renderer_set_viewport(VALUE self, VALUE rect)
1655
+ {
1656
+ HANDLE_ERROR(SDL_RenderSetClipRect(Get_SDL_Renderer(self), Get_SDL_Rect_or_NULL(rect)));
1657
+ return rect;
1658
+ }
1659
+
1660
+ /*
1661
+ * Return true if the renderer supports render target.
1662
+ *
1663
+ * @see #render_target=
1664
+ */
1665
+ static VALUE Renderer_support_render_target_p(VALUE self)
1666
+ {
1667
+ return INT2BOOL(SDL_RenderTargetSupported(Get_SDL_Renderer(self)));
1668
+ }
1669
+
1670
+ /*
1671
+ * Get the output size of a rendering context.
1672
+ *
1673
+ * @return [[Integer, Integer]] the width and the height
1674
+ */
1675
+ static VALUE Renderer_output_size(VALUE self)
1676
+ {
1677
+ int w, h;
1678
+ HANDLE_ERROR(SDL_GetRendererOutputSize(Get_SDL_Renderer(self), &w, &h));
1679
+ return rb_ary_new3(2, INT2FIX(w), INT2FIX(h));
1680
+ }
1681
+
1682
+ /*
1683
+ * @overload render_target=(target)
1684
+ * Set a texture as the current render target.
1685
+ *
1686
+ * Some renderers have ability to render to a texture instead of a screen.
1687
+ * You can judge whether your renderer has this ability using
1688
+ * {#support_render_target?}.
1689
+ *
1690
+ * The target texture musbe be {#create_texture created} with the
1691
+ * {SDL2::Texture::ACCESS_TARGET} flag.
1692
+ *
1693
+ * @param [SDL2::Texture,nil] target the targeted texture, or nil
1694
+ * for the default render target(i.e. screen)
1695
+ *
1696
+ * @return [target]
1697
+ *
1698
+ * @see #render_target
1699
+ */
1700
+ static VALUE Renderer_set_render_target(VALUE self, VALUE target)
1701
+ {
1702
+ HANDLE_ERROR(SDL_SetRenderTarget(Get_SDL_Renderer(self),
1703
+ (target == Qnil) ? NULL : Get_SDL_Texture(target)));
1704
+ rb_iv_set(self, "render_target", target);
1705
+ return target;
1706
+ }
1707
+
1708
+ /*
1709
+ * Get the current render target.
1710
+ *
1711
+ * @return [SDL2::Texture] the current rendering target
1712
+ * @return [nil] for the default render target (i.e. screen)
1713
+ *
1714
+ * @see #render_target=
1715
+ * @see #support_render_target?
1716
+ */
1717
+ static VALUE Renderer_render_target(VALUE self)
1718
+ {
1719
+ return rb_iv_get(self, "render_target");
1720
+ }
1721
+
1722
+ /*
1723
+ * Reset the render target to the screen.
1724
+ *
1725
+ * @return [nil]
1726
+ */
1727
+ static VALUE Renderer_reset_render_target(VALUE self)
1728
+ {
1729
+ return Renderer_set_render_target(self, Qnil);
1730
+ }
1731
+
1732
+ /* @return [Hash<String=>Object>] (GC) debug information */
1733
+ static VALUE Renderer_debug_info(VALUE self)
1734
+ {
1735
+ Renderer* r = Get_Renderer(self);
1736
+ VALUE info = rb_hash_new();
1737
+ int num_active_textures = 0;
1738
+ int i;
1739
+ rb_hash_aset(info, rb_str_new2("destroy?"), INT2BOOL(r->renderer == NULL));
1740
+ rb_hash_aset(info, rb_str_new2("max_textures"), INT2NUM(r->max_textures));
1741
+ rb_hash_aset(info, rb_str_new2("num_textures"), INT2NUM(r->num_textures));
1742
+ for (i=0; i<r->num_textures; ++i)
1743
+ if (r->textures[i]->texture)
1744
+ ++num_active_textures;
1745
+ rb_hash_aset(info, rb_str_new2("num_active_textures"), INT2NUM(num_active_textures));
1746
+ rb_hash_aset(info, rb_str_new2("refcount"), INT2NUM(r->refcount));
1747
+
1748
+ return info;
1749
+ }
1750
+
1751
+ // Draw anti-aliased line with alpha blending.
1752
+ static VALUE Renderer_draw_line_aa(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2)
1753
+ {
1754
+ SDL_BlendMode mode;
1755
+ Uint8 r, g, b, a;
1756
+ HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &mode));
1757
+ HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self), &r, &g, &b, &a));
1758
+ HANDLE_ERROR(aalineRGBA(Get_SDL_Renderer(self), NUM2INT(x1), NUM2INT(y1), NUM2INT(x2), NUM2INT(y2), r, g, b, a));
1759
+ HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), mode));
1760
+ return Qnil;
1761
+ }
1762
+
1763
+ // Draw a thick line with alpha blending.
1764
+ static VALUE Renderer_draw_line_thick(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2, VALUE width)
1765
+ {
1766
+ SDL_BlendMode mode;
1767
+ Uint8 r, g, b, a;
1768
+ HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &mode));
1769
+ HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self), &r, &g, &b, &a));
1770
+ HANDLE_ERROR(thickLineRGBA(Get_SDL_Renderer(self), NUM2INT(x1), NUM2INT(y1), NUM2INT(x2), NUM2INT(y2), NUM2INT(width), r, g, b, a));
1771
+ HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), mode));
1772
+ return Qnil;
1773
+ }
1774
+
1775
+ // Draw trigon (triangle outline) with alpha blending.
1776
+ static VALUE Renderer_draw_triangle(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2, VALUE x3, VALUE y3)
1777
+ {
1778
+ SDL_BlendMode mode;
1779
+ Uint8 r, g, b, a;
1780
+ HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &mode));
1781
+ HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self), &r, &g, &b, &a));
1782
+ HANDLE_ERROR(trigonRGBA(Get_SDL_Renderer(self), NUM2INT(x1), NUM2INT(y1), NUM2INT(x2), NUM2INT(y2), NUM2INT(x3), NUM2INT(y3), r, g, b, a));
1783
+ HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), mode));
1784
+ return Qnil;
1785
+ }
1786
+
1787
+ // Draw anti-aliased trigon (triangle outline) with alpha blending.
1788
+ static VALUE Renderer_draw_triangle_aa(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2, VALUE x3, VALUE y3)
1789
+ {
1790
+ SDL_BlendMode mode;
1791
+ Uint8 r, g, b, a;
1792
+ HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &mode));
1793
+ HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self), &r, &g, &b, &a));
1794
+ HANDLE_ERROR(aatrigonRGBA(Get_SDL_Renderer(self), NUM2INT(x1), NUM2INT(y1), NUM2INT(x2), NUM2INT(y2), NUM2INT(x3), NUM2INT(y3), r, g, b, a));
1795
+ HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), mode));
1796
+ return Qnil;
1797
+ }
1798
+
1799
+ // Draw filled trigon (triangle) with alpha blending.
1800
+ static VALUE Renderer_fill_triangle(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2, VALUE x3, VALUE y3)
1801
+ {
1802
+ SDL_BlendMode mode;
1803
+ Uint8 r, g, b, a;
1804
+ HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &mode));
1805
+ HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self), &r, &g, &b, &a));
1806
+ HANDLE_ERROR(filledTrigonRGBA(Get_SDL_Renderer(self), NUM2INT(x1), NUM2INT(y1), NUM2INT(x2), NUM2INT(y2), NUM2INT(x3), NUM2INT(y3), r, g, b, a));
1807
+ HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), mode));
1808
+ return Qnil;
1809
+ }
1810
+
1811
+ typedef int (*polygon_gfxFunction)(SDL_Renderer *, const Sint16 *, const Sint16 *, int, Uint8, Uint8, Uint8, Uint8);
1812
+ struct draw_polygon_closure
1813
+ {
1814
+ polygon_gfxFunction gfxFunction;
1815
+ SDL_Renderer *renderer;
1816
+ Sint16 *vx, *vy;
1817
+ long point_count;
1818
+ Uint8 r, g, b, a;
1819
+ SDL_BlendMode blend_mode;
1820
+ };
1821
+
1822
+ static VALUE draw_polygon_generic(VALUE argv)
1823
+ {
1824
+ const struct draw_polygon_closure *closure = (const struct draw_polygon_closure *) argv;
1825
+ HANDLE_ERROR(closure->gfxFunction(closure->renderer, closure->vx, closure->vy, closure->point_count,
1826
+ closure->r, closure->g, closure->b, closure->a));
1827
+ return Qnil;
1828
+ }
1829
+
1830
+ static VALUE draw_polygon_generic_cleanup(VALUE argv)
1831
+ {
1832
+ const struct draw_polygon_closure *closure = (const struct draw_polygon_closure *) argv;
1833
+ HANDLE_ERROR(SDL_SetRenderDrawBlendMode(closure->renderer, closure->blend_mode));
1834
+ free(closure->vx);
1835
+ free(closure->vy);
1836
+ return Qnil;
1837
+ }
1838
+
1839
+ static VALUE Renderer_draw_polygon_generic(VALUE self, VALUE vertices_x, VALUE vertices_y, polygon_gfxFunction polygon_gfxFunction)
1840
+ {
1841
+ struct draw_polygon_closure closure;
1842
+
1843
+ Check_Type(vertices_x, T_ARRAY);
1844
+ Check_Type(vertices_y, T_ARRAY);
1845
+
1846
+ HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &closure.blend_mode));
1847
+ HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self),
1848
+ &closure.r, &closure.g, &closure.b, &closure.a));
1849
+ closure.gfxFunction = polygon_gfxFunction;
1850
+ closure.renderer = Get_SDL_Renderer(self);
1851
+ closure.point_count = RARRAY_LEN(vertices_x);
1852
+ if (RARRAY_LEN(vertices_y) == closure.point_count)
1853
+ rb_raise(rb_eArgError, "Both arrays must be of same size");
1854
+ closure.vx = ruby_xmalloc2(closure.point_count, sizeof(*closure.vx));
1855
+ closure.vy = ruby_xmalloc2(closure.point_count, sizeof(*closure.vy));
1856
+ for (long i = 0; i < closure.point_count; i++) {
1857
+ closure.vx[i] = NUM2INT(rb_ary_entry(vertices_x, i));
1858
+ closure.vy[i] = NUM2INT(rb_ary_entry(vertices_y, i));
1859
+ }
1860
+
1861
+ return rb_ensure(draw_polygon_generic, (VALUE) &closure, draw_polygon_generic_cleanup, (VALUE) &closure);
1862
+ }
1863
+
1864
+ // Draw polygon with the currently set color and blend mode.
1865
+ static VALUE Renderer_draw_polygon(VALUE self, VALUE vertices_x, VALUE vertices_y)
1866
+ {
1867
+ return Renderer_draw_polygon_generic(self, vertices_x, vertices_y, polygonRGBA);
1868
+ }
1869
+
1870
+ // Draw anti-aliased polygon with alpha blending.
1871
+ static VALUE Renderer_draw_polygon_aa(VALUE self, VALUE vertices_x, VALUE vertices_y)
1872
+ {
1873
+ return Renderer_draw_polygon_generic(self, vertices_x, vertices_y, aapolygonRGBA);
1874
+ }
1875
+
1876
+ // Draw filled polygon with alpha blending.
1877
+ static VALUE Renderer_fill_polygon(VALUE self, VALUE vertices_x, VALUE vertices_y)
1878
+ {
1879
+ return Renderer_draw_polygon_generic(self, vertices_x, vertices_y, filledPolygonRGBA);
1880
+ }
1881
+
1882
+ struct draw_polygon_textured_closure
1883
+ {
1884
+ SDL_Renderer *renderer;
1885
+ Sint16 *vx, *vy;
1886
+ long point_count;
1887
+ SDL_Surface *texture;
1888
+ int texture_dx, texture_dy;
1889
+ };
1890
+
1891
+ static VALUE draw_polygon_textured(VALUE argv)
1892
+ {
1893
+ const struct draw_polygon_textured_closure *closure =
1894
+ (const struct draw_polygon_textured_closure *) argv;
1895
+ HANDLE_ERROR(texturedPolygon(closure->renderer, closure->vx, closure->vy, closure->point_count,
1896
+ closure->texture, closure->texture_dx, closure->texture_dy));
1897
+ return Qnil;
1898
+ }
1899
+
1900
+ static VALUE draw_polygon_textured_cleanup(VALUE argv)
1901
+ {
1902
+ const struct draw_polygon_textured_closure *closure =
1903
+ (const struct draw_polygon_textured_closure *) argv;
1904
+ free(closure->vx);
1905
+ free(closure->vy);
1906
+ return Qnil;
1907
+ }
1908
+
1909
+ // Draws a polygon filled with the given texture.
1910
+ static VALUE Renderer_fill_polygon_textured(VALUE self, VALUE vertices_x, VALUE vertices_y, VALUE surface, VALUE surface_dx, VALUE surface_dy)
1911
+ {
1912
+ struct draw_polygon_textured_closure closure;
1913
+
1914
+ Check_Type(vertices_x, T_ARRAY);
1915
+ Check_Type(vertices_y, T_ARRAY);
1916
+
1917
+ closure.renderer = Get_SDL_Renderer(self);
1918
+ closure.texture = Get_SDL_Surface(surface);
1919
+ closure.texture_dx = NUM2INT(surface_dx);
1920
+ closure.texture_dy = NUM2INT(surface_dy);
1921
+
1922
+ closure.point_count = RARRAY_LEN(vertices_x);
1923
+ if (RARRAY_LEN(vertices_y) == closure.point_count)
1924
+ rb_raise(rb_eArgError, "Both arrays must be of same size");
1925
+ closure.vx = ruby_xmalloc2(closure.point_count, sizeof(*closure.vx));
1926
+ closure.vy = ruby_xmalloc2(closure.point_count, sizeof(*closure.vy));
1927
+ for (long i = 0; i < closure.point_count; i++) {
1928
+ closure.vx[i] = NUM2INT(rb_ary_entry(vertices_x, i));
1929
+ closure.vy[i] = NUM2INT(rb_ary_entry(vertices_y, i));
1930
+ }
1931
+
1932
+ return rb_ensure(draw_polygon_textured, (VALUE) &closure, draw_polygon_textured_cleanup, (VALUE) &closure);
1933
+ }
1934
+
1935
+ // Arc with blending.
1936
+ static VALUE Renderer_draw_arc(VALUE self, VALUE x, VALUE y, VALUE rad, VALUE start, VALUE end)
1937
+ {
1938
+ SDL_BlendMode mode;
1939
+ Uint8 r, g, b, a;
1940
+ HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &mode));
1941
+ HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self), &r, &g, &b, &a));
1942
+ HANDLE_ERROR(arcRGBA(Get_SDL_Renderer(self), NUM2INT(x), NUM2INT(y), NUM2INT(rad), NUM2INT(start), NUM2INT(end), r, g, b, a));
1943
+ HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), mode));
1944
+ return Qnil;
1945
+ }
1946
+
1947
+ // Draw ellipse with blending.
1948
+ static VALUE Renderer_draw_ellipse(VALUE self, VALUE x, VALUE y, VALUE rx, VALUE ry)
1949
+ {
1950
+ SDL_BlendMode mode;
1951
+ Uint8 r, g, b, a;
1952
+ HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &mode));
1953
+ HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self), &r, &g, &b, &a));
1954
+ HANDLE_ERROR(ellipseRGBA(Get_SDL_Renderer(self), NUM2INT(x), NUM2INT(y), NUM2INT(rx), NUM2INT(ry), r, g, b, a));
1955
+ HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), mode));
1956
+ return Qnil;
1957
+ }
1958
+
1959
+ // Draw anti-aliased ellipse with blending.
1960
+ static VALUE Renderer_draw_ellipse_aa(VALUE self, VALUE x, VALUE y, VALUE rx, VALUE ry)
1961
+ {
1962
+ SDL_BlendMode mode;
1963
+ Uint8 r, g, b, a;
1964
+ HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &mode));
1965
+ HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self), &r, &g, &b, &a));
1966
+ HANDLE_ERROR(aaellipseRGBA(Get_SDL_Renderer(self), NUM2INT(x), NUM2INT(y), NUM2INT(rx), NUM2INT(ry), r, g, b, a));
1967
+ HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), mode));
1968
+ return Qnil;
1969
+ }
1970
+
1971
+ // Draw filled ellipse with blending.
1972
+ static VALUE Renderer_fill_ellipse(VALUE self, VALUE x, VALUE y, VALUE rx, VALUE ry)
1973
+ {
1974
+ SDL_BlendMode mode;
1975
+ Uint8 r, g, b, a;
1976
+ HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &mode));
1977
+ HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self), &r, &g, &b, &a));
1978
+ HANDLE_ERROR(filledEllipseRGBA(Get_SDL_Renderer(self), NUM2INT(x), NUM2INT(y), NUM2INT(rx), NUM2INT(ry), r, g, b, a));
1979
+ HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), mode));
1980
+ return Qnil;
1981
+ }
1982
+
1983
+ // Draw pie (outline) with alpha blending.
1984
+ static VALUE Renderer_draw_pie(VALUE self, VALUE x, VALUE y, VALUE rad, VALUE start, VALUE end)
1985
+ {
1986
+ SDL_BlendMode mode;
1987
+ Uint8 r, g, b, a;
1988
+ HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &mode));
1989
+ HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self), &r, &g, &b, &a));
1990
+ HANDLE_ERROR(pieRGBA(Get_SDL_Renderer(self), NUM2INT(x), NUM2INT(y), NUM2INT(rad), NUM2INT(start), NUM2INT(end), r, g, b, a));
1991
+ HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), mode));
1992
+ return Qnil;
1993
+ }
1994
+
1995
+ // Draw filled pie with alpha blending.
1996
+ static VALUE Renderer_fill_pie(VALUE self, VALUE x, VALUE y, VALUE rad, VALUE start, VALUE end)
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(filledPieRGBA(Get_SDL_Renderer(self), NUM2INT(x), NUM2INT(y), NUM2INT(rad), NUM2INT(start), NUM2INT(end), r, g, b, a));
2003
+ HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), mode));
2004
+ return Qnil;
2005
+ return Qnil;
2006
+ }
2007
+
2008
+ int internal_roundedRectangleRGBA(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
2009
+
2010
+ // Draw rounded-corner rectangle with blending.
2011
+ static VALUE Renderer_draw_rounded_rect(VALUE self, VALUE x, VALUE y, VALUE w, VALUE h, VALUE rad)
2012
+ {
2013
+ SDL_BlendMode mode;
2014
+ Uint8 r, g, b, a;
2015
+ HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &mode));
2016
+ HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self), &r, &g, &b, &a));
2017
+ HANDLE_ERROR(internal_roundedRectangleRGBA(Get_SDL_Renderer(self),
2018
+ NUM2INT(x), NUM2INT(y),
2019
+ NUM2INT(x) + NUM2INT(w), NUM2INT(y) + NUM2INT(h),
2020
+ NUM2INT(rad), r, g, b, a));
2021
+ HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), mode));
2022
+ return Qnil;
2023
+ }
2024
+
2025
+ // From: https://github.com/rtrussell/BBCSDL/blob/033203c/src/SDL2_gfxPrimitives.c
2026
+ // With modifications so that the draw domain is x:[x1, x2) and y:[y1,y2)
2027
+ // and fixup other off by one errors.
2028
+ int internal_roundedRectangleRGBA(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a) {
2029
+ int result = 0;
2030
+ Sint16 w, h;
2031
+ Sint16 xx1, xx2;
2032
+ Sint16 yy1, yy2;
2033
+
2034
+ if (renderer == NULL)
2035
+ return -1;
2036
+
2037
+ if (rad < 0) // Check radius for valid range
2038
+ return -1;
2039
+
2040
+ if (rad <= 1) //Special case - no rounding
2041
+ return rectangleRGBA(renderer, x1, y1, x2, y2, r, g, b, a);
2042
+
2043
+ // Test for special cases of straight lines or single point
2044
+ if (x1 == x2) {
2045
+ if (y1 == y2)
2046
+ return (pixelRGBA(renderer, x1, y1, r, g, b, a));
2047
+ else
2048
+ return (vlineRGBA(renderer, x1, y1, y2, r, g, b, a));
2049
+ } else if (y1 == y2)
2050
+ return (hlineRGBA(renderer, x1, x2, y1, r, g, b, a));
2051
+
2052
+ // Swap x1, x2 and/or y1, y2 if required
2053
+ if (x1 > x2) {
2054
+ Sint16 tmp = x1;
2055
+ x1 = x2;
2056
+ x2 = tmp;
2057
+ }
2058
+ if (y1 > y2) {
2059
+ Sint16 tmp = y1;
2060
+ y1 = y2;
2061
+ y2 = tmp;
2062
+ }
2063
+
2064
+ //Calculate width & height
2065
+ w = x2 - x1;
2066
+ h = y2 - y1;
2067
+
2068
+ //Maybe adjust radius
2069
+ if ((rad * 2) > w)
2070
+ rad = w / 2;
2071
+ if ((rad * 2) > h)
2072
+ rad = h / 2;
2073
+
2074
+ // Draw corners
2075
+ xx1 = x1 + rad;
2076
+ xx2 = x2 - rad;
2077
+ yy1 = y1 + rad;
2078
+ yy2 = y2 - rad;
2079
+ result |= arcRGBA(renderer, xx1, yy1, rad, 180, 270, r, g, b, a);
2080
+ result |= arcRGBA(renderer, xx2 - 1, yy1, rad, 270, 360, r, g, b, a);
2081
+ result |= arcRGBA(renderer, xx1, yy2 - 1, rad, 90, 180, r, g, b, a);
2082
+ result |= arcRGBA(renderer, xx2 - 1, yy2 - 1, rad, 0, 90, r, g, b, a);
2083
+
2084
+ // Draw lines
2085
+ if (xx1 <= xx2) {
2086
+ result |= hlineRGBA(renderer, xx1, xx2, y1, r, g, b, a);
2087
+ result |= hlineRGBA(renderer, xx1, xx2, y2 - 1, r, g, b, a);
2088
+ }
2089
+ if (yy1 <= yy2) {
2090
+ result |= vlineRGBA(renderer, x1, yy1, yy2, r, g, b, a);
2091
+ result |= vlineRGBA(renderer, x2 - 1, yy1, yy2, r, g, b, a);
2092
+ }
2093
+
2094
+ return result;
2095
+ }
2096
+
2097
+ int internal_roundedBoxRGBA(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2,
2098
+ Sint16 y2, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
2099
+
2100
+ // Draw rounded-corner box (filled rectangle) with blending.
2101
+ static VALUE Renderer_fill_rounded_rect(VALUE self, VALUE x, VALUE y, VALUE w, VALUE h, VALUE rad)
2102
+ {
2103
+ SDL_BlendMode mode;
2104
+ Uint8 r, g, b, a;
2105
+ HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &mode));
2106
+ HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self), &r, &g, &b, &a));
2107
+ HANDLE_ERROR(internal_roundedBoxRGBA(Get_SDL_Renderer(self),
2108
+ NUM2INT(x), NUM2INT(y),
2109
+ NUM2INT(x) + NUM2INT(w), NUM2INT(y) + NUM2INT(h),
2110
+ NUM2INT(rad), r, g, b, a));
2111
+ HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), mode));
2112
+ return Qnil;
2113
+ }
2114
+
2115
+ // From: https://github.com/rtrussell/BBCSDL/blob/033203c/src/SDL2_gfxPrimitives.c
2116
+ // Threw out old code that actually does round corners in favor of a midpoint circle algorithm
2117
+ // From: https://rosettacode.org/wiki/Bitmap/Midpoint_circle_algorithm#C
2118
+ int internal_roundedBoxRGBA(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2,
2119
+ Sint16 y2, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
2120
+ {
2121
+ int result = 0;
2122
+ Sint16 w, h;
2123
+ Sint16 cx1, cy1, cx2, cy2;
2124
+
2125
+ if (renderer == NULL)
2126
+ return -1;
2127
+
2128
+ //Check radius for valid range
2129
+ if (rad < 0)
2130
+ return -1;
2131
+
2132
+ // Special case - no round corner at all
2133
+ if (rad <= 1)
2134
+ return boxRGBA(renderer, x1, y1, x2, y2, r, g, b, a);
2135
+
2136
+ // Test for special cases of straight lines or single point
2137
+ if (x1 == x2) {
2138
+ if (y1 == y2)
2139
+ return (pixelRGBA(renderer, x1, y1, r, g, b, a));
2140
+ else
2141
+ return (vlineRGBA(renderer, x1, y1, y2, r, g, b, a));
2142
+ } else if (y1 == y2)
2143
+ return (hlineRGBA(renderer, x1, x2, y1, r, g, b, a));
2144
+
2145
+ // Swap x1, x2 and/or y1, y2 if required
2146
+ if (x1 > x2) {
2147
+ Sint16 tmp = x1;
2148
+ x1 = x2;
2149
+ x2 = tmp;
2150
+ }
2151
+ if (y1 > y2) {
2152
+ Sint16 tmp = y1;
2153
+ y1 = y2;
2154
+ y2 = tmp;
2155
+ }
2156
+
2157
+ // Calculate width & height
2158
+ w = x2 - x1;
2159
+ h = y2 - y1;
2160
+
2161
+ // Maybe adjust radius
2162
+ if (rad + rad > w)
2163
+ rad = w / 2;
2164
+ if (rad + rad > h)
2165
+ rad = h / 2;
2166
+
2167
+ //Calculate the four centers
2168
+ cx1 = x1 + rad;
2169
+ cy1 = y1 + rad;
2170
+ cx2 = x2 - rad;
2171
+ cy2 = y2 - rad;
2172
+
2173
+ // Draw corners and north/south wedge
2174
+ // Theory: two calls through the midpoint circle algorithm will gives bounds
2175
+ // for a drawn horizontal line.
2176
+ //
2177
+ // at end of while loop: outline is (x0 +/- x, y0 +/- y) and (x0 +/- y, y0 +/- x)
2178
+ // 8 octants in total, draw between two each line, therefore 4 calls
2179
+ {
2180
+ int f = 1 - rad;
2181
+ int ddF_x = 0;
2182
+ int ddF_y = -2 * rad;
2183
+ int x = 0;
2184
+ int y = rad;
2185
+
2186
+ while(x < y) {
2187
+ if (f >= 0) {
2188
+ if (x < y - 1) {
2189
+ result |= hlineRGBA(renderer, cx1 - x, cx2 + x, cy1 - y, r, g, b, a);
2190
+ result |= hlineRGBA(renderer, cx1 - x, cx2 + x, cy2 + y - 1, r, g, b, a);
2191
+ }
2192
+ y--;
2193
+ ddF_y += 2;
2194
+ f += ddF_y;
2195
+ }
2196
+
2197
+ x++;
2198
+ ddF_x += 2;
2199
+ f += ddF_x + 1;
2200
+ result |= hlineRGBA(renderer, cx1 - y, cx2 + y, cy1 - x, r, g, b, a);
2201
+ result |= hlineRGBA(renderer, cx1 - y, cx2 + y, cy2 + x - 1, r, g, b, a);
2202
+ }
2203
+ }
2204
+
2205
+
2206
+ // east/west and center wedge
2207
+ if (x2 - x1 - rad - rad > 0 && x2 - x1 - rad - rad > 0) { //TODO: check math
2208
+ struct SDL_Rect rect = {x1, y1 + rad, x2 - x1, y2 - y1 - rad - rad};
2209
+ result |= SDL_RenderFillRect(renderer, &rect);
2210
+ }
2211
+
2212
+ return result;
2213
+ }
2214
+
2215
+ // Draw a cubic bezier curve with alpha blending.
2216
+ 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)
2217
+ {
2218
+ SDL_BlendMode mode;
2219
+ Uint8 r, g, b, a;
2220
+ Sint16 vx[] = { NUM2INT(x1), NUM2INT(x2), NUM2INT(x3), NUM2INT(x4) };
2221
+ Sint16 vy[] = { NUM2INT(y1), NUM2INT(y2), NUM2INT(y3), NUM2INT(y4) };
2222
+ HANDLE_ERROR(SDL_GetRenderDrawBlendMode(Get_SDL_Renderer(self), &mode));
2223
+ HANDLE_ERROR(SDL_GetRenderDrawColor(Get_SDL_Renderer(self), &r, &g, &b, &a));
2224
+ HANDLE_ERROR(bezierRGBA(Get_SDL_Renderer(self), vx, vy, 4, NUM2INT(resolution), r, g, b, a));
2225
+ HANDLE_ERROR(SDL_SetRenderDrawBlendMode(Get_SDL_Renderer(self), mode));
2226
+ return Qnil;
2227
+ }
2228
+
2229
+ /*
2230
+ * Document-class: SDL2::Renderer::Info
2231
+ *
2232
+ * This class contains information of a rendering context.
2233
+ *
2234
+ * @!attribute [r] name
2235
+ * @return [String] the name of the renderer
2236
+ *
2237
+ * @!attribute [r] texture_formats
2238
+ * @return [Array<SDL2::PixelFormat>] available texture formats
2239
+ *
2240
+ * @!attribute [r] max_texture_width
2241
+ * @return [Integer] maximum texture width
2242
+ *
2243
+ * @!attribute [r] max_texture_height
2244
+ * @return [Integer] maximum texture height
2245
+ */
2246
+
2247
+ /*
2248
+ * Document-module: SDL2::Renderer::Flags
2249
+ *
2250
+ * The OR'd bits of the constants of this module represents
2251
+ * the state of renderers.
2252
+ *
2253
+ * You can use this flag
2254
+ * {SDL2::Window#create_renderer when you create a new renderer}.
2255
+ * No flags(==0) gives priority to available ACCELERATED renderers.
2256
+ */
2257
+
2258
+ /*
2259
+ * Document-module: SDL2::BlendMode
2260
+ *
2261
+ * Constants represent blend mode for {SDL2::Renderer.copy} and
2262
+ * drawing operations.
2263
+ *
2264
+ * You can change the blending mode using
2265
+ * {SDL2::Renderer#draw_blend_mode=} and {SDL2::Texture#blend_mode=}.
2266
+ *
2267
+ * In the backend of SDL, opengl or direct3d blending
2268
+ * mechanism is used for blending operations.
2269
+ */
2270
+
2271
+ /*
2272
+ * Document-class: SDL2::Texture
2273
+ *
2274
+ * This class represents the texture associated with a renderer.
2275
+ *
2276
+ *
2277
+ * @!method destroy?
2278
+ * Return true if the texture is {#destroy destroyed}.
2279
+ */
2280
+
2281
+ /*
2282
+ * Destroy the texture and deallocate memory.
2283
+ *
2284
+ * @see #destroy?
2285
+ */
2286
+ static VALUE Texture_destroy(VALUE self)
2287
+ {
2288
+ Texture_destroy_internal(Get_Texture(self));
2289
+ return Qnil;
2290
+ }
2291
+
2292
+ /*
2293
+ * Get the blending mode of the texture.
2294
+ *
2295
+ * @return [Integer] blend mode
2296
+ *
2297
+ * @see #blend_mode=
2298
+ */
2299
+ static VALUE Texture_blend_mode(VALUE self)
2300
+ {
2301
+ SDL_BlendMode mode;
2302
+ HANDLE_ERROR(SDL_GetTextureBlendMode(Get_SDL_Texture(self), &mode));
2303
+ return INT2FIX(mode);
2304
+ }
2305
+
2306
+ /*
2307
+ * @overload blend_mode=(mode)
2308
+ * Set the blending model of the texture.
2309
+ *
2310
+ * @param mode [Integer] blending mode
2311
+ * @return [mode]
2312
+ *
2313
+ * @see #blend_mode
2314
+ */
2315
+ static VALUE Texture_set_blend_mode(VALUE self, VALUE mode)
2316
+ {
2317
+ HANDLE_ERROR(SDL_SetTextureBlendMode(Get_SDL_Texture(self), NUM2INT(mode)));
2318
+ return mode;
2319
+ }
2320
+
2321
+ /*
2322
+ * Get an additional alpha value used in render copy operations.
2323
+ *
2324
+ * @return [Integer] the current alpha value
2325
+ *
2326
+ * @see #alpha_mod=
2327
+ */
2328
+ static VALUE Texture_alpha_mod(VALUE self)
2329
+ {
2330
+ Uint8 alpha;
2331
+ HANDLE_ERROR(SDL_GetTextureAlphaMod(Get_SDL_Texture(self), &alpha));
2332
+ return INT2FIX(alpha);
2333
+ }
2334
+
2335
+ /*
2336
+ * @overload alpha_mod=(alpha)
2337
+ * Set an additional alpha value used in render copy operations.
2338
+ *
2339
+ * @param alpha [Integer] the alpha value multiplied into copy operation,
2340
+ * from 0 to 255
2341
+ * @return [alpha]
2342
+ *
2343
+ * @see #alpha_mod
2344
+ */
2345
+ static VALUE Texture_set_alpha_mod(VALUE self, VALUE alpha)
2346
+ {
2347
+ HANDLE_ERROR(SDL_SetTextureAlphaMod(Get_SDL_Texture(self), NUM2UCHAR(alpha)));
2348
+ return alpha;
2349
+ }
2350
+
2351
+ /*
2352
+ * Get an additional color value used in render copy operations.
2353
+ *
2354
+ * @return [Integer] the current red, green, and blue
2355
+ * color value.
2356
+ */
2357
+ static VALUE Texture_color_mod(VALUE self)
2358
+ {
2359
+ Uint8 r, g, b;
2360
+ HANDLE_ERROR(SDL_GetTextureColorMod(Get_SDL_Texture(self), &r, &g, &b));
2361
+ return rb_ary_new3(3, INT2FIX(r), INT2FIX(g), INT2FIX(b));
2362
+ }
2363
+
2364
+ /*
2365
+ * @overload color_mod=(rgb)
2366
+ * Set an additional color value used in render copy operations.
2367
+ *
2368
+ * @param rgb [Integer] the red, green, and blue
2369
+ * color value multiplied into copy operations.
2370
+ * @return [rgb]
2371
+ */
2372
+ static VALUE Texture_set_color_mod(VALUE self, VALUE rgb)
2373
+ {
2374
+ SDL_Color color = Color_to_SDL_Color(rgb);
2375
+ HANDLE_ERROR(SDL_SetTextureColorMod(Get_SDL_Texture(self),
2376
+ color.r, color.g, color.b));
2377
+ return rgb;
2378
+ }
2379
+
2380
+ /*
2381
+ * Get the format of the texture.
2382
+ *
2383
+ * @return [SDL2::PixelFormat]
2384
+ */
2385
+ static VALUE Texture_format(VALUE self)
2386
+ {
2387
+ Uint32 format;
2388
+ HANDLE_ERROR(SDL_QueryTexture(Get_SDL_Texture(self), &format, NULL, NULL, NULL));
2389
+ return PixelFormat_new(format);
2390
+ }
2391
+
2392
+ /*
2393
+ * Get the access pattern allowed for the texture.
2394
+ *
2395
+ * The return value is one of the following:
2396
+ *
2397
+ * * {SDL2::Texture::ACCESS_STATIC}
2398
+ * * {SDL2::Texture::ACCESS_STREAMING}
2399
+ * * {SDL2::Texture::ACCESS_TARGET}
2400
+ *
2401
+ * @return [Integer]
2402
+ *
2403
+ * @see SDL2::Renderer#create_texture
2404
+ */
2405
+ static VALUE Texture_access_pattern(VALUE self)
2406
+ {
2407
+ int access;
2408
+ HANDLE_ERROR(SDL_QueryTexture(Get_SDL_Texture(self), NULL, &access, NULL, NULL));
2409
+ return INT2FIX(access);
2410
+ }
2411
+
2412
+ /*
2413
+ * Get the width of the texture.
2414
+ *
2415
+ * @return [Integer]
2416
+ *
2417
+ * @see SDL2::Renderer#create_texture
2418
+ */
2419
+ static VALUE Texture_w(VALUE self)
2420
+ {
2421
+ int w;
2422
+ HANDLE_ERROR(SDL_QueryTexture(Get_SDL_Texture(self), NULL, NULL, &w, NULL));
2423
+ return INT2FIX(w);
2424
+ }
2425
+
2426
+ /*
2427
+ * Get the height of the texture.
2428
+ *
2429
+ * @return [Integer]
2430
+ *
2431
+ * @see SDL2::Renderer#create_texture
2432
+ */
2433
+ static VALUE Texture_h(VALUE self)
2434
+ {
2435
+ int h;
2436
+ HANDLE_ERROR(SDL_QueryTexture(Get_SDL_Texture(self), NULL, NULL, NULL, &h));
2437
+ return INT2FIX(h);
2438
+ }
2439
+
2440
+ /* @return [String] inspection string */
2441
+ static VALUE Texture_inspect(VALUE self)
2442
+ {
2443
+ Texture* t = Get_Texture(self);
2444
+ Uint32 format;
2445
+ int access, w, h;
2446
+ if (!t->texture)
2447
+ return rb_sprintf("<%s: (destroyed)>", rb_obj_classname(self));
2448
+
2449
+ HANDLE_ERROR(SDL_QueryTexture(t->texture, &format, &access, &w, &h));
2450
+ return rb_sprintf("<%s:%p format=%s access=%d w=%d h=%d>",
2451
+ rb_obj_classname(self), (void*)self, SDL_GetPixelFormatName(format),
2452
+ access, w, h);
2453
+ }
2454
+
2455
+ /* @return [Hash<String=>Object>] (GC) debugging information */
2456
+ static VALUE Texture_debug_info(VALUE self)
2457
+ {
2458
+ Texture* t = Get_Texture(self);
2459
+ VALUE info = rb_hash_new();
2460
+ rb_hash_aset(info, rb_str_new2("destroy?"), INT2BOOL(t->texture == NULL));
2461
+ rb_hash_aset(info, rb_str_new2("refcount"), INT2NUM(t->refcount));
2462
+ return info;
2463
+ }
2464
+
2465
+ /*
2466
+ * Document-class: SDL2::Surface
2467
+ *
2468
+ * This class represents bitmap images (collection of pixels).
2469
+ *
2470
+ * Normally in SDL2, this class is not used for drawing a image
2471
+ * on a window. {SDL2::Texture} is used for the purpose.
2472
+ *
2473
+ * Mainly this class is for compatibility with SDL1, but the class
2474
+ * is useful for simple pixel manipulation.
2475
+ * For example, {SDL2::TTF} can create only surfaces, not textures.
2476
+ * You can convert a surface to texture with
2477
+ * {SDL2::Renderer#create_texture_from}.
2478
+ *
2479
+ * @!method destroy?
2480
+ * Return true if the surface is {#destroy destroyed}.
2481
+ *
2482
+ */
2483
+
2484
+ /*
2485
+ * @overload load_bmp(path)
2486
+ * Load a surface from bmp file.
2487
+ *
2488
+ * @param path [String] bmp file path
2489
+ * @return [SDL2::Surface]
2490
+ * @raise [SDL2::Error] raised when an error occurs.
2491
+ * For example, if there is no file or the file file
2492
+ * format is not Windows BMP.
2493
+ *
2494
+ */
2495
+ static VALUE Surface_s_load_bmp(VALUE self, VALUE fname)
2496
+ {
2497
+ SDL_Surface* surface = SDL_LoadBMP(StringValueCStr(fname));
2498
+
2499
+ if (surface == NULL)
2500
+ HANDLE_ERROR(-1);
2501
+
2502
+ return Surface_new(surface);
2503
+ }
2504
+
2505
+ /*
2506
+ * @overload from_string(string, width, heigth, depth, pitch=nil, rmask=nil, gmask=nil, bmask=nil, amask=nil)
2507
+ *
2508
+ * Create a RGB surface from pixel data as String object.
2509
+ *
2510
+ * If rmask, gmask, bmask are omitted, the default masks are used.
2511
+ * If amask is omitted, alpha mask is considered to be zero.
2512
+ *
2513
+ * @param string [String] the pixel data
2514
+ * @param width [Integer] the width of the creating surface
2515
+ * @param height [Integer] the height of the creating surface
2516
+ * @param depth [Integer] the color depth (in bits) of the creating surface
2517
+ * @param pitch [Integer] the number of bytes of one scanline
2518
+ * if this argument is omitted, width*depth/8 is used.
2519
+ * @param rmask [Integer] the red mask of a pixel
2520
+ * @param gmask [Integer] the green mask of a pixel
2521
+ * @param bmask [Integer] the blue mask of a pixel
2522
+ * @param amask [Integer] the alpha mask of a pixel
2523
+ * @return [SDL2::Surface] a new surface
2524
+ * @raise [SDL2::Error] raised when an error occurs in C SDL library
2525
+ *
2526
+ */
2527
+ static VALUE Surface_s_from_string(int argc, VALUE* argv, VALUE self)
2528
+ {
2529
+ VALUE string, width, height, depth, pitch, Rmask, Gmask, Bmask, Amask;
2530
+ int w, h, d, p, r, g, b, a;
2531
+ SDL_Surface* surface;
2532
+ void* pixels;
2533
+ Surface* s;
2534
+
2535
+ rb_scan_args(argc, argv, "45", &string, &width, &height, &depth,
2536
+ &pitch, &Rmask, &Gmask, &Bmask, &Amask);
2537
+ StringValue(string);
2538
+ w = NUM2INT(width);
2539
+ h = NUM2INT(height);
2540
+ d = NUM2INT(depth);
2541
+ p = (pitch == Qnil) ? d*w/8 : NUM2INT(pitch);
2542
+ r = (Rmask == Qnil) ? 0 : NUM2UINT(Rmask);
2543
+ g = (Gmask == Qnil) ? 0 : NUM2UINT(Gmask);
2544
+ b = (Bmask == Qnil) ? 0 : NUM2UINT(Bmask);
2545
+ a = (Amask == Qnil) ? 0 : NUM2UINT(Amask);
2546
+
2547
+ if (RSTRING_LEN(string) < p*h)
2548
+ rb_raise(rb_eArgError, "String too short");
2549
+ if (p < d*w/8 )
2550
+ rb_raise(rb_eArgError, "pitch too small");
2551
+
2552
+ pixels = ruby_xmalloc(RSTRING_LEN(string));
2553
+ memcpy(pixels, RSTRING_PTR(string), RSTRING_LEN(string));
2554
+ surface = SDL_CreateRGBSurfaceFrom(pixels, w, h, d, p, r, g, b, a);
2555
+ if (!surface)
2556
+ SDL_ERROR();
2557
+
2558
+ RB_GC_GUARD(string);
2559
+
2560
+ s = ALLOC(Surface);
2561
+ s->surface = surface;
2562
+ s->need_to_free_pixels = 1;
2563
+ return Data_Wrap_Struct(cSurface, 0, Surface_free, s);
2564
+ }
2565
+
2566
+ /*
2567
+ * Destroy the surface and deallocate the memory for pixels.
2568
+ *
2569
+ * @return [nil]
2570
+ * @see #destroy?
2571
+ */
2572
+ static VALUE Surface_destroy(VALUE self)
2573
+ {
2574
+ Surface* s = Get_Surface(self);
2575
+ if (s->need_to_free_pixels)
2576
+ free(s->surface->pixels);
2577
+ s->need_to_free_pixels = 0;
2578
+ if (s->surface)
2579
+ SDL_FreeSurface(s->surface);
2580
+ s->surface = NULL;
2581
+ return Qnil;
2582
+ }
2583
+
2584
+ /*
2585
+ * Get the blending mode of the surface used for blit operations.
2586
+ *
2587
+ * @return [Integer]
2588
+ * @see #blend_mode=
2589
+ */
2590
+ static VALUE Surface_blend_mode(VALUE self)
2591
+ {
2592
+ SDL_BlendMode mode;
2593
+ HANDLE_ERROR(SDL_GetSurfaceBlendMode(Get_SDL_Surface(self), &mode));
2594
+ return INT2FIX(mode);
2595
+ }
2596
+
2597
+ /*
2598
+ * @overload blend_mode=(mode)
2599
+ * Set the blending mode of the surface used for blit operations.
2600
+ *
2601
+ * @param mode [Integer] the blending mode
2602
+ * @return [mode]
2603
+ * @see #blend_mode
2604
+ */
2605
+ static VALUE Surface_set_blend_mode(VALUE self, VALUE mode)
2606
+ {
2607
+ HANDLE_ERROR(SDL_SetSurfaceBlendMode(Get_SDL_Surface(self), NUM2INT(mode)));
2608
+ return mode;
2609
+ }
2610
+
2611
+ /*
2612
+ * Return true if the surface need to lock when you get access to the
2613
+ * pixel data of the surface.
2614
+ *
2615
+ * @see #lock
2616
+ */
2617
+ static VALUE Surface_must_lock_p(VALUE self)
2618
+ {
2619
+ return INT2BOOL(SDL_MUSTLOCK(Get_SDL_Surface(self)));
2620
+ }
2621
+
2622
+ /*
2623
+ * Lock the surface.
2624
+ *
2625
+ * @return [nil]
2626
+ *
2627
+ * @see #unlock
2628
+ * @see #must_lock?
2629
+ */
2630
+ static VALUE Surface_lock(VALUE self)
2631
+ {
2632
+ HANDLE_ERROR(SDL_LockSurface(Get_SDL_Surface(self)));
2633
+ return Qnil;
2634
+ }
2635
+
2636
+ /*
2637
+ * Unlock the surface.
2638
+ *
2639
+ * @return [nil]
2640
+ *
2641
+ * @see #lock
2642
+ */
2643
+ static VALUE Surface_unlock(VALUE self)
2644
+ {
2645
+ SDL_UnlockSurface(Get_SDL_Surface(self));
2646
+ return Qnil;
2647
+ }
2648
+
2649
+ /*
2650
+ * @overload pixel(x, y)
2651
+ * Get a pixel data at (**x**, **y**)
2652
+ *
2653
+ * @param x [Integer] the x coordinate
2654
+ * @param y [Integer] the y coordinate
2655
+ * @return [Integer] pixel data
2656
+ *
2657
+ * @see #pixel_color
2658
+ *
2659
+ */
2660
+ static VALUE Surface_pixel(VALUE self, VALUE x_coord, VALUE y_coord)
2661
+ {
2662
+ int x = NUM2INT(x_coord);
2663
+ int y = NUM2INT(y_coord);
2664
+ SDL_Surface* surface = Get_SDL_Surface(self);
2665
+ int offset;
2666
+ Uint32 pixel = 0;
2667
+ int i;
2668
+
2669
+ if (x < 0 || x >= surface->w || y < 0 || y >= surface->h)
2670
+ rb_raise(rb_eArgError, "(%d, %d) out of range for %dx%d",
2671
+ x, y, surface->w, surface->h);
2672
+ offset = surface->pitch * y + surface->format->BytesPerPixel * x;
2673
+ for (i=0; i<surface->format->BytesPerPixel; ++i) {
2674
+ pixel += *((Uint8*)surface->pixels + offset + i) << (8*i);
2675
+ }
2676
+
2677
+ return UINT2NUM(SDL_SwapLE32(pixel));
2678
+ }
2679
+
2680
+ /*
2681
+ * Get all pixel data of the surface as a string.
2682
+ *
2683
+ * @return [String]
2684
+ *
2685
+ */
2686
+ static VALUE Surface_pixels(VALUE self)
2687
+ {
2688
+ SDL_Surface* surface = Get_SDL_Surface(self);
2689
+ int size = surface->h * surface->pitch;
2690
+ return rb_str_new(surface->pixels, size);
2691
+ }
2692
+
2693
+ /*
2694
+ * Get the pitch (bytes per horizontal line) of the surface.
2695
+ *
2696
+ * @return [Integer]
2697
+ */
2698
+ static VALUE Surface_pitch(VALUE self)
2699
+ {
2700
+ return UINT2NUM(Get_SDL_Surface(self)->pitch);
2701
+ }
2702
+
2703
+ /*
2704
+ * Get bits per pixel of the surface.
2705
+ *
2706
+ * @return [Integer]
2707
+ */
2708
+ static VALUE Surface_bits_per_pixel(VALUE self)
2709
+ {
2710
+ return UCHAR2NUM(Get_SDL_Surface(self)->format->BitsPerPixel);
2711
+ }
2712
+
2713
+ /*
2714
+ * Get bytes per pixel of the surface.
2715
+ *
2716
+ * @return [Integer]
2717
+ */
2718
+ static VALUE Surface_bytes_per_pixel(VALUE self)
2719
+ {
2720
+ return UCHAR2NUM(Get_SDL_Surface(self)->format->BytesPerPixel);
2721
+ }
2722
+
2723
+ /*
2724
+ * @overload pixel_color(x, y)
2725
+ * Get the pixel color (r,g,b and a) at (**x**, **y**) of the surface.
2726
+ *
2727
+ * @param x [Integer] the x coordinate
2728
+ * @param y [Integer] the y coordinate
2729
+ * @return [[Integer, Integer, Integer, Integer]]
2730
+ * the red, green, blue, and alpha component of the specified pixel.
2731
+ *
2732
+ */
2733
+ static VALUE Surface_pixel_color(VALUE self, VALUE x, VALUE y)
2734
+ {
2735
+ Uint32 pixel = NUM2UINT(Surface_pixel(self, x, y));
2736
+ SDL_Surface* surface = Get_SDL_Surface(self);
2737
+ Uint8 r, g, b, a;
2738
+ SDL_GetRGBA(pixel, surface->format, &r, &g, &b, &a);
2739
+
2740
+ return rb_ary_new3(4, UCHAR2NUM(r), UCHAR2NUM(g), UCHAR2NUM(b), UCHAR2NUM(a));
2741
+ }
2742
+
2743
+ static Uint32 pixel_value(VALUE val, SDL_PixelFormat* format)
2744
+ {
2745
+ if (RTEST(rb_funcall(val, rb_intern("integer?"), 0, 0))) {
2746
+ return NUM2UINT(val);
2747
+ } else {
2748
+ long len;
2749
+ Uint8 r, g, b, a;
2750
+ Check_Type(val, T_ARRAY);
2751
+ len = RARRAY_LEN(val);
2752
+ if (len == 3 || len == 4) {
2753
+ r = NUM2UCHAR(rb_ary_entry(val, 0));
2754
+ g = NUM2UCHAR(rb_ary_entry(val, 1));
2755
+ b = NUM2UCHAR(rb_ary_entry(val, 2));
2756
+ if (len == 3)
2757
+ a = 255;
2758
+ else
2759
+ a = NUM2UCHAR(rb_ary_entry(val, 3));
2760
+ return SDL_MapRGBA(format, r, g, b, a);
2761
+ } else {
2762
+ rb_raise(rb_eArgError, "Wrong length of array (%ld for 3..4)", len);
2763
+ }
2764
+ }
2765
+ return 0;
2766
+ }
2767
+
2768
+ /*
2769
+ * Unset the color key of the surface.
2770
+ *
2771
+ * @return [nil]
2772
+ *
2773
+ * @see #color_key=
2774
+ */
2775
+ static VALUE Surface_unset_color_key(VALUE self)
2776
+ {
2777
+ HANDLE_ERROR(SDL_SetColorKey(Get_SDL_Surface(self), SDL_FALSE, 0));
2778
+ return Qnil;
2779
+ }
2780
+
2781
+ /*
2782
+ * @overload color_key=(key)
2783
+ * Set the color key of the surface
2784
+ *
2785
+ * @param key [Integer, Array<Integer>]
2786
+ * the color key, pixel value (see {#pixel}) or pixel color (array of
2787
+ * three or four integer elements).
2788
+ *
2789
+ * @return [key]
2790
+ *
2791
+ * @see #color_key
2792
+ * @see #unset_color_key
2793
+ */
2794
+ static VALUE Surface_set_color_key(VALUE self, VALUE key)
2795
+ {
2796
+ SDL_Surface* surface = Get_SDL_Surface(self);
2797
+ if (key == Qnil)
2798
+ return Surface_unset_color_key(self);
2799
+
2800
+ HANDLE_ERROR(SDL_SetColorKey(surface, SDL_TRUE, pixel_value(key, surface->format)));
2801
+
2802
+ return key;
2803
+ }
2804
+
2805
+ /*
2806
+ * Get the color key of the surface
2807
+ *
2808
+ * @return [Integer] the color key, as pixel value (see {#pixel})
2809
+ *
2810
+ * @see #color_key=
2811
+ * @see #unset_color_key
2812
+ */
2813
+ static VALUE Surface_color_key(VALUE self)
2814
+ {
2815
+ Uint32 key;
2816
+ if (SDL_GetColorKey(Get_SDL_Surface(self), &key) < 0)
2817
+ return Qnil;
2818
+ else
2819
+ return UINT2NUM(key);
2820
+ }
2821
+
2822
+ /*
2823
+ * Get the width of the surface.
2824
+ *
2825
+ * @return [Integer]
2826
+ */
2827
+ static VALUE Surface_w(VALUE self)
2828
+ {
2829
+ return INT2NUM(Get_SDL_Surface(self)->w);
2830
+ }
2831
+
2832
+ /*
2833
+ * Get the height of the surface.
2834
+ *
2835
+ * @return [Integer]
2836
+ */
2837
+ static VALUE Surface_h(VALUE self)
2838
+ {
2839
+ return INT2NUM(Get_SDL_Surface(self)->h);
2840
+ }
2841
+
2842
+ /*
2843
+ * @overload blit_to(dst, x, y)
2844
+ * Perform a fast blit to **dst** surface.
2845
+ *
2846
+ * @param dst [SDL2::Surface] the destination surface
2847
+ * @param x [Integer]
2848
+ * @param y [Integer]
2849
+ * Blits this surface onto the given destination surface at the given
2850
+ * coordinates.
2851
+ *
2852
+ * @return [self]
2853
+ */
2854
+ static VALUE Surface_blit_to(VALUE self, VALUE dst, VALUE x, VALUE y)
2855
+ {
2856
+ SDL_Surface *surface = Get_SDL_Surface(self);
2857
+ SDL_Rect rect;
2858
+
2859
+ rect.x = FIX2INT(x);
2860
+ rect.y = FIX2INT(y);
2861
+ rect.w = surface->w;
2862
+ rect.h = surface->h;
2863
+
2864
+ HANDLE_ERROR(SDL_BlitSurface(surface,
2865
+ NULL,
2866
+ Get_SDL_Surface(dst),
2867
+ &rect));
2868
+ return self;
2869
+ }
2870
+
2871
+
2872
+ /*
2873
+ * @overload fill_rect(rect, color)
2874
+ * Draw a filled rectangle using the given color.
2875
+ *
2876
+ * @param rect [SDL2::Rect] the drawing rectangle
2877
+ * @param color [Integer]
2878
+ *
2879
+ * @return [nil]
2880
+ */
2881
+ static VALUE Surface_fill_rect(VALUE self, VALUE rect, VALUE rgba)
2882
+ {
2883
+ /* Remove alpha channel */
2884
+ Uint32 color = NUM2UINT(rgba) >> 8;
2885
+ HANDLE_ERROR(SDL_FillRect(Get_SDL_Surface(self), Get_SDL_Rect_or_NULL(rect), color));
2886
+ return Qnil;
2887
+ }
2888
+
2889
+ /*
2890
+ * @overload blit(src, srcrect, dst, dstrect)
2891
+ * Perform a fast blit from **src** surface to **dst** surface.
2892
+ *
2893
+ * @param src [SDL2::Surface] the source surface
2894
+ * @param srcrect [SDL2::Rect,nil] the region in the source surface,
2895
+ * if nil is given, the whole source is used
2896
+ * @param dst [SDL2::Surface] the destination surface
2897
+ * @param dstrect [SDL2::Rect,nil] the region in the destination surface
2898
+ * if nil is given, the source image is copied to (0, 0) on
2899
+ * the destination surface.
2900
+ * **dstrect** is changed by this method to store the
2901
+ * actually copied region (since the surface has clipping functionality,
2902
+ * actually copied region may be different from given **dstrect**).
2903
+ * @return [nil]
2904
+ */
2905
+ static VALUE Surface_s_blit(VALUE self, VALUE src, VALUE srcrect, VALUE dst, VALUE dstrect)
2906
+ {
2907
+ HANDLE_ERROR(SDL_BlitSurface(Get_SDL_Surface(src),
2908
+ Get_SDL_Rect_or_NULL(srcrect),
2909
+ Get_SDL_Surface(dst),
2910
+ Get_SDL_Rect_or_NULL(dstrect)));
2911
+ return Qnil;
2912
+ }
2913
+
2914
+ /*
2915
+ * @overload blit_scaled(src, srcrect, dst, dstrect)
2916
+ * Perform a fast scaling blit from **src** surface to **dst** surface.
2917
+ *
2918
+ * @param src [SDL2::Surface] the source surface
2919
+ * @param srcrect [SDL2::Rect,nil] the region in the source surface,
2920
+ * if nil is given, the whole source is used
2921
+ * @param dst [SDL2::Surface] the destination surface
2922
+ * @param dstrect [SDL2::Rect,nil] the region in the destination surface
2923
+ * if nil is given, the source image is copied to (0, 0) on
2924
+ * the destination surface.
2925
+ * **dstrect** is changed by this method to store the
2926
+ * actually copied region (since the surface has clipping functionality,
2927
+ * actually copied region may be different from given **dstrect**).
2928
+ * @return [nil]
2929
+ */
2930
+ static VALUE Surface_s_blit_scaled(VALUE self, VALUE src, VALUE srcrect, VALUE dst, VALUE dstrect)
2931
+ {
2932
+ HANDLE_ERROR(SDL_BlitScaled(Get_SDL_Surface(src),
2933
+ Get_SDL_Rect_or_NULL(srcrect),
2934
+ Get_SDL_Surface(dst),
2935
+ Get_SDL_Rect_or_NULL(dstrect)));
2936
+ return Qnil;
2937
+ }
2938
+
2939
+ /*
2940
+ * Create an empty RGB surface.
2941
+ *
2942
+ * If rmask, gmask, bmask are omitted, the default masks are used.
2943
+ * If amask is omitted, alpha mask is considered to be zero.
2944
+ *
2945
+ * @overload new(width, height, depth)
2946
+ * @overload new(width, height, depth, amask)
2947
+ * @overload new(width, heigth, depth, rmask, gmask, bmask, amask)
2948
+ *
2949
+ * @param width [Integer] the width of the new surface
2950
+ * @param height [Integer] the height of the new surface
2951
+ * @param depth [Integer] the bit depth of the new surface
2952
+ * @param rmask [Integer] the red mask of a pixel
2953
+ * @param gmask [Integer] the green mask of a pixel
2954
+ * @param bmask [Integer] the blue mask of a pixel
2955
+ * @param amask [Integer] the alpha mask of a pixel
2956
+ *
2957
+ * @return [SDL2::Surface]
2958
+ */
2959
+ static VALUE Surface_s_new(int argc, VALUE* argv, VALUE self)
2960
+ {
2961
+ VALUE width, height, depth;
2962
+ Uint32 Rmask, Gmask, Bmask, Amask;
2963
+ SDL_Surface * surface;
2964
+
2965
+ if (argc == 3) {
2966
+ rb_scan_args(argc, argv, "30", &width, &height, &depth);
2967
+ Rmask = Gmask = Bmask = Amask = 0;
2968
+ } else if (argc == 7) {
2969
+ VALUE rm, gm, bm, am;
2970
+ rb_scan_args(argc, argv, "70", &width, &height, &depth, &rm, &gm, &bm, &am);
2971
+ Rmask = NUM2UINT(rm); Gmask = NUM2UINT(gm);
2972
+ Bmask = NUM2UINT(bm); Amask = NUM2UINT(am);
2973
+ } else {
2974
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 4 or 7)", argc);
2975
+ }
2976
+ surface = SDL_CreateRGBSurface(0, NUM2INT(width), NUM2INT(height), NUM2INT(depth),
2977
+ Rmask, Gmask, Bmask, Amask);
2978
+ if (!surface)
2979
+ SDL_ERROR();
2980
+
2981
+ return Surface_new(surface);
2982
+ }
2983
+
2984
+ #define FIELD_ACCESSOR(classname, typename, field) \
2985
+ static VALUE classname##_##field(VALUE self) \
2986
+ { \
2987
+ typename* r; Data_Get_Struct(self, typename, r); \
2988
+ return INT2NUM(r->field); \
2989
+ } \
2990
+ static VALUE classname##_set_##field(VALUE self, VALUE val) \
2991
+ { \
2992
+ typename* r; Data_Get_Struct(self, typename, r); \
2993
+ r->field = NUM2INT(val); return val; \
2994
+ }
2995
+
2996
+
2997
+ /* Document-class: SDL2::Rect
2998
+ *
2999
+ * This class represents a rectangle in SDL2.
3000
+ *
3001
+ * Any rectangle is represented by four attributes x, y, w, and h,
3002
+ * and these four attributes must be integer.
3003
+ *
3004
+ * @!attribute [rw] x
3005
+ * X coordinate of the left-top point of the rectangle
3006
+ * @return [Integer]
3007
+ *
3008
+ * @!attribute [rw] y
3009
+ * Y coordinate of the left-top point of the rectangle
3010
+ * @return [Integer]
3011
+ *
3012
+ * @!attribute [rw] w
3013
+ * Width of the rectangle
3014
+ * @return [Integer]
3015
+ *
3016
+ * @!attribute [rw] h
3017
+ * Height of the rectangle
3018
+ * @return [Integer]
3019
+ *
3020
+ * @!method self.[](*args)
3021
+ * Alias of new. See {#initialize}.
3022
+ * @return [SDL2::Rect]
3023
+ */
3024
+ static VALUE Rect_s_allocate(VALUE klass)
3025
+ {
3026
+ SDL_Rect* rect = ALLOC(SDL_Rect);
3027
+ rect->x = rect->y = rect->w = rect->h = 0;
3028
+
3029
+ return Data_Wrap_Struct(cRect, 0, free, rect);
3030
+ }
3031
+
3032
+ /*
3033
+ * Create a new SDL2::Rect object
3034
+ *
3035
+ * @return [SDL2::Rect]
3036
+ *
3037
+ * @overload initialize(x, y, w, h)
3038
+ * Create a new SDL2::Rect object
3039
+ *
3040
+ * @param x [Integer] X coordinate of the left-top point of the rectangle
3041
+ * @param y [Integer] Y coordinate of the left-top point of the rectangle
3042
+ * @param w [Integer] Width of the rectangle
3043
+ * @param h [Integer] Height of the rectangle
3044
+ *
3045
+ * @overload initialize
3046
+ * Create a new SDL2::Rect object whose x, w, w, and h are all
3047
+ * zero.
3048
+ */
3049
+ static VALUE Rect_initialize(int argc, VALUE* argv, VALUE self)
3050
+ {
3051
+ VALUE x, y, w, h;
3052
+ rb_scan_args(argc, argv, "04", &x, &y, &w, &h);
3053
+ if (argc == 0) {
3054
+ /* do nothing*/
3055
+ } else if (argc == 4) {
3056
+ SDL_Rect* rect;
3057
+ Data_Get_Struct(self, SDL_Rect, rect);
3058
+ rect->x = NUM2INT(x); rect->y = NUM2INT(y);
3059
+ rect->w = NUM2INT(w); rect->h = NUM2INT(h);
3060
+ } else {
3061
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 or 4)", argc);
3062
+ }
3063
+ return Qnil;
3064
+ }
3065
+
3066
+ /*
3067
+ * Inspection string for debug
3068
+ * @return [String]
3069
+ */
3070
+ static VALUE Rect_inspect(VALUE self)
3071
+ {
3072
+ SDL_Rect* rect = Get_SDL_Rect(self);
3073
+ return rb_sprintf("<SDL2::Rect: x=%d y=%d w=%d h=%d>",
3074
+ rect->x, rect->y, rect->w, rect->h);
3075
+ }
3076
+
3077
+ FIELD_ACCESSOR(Rect, SDL_Rect, x);
3078
+ FIELD_ACCESSOR(Rect, SDL_Rect, y);
3079
+ FIELD_ACCESSOR(Rect, SDL_Rect, w);
3080
+ FIELD_ACCESSOR(Rect, SDL_Rect, h);
3081
+
3082
+ /*
3083
+ * @overload intersection(other)
3084
+ * Returns the intersection rect of self and other.
3085
+ *
3086
+ * If there is no intersection, returns nil.
3087
+ *
3088
+ * @return [SDL2::Rect, nil]
3089
+ * @param [SDL2::Rect] other rectangle
3090
+ */
3091
+ static VALUE Rect_intersection(VALUE self, VALUE other)
3092
+ {
3093
+ VALUE result = Rect_s_allocate(cRect);
3094
+ if (SDL_IntersectRect(Get_SDL_Rect(self), Get_SDL_Rect(other), Get_SDL_Rect(result))) {
3095
+ return result;
3096
+ } else {
3097
+ return Qnil;
3098
+ }
3099
+ }
3100
+
3101
+ /*
3102
+ * @overload union(other)
3103
+ * Returns the minimal rect containing self and other
3104
+ *
3105
+ * @return [SDL2::Rect]
3106
+ * @param [SDL2::Rect] other rectangle
3107
+ */
3108
+ static VALUE Rect_union(VALUE self, VALUE other)
3109
+ {
3110
+ VALUE result = Rect_s_allocate(cRect);
3111
+ SDL_UnionRect(Get_SDL_Rect(self), Get_SDL_Rect(other), Get_SDL_Rect(result));
3112
+ return result;
3113
+ }
3114
+
3115
+ /*
3116
+ * Document-class: SDL2::Point
3117
+ *
3118
+ * This class represents a point in SDL library.
3119
+ * Some method requires this method.
3120
+ *
3121
+ * @!attribute [rw] x
3122
+ * X coordinate of the point.
3123
+ * @return [Integer]
3124
+ *
3125
+ * @!attribute [rw] y
3126
+ * Y coordinate of the point.
3127
+ * @return [Integer]
3128
+ */
3129
+ static VALUE Point_s_allocate(VALUE klass)
3130
+ {
3131
+ SDL_Point* point;
3132
+ return Data_Make_Struct(klass, SDL_Point, 0, free, point);
3133
+ }
3134
+
3135
+ /*
3136
+ * Create a new point object.
3137
+ *
3138
+ * @overload initialize(x, y)
3139
+ * @param x the x coordinate of the point
3140
+ * @param y the y coordinate of the point
3141
+ *
3142
+ * @overload initialize
3143
+ * x and y of the created point object are initialized by 0
3144
+ *
3145
+ * @return [SDL2::Point]
3146
+ *
3147
+ */
3148
+ static VALUE Point_initialize(int argc, VALUE* argv, VALUE self)
3149
+ {
3150
+ VALUE x, y;
3151
+ SDL_Point* point = Get_SDL_Point(self);
3152
+ rb_scan_args(argc, argv, "02", &x, &y);
3153
+ point->x = (x == Qnil) ? 0 : NUM2INT(x);
3154
+ point->y = (y == Qnil) ? 0 : NUM2INT(y);
3155
+ return Qnil;
3156
+ }
3157
+
3158
+ /*
3159
+ * Return inspection string.
3160
+ * @return [String]
3161
+ */
3162
+ static VALUE Point_inspect(VALUE self)
3163
+ {
3164
+ SDL_Point* point = Get_SDL_Point(self);
3165
+ return rb_sprintf("<SDL2::Point x=%d y=%d>", point->x, point->y);
3166
+ }
3167
+
3168
+ FIELD_ACCESSOR(Point, SDL_Point, x);
3169
+ FIELD_ACCESSOR(Point, SDL_Point, y);
3170
+
3171
+
3172
+ /*
3173
+ * Document-class: SDL2::PixelFormat
3174
+ *
3175
+ * This class represents pixel format of textures, windows, and displays.
3176
+ *
3177
+ * In C level, SDL use unsigned integers as pixel formats. This class
3178
+ * wraps these integers. You can get the integers from {#format}.
3179
+ *
3180
+ * @!attribute [r] format
3181
+ * An integer representing the pixel format.
3182
+ *
3183
+ * @return [Integer]
3184
+ */
3185
+
3186
+ /*
3187
+ * @overload initialize(format)
3188
+ *
3189
+ * Initialize pixel format from the given integer representing a fomrmat.
3190
+ *
3191
+ * @param format [Integer] an unsigned integer as a pixel formats
3192
+ */
3193
+ static VALUE PixelForamt_initialize(VALUE self, VALUE format)
3194
+ {
3195
+ rb_iv_set(self, "@format", format);
3196
+ return Qnil;
3197
+ }
3198
+
3199
+ /*
3200
+ * Get the type of the format.
3201
+ *
3202
+ * @return [Integer] One of the constants of {Type} module.
3203
+ */
3204
+ static VALUE PixelFormat_type(VALUE self)
3205
+ {
3206
+ return UINT2NUM(SDL_PIXELTYPE(NUM2UINT(rb_iv_get(self, "@format"))));
3207
+ }
3208
+
3209
+ /*
3210
+
3211
+ */
3212
+
3213
+ /*
3214
+ * Get the human readable name of the pixel format
3215
+ *
3216
+ * @return [String]
3217
+ */
3218
+ static VALUE PixelFormat_name(VALUE self)
3219
+ {
3220
+ return utf8str_new_cstr(SDL_GetPixelFormatName(NUM2UINT(rb_iv_get(self, "@format"))));
3221
+ };
3222
+
3223
+ /*
3224
+ * Get the ordering of channels or bits in the pixel format.
3225
+ *
3226
+ * @return [Integer] One of the constants of {BitmapOrder} module or {PackedOrder} module.
3227
+ */
3228
+ static VALUE PixelFormat_order(VALUE self)
3229
+ {
3230
+ return UINT2NUM(SDL_PIXELORDER(NUM2UINT(rb_iv_get(self, "@format"))));
3231
+ };
3232
+
3233
+ /*
3234
+ * Get the channel bit pattern of the pixel format.
3235
+ *
3236
+ * @return [Integer] One of the constants of {PackedLayout} module.
3237
+ */
3238
+ static VALUE PixelFormat_layout(VALUE self)
3239
+ {
3240
+ return UINT2NUM(SDL_PIXELLAYOUT(NUM2UINT(rb_iv_get(self, "@format"))));
3241
+ };
3242
+
3243
+ /*
3244
+ * Get the number of bits per pixel.
3245
+ *
3246
+ * @return [Integer]
3247
+ */
3248
+ static VALUE PixelFormat_bits_per_pixel(VALUE self)
3249
+ {
3250
+ return INT2NUM(SDL_BITSPERPIXEL(NUM2UINT(rb_iv_get(self, "@format"))));
3251
+ };
3252
+
3253
+ /*
3254
+ * Get the number of bytes per pixel.
3255
+ *
3256
+ * @return [Integer]
3257
+ */
3258
+ static VALUE PixelFormat_bytes_per_pixel(VALUE self)
3259
+ {
3260
+ return INT2NUM(SDL_BYTESPERPIXEL(NUM2UINT(rb_iv_get(self, "@format"))));
3261
+ };
3262
+
3263
+ /*
3264
+ * Return true if the pixel format have a palette.
3265
+ */
3266
+ static VALUE PixelFormat_indexed_p(VALUE self)
3267
+ {
3268
+ return INT2BOOL(SDL_ISPIXELFORMAT_INDEXED(NUM2UINT(rb_iv_get(self, "@format"))));
3269
+ };
3270
+
3271
+ /*
3272
+ * Return true if the pixel format have an alpha channel.
3273
+ */
3274
+ static VALUE PixelFormat_alpha_p(VALUE self)
3275
+ {
3276
+ return INT2BOOL(SDL_ISPIXELFORMAT_ALPHA(NUM2UINT(rb_iv_get(self, "@format"))));
3277
+ };
3278
+
3279
+ /*
3280
+ * Return true if the pixel format is not indexed, and not RGB(A),
3281
+ * for example, the pixel format is YUV.
3282
+ */
3283
+ static VALUE PixelFormat_fourcc_p(VALUE self)
3284
+ {
3285
+ return INT2BOOL(SDL_ISPIXELFORMAT_FOURCC(NUM2UINT(rb_iv_get(self, "@format"))));
3286
+ };
3287
+
3288
+ /*
3289
+ * @overload ==(other)
3290
+ * Return true if two pixel format is the same format.
3291
+ *
3292
+ * @return [Boolean]
3293
+ */
3294
+ static VALUE PixelFormat_eq(VALUE self, VALUE other)
3295
+ {
3296
+ if (!rb_obj_is_kind_of(other, cPixelFormat))
3297
+ return Qfalse;
3298
+
3299
+ return INT2BOOL(rb_iv_get(self, "@format") == rb_iv_get(other, "@format"));
3300
+ }
3301
+
3302
+ /* @return [String] inspection string */
3303
+ static VALUE PixelFormat_inspect(VALUE self)
3304
+ {
3305
+ Uint32 format = NUM2UINT(rb_iv_get(self, "@format"));
3306
+ return rb_sprintf("<%s: %s type=%d order=%d layout=%d"
3307
+ " bits=%d bytes=%d indexed=%s alpha=%s fourcc=%s>",
3308
+ rb_obj_classname(self),
3309
+ SDL_GetPixelFormatName(format),
3310
+ SDL_PIXELTYPE(format), SDL_PIXELORDER(format), SDL_PIXELLAYOUT(format),
3311
+ SDL_BITSPERPIXEL(format), SDL_BYTESPERPIXEL(format),
3312
+ INT2BOOLCSTR(SDL_ISPIXELFORMAT_INDEXED(format)),
3313
+ INT2BOOLCSTR(SDL_ISPIXELFORMAT_ALPHA(format)),
3314
+ INT2BOOLCSTR(SDL_ISPIXELFORMAT_FOURCC(format)));
3315
+ }
3316
+
3317
+ /*
3318
+ * Document-module: SDL2::ScreenSaver
3319
+ *
3320
+ * This module provides functions to disable and enable a screensaver.
3321
+ */
3322
+
3323
+ /*
3324
+ * Enable screensaver.
3325
+ *
3326
+ * @return [nil]
3327
+ * @see .disable
3328
+ * @see .enabled?
3329
+ */
3330
+ static VALUE ScreenSaver_enable(VALUE self)
3331
+ {
3332
+ SDL_EnableScreenSaver();
3333
+ return Qnil;
3334
+ }
3335
+
3336
+ /*
3337
+ * Disable screensaver.
3338
+ *
3339
+ * @return [nil]
3340
+ * @see .enable
3341
+ * @see .enabled?
3342
+ */
3343
+ static VALUE ScreenSaver_disable(VALUE self)
3344
+ {
3345
+ SDL_DisableScreenSaver();
3346
+ return Qnil;
3347
+ }
3348
+
3349
+ /*
3350
+ * Return true if the screensaver is enabled.
3351
+ *
3352
+ * @see .enable
3353
+ * @see .disable
3354
+ */
3355
+ static VALUE ScreenSaver_enabled_p(VALUE self)
3356
+ {
3357
+ return INT2BOOL(SDL_IsScreenSaverEnabled());
3358
+ }
3359
+
3360
+ /*
3361
+
3362
+ */
3363
+
3364
+ void rubysdl2_init_video(void)
3365
+ {
3366
+ rb_define_module_function(mSDL2, "video_drivers", SDL2_s_video_drivers, 0);
3367
+ rb_define_module_function(mSDL2, "current_video_driver", SDL2_s_current_video_driver, 0);
3368
+ rb_define_module_function(mSDL2, "video_init", SDL2_s_video_init, 1);
3369
+
3370
+ cWindow = rb_define_class_under(mSDL2, "Window", rb_cObject);
3371
+
3372
+ rb_undef_alloc_func(cWindow);
3373
+ rb_define_singleton_method(cWindow, "create", Window_s_create, 6);
3374
+ rb_define_singleton_method(cWindow, "all_windows", Window_s_all_windows, 0);
3375
+ rb_define_singleton_method(cWindow, "find_by_id", Window_s_find_by_id, 1);
3376
+ rb_define_method(cWindow, "destroy?", Window_destroy_p, 0);
3377
+ rb_define_method(cWindow, "destroy", Window_destroy, 0);
3378
+ rb_define_method(cWindow, "create_renderer", Window_create_renderer, 2);
3379
+ rb_define_method(cWindow, "renderer", Window_renderer, 0);
3380
+ rb_define_method(cWindow, "window_id", Window_window_id, 0);
3381
+ rb_define_method(cWindow, "inspect", Window_inspect, 0);
3382
+ rb_define_method(cWindow, "display_mode", Window_display_mode, 0);
3383
+ rb_define_method(cWindow, "display", Window_display, 0);
3384
+ rb_define_method(cWindow, "debug_info", Window_debug_info, 0);
3385
+ rb_define_method(cWindow, "brightness", Window_brightness, 0);
3386
+ rb_define_method(cWindow, "brightness=", Window_set_brightness, 1);
3387
+ rb_define_method(cWindow, "flags", Window_flags, 0);
3388
+ rb_define_method(cWindow, "gamma_ramp", Window_gamma_ramp, 0);
3389
+ rb_define_method(cWindow, "input_is_grabbed?", Window_input_is_grabbed_p, 0);
3390
+ rb_define_method(cWindow, "input_is_grabbed=", Window_set_input_is_grabbed, 1);
3391
+ rb_define_method(cWindow, "maximum_size", Window_maximum_size, 0);
3392
+ rb_define_method(cWindow, "maximum_size=", Window_set_maximum_size, 1);
3393
+ rb_define_method(cWindow, "minimum_size", Window_minimum_size, 0);
3394
+ rb_define_method(cWindow, "minimum_size=", Window_set_minimum_size, 1);
3395
+ rb_define_method(cWindow, "position", Window_position, 0);
3396
+ rb_define_method(cWindow, "position=", Window_set_position, 1);
3397
+ rb_define_method(cWindow, "size", Window_size, 0);
3398
+ rb_define_method(cWindow, "size=", Window_set_size, 1);
3399
+ rb_define_method(cWindow, "title", Window_title, 0);
3400
+ rb_define_method(cWindow, "title=", Window_set_title, 1);
3401
+ rb_define_method(cWindow, "bordered", Window_bordered, 0);
3402
+ rb_define_method(cWindow, "bordered=", Window_set_bordered, 1);
3403
+ rb_define_method(cWindow, "icon=", Window_set_icon, 1);
3404
+ rb_define_method(cWindow, "show", Window_show, 0);
3405
+ rb_define_method(cWindow, "hide", Window_hide, 0);
3406
+ rb_define_method(cWindow, "maximize", Window_maximize, 0);
3407
+ rb_define_method(cWindow, "minimize", Window_minimize, 0);
3408
+ rb_define_method(cWindow, "raise", Window_raise, 0);
3409
+ rb_define_method(cWindow, "restore", Window_restore, 0);
3410
+ rb_define_method(cWindow, "fullscreen_mode", Window_fullscreen_mode, 0);
3411
+ rb_define_method(cWindow, "fullscreen_mode=", Window_set_fullscreen_mode, 1);
3412
+ #if SDL_VERSION_ATLEAST(2,0,1)
3413
+ rb_define_method(cWindow, "gl_drawable_size", Window_gl_drawable_size, 0);
3414
+ #endif
3415
+ rb_define_method(cWindow, "gl_swap", Window_gl_swap, 0);
3416
+ rb_define_method(cWindow, "surface", Window_surface, 0);
3417
+ rb_define_method(cWindow, "update", Window_update, 0);
3418
+
3419
+ /* Indicate that you don't care what the window position is */
3420
+ rb_define_const(cWindow, "POS_CENTERED", INT2NUM(SDL_WINDOWPOS_CENTERED));
3421
+ /* Indicate that the window position should be centered */
3422
+ rb_define_const(cWindow, "POS_UNDEFINED", INT2NUM(SDL_WINDOWPOS_UNDEFINED));
3423
+
3424
+ mWindowFlags = rb_define_module_under(cWindow, "Flags");
3425
+ /* */
3426
+ /* fullscreen window */
3427
+ rb_define_const(mWindowFlags, "FULLSCREEN", UINT2NUM(SDL_WINDOW_FULLSCREEN));
3428
+ /* fullscreen window at the current desktop resolution */
3429
+ rb_define_const(mWindowFlags, "FULLSCREEN_DESKTOP", UINT2NUM(SDL_WINDOW_FULLSCREEN_DESKTOP));
3430
+ /* window usable with OpenGL context */
3431
+ rb_define_const(mWindowFlags, "OPENGL", UINT2NUM(SDL_WINDOW_OPENGL));
3432
+ /* window is visible */
3433
+ rb_define_const(mWindowFlags, "SHOWN", UINT2NUM(SDL_WINDOW_SHOWN));
3434
+ /* window is not visible */
3435
+ rb_define_const(mWindowFlags, "HIDDEN", UINT2NUM(SDL_WINDOW_HIDDEN));
3436
+ /* no window decoration */
3437
+ rb_define_const(mWindowFlags, "BORDERLESS", UINT2NUM(SDL_WINDOW_BORDERLESS));
3438
+ /* window is resizable */
3439
+ rb_define_const(mWindowFlags, "RESIZABLE", UINT2NUM(SDL_WINDOW_RESIZABLE));
3440
+ /* window is minimized */
3441
+ rb_define_const(mWindowFlags, "MINIMIZED", UINT2NUM(SDL_WINDOW_MINIMIZED));
3442
+ /* window is maximized */
3443
+ rb_define_const(mWindowFlags, "MAXIMIZED", UINT2NUM(SDL_WINDOW_MAXIMIZED));
3444
+ /* window has grabbed input focus */
3445
+ rb_define_const(mWindowFlags, "INPUT_GRABBED", UINT2NUM(SDL_WINDOW_INPUT_GRABBED));
3446
+ /* window has input focus */
3447
+ rb_define_const(mWindowFlags, "INPUT_FOCUS", UINT2NUM(SDL_WINDOW_INPUT_FOCUS));
3448
+ /* window has mouse focus */
3449
+ rb_define_const(mWindowFlags, "MOUSE_FOCUS", UINT2NUM(SDL_WINDOW_MOUSE_FOCUS));
3450
+ /* window is not created by SDL */
3451
+ rb_define_const(mWindowFlags, "FOREIGN", UINT2NUM(SDL_WINDOW_FOREIGN));
3452
+ #ifdef HAVE_CONST_SDL_WINDOW_ALLOW_HIGHDPI
3453
+ /* window should be created in high-DPI mode if supported (>= SDL 2.0.1)*/
3454
+ rb_define_const(mWindowFlags, "ALLOW_HIGHDPI", UINT2NUM(SDL_WINDOW_ALLOW_HIGHDPI));
3455
+ #endif
3456
+ #ifdef HAVE_CONST_SDL_WINDOW_MOSUE_CAPTURE
3457
+ /* window has mouse caputred (>= SDL 2.0.4) */
3458
+ rb_define_const(mWindowFlags, "MOUSE_CAPTURE", UINT2NUM(SDL_WINDOW_MOUSE_CAPTURE));
3459
+ #endif
3460
+
3461
+ cDisplay = rb_define_class_under(mSDL2, "Display", rb_cObject);
3462
+
3463
+ rb_define_module_function(cDisplay, "displays", Display_s_displays, 0);
3464
+ rb_define_attr(cDisplay, "index", 1, 0);
3465
+ rb_define_attr(cDisplay, "name", 1, 0);
3466
+ rb_define_method(cDisplay, "modes", Display_modes, 0);
3467
+ rb_define_method(cDisplay, "current_mode", Display_current_mode, 0);
3468
+ rb_define_method(cDisplay, "desktop_mode", Display_desktop_mode, 0);
3469
+ rb_define_method(cDisplay, "closest_mode", Display_closest_mode, 1);
3470
+ rb_define_method(cDisplay, "bounds", Display_bounds, 0);
3471
+
3472
+
3473
+ cDisplayMode = rb_define_class_under(cDisplay, "Mode", rb_cObject);
3474
+
3475
+ rb_define_alloc_func(cDisplayMode, DisplayMode_s_allocate);
3476
+ rb_define_method(cDisplayMode, "initialize", DisplayMode_initialize, 4);
3477
+ rb_define_method(cDisplayMode, "inspect", DisplayMode_inspect, 0);
3478
+ rb_define_method(cDisplayMode, "format", DisplayMode_format, 0);
3479
+ rb_define_method(cDisplayMode, "w", DisplayMode_w, 0);
3480
+ rb_define_method(cDisplayMode, "h", DisplayMode_h, 0);
3481
+ rb_define_method(cDisplayMode, "refresh_rate", DisplayMode_refresh_rate, 0);
3482
+
3483
+
3484
+ cRenderer = rb_define_class_under(mSDL2, "Renderer", rb_cObject);
3485
+
3486
+ rb_undef_alloc_func(cRenderer);
3487
+ rb_define_singleton_method(cRenderer, "drivers_info", Renderer_s_drivers_info, 0);
3488
+ rb_define_method(cRenderer, "destroy?", Renderer_destroy_p, 0);
3489
+ rb_define_method(cRenderer, "destroy", Renderer_destroy, 0);
3490
+ rb_define_method(cRenderer, "debug_info", Renderer_debug_info, 0);
3491
+ rb_define_method(cRenderer, "create_texture", Renderer_create_texture, 4);
3492
+ rb_define_method(cRenderer, "create_texture_from", Renderer_create_texture_from, 1);
3493
+ rb_define_method(cRenderer, "copy", Renderer_copy, 3);
3494
+ rb_define_method(cRenderer, "copy_ex", Renderer_copy_ex, 6);
3495
+ rb_define_method(cRenderer, "present", Renderer_present, 0);
3496
+ rb_define_method(cRenderer, "draw_color",Renderer_draw_color, 0);
3497
+ rb_define_method(cRenderer, "draw_color=",Renderer_set_draw_color, 1);
3498
+ rb_define_method(cRenderer, "clear", Renderer_clear, 0);
3499
+ rb_define_method(cRenderer, "draw_line",Renderer_draw_line, 4);
3500
+ rb_define_method(cRenderer, "draw_point",Renderer_draw_point, 2);
3501
+ rb_define_method(cRenderer, "draw_rect", Renderer_draw_rect, 1);
3502
+ rb_define_method(cRenderer, "fill_rect", Renderer_fill_rect, 1);
3503
+ rb_define_method(cRenderer, "draw_blend_mode", Renderer_draw_blend_mode, 0);
3504
+ rb_define_method(cRenderer, "draw_blend_mode=", Renderer_set_draw_blend_mode, 1);
3505
+ rb_define_method(cRenderer, "clip_rect", Renderer_clip_rect, 0);
3506
+ rb_define_method(cRenderer, "clip_rect=", Renderer_set_clip_rect, 1);
3507
+ #if SDL_VERSION_ATLEAST(2,0,4)
3508
+ rb_define_method(cRenderer, "clip_enabled?", Render_clip_enabled_p, 0);
3509
+ #endif
3510
+ rb_define_method(cRenderer, "logical_size", Renderer_logical_size, 0);
3511
+ rb_define_method(cRenderer, "logical_size=", Renderer_set_logical_size, 1);
3512
+ rb_define_method(cRenderer, "scale", Renderer_scale, 0);
3513
+ rb_define_method(cRenderer, "scale=", Renderer_set_scale, 1);
3514
+ rb_define_method(cRenderer, "viewport", Renderer_viewport, 0);
3515
+ rb_define_method(cRenderer, "viewport=", Renderer_set_viewport, 1);
3516
+ rb_define_method(cRenderer, "support_render_target?", Renderer_support_render_target_p, 0);
3517
+ rb_define_method(cRenderer, "output_size", Renderer_output_size, 0);
3518
+ rb_define_method(cRenderer, "render_target", Renderer_render_target, 0);
3519
+ rb_define_method(cRenderer, "render_target=", Renderer_set_render_target, 1);
3520
+ rb_define_method(cRenderer, "reset_render_target", Renderer_reset_render_target, 0);
3521
+
3522
+ rb_define_method(cRenderer, "info", Renderer_info, 0);
3523
+
3524
+ #ifdef HAVE_SDL2_GFXPRIMITIVES_H
3525
+ rb_define_method(cRenderer, "draw_line_aa", Renderer_draw_line_aa, 4);
3526
+ rb_define_method(cRenderer, "draw_line_thick", Renderer_draw_line_thick, 5);
3527
+ rb_define_method(cRenderer, "draw_triangle", Renderer_draw_triangle, 6);
3528
+ rb_define_method(cRenderer, "draw_triangle_aa", Renderer_draw_triangle_aa, 6);
3529
+ rb_define_method(cRenderer, "fill_triangle", Renderer_fill_triangle, 6);
3530
+ rb_define_method(cRenderer, "draw_polygon", Renderer_draw_polygon, 2);
3531
+ rb_define_method(cRenderer, "draw_polygon_aa", Renderer_draw_polygon_aa, 2);
3532
+ rb_define_method(cRenderer, "fill_polygon", Renderer_fill_polygon, 2);
3533
+ rb_define_method(cRenderer, "fill_polygon_textured", Renderer_fill_polygon_textured, 5);
3534
+ rb_define_method(cRenderer, "draw_arc", Renderer_draw_arc, 5);
3535
+ rb_define_method(cRenderer, "draw_ellipse", Renderer_draw_ellipse, 4);
3536
+ rb_define_method(cRenderer, "draw_ellipse_aa", Renderer_draw_ellipse_aa, 4);
3537
+ rb_define_method(cRenderer, "fill_ellipse", Renderer_fill_ellipse, 4);
3538
+ rb_define_method(cRenderer, "draw_pie", Renderer_draw_pie, 5);
3539
+ rb_define_method(cRenderer, "fill_pie", Renderer_fill_pie, 5);
3540
+ rb_define_method(cRenderer, "draw_rounded_rect", Renderer_draw_rounded_rect, 5);
3541
+ rb_define_method(cRenderer, "fill_rounded_rect", Renderer_fill_rounded_rect, 5);
3542
+ rb_define_method(cRenderer, "draw_quad_bezier", Renderer_draw_quad_bezier, 9);
3543
+ #endif
3544
+
3545
+ mRendererFlags = rb_define_module_under(cRenderer, "Flags");
3546
+
3547
+ /* */
3548
+ /* the renderer is a software fallback */
3549
+ rb_define_const(mRendererFlags, "SOFTWARE", UINT2NUM(SDL_RENDERER_SOFTWARE));
3550
+ /* the renderer uses hardware acceleration */
3551
+ rb_define_const(mRendererFlags, "ACCELERATED", UINT2NUM(SDL_RENDERER_ACCELERATED));
3552
+ #ifdef HAVE_CONST_SDL_RENDERER_PRESENTVSYNC
3553
+ /* present is synchronized with the refresh rate */
3554
+ rb_define_const(mRendererFlags, "PRESENTVSYNC", UINT2NUM(SDL_RENDERER_PRESENTVSYNC));
3555
+ #endif
3556
+ /* the renderer supports rendering to texture */
3557
+ rb_define_const(mRendererFlags, "TARGETTEXTURE", UINT2NUM(SDL_RENDERER_TARGETTEXTURE));
3558
+ /* */
3559
+ /* Do not flip, used in {Renderer#copy_ex} */
3560
+ rb_define_const(cRenderer, "FLIP_NONE", INT2FIX(SDL_FLIP_NONE));
3561
+ /* Flip horizontally, used in {Renderer#copy_ex} */
3562
+ rb_define_const(cRenderer, "FLIP_HORIZONTAL", INT2FIX(SDL_FLIP_HORIZONTAL));
3563
+ /* Flip vertically, used in {Renderer#copy_ex} */
3564
+ rb_define_const(cRenderer, "FLIP_VERTICAL", INT2FIX(SDL_FLIP_VERTICAL));
3565
+
3566
+ mBlendMode = rb_define_module_under(mSDL2, "BlendMode");
3567
+ /* */
3568
+ /* no blending (dstRGBA = srcRGBA) */
3569
+ rb_define_const(mBlendMode, "NONE", INT2FIX(SDL_BLENDMODE_NONE));
3570
+ /* alpha blending (dstRGB = (srcRGB * srcA) + (dstRGB * (1-srcA), dstA = srcA + (dstA * (1-srcA)))*/
3571
+ rb_define_const(mBlendMode, "BLEND", INT2FIX(SDL_BLENDMODE_BLEND));
3572
+ /* additive blending (dstRGB = (srcRGB * srcA) + dstRGB, dstA = dstA) */
3573
+ rb_define_const(mBlendMode, "ADD", INT2FIX(SDL_BLENDMODE_ADD));
3574
+ /* color modulate (multiplicative) (dstRGB = srcRGB * dstRGB, dstA = dstA) */
3575
+ rb_define_const(mBlendMode, "MOD", INT2FIX(SDL_BLENDMODE_MOD));
3576
+
3577
+ cTexture = rb_define_class_under(mSDL2, "Texture", rb_cObject);
3578
+
3579
+ rb_undef_alloc_func(cTexture);
3580
+ rb_define_method(cTexture, "destroy?", Texture_destroy_p, 0);
3581
+ rb_define_method(cTexture, "destroy", Texture_destroy, 0);
3582
+ rb_define_method(cTexture, "blend_mode", Texture_blend_mode, 0);
3583
+ rb_define_method(cTexture, "blend_mode=", Texture_set_blend_mode, 1);
3584
+ rb_define_method(cTexture, "color_mod", Texture_color_mod, 0);
3585
+ rb_define_method(cTexture, "color_mod=", Texture_set_color_mod, 1);
3586
+ rb_define_method(cTexture, "alpha_mod", Texture_alpha_mod, 0);
3587
+ rb_define_method(cTexture, "alpha_mod=", Texture_set_alpha_mod, 1);
3588
+ rb_define_method(cTexture, "format", Texture_format, 0);
3589
+ rb_define_method(cTexture, "access_pattern", Texture_access_pattern, 0);
3590
+ rb_define_method(cTexture, "w", Texture_w, 0);
3591
+ rb_define_method(cTexture, "h", Texture_h, 0);
3592
+ rb_define_method(cTexture, "inspect", Texture_inspect, 0);
3593
+ rb_define_method(cTexture, "debug_info", Texture_debug_info, 0);
3594
+ /* */
3595
+ /* texture access pattern - changes rarely, not lockable */
3596
+ rb_define_const(cTexture, "ACCESS_STATIC", INT2NUM(SDL_TEXTUREACCESS_STATIC));
3597
+ /* texture access pattern - changes frequently, lockable */
3598
+ rb_define_const(cTexture, "ACCESS_STREAMING", INT2NUM(SDL_TEXTUREACCESS_STREAMING));
3599
+ /* texture access pattern - can be used as a render target */
3600
+ rb_define_const(cTexture, "ACCESS_TARGET", INT2NUM(SDL_TEXTUREACCESS_TARGET));
3601
+
3602
+
3603
+ cSurface = rb_define_class_under(mSDL2, "Surface", rb_cObject);
3604
+
3605
+ rb_undef_alloc_func(cSurface);
3606
+ rb_define_singleton_method(cSurface, "load_bmp", Surface_s_load_bmp, 1);
3607
+ rb_define_singleton_method(cSurface, "blit", Surface_s_blit, 4);
3608
+ rb_define_singleton_method(cSurface, "blit_scaled", Surface_s_blit_scaled, 4);
3609
+ rb_define_singleton_method(cSurface, "new", Surface_s_new, -1);
3610
+ rb_define_singleton_method(cSurface, "from_string", Surface_s_from_string, -1);
3611
+ rb_define_method(cSurface, "destroy?", Surface_destroy_p, 0);
3612
+ rb_define_method(cSurface, "destroy", Surface_destroy, 0);
3613
+ rb_define_method(cSurface, "blend_mode", Surface_blend_mode, 0);
3614
+ rb_define_method(cSurface, "blend_mode=", Surface_set_blend_mode, 1);
3615
+ rb_define_method(cSurface, "must_lock?", Surface_must_lock_p, 0);
3616
+ rb_define_method(cSurface, "lock", Surface_lock, 0);
3617
+ rb_define_method(cSurface, "unlock", Surface_unlock, 0);
3618
+ rb_define_method(cSurface, "w", Surface_w, 0);
3619
+ rb_define_method(cSurface, "h", Surface_h, 0);
3620
+ rb_define_method(cSurface, "pixel", Surface_pixel, 2);
3621
+ rb_define_method(cSurface, "pixel_color", Surface_pixel_color, 2);
3622
+ rb_define_method(cSurface, "color_key", Surface_color_key, 0);
3623
+ rb_define_method(cSurface, "color_key=", Surface_set_color_key, 1);
3624
+ rb_define_method(cSurface, "unset_color_key", Surface_unset_color_key, 0);
3625
+ rb_define_method(cSurface, "pixels", Surface_pixels, 0);
3626
+ rb_define_method(cSurface, "pitch", Surface_pitch, 0);
3627
+ rb_define_method(cSurface, "bits_per_pixel", Surface_bits_per_pixel, 0);
3628
+ rb_define_method(cSurface, "bytes_per_pixel", Surface_bytes_per_pixel, 0);
3629
+ rb_define_method(cSurface, "blit_to", Surface_blit_to, 3);
3630
+ rb_define_method(cSurface, "fill_rect", Surface_fill_rect, 2);
3631
+
3632
+ cRect = rb_define_class_under(mSDL2, "Rect", rb_cObject);
3633
+
3634
+ rb_define_alloc_func(cRect, Rect_s_allocate);
3635
+ rb_define_method(cRect, "initialize", Rect_initialize, -1);
3636
+ rb_define_alias(rb_singleton_class(cRect), "[]", "new");
3637
+ rb_define_method(cRect, "inspect", Rect_inspect, 0);
3638
+ rb_define_method(cRect, "x", Rect_x, 0);
3639
+ rb_define_method(cRect, "x=", Rect_set_x, 1);
3640
+ rb_define_method(cRect, "y", Rect_y, 0);
3641
+ rb_define_method(cRect, "y=", Rect_set_y, 1);
3642
+ rb_define_method(cRect, "w", Rect_w, 0);
3643
+ rb_define_method(cRect, "w=", Rect_set_w, 1);
3644
+ rb_define_method(cRect, "h", Rect_h, 0);
3645
+ rb_define_method(cRect, "h=", Rect_set_h, 1);
3646
+ rb_define_method(cRect, "union", Rect_union, 1);
3647
+ rb_define_method(cRect, "intersection", Rect_intersection, 1);
3648
+
3649
+ cPoint = rb_define_class_under(mSDL2, "Point", rb_cObject);
3650
+
3651
+ rb_define_alloc_func(cPoint, Point_s_allocate);
3652
+ rb_define_method(cPoint, "initialize", Point_initialize, -1);
3653
+ rb_define_alias(rb_singleton_class(cPoint), "[]", "new");
3654
+ rb_define_method(cPoint, "inspect", Point_inspect, 0);
3655
+ rb_define_method(cPoint, "x", Point_x, 0);
3656
+ rb_define_method(cPoint, "x=", Point_set_x, 1);
3657
+ rb_define_method(cPoint, "y", Point_y, 0);
3658
+ rb_define_method(cPoint, "y=", Point_set_y, 1);
3659
+
3660
+
3661
+ cRendererInfo = rb_define_class_under(cRenderer, "Info", rb_cObject);
3662
+ define_attr_readers(cRendererInfo, "name", "flags", "texture_formats",
3663
+ "max_texture_width", "max_texture_height", NULL);
3664
+
3665
+
3666
+ cPixelFormat = rb_define_class_under(mSDL2, "PixelFormat", rb_cObject);
3667
+
3668
+ rb_define_method(cPixelFormat, "initialize", PixelForamt_initialize, 1);
3669
+ rb_define_attr(cPixelFormat, "format", 1, 0);
3670
+ rb_define_method(cPixelFormat, "name", PixelFormat_name, 0);
3671
+ rb_define_method(cPixelFormat, "inspect", PixelFormat_inspect, 0);
3672
+ rb_define_method(cPixelFormat, "type", PixelFormat_type, 0);
3673
+ rb_define_method(cPixelFormat, "order", PixelFormat_order, 0);
3674
+ rb_define_method(cPixelFormat, "layout", PixelFormat_layout, 0);
3675
+ rb_define_method(cPixelFormat, "bits_per_pixel", PixelFormat_bits_per_pixel, 0);
3676
+ rb_define_alias(cPixelFormat, "bpp", "bits_per_pixel");
3677
+ rb_define_method(cPixelFormat, "bytes_per_pixel", PixelFormat_bytes_per_pixel, 0);
3678
+ rb_define_method(cPixelFormat, "indexed?", PixelFormat_indexed_p, 0);
3679
+ rb_define_method(cPixelFormat, "alpha?", PixelFormat_alpha_p, 0);
3680
+ rb_define_method(cPixelFormat, "fourcc?", PixelFormat_fourcc_p, 0);
3681
+ rb_define_method(cPixelFormat, "==", PixelFormat_eq, 1);
3682
+
3683
+ mPixelType = rb_define_module_under(cPixelFormat, "Type");
3684
+ /* */
3685
+ rb_define_const(mPixelType, "UNKNOWN", UINT2NUM(SDL_PIXELTYPE_UNKNOWN));
3686
+ rb_define_const(mPixelType, "INDEX1", UINT2NUM(SDL_PIXELTYPE_INDEX1));
3687
+ rb_define_const(mPixelType, "INDEX4", UINT2NUM(SDL_PIXELTYPE_INDEX4));
3688
+ rb_define_const(mPixelType, "INDEX8", UINT2NUM(SDL_PIXELTYPE_INDEX8));
3689
+ rb_define_const(mPixelType, "PACKED8", UINT2NUM(SDL_PIXELTYPE_PACKED8));
3690
+ rb_define_const(mPixelType, "PACKED16", UINT2NUM(SDL_PIXELTYPE_PACKED16));
3691
+ rb_define_const(mPixelType, "PACKED32", UINT2NUM(SDL_PIXELTYPE_PACKED32));
3692
+ rb_define_const(mPixelType, "ARRAYU8", UINT2NUM(SDL_PIXELTYPE_ARRAYU8));
3693
+ rb_define_const(mPixelType, "ARRAYU16", UINT2NUM(SDL_PIXELTYPE_ARRAYU16));
3694
+ rb_define_const(mPixelType, "ARRAYU32", UINT2NUM(SDL_PIXELTYPE_ARRAYU32));
3695
+ rb_define_const(mPixelType, "ARRAYF16", UINT2NUM(SDL_PIXELTYPE_ARRAYF16));
3696
+ rb_define_const(mPixelType, "ARRAYF32", UINT2NUM(SDL_PIXELTYPE_ARRAYF32));
3697
+
3698
+ mBitmapOrder = rb_define_module_under(cPixelFormat, "BitmapOrder");
3699
+ rb_define_const(mBitmapOrder, "NONE", UINT2NUM(SDL_BITMAPORDER_NONE));
3700
+ rb_define_const(mBitmapOrder, "O_1234", UINT2NUM(SDL_BITMAPORDER_1234));
3701
+ rb_define_const(mBitmapOrder, "O_4321", UINT2NUM(SDL_BITMAPORDER_4321));
3702
+
3703
+ mPackedOrder = rb_define_module_under(cPixelFormat, "PackedOrder");
3704
+ /* */
3705
+ rb_define_const(mPackedOrder, "NONE", UINT2NUM(SDL_PACKEDORDER_NONE));
3706
+ rb_define_const(mPackedOrder, "XRGB", UINT2NUM(SDL_PACKEDORDER_XRGB));
3707
+ rb_define_const(mPackedOrder, "RGBX", UINT2NUM(SDL_PACKEDORDER_RGBX));
3708
+ rb_define_const(mPackedOrder, "ARGB", UINT2NUM(SDL_PACKEDORDER_ARGB));
3709
+ rb_define_const(mPackedOrder, "RGBA", UINT2NUM(SDL_PACKEDORDER_RGBA));
3710
+ rb_define_const(mPackedOrder, "XBGR", UINT2NUM(SDL_PACKEDORDER_XBGR));
3711
+ rb_define_const(mPackedOrder, "BGRX", UINT2NUM(SDL_PACKEDORDER_BGRX));
3712
+ rb_define_const(mPackedOrder, "ABGR", UINT2NUM(SDL_PACKEDORDER_ABGR));
3713
+ rb_define_const(mPackedOrder, "BGRA", UINT2NUM(SDL_PACKEDORDER_BGRA));
3714
+
3715
+ mArrayOrder = rb_define_module_under(cPixelFormat, "ArrayOrder");
3716
+ /* */
3717
+ rb_define_const(mArrayOrder, "NONE", UINT2NUM(SDL_ARRAYORDER_NONE));
3718
+ rb_define_const(mArrayOrder, "RGB", UINT2NUM(SDL_ARRAYORDER_RGB));
3719
+ rb_define_const(mArrayOrder, "RGBA", UINT2NUM(SDL_ARRAYORDER_RGBA));
3720
+ rb_define_const(mArrayOrder, "ARGB", UINT2NUM(SDL_ARRAYORDER_ARGB));
3721
+ rb_define_const(mArrayOrder, "BGR", UINT2NUM(SDL_ARRAYORDER_BGR));
3722
+ rb_define_const(mArrayOrder, "BGRA", UINT2NUM(SDL_ARRAYORDER_BGRA));
3723
+ rb_define_const(mArrayOrder, "ABGR", UINT2NUM(SDL_ARRAYORDER_ABGR));
3724
+
3725
+ mPackedLayout = rb_define_module_under(cPixelFormat, "PackedLayout");
3726
+ /* */
3727
+ rb_define_const(mPackedLayout, "NONE", UINT2NUM(SDL_PACKEDLAYOUT_NONE));
3728
+ rb_define_const(mPackedLayout, "L_332", UINT2NUM(SDL_PACKEDLAYOUT_332));
3729
+ rb_define_const(mPackedLayout, "L_4444", UINT2NUM(SDL_PACKEDLAYOUT_4444));
3730
+ rb_define_const(mPackedLayout, "L_1555", UINT2NUM(SDL_PACKEDLAYOUT_1555));
3731
+ rb_define_const(mPackedLayout, "L_5551", UINT2NUM(SDL_PACKEDLAYOUT_5551));
3732
+ rb_define_const(mPackedLayout, "L_565", UINT2NUM(SDL_PACKEDLAYOUT_565));
3733
+ rb_define_const(mPackedLayout, "L_8888", UINT2NUM(SDL_PACKEDLAYOUT_8888));
3734
+ rb_define_const(mPackedLayout, "L_2101010", UINT2NUM(SDL_PACKEDLAYOUT_2101010));
3735
+ rb_define_const(mPackedLayout, "L_1010102", UINT2NUM(SDL_PACKEDLAYOUT_1010102));
3736
+
3737
+ {
3738
+ VALUE formats = rb_ary_new();
3739
+ /* -: Array of all available formats */
3740
+ rb_define_const(cPixelFormat, "FORMATS", formats);
3741
+ /*
3742
+ */
3743
+
3744
+ do {
3745
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_UNKNOWN);
3746
+ /* -: PixelFormat: Unused - reserved by SDL */
3747
+ rb_define_const(cPixelFormat, "UNKNOWN", format);
3748
+ rb_ary_push(formats, format);
3749
+ } while (0);
3750
+ do {
3751
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_INDEX1LSB);
3752
+
3753
+ rb_define_const(cPixelFormat, "INDEX1LSB", format);
3754
+ rb_ary_push(formats, format);
3755
+ } while (0);
3756
+ do {
3757
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_INDEX1MSB);
3758
+
3759
+ rb_define_const(cPixelFormat, "INDEX1MSB", format);
3760
+ rb_ary_push(formats, format);
3761
+ } while (0);
3762
+ do {
3763
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_INDEX4LSB);
3764
+
3765
+ rb_define_const(cPixelFormat, "INDEX4LSB", format);
3766
+ rb_ary_push(formats, format);
3767
+ } while (0);
3768
+ do {
3769
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_INDEX4MSB);
3770
+
3771
+ rb_define_const(cPixelFormat, "INDEX4MSB", format);
3772
+ rb_ary_push(formats, format);
3773
+ } while (0);
3774
+ do {
3775
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_INDEX8);
3776
+
3777
+ rb_define_const(cPixelFormat, "INDEX8", format);
3778
+ rb_ary_push(formats, format);
3779
+ } while (0);
3780
+ do {
3781
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_RGB332);
3782
+
3783
+ rb_define_const(cPixelFormat, "RGB332", format);
3784
+ rb_ary_push(formats, format);
3785
+ } while (0);
3786
+ do {
3787
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_RGB444);
3788
+
3789
+ rb_define_const(cPixelFormat, "RGB444", format);
3790
+ rb_ary_push(formats, format);
3791
+ } while (0);
3792
+ do {
3793
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_RGB555);
3794
+
3795
+ rb_define_const(cPixelFormat, "RGB555", format);
3796
+ rb_ary_push(formats, format);
3797
+ } while (0);
3798
+ do {
3799
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_BGR555);
3800
+
3801
+ rb_define_const(cPixelFormat, "BGR555", format);
3802
+ rb_ary_push(formats, format);
3803
+ } while (0);
3804
+ do {
3805
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_ARGB4444);
3806
+
3807
+ rb_define_const(cPixelFormat, "ARGB4444", format);
3808
+ rb_ary_push(formats, format);
3809
+ } while (0);
3810
+ do {
3811
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_RGBA4444);
3812
+
3813
+ rb_define_const(cPixelFormat, "RGBA4444", format);
3814
+ rb_ary_push(formats, format);
3815
+ } while (0);
3816
+ do {
3817
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_ABGR4444);
3818
+
3819
+ rb_define_const(cPixelFormat, "ABGR4444", format);
3820
+ rb_ary_push(formats, format);
3821
+ } while (0);
3822
+ do {
3823
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_BGRA4444);
3824
+
3825
+ rb_define_const(cPixelFormat, "BGRA4444", format);
3826
+ rb_ary_push(formats, format);
3827
+ } while (0);
3828
+ do {
3829
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_ARGB1555);
3830
+
3831
+ rb_define_const(cPixelFormat, "ARGB1555", format);
3832
+ rb_ary_push(formats, format);
3833
+ } while (0);
3834
+ do {
3835
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_RGBA5551);
3836
+
3837
+ rb_define_const(cPixelFormat, "RGBA5551", format);
3838
+ rb_ary_push(formats, format);
3839
+ } while (0);
3840
+ do {
3841
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_ABGR1555);
3842
+
3843
+ rb_define_const(cPixelFormat, "ABGR1555", format);
3844
+ rb_ary_push(formats, format);
3845
+ } while (0);
3846
+ do {
3847
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_BGRA5551);
3848
+
3849
+ rb_define_const(cPixelFormat, "BGRA5551", format);
3850
+ rb_ary_push(formats, format);
3851
+ } while (0);
3852
+ do {
3853
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_RGB565);
3854
+
3855
+ rb_define_const(cPixelFormat, "RGB565", format);
3856
+ rb_ary_push(formats, format);
3857
+ } while (0);
3858
+ do {
3859
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_BGR565);
3860
+
3861
+ rb_define_const(cPixelFormat, "BGR565", format);
3862
+ rb_ary_push(formats, format);
3863
+ } while (0);
3864
+ do {
3865
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_RGB24);
3866
+
3867
+ rb_define_const(cPixelFormat, "RGB24", format);
3868
+ rb_ary_push(formats, format);
3869
+ } while (0);
3870
+ do {
3871
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_BGR24);
3872
+
3873
+ rb_define_const(cPixelFormat, "BGR24", format);
3874
+ rb_ary_push(formats, format);
3875
+ } while (0);
3876
+ do {
3877
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_RGB888);
3878
+
3879
+ rb_define_const(cPixelFormat, "RGB888", format);
3880
+ rb_ary_push(formats, format);
3881
+ } while (0);
3882
+ do {
3883
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_RGBX8888);
3884
+
3885
+ rb_define_const(cPixelFormat, "RGBX8888", format);
3886
+ rb_ary_push(formats, format);
3887
+ } while (0);
3888
+ do {
3889
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_BGR888);
3890
+
3891
+ rb_define_const(cPixelFormat, "BGR888", format);
3892
+ rb_ary_push(formats, format);
3893
+ } while (0);
3894
+ do {
3895
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_BGRX8888);
3896
+
3897
+ rb_define_const(cPixelFormat, "BGRX8888", format);
3898
+ rb_ary_push(formats, format);
3899
+ } while (0);
3900
+ do {
3901
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_ARGB8888);
3902
+
3903
+ rb_define_const(cPixelFormat, "ARGB8888", format);
3904
+ rb_ary_push(formats, format);
3905
+ } while (0);
3906
+ do {
3907
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_RGBA8888);
3908
+
3909
+ rb_define_const(cPixelFormat, "RGBA8888", format);
3910
+ rb_ary_push(formats, format);
3911
+ } while (0);
3912
+ do {
3913
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_ABGR8888);
3914
+
3915
+ rb_define_const(cPixelFormat, "ABGR8888", format);
3916
+ rb_ary_push(formats, format);
3917
+ } while (0);
3918
+ do {
3919
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_BGRA8888);
3920
+
3921
+ rb_define_const(cPixelFormat, "BGRA8888", format);
3922
+ rb_ary_push(formats, format);
3923
+ } while (0);
3924
+ do {
3925
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_ARGB2101010);
3926
+
3927
+ rb_define_const(cPixelFormat, "ARGB2101010", format);
3928
+ rb_ary_push(formats, format);
3929
+ } while (0);
3930
+ do {
3931
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_YV12);
3932
+
3933
+ rb_define_const(cPixelFormat, "YV12", format);
3934
+ rb_ary_push(formats, format);
3935
+ } while (0);
3936
+ do {
3937
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_IYUV);
3938
+
3939
+ rb_define_const(cPixelFormat, "IYUV", format);
3940
+ rb_ary_push(formats, format);
3941
+ } while (0);
3942
+ do {
3943
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_YUY2);
3944
+
3945
+ rb_define_const(cPixelFormat, "YUY2", format);
3946
+ rb_ary_push(formats, format);
3947
+ } while (0);
3948
+ do {
3949
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_UYVY);
3950
+
3951
+ rb_define_const(cPixelFormat, "UYVY", format);
3952
+ rb_ary_push(formats, format);
3953
+ } while (0);
3954
+ do {
3955
+ VALUE format = PixelFormat_new(SDL_PIXELFORMAT_YVYU);
3956
+
3957
+ rb_define_const(cPixelFormat, "YVYU", format);
3958
+ rb_ary_push(formats, format);
3959
+ } while (0);
3960
+ rb_obj_freeze(formats);
3961
+ }
3962
+
3963
+ mScreenSaver = rb_define_module_under(mSDL2, "ScreenSaver");
3964
+ rb_define_module_function(mScreenSaver, "enable", ScreenSaver_enable, 0);
3965
+ rb_define_module_function(mScreenSaver, "disable", ScreenSaver_disable, 0);
3966
+ rb_define_module_function(mScreenSaver, "enabled?", ScreenSaver_enabled_p, 0);
3967
+
3968
+
3969
+ rb_gc_register_address(&hash_windowid_to_window);
3970
+ hash_windowid_to_window = rb_hash_new();
3971
+ }
3972
+
3973
+ #ifdef HAVE_SDL_IMAGE_H
3974
+ #include <SDL_image.h>
3975
+
3976
+ static VALUE mIMG;
3977
+
3978
+ /*
3979
+ * Document-module: SDL2::IMG
3980
+ *
3981
+ * This module provides the interface to SDL_image. You can load
3982
+ * many kinds of image files using this modules.
3983
+ *
3984
+ * This module provides only initialization interface {SDL2::IMG.init}.
3985
+ * After calling init, you can load image files using {SDL2::Surface.load}.
3986
+ */
3987
+
3988
+ /*
3989
+ * @overload init(flags)
3990
+ * Initialize SDL_image.
3991
+ *
3992
+ * You can specify the supporting image formats by bitwise OR'd of the
3993
+ * following constants.
3994
+ *
3995
+ * * {SDL2::IMG::INIT_JPG}
3996
+ * * {SDL2::IMG::INIT_PNG}
3997
+ * * {SDL2::IMG::INIT_TIF}
3998
+ * * {SDL2::IMG::INIT_WEBP}
3999
+ *
4000
+ * You need to initialize SDL_image to check whether specified format
4001
+ * is supported by your environment. If your environment does not
4002
+ * support required support format, you have a {SDL2::Error} exception.
4003
+ *
4004
+ * @param [Integer] flags submodule bits
4005
+ * @return [nil]
4006
+ *
4007
+ * @raise [SDL2::Error] raised when initializing is failed.
4008
+ */
4009
+ static VALUE IMG_s_init(VALUE self, VALUE f)
4010
+ {
4011
+ int flags = NUM2INT(f);
4012
+ if ((IMG_Init(flags) & flags) != flags)
4013
+ rb_raise(eSDL2Error, "Couldn't initialize SDL_image");
4014
+ return Qnil;
4015
+ }
4016
+
4017
+ /*
4018
+ * @overload load(file)
4019
+ * Load file and create a new {SDL2::Surface}.
4020
+ *
4021
+ * This method uses SDL_image. SDL_image supports following formats:
4022
+ * BMP, CUR, GIF, ICO, JPG, LBP, PCX, PNG, PNM, TGA, TIF, XCF, XPM, and XV.
4023
+ *
4024
+ * @param [String] file the image file name to load a surface from
4025
+ * @return [SDL2::Surface] Created surface
4026
+ *
4027
+ * @raise [SDL2::Error] raised when you fail to load (for example,
4028
+ * you have a wrong file name, or the file is broken)
4029
+ *
4030
+ * @see SDL2::IMG.init
4031
+ * @see SDL2::Renderer#load_texture
4032
+ */
4033
+ static VALUE Surface_s_load(VALUE self, VALUE fname)
4034
+ {
4035
+ SDL_Surface* surface = IMG_Load(StringValueCStr(fname));
4036
+ if (!surface) {
4037
+ SDL_SetError("%s", IMG_GetError());
4038
+ SDL_ERROR();
4039
+ }
4040
+ return Surface_new(surface);
4041
+ }
4042
+
4043
+ /*
4044
+ * @overload load_texture(file)
4045
+ *
4046
+ * Load file and create a new {SDL2::Texture}.
4047
+ *
4048
+ * This method uses SDL_image. SDL_image supports following formats:
4049
+ * BMP, CUR, GIF, ICO, JPG, LBP, PCX, PNG, PNM, TGA, TIF, XCF, XPM, and XV.
4050
+ *
4051
+ * @param [String] file the image file name to load a texture from
4052
+ * @return [SDL2::Texture] Created texture
4053
+ *
4054
+ * @raise [SDL2::Error] raised when you fail to load (for example,
4055
+ * you have a wrong file name, or the file is broken)
4056
+ *
4057
+ * @see SDL2::IMG.init
4058
+ * @see SDL2::Surface.load
4059
+ */
4060
+ static VALUE Renderer_load_texture(VALUE self, VALUE fname)
4061
+ {
4062
+ SDL_Texture* texture = IMG_LoadTexture(Get_SDL_Renderer(self), StringValueCStr(fname));
4063
+ if (!texture) {
4064
+ SDL_SetError("%s", IMG_GetError());
4065
+ SDL_ERROR();
4066
+ }
4067
+ return Texture_new(texture, Get_Renderer(self));
4068
+ }
4069
+
4070
+ void rubysdl2_init_image(void)
4071
+ {
4072
+ mIMG = rb_define_module_under(mSDL2, "IMG");
4073
+ rb_define_module_function(mIMG, "init", IMG_s_init, 1);
4074
+
4075
+ rb_define_singleton_method(cSurface, "load", Surface_s_load, 1);
4076
+ rb_define_method(cRenderer, "load_texture", Renderer_load_texture, 1);
4077
+
4078
+
4079
+ /* Initialize the JPEG loader */
4080
+ rb_define_const(mIMG, "INIT_JPG", INT2NUM(IMG_INIT_JPG));
4081
+ /* Initialize the PNG loader */
4082
+ rb_define_const(mIMG, "INIT_PNG", INT2NUM(IMG_INIT_PNG));
4083
+ /* Initialize the TIF loader */
4084
+ rb_define_const(mIMG, "INIT_TIF", INT2NUM(IMG_INIT_TIF));
4085
+ /* Initialize the WEBP loader */
4086
+ rb_define_const(mIMG, "INIT_WEBP", INT2NUM(IMG_INIT_WEBP));
4087
+ }
4088
+
4089
+ #else /* HAVE_SDL_IMAGE_H */
4090
+ void rubysdl2_init_image(void)
4091
+ {
4092
+ }
4093
+ #endif