graphics 1.0.0b1 → 1.0.0b4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/History.rdoc +30 -0
- data/Manifest.txt +39 -7
- data/README.rdoc +48 -4
- data/Rakefile +8 -2
- data/examples/boid.rb +9 -18
- data/examples/bounce.rb +15 -23
- data/examples/canvas.rb +75 -0
- data/examples/collision.rb +6 -6
- data/examples/demo.rb +5 -7
- data/examples/editor.rb +12 -9
- data/examples/fluid.rb +2 -3
- data/examples/fluid2.rb +1 -1
- data/examples/{lito2.rb → gol.rb} +0 -0
- data/examples/{zenspider4.rb → gol2.rb} +0 -0
- data/examples/logo.rb +4 -7
- data/examples/maze.rb +136 -0
- data/examples/tank.rb +10 -11
- data/examples/tank2.rb +12 -17
- data/examples/targeting.rb +1 -1
- data/examples/vants.rb +1 -1
- data/examples/walker.rb +3 -12
- data/examples/walker2.rb +197 -0
- data/examples/zombies.rb +31 -35
- data/ext/sdl/extconf.rb +31 -0
- data/ext/sdl/sdl.c +1067 -0
- data/ext/sdl/sge/INSTALL +72 -0
- data/ext/sdl/sge/LICENSE +504 -0
- data/ext/sdl/sge/Makefile +83 -0
- data/ext/sdl/sge/Makefile.conf +63 -0
- data/ext/sdl/sge/README +219 -0
- data/ext/sdl/sge/Todo +7 -0
- data/ext/sdl/sge/WhatsNew +224 -0
- data/ext/sdl/sge/sge.h +31 -0
- data/ext/sdl/sge/sge_blib.cpp +1939 -0
- data/ext/sdl/sge/sge_blib.h +68 -0
- data/ext/sdl/sge/sge_bm_text.cpp +451 -0
- data/ext/sdl/sge/sge_bm_text.h +71 -0
- data/ext/sdl/sge/sge_collision.cpp +388 -0
- data/ext/sdl/sge/sge_collision.h +54 -0
- data/ext/sdl/sge/sge_config.h +6 -0
- data/ext/sdl/sge/sge_internal.h +152 -0
- data/ext/sdl/sge/sge_misc.cpp +92 -0
- data/ext/sdl/sge/sge_misc.h +37 -0
- data/ext/sdl/sge/sge_primitives.cpp +2516 -0
- data/ext/sdl/sge/sge_primitives.h +111 -0
- data/ext/sdl/sge/sge_rotation.cpp +683 -0
- data/ext/sdl/sge/sge_rotation.h +46 -0
- data/ext/sdl/sge/sge_shape.cpp +762 -0
- data/ext/sdl/sge/sge_shape.h +365 -0
- data/ext/sdl/sge/sge_surface.cpp +1090 -0
- data/ext/sdl/sge/sge_surface.h +100 -0
- data/ext/sdl/sge/sge_textpp.cpp +785 -0
- data/ext/sdl/sge/sge_textpp.h +270 -0
- data/ext/sdl/sge/sge_tt_text.cpp +1456 -0
- data/ext/sdl/sge/sge_tt_text.h +114 -0
- data/graphics_setup.sh +26 -0
- data/lib/graphics.rb +1 -1
- data/lib/graphics/body.rb +50 -3
- data/lib/graphics/extensions.rb +13 -7
- data/lib/graphics/simulation.rb +126 -46
- data/test/test_graphics.rb +52 -12
- data/test/test_sdl.rb +1 -0
- metadata +54 -23
- metadata.gz.sig +0 -0
- data/.gemtest +0 -0
- data/examples/lito.rb +0 -108
- data/examples/zenspider1.rb +0 -93
- data/examples/zenspider2.rb +0 -123
- data/examples/zenspider3.rb +0 -104
- data/rubysdl_setup.sh +0 -34
data/examples/zombies.rb
CHANGED
@@ -126,11 +126,11 @@ class Person < Entity
|
|
126
126
|
end
|
127
127
|
|
128
128
|
def update_infection
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
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
|
-
|
194
|
-
|
195
|
-
|
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
|
-
|
199
|
-
|
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
|
292
|
-
|
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
|
-
|
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
|
-
|
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
|
data/ext/sdl/extconf.rb
ADDED
@@ -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"
|
data/ext/sdl/sdl.c
ADDED
@@ -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
|
+
}
|