graphics 1.0.0b1 → 1.0.0b4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
}
|