texplay 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/CHANGELOG +63 -0
  2. data/README +21 -0
  3. data/README1st +9 -0
  4. data/Rakefile +85 -0
  5. data/examples/basic.rb +48 -0
  6. data/examples/basic2.rb +37 -0
  7. data/examples/benchmark.rb +299 -0
  8. data/examples/common.rb +8 -0
  9. data/examples/example_alpha_blend.rb +31 -0
  10. data/examples/example_bezier.rb +51 -0
  11. data/examples/example_color_control.rb +68 -0
  12. data/examples/example_color_transform.rb +29 -0
  13. data/examples/example_dup.rb +52 -0
  14. data/examples/example_each.rb +42 -0
  15. data/examples/example_effect.rb +35 -0
  16. data/examples/example_fill.rb +49 -0
  17. data/examples/example_fill_old.rb +49 -0
  18. data/examples/example_fluent.rb +31 -0
  19. data/examples/example_gen_eval.rb +34 -0
  20. data/examples/example_hash_arguments.rb +47 -0
  21. data/examples/example_melt.rb +27 -0
  22. data/examples/example_polyline.rb +43 -0
  23. data/examples/example_simple.rb +35 -0
  24. data/examples/example_splice.rb +37 -0
  25. data/examples/example_sync.rb +60 -0
  26. data/examples/example_turtle.rb +40 -0
  27. data/examples/media/empty2.png +0 -0
  28. data/examples/media/gosu.png +0 -0
  29. data/examples/media/maria.png +0 -0
  30. data/examples/media/rose.bmp +0 -0
  31. data/examples/media/sand1.png +0 -0
  32. data/examples/media/sunset.png +0 -0
  33. data/examples/media/texplay.png +0 -0
  34. data/examples/specs.rb +240 -0
  35. data/examples/test.rb +70 -0
  36. data/examples/test2.rb +72 -0
  37. data/lib/texplay-contrib.rb +77 -0
  38. data/lib/texplay.rb +134 -0
  39. data/src/Makefile +181 -0
  40. data/src/TAGS +286 -0
  41. data/src/actions.c +1306 -0
  42. data/src/actions.h +52 -0
  43. data/src/actions.o +0 -0
  44. data/src/bindings.c +1081 -0
  45. data/src/bindings.h +45 -0
  46. data/src/bindings.o +0 -0
  47. data/src/cache.c +132 -0
  48. data/src/cache.h +24 -0
  49. data/src/cache.o +0 -0
  50. data/src/compat.h +23 -0
  51. data/src/ctexplay.so +0 -0
  52. data/src/extconf.rb +18 -0
  53. data/src/gen_eval.c +209 -0
  54. data/src/gen_eval.h +20 -0
  55. data/src/gen_eval.o +0 -0
  56. data/src/mkmf.log +22 -0
  57. data/src/object2module.c +171 -0
  58. data/src/object2module.h +11 -0
  59. data/src/object2module.o +0 -0
  60. data/src/texplay.c +136 -0
  61. data/src/texplay.h +107 -0
  62. data/src/texplay.o +0 -0
  63. data/src/utils.c +959 -0
  64. data/src/utils.h +143 -0
  65. data/src/utils.o +0 -0
  66. metadata +126 -0
@@ -0,0 +1,45 @@
1
+ #ifndef GUARD_BINDINGS_H
2
+ #define GUARD_BINDINGS_H
3
+
4
+ /* class methods */
5
+ VALUE M_create_macro(VALUE self , VALUE method_name);
6
+ VALUE M_remove_macro(VALUE self, VALUE method_name);
7
+ VALUE M_refresh_cache_all(VALUE self);
8
+ VALUE M_create_blank(VALUE self, VALUE window, VALUE width, VALUE height);
9
+
10
+ /* instance methods */
11
+ VALUE m_paint(int argc, VALUE * argv, VALUE self);
12
+ VALUE m_getpixel(int argc, VALUE * argv, VALUE self);
13
+ VALUE m_circle(int argc, VALUE * argv, VALUE self);
14
+ VALUE m_line(int argc, VALUE * argv, VALUE self);
15
+ VALUE m_rect(int argc, VALUE * argv, VALUE self);
16
+ VALUE m_pixel(int argc, VALUE * argv, VALUE self);
17
+ VALUE m_flood_fill(int argc, VALUE * argv, VALUE self);
18
+ VALUE m_bezier(int argc, VALUE * argv, VALUE self);
19
+ VALUE m_polyline(int argc, VALUE * argv, VALUE self);
20
+ VALUE m_ngon(int argc, VALUE * argv, VALUE self);
21
+ VALUE m_special_pixel(int argc, VALUE * argv, VALUE self);
22
+ VALUE m_splice(int argc, VALUE * argv, VALUE self);
23
+ VALUE m_clear(int argc, VALUE * argv, VALUE self);
24
+ VALUE m_offset(int argc, VALUE * argv, VALUE self);
25
+ VALUE m_color(int argc, VALUE * argv, VALUE self);
26
+ VALUE m_missing(int argc, VALUE * argv, VALUE self);
27
+ VALUE m_bitmask(int argc, VALUE * argv, VALUE self);
28
+ VALUE m_lshift(int argc, VALUE * argv, VALUE self);
29
+ VALUE m_rshift(int argc, VALUE * argv, VALUE self);
30
+
31
+ VALUE m_each(int argc, VALUE * argv, VALUE self);
32
+
33
+
34
+ VALUE m_quad_cached(VALUE self);
35
+ VALUE m_cache_refresh(VALUE self);
36
+
37
+ VALUE m_user_set_options(VALUE self, VALUE options);
38
+ VALUE m_user_delete_options(VALUE self);
39
+ VALUE m_get_options(VALUE self);
40
+ VALUE m_force_sync(VALUE self, VALUE ary);
41
+
42
+ VALUE m_dup_image(VALUE self);
43
+ VALUE m_clone_image(VALUE self);
44
+
45
+ #endif
Binary file
@@ -0,0 +1,132 @@
1
+ /* cache.c */
2
+
3
+ #include <ruby.h>
4
+
5
+ #ifdef __APPLE__
6
+ #include <glut.h>
7
+ #else
8
+ #include <GL/glut.h>
9
+ #endif
10
+
11
+ #include "cache.h"
12
+ #include "texplay.h"
13
+
14
+ typedef struct {
15
+ int len;
16
+ cache_entry entry[CACHE_SIZE];
17
+ } cache_t;
18
+
19
+ /* var has internal linkage, static duration */
20
+ /* contains cache data */
21
+ static cache_t cache = {0};
22
+
23
+ /* create a new cache entry */
24
+ cache_entry*
25
+ cache_create_entry(int tname) {
26
+ float * new_array;
27
+ int sidelength, new_element = cache.len;
28
+ GLint saved_tname;
29
+
30
+ if(cache.len >= CACHE_SIZE) { rb_raise(rb_eRuntimeError, "cache is full! increase CACHE_SIZE"); }
31
+
32
+ /* save current texture binding */
33
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &saved_tname);
34
+
35
+ /* opengl initialization code */
36
+ glEnable(GL_TEXTURE_2D);
37
+ glBindTexture(GL_TEXTURE_2D, tname);
38
+
39
+ /* get length of a side, since square texture */
40
+ glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &sidelength);
41
+
42
+ /* initialize texture data array, mult. by 4 because {rgba} */
43
+ new_array = malloc(sidelength * sidelength * 4 * sizeof(float));
44
+
45
+ /* get texture data from video memory */
46
+ glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT,(void*)(new_array));
47
+
48
+ /* save texture data in the cache */
49
+ cache.entry[new_element].tname = tname;
50
+ cache.entry[new_element].sidelength = sidelength;
51
+ cache.entry[new_element].tdata = new_array;
52
+
53
+ /* update size of cache */
54
+ cache.len++;
55
+
56
+ /* restore saved texture binding */
57
+ glBindTexture(GL_TEXTURE_2D, saved_tname);
58
+
59
+ return &cache.entry[new_element];
60
+ }
61
+
62
+ /* return the entry if it exists, otherwise return NULL */
63
+ cache_entry*
64
+ find_in_cache(int tname) {
65
+ /* check if entry exists in cache */
66
+ int index;
67
+ for(index = 0; index < cache.len; index++)
68
+ if(cache.entry[index].tname == tname)
69
+ return &cache.entry[index];
70
+
71
+
72
+ return NULL;
73
+ }
74
+
75
+ /* if the entry doesn't exist then create it and return it.
76
+ otherwise just return it */
77
+ cache_entry*
78
+ find_or_create_cache_entry(int tname) {
79
+ cache_entry * entry;
80
+
81
+ if((entry=find_in_cache(tname)))
82
+ return entry;
83
+ else
84
+ return cache_create_entry(tname);
85
+ }
86
+
87
+ /* refresh the cache for all quads */
88
+ void
89
+ cache_refresh_all(void) {
90
+ float * tdata;
91
+ int tname, index;
92
+ GLint saved_tname;
93
+
94
+ /* save current texture binding */
95
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &saved_tname);
96
+
97
+ for(index = 0; index < cache.len; index++) {
98
+ tdata = cache.entry[index].tdata;
99
+ tname = cache.entry[index].tname;
100
+
101
+ /* opengl initialization code */
102
+ glEnable(GL_TEXTURE_2D);
103
+ glBindTexture(GL_TEXTURE_2D, tname);
104
+
105
+ glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, (void*)(tdata));
106
+ }
107
+
108
+ /* restore saved texture binding */
109
+ glBindTexture(GL_TEXTURE_2D, saved_tname);
110
+ }
111
+
112
+ /* refresh the cache for a specific quad */
113
+ void
114
+ cache_refresh_entry(int tname) {
115
+ GLint saved_tname;
116
+ cache_entry * entry;
117
+
118
+ /* save current texture binding */
119
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &saved_tname);
120
+
121
+ entry = find_in_cache(tname);
122
+
123
+ /* opengl initialization code */
124
+ glEnable(GL_TEXTURE_2D);
125
+ glBindTexture(GL_TEXTURE_2D, entry->tname);
126
+
127
+ glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, (void*)(entry->tdata));
128
+
129
+ /* restore saved texture binding */
130
+ glBindTexture(GL_TEXTURE_2D, saved_tname);
131
+ }
132
+
@@ -0,0 +1,24 @@
1
+ /* cache.h */
2
+ /* see cache.c for annotations */
3
+
4
+ #ifndef GUARD_CACHE_H
5
+ #define GUARD_CACHE_H
6
+
7
+ /* defines */
8
+ #define CACHE_SIZE 10000
9
+
10
+ /* data types */
11
+ typedef struct {
12
+ int tname;
13
+ int sidelength;
14
+ float * tdata;
15
+ } cache_entry;
16
+
17
+ /* functions */
18
+ void cache_refresh_all(void);
19
+ void cache_refresh_entry(int tname);
20
+ cache_entry * cache_create_entry(int texture_name);
21
+ cache_entry * find_in_cache(int texture_name);
22
+ cache_entry * find_or_create_cache_entry(int texture_name);
23
+
24
+ #endif
Binary file
@@ -0,0 +1,23 @@
1
+ /* contains basic macros to facilitate ruby 1.8 and ruby 1.9 compatibility */
2
+
3
+ #ifndef GUARD_COMPAT_H
4
+ #define GUARD_COMPAT_H
5
+
6
+ #include <ruby.h>
7
+
8
+ /* this is the test we use to identify ruby 1.9.1 */
9
+ #ifdef RCLASS_M_TBL
10
+ # define RUBY_19
11
+ #endif
12
+
13
+ /* macros for backwards compatibility with 1.8 */
14
+ #ifndef RUBY_19
15
+ # define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl)
16
+ # define RCLASS_SUPER(c) (RCLASS(c)->super)
17
+ # define RCLASS_IV_TBL(c) (RCLASS(c)->iv_tbl)
18
+ #endif
19
+
20
+ /* a useful macro. cannot use ordinary CLASS_OF as it does not return an lvalue */
21
+ #define KLASS_OF(c) (RBASIC(c)->klass)
22
+
23
+ #endif
Binary file
@@ -0,0 +1,18 @@
1
+ require 'mkmf'
2
+
3
+
4
+ # linux
5
+ if RUBY_PLATFORM =~ /linux/ then
6
+ exit unless have_library("glut")
7
+
8
+ # macosx
9
+ elsif RUBY_PLATFORM =~ /darwin/
10
+ $LDFLAGS += " -framework GLUT"
11
+ $CPPFLAGS += " -I/System/Library/Frameworks/GLUT.framework/Headers"
12
+
13
+ # windows
14
+ else
15
+ exit unless have_library("glut32")
16
+ end
17
+
18
+ create_makefile('ctexplay')
@@ -0,0 +1,209 @@
1
+ /* gen_eval.c */
2
+ /* (C) John Mair 2009
3
+ * This program is distributed under the terms of the MIT License
4
+ * */
5
+
6
+ #include <ruby.h>
7
+ #include "object2module.h"
8
+ #include "compat.h"
9
+
10
+ VALUE
11
+ retrieve_hidden_self(VALUE duped_context)
12
+ {
13
+ VALUE thread_id, unique_name, hidden_self;
14
+
15
+ /* retrieve hidden self (if it exists) */
16
+ thread_id = rb_funcall(rb_obj_id(rb_thread_current()), rb_intern("to_s"), 0);
17
+ unique_name = rb_str_plus(rb_str_new2("__hidden_self__"), thread_id);
18
+
19
+ hidden_self = rb_ivar_get(duped_context, rb_to_id(unique_name));
20
+
21
+ return hidden_self;
22
+ }
23
+
24
+ void
25
+ set_hidden_self(VALUE duped_context, VALUE hidden_self)
26
+ {
27
+ VALUE thread_id, unique_name;
28
+
29
+ /* generate a unique (thread safe) name for the hidden self */
30
+ thread_id = rb_funcall(rb_obj_id(rb_thread_current()), rb_intern("to_s"), 0);
31
+ unique_name = rb_str_plus(rb_str_new2("__hidden_self__"), thread_id);
32
+
33
+ /* store self in hidden var in duped context */
34
+ rb_ivar_set(duped_context, rb_to_id(unique_name), hidden_self);
35
+ }
36
+
37
+ VALUE
38
+ rb_capture(VALUE self) {
39
+ VALUE hidden_self;
40
+
41
+ rb_need_block();
42
+
43
+ hidden_self = retrieve_hidden_self(self);
44
+
45
+ /* 2 cases: (1) if rb_gen_eval is active then instance_eval wrt hidden_self
46
+ (2) otherwise simply yield to the block
47
+ */
48
+ if(!NIL_P(hidden_self))
49
+ rb_obj_instance_eval(0, 0, hidden_self);
50
+ else
51
+ rb_yield(Qnil);
52
+
53
+ return hidden_self;
54
+ }
55
+
56
+ /** ruby 1.9 funcs **/
57
+ #ifdef RUBY_19
58
+ void
59
+ redirect_iv_for_object(VALUE obj, VALUE dest)
60
+ {
61
+ if(TYPE(obj) != T_OBJECT)
62
+ rb_raise(rb_eArgError, "must provide a T_OBJECT");
63
+
64
+ if (!(RBASIC(dest)->flags & ROBJECT_EMBED) && ROBJECT_IVPTR(dest)) {
65
+ rb_raise(rb_eArgError, "im sorry gen_eval does not yet work with this type of ROBJECT");
66
+ }
67
+ if (RBASIC(obj)->flags & ROBJECT_EMBED) {
68
+ rb_raise(rb_eArgError, "im sorry gen_eval does not yet work with ROBJECT_EMBED types");
69
+ }
70
+ else {
71
+ ROBJECT(dest)->as.heap.ivptr = ROBJECT(obj)->as.heap.ivptr;
72
+ ROBJECT(dest)->as.heap.numiv = ROBJECT(obj)->as.heap.numiv;
73
+ ROBJECT(dest)->as.heap.iv_index_tbl = ROBJECT(obj)->as.heap.iv_index_tbl;
74
+ RBASIC(dest)->flags &= ~ROBJECT_EMBED;
75
+ }
76
+ }
77
+
78
+ void
79
+ release_iv_for_object(VALUE obj)
80
+ {
81
+ if(TYPE(obj) != T_OBJECT)
82
+ rb_raise(rb_eArgError, "must provide a T_OBJECT");
83
+
84
+ ROBJECT(obj)->as.heap.ivptr = (void *) 0;
85
+ ROBJECT(obj)->as.heap.numiv = 0;
86
+ ROBJECT(obj)->as.heap.iv_index_tbl = (void *) 0;
87
+ RBASIC(obj)->flags &= ~ROBJECT_EMBED;
88
+ }
89
+ #endif
90
+ /** end of ruby 1.9 funcs **/
91
+
92
+ VALUE
93
+ rb_gen_eval(int argc, VALUE * argv, VALUE self) {
94
+ VALUE duped_context;
95
+ VALUE is_a_module;
96
+ VALUE context;
97
+ VALUE result;
98
+
99
+ rb_need_block();
100
+
101
+ context = rb_funcall(rb_block_proc(), rb_intern("__context__"), 0);
102
+
103
+ /* using Class instead of Object (where possible) because Object's iv_tbl setup in 1.9 is weird */
104
+ #ifdef RUBY_19
105
+ if(TYPE(context) == T_OBJECT)
106
+ duped_context = rb_funcall(rb_cObject, rb_intern("new"), 0);
107
+ else
108
+ duped_context = rb_funcall(rb_cClass, rb_intern("new"), 0);
109
+
110
+ #else
111
+
112
+ duped_context = rb_funcall(rb_cClass, rb_intern("new"), 0);
113
+
114
+ #endif
115
+
116
+
117
+ /* the duped_context shares the context's iv_tbl.
118
+ 2 cases: (1) external iv_tbl, (2) local iv_tbl
119
+
120
+ NOTE: we do not need to save original iv_tbl before replacing it, a brand new Class
121
+ instance does not yet have an iv_tbl (the pointer is set to 0)
122
+ */
123
+ if(FL_TEST(context, FL_EXIVAR))
124
+ RCLASS_IV_TBL(duped_context) = (struct st_table *) rb_generic_ivar_table(context);
125
+ else {
126
+ #ifdef RUBY_19
127
+ if(TYPE(context) == T_OBJECT)
128
+ redirect_iv_for_object(context, duped_context);
129
+ else {
130
+ RCLASS_IV_TBL(duped_context) = (struct st_table *) RCLASS_IV_TBL(context);
131
+ }
132
+ #else
133
+ RCLASS_IV_TBL(duped_context) = (struct st_table *) RCLASS_IV_TBL(context);
134
+ #endif
135
+
136
+
137
+ }
138
+
139
+ /* ensure singleton exists */
140
+ rb_singleton_class(context);
141
+
142
+ /* set up the class hierarchy for our dup_context */
143
+ KLASS_OF(duped_context) = rb_singleton_class_clone(context);
144
+
145
+ /* if no args then default to mixing in 'self' */
146
+ if(argc == 0) {
147
+ argc = 1;
148
+ argv = &self;
149
+ }
150
+
151
+ /* mix the objects (or self) into the duped context */
152
+ rb_gen_extend(argc, argv, duped_context);
153
+
154
+ /* store self in hidden var in duped context */
155
+ set_hidden_self(duped_context, self);
156
+
157
+ is_a_module = rb_funcall(duped_context, rb_intern("is_a?"), 1, rb_cModule);
158
+
159
+ /* eval block wrt duped_context */
160
+ if(is_a_module == Qtrue)
161
+ result = rb_mod_module_eval(0, 0, duped_context);
162
+ else
163
+ result = rb_obj_instance_eval(0, 0, duped_context);
164
+
165
+ /* clean up goes below */
166
+
167
+ /* release context's iv_tbl from duped_context. */
168
+ #ifdef RUBY_19
169
+ if(TYPE(duped_context) == T_OBJECT)
170
+ release_iv_for_object(duped_context);
171
+ else {
172
+ RCLASS_IV_TBL(duped_context) = (struct st_table *) 0;
173
+ }
174
+ #else
175
+ RCLASS_IV_TBL(duped_context) = (struct st_table *) 0;
176
+ #endif
177
+
178
+ /* delete hidden self */
179
+ set_hidden_self(duped_context, Qnil);
180
+
181
+ return result;
182
+ }
183
+
184
+ void
185
+ Init_gen_eval() {
186
+
187
+ rb_define_method(rb_cObject, "gen_eval", rb_gen_eval, -1);
188
+ rb_define_method(rb_cObject, "capture", rb_capture, 0);
189
+
190
+ rb_define_method(rb_cObject, "to_module", rb_to_module , 0);
191
+ rb_define_method(rb_cObject, "reset_tbls", rb_reset_tbls , 0);
192
+ rb_define_method(rb_cObject, "gen_extend", rb_gen_extend, -1);
193
+ rb_define_method(rb_cModule, "gen_include", rb_gen_include, -1);
194
+
195
+ /* below is much too hard to achieve in pure C */
196
+ rb_eval_string("class Proc;"
197
+ " def __context__;"
198
+ " eval('self', self.binding);"
199
+ " end;"
200
+ "end;"
201
+ );
202
+
203
+ rb_define_alias(rb_cObject, "gen_eval_with", "gen_eval");
204
+ }
205
+
206
+
207
+
208
+
209
+