texplay 0.2.7-x86-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 +103 -0
- data/README.markdown +41 -0
- data/Rakefile +61 -0
- data/examples/common.rb +8 -0
- data/examples/example_alpha_blend.rb +31 -0
- data/examples/example_bezier.rb +42 -0
- data/examples/example_blur.rb +59 -0
- data/examples/example_color_control.rb +69 -0
- data/examples/example_color_transform.rb +29 -0
- data/examples/example_dup.rb +75 -0
- data/examples/example_each.rb +42 -0
- data/examples/example_effect.rb +35 -0
- data/examples/example_fill.rb +44 -0
- data/examples/example_fill_old.rb +49 -0
- data/examples/example_fluent.rb +31 -0
- data/examples/example_gen_eval.rb +34 -0
- data/examples/example_hash_arguments.rb +47 -0
- data/examples/example_lsystem.rb +61 -0
- data/examples/example_melt.rb +27 -0
- data/examples/example_polyline.rb +43 -0
- data/examples/example_scale.rb +29 -0
- data/examples/example_simple.rb +38 -0
- data/examples/example_splice.rb +33 -0
- data/examples/example_sync.rb +60 -0
- data/examples/example_turtle.rb +40 -0
- data/examples/media/empty2.png +0 -0
- data/examples/media/gosu.png +0 -0
- data/examples/media/logo.png +0 -0
- data/examples/media/maria.png +0 -0
- data/examples/media/rose.bmp +0 -0
- data/examples/media/sand1.png +0 -0
- data/examples/media/sunset.png +0 -0
- data/examples/media/texplay.png +0 -0
- data/ext/texplay/actions.c +1331 -0
- data/ext/texplay/actions.h +52 -0
- data/ext/texplay/bindings.c +1129 -0
- data/ext/texplay/bindings.h +46 -0
- data/ext/texplay/cache.c +135 -0
- data/ext/texplay/cache.h +24 -0
- data/ext/texplay/compat.h +27 -0
- data/ext/texplay/extconf.rb +30 -0
- data/ext/texplay/gen_eval.c +211 -0
- data/ext/texplay/gen_eval.h +20 -0
- data/ext/texplay/object2module.c +171 -0
- data/ext/texplay/object2module.h +11 -0
- data/ext/texplay/texplay.c +137 -0
- data/ext/texplay/texplay.h +107 -0
- data/ext/texplay/utils.c +978 -0
- data/ext/texplay/utils.h +145 -0
- data/lib/1.8/texplay.so +0 -0
- data/lib/1.9/texplay.so +0 -0
- data/lib/texplay-contrib.rb +171 -0
- data/lib/texplay.rb +134 -0
- metadata +114 -0
@@ -0,0 +1,1129 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#include <stdio.h>
|
3
|
+
#include <string.h>
|
4
|
+
#include <ctype.h>
|
5
|
+
#include <math.h>
|
6
|
+
#include <stdlib.h>
|
7
|
+
#include <assert.h>
|
8
|
+
#include <stdarg.h>
|
9
|
+
|
10
|
+
#ifdef __APPLE__
|
11
|
+
# include <glut.h>
|
12
|
+
#else
|
13
|
+
# include <GL/glut.h>
|
14
|
+
#endif
|
15
|
+
|
16
|
+
#include "texplay.h"
|
17
|
+
#include "utils.h"
|
18
|
+
#include "bindings.h"
|
19
|
+
#include "actions.h"
|
20
|
+
#include "cache.h"
|
21
|
+
#include "compat.h"
|
22
|
+
|
23
|
+
/* associated with gen_eval */
|
24
|
+
#include "object2module.h"
|
25
|
+
#include "gen_eval.h"
|
26
|
+
|
27
|
+
/* syncing mode */
|
28
|
+
/* lazy_sync = sync at end of paint block */
|
29
|
+
/* eager_sync = sync immediately (after action) */
|
30
|
+
/* no_sync = do not sync at all */
|
31
|
+
sync sync_mode = eager_sync;
|
32
|
+
|
33
|
+
static void
|
34
|
+
process_x_y_pairs(VALUE image, int num_pairs, VALUE * argv, ...)
|
35
|
+
{
|
36
|
+
va_list ap;
|
37
|
+
int i;
|
38
|
+
int draw_offset_x;
|
39
|
+
int draw_offset_y;
|
40
|
+
VALUE offset_val;
|
41
|
+
|
42
|
+
offset_val = get_image_local(image, DRAW_OFFSET);
|
43
|
+
|
44
|
+
draw_offset_x = NUM2INT(get_from_array(offset_val, 0));
|
45
|
+
draw_offset_y = NUM2INT(get_from_array(offset_val, 1));
|
46
|
+
|
47
|
+
va_start(ap, argv);
|
48
|
+
if(is_a_point(argv[0])) {
|
49
|
+
for(i = 0; i < num_pairs; i++) {
|
50
|
+
int *x_ptr, *y_ptr;
|
51
|
+
|
52
|
+
x_ptr = va_arg(ap, int*);
|
53
|
+
y_ptr = va_arg(ap, int*);
|
54
|
+
|
55
|
+
*x_ptr = NUM2INT(rb_funcall(argv[i], rb_intern("x"), 0)) + draw_offset_x;
|
56
|
+
*y_ptr = NUM2INT(rb_funcall(argv[i], rb_intern("y"), 0)) + draw_offset_y;
|
57
|
+
}
|
58
|
+
}
|
59
|
+
else {
|
60
|
+
for(i = 0; i < (num_pairs * 2); i+=2) {
|
61
|
+
int *x_ptr, *y_ptr;
|
62
|
+
|
63
|
+
x_ptr = va_arg(ap, int*);
|
64
|
+
y_ptr = va_arg(ap, int*);
|
65
|
+
|
66
|
+
*x_ptr = NUM2INT(argv[i]) + draw_offset_x;
|
67
|
+
*y_ptr = NUM2INT(argv[i + 1]) + draw_offset_y;
|
68
|
+
}
|
69
|
+
}
|
70
|
+
va_end(ap);
|
71
|
+
}
|
72
|
+
|
73
|
+
|
74
|
+
/* singleton methods */
|
75
|
+
|
76
|
+
/* responsible for creating macros */
|
77
|
+
VALUE
|
78
|
+
M_create_macro(VALUE self, VALUE method_name)
|
79
|
+
{
|
80
|
+
VALUE proc;
|
81
|
+
|
82
|
+
rb_need_block();
|
83
|
+
|
84
|
+
/* convert the block to a proc */
|
85
|
+
proc = rb_block_proc();
|
86
|
+
|
87
|
+
/* define the method in the TexPlay class so that it is accessible to 'instances' */
|
88
|
+
rb_funcall(self, rb_intern("define_method"), 2, method_name, proc);
|
89
|
+
|
90
|
+
return Qnil;
|
91
|
+
}
|
92
|
+
|
93
|
+
|
94
|
+
/* responsible for removing macros */
|
95
|
+
VALUE
|
96
|
+
M_remove_macro(VALUE self, VALUE method_name)
|
97
|
+
{
|
98
|
+
|
99
|
+
/* remove the method in the TexPlay class */
|
100
|
+
rb_funcall(self, rb_intern("remove_method"), 1, method_name);
|
101
|
+
|
102
|
+
return Qnil;
|
103
|
+
}
|
104
|
+
|
105
|
+
/* responsible for refreshing all entries in cache */
|
106
|
+
VALUE
|
107
|
+
M_refresh_cache_all(VALUE self)
|
108
|
+
{
|
109
|
+
cache_refresh_all();
|
110
|
+
|
111
|
+
return Qnil;
|
112
|
+
}
|
113
|
+
|
114
|
+
/* creates a blank image */
|
115
|
+
VALUE
|
116
|
+
M_create_blank(VALUE self, VALUE window, VALUE width, VALUE height)
|
117
|
+
{
|
118
|
+
VALUE fresh_image;
|
119
|
+
|
120
|
+
fresh_image = create_image(window, NUM2INT(width), NUM2INT(height));
|
121
|
+
|
122
|
+
return fresh_image;
|
123
|
+
}
|
124
|
+
/** end singleton methods **/
|
125
|
+
|
126
|
+
/* some helper methods */
|
127
|
+
static void
|
128
|
+
rb_lazy_bounds_to_image_bounds(VALUE image, image_bounds * bounds)
|
129
|
+
{
|
130
|
+
VALUE lazy_bounds;
|
131
|
+
|
132
|
+
lazy_bounds = get_image_local(image, LAZY_BOUNDS);
|
133
|
+
|
134
|
+
Check_Type(lazy_bounds, T_ARRAY);
|
135
|
+
|
136
|
+
bounds->xmin = FIX2INT(get_from_array(lazy_bounds, 0));
|
137
|
+
bounds->ymin = FIX2INT(get_from_array(lazy_bounds, 1));
|
138
|
+
bounds->xmax = FIX2INT(get_from_array(lazy_bounds, 2));
|
139
|
+
bounds->ymax = FIX2INT(get_from_array(lazy_bounds, 3));
|
140
|
+
}
|
141
|
+
|
142
|
+
static VALUE
|
143
|
+
parse_sync_mode(VALUE user_sync_mode)
|
144
|
+
{
|
145
|
+
sync mode;
|
146
|
+
|
147
|
+
Check_Type(user_sync_mode, T_SYMBOL);
|
148
|
+
|
149
|
+
if(user_sync_mode == string2sym("lazy_sync"))
|
150
|
+
mode = lazy_sync;
|
151
|
+
else if(user_sync_mode == string2sym("eager_sync"))
|
152
|
+
mode = eager_sync;
|
153
|
+
else if(user_sync_mode == string2sym("no_sync"))
|
154
|
+
mode = no_sync;
|
155
|
+
else
|
156
|
+
rb_raise(rb_eArgError, "unrecognized sync mode: %s\n. Allowable modes are "
|
157
|
+
":lazy_sync, :eager_sync, :no_sync.",
|
158
|
+
sym2string(user_sync_mode));
|
159
|
+
|
160
|
+
return mode;
|
161
|
+
}
|
162
|
+
/* end helpers */
|
163
|
+
|
164
|
+
/* entry point for TexPlay paint actions */
|
165
|
+
VALUE
|
166
|
+
m_paint(int argc, VALUE * argv, VALUE self)
|
167
|
+
{
|
168
|
+
texture_info tex;
|
169
|
+
VALUE options;
|
170
|
+
image_bounds bounds;
|
171
|
+
int arity;
|
172
|
+
|
173
|
+
ADJUST_SELF(self);
|
174
|
+
|
175
|
+
rb_scan_args(argc, argv, "01", &options);
|
176
|
+
|
177
|
+
/* get texture info from image */
|
178
|
+
get_texture_info(self, &tex);
|
179
|
+
|
180
|
+
/* set default sync_mode to lazy */
|
181
|
+
sync_mode = lazy_sync;
|
182
|
+
|
183
|
+
/* parse sync_mode, overriding lazy sync mode? */
|
184
|
+
if(has_optional_hash_arg(options, "sync_mode")) {
|
185
|
+
VALUE user_sync_mode = get_from_hash(options, "sync_mode");
|
186
|
+
sync_mode = parse_sync_mode(user_sync_mode);
|
187
|
+
}
|
188
|
+
|
189
|
+
/* if no block then just sync */
|
190
|
+
if(!rb_block_given_p()) {
|
191
|
+
|
192
|
+
rb_lazy_bounds_to_image_bounds(self, &bounds);
|
193
|
+
|
194
|
+
create_subtexture_and_sync_to_gl(&bounds, &tex);
|
195
|
+
|
196
|
+
/* reset the LAZY_BOUNDS now we've sync'd */
|
197
|
+
set_image_local(self, LAZY_BOUNDS, Qnil);
|
198
|
+
|
199
|
+
sync_mode = eager_sync;
|
200
|
+
|
201
|
+
return self;
|
202
|
+
}
|
203
|
+
|
204
|
+
/* find arity of block */
|
205
|
+
arity = FIX2INT(rb_funcall(rb_block_proc(), rb_intern("arity"), 0));
|
206
|
+
|
207
|
+
/* yield self if the arity is 1, else gen_eval the block */
|
208
|
+
switch(arity) {
|
209
|
+
case -1:
|
210
|
+
case 0:
|
211
|
+
rb_gen_eval(0, 0, self);
|
212
|
+
break;
|
213
|
+
case 1:
|
214
|
+
rb_yield(self);
|
215
|
+
break;
|
216
|
+
default:
|
217
|
+
rb_raise(rb_eArgError, "block arity must be either 1 or -1 or 0, received arity of: %d", arity);
|
218
|
+
}
|
219
|
+
|
220
|
+
/* if lazy sync is selected then sync now..as the paint block has finished executing the draw actions*/
|
221
|
+
if(sync_mode == lazy_sync) {
|
222
|
+
|
223
|
+
rb_lazy_bounds_to_image_bounds(self, &bounds);
|
224
|
+
|
225
|
+
create_subtexture_and_sync_to_gl(&bounds, &tex);
|
226
|
+
|
227
|
+
/* reset the LAZY_BOUNDS now we've sync'd */
|
228
|
+
set_image_local(self, LAZY_BOUNDS, Qnil);
|
229
|
+
|
230
|
+
}
|
231
|
+
|
232
|
+
/* now we've finished the paint block we reset the default sync_mode back to eager */
|
233
|
+
sync_mode = eager_sync;
|
234
|
+
|
235
|
+
return self;
|
236
|
+
}
|
237
|
+
|
238
|
+
VALUE
|
239
|
+
m_force_sync(VALUE self, VALUE ary)
|
240
|
+
{
|
241
|
+
image_bounds bounds;
|
242
|
+
texture_info tex;
|
243
|
+
|
244
|
+
ADJUST_SELF(self);
|
245
|
+
|
246
|
+
Check_Type(ary, T_ARRAY);
|
247
|
+
|
248
|
+
get_texture_info(self, &tex);
|
249
|
+
|
250
|
+
bounds.xmin = NUM2INT(get_from_array(ary, 0));
|
251
|
+
bounds.ymin = NUM2INT(get_from_array(ary, 1));
|
252
|
+
bounds.xmax = NUM2INT(get_from_array(ary, 2));
|
253
|
+
bounds.ymax = NUM2INT(get_from_array(ary, 3));
|
254
|
+
|
255
|
+
create_subtexture_and_sync_to_gl(&bounds, &tex);
|
256
|
+
|
257
|
+
return Qnil;
|
258
|
+
}
|
259
|
+
|
260
|
+
VALUE
|
261
|
+
m_dup_image(VALUE self)
|
262
|
+
{
|
263
|
+
texture_info tex, dup_tex;
|
264
|
+
VALUE dupped_image;
|
265
|
+
VALUE window;
|
266
|
+
|
267
|
+
ADJUST_SELF(self);
|
268
|
+
|
269
|
+
get_texture_info(self, &tex);
|
270
|
+
|
271
|
+
window = rb_funcall(self, rb_intern("__window__"), 0);
|
272
|
+
|
273
|
+
/* create a new blank image with the height/width of the current image */
|
274
|
+
dupped_image = create_image(window, tex.width, tex.height);
|
275
|
+
|
276
|
+
/* get the new image's data */
|
277
|
+
get_texture_info(dupped_image, &dup_tex);
|
278
|
+
|
279
|
+
/* splice into the new image content from the current image, and sync it to gl */
|
280
|
+
splice_do_action(0, 0, 0, 0, XMAX_OOB, YMAX_OOB, &tex, &dup_tex, Qnil, eager_sync, true, NULL);
|
281
|
+
|
282
|
+
/* copy across the ivars too! */
|
283
|
+
rb_copy_generic_ivar(dupped_image, self);
|
284
|
+
|
285
|
+
/* we now have a full dup of the current image, return it */
|
286
|
+
return dupped_image;
|
287
|
+
}
|
288
|
+
|
289
|
+
VALUE
|
290
|
+
m_clone_image(VALUE self)
|
291
|
+
{
|
292
|
+
VALUE cloned_image;
|
293
|
+
|
294
|
+
ADJUST_SELF(self);
|
295
|
+
|
296
|
+
cloned_image = m_dup_image(self);
|
297
|
+
|
298
|
+
/* the main diff b/w clone and dup is that clone also dups the singleton */
|
299
|
+
KLASS_OF(cloned_image) = rb_singleton_class_clone(self);
|
300
|
+
|
301
|
+
return cloned_image;
|
302
|
+
}
|
303
|
+
|
304
|
+
VALUE
|
305
|
+
m_user_set_options(VALUE self, VALUE options)
|
306
|
+
{
|
307
|
+
ADJUST_SELF(self);
|
308
|
+
|
309
|
+
if(!is_a_hash(options))
|
310
|
+
rb_raise(rb_eArgError, "only a single hash argument is accepted");
|
311
|
+
|
312
|
+
set_image_local(self, USER_DEFAULTS, options);
|
313
|
+
|
314
|
+
return Qnil;
|
315
|
+
}
|
316
|
+
|
317
|
+
VALUE
|
318
|
+
m_user_delete_options(VALUE self)
|
319
|
+
{
|
320
|
+
|
321
|
+
ADJUST_SELF(self);
|
322
|
+
|
323
|
+
set_image_local(self, USER_DEFAULTS, Qnil);
|
324
|
+
|
325
|
+
return Qnil;
|
326
|
+
}
|
327
|
+
|
328
|
+
VALUE
|
329
|
+
m_get_options(VALUE self)
|
330
|
+
{
|
331
|
+
ADJUST_SELF(self);
|
332
|
+
|
333
|
+
return get_image_local(self, USER_DEFAULTS);
|
334
|
+
}
|
335
|
+
|
336
|
+
static void
|
337
|
+
get_image_chunk_with_size(char * data, texture_info * tex, char * blob)
|
338
|
+
{
|
339
|
+
int x, y;
|
340
|
+
|
341
|
+
for(y = 0; y < tex->height; y++)
|
342
|
+
for(x = 0; x < tex->width; x++) {
|
343
|
+
int buf_index = 4 * (x + y * tex->width);
|
344
|
+
|
345
|
+
int offset = calc_pixel_offset(tex, x, y);
|
346
|
+
|
347
|
+
memcpy(blob + buf_index, data + offset, 4);
|
348
|
+
}
|
349
|
+
}
|
350
|
+
|
351
|
+
VALUE
|
352
|
+
m_to_blob(VALUE self)
|
353
|
+
{
|
354
|
+
texture_info tex;
|
355
|
+
int sidelength;
|
356
|
+
VALUE blob;
|
357
|
+
void * new_array = NULL;
|
358
|
+
|
359
|
+
ADJUST_SELF(self);
|
360
|
+
|
361
|
+
get_texture_info(self, &tex);
|
362
|
+
|
363
|
+
glEnable(GL_TEXTURE_2D);
|
364
|
+
glBindTexture(GL_TEXTURE_2D, tex.tname);
|
365
|
+
|
366
|
+
/* get length of a side, since square texture */
|
367
|
+
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &sidelength);
|
368
|
+
|
369
|
+
/* initialize texture data array, mult. by 4 because {rgba} */
|
370
|
+
new_array = malloc(sidelength * sidelength * 4);
|
371
|
+
|
372
|
+
/* get texture data from video memory */
|
373
|
+
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE,(void*)(new_array));
|
374
|
+
|
375
|
+
blob = rb_str_new(NULL, 4 * tex.width * tex.height);
|
376
|
+
|
377
|
+
get_image_chunk_with_size(new_array, &tex, RSTRING_PTR(blob));
|
378
|
+
|
379
|
+
glDisable(GL_TEXTURE_2D);
|
380
|
+
|
381
|
+
return blob;
|
382
|
+
}
|
383
|
+
|
384
|
+
/* return the pixel colour for the given x, y */
|
385
|
+
VALUE
|
386
|
+
m_getpixel(int argc, VALUE * argv, VALUE self)
|
387
|
+
{
|
388
|
+
int x1, y1;
|
389
|
+
texture_info tex;
|
390
|
+
rgba pix;
|
391
|
+
|
392
|
+
/* change self to hidden self if using gen_eval */
|
393
|
+
ADJUST_SELF(self);
|
394
|
+
|
395
|
+
process_x_y_pairs(self, 1, argv, &x1, &y1);
|
396
|
+
|
397
|
+
/* get texture info */
|
398
|
+
get_texture_info(self, &tex);
|
399
|
+
|
400
|
+
/* locate the desired pixel; */
|
401
|
+
pix = get_pixel_color(&tex, x1, y1);
|
402
|
+
|
403
|
+
if(not_a_color(pix))
|
404
|
+
return Qnil;
|
405
|
+
else
|
406
|
+
return convert_rgba_to_rb_color(&pix);
|
407
|
+
}
|
408
|
+
|
409
|
+
/* circle action */
|
410
|
+
VALUE
|
411
|
+
m_circle(int argc, VALUE * argv, VALUE self)
|
412
|
+
{
|
413
|
+
int x1, y1, r;
|
414
|
+
int last = argc - 1;
|
415
|
+
VALUE options;
|
416
|
+
texture_info tex;
|
417
|
+
|
418
|
+
ADJUST_SELF(self);
|
419
|
+
|
420
|
+
if(argc < 2) rb_raise(rb_eArgError, "circle action needs at least 2 parameter");
|
421
|
+
|
422
|
+
process_x_y_pairs(self, 1, argv, &x1, &y1);
|
423
|
+
|
424
|
+
if(is_a_point(argv[0]))
|
425
|
+
r = NUM2INT(argv[1]);
|
426
|
+
else
|
427
|
+
r = NUM2INT(argv[2]);
|
428
|
+
|
429
|
+
options = argv[last];
|
430
|
+
|
431
|
+
get_texture_info(self, &tex);
|
432
|
+
|
433
|
+
circle_do_action(x1, y1, r, &tex, options, sync_mode, true, NULL);
|
434
|
+
|
435
|
+
return self;
|
436
|
+
}
|
437
|
+
|
438
|
+
/* ngon */
|
439
|
+
VALUE
|
440
|
+
m_ngon(int argc, VALUE * argv, VALUE self)
|
441
|
+
{
|
442
|
+
int x1, y1, r, n;
|
443
|
+
int last = argc - 1;
|
444
|
+
VALUE options;
|
445
|
+
texture_info tex;
|
446
|
+
|
447
|
+
ADJUST_SELF(self);
|
448
|
+
|
449
|
+
if(argc < 3) rb_raise(rb_eArgError, "ngon requires at least 3 parameters (x, y, radius, num_sides)");
|
450
|
+
|
451
|
+
process_x_y_pairs(self, 1, argv, &x1, &y1);
|
452
|
+
|
453
|
+
options = argv[last];
|
454
|
+
|
455
|
+
get_texture_info(self, &tex);
|
456
|
+
|
457
|
+
r = NUM2INT(argv[2]);
|
458
|
+
n = NUM2INT(argv[3]);
|
459
|
+
|
460
|
+
ngon_do_action(x1, y1, r, n, &tex, options, sync_mode, true, NULL);
|
461
|
+
|
462
|
+
return self;
|
463
|
+
}
|
464
|
+
|
465
|
+
|
466
|
+
/* flood fill action */
|
467
|
+
VALUE
|
468
|
+
m_flood_fill(int argc, VALUE * argv, VALUE self)
|
469
|
+
{
|
470
|
+
int x1, y1;
|
471
|
+
int last = argc - 1;
|
472
|
+
VALUE options;
|
473
|
+
texture_info tex;
|
474
|
+
bool iter = false, glow = false;
|
475
|
+
|
476
|
+
ADJUST_SELF(self);
|
477
|
+
|
478
|
+
if (argc < 1) rb_raise(rb_eArgError, "flood fill action needs at least 1 parameter");
|
479
|
+
|
480
|
+
process_x_y_pairs(self, 1, argv, &x1, &y1);
|
481
|
+
|
482
|
+
options = argv[last];
|
483
|
+
|
484
|
+
get_texture_info(self, &tex);
|
485
|
+
|
486
|
+
if(is_a_hash(options)) {
|
487
|
+
if(RTEST(get_from_hash(options, "iter")))
|
488
|
+
iter = true;
|
489
|
+
if(RTEST(get_from_hash(options, "glow")))
|
490
|
+
glow = true;
|
491
|
+
}
|
492
|
+
|
493
|
+
if(iter) {
|
494
|
+
flood_fill_do_action(x1, y1, &tex, options, sync_mode, true, NULL);
|
495
|
+
}
|
496
|
+
else if(glow) {
|
497
|
+
glow_fill_do_action(x1, y1, &tex, options, sync_mode, true, NULL);
|
498
|
+
|
499
|
+
}
|
500
|
+
/* this is the default fill */
|
501
|
+
else {
|
502
|
+
scan_fill_do_action(x1, y1, &tex, options, sync_mode, true, NULL);
|
503
|
+
}
|
504
|
+
|
505
|
+
return self;
|
506
|
+
}
|
507
|
+
|
508
|
+
|
509
|
+
/* line action */
|
510
|
+
VALUE
|
511
|
+
m_line(int argc, VALUE * argv, VALUE self)
|
512
|
+
{
|
513
|
+
int x1, y1, x2, y2;
|
514
|
+
int last = argc - 1;
|
515
|
+
VALUE options;
|
516
|
+
texture_info tex;
|
517
|
+
|
518
|
+
ADJUST_SELF(self);
|
519
|
+
|
520
|
+
if(argc < 2) rb_raise(rb_eArgError, "line action needs at least 2 parameters");
|
521
|
+
|
522
|
+
process_x_y_pairs(self, 2, argv, &x1, &y1, &x2, &y2);
|
523
|
+
|
524
|
+
options = argv[last];
|
525
|
+
|
526
|
+
get_texture_info(self, &tex);
|
527
|
+
|
528
|
+
line_do_action(x1, y1, x2, y2, &tex, options, sync_mode, true, NULL);
|
529
|
+
|
530
|
+
return self;
|
531
|
+
}
|
532
|
+
|
533
|
+
/* box action */
|
534
|
+
VALUE
|
535
|
+
m_rect(int argc, VALUE * argv, VALUE self)
|
536
|
+
{
|
537
|
+
|
538
|
+
int x1, y1, x2, y2;
|
539
|
+
int last = argc - 1;
|
540
|
+
VALUE options;
|
541
|
+
texture_info tex;
|
542
|
+
|
543
|
+
ADJUST_SELF(self);
|
544
|
+
|
545
|
+
if(argc < 2) rb_raise(rb_eArgError, "rect action needs at least 2 parameters");
|
546
|
+
|
547
|
+
process_x_y_pairs(self, 2, argv, &x1, &y1, &x2, &y2);
|
548
|
+
|
549
|
+
options = argv[last];
|
550
|
+
|
551
|
+
get_texture_info(self, &tex);
|
552
|
+
|
553
|
+
rect_do_action(x1, y1, x2, y2, &tex, options, sync_mode, true, NULL);
|
554
|
+
|
555
|
+
return self;
|
556
|
+
}
|
557
|
+
|
558
|
+
|
559
|
+
/* pixel action */
|
560
|
+
VALUE
|
561
|
+
m_pixel(int argc, VALUE * argv, VALUE self)
|
562
|
+
{
|
563
|
+
int x1, y1;
|
564
|
+
int last = argc - 1;
|
565
|
+
VALUE options;
|
566
|
+
texture_info tex;
|
567
|
+
|
568
|
+
ADJUST_SELF(self);
|
569
|
+
|
570
|
+
if(argc < 1) rb_raise(rb_eArgError, "pixel action needs 1 parameter");
|
571
|
+
|
572
|
+
process_x_y_pairs(self, 1, argv, &x1, &y1);
|
573
|
+
|
574
|
+
options = argv[last];
|
575
|
+
|
576
|
+
get_texture_info(self, &tex);
|
577
|
+
|
578
|
+
pixel_do_action(x1, y1, &tex, options, sync_mode, true, NULL);
|
579
|
+
|
580
|
+
return self;
|
581
|
+
}
|
582
|
+
|
583
|
+
/* bezier curve */
|
584
|
+
VALUE
|
585
|
+
m_bezier(int argc, VALUE * argv, VALUE self)
|
586
|
+
{
|
587
|
+
VALUE points = Qnil;
|
588
|
+
VALUE options = Qnil;
|
589
|
+
int last = argc - 1;
|
590
|
+
texture_info tex;
|
591
|
+
|
592
|
+
ADJUST_SELF(self);
|
593
|
+
|
594
|
+
if(argc < 1) rb_raise(rb_eArgError, "bezier action needs at least 1 parameter");
|
595
|
+
|
596
|
+
/* get array of points */
|
597
|
+
points = argv[0];
|
598
|
+
Check_Type(points, T_ARRAY);
|
599
|
+
|
600
|
+
options = argv[last];
|
601
|
+
|
602
|
+
get_texture_info(self, &tex);
|
603
|
+
|
604
|
+
bezier_do_action(points, &tex, options, sync_mode, true, NULL);
|
605
|
+
|
606
|
+
return self;
|
607
|
+
}
|
608
|
+
|
609
|
+
/* bezier curve */
|
610
|
+
VALUE
|
611
|
+
m_polyline(int argc, VALUE * argv, VALUE self)
|
612
|
+
{
|
613
|
+
VALUE points = Qnil;
|
614
|
+
VALUE options = Qnil;
|
615
|
+
int last = argc - 1;
|
616
|
+
texture_info tex;
|
617
|
+
|
618
|
+
ADJUST_SELF(self);
|
619
|
+
|
620
|
+
if(argc < 1) rb_raise(rb_eArgError, "polyline action needs at least 1 parameter");
|
621
|
+
|
622
|
+
/* get array of points */
|
623
|
+
points = argv[0];
|
624
|
+
Check_Type(points, T_ARRAY);
|
625
|
+
|
626
|
+
options = argv[last];
|
627
|
+
|
628
|
+
get_texture_info(self, &tex);
|
629
|
+
|
630
|
+
polyline_do_action(points, &tex, options, sync_mode, true, NULL);
|
631
|
+
|
632
|
+
return self;
|
633
|
+
}
|
634
|
+
|
635
|
+
|
636
|
+
|
637
|
+
/* splice action */
|
638
|
+
VALUE
|
639
|
+
m_splice(int argc, VALUE * argv, VALUE self)
|
640
|
+
{
|
641
|
+
int x0, y0;
|
642
|
+
int cx1 = 0, cy1 = 0, cx2 = XMAX_OOB, cy2 = YMAX_OOB;
|
643
|
+
texture_info splice_tex;
|
644
|
+
int last = argc - 1;
|
645
|
+
texture_info tex;
|
646
|
+
VALUE options;
|
647
|
+
|
648
|
+
ADJUST_SELF(self);
|
649
|
+
|
650
|
+
if(argc < 3) rb_raise(rb_eArgError, "splice action needs at least 3 parameters");
|
651
|
+
|
652
|
+
if(!is_gosu_image(argv[0]))
|
653
|
+
rb_raise(rb_eArgError, "first parameter must be a valid Gosu::Image");
|
654
|
+
|
655
|
+
/* get the splice image */
|
656
|
+
get_texture_info(argv[0], &splice_tex);
|
657
|
+
|
658
|
+
/* add 1 to argv to skip the Image parameter */
|
659
|
+
process_x_y_pairs(self, 1, argv + 1, &x0, &y0);
|
660
|
+
|
661
|
+
/* get the hash args */
|
662
|
+
options = argv[last];
|
663
|
+
|
664
|
+
get_texture_info(self, &tex);
|
665
|
+
|
666
|
+
/* get the crop boundaries */
|
667
|
+
if(is_a_hash(options))
|
668
|
+
if(RTEST(get_from_hash(options, "crop"))) {
|
669
|
+
VALUE c = get_from_hash(options, "crop");
|
670
|
+
Check_Type(c, T_ARRAY);
|
671
|
+
cx1 = NUM2INT(get_from_array(c, 0));
|
672
|
+
cy1 = NUM2INT(get_from_array(c, 1));
|
673
|
+
cx2 = NUM2INT(get_from_array(c, 2));
|
674
|
+
cy2 = NUM2INT(get_from_array(c, 3));
|
675
|
+
}
|
676
|
+
|
677
|
+
splice_do_action(x0, y0, cx1, cy1, cx2, cy2, &splice_tex,
|
678
|
+
&tex, options, sync_mode, true, NULL);
|
679
|
+
|
680
|
+
return self;
|
681
|
+
}
|
682
|
+
|
683
|
+
|
684
|
+
/* clear action - really just an alias for box */
|
685
|
+
VALUE
|
686
|
+
m_clear(int argc, VALUE * argv, VALUE self)
|
687
|
+
{
|
688
|
+
VALUE parms[4];
|
689
|
+
|
690
|
+
parms[0] = INT2NUM(0);
|
691
|
+
parms[1] = INT2NUM(0);
|
692
|
+
parms[2] = INT2NUM(XMAX_OOB);
|
693
|
+
parms[3] = INT2NUM(YMAX_OOB);
|
694
|
+
|
695
|
+
// m_box(ARY_SIZE(parms), parms, self);
|
696
|
+
|
697
|
+
return self;
|
698
|
+
}
|
699
|
+
|
700
|
+
/* offset function */
|
701
|
+
VALUE
|
702
|
+
m_offset(int argc, VALUE * argv, VALUE self)
|
703
|
+
{
|
704
|
+
char * try_offset;
|
705
|
+
|
706
|
+
ADJUST_SELF(self);
|
707
|
+
|
708
|
+
if(argc == 0)
|
709
|
+
return get_image_local(self, DRAW_OFFSET);
|
710
|
+
|
711
|
+
switch(TYPE(argv[0])) {
|
712
|
+
|
713
|
+
case T_ARRAY:
|
714
|
+
|
715
|
+
set_image_local(self, DRAW_OFFSET, argv[0]);
|
716
|
+
break;
|
717
|
+
case T_SYMBOL:
|
718
|
+
try_offset = sym2string(argv[0]);
|
719
|
+
|
720
|
+
if(!strcmp("default", try_offset)) {
|
721
|
+
set_image_local(self, DRAW_OFFSET, Qnil);
|
722
|
+
}
|
723
|
+
else {
|
724
|
+
rb_raise(rb_eArgError, "no such offset defined: %s\n", try_offset);
|
725
|
+
}
|
726
|
+
|
727
|
+
break;
|
728
|
+
default:
|
729
|
+
rb_raise(rb_eArgError, "invalid offset. please use an array or :default.");
|
730
|
+
}
|
731
|
+
return Qnil;
|
732
|
+
}
|
733
|
+
|
734
|
+
/* color change */
|
735
|
+
VALUE
|
736
|
+
m_color(int argc, VALUE * argv, VALUE self)
|
737
|
+
{
|
738
|
+
VALUE first;
|
739
|
+
rgba new_color;
|
740
|
+
|
741
|
+
ADJUST_SELF(self);
|
742
|
+
|
743
|
+
/* if no params then return action current color */
|
744
|
+
if(argc == 0)
|
745
|
+
return get_image_local(self, IMAGE_COLOR);
|
746
|
+
|
747
|
+
/* otherwise set the action color */
|
748
|
+
/* NB: we cannot just set image_local_color to 'first' because first may not be an array,
|
749
|
+
it could also be a symbol */
|
750
|
+
|
751
|
+
first = argv[0];
|
752
|
+
|
753
|
+
new_color = convert_rb_color_to_rgba(first);
|
754
|
+
|
755
|
+
/* im quite sure i DO want to set the color even if it is not_a_color.
|
756
|
+
why ? consistency only
|
757
|
+
(NB: not_a_color_v is skipped by the set_pixel_color routine */
|
758
|
+
|
759
|
+
/* if(is_a_color(new_color)) */
|
760
|
+
|
761
|
+
save_rgba_to_image_local_color(self, new_color);
|
762
|
+
|
763
|
+
return Qnil;
|
764
|
+
}
|
765
|
+
|
766
|
+
/* this function manages all other method calls */
|
767
|
+
VALUE
|
768
|
+
m_missing(int argc, VALUE * argv, VALUE self)
|
769
|
+
{
|
770
|
+
char * action_name = lowercase(sym2string(argv[0]));
|
771
|
+
|
772
|
+
/* try case insensitive version of action name */
|
773
|
+
if(rb_respond_to(self, rb_intern(action_name))) {
|
774
|
+
rb_funcall2(self, rb_intern(action_name), --argc, ++argv);
|
775
|
+
}
|
776
|
+
/* still no match? then method does not exist */
|
777
|
+
else {
|
778
|
+
rb_raise (rb_eRuntimeError, "unrecognized action: %s\n", action_name);
|
779
|
+
}
|
780
|
+
|
781
|
+
return self;
|
782
|
+
}
|
783
|
+
|
784
|
+
/* refreshes the cache */
|
785
|
+
VALUE
|
786
|
+
m_cache_refresh(VALUE self)
|
787
|
+
{
|
788
|
+
texture_info tex;
|
789
|
+
|
790
|
+
ADJUST_SELF(self);
|
791
|
+
|
792
|
+
get_texture_info(self, &tex);
|
793
|
+
|
794
|
+
cache_refresh_entry(tex.tname);
|
795
|
+
|
796
|
+
return self;
|
797
|
+
}
|
798
|
+
|
799
|
+
/* check whether img quad is already cached */
|
800
|
+
VALUE
|
801
|
+
m_quad_cached(VALUE self)
|
802
|
+
{
|
803
|
+
VALUE info, gc_state_off;
|
804
|
+
int tex_name;
|
805
|
+
cache_entry * entry;
|
806
|
+
|
807
|
+
ADJUST_SELF(self);
|
808
|
+
|
809
|
+
/* prevent weird segfault bug */
|
810
|
+
gc_state_off = rb_gc_disable();
|
811
|
+
|
812
|
+
/* ensure gl_tex_info returns non nil */
|
813
|
+
info = check_for_texture_info(self);
|
814
|
+
|
815
|
+
tex_name = FIX2INT(rb_funcall(info, rb_intern("tex_name"), 0));
|
816
|
+
|
817
|
+
entry = find_in_cache(tex_name);
|
818
|
+
|
819
|
+
/* only enable gc if was enabled on function entry */
|
820
|
+
if(!gc_state_off) rb_gc_enable();
|
821
|
+
|
822
|
+
return entry ? Qtrue : Qfalse;
|
823
|
+
}
|
824
|
+
|
825
|
+
/** m_each **/
|
826
|
+
VALUE
|
827
|
+
m_each(int argc, VALUE * argv, VALUE self)
|
828
|
+
{
|
829
|
+
int x1 = 0, y1 = 0, x2 = XMAX_OOB, y2 = YMAX_OOB;
|
830
|
+
texture_info tex;
|
831
|
+
VALUE proc;
|
832
|
+
VALUE options = Qnil;
|
833
|
+
|
834
|
+
rb_need_block();
|
835
|
+
|
836
|
+
ADJUST_SELF(self);
|
837
|
+
|
838
|
+
get_texture_info(self, &tex);
|
839
|
+
|
840
|
+
if(argc >= 1) {
|
841
|
+
options = argv[0];
|
842
|
+
Check_Type(options, T_HASH);
|
843
|
+
if(RTEST(get_from_hash(options, "region"))) {
|
844
|
+
VALUE region = get_from_hash(options, "region");
|
845
|
+
Check_Type(region, T_ARRAY);
|
846
|
+
|
847
|
+
if(RARRAY_LEN(region) < 4)
|
848
|
+
rb_raise(rb_eArgError, "region requires 4 elements");
|
849
|
+
|
850
|
+
x1 = NUM2INT(get_from_array(region, 0));
|
851
|
+
y1 = NUM2INT(get_from_array(region, 1));
|
852
|
+
x2 = NUM2INT(get_from_array(region, 2));
|
853
|
+
y2 = NUM2INT(get_from_array(region, 3));
|
854
|
+
|
855
|
+
}
|
856
|
+
|
857
|
+
}
|
858
|
+
|
859
|
+
constrain_boundaries(&x1, &y1,
|
860
|
+
&x2, &y2, tex.width, tex.height);
|
861
|
+
|
862
|
+
proc = rb_block_proc();
|
863
|
+
|
864
|
+
each_pixel_do_action(x1, y1, x2, y2, proc, &tex, options, sync_mode, true, NULL);
|
865
|
+
|
866
|
+
return self;
|
867
|
+
}
|
868
|
+
/** end of each **/
|
869
|
+
|
870
|
+
/** turtle drawing functions **/
|
871
|
+
/* static VALUE */
|
872
|
+
/* m_turtle_move_to */
|
873
|
+
|
874
|
+
/* VALUE */
|
875
|
+
/* m_bezier(int argc, VALUE * argv, VALUE self) */
|
876
|
+
/* { */
|
877
|
+
/* VALUE points = Qnil; */
|
878
|
+
/* VALUE options = Qnil; */
|
879
|
+
/* int last = argc - 1; */
|
880
|
+
/* texture_info tex; */
|
881
|
+
|
882
|
+
/* ADJUST_SELF(self); */
|
883
|
+
|
884
|
+
/* if(argc < 1) rb_raise(rb_eArgError, "bezier action needs at least 1 parameter"); */
|
885
|
+
|
886
|
+
/* /\* get array of points *\/ */
|
887
|
+
/* points = argv[0]; */
|
888
|
+
/* Check_Type(points, T_ARRAY); */
|
889
|
+
|
890
|
+
/* options = argv[last]; */
|
891
|
+
|
892
|
+
/* get_texture_info(self, &tex); */
|
893
|
+
|
894
|
+
/* bezier_do_action(points, &tex, options, sync_mode, true, NULL); */
|
895
|
+
|
896
|
+
/* return self; */
|
897
|
+
/* } */
|
898
|
+
|
899
|
+
/** end turtle drawing **/
|
900
|
+
|
901
|
+
|
902
|
+
/* below is yucky old code that needs to be updated */
|
903
|
+
/* each_pixel iterator */
|
904
|
+
|
905
|
+
|
906
|
+
/* VALUE */
|
907
|
+
/* m_each(int argc, VALUE * argv, VALUE self) */
|
908
|
+
/* { */
|
909
|
+
/* int x0, y0, x1, y1, xbound, ybound, arity; */
|
910
|
+
/* VALUE options, region, pixel_data[2], yield_vals; */
|
911
|
+
/* register int x, y; */
|
912
|
+
/* texture_info tex; */
|
913
|
+
/* image_bounds bounds; */
|
914
|
+
|
915
|
+
/* rb_need_block(); */
|
916
|
+
|
917
|
+
/* arity = FIX2INT(rb_funcall(rb_block_proc(), rb_intern("arity"), 0)); */
|
918
|
+
/* if(arity != 1 && arity != 3) */
|
919
|
+
/* rb_raise(rb_eRuntimeError, "block arity must be either 1 or 3"); */
|
920
|
+
|
921
|
+
/* /\* ADJUST_SELF(self); *\/ */
|
922
|
+
|
923
|
+
/* /\* rb_scan_args(argc, argv, "01", &options); *\/ */
|
924
|
+
|
925
|
+
/* /\* /\\* get texture info *\\/ *\/ */
|
926
|
+
/* /\* get_texture_info(self, &tex); *\/ */
|
927
|
+
|
928
|
+
/* /\* /\\* default values for region *\\/ *\/ */
|
929
|
+
/* /\* x0 = 0; y0 = 0; x1 = tex.width; y1 = tex.height; *\/ */
|
930
|
+
|
931
|
+
/* /\* if(has_optional_hash_arg(options, "region")) { *\/ */
|
932
|
+
/* /\* region = get_from_hash(options, "region"); *\/ */
|
933
|
+
|
934
|
+
/* /\* x0 = NUM2INT(get_from_array(region, 0)); *\/ */
|
935
|
+
/* /\* y0 = NUM2INT(get_from_array(region, 1)); *\/ */
|
936
|
+
/* /\* x1 = NUM2INT(get_from_array(region, 2)); *\/ */
|
937
|
+
/* /\* y1 = NUM2INT(get_from_array(region, 3)); *\/ */
|
938
|
+
|
939
|
+
/* /\* constrain_boundaries(&x0, &y0, &x1, &y1, tex.width, tex.height); *\/ */
|
940
|
+
/* /\* } *\/ */
|
941
|
+
|
942
|
+
/* /\* /\\* width and height of action *\\/ *\/ */
|
943
|
+
/* /\* xbound = x1 - x0; *\/ */
|
944
|
+
/* /\* ybound = y1 - y0; *\/ */
|
945
|
+
|
946
|
+
/* /\* yield_vals = rb_ary_new(); *\/ */
|
947
|
+
|
948
|
+
/* /\* for(y = 0; y < ybound; y++) *\/ */
|
949
|
+
/* /\* for(x = 0; x < xbound; x++) { *\/ */
|
950
|
+
/* /\* VALUE pixel_color; *\/ */
|
951
|
+
/* /\* rgba old_color; *\/ */
|
952
|
+
|
953
|
+
/* /\* /\\* adjusted x and y *\\/ *\/ */
|
954
|
+
/* /\* register int ax = x + x0, ay = y + y0; *\/ */
|
955
|
+
|
956
|
+
/* /\* pixel_data[0] = INT2FIX(ax); *\/ */
|
957
|
+
/* /\* pixel_data[1] = INT2FIX(ay); *\/ */
|
958
|
+
|
959
|
+
/* /\* pixel_color = m_getpixel(self, INT2FIX(ax), INT2FIX(ay)); *\/ */
|
960
|
+
|
961
|
+
/* /\* if(arity == 1) { *\/ */
|
962
|
+
/* /\* rb_yield(pixel_color); *\/ */
|
963
|
+
/* /\* } *\/ */
|
964
|
+
/* /\* else if(arity == 3) { *\/ */
|
965
|
+
/* /\* rb_ary_store(yield_vals, 0, pixel_color); *\/ */
|
966
|
+
/* /\* rb_ary_store(yield_vals, 1, INT2FIX(x)); *\/ */
|
967
|
+
/* /\* rb_ary_store(yield_vals, 2, INT2FIX(y)); *\/ */
|
968
|
+
|
969
|
+
/* /\* rb_yield(yield_vals); *\/ */
|
970
|
+
/* /\* } *\/ */
|
971
|
+
|
972
|
+
/* /\* m_color(1, &pixel_color, self); *\/ */
|
973
|
+
/* /\* // process_action(pixel, self, 2, pixel_data, false); *\/ */
|
974
|
+
/* /\* // color_struct = old_color; *\/ */
|
975
|
+
/* /\* } *\/ */
|
976
|
+
|
977
|
+
/* /\* bounds.xmin = x0; *\/ */
|
978
|
+
/* /\* bounds.ymin = y0; *\/ */
|
979
|
+
/* /\* bounds.xmax = x1; *\/ */
|
980
|
+
/* /\* bounds.ymax = y1; *\/ */
|
981
|
+
|
982
|
+
/* /\* create_subtexture_and_sync_to_gl(&bounds, &tex); *\/ */
|
983
|
+
|
984
|
+
/* /\* return self; *\/ */
|
985
|
+
/* /\* } *\/ */
|
986
|
+
|
987
|
+
/* /\** end each_pixel algorithm **\/} */
|
988
|
+
/* /\** end each_pixel algorithm **\/ */
|
989
|
+
|
990
|
+
|
991
|
+
/* /\* VALUE *\/ */
|
992
|
+
/* /\* m_lshift(int argc, VALUE * argv, VALUE self) *\/ */
|
993
|
+
/* /\* { *\/ */
|
994
|
+
/* /\* int y,x, step, yoffset; *\/ */
|
995
|
+
/* /\* VALUE options, loop; *\/ */
|
996
|
+
/* /\* register int offset; *\/ */
|
997
|
+
/* /\* texture_info tex; *\/ */
|
998
|
+
/* /\* image_bounds bounds; *\/ */
|
999
|
+
|
1000
|
+
/* /\* ADJUST_SELF(self); *\/ */
|
1001
|
+
|
1002
|
+
/* /\* rb_scan_args(argc, argv, "01", &options); *\/ */
|
1003
|
+
|
1004
|
+
/* /\* /\\* default values for other params *\\/ *\/ */
|
1005
|
+
/* /\* step = 1; loop = Qfalse; *\/ */
|
1006
|
+
|
1007
|
+
/* /\* if(TYPE(options) == T_HASH) { *\/ */
|
1008
|
+
/* /\* step = NUM2INT(get_from_hash(options, "step")); *\/ */
|
1009
|
+
/* /\* loop = get_from_hash(options, "loop"); *\/ */
|
1010
|
+
/* /\* } *\/ */
|
1011
|
+
/* /\* else if(options != Qnil) { *\/ */
|
1012
|
+
/* /\* rb_raise(rb_eArgError, "argument must be a hash"); *\/ */
|
1013
|
+
/* /\* } *\/ */
|
1014
|
+
|
1015
|
+
/* /\* /\\* get texture info *\\/ *\/ */
|
1016
|
+
/* /\* get_texture_info(self, &tex); *\/ */
|
1017
|
+
|
1018
|
+
/* /\* for(y = 0; y < tex.height; y++) { *\/ */
|
1019
|
+
/* /\* for(x = 0; x < tex.width; x++) { *\/ */
|
1020
|
+
/* /\* offset = calc_pixel_offset(&tex, x, y); *\/ */
|
1021
|
+
|
1022
|
+
/* /\* if((x + step) < tex.width) { *\/ */
|
1023
|
+
/* /\* color_copy(tex.td_array + offset + step * 4, tex.td_array + offset); *\/ */
|
1024
|
+
/* /\* } *\/ */
|
1025
|
+
/* /\* else { *\/ */
|
1026
|
+
/* /\* if(loop == Qtrue) { *\/ */
|
1027
|
+
/* /\* yoffset = calc_pixel_offset(&tex, x + step - tex.width, y); *\/ */
|
1028
|
+
|
1029
|
+
/* /\* color_copy(tex.td_array + yoffset, tex.td_array + offset); *\/ */
|
1030
|
+
/* /\* } *\/ */
|
1031
|
+
/* /\* else { *\/ */
|
1032
|
+
|
1033
|
+
/* /\* zero_color(tex.td_array + offset); *\/ */
|
1034
|
+
/* /\* } *\/ */
|
1035
|
+
/* /\* } *\/ */
|
1036
|
+
|
1037
|
+
/* /\* } *\/ */
|
1038
|
+
/* /\* } *\/ */
|
1039
|
+
|
1040
|
+
/* /\* bounds.xmin = 0; *\/ */
|
1041
|
+
/* /\* bounds.xmax = tex.width; *\/ */
|
1042
|
+
/* /\* bounds.ymin = 0; *\/ */
|
1043
|
+
/* /\* bounds.ymax = tex.height; *\/ */
|
1044
|
+
|
1045
|
+
/* /\* create_subtexture_and_sync_to_gl(&bounds, &tex); *\/ */
|
1046
|
+
|
1047
|
+
/* /\* return Qnil; *\/ */
|
1048
|
+
/* /\* } *\/ */
|
1049
|
+
|
1050
|
+
/* /\* VALUE *\/ */
|
1051
|
+
/* /\* m_rshift(int argc, VALUE * argv, VALUE self) *\/ */
|
1052
|
+
/* /\* { *\/ */
|
1053
|
+
/* /\* int y,x, step, yoffset; *\/ */
|
1054
|
+
/* /\* VALUE options, loop; *\/ */
|
1055
|
+
/* /\* register int offset; *\/ */
|
1056
|
+
/* /\* texture_info tex; *\/ */
|
1057
|
+
/* /\* image_bounds bounds; *\/ */
|
1058
|
+
|
1059
|
+
/* /\* ADJUST_SELF(self); *\/ */
|
1060
|
+
|
1061
|
+
/* /\* rb_scan_args(argc, argv, "01", &options); *\/ */
|
1062
|
+
|
1063
|
+
/* /\* /\\* default values for other params *\\/ *\/ */
|
1064
|
+
/* /\* step = 1; loop = Qfalse; *\/ */
|
1065
|
+
|
1066
|
+
/* /\* if(TYPE(options) == T_HASH) { *\/ */
|
1067
|
+
/* /\* step = NUM2INT(get_from_hash(options, "step")); *\/ */
|
1068
|
+
/* /\* loop = get_from_hash(options, "loop"); *\/ */
|
1069
|
+
/* /\* } *\/ */
|
1070
|
+
/* /\* else if(options != Qnil) { *\/ */
|
1071
|
+
/* /\* rb_raise(rb_eArgError, "argument must be a hash"); *\/ */
|
1072
|
+
/* /\* } *\/ */
|
1073
|
+
|
1074
|
+
/* /\* /\\* get texture info *\\/ *\/ */
|
1075
|
+
/* /\* get_texture_info(self, &tex); *\/ */
|
1076
|
+
|
1077
|
+
/* /\* for(y = 0; y < tex.height; y++) { *\/ */
|
1078
|
+
/* /\* for(x = tex.width - 1; x > -1; x--) { *\/ */
|
1079
|
+
/* /\* offset = calc_pixel_offset(&tex, x, y); *\/ */
|
1080
|
+
|
1081
|
+
/* /\* if((x - step) > -1) { *\/ */
|
1082
|
+
/* /\* color_copy(tex.td_array + offset - step * 4, tex.td_array + offset); *\/ */
|
1083
|
+
/* /\* } *\/ */
|
1084
|
+
/* /\* else { *\/ */
|
1085
|
+
/* /\* if(loop == Qtrue) { *\/ */
|
1086
|
+
/* /\* yoffset = calc_pixel_offset(&tex, x + tex.width - step, y); *\/ */
|
1087
|
+
/* /\* color_copy(tex.td_array + yoffset, tex.td_array + offset); *\/ */
|
1088
|
+
/* /\* } *\/ */
|
1089
|
+
/* /\* else { *\/ */
|
1090
|
+
/* /\* zero_color(tex.td_array + offset); *\/ */
|
1091
|
+
/* /\* } *\/ */
|
1092
|
+
/* /\* } *\/ */
|
1093
|
+
|
1094
|
+
/* /\* } *\/ */
|
1095
|
+
/* /\* } *\/ */
|
1096
|
+
|
1097
|
+
/* /\* bounds.xmin = 0; *\/ */
|
1098
|
+
/* /\* bounds.xmax = tex.width; *\/ */
|
1099
|
+
/* /\* bounds.ymin = 0; *\/ */
|
1100
|
+
/* /\* bounds.ymax = tex.height; *\/ */
|
1101
|
+
|
1102
|
+
/* /\* create_subtexture_and_sync_to_gl(&bounds, &tex); *\/ */
|
1103
|
+
|
1104
|
+
/* /\* return Qnil; *\/ */
|
1105
|
+
/* /\* } *\/ */
|
1106
|
+
|
1107
|
+
/* /\* /\\* special pixel action for image[]= *\\/ *\/ */
|
1108
|
+
/* /\* VALUE *\/ */
|
1109
|
+
/* /\* m_special_pixel(int argc, VALUE * argv, VALUE self) *\/ */
|
1110
|
+
/* /\* { *\/ */
|
1111
|
+
|
1112
|
+
/* /\* rgba old_color; *\/ */
|
1113
|
+
|
1114
|
+
/* /\* ADJUST_SELF(self); *\/ */
|
1115
|
+
|
1116
|
+
/* /\* if(argc < 3) rb_raise(rb_eArgError, "[]= action needs 3 parameters"); *\/ */
|
1117
|
+
|
1118
|
+
/* /\* m_color(1, &argv[2], self); *\/ */
|
1119
|
+
|
1120
|
+
/* /\* m_pixel(2, argv, self); *\/ */
|
1121
|
+
|
1122
|
+
/* /\* // color_struct = old_color; *\/ */
|
1123
|
+
|
1124
|
+
|
1125
|
+
/* /\* return Qnil; *\/ */
|
1126
|
+
/* /\* } *\/ */
|
1127
|
+
|
1128
|
+
/* /\* /\\* instance methods *\\/ *\/ */
|
1129
|
+
|