sdl2-win93 1.0.0

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