graphics 1.0.0b1 → 1.0.0b4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/History.rdoc +30 -0
  5. data/Manifest.txt +39 -7
  6. data/README.rdoc +48 -4
  7. data/Rakefile +8 -2
  8. data/examples/boid.rb +9 -18
  9. data/examples/bounce.rb +15 -23
  10. data/examples/canvas.rb +75 -0
  11. data/examples/collision.rb +6 -6
  12. data/examples/demo.rb +5 -7
  13. data/examples/editor.rb +12 -9
  14. data/examples/fluid.rb +2 -3
  15. data/examples/fluid2.rb +1 -1
  16. data/examples/{lito2.rb → gol.rb} +0 -0
  17. data/examples/{zenspider4.rb → gol2.rb} +0 -0
  18. data/examples/logo.rb +4 -7
  19. data/examples/maze.rb +136 -0
  20. data/examples/tank.rb +10 -11
  21. data/examples/tank2.rb +12 -17
  22. data/examples/targeting.rb +1 -1
  23. data/examples/vants.rb +1 -1
  24. data/examples/walker.rb +3 -12
  25. data/examples/walker2.rb +197 -0
  26. data/examples/zombies.rb +31 -35
  27. data/ext/sdl/extconf.rb +31 -0
  28. data/ext/sdl/sdl.c +1067 -0
  29. data/ext/sdl/sge/INSTALL +72 -0
  30. data/ext/sdl/sge/LICENSE +504 -0
  31. data/ext/sdl/sge/Makefile +83 -0
  32. data/ext/sdl/sge/Makefile.conf +63 -0
  33. data/ext/sdl/sge/README +219 -0
  34. data/ext/sdl/sge/Todo +7 -0
  35. data/ext/sdl/sge/WhatsNew +224 -0
  36. data/ext/sdl/sge/sge.h +31 -0
  37. data/ext/sdl/sge/sge_blib.cpp +1939 -0
  38. data/ext/sdl/sge/sge_blib.h +68 -0
  39. data/ext/sdl/sge/sge_bm_text.cpp +451 -0
  40. data/ext/sdl/sge/sge_bm_text.h +71 -0
  41. data/ext/sdl/sge/sge_collision.cpp +388 -0
  42. data/ext/sdl/sge/sge_collision.h +54 -0
  43. data/ext/sdl/sge/sge_config.h +6 -0
  44. data/ext/sdl/sge/sge_internal.h +152 -0
  45. data/ext/sdl/sge/sge_misc.cpp +92 -0
  46. data/ext/sdl/sge/sge_misc.h +37 -0
  47. data/ext/sdl/sge/sge_primitives.cpp +2516 -0
  48. data/ext/sdl/sge/sge_primitives.h +111 -0
  49. data/ext/sdl/sge/sge_rotation.cpp +683 -0
  50. data/ext/sdl/sge/sge_rotation.h +46 -0
  51. data/ext/sdl/sge/sge_shape.cpp +762 -0
  52. data/ext/sdl/sge/sge_shape.h +365 -0
  53. data/ext/sdl/sge/sge_surface.cpp +1090 -0
  54. data/ext/sdl/sge/sge_surface.h +100 -0
  55. data/ext/sdl/sge/sge_textpp.cpp +785 -0
  56. data/ext/sdl/sge/sge_textpp.h +270 -0
  57. data/ext/sdl/sge/sge_tt_text.cpp +1456 -0
  58. data/ext/sdl/sge/sge_tt_text.h +114 -0
  59. data/graphics_setup.sh +26 -0
  60. data/lib/graphics.rb +1 -1
  61. data/lib/graphics/body.rb +50 -3
  62. data/lib/graphics/extensions.rb +13 -7
  63. data/lib/graphics/simulation.rb +126 -46
  64. data/test/test_graphics.rb +52 -12
  65. data/test/test_sdl.rb +1 -0
  66. metadata +54 -23
  67. metadata.gz.sig +0 -0
  68. data/.gemtest +0 -0
  69. data/examples/lito.rb +0 -108
  70. data/examples/zenspider1.rb +0 -93
  71. data/examples/zenspider2.rb +0 -123
  72. data/examples/zenspider3.rb +0 -104
  73. data/rubysdl_setup.sh +0 -34
@@ -126,11 +126,11 @@ class Person < Entity
126
126
  end
127
127
 
128
128
  def update_infection
129
- if @infect then
130
- @infect -= 1
131
- sim.zombie << Zombie.from_person(sim.person.delete(self), sim) if @infect <= 0
132
- true
133
- end
129
+ return unless @infect
130
+
131
+ @infect -= 1
132
+ sim.zombie << Zombie.from_person(sim.person.delete(self), sim) if @infect <= 0
133
+ true
134
134
  end
135
135
 
136
136
  def visible
@@ -190,23 +190,24 @@ class Hunter < Person
190
190
 
191
191
  baddies = sim.zombie + sim.person.select(&:infect)
192
192
  nearest = baddies.sort_by { |z| self.distance_from_squared z }.first
193
- if nearest then
194
- if self.touching? nearest then
195
- if Person === nearest then
193
+
194
+ return unless nearest
195
+
196
+ if self.touching? nearest then
197
+ if Person === nearest then
198
+ nearest.kill
199
+ else
200
+ if rand(10) != 0 then
196
201
  nearest.kill
197
202
  else
198
- if rand(10) != 0 then
199
- nearest.kill
200
- else
201
- self.state = INFECT
202
- self.infect = INFECT_STEPS.to_i
203
- end
203
+ self.state = INFECT
204
+ self.infect = INFECT_STEPS.to_i
204
205
  end
205
- elsif near? nearest then
206
- move_towards nearest
207
- else
208
- move_towards nearest
209
206
  end
207
+ elsif near? nearest then
208
+ move_towards nearest
209
+ else
210
+ move_towards nearest
210
211
  end
211
212
  end
212
213
 
@@ -288,13 +289,8 @@ class ZombieGame < Graphics::Simulation
288
289
  def draw tick
289
290
  clear
290
291
 
291
- person.each do |p|
292
- p.draw
293
- end
294
-
295
- zombie.each do |p|
296
- p.draw
297
- end
292
+ person.each(&:draw)
293
+ zombie.each(&:draw)
298
294
 
299
295
  fps tick
300
296
  end
@@ -311,18 +307,18 @@ class ZombieGame < Graphics::Simulation
311
307
  p.update i
312
308
  end
313
309
 
314
- if zombie.empty? or person.all?(&:infected?) then
315
- t = Time.now - start
316
- if zombie.empty? then
317
- print "Infestation stopped "
318
- else
319
- print "All people infected "
320
- end
321
- puts "in #{i} iterations, #{t} sec"
322
- puts " #{i / t} frames / sec"
310
+ return unless zombie.empty? or person.empty?
323
311
 
324
- exit
312
+ t = Time.now - start
313
+ if zombie.empty? then
314
+ print "Infestation stopped "
315
+ else
316
+ print "All people infected "
325
317
  end
318
+ puts "in #{i} iterations, #{t} sec"
319
+ puts " #{i / t} frames / sec"
320
+
321
+ exit
326
322
  end
327
323
 
328
324
  def populate klass, coll
@@ -0,0 +1,31 @@
1
+ require "mkmf"
2
+
3
+ $VPATH << "$(srcdir)/sge"
4
+ $INCFLAGS << " -I$(srcdir)/sge"
5
+
6
+ $srcs = Dir.glob("#{$srcdir}/{,sge/}*.c{,pp}")
7
+
8
+ sdl_config = with_config "sdl-config", "sdl-config"
9
+ $CPPFLAGS += " " + `#{sdl_config} --cflags`.chomp
10
+ $LOCAL_LIBS += " " + `#{sdl_config} --libs`.chomp
11
+
12
+ have_library("SDL_mixer", "Mix_OpenAudio") or abort "Need sdl_mixer"
13
+ have_library("SDL_image", "IMG_Load") or abort "Need sdl_image"
14
+ have_library("SDL_ttf", "TTF_Init") or abort "Need sdl_ttf"
15
+ # have_library("SDL_gfx", "fuck") or abort "Need sdl_gfx"
16
+
17
+ # have_func "TTF_OpenFontIndex"
18
+ # have_func "TTF_FontFaces"
19
+ # have_func "TTF_FontFaceIsFixedWidth"
20
+ # have_func "TTF_FontFaceFamilyName"
21
+ # have_func "TTF_FontFaceStyleName"
22
+ # have_func "Mix_LoadMUS_RW"
23
+ # have_func "rb_thread_blocking_region"
24
+ # have_func "rb_thread_call_without_gvl" if have_header "ruby/thread.h"
25
+
26
+ # if have_func("rb_enc_str_new") && have_func("rb_str_export_to_enc")
27
+ # $CPPFLAGS += " -D ENABLE_M17N"
28
+ # $CPPFLAGS += " -D ENABLE_M17N_FILESYSTEM" if enable_config "m17n-filesystem", false
29
+ # end
30
+
31
+ create_makefile "sdl/sdl"
@@ -0,0 +1,1067 @@
1
+ #include <SDL.h>
2
+ #include <ruby.h>
3
+ #include <ruby/intern.h>
4
+ #include <SDL_ttf.h>
5
+ #include <SDL_image.h>
6
+ #include <sge.h>
7
+ #include <SDL_mixer.h>
8
+
9
+ // https://github.com/google/protobuf/blob/master/ruby/ext/google/protobuf_c/defs.c
10
+
11
+ #define DEFINE_CLASS_(name, string_name, mark, free, memsize) \
12
+ static void mark(void*); \
13
+ static void free(void*); \
14
+ static VALUE c##name; \
15
+ static const rb_data_type_t _##name##_type = { \
16
+ string_name, \
17
+ { mark, free, memsize, { NULL, NULL }, }, NULL, NULL, \
18
+ }; \
19
+ static SDL_##name* ruby_to_##name(VALUE val) { \
20
+ SDL_##name* ret; \
21
+ TypedData_Get_Struct(val, SDL_##name, &_##name##_type, ret); \
22
+ return ret; \
23
+ }
24
+
25
+ #define DEFINE_CLASS(name, string_name) \
26
+ static size_t _##name##_memsize(const void *); \
27
+ DEFINE_CLASS_(name, string_name, \
28
+ _##name##_mark, _##name##_free, _##name##_memsize)
29
+
30
+ #define DEFINE_CLASS_0(name, string_name) \
31
+ DEFINE_CLASS_(name, string_name, _##name##_mark, _##name##_free, NULL)
32
+
33
+ #define DEFINE_SELF(type, var, rb_var) \
34
+ SDL_##type* var = ruby_to_##type(rb_var)
35
+
36
+ #define NUM2SINT32(n) (Sint32)NUM2INT(n)
37
+ #define NUM2SINT16(n) (Sint16)NUM2INT(n)
38
+ #define NUM2UINT32(n) (Uint32)NUM2UINT(n)
39
+ #define NUM2UINT16(n) (Uint16)NUM2UINT(n)
40
+ #define NUM2UINT8(n) (Uint8)NUM2INT(n)
41
+ #define INT2BOOL(n) ((n)?Qtrue:Qfalse)
42
+ #define NUM2FLT(n) (float)NUM2DBL(n)
43
+
44
+ #define NewRect(x,y,w,h) { NUM2SINT16(x), NUM2SINT16(y), NUM2UINT16(w), NUM2UINT16(h) }
45
+
46
+ #define UNUSED(x) (void)(x)
47
+
48
+ #define ZERO_RECT(r) r.x == 0 && r.y == 0 && r.w == 0 && r.h == 0
49
+
50
+ #define FAILURE(s) rb_raise(eSDLError, "%s failed: %s", (s), SDL_GetError());
51
+ #define AUDIO_FAILURE(s) rb_raise(eSDLError, "%s failed: %s", (s), Mix_GetError());
52
+
53
+ #ifdef rb_intern
54
+ #undef rb_intern // HACK -- clang warns about recursive macros
55
+ #endif
56
+
57
+ #define DEFINE_ID(name) static ID id_iv_##name
58
+ #define INIT_ID(name) id_iv_##name = rb_intern("@"#name)
59
+
60
+ #define DEFINE_DRAW6(type, name, func) \
61
+ static VALUE Surface_##name(VALUE s, VALUE x, VALUE y, VALUE w, VALUE h, VALUE c) { \
62
+ return _draw_func_##type(&func, s, x, y, w, h, c); \
63
+ }
64
+
65
+ #define DEFINE_SXYRC(name, func) \
66
+ static VALUE Surface_##name(VALUE s, VALUE x, VALUE y, VALUE r, VALUE c) { \
67
+ return _draw_func_sxyrc(&func, s, x, y, r, c); \
68
+ }
69
+
70
+ #define DEFINE_SXYXYC(name, func) DEFINE_DRAW6(sxyxyc, name, func)
71
+ #define DEFINE_SXYWHC(name, func) DEFINE_DRAW6(sxywhc, name, func)
72
+
73
+ static VALUE cEvent;
74
+ static VALUE cEventKeydown;
75
+ static VALUE cEventKeyup;
76
+ static VALUE cEventMousedown;
77
+ static VALUE cEventMousemove;
78
+ static VALUE cEventMouseup;
79
+ static VALUE cEventQuit;
80
+ static VALUE cScreen;
81
+ static VALUE eSDLError;
82
+ static VALUE eSDLMem;
83
+ static VALUE mKey;
84
+ static VALUE mSDL;
85
+ static VALUE mWM;
86
+ static VALUE mMouse;
87
+
88
+ typedef TTF_Font SDL_TTFFont;
89
+ typedef Mix_Chunk SDL_Audio;
90
+ typedef sge_cdata SDL_CollisionMap;
91
+
92
+ DEFINE_ID(button);
93
+ DEFINE_ID(mod);
94
+ DEFINE_ID(press);
95
+ DEFINE_ID(state);
96
+ DEFINE_ID(sym);
97
+ DEFINE_ID(unicode);
98
+ DEFINE_ID(x);
99
+ DEFINE_ID(xrel);
100
+ DEFINE_ID(y);
101
+ DEFINE_ID(yrel);
102
+
103
+ DEFINE_CLASS(Audio, "SDL::Audio")
104
+ DEFINE_CLASS(Surface, "SDL::Surface")
105
+ DEFINE_CLASS(CollisionMap, "SDL::CollisionMap")
106
+ DEFINE_CLASS(PixelFormat, "SDL::PixelFormat")
107
+ DEFINE_CLASS_0(TTFFont, "SDL::TTFFont")
108
+
109
+ typedef VALUE (*event_creator)(SDL_Event *);
110
+ static event_creator event_creators[SDL_NUMEVENTS];
111
+
112
+ static int is_quit = 0;
113
+ static Uint8* key_state = NULL;
114
+ static SDLMod mod_state;
115
+
116
+ void Init_sdl(void);
117
+
118
+ //// Misc / Utility functions:
119
+
120
+ // TODO: collapse to one format
121
+ static Uint32 VALUE2COLOR(VALUE color, SDL_PixelFormat *format) {
122
+ // TODO: reverse and use FIXNUM_P ?
123
+ if (rb_obj_is_kind_of(color, rb_cArray)) {
124
+ switch (RARRAY_LEN(color)) {
125
+ case 3:
126
+ return SDL_MapRGB(format,
127
+ (Uint8)FIX2UINT(rb_ary_entry(color, 0)),
128
+ (Uint8)FIX2UINT(rb_ary_entry(color, 1)),
129
+ (Uint8)FIX2UINT(rb_ary_entry(color, 2)));
130
+ case 4:
131
+ return SDL_MapRGBA(format,
132
+ (Uint8)FIX2UINT(rb_ary_entry(color, 0)),
133
+ (Uint8)FIX2UINT(rb_ary_entry(color, 1)),
134
+ (Uint8)FIX2UINT(rb_ary_entry(color, 2)),
135
+ (Uint8)FIX2UINT(rb_ary_entry(color, 3)));
136
+ default:
137
+ rb_raise(rb_eArgError, "type mismatch:color array needs 3 or 4 elements");
138
+ }
139
+ } else {
140
+ return NUM2UINT(color);
141
+ }
142
+ }
143
+
144
+ //// SDL methods:
145
+
146
+ static VALUE sdl_s_init(VALUE mod, VALUE flags) {
147
+ UNUSED(mod);
148
+ if (SDL_Init(NUM2UINT(flags)))
149
+ FAILURE("SDL.init");
150
+
151
+ if (TTF_Init())
152
+ rb_raise(eSDLError, "TTF_Init error: %s", TTF_GetError());
153
+
154
+ return Qnil;
155
+ }
156
+
157
+ static void sdl__quit(VALUE v) {
158
+ UNUSED(v);
159
+ if (is_quit) return;
160
+ is_quit = 1;
161
+
162
+ TTF_Quit();
163
+ SDL_Quit();
164
+ }
165
+
166
+ //// SDL::Audio methods:
167
+
168
+ static void _Audio_free(void* p) {
169
+ // if (is_quit) return;
170
+ if (!p) return;
171
+
172
+ Mix_Chunk *chunk = p;
173
+
174
+ if (Mix_QuerySpec(NULL, NULL, NULL))
175
+ Mix_FreeChunk(chunk);
176
+ }
177
+
178
+ static void _Audio_mark(void* p) {
179
+ UNUSED(p);
180
+ }
181
+
182
+ static size_t _Audio_memsize(const void *p) {
183
+ return p ? sizeof(Mix_Chunk) + ((Mix_Chunk*)p)->alen : 0;
184
+ }
185
+
186
+ static VALUE Audio_s_open(VALUE self, VALUE n_channels) {
187
+ UNUSED(self);
188
+ int n = NUM2INT(n_channels);
189
+
190
+ // TODO: int Mix_Init(MIX_INIT_MP3) ?
191
+
192
+ if (Mix_QuerySpec(NULL, NULL, NULL))
193
+ return Qnil; // TODO: raise?
194
+
195
+ if (Mix_OpenAudio(22050, MIX_DEFAULT_FORMAT, 2, 4096))
196
+ AUDIO_FAILURE("SDL::Audio.open");
197
+
198
+ return INT2FIX(Mix_AllocateChannels(n));
199
+ }
200
+
201
+ static VALUE Audio_s_load(VALUE self, VALUE path) {
202
+ UNUSED(self);
203
+ ExportStringValue(path);
204
+
205
+ Mix_Chunk *chunk = Mix_LoadWAV(RSTRING_PTR(path));
206
+
207
+ if (!chunk)
208
+ FAILURE("Audio.load");
209
+
210
+ return TypedData_Wrap_Struct(cAudio, &_Audio_type, chunk);
211
+ }
212
+
213
+ static VALUE Audio_play(VALUE self) {
214
+ DEFINE_SELF(Audio, audio, self);
215
+
216
+ if (Mix_PlayChannel(-1, audio, 0) < 0)
217
+ AUDIO_FAILURE("Audio#play");
218
+
219
+ return Qnil;
220
+ }
221
+
222
+ //// SDL::CollisionMap methods:
223
+
224
+ static void _CollisionMap_free(void* p) {
225
+ if (is_quit) return;
226
+ if (!p) return;
227
+
228
+ SDL_PixelFormat *format = p;
229
+
230
+ if (format->palette) {
231
+ free(format->palette->colors);
232
+ free(format->palette);
233
+ }
234
+
235
+ free(format);
236
+ }
237
+
238
+ static void _CollisionMap_mark(void* p) {
239
+ UNUSED(p);
240
+ }
241
+
242
+ static size_t _CollisionMap_memsize(const void *p) {
243
+ return p ? sizeof(sge_cdata) : 0;
244
+ }
245
+
246
+ static VALUE CollisionMap_check(VALUE cmap1, VALUE x1, VALUE y1,
247
+ VALUE cmap2, VALUE x2, VALUE y2) {
248
+ DEFINE_SELF(CollisionMap, cdata1, cmap1);
249
+ DEFINE_SELF(CollisionMap, cdata2, cmap2);
250
+
251
+ if(!sge_cmcheck(cdata1, NUM2SINT16(x1), NUM2SINT16(y1),
252
+ cdata2, NUM2SINT16(x2), NUM2SINT16(y2)))
253
+ return Qnil;
254
+
255
+ return rb_ary_new3(2, INT2NUM(sge_get_cx()), INT2NUM(sge_get_cy()));
256
+ }
257
+
258
+ //// SDL::Event methods:
259
+
260
+ static VALUE Event_s_poll(VALUE self) {
261
+ UNUSED(self);
262
+ SDL_Event event;
263
+
264
+ return SDL_PollEvent(&event) == 1 ? event_creators[event.type](&event) : Qnil;
265
+ }
266
+
267
+ static VALUE Event__null(SDL_Event *event) {
268
+ UNUSED(event);
269
+ return Qnil;
270
+ }
271
+
272
+ static VALUE Event__quit(SDL_Event *event) {
273
+ UNUSED(event);
274
+ return rb_obj_alloc(cEventQuit);
275
+ }
276
+
277
+ static VALUE __new_key_event(VALUE klass, SDL_Event *event) {
278
+ VALUE obj = rb_obj_alloc(klass); // TODO: TypedData_Wrap_Struct ?
279
+ rb_ivar_set(obj, id_iv_press, INT2BOOL(event->key.state == SDL_PRESSED)); // TODO: nuke?
280
+ rb_ivar_set(obj, id_iv_sym, INT2FIX(event->key.keysym.sym));
281
+ rb_ivar_set(obj, id_iv_mod, UINT2NUM(event->key.keysym.mod));
282
+ rb_ivar_set(obj, id_iv_unicode, UINT2NUM(event->key.keysym.unicode));
283
+ return obj;
284
+ }
285
+
286
+ static VALUE Event__keydown(SDL_Event *event) {
287
+ return __new_key_event(cEventKeydown, event);
288
+ }
289
+
290
+ static VALUE Event__keyup(SDL_Event *event) {
291
+ return __new_key_event(cEventKeyup, event);
292
+ }
293
+
294
+ static VALUE Event__mousemove(SDL_Event *event) {
295
+ VALUE obj = rb_obj_alloc(cEventMousemove);
296
+
297
+ rb_ivar_set(obj, id_iv_state, INT2FIX(event->motion.state));
298
+ rb_ivar_set(obj, id_iv_x, INT2FIX(event->motion.x));
299
+ rb_ivar_set(obj, id_iv_y, INT2FIX(event->motion.y));
300
+ rb_ivar_set(obj, id_iv_xrel, INT2FIX(event->motion.xrel));
301
+ rb_ivar_set(obj, id_iv_yrel, INT2FIX(event->motion.yrel));
302
+
303
+ return obj;
304
+ }
305
+
306
+ static VALUE __new_mouse_event(VALUE klass, SDL_Event *event)
307
+ {
308
+ VALUE obj = rb_obj_alloc(klass);
309
+
310
+ rb_ivar_set(obj, id_iv_button, INT2FIX(event->button.button));
311
+ rb_ivar_set(obj, id_iv_press, INT2BOOL(event->button.state == SDL_PRESSED));
312
+ rb_ivar_set(obj, id_iv_x, INT2FIX(event->button.x));
313
+ rb_ivar_set(obj, id_iv_y, INT2FIX(event->button.y));
314
+
315
+ return obj;
316
+ }
317
+
318
+ static VALUE Event__mousedown(SDL_Event *event) {
319
+ return __new_mouse_event(cEventMousedown, event);
320
+ }
321
+
322
+ static VALUE Event__mouseup(SDL_Event *event) {
323
+ return __new_mouse_event(cEventMouseup, event);
324
+ }
325
+
326
+ //// SDL::Key methods:
327
+
328
+ static VALUE Key_s_press_p(VALUE mod, VALUE keysym) {
329
+ UNUSED(mod);
330
+ int sym = NUM2INT(keysym);
331
+
332
+ if (SDLK_FIRST >= sym || sym >= SDLK_LAST)
333
+ rb_raise(eSDLError, "%d is out of key", sym);
334
+
335
+ if (!key_state)
336
+ rb_raise(eSDLError,
337
+ "You should call SDL::Key#scan before calling SDL::Key#press?");
338
+
339
+ return INT2BOOL(key_state[sym]);
340
+ }
341
+
342
+ static VALUE Key_s_scan(VALUE mod) {
343
+ UNUSED(mod);
344
+
345
+ key_state = SDL_GetKeyState(NULL);
346
+ mod_state = SDL_GetModState();
347
+
348
+ return Qnil;
349
+ }
350
+
351
+ //// SDL::Mouse methods:
352
+
353
+ static VALUE Mouse_s_state(VALUE mod) {
354
+ UNUSED(mod);
355
+
356
+ int x,y;
357
+ Uint8 result = SDL_GetMouseState(&x, &y);
358
+
359
+ return rb_ary_new3(5,
360
+ INT2FIX(x),
361
+ INT2FIX(y),
362
+ INT2BOOL(result&SDL_BUTTON_LMASK),
363
+ INT2BOOL(result&SDL_BUTTON_MMASK),
364
+ INT2BOOL(result&SDL_BUTTON_RMASK));
365
+ }
366
+
367
+
368
+ //// SDL::PixelFormat methods:
369
+
370
+ static void _PixelFormat_free(void* p) {
371
+ if (is_quit) return;
372
+ if (!p) return;
373
+
374
+ SDL_PixelFormat *format = p;
375
+
376
+ if (format->palette) {
377
+ free(format->palette->colors);
378
+ free(format->palette);
379
+ }
380
+
381
+ free(format);
382
+ }
383
+
384
+ static void _PixelFormat_mark(void* p) {
385
+ UNUSED(p);
386
+ }
387
+
388
+ static size_t _PixelFormat_memsize(const void *p) {
389
+ return p ? sizeof(struct SDL_PixelFormat) : 0;
390
+ }
391
+
392
+ static VALUE PixelFormat_map_rgba(VALUE self, VALUE r, VALUE g, VALUE b, VALUE a) {
393
+ DEFINE_SELF(PixelFormat, format, self);
394
+
395
+ return UINT2NUM(SDL_MapRGBA(format,
396
+ NUM2UINT8(r), NUM2UINT8(g),
397
+ NUM2UINT8(b), NUM2UINT8(a)));
398
+ }
399
+
400
+ static VALUE PixelFormat_get_rgb(VALUE self, VALUE pixel) {
401
+ DEFINE_SELF(PixelFormat, format, self);
402
+ Uint8 r, g, b;
403
+
404
+ SDL_GetRGB(NUM2UINT(pixel), format, &r, &g, &b);
405
+
406
+ return rb_ary_new3(3, UINT2NUM(r), UINT2NUM(g), UINT2NUM(b));
407
+ }
408
+
409
+ static VALUE PixelFormat_colorkey(VALUE self) {
410
+ DEFINE_SELF(PixelFormat, format, self);
411
+
412
+ return UINT2NUM(format->colorkey);
413
+ }
414
+
415
+ static VALUE PixelFormat_alpha(VALUE self) {
416
+ DEFINE_SELF(PixelFormat, format, self);
417
+
418
+ return UINT2NUM(format->alpha);
419
+ }
420
+
421
+ //// SDL::Screen methods:
422
+
423
+ static VALUE Screen_s_open(VALUE klass, VALUE w, VALUE h, VALUE bpp, VALUE flags) {
424
+ UNUSED(klass);
425
+ SDL_Surface *screen;
426
+
427
+ screen = SDL_SetVideoMode(NUM2INT(w), NUM2INT(h), NUM2INT(bpp), NUM2UINT(flags));
428
+
429
+ if (!screen)
430
+ rb_raise(eSDLError, "Couldn't set %dx%d %d bpp video mode: %s",
431
+ NUM2INT(w), NUM2INT(h), NUM2INT(bpp), SDL_GetError());
432
+
433
+ return TypedData_Wrap_Struct(cScreen, &_Surface_type, screen);
434
+ }
435
+
436
+ static VALUE Screen_flip(VALUE self) {
437
+ DEFINE_SELF(Surface, surface, self);
438
+
439
+ if (SDL_Flip(surface) < 0)
440
+ FAILURE("Screen#flip");
441
+
442
+ return Qnil;
443
+ }
444
+
445
+ static VALUE Screen_update(VALUE self, VALUE x, VALUE y, VALUE w, VALUE h) {
446
+ DEFINE_SELF(Surface, surface, self);
447
+
448
+ SDL_UpdateRect(surface,
449
+ NUM2SINT32(x), NUM2SINT32(y),
450
+ NUM2UINT32(w), NUM2UINT32(h));
451
+
452
+ return Qnil;
453
+ }
454
+
455
+ //// SDL::Surface methods:
456
+
457
+ static void _Surface_free(void* surface) {
458
+ if (is_quit) return;
459
+ if (surface) SDL_FreeSurface(surface);
460
+ }
461
+
462
+ static void _Surface_mark(void* surface) {
463
+ UNUSED(surface);
464
+ }
465
+
466
+ static size_t _Surface_memsize(const void *p) {
467
+ return p ? sizeof(struct SDL_Surface) : 0;
468
+ }
469
+
470
+ static VALUE Surface_s_blit(VALUE self,
471
+ VALUE src, VALUE srcX, VALUE srcY, VALUE srcW, VALUE srcH,
472
+ VALUE dst, VALUE dstX, VALUE dstY) {
473
+ UNUSED(self);
474
+ DEFINE_SELF(Surface, src_surface, src);
475
+ DEFINE_SELF(Surface, dst_surface, dst);
476
+
477
+ SDL_Rect src_rect = NewRect(srcX, srcY, srcW, srcH);
478
+ SDL_Rect dst_rect = NewRect(dstX, dstY, srcW, srcH);
479
+ SDL_Rect *sr = ZERO_RECT(src_rect) ? NULL : &src_rect;
480
+ SDL_Rect *dr = ZERO_RECT(dst_rect) ? NULL : &dst_rect;
481
+ int result = SDL_BlitSurface(src_surface, sr, dst_surface, dr);
482
+
483
+ switch (result) {
484
+ case -1:
485
+ FAILURE("SDL::Surface.blit");
486
+ case -2:
487
+ rb_raise(eSDLMem, "SDL::Surface lost video memory");
488
+ }
489
+
490
+ return INT2NUM(result);
491
+ }
492
+
493
+ static VALUE Surface_s_new(VALUE self, VALUE w, VALUE h, VALUE pf) {
494
+ UNUSED(self);
495
+ SDL_Surface* surface;
496
+
497
+ DEFINE_SELF(PixelFormat, format, pf);
498
+
499
+ surface = SDL_CreateRGBSurface(SDL_SWSURFACE, NUM2INT(w), NUM2INT(h),
500
+ format->BitsPerPixel,
501
+ format->Rmask, format->Gmask,
502
+ format->Bmask, format->Amask);
503
+ if (!surface)
504
+ FAILURE("Surface.new");
505
+
506
+ return TypedData_Wrap_Struct(cSurface, &_Surface_type, surface);
507
+ }
508
+
509
+ static VALUE Surface_s_load(VALUE klass, VALUE path) {
510
+ UNUSED(klass);
511
+ SDL_Surface *surface;
512
+
513
+ ExportStringValue(path);
514
+
515
+ surface = IMG_Load(RSTRING_PTR(path));
516
+
517
+ if (!surface)
518
+ rb_raise(eSDLError, "Couldn't load file %s : %s",
519
+ RSTRING_PTR(path),
520
+ SDL_GetError());
521
+
522
+ return TypedData_Wrap_Struct(cSurface, &_Surface_type, surface);
523
+ }
524
+
525
+ static VALUE Surface_set_color_key(VALUE self, VALUE flag, VALUE key) {
526
+ DEFINE_SELF(Surface, surface, self);
527
+
528
+ if (SDL_SetColorKey(surface,
529
+ NUM2UINT(flag),
530
+ VALUE2COLOR(key, surface->format)) < 0)
531
+ FAILURE("Surface#set_color_key");
532
+
533
+ return Qnil;
534
+ }
535
+
536
+ typedef void (*sxyxyc_func)(SDL_Surface *, Sint16, Sint16, Sint16, Sint16, Uint32);
537
+ typedef void (*sxyrc_func)(SDL_Surface *, Sint16, Sint16, Sint16, Uint32);
538
+
539
+ static VALUE _draw_func_sxyrc(sxyrc_func f, VALUE self, VALUE x, VALUE y, VALUE r, VALUE c) {
540
+ DEFINE_SELF(Surface, surface, self);
541
+
542
+ Sint16 x1, y1, r_;
543
+ Uint32 color;
544
+
545
+ x1 = NUM2SINT16(x);
546
+ y1 = NUM2SINT16(y);
547
+ r_ = NUM2SINT16(r);
548
+ color = VALUE2COLOR(c, surface->format);
549
+
550
+ f(surface, x1, y1, r_, color);
551
+
552
+ return Qnil;
553
+ }
554
+
555
+ static VALUE _draw_func_sxywhc(sxyxyc_func f, VALUE self, VALUE x, VALUE y, VALUE w, VALUE h, VALUE c) {
556
+ DEFINE_SELF(Surface, surface, self);
557
+
558
+ Sint16 x1, y1, x2, y2;
559
+ Uint32 color;
560
+
561
+ x1 = NUM2SINT16(x);
562
+ y1 = NUM2SINT16(y);
563
+ x2 = x1 + NUM2SINT16(w);
564
+ y2 = y1 + NUM2SINT16(h);
565
+ color = VALUE2COLOR(c, surface->format);
566
+
567
+ f(surface, x1, y1, x2, y2, color);
568
+
569
+ return Qnil;
570
+ }
571
+
572
+ static VALUE _draw_func_sxyxyc(sxyxyc_func f, VALUE self, VALUE x, VALUE y, VALUE w, VALUE h, VALUE c) {
573
+ DEFINE_SELF(Surface, surface, self);
574
+
575
+ Sint16 x1, y1, r1, r2;
576
+ Uint32 color;
577
+
578
+ x1 = NUM2SINT16(x);
579
+ y1 = NUM2SINT16(y);
580
+ r1 = NUM2SINT16(w);
581
+ r2 = NUM2SINT16(h);
582
+ color = VALUE2COLOR(c, surface->format);
583
+
584
+ f(surface, x1, y1, r1, r2, color);
585
+
586
+ return Qnil;
587
+ }
588
+
589
+ static VALUE Surface_draw_bezier(VALUE self,
590
+ VALUE x1, VALUE y1,
591
+ VALUE cx1, VALUE cy1,
592
+ VALUE cx2, VALUE cy2,
593
+ VALUE x2, VALUE y2,
594
+ VALUE l, VALUE c) {
595
+ DEFINE_SELF(Surface, surface, self);
596
+
597
+ sge_AABezier(surface,
598
+ NUM2SINT16(x1), NUM2SINT16(y1),
599
+ NUM2SINT16(cx1), NUM2SINT16(cy1),
600
+ NUM2SINT16(cx2), NUM2SINT16(cy2),
601
+ NUM2SINT16(x2), NUM2SINT16(y2),
602
+ NUM2INT(l),
603
+ VALUE2COLOR(c, surface->format));
604
+
605
+ return Qnil;
606
+ }
607
+
608
+ DEFINE_SXYRC(draw_circle, sge_AACircle)
609
+ DEFINE_SXYRC(fill_circle, sge_AAFilledCircle)
610
+ DEFINE_SXYXYC(draw_line, sge_AALine)
611
+ DEFINE_SXYXYC(fill_ellipse, sge_FilledEllipse)
612
+ DEFINE_SXYXYC(draw_ellipse, sge_Ellipse)
613
+ DEFINE_SXYWHC(draw_rect, sge_Rect)
614
+ DEFINE_SXYWHC(fill_rect, sge_FilledRect)
615
+
616
+ static VALUE Surface_fast_rect(VALUE self, VALUE x, VALUE y, VALUE w, VALUE h, VALUE color) {
617
+ DEFINE_SELF(Surface, surface, self);
618
+
619
+ SDL_Rect rect = NewRect(x, y, w, h);
620
+
621
+ if (SDL_FillRect(surface, &rect, VALUE2COLOR(color, surface->format)) < 0)
622
+ FAILURE("Surface#fast_rect");
623
+
624
+ return Qnil;
625
+ }
626
+
627
+ static VALUE Surface_flags(VALUE self) {
628
+ DEFINE_SELF(Surface, surface, self);
629
+
630
+ return UINT2NUM(surface->flags);
631
+ }
632
+
633
+ static VALUE Surface_set_alpha(VALUE self, VALUE flag, VALUE alpha) {
634
+ DEFINE_SELF(Surface, surface, self);
635
+
636
+ if (SDL_SetAlpha(surface, NUM2UINT(flag), NUM2UINT8(alpha)))
637
+ FAILURE("Surface#set_alpha");
638
+
639
+ return Qnil;
640
+ }
641
+
642
+ static VALUE Surface_format(VALUE self) {
643
+ DEFINE_SELF(Surface, surface, self);
644
+ SDL_PixelFormat* format;
645
+ SDL_Palette* palette;
646
+ SDL_Palette* src = surface->format->palette;
647
+
648
+ if (src) {
649
+ palette = ALLOC(SDL_Palette);
650
+ palette->ncolors = src->ncolors;
651
+ palette->colors = ALLOC_N(SDL_Color, (size_t)src->ncolors);
652
+ MEMCPY(palette->colors, src->colors, SDL_Color, (size_t)src->ncolors);
653
+ } else {
654
+ palette = NULL;
655
+ }
656
+
657
+ VALUE ret = TypedData_Make_Struct(cPixelFormat, SDL_PixelFormat, &_PixelFormat_type, format);
658
+
659
+ *format = *(surface->format);
660
+ format->palette = palette;
661
+
662
+ return ret;
663
+ }
664
+
665
+ static VALUE Surface_h(VALUE self) {
666
+ DEFINE_SELF(Surface, surface, self);
667
+
668
+ return INT2NUM(surface->h);
669
+ }
670
+
671
+ static VALUE Surface_index(VALUE self, VALUE x, VALUE y) {
672
+ DEFINE_SELF(Surface, surface, self);
673
+
674
+ return UINT2NUM(sge_GetPixel(surface,
675
+ NUM2SINT16(x), NUM2SINT16(y)));
676
+ }
677
+
678
+ static VALUE Surface_index_equals(VALUE self, VALUE x, VALUE y, VALUE color) {
679
+ DEFINE_SELF(Surface, surface, self);
680
+
681
+ sge_PutPixel(surface,
682
+ NUM2SINT16(x), NUM2SINT16(y),
683
+ VALUE2COLOR(color, surface->format));
684
+
685
+ return Qnil;
686
+ }
687
+
688
+ static VALUE Surface_make_collision_map(VALUE self) {
689
+ DEFINE_SELF(Surface, surface, self);
690
+
691
+ sge_cdata * cdata = sge_make_cmap(surface);
692
+
693
+ if (!cdata)
694
+ FAILURE("Surface#make_collision_map");
695
+
696
+ return TypedData_Wrap_Struct(cCollisionMap, &_CollisionMap_type, cdata);
697
+ }
698
+
699
+ static VALUE Surface_w(VALUE self) {
700
+ DEFINE_SELF(Surface, surface, self);
701
+
702
+ return INT2NUM(surface->w);
703
+ }
704
+
705
+ static VALUE Surface_transform(VALUE self, VALUE bgcolor, VALUE angle,
706
+ VALUE xscale, VALUE yscale, VALUE flags) {
707
+ DEFINE_SELF(Surface, surface, self);
708
+
709
+ SDL_Surface *result = sge_transform_surface(surface,
710
+ VALUE2COLOR(bgcolor, surface->format),
711
+ NUM2FLT(angle),
712
+ NUM2FLT(xscale),
713
+ NUM2FLT(yscale),
714
+ NUM2UINT8(flags));
715
+ if (!result)
716
+ FAILURE("Surface#transform");
717
+
718
+ if (SDL_SetColorKey(result,
719
+ SDL_SRCCOLORKEY|SDL_RLEACCEL,
720
+ surface->format->colorkey) < 0)
721
+ FAILURE("Surface#transform(set_color_key)");
722
+
723
+
724
+ if (SDL_SetAlpha(result, SDL_SRCALPHA|SDL_RLEACCEL, surface->format->alpha))
725
+ FAILURE("Surface#transform(set_alpha)");
726
+
727
+ return TypedData_Wrap_Struct(cSurface, &_Surface_type, result);
728
+ }
729
+
730
+ //// SDL::TTFFont methods:
731
+
732
+ static void _TTFFont_free(void* font) {
733
+ if (is_quit) return;
734
+ if (font) TTF_CloseFont(font);
735
+ }
736
+
737
+ static void _TTFFont_mark(void* p) {
738
+ UNUSED(p);
739
+ }
740
+
741
+ static VALUE Font_s_open(VALUE self, VALUE path, VALUE size) {
742
+ UNUSED(self);
743
+
744
+ ExportStringValue(path);
745
+
746
+ TTF_Font* font = TTF_OpenFont(RSTRING_PTR(path), NUM2UINT16(size));
747
+
748
+ if (!font)
749
+ FAILURE("Font.open");
750
+
751
+ return TypedData_Wrap_Struct(cTTFFont, &_TTFFont_type, font);
752
+ }
753
+
754
+ static VALUE Font_height(VALUE self) {
755
+ DEFINE_SELF(TTFFont, font, self);
756
+
757
+ return INT2FIX(TTF_FontHeight(font));
758
+ }
759
+
760
+ static VALUE Font_render(VALUE self, VALUE dst, VALUE text, VALUE c) {
761
+ DEFINE_SELF(TTFFont, font, self);
762
+ DEFINE_SELF(Surface, surface, dst);
763
+
764
+ SDL_Surface *result;
765
+
766
+ SDL_Color fg = sge_GetRGB(surface, VALUE2COLOR(c, surface->format));
767
+
768
+ ExportStringValue(text);
769
+ result = TTF_RenderUTF8_Blended(font, StringValueCStr(text), fg);
770
+
771
+ if (result) return TypedData_Wrap_Struct(cSurface, &_Surface_type, result);
772
+ return Qnil;
773
+ }
774
+
775
+ static VALUE Font_draw(VALUE self, VALUE dst, VALUE text, VALUE x, VALUE y, VALUE c) {
776
+ VALUE img = Font_render(self, dst, text, c);
777
+ VALUE zero = INT2FIX(0);
778
+
779
+ Surface_s_blit(cSurface, img, zero, zero, zero, zero, dst, x, y);
780
+
781
+ return Qnil;
782
+ }
783
+
784
+ //// SDL::WM methods:
785
+
786
+ static VALUE WM_s_set_caption(VALUE mod, VALUE title, VALUE icon) {
787
+ UNUSED(mod);
788
+ ExportStringValue(title);
789
+ ExportStringValue(icon);
790
+
791
+ SDL_WM_SetCaption(StringValueCStr(title), StringValueCStr(icon));
792
+
793
+ return Qnil;
794
+ }
795
+
796
+ // The Rest...
797
+
798
+ void Init_sdl() {
799
+
800
+ mSDL = rb_define_module("SDL");
801
+ mKey = rb_define_module_under(mSDL, "Key");
802
+ mWM = rb_define_module_under(mSDL, "WM");
803
+ mMouse = rb_define_module_under(mSDL, "Mouse");
804
+
805
+ cAudio = rb_define_class_under(mSDL, "Audio", rb_cData);
806
+ cCollisionMap = rb_define_class_under(mSDL, "CollisionMap", rb_cData);
807
+ cEvent = rb_define_class_under(mSDL, "Event", rb_cObject);
808
+ cPixelFormat = rb_define_class_under(mSDL, "PixelFormat", rb_cData);
809
+ cSurface = rb_define_class_under(mSDL, "Surface", rb_cData);
810
+ cTTFFont = rb_define_class_under(mSDL, "TTF", rb_cData); // TODO: Font
811
+
812
+ cScreen = rb_define_class_under(mSDL, "Screen", cSurface);
813
+
814
+ cEventQuit = rb_define_class_under(cEvent, "Quit", cEvent);
815
+ cEventKeydown = rb_define_class_under(cEvent, "Keydown", cEvent);
816
+ cEventKeyup = rb_define_class_under(cEvent, "Keyup", cEvent);
817
+
818
+ cEventMousemove = rb_define_class_under(cEvent, "Mousemove", cEvent);
819
+ cEventMousedown = rb_define_class_under(cEvent, "Mousedown", cEvent);
820
+ cEventMouseup = rb_define_class_under(cEvent, "Mouseup", cEvent);
821
+
822
+ eSDLError = rb_define_class_under(mSDL, "Error", rb_eStandardError);
823
+ eSDLMem = rb_define_class_under(cSurface, "VideoMemoryLost", rb_eStandardError);
824
+
825
+ //// SDL methods:
826
+
827
+ rb_define_module_function(mSDL, "init", sdl_s_init, 1);
828
+
829
+ //// SDL::Audio methods:
830
+
831
+ rb_define_singleton_method(cAudio, "open", Audio_s_open, 1);
832
+ rb_define_singleton_method(cAudio, "load", Audio_s_load, 1);
833
+ rb_define_method(cAudio, "play", Audio_play, 0);
834
+
835
+ //// SDL::CollisionMap methods:
836
+
837
+ rb_define_method(cCollisionMap, "check", CollisionMap_check, 5);
838
+
839
+ //// SDL::Event methods:
840
+
841
+ rb_define_singleton_method(cEvent, "poll", Event_s_poll, 0);
842
+
843
+ rb_define_attr(cEventKeydown, "press", 1, 1);
844
+ rb_define_attr(cEventKeydown, "sym", 1, 1);
845
+ rb_define_attr(cEventKeydown, "mod", 1, 1);
846
+ rb_define_attr(cEventKeydown, "unicode", 1, 1);
847
+
848
+ rb_define_attr(cEventKeyup, "press", 1, 1); // TODO: refactor, possibly subclass
849
+ rb_define_attr(cEventKeyup, "sym", 1, 1);
850
+ rb_define_attr(cEventKeyup, "mod", 1, 1);
851
+ rb_define_attr(cEventKeyup, "unicode", 1, 1);
852
+
853
+ rb_define_attr(cEventMousemove, "state", 1, 1);
854
+ rb_define_attr(cEventMousemove, "x", 1, 1);
855
+ rb_define_attr(cEventMousemove, "y", 1, 1);
856
+ rb_define_attr(cEventMousemove, "xrel", 1, 1);
857
+ rb_define_attr(cEventMousemove, "yrel", 1, 1);
858
+
859
+ rb_define_attr(cEventMousedown, "button", 1, 1);
860
+ rb_define_attr(cEventMousedown, "press", 1, 1);
861
+ rb_define_attr(cEventMousedown, "x", 1, 1);
862
+ rb_define_attr(cEventMousedown, "y", 1, 1);
863
+
864
+ rb_define_attr(cEventMouseup, "button", 1, 1);
865
+ rb_define_attr(cEventMouseup, "press", 1, 1);
866
+ rb_define_attr(cEventMouseup, "x", 1, 1);
867
+ rb_define_attr(cEventMouseup, "y", 1, 1);
868
+
869
+ //// SDL::Key methods:
870
+
871
+ rb_define_module_function(mKey, "press?", Key_s_press_p, 1);
872
+ rb_define_module_function(mKey, "scan", Key_s_scan, 0);
873
+
874
+ //// SDL::Mouse methods:
875
+
876
+ rb_define_module_function(mMouse, "state", Mouse_s_state, 0);
877
+
878
+ //// SDL::PixelFormat methods:
879
+
880
+ rb_define_method(cPixelFormat, "get_rgb", PixelFormat_get_rgb, 1);
881
+ rb_define_method(cPixelFormat, "map_rgba", PixelFormat_map_rgba, 4);
882
+ rb_define_method(cPixelFormat, "colorkey", PixelFormat_colorkey, 0);
883
+ rb_define_method(cPixelFormat, "alpha", PixelFormat_alpha, 0);
884
+
885
+ //// SDL::Screen methods:
886
+
887
+ rb_define_singleton_method(cScreen, "open", Screen_s_open, 4);
888
+ rb_define_method(cScreen, "flip", Screen_flip, 0);
889
+ rb_define_method(cScreen, "update", Screen_update, 4);
890
+
891
+ //// SDL::Surface methods:
892
+
893
+ rb_define_singleton_method(cSurface, "blit", Surface_s_blit, 8);
894
+ rb_define_singleton_method(cSurface, "new", Surface_s_new, 3);
895
+ rb_define_singleton_method(cSurface, "load", Surface_s_load, 1);
896
+ rb_define_method(cSurface, "set_color_key", Surface_set_color_key, 2);
897
+ rb_define_method(cSurface, "draw_bezier", Surface_draw_bezier, 10);
898
+ rb_define_method(cSurface, "draw_circle", Surface_draw_circle, 4);
899
+ rb_define_method(cSurface, "fill_circle", Surface_fill_circle, 4);
900
+ rb_define_method(cSurface, "draw_ellipse", Surface_draw_ellipse, 5);
901
+ rb_define_method(cSurface, "fill_ellipse", Surface_fill_ellipse, 5);
902
+ rb_define_method(cSurface, "draw_line", Surface_draw_line, 5);
903
+ rb_define_method(cSurface, "draw_rect", Surface_draw_rect, 5);
904
+ rb_define_method(cSurface, "fill_rect", Surface_fill_rect, 5);
905
+ rb_define_method(cSurface, "fast_rect", Surface_fast_rect, 5);
906
+ rb_define_method(cSurface, "format", Surface_format, 0);
907
+ rb_define_method(cSurface, "h", Surface_h, 0);
908
+ rb_define_method(cSurface, "make_collision_map", Surface_make_collision_map, 0);
909
+ rb_define_method(cSurface, "w", Surface_w, 0);
910
+ rb_define_method(cSurface, "[]", Surface_index, 2);
911
+ rb_define_method(cSurface, "[]=", Surface_index_equals, 3);
912
+ rb_define_method(cSurface, "transform", Surface_transform, 5);
913
+ rb_define_method(cSurface, "flags", Surface_flags, 0);
914
+ rb_define_method(cSurface, "set_alpha", Surface_set_alpha, 2);
915
+
916
+ //// SDL::TTFFont methods:
917
+
918
+ rb_define_singleton_method(cTTFFont, "open", Font_s_open, 2);
919
+
920
+ rb_define_method(cTTFFont, "height", Font_height, 0);
921
+ rb_define_method(cTTFFont, "render", Font_render, 3);
922
+ rb_define_method(cTTFFont, "draw", Font_draw, 5);
923
+
924
+ //// SDL::WM methods:
925
+
926
+ rb_define_module_function(mWM, "set_caption", WM_s_set_caption, 2);
927
+
928
+ //// Other Init Actions:
929
+
930
+ sge_Lock_ON();
931
+ sge_Update_OFF();
932
+ SDL_EnableUNICODE(1);
933
+
934
+ for (int i=0; i < SDL_NUMEVENTS; ++i)
935
+ event_creators[i] = Event__null;
936
+
937
+ // event_creators[SDL_ACTIVEEVENT] = Event__active;
938
+ event_creators[SDL_KEYDOWN] = Event__keydown;
939
+ event_creators[SDL_KEYUP] = Event__keyup;
940
+ event_creators[SDL_MOUSEMOTION] = Event__mousemove;
941
+ event_creators[SDL_MOUSEBUTTONDOWN] = Event__mousedown;
942
+ event_creators[SDL_MOUSEBUTTONUP] = Event__mouseup;
943
+ event_creators[SDL_QUIT] = Event__quit;
944
+ // event_creators[SDL_SYSWMEVENT] = Event__syswm;
945
+ // event_creators[SDL_VIDEORESIZE] = Event__videoresize;
946
+
947
+ rb_set_end_proc(sdl__quit, 0);
948
+
949
+ //// Simple Mapped Constants:
950
+
951
+ INIT_ID(button);
952
+ INIT_ID(mod);
953
+ INIT_ID(press);
954
+ INIT_ID(state);
955
+ INIT_ID(sym);
956
+ INIT_ID(unicode);
957
+ INIT_ID(x);
958
+ INIT_ID(xrel);
959
+ INIT_ID(y);
960
+ INIT_ID(yrel);
961
+
962
+ #define DC(n) rb_define_const(mSDL, #n, UINT2NUM(SDL_##n))
963
+ DC(DOUBLEBUF);
964
+ DC(HWSURFACE);
965
+ DC(INIT_EVERYTHING);
966
+ DC(INIT_VIDEO);
967
+ DC(RLEACCEL);
968
+ DC(SRCALPHA);
969
+ DC(SRCCOLORKEY);
970
+ DC(SWSURFACE);
971
+
972
+ // DC("ANYFORMAT");
973
+ // DC("ASYNCBLIT");
974
+ // DC("FULLSCREEN");
975
+ // DC("HWACCEL");
976
+ // DC("HWPALETTE");
977
+ // DC("NOFRAME");
978
+ // DC("OPENGL");
979
+ // DC("OPENGLBLIT");
980
+ // DC("PREALLOC");
981
+ // DC("RESIZABLE");
982
+ // DC("RLEACCELOK");
983
+
984
+ //// Keyboard Constants
985
+
986
+ #define _KEY(n, v) rb_define_const(mKey, (n), INT2NUM(v))
987
+ #define KEY(n, v) _KEY(n, SDLK_##v)
988
+ #define DK(n) _KEY(#n, SDLK_##n)
989
+ #define DKP(n) _KEY("K"#n, SDLK_##n)
990
+ #define DM(n) _KEY("MOD_"#n, KMOD_##n)
991
+ #define DR(n) _KEY("DEFAULT_REPEAT_"#n, SDL_DEFAULT_REPEAT_##n)
992
+
993
+ DK(UNKNOWN); DK(FIRST); DK(BACKSPACE); DK(TAB); DK(CLEAR);
994
+ DK(RETURN); DK(PAUSE); DK(ESCAPE); DK(SPACE); DK(EXCLAIM);
995
+ DK(QUOTEDBL); DK(HASH); DK(DOLLAR); DK(AMPERSAND); DK(QUOTE);
996
+ DK(LEFTPAREN); DK(RIGHTPAREN); DK(ASTERISK); DK(PLUS); DK(COMMA);
997
+ DK(MINUS); DK(PERIOD); DK(SLASH); DK(QUESTION); DK(AT);
998
+ DK(COLON); DK(SEMICOLON); DK(LESS); DK(EQUALS); DK(GREATER);
999
+
1000
+ DKP(0); DKP(1); DKP(2); DKP(3); DKP(4); DKP(5); DKP(6); DKP(7); DKP(8); DKP(9);
1001
+
1002
+ DK(LEFTBRACKET); DK(BACKSLASH); DK(RIGHTBRACKET); DK(CARET);
1003
+ DK(UNDERSCORE); DK(BACKQUOTE); DK(DELETE);
1004
+
1005
+ // Skip uppercase letters
1006
+ KEY("A", a); KEY("B", b); KEY("C", c); KEY("D", d); KEY("E", e);
1007
+ KEY("F", f); KEY("G", g); KEY("H", h); KEY("I", i); KEY("J", j);
1008
+ KEY("K", k); KEY("L", l); KEY("M", m); KEY("N", n); KEY("O", o);
1009
+ KEY("P", p); KEY("Q", q); KEY("R", r); KEY("S", s); KEY("T", t);
1010
+ KEY("U", u); KEY("V", v); KEY("W", w); KEY("X", x); KEY("Y", y);
1011
+ KEY("Z", z);
1012
+
1013
+ // International keyboard syms
1014
+ DK(WORLD_0); DK(WORLD_1); DK(WORLD_2); DK(WORLD_3); DK(WORLD_4);
1015
+ DK(WORLD_5); DK(WORLD_6); DK(WORLD_7); DK(WORLD_8); DK(WORLD_9);
1016
+ DK(WORLD_10); DK(WORLD_11); DK(WORLD_12); DK(WORLD_13); DK(WORLD_14);
1017
+ DK(WORLD_15); DK(WORLD_16); DK(WORLD_17); DK(WORLD_18); DK(WORLD_19);
1018
+ DK(WORLD_20); DK(WORLD_21); DK(WORLD_22); DK(WORLD_23); DK(WORLD_24);
1019
+ DK(WORLD_25); DK(WORLD_26); DK(WORLD_27); DK(WORLD_28); DK(WORLD_29);
1020
+ DK(WORLD_30); DK(WORLD_31); DK(WORLD_32); DK(WORLD_33); DK(WORLD_34);
1021
+ DK(WORLD_35); DK(WORLD_36); DK(WORLD_37); DK(WORLD_38); DK(WORLD_39);
1022
+ DK(WORLD_40); DK(WORLD_41); DK(WORLD_42); DK(WORLD_43); DK(WORLD_44);
1023
+ DK(WORLD_45); DK(WORLD_46); DK(WORLD_47); DK(WORLD_48); DK(WORLD_49);
1024
+ DK(WORLD_50); DK(WORLD_51); DK(WORLD_52); DK(WORLD_53); DK(WORLD_54);
1025
+ DK(WORLD_55); DK(WORLD_56); DK(WORLD_57); DK(WORLD_58); DK(WORLD_59);
1026
+ DK(WORLD_60); DK(WORLD_61); DK(WORLD_62); DK(WORLD_63); DK(WORLD_64);
1027
+ DK(WORLD_65); DK(WORLD_66); DK(WORLD_67); DK(WORLD_68); DK(WORLD_69);
1028
+ DK(WORLD_70); DK(WORLD_71); DK(WORLD_72); DK(WORLD_73); DK(WORLD_74);
1029
+ DK(WORLD_75); DK(WORLD_76); DK(WORLD_77); DK(WORLD_78); DK(WORLD_79);
1030
+ DK(WORLD_80); DK(WORLD_81); DK(WORLD_82); DK(WORLD_83); DK(WORLD_84);
1031
+ DK(WORLD_85); DK(WORLD_86); DK(WORLD_87); DK(WORLD_88); DK(WORLD_89);
1032
+ DK(WORLD_90); DK(WORLD_91); DK(WORLD_92); DK(WORLD_93); DK(WORLD_94);
1033
+ DK(WORLD_95);
1034
+
1035
+ // Numeric keypad
1036
+ DK(KP0); DK(KP1); DK(KP2); DK(KP3); DK(KP4);
1037
+ DK(KP5); DK(KP6); DK(KP7); DK(KP8); DK(KP9);
1038
+
1039
+ DK(KP_PERIOD); DK(KP_DIVIDE); DK(KP_MULTIPLY); DK(KP_MINUS);
1040
+ DK(KP_PLUS); DK(KP_ENTER); DK(KP_EQUALS);
1041
+
1042
+ // Arrows + Home/End pad
1043
+ DK(UP); DK(DOWN); DK(RIGHT); DK(LEFT); DK(INSERT);
1044
+ DK(HOME); DK(END); DK(PAGEUP); DK(PAGEDOWN);
1045
+
1046
+ // Function keys
1047
+ DK(F1); DK(F2); DK(F3); DK(F4); DK(F5); DK(F6); DK(F7); DK(F8); DK(F9);
1048
+ DK(F10); DK(F11); DK(F12); DK(F13); DK(F14); DK(F15);
1049
+
1050
+ // Key state modifier keys
1051
+ DK(NUMLOCK); DK(CAPSLOCK); DK(SCROLLOCK); DK(RSHIFT); DK(LSHIFT); DK(RCTRL);
1052
+ DK(LCTRL); DK(RALT); DK(LALT); DK(RMETA); DK(LMETA); DK(LSUPER); DK(RSUPER);
1053
+ DK(MODE);
1054
+
1055
+ // Miscellaneous function keys
1056
+ DK(HELP); DK(PRINT); DK(SYSREQ); DK(BREAK);
1057
+ DK(MENU); DK(POWER); DK(EURO); DK(LAST);
1058
+
1059
+ // key mods
1060
+ DM(NONE); DM(LSHIFT); DM(RSHIFT); DM(LCTRL); DM(RCTRL); DM(LALT); DM(RALT);
1061
+ DM(LMETA); DM(RMETA); DM(NUM); DM(CAPS); DM(MODE); DM(RESERVED); DM(CTRL);
1062
+ DM(SHIFT); DM(ALT); DM(META);
1063
+
1064
+ // key repeat constants
1065
+ DR(DELAY);
1066
+ DR(INTERVAL);
1067
+ }