texplay 0.3.0-i386-mswin32 → 0.3.1-i386-mswin32
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.
- data/CHANGELOG +3 -0
- data/README.markdown +1 -1
- data/Rakefile +16 -10
- data/ext/texplay/utils.c +430 -426
- data/lib/1.8/texplay.so +0 -0
- data/lib/1.9/texplay.so +0 -0
- data/lib/texplay/version.rb +1 -1
- metadata +9 -5
data/ext/texplay/utils.c
CHANGED
@@ -18,18 +18,18 @@
|
|
18
18
|
#endif
|
19
19
|
|
20
20
|
/*
|
21
|
-
#define MULT_FLOAT4(X, Y) ({ \
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
#define COPY_FLOAT4(X, Y) ({ \
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
21
|
+
#define MULT_FLOAT4(X, Y) ({ \
|
22
|
+
asm volatile ( \
|
23
|
+
"movups (%0), %%xmm0\n\t" \
|
24
|
+
"mulps (%1), %%xmm0\n\t" \
|
25
|
+
"movups %%xmm0, (%1)" \
|
26
|
+
:: "r" (X), "r" (Y)); })
|
27
|
+
|
28
|
+
#define COPY_FLOAT4(X, Y) ({ \
|
29
|
+
asm volatile ( \
|
30
|
+
"movups (%0), %%xmm0\n\t" \
|
31
|
+
"movups %%xmm0, (%1)" \
|
32
|
+
:: "r" (X), "r" (Y)); })
|
33
33
|
|
34
34
|
*/
|
35
35
|
/* external linkage with static duration */
|
@@ -39,70 +39,70 @@ const rgba not_a_color_v = { -1.0, -1.0, -1.0, -1.0 };
|
|
39
39
|
char*
|
40
40
|
lowercase(char * string)
|
41
41
|
{
|
42
|
-
|
42
|
+
int i = 0;
|
43
43
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
44
|
+
while (string[i]) {
|
45
|
+
string[i] = tolower(string[i]);
|
46
|
+
i++;
|
47
|
+
}
|
48
48
|
|
49
|
-
|
49
|
+
return string;
|
50
50
|
}
|
51
51
|
|
52
52
|
char*
|
53
53
|
sym2string(VALUE sym)
|
54
54
|
{
|
55
|
-
|
55
|
+
return rb_id2name(SYM2ID(sym));
|
56
56
|
}
|
57
57
|
|
58
58
|
VALUE
|
59
59
|
string2sym(char * string)
|
60
60
|
{
|
61
|
-
|
61
|
+
return ID2SYM(rb_intern(string));
|
62
62
|
}
|
63
63
|
|
64
64
|
bool
|
65
65
|
is_a_hash(VALUE try_hash)
|
66
66
|
{
|
67
|
-
|
67
|
+
return TYPE(try_hash) == T_HASH;
|
68
68
|
}
|
69
69
|
|
70
70
|
bool
|
71
71
|
is_an_array(VALUE try_array)
|
72
72
|
{
|
73
|
-
|
73
|
+
return TYPE(try_array) == T_ARRAY;
|
74
74
|
}
|
75
75
|
|
76
76
|
bool is_a_num(VALUE try_num)
|
77
77
|
{
|
78
|
-
|
78
|
+
return TYPE(try_num) == T_FIXNUM || TYPE(try_num) == T_FLOAT;
|
79
79
|
}
|
80
80
|
|
81
81
|
VALUE
|
82
82
|
get_from_hash(VALUE hash, char * sym)
|
83
83
|
{
|
84
84
|
|
85
|
-
|
85
|
+
if(TYPE(hash) != T_HASH) rb_raise(rb_eArgError, "hash argument expected");
|
86
86
|
|
87
|
-
|
87
|
+
return rb_hash_aref(hash, string2sym(sym));
|
88
88
|
}
|
89
89
|
|
90
90
|
VALUE
|
91
91
|
set_hash_value(VALUE hash, char * sym, VALUE val)
|
92
92
|
{
|
93
|
-
|
93
|
+
if(TYPE(hash) != T_HASH) rb_raise(rb_eArgError, "hash argument expected");
|
94
94
|
|
95
|
-
|
95
|
+
rb_hash_aset(hash, string2sym(sym), val);
|
96
96
|
|
97
|
-
|
97
|
+
return val;
|
98
98
|
}
|
99
99
|
|
100
100
|
VALUE
|
101
101
|
delete_from_hash(VALUE hash, char * sym)
|
102
102
|
{
|
103
|
-
|
103
|
+
if(TYPE(hash) != T_HASH) rb_raise(rb_eArgError, "hash argument expected");
|
104
104
|
|
105
|
-
|
105
|
+
return rb_hash_delete(hash, string2sym(sym));
|
106
106
|
}
|
107
107
|
|
108
108
|
/* returns true if 'hash' is a hash and the value mapped to key 'sym' is
|
@@ -110,183 +110,183 @@ delete_from_hash(VALUE hash, char * sym)
|
|
110
110
|
bool
|
111
111
|
hash_value_is(VALUE hash, char * sym, VALUE val)
|
112
112
|
{
|
113
|
-
|
113
|
+
if(TYPE(hash) != T_HASH) return false;
|
114
114
|
|
115
|
-
|
116
|
-
|
115
|
+
if(get_from_hash(hash, sym) == val)
|
116
|
+
return true;
|
117
117
|
|
118
|
-
|
118
|
+
return false;
|
119
119
|
}
|
120
120
|
|
121
121
|
bool
|
122
122
|
has_optional_hash_arg(VALUE hash, char * sym)
|
123
123
|
{
|
124
|
-
|
124
|
+
if(TYPE(hash) != T_HASH) return false;
|
125
125
|
|
126
|
-
|
127
|
-
|
126
|
+
if(NIL_P(get_from_hash(hash, sym)))
|
127
|
+
return false;
|
128
128
|
|
129
|
-
|
130
|
-
|
129
|
+
/* 'hash' is a hash and the sym exists */
|
130
|
+
return true;
|
131
131
|
}
|
132
132
|
|
133
133
|
VALUE
|
134
134
|
set_array_value(VALUE array, int index, VALUE val)
|
135
135
|
{
|
136
|
-
|
136
|
+
if(TYPE(array) != T_ARRAY) rb_raise(rb_eArgError, "array argument expected");
|
137
137
|
|
138
|
-
|
138
|
+
rb_ary_store(array, index, val);
|
139
139
|
|
140
|
-
|
140
|
+
return val;
|
141
141
|
}
|
142
142
|
|
143
143
|
VALUE
|
144
144
|
get_from_array(VALUE array, int index)
|
145
145
|
{
|
146
146
|
|
147
|
-
|
147
|
+
if(TYPE(array) != T_ARRAY) rb_raise(rb_eArgError, "array argument expected");
|
148
148
|
|
149
|
-
|
149
|
+
return rb_ary_entry(array, index);
|
150
150
|
}
|
151
151
|
|
152
152
|
|
153
153
|
VALUE
|
154
154
|
init_image_local(VALUE image)
|
155
155
|
{
|
156
|
-
|
156
|
+
VALUE image_local;
|
157
157
|
|
158
|
-
|
159
|
-
|
158
|
+
if(!is_gosu_image(image))
|
159
|
+
rb_raise(rb_eArgError, "not a valid image");
|
160
160
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
161
|
+
/* initialize image_local hash if does not exist */
|
162
|
+
if(!is_an_array(rb_iv_get(image, "__image_local__"))) {
|
163
|
+
image_local = rb_ary_new();
|
164
|
+
rb_iv_set(image, "__image_local__", image_local);
|
165
|
+
}
|
166
166
|
|
167
|
-
|
167
|
+
image_local = rb_iv_get(image, "__image_local__");
|
168
168
|
|
169
|
-
|
169
|
+
return image_local;
|
170
170
|
}
|
171
171
|
|
172
172
|
void
|
173
173
|
set_image_local(VALUE image, int name, VALUE val)
|
174
174
|
{
|
175
|
-
|
175
|
+
VALUE image_local;
|
176
176
|
|
177
|
-
|
177
|
+
image_local = init_image_local(image);
|
178
178
|
|
179
|
-
|
179
|
+
set_array_value(image_local, name, val);
|
180
180
|
}
|
181
181
|
|
182
182
|
VALUE
|
183
183
|
get_image_local(VALUE image, int name)
|
184
184
|
{
|
185
|
-
|
186
|
-
|
185
|
+
VALUE image_local;
|
186
|
+
VALUE val;
|
187
187
|
|
188
|
-
|
188
|
+
init_image_local(image);
|
189
189
|
|
190
|
-
|
191
|
-
|
190
|
+
/* this var holds all the image local variables in an array */
|
191
|
+
image_local = rb_iv_get(image, "__image_local__");
|
192
192
|
|
193
|
-
|
194
|
-
|
193
|
+
/* a particular image_local variable */
|
194
|
+
val = get_from_array(image_local, name);
|
195
195
|
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
}
|
196
|
+
/* if the variable exists then return it */
|
197
|
+
if(!NIL_P(val))
|
198
|
+
return val;
|
199
|
+
|
200
|
+
/* otherwise initialize the variable and then return it */
|
201
|
+
else {
|
202
|
+
switch(name) {
|
203
|
+
VALUE init_offset, init_bounds, init_color, init_defaults;
|
204
|
+
case DRAW_OFFSET:
|
205
|
+
init_offset = rb_ary_new2(2);
|
206
|
+
set_array_value(init_offset, 0, INT2FIX(0));
|
207
|
+
set_array_value(init_offset, 1, INT2FIX(0));
|
208
|
+
|
209
|
+
set_array_value(image_local, DRAW_OFFSET, init_offset);
|
210
|
+
|
211
|
+
return init_offset;
|
212
|
+
break;
|
213
|
+
case LAZY_BOUNDS:
|
214
|
+
init_bounds = rb_ary_new2(4);
|
215
|
+
set_array_value(init_bounds, 0, INT2FIX(XMAX_OOB));
|
216
|
+
set_array_value(init_bounds, 1, INT2FIX(YMAX_OOB));
|
217
|
+
set_array_value(init_bounds, 2, INT2FIX(XMIN_OOB));
|
218
|
+
set_array_value(init_bounds, 3, INT2FIX(YMIN_OOB));
|
219
|
+
|
220
|
+
set_array_value(image_local, LAZY_BOUNDS, init_bounds);
|
221
|
+
|
222
|
+
return init_bounds;
|
223
|
+
break;
|
224
|
+
case IMAGE_COLOR:
|
225
|
+
init_color = rb_ary_new2(4);
|
226
|
+
set_array_value(init_color, 0, rb_float_new(1.0));
|
227
|
+
set_array_value(init_color, 1, rb_float_new(1.0));
|
228
|
+
set_array_value(init_color, 2, rb_float_new(1.0));
|
229
|
+
set_array_value(init_color, 3, rb_float_new(1.0));
|
230
|
+
|
231
|
+
set_array_value(image_local, IMAGE_COLOR, init_color);
|
232
|
+
|
233
|
+
return init_color;
|
234
|
+
break;
|
235
|
+
case USER_DEFAULTS:
|
236
|
+
init_defaults = rb_hash_new();
|
237
|
+
|
238
|
+
set_array_value(image_local, USER_DEFAULTS, init_defaults);
|
239
|
+
|
240
|
+
return init_defaults;
|
241
|
+
break;
|
242
|
+
default:
|
243
|
+
rb_raise(rb_eArgError, "unrecognized image_local variable number. got %d", name);
|
245
244
|
}
|
245
|
+
}
|
246
246
|
|
247
|
-
|
248
|
-
|
247
|
+
/* never reached */
|
248
|
+
return Qnil;
|
249
249
|
}
|
250
250
|
|
251
251
|
rgba
|
252
252
|
convert_image_local_color_to_rgba(VALUE image)
|
253
253
|
{
|
254
|
-
|
255
|
-
|
254
|
+
rgba color;
|
255
|
+
VALUE image_local_color = get_image_local(image, IMAGE_COLOR);
|
256
256
|
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
257
|
+
color.red = NUM2DBL(get_from_array(image_local_color, red));
|
258
|
+
color.green = NUM2DBL(get_from_array(image_local_color, green));
|
259
|
+
color.blue = NUM2DBL(get_from_array(image_local_color, blue));
|
260
|
+
color.alpha = NUM2DBL(get_from_array(image_local_color, alpha));
|
261
261
|
|
262
|
-
|
262
|
+
return color;
|
263
263
|
}
|
264
264
|
|
265
265
|
VALUE
|
266
266
|
save_rgba_to_image_local_color(VALUE image, rgba color)
|
267
267
|
{
|
268
|
-
|
269
|
-
|
268
|
+
/* abbreviation for image_local_color */
|
269
|
+
VALUE ilc = get_image_local(image, IMAGE_COLOR);
|
270
270
|
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
271
|
+
set_array_value(ilc, 0, rb_float_new(color.red));
|
272
|
+
set_array_value(ilc, 1, rb_float_new(color.green));
|
273
|
+
set_array_value(ilc, 2, rb_float_new(color.blue));
|
274
|
+
set_array_value(ilc, 3, rb_float_new(color.alpha));
|
275
275
|
|
276
|
-
|
276
|
+
return ilc;
|
277
277
|
}
|
278
278
|
|
279
279
|
bool
|
280
280
|
not_a_color(rgba color1)
|
281
281
|
{
|
282
|
-
|
283
|
-
|
282
|
+
return color1.red == -1 || color1.green == -1 ||
|
283
|
+
color1.blue == -1 || color1.alpha == -1;
|
284
284
|
}
|
285
285
|
|
286
286
|
bool
|
287
287
|
is_a_color(rgba color1)
|
288
288
|
{
|
289
|
-
|
289
|
+
return !not_a_color(color1);
|
290
290
|
}
|
291
291
|
|
292
292
|
bool
|
@@ -310,30 +310,30 @@ not_rb_raw_color(VALUE cval)
|
|
310
310
|
static bool
|
311
311
|
is_transparent_color(rgba color1)
|
312
312
|
{
|
313
|
-
|
314
|
-
|
313
|
+
return color1.red == -666 && color1.green == -666 && color1.blue == -666 &&
|
314
|
+
color1.alpha == -666;
|
315
315
|
}
|
316
316
|
|
317
317
|
static bool
|
318
318
|
special_cmp_color(rgba color1, rgba color2)
|
319
319
|
{
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
320
|
+
if (is_transparent_color(color1))
|
321
|
+
return color2.alpha == 0;
|
322
|
+
else if (is_transparent_color(color2))
|
323
|
+
return color1.alpha == 0;
|
324
|
+
else
|
325
|
+
return false;
|
326
326
|
}
|
327
327
|
|
328
328
|
static bool
|
329
329
|
special_cmp_color_with_tolerance(rgba color1, rgba color2, float tolerance)
|
330
330
|
{
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
331
|
+
if (is_transparent_color(color1))
|
332
|
+
return (color2.alpha) <= tolerance;
|
333
|
+
else if (is_transparent_color(color2))
|
334
|
+
return color1.alpha <= tolerance;
|
335
|
+
else
|
336
|
+
return false;
|
337
337
|
}
|
338
338
|
|
339
339
|
|
@@ -359,11 +359,11 @@ cmp_color_with_tolerance(rgba color1, rgba color2, float tolerance)
|
|
359
359
|
bool
|
360
360
|
cmp_color(rgba color1, rgba color2)
|
361
361
|
{
|
362
|
-
|
363
|
-
|
362
|
+
if (color1.red < 0 || color2.red < 0)
|
363
|
+
return special_cmp_color(color1, color2);
|
364
364
|
|
365
|
-
|
366
|
-
|
365
|
+
return (color1.red == color2.red) && (color1.green == color2.green) && (color1.blue == color2.blue)
|
366
|
+
&& (color1.alpha == color2.alpha);
|
367
367
|
}
|
368
368
|
|
369
369
|
|
@@ -371,78 +371,78 @@ cmp_color(rgba color1, rgba color2)
|
|
371
371
|
void
|
372
372
|
color_copy(float * source, float * dest)
|
373
373
|
{
|
374
|
-
|
375
|
-
|
374
|
+
//COPY_FLOAT4(source, dest);
|
375
|
+
memcpy(dest, source, 4 * sizeof(float));
|
376
376
|
}
|
377
377
|
|
378
378
|
void
|
379
379
|
zero_color(float * tex)
|
380
380
|
{
|
381
|
-
|
381
|
+
memset(tex, 0, 4 * sizeof(float));
|
382
382
|
}
|
383
383
|
/*** ***/
|
384
384
|
|
385
385
|
rgba
|
386
386
|
find_color_from_string(char * try_color)
|
387
387
|
{
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
388
|
+
rgba cur_color;
|
389
|
+
|
390
|
+
if(!strcmp("red", try_color)) {
|
391
|
+
cur_color.red = 1.0; cur_color.green = 0.0; cur_color.blue = 0.0; cur_color.alpha = 1.0;
|
392
|
+
}
|
393
|
+
else if(!strcmp("green", try_color)) {
|
394
|
+
cur_color.red = 0.0; cur_color.green = 1.0; cur_color.blue = 0.0; cur_color.alpha = 1.0;
|
395
|
+
}
|
396
|
+
else if(!strcmp("blue", try_color)) {
|
397
|
+
cur_color.red = 0.0; cur_color.green = 0.0; cur_color.blue = 1.0; cur_color.alpha = 1.0;
|
398
|
+
}
|
399
|
+
else if(!strcmp("black", try_color)) {
|
400
|
+
cur_color.red = 0.0; cur_color.green = 0.0; cur_color.blue = 0.0; cur_color.alpha = 1.0;
|
401
|
+
}
|
402
|
+
else if(!strcmp("white", try_color)) {
|
403
|
+
cur_color.red = 1.0; cur_color.green = 1.0; cur_color.blue = 1.0; cur_color.alpha = 1.0;
|
404
|
+
}
|
405
|
+
else if(!strcmp("purple", try_color)) {
|
406
|
+
cur_color.red = 1.0; cur_color.green = 0.0; cur_color.blue = 1.0; cur_color.alpha = 1.0;
|
407
|
+
}
|
408
|
+
else if(!strcmp("yellow", try_color)) {
|
409
|
+
cur_color.red = 1.0; cur_color.green = 1.0; cur_color.blue = 0.0; cur_color.alpha = 1.0;
|
410
|
+
}
|
411
|
+
else if(!strcmp("cyan", try_color)) {
|
412
|
+
cur_color.red = 0.0; cur_color.green = 1.0; cur_color.blue = 1.0; cur_color.alpha = 1.0;
|
413
|
+
}
|
414
|
+
else if(!strcmp("orange", try_color)) {
|
415
|
+
cur_color.red = 1.0; cur_color.green = 0.5; cur_color.blue = 0.0; cur_color.alpha = 1.0;
|
416
|
+
}
|
417
|
+
else if(!strcmp("brown", try_color)) {
|
418
|
+
cur_color.red = 0.39; cur_color.green = 0.26; cur_color.blue = 0.13; cur_color.alpha = 1.0;
|
419
|
+
}
|
420
|
+
else if(!strcmp("turquoise", try_color)) {
|
421
|
+
cur_color.red = 0.1; cur_color.green = 0.6; cur_color.blue = 0.8; cur_color.alpha = 1.0;
|
422
|
+
}
|
423
|
+
else if(!strcmp("tyrian", try_color)) {
|
424
|
+
cur_color.red = 0.4; cur_color.green = 0.007; cur_color.blue = 0.235; cur_color.alpha = 1.0;
|
425
|
+
}
|
426
|
+
else if(!strcmp("alpha", try_color)) {
|
427
|
+
cur_color.red = 0.0; cur_color.green = 0.0; cur_color.blue = 0.0; cur_color.alpha = 0.0;
|
428
|
+
}
|
429
|
+
else if(!strcmp("transparent", try_color)) {
|
430
|
+
cur_color.red = -666; cur_color.green = -666; cur_color.blue = -666; cur_color.alpha = -666;
|
431
|
+
}
|
432
|
+
else if(!strcmp("none", try_color)) {
|
433
|
+
cur_color = not_a_color_v;
|
434
|
+
}
|
435
|
+
else if(!strcmp("random", try_color) || !strcmp("rand", try_color)) {
|
436
|
+
cur_color.red = rand() / (float)RAND_MAX;
|
437
|
+
cur_color.green = rand() / (float)RAND_MAX;
|
438
|
+
cur_color.blue = rand() / (float)RAND_MAX;
|
439
|
+
cur_color.alpha = 1.0;
|
440
|
+
}
|
441
|
+
|
442
|
+
else
|
443
|
+
rb_raise(rb_eArgError, "invalid colour specified (no color matches the symbol: %s)\n", try_color);
|
444
|
+
|
445
|
+
return cur_color;
|
446
446
|
}
|
447
447
|
|
448
448
|
rgba
|
@@ -450,11 +450,11 @@ convert_gosu_to_rgba_color(VALUE gcolor)
|
|
450
450
|
{
|
451
451
|
|
452
452
|
return (rgba) {
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
453
|
+
FIX2INT(rb_funcall(gcolor, rb_intern("red"), 0)) / 255.0,
|
454
|
+
FIX2INT(rb_funcall(gcolor, rb_intern("green"), 0)) / 255.0,
|
455
|
+
FIX2INT(rb_funcall(gcolor, rb_intern("blue"), 0)) / 255.0,
|
456
|
+
FIX2INT(rb_funcall(gcolor, rb_intern("alpha"), 0)) / 255.0
|
457
|
+
};
|
458
458
|
}
|
459
459
|
|
460
460
|
|
@@ -462,144 +462,144 @@ convert_gosu_to_rgba_color(VALUE gcolor)
|
|
462
462
|
VALUE
|
463
463
|
convert_rgba_to_rb_color(rgba * pix)
|
464
464
|
{
|
465
|
-
|
465
|
+
if (not_a_color(*pix)) return Qnil;
|
466
466
|
|
467
|
-
|
468
|
-
|
467
|
+
/* create a new ruby array to store the pixel data */
|
468
|
+
VALUE pix_array = rb_ary_new2(4);
|
469
469
|
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
470
|
+
/* store the pixel data */
|
471
|
+
rb_ary_store(pix_array, red, rb_float_new(pix->red));
|
472
|
+
rb_ary_store(pix_array, green, rb_float_new(pix->green));
|
473
|
+
rb_ary_store(pix_array, blue, rb_float_new(pix->blue));
|
474
|
+
rb_ary_store(pix_array, alpha, rb_float_new(pix->alpha));
|
475
475
|
|
476
|
-
|
476
|
+
return pix_array;
|
477
477
|
}
|
478
478
|
|
479
479
|
/* convert C color to gosu color */
|
480
480
|
VALUE
|
481
481
|
convert_rgba_to_gosu_color(rgba * pix)
|
482
482
|
{
|
483
|
-
|
483
|
+
if (not_a_color(*pix)) return Qnil;
|
484
484
|
|
485
|
-
|
485
|
+
VALUE gosu_color = rb_funcall(gosu_color_class(), rb_intern("new"), 0);
|
486
486
|
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
487
|
+
rb_funcall(gosu_color, rb_intern("red="), 1, INT2FIX(pix->red * 255));
|
488
|
+
rb_funcall(gosu_color, rb_intern("green="), 1, INT2FIX(pix->green * 255));
|
489
|
+
rb_funcall(gosu_color, rb_intern("blue="), 1, INT2FIX(pix->blue * 255));
|
490
|
+
rb_funcall(gosu_color, rb_intern("alpha="), 1, INT2FIX(pix->alpha * 255));
|
491
491
|
|
492
|
-
|
492
|
+
return gosu_color;
|
493
493
|
}
|
494
494
|
|
495
495
|
VALUE
|
496
496
|
gosu_color_class()
|
497
497
|
{
|
498
|
-
|
498
|
+
static VALUE gcolor_class = 0;
|
499
499
|
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
500
|
+
if (gcolor_class == 0) {
|
501
|
+
VALUE gosu_class = rb_const_get(rb_cObject, rb_intern("Gosu"));
|
502
|
+
gcolor_class = rb_const_get(gosu_class, rb_intern("Color"));
|
503
|
+
}
|
504
504
|
|
505
|
-
|
505
|
+
return gcolor_class;
|
506
506
|
}
|
507
507
|
|
508
508
|
/* convert Ruby color to C color */
|
509
509
|
rgba
|
510
510
|
convert_rb_color_to_rgba(VALUE cval)
|
511
511
|
{
|
512
|
-
|
512
|
+
rgba my_color;
|
513
513
|
|
514
|
-
|
514
|
+
if (is_gosu_color(cval)) return convert_gosu_to_rgba_color(cval);
|
515
515
|
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
516
|
+
/* current color for actions */
|
517
|
+
switch(TYPE(cval)) {
|
518
|
+
char * try_color;
|
519
|
+
case T_SYMBOL:
|
520
|
+
try_color = lowercase(sym2string(cval));
|
521
521
|
|
522
|
-
|
522
|
+
my_color = find_color_from_string(try_color);
|
523
523
|
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
524
|
+
break;
|
525
|
+
case T_ARRAY:
|
526
|
+
my_color.red = NUM2DBL(rb_ary_entry(cval, red));
|
527
|
+
my_color.green = NUM2DBL(rb_ary_entry(cval, green));
|
528
|
+
my_color.blue = NUM2DBL(rb_ary_entry(cval, blue));
|
529
529
|
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
530
|
+
if(NUM2INT(rb_funcall(cval, rb_intern("length"), 0)) > 3)
|
531
|
+
my_color.alpha = NUM2DBL(rb_ary_entry(cval, alpha));
|
532
|
+
else
|
533
|
+
my_color.alpha = 1;
|
534
534
|
|
535
|
-
|
535
|
+
break;
|
536
536
|
|
537
537
|
/* hex literals */
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
538
|
+
case T_FIXNUM:
|
539
|
+
case T_BIGNUM:
|
540
|
+
return convert_gosu_to_rgba_color(rb_funcall(gosu_color_class(),
|
541
|
+
rb_intern("new"), 1, cval));
|
542
542
|
break;
|
543
543
|
|
544
|
-
|
545
|
-
|
546
|
-
|
544
|
+
default:
|
545
|
+
rb_raise(rb_eArgError, "unsupported argument type for color. Got type 0x%x\n", TYPE(cval) );
|
546
|
+
}
|
547
547
|
|
548
|
-
|
549
|
-
|
550
|
-
|
548
|
+
/* a valid color */
|
549
|
+
if(is_a_color(my_color))
|
550
|
+
return my_color;
|
551
551
|
|
552
|
-
|
553
|
-
|
554
|
-
|
552
|
+
/* special condition for when color is taken from outside range of bitmap. Color is just ignored */
|
553
|
+
else if(not_a_color(my_color))
|
554
|
+
return not_a_color_v;
|
555
555
|
|
556
|
-
|
557
|
-
|
558
|
-
|
556
|
+
/* anything else should fail */
|
557
|
+
else
|
558
|
+
rb_raise(rb_eArgError, "invalid colour specified (negative value given)\n");
|
559
559
|
}
|
560
560
|
|
561
561
|
/* error checking functions */
|
562
562
|
void
|
563
563
|
check_mask(VALUE mask)
|
564
564
|
{
|
565
|
-
|
565
|
+
char * try_mask;
|
566
566
|
|
567
|
-
|
568
|
-
|
567
|
+
if(TYPE(mask) != T_ARRAY && TYPE(mask) != T_SYMBOL)
|
568
|
+
rb_raise(rb_eArgError, "array or symbol parameter required");
|
569
569
|
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
}
|
570
|
+
/* is it a valid mask symbol? */
|
571
|
+
if(TYPE(mask) == T_SYMBOL) {
|
572
|
+
try_mask = lowercase(sym2string(mask));
|
573
|
+
if(*try_mask == '_') try_mask++;
|
574
|
+
if(not_a_color(find_color_from_string(try_mask))) {
|
575
|
+
rb_raise(rb_eArgError, "unrecognized mask symbol: %s\n", sym2string(mask));
|
577
576
|
}
|
577
|
+
}
|
578
578
|
}
|
579
579
|
|
580
580
|
void
|
581
581
|
check_image(VALUE image)
|
582
582
|
{
|
583
|
-
|
584
|
-
|
583
|
+
if(!rb_respond_to(image, rb_intern("gl_tex_info")))
|
584
|
+
rb_raise(rb_eRuntimeError,"must specify a valid source image");
|
585
585
|
}
|
586
586
|
|
587
587
|
bool
|
588
588
|
is_gosu_image(VALUE try_image)
|
589
589
|
{
|
590
|
-
|
591
|
-
|
590
|
+
if(rb_respond_to(try_image, rb_intern("gl_tex_info")))
|
591
|
+
return true;
|
592
592
|
|
593
|
-
|
593
|
+
return false;
|
594
594
|
}
|
595
595
|
|
596
596
|
bool
|
597
597
|
is_gosu_color(VALUE try_color)
|
598
598
|
{
|
599
|
-
|
600
|
-
|
599
|
+
if(rb_respond_to(try_color, rb_intern("red")))
|
600
|
+
return true;
|
601
601
|
|
602
|
-
|
602
|
+
return false;
|
603
603
|
}
|
604
604
|
|
605
605
|
|
@@ -616,93 +616,93 @@ const int BOTTOM = 1; //0001
|
|
616
616
|
static outcode
|
617
617
|
ComputeOutCode (int x, int y, int xmin, int ymin, int xmax, int ymax)
|
618
618
|
{
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
619
|
+
outcode code = 0;
|
620
|
+
if (y > ymax) //above the clip window
|
621
|
+
code |= TOP;
|
622
|
+
else if (y < ymin) //below the clip window
|
623
|
+
code |= BOTTOM;
|
624
|
+
if (x > xmax) //to the right of clip window
|
625
|
+
code |= RIGHT;
|
626
|
+
else if (x < xmin) //to the left of clip window
|
627
|
+
code |= LEFT;
|
628
|
+
return code;
|
629
629
|
}
|
630
630
|
|
631
631
|
/** Cohen-Sutherland clipping algorithm clips a line from
|
632
|
-
P0 = (x0, y0) to P1 = (x1, y1) against a rectangle with
|
633
|
-
diagonal from (xmin, ymin) to (xmax, ymax). **/
|
632
|
+
P0 = (x0, y0) to P1 = (x1, y1) against a rectangle with
|
633
|
+
diagonal from (xmin, ymin) to (xmax, ymax). **/
|
634
634
|
void
|
635
635
|
cohen_sutherland_clip (int * x0, int * y0,int * x1, int * y1, int xmin, int ymin,
|
636
|
-
|
636
|
+
int xmax, int ymax)
|
637
637
|
{
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
638
|
+
//Outcodes for P0, P1, and whatever point lies outside the clip rectangle
|
639
|
+
outcode outcode0, outcode1, outcodeOut;
|
640
|
+
bool accept = false, done = false;
|
641
|
+
int tx0 = *x0, ty0 = *y0, tx1 = *x1, ty1 = *y1;
|
642
642
|
|
643
|
-
|
644
|
-
|
645
|
-
|
643
|
+
//compute outcodes
|
644
|
+
outcode0 = ComputeOutCode (tx0, ty0, xmin, ymin, xmax, ymax);
|
645
|
+
outcode1 = ComputeOutCode (tx1, ty1, xmin, ymin, xmax, ymax);
|
646
646
|
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
647
|
+
do{
|
648
|
+
if (!(outcode0 | outcode1)) //logical or is 0. Trivially accept and get out of loop
|
649
|
+
{
|
650
|
+
accept = true;
|
651
|
+
done = true;
|
652
|
+
}
|
653
|
+
else if (outcode0 & outcode1) //logical and is not 0. Trivially reject and get out of loop
|
654
|
+
done = true;
|
655
|
+
else
|
656
|
+
{
|
657
|
+
//failed both tests, so calculate the line segment to clip
|
658
|
+
//from an outside point to an intersection with clip edge
|
659
|
+
double x, y;
|
660
|
+
//At least one endpoint is outside the clip rectangle; pick it.
|
661
|
+
outcodeOut = outcode0? outcode0: outcode1;
|
662
|
+
//Now find the intersection point;
|
663
|
+
//use formulas y = y0 + slope * (x - x0), x = x0 + (1/slope)* (y - y0)
|
664
|
+
if (outcodeOut & TOP) //point is above the clip rectangle
|
665
|
+
{
|
666
|
+
x = tx0 + (tx1 - tx0) * (ymax - ty0)/(ty1 - ty0);
|
667
|
+
y = ymax;
|
668
|
+
}
|
669
|
+
else if (outcodeOut & BOTTOM) //point is below the clip rectangle
|
670
|
+
{
|
671
|
+
x = tx0 + (tx1 - tx0) * (ymin - ty0)/(ty1 - ty0);
|
672
|
+
y = ymin;
|
673
|
+
}
|
674
|
+
else if (outcodeOut & RIGHT) //point is to the right of clip rectangle
|
675
|
+
{
|
676
|
+
y = ty0 + (ty1 - ty0) * (xmax - tx0)/(tx1 - tx0);
|
677
|
+
x = xmax;
|
678
|
+
}
|
679
|
+
else //point is to the left of clip rectangle
|
680
|
+
{
|
681
|
+
y = ty0 + (ty1 - ty0) * (xmin - tx0)/(tx1 - tx0);
|
682
|
+
x = xmin;
|
683
|
+
}
|
684
|
+
//Now we move outside point to intersection point to clip
|
685
|
+
//and get ready for next pass.
|
686
|
+
if (outcodeOut == outcode0)
|
687
|
+
{
|
688
|
+
tx0 = x;
|
689
|
+
ty0 = y;
|
690
|
+
outcode0 = ComputeOutCode (tx0, ty0, xmin, ymin, xmax, ymax);
|
691
|
+
}
|
692
|
+
else
|
693
|
+
{
|
694
|
+
tx1 = x;
|
695
|
+
ty1 = y;
|
696
|
+
outcode1 = ComputeOutCode (tx1, ty1, xmin, ymin, xmax, ymax);
|
697
|
+
}
|
698
|
+
}
|
699
|
+
}while (!done);
|
700
700
|
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
701
|
+
if (accept)
|
702
|
+
{
|
703
|
+
*x0 = tx0; *x1 = tx1;
|
704
|
+
*y0 = ty0; *y1 = ty1;
|
705
|
+
}
|
706
706
|
|
707
707
|
}
|
708
708
|
/** end of cohen-sutherland line clipper **/
|
@@ -711,20 +711,20 @@ cohen_sutherland_clip (int * x0, int * y0,int * x1, int * y1, int xmin, int ymin
|
|
711
711
|
void
|
712
712
|
constrain_boundaries(int * x0, int * y0, int * x1, int * y1, int width, int height)
|
713
713
|
{
|
714
|
-
|
715
|
-
|
714
|
+
if(*y0 < 0) *y0 = 0;
|
715
|
+
if(*y1 < 0) *y1 = 0;
|
716
716
|
|
717
|
-
|
718
|
-
|
717
|
+
if(*x0 < 0) *x0 = 0;
|
718
|
+
if(*x1 < 0) *x1 = 0;
|
719
719
|
|
720
|
-
|
721
|
-
|
720
|
+
if(*x0 > (width - 1)) *x0 = width - 1;
|
721
|
+
if(*x1 > (width - 1)) *x1 = width - 1;
|
722
722
|
|
723
|
-
|
724
|
-
|
723
|
+
if(*y0 > (height - 1)) *y0 = height - 1;
|
724
|
+
if(*y1 > (height - 1)) *y1 = height - 1;
|
725
725
|
|
726
|
-
|
727
|
-
|
726
|
+
if(*y0 > *y1) { SWAP(*y0, *y1); }
|
727
|
+
if(*x0 > *x1) { SWAP(*x0, *x1); }
|
728
728
|
}
|
729
729
|
|
730
730
|
|
@@ -735,33 +735,33 @@ bool
|
|
735
735
|
bound_by_rect_and_inner(int x, int y, int x0, int y0, int x1, int y1, int inner)
|
736
736
|
{
|
737
737
|
|
738
|
-
|
739
|
-
|
738
|
+
return ((x >= x0) && (x <= x1) && (y >= y0) && (y <= y1)) &&
|
739
|
+
!((x >= x0 + inner) && (x <= x1 - inner) && (y >= y0 + inner) && (y <= y1 - inner));
|
740
740
|
}
|
741
741
|
|
742
742
|
/* same as above but excluding inner rectangle */
|
743
743
|
bool
|
744
744
|
bound_by_rect(int x, int y, int x0, int y0, int x1, int y1)
|
745
745
|
{
|
746
|
-
|
746
|
+
return bound_by_rect_and_inner(x, y, x0, y0, x1, y1, OOB_VAL);
|
747
747
|
}
|
748
748
|
|
749
749
|
/* calculate the array offset for a given pixel in action context */
|
750
750
|
int
|
751
751
|
calc_pixel_offset_for_action(action_struct * cur, texture_info * tex, int x, int y)
|
752
752
|
{
|
753
|
-
|
753
|
+
int offset = calc_pixel_offset(tex, x + cur->xmin, y + cur->ymin);
|
754
754
|
|
755
|
-
|
755
|
+
return offset;
|
756
756
|
}
|
757
757
|
|
758
758
|
/* calculate the array offset for a given pixel */
|
759
759
|
int
|
760
760
|
calc_pixel_offset(texture_info * tex, int x, int y)
|
761
761
|
{
|
762
|
-
|
762
|
+
int offset = 4 * (tex->firstpixel + x + tex->yincr * y);
|
763
763
|
|
764
|
-
|
764
|
+
return offset;
|
765
765
|
}
|
766
766
|
|
767
767
|
/* NEWEST version that solves segfault on linux, back
|
@@ -770,19 +770,23 @@ calc_pixel_offset(texture_info * tex, int x, int y)
|
|
770
770
|
unsigned
|
771
771
|
max_quad_size(void)
|
772
772
|
{
|
773
|
-
|
773
|
+
#if 1
|
774
|
+
return 1024;
|
775
|
+
#endif
|
776
|
+
|
777
|
+
static unsigned size = 0;
|
774
778
|
|
775
|
-
|
776
|
-
|
777
|
-
|
779
|
+
if (size == 0) {
|
780
|
+
VALUE gosu = rb_const_get(rb_cObject, rb_intern("Gosu"));
|
781
|
+
VALUE rb_size = rb_const_get(gosu, rb_intern("MAX_TEXTURE_SIZE"));
|
778
782
|
|
779
|
-
|
780
|
-
|
783
|
+
size = FIX2INT(rb_size);
|
784
|
+
}
|
781
785
|
|
782
|
-
|
786
|
+
return size;
|
783
787
|
}
|
784
788
|
|
785
|
-
|
789
|
+
/* old version for quick update, OUT OF ACTIONN */
|
786
790
|
/* unsigned */
|
787
791
|
/* max_quad_size(void) */
|
788
792
|
/* { */
|
@@ -811,77 +815,77 @@ max_quad_size(void)
|
|
811
815
|
bool
|
812
816
|
is_a_point(VALUE try_point)
|
813
817
|
{
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
+
/* if it responds to 'x' it's near enough (technically must respond to x AND y) */
|
819
|
+
/* added the is_a_num() check due to WEIRD bug where FIXNUMS were responding to the 'x' method (wtf?) but returning nil when invoked */
|
820
|
+
if(rb_respond_to(try_point, rb_intern("x")) && !is_a_num(try_point))
|
821
|
+
return true;
|
818
822
|
|
819
|
-
|
823
|
+
return false;
|
820
824
|
}
|
821
825
|
|
822
826
|
VALUE
|
823
827
|
point_x(VALUE point)
|
824
828
|
{
|
825
|
-
|
829
|
+
return rb_funcall(point, rb_intern("x"), 0);
|
826
830
|
}
|
827
831
|
|
828
832
|
VALUE
|
829
833
|
point_y(VALUE point)
|
830
834
|
{
|
831
|
-
|
835
|
+
return rb_funcall(point, rb_intern("y"), 0);
|
832
836
|
}
|
833
837
|
|
834
838
|
/* mathematical utils, used mainly by bezier curves */
|
835
839
|
double
|
836
840
|
power(float base, int exp)
|
837
841
|
{
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
}
|
850
|
-
return ans;
|
842
|
+
float ans = 1.0;
|
843
|
+
if(base == 0.0) {
|
844
|
+
if(exp == 0)
|
845
|
+
return 1;
|
846
|
+
else
|
847
|
+
return 0;
|
848
|
+
}
|
849
|
+
else if(exp == 0) return 1;
|
850
|
+
else {
|
851
|
+
for(int k = exp; k >= 1; k--) {
|
852
|
+
ans = ans * base;
|
851
853
|
}
|
854
|
+
return ans;
|
855
|
+
}
|
852
856
|
}
|
853
857
|
|
854
858
|
unsigned
|
855
859
|
fact(int n)
|
856
860
|
{
|
857
|
-
|
858
|
-
|
859
|
-
|
861
|
+
if (n == 0 || n == 1) return 1;
|
862
|
+
else
|
863
|
+
return (n * fact(n - 1));
|
860
864
|
}
|
861
865
|
|
862
866
|
unsigned
|
863
867
|
comb(int n, int r)
|
864
868
|
{
|
865
|
-
|
866
|
-
|
867
|
-
|
869
|
+
/* nCr is symmetrical about n / 2 */
|
870
|
+
if(r > (n / 2))
|
871
|
+
r = n - r;
|
868
872
|
|
869
|
-
|
873
|
+
return perm(n, r) / fact(r);
|
870
874
|
}
|
871
875
|
|
872
876
|
unsigned
|
873
877
|
perm(int n, int r)
|
874
878
|
{
|
875
|
-
|
876
|
-
|
877
|
-
|
879
|
+
int val = 1;
|
880
|
+
for(int i = n; i > (n - r); i--)
|
881
|
+
val *= i;
|
878
882
|
|
879
|
-
|
883
|
+
return val;
|
880
884
|
}
|
881
885
|
|
882
886
|
double
|
883
887
|
bernstein(int n, int k, float u)
|
884
888
|
{
|
885
|
-
|
886
|
-
|
889
|
+
double temp = comb(n, k) * pow(u, k) * pow(1 - u, n - k);
|
890
|
+
return temp;
|
887
891
|
}
|