1 /* tangram, Copyright (c) 2005 Jeremy English <jhe@jeremyenglish.org>
3 * Permission to use, copy, modify, distribute, and sell this software and its
4 * documentation for any purpose is hereby granted without fee, provided that
5 * the above copyright notice appear in all copies and that both that
6 * copyright notice and this permission notice appear in supporting
7 * documentation. No representations are made about the suitability of this
8 * software for any purpose. It is provided "as is" without express or
13 #include <X11/Intrinsic.h>
15 extern XtAppContext app;
17 #define PROGCLASS "TANGRAM"
18 #define HACK_INIT init_tangram
19 #define HACK_DRAW draw_tangram
20 #define HACK_RESHAPE reshape_tangram
21 #define sws_opts xlockmore_opts
24 #define DEFAULTS "*delay: 30000 \n" \
25 "*wireframe: False \n" \
28 #define countof(x) (sizeof((x))/sizeof((*x)))
30 #include "xlockmore.h"
35 #ifdef USE_GL /* whole file */
41 #include "tangram_shapes.h"
61 coord crd; /* coordinates */
62 GLint r; /* rotation */
63 GLint fr; /* flip Rotate. Used to keep track during animation */
64 GLint dl; /* display List */
85 tangram_shape solved[][7] = {
87 {{-1.664000, -1.552000, 0}, 135, 0, 0},
88 {{-1.696000, 0.944000, 0}, 315, 0, 0},
89 {{0.064000, -2.128000, 0}, 135, 0, 0},
90 {{-0.960000, -1.056000, 0}, 90, 0, 0},
91 {{1.104000, 0.960000, 0}, 270, 0, 0},
92 {{-1.376000, -0.800000, 0}, 180, 0, 0},
93 {{1.152000, 0.736000, 0}, 360, 0, 0},
96 {{-0.096000, 1.552000, 0}, 135, 180, 0},
97 {{-0.064000, 2.336000, 0}, 315, 0, 0},
98 {{-0.080000, -0.224000, 0}, 135, 180, 0},
99 {{-2.096000, 1.584000, 0}, 90, 180, 0},
100 {{1.920000, 1.584000, 0}, 270, 0, 0},
101 {{0.416000, -0.192000, 0}, 180, 0, 0},
102 {{-0.096000, -1.296000, 0}, 335, 0, 0},
105 {{-0.144000, -0.720000, 0}, 225, 0, 0},
106 {{0.608000, 0.032000, 0}, 135, 0, 0},
107 {{-1.584000, 0.720000, 0}, 0, 0, 0},
108 {{-0.112000, -0.720000, 0}, 315, 0, 0},
109 {{-0.096000, -0.704000, 0}, 45, 0, 0},
110 {{0.592000, 0.016000, 0}, 225, 0, 0},
111 {{-0.880000, -0.032000, 0}, 315, 0, 0},
114 {{1.472000, 2.176000, 0}, 225, 0, 0},
115 {{1.248000, 3.488000, 0}, 270, 0, 0},
116 {{-0.752000, -1.680000, 0}, 270, 0, 0},
117 {{0.704000, -1.552000, 0}, 135, 0, 0},
118 {{1.280000, -0.080000, 0}, 180, 0, 0},
119 {{-0.016000, -0.896000, 0}, 225, 0, 0},
120 {{-0.000000, -0.944000, 0}, 315, 0, 0},
123 {{0.320000, 1.360000, 0}, 90, 0, 0},
124 {{0.704000, 3.072000, 0}, 270, 0, 0},
125 {{-1.200000, -3.392000, 0}, 135, 0, 0},
126 {{0.688000, -1.184000, 0}, 135, 0, 0},
127 {{-0.768000, 0.192000, 0}, 315, 0, 0},
128 {{-1.168000, -2.304000, 0}, 180, 0, 0},
129 {{1.312000, 1.296000, 0}, 270, 0, 0},
132 {{-2.064000, 0.848000, 0}, 65, 0, 0},
133 {{0.096000, 1.424000, 0}, 99, 180, 0},
134 {{2.016000, -2.448000, 0}, 270, 180, 0},
135 {{-2.016000, 0.368000, 0}, 315, 0, 0},
136 {{-0.560000, -1.040000, 0}, 135, 0, 0},
137 {{1.312000, -1.696000, 0}, 225, 0, 0},
138 {{0.864000, 0.336000, 0}, 180, 180, 0},
141 {{0.560000, -0.208000, 0}, 135, 0, 0},
142 {{0.336000, -1.552000, 0}, 90, 180, 0},
143 {{-2.336000, 1.248000, 0}, 90, 180, 0},
144 {{1.296000, -1.504000, 0}, 180, 0, 0},
145 {{-0.896000, 1.200000, 0}, 135, 180, 0},
146 {{0.304000, -2.544000, 0}, 180, 0, 0},
147 {{1.248000, 0.544000, 0}, 225, 0, 0},
150 {{-0.480000, -2.832000, 0}, 45, 0, 0},
151 {{-0.544000, -2.832000, 0}, 225, 180, 0},
152 {{-0.064000, -0.880000, 0}, 225, 180, 0},
153 {{-2.528000, 2.656000, 0}, 0, 0, 0},
154 {{-2.512000, 0.640000, 0}, 45, 180, 0},
155 {{0.192000, -2.096000, 0}, 225, 0, 0},
156 {{-0.064000, -0.832000, 0}, 180, 0, 0},
159 {{0.880000, -1.456000, 0}, 45, 0, 0},
160 {{0.832000, 0.592000, 0}, 180, 180, 0},
161 {{-2.016000, 1.648000, 0}, 135, 180, 0},
162 {{0.448000, 2.064000, 0}, 315, 0, 0},
163 {{-0.992000, 0.688000, 0}, 315, 180, 0},
164 {{1.856000, -0.400000, 0}, 180, 0, 0},
165 {{-0.128000, -1.424000, 0}, 90, 0, 0},
168 {{2.208000, 2.000000, 0}, 180, 0, 0},
169 {{-0.640000, 3.072000, 0}, 180, 180, 0},
170 {{1.360000, -3.312000, 0}, 180, 0, 0},
171 {{-0.592000, 2.256000, 0}, 360, 0, 0},
172 {{-0.960000, -0.160000, 0}, 45, 180, 0},
173 {{0.288000, -2.896000, 0}, 135, 0, 0},
174 {{0.496000, -0.128000, 0}, 135, 0, 0},
177 {{-0.480000, 0.864000, 0}, 58, 180, 0},
178 {{0.624000, -0.752000, 0}, 90, 180, 0},
179 {{0.576000, -0.560000, 0}, 180, 180, 0},
180 {{-0.192000, -1.264000, 0}, 225, 0, 0},
181 {{-0.176000, -1.280000, 0}, 135, 180, 0},
182 {{-0.816000, -0.528000, 0}, 123, 0, 0},
183 {{-0.416000, -0.528000, 0}, 90, 0, 0},
186 {{0.688000, -0.144000, 0}, 45, 180, 0},
187 {{-0.080000, 0.592000, 0}, 225, 0, 0},
188 {{-0.048000, 0.592000, 0}, 315, 180, 0},
189 {{-1.488000, -0.848000, 0}, 45, 0, 0},
190 {{1.376000, -0.864000, 0}, 225, 180, 0},
191 {{0.688000, -0.128000, 0}, 135, 0, 0},
192 {{-1.504000, -0.832000, 0}, 135, 0, 0},
195 {{0.624000, -1.776000, 0}, 225, 180, 0},
196 {{-0.144000, 0.432000, 0}, 225, 0, 0},
197 {{-0.800000, -0.272000, 0}, 45, 180, 0},
198 {{-2.320000, -0.304000, 0}, 45, 0, 0},
199 {{2.048000, -0.320000, 0}, 225, 180, 0},
200 {{-0.112000, 0.480000, 0}, 135, 0, 0},
201 {{-0.832000, -0.320000, 0}, 135, 180, 0},
204 {{-1.744000, -0.400000, 0}, 45, 180, 0},
205 {{0.416000, 1.776000, 0}, 315, 0, 0},
206 {{-1.008000, 0.272000, 0}, 90, 180, 0},
207 {{0.800000, 1.488000, 0}, 135, 0, 0},
208 {{0.832000, 1.440000, 0}, 45, 180, 0},
209 {{-1.744000, -1.872000, 0}, 135, 0, 0},
210 {{-1.008000, 0.320000, 0}, 45, 180, 0},
213 {{-0.720000, 3.440000, 0}, 180, 180, 0},
214 {{0.912000, -1.072000, 0}, 225, 0, 0},
215 {{0.736000, 3.440000, 0}, 180, 180, 0},
216 {{0.720000, 1.984000, 0}, 225, 0, 0},
217 {{-0.672000, 0.544000, 0}, 45, 180, 0},
218 {{-0.192000, -3.840000, 0}, 135, 0, 0},
219 {{-0.528000, -2.480000, 0}, 135, 0, 0},
222 {{1.184000, 1.904000, 0}, 90, 180, 0},
223 {{-2.256000, 0.960000, 0}, 90, 0, 0},
224 {{-0.208000, -0.528000, 0}, 45, 180, 0},
225 {{-0.256000, -0.512000, 0}, 135, 0, 0},
226 {{0.144000, -0.944000, 0}, 135, 180, 0},
227 {{-0.608000, -3.648000, 0}, 105, 0, 0},
228 {{0.832000, -0.912000, 0}, 135, 0, 0},
231 {{-1.056000, -2.272000, 0}, 90, 0, 0},
232 {{0.960000, -1.264000, 0}, 180, 0, 0},
233 {{-0.000000, -2.288000, 0}, 135, 0, 0},
234 {{-1.088000, -2.256000, 0}, 180, 0, 0},
235 {{0.992000, 0.736000, 0}, 0, 0, 0},
236 {{0.960000, -0.256000, 0}, 180, 0, 0},
237 {{-0.064000, 0.752000, 0}, 180, 180, 0},
240 {{-1.360000, -0.224000, 0}, 0, 0, 0},
241 {{-0.336000, -0.176000, 0}, 90, 0, 0},
242 {{0.688000, -0.192000, 0}, 45, 0, 0},
243 {{-1.424000, -1.168000, 0}, 180, 0, 0},
244 {{1.744000, 0.816000, 0}, 0, 0, 0},
245 {{-0.384000, -0.176000, 0}, 180, 0, 0},
246 {{1.648000, -1.216000, 0}, 270, 180, 0},
249 {{2.112000, 1.504000, 0}, 0, 0, 0},
250 {{-1.040000, 1.472000, 0}, 180, 180, 0},
251 {{0.032000, -1.600000, 0}, 135, 0, 0},
252 {{1.056000, 1.504000, 0}, 270, 0, 0},
253 {{-0.992000, -0.528000, 0}, 0, 180, 0},
254 {{2.080000, 0.512000, 0}, 180, 0, 0},
255 {{-1.104000, 0.480000, 0}, 270, 180, 0},
258 {{0.608000, 1.184000, 0}, 135, 0, 0},
259 {{-2.928000, -1.584000, 0}, 135, 0, 0},
260 {{0.688000, 0.560000, 0}, 90, 180, 0},
261 {{0.640000, -0.832000, 0}, 180, 0, 0},
262 {{-0.752000, -2.304000, 0}, 315, 180, 0},
263 {{-2.192000, -0.912000, 0}, 315, 0, 0},
264 {{2.704000, 1.616000, 0}, 270, 0, 0},
267 {{0.880000, 0.960000, 0}, 45, 0, 0},
268 {{0.832000, -0.960000, 0}, 0, 0, 0},
269 {{1.536000, 1.712000, 0}, 225, 180, 0},
270 {{-0.992000, 2.096000, 0}, 315, 0, 0},
271 {{0.480000, 2.704000, 0}, 180, 180, 0},
272 {{0.816000, 0.912000, 0}, 315, 0, 0},
273 {{0.784000, -1.952000, 0}, 315, 180, 0},
276 {{0.176000, 3.584000, 0}, 270, 0, 0},
277 {{2.016000, -1.424000, 0}, 90, 0, 0},
278 {{2.496000, 0.608000, 0}, 180, 180, 0},
279 {{-0.304000, 0.496000, 0}, 270, 0, 0},
280 {{-0.256000, -0.144000, 0}, 0, 180, 0},
281 {{-1.600000, -0.368000, 0}, 303, 0, 0},
282 {{0.768000, 0.912000, 0}, 180, 0, 0},
285 {{-2.096000, 1.696000, 0}, 315, 0, 0},
286 {{-1.632000, -1.440000, 0}, 45, 0, 0},
287 {{-1.232000, -0.064000, 0}, 315, 180, 0},
288 {{0.304000, 2.416000, 0}, 315, 0, 0},
289 {{1.776000, -0.496000, 0}, 315, 180, 0},
290 {{1.168000, -0.240000, 0}, 332, 0, 0},
291 {{-0.880000, -1.216000, 0}, 135, 0, 0},
294 {{-0.432000, -0.496000, 0}, 259, 0, 0},
295 {{0.176000, -1.488000, 0}, 105, 0, 0},
296 {{1.184000, -1.168000, 0}, 300, 180, 0},
297 {{1.824000, 0.096000, 0}, 195, 0, 0},
298 {{-2.400000, -0.048000, 0}, 11, 180, 0},
299 {{-0.240000, -1.200000, 0}, 315, 0, 0},
300 {{-0.688000, -1.488000, 0}, 281, 180, 0},
303 {{0.096000, 2.000000, 0}, 315, 0, 0},
304 {{0.432000, 0.160000, 0}, 360, 0, 0},
305 {{0.208000, -1.504000, 0}, 220, 180, 0},
306 {{-1.104000, -0.336000, 0}, 50, 0, 0},
307 {{-1.136000, -0.288000, 0}, 310, 180, 0},
308 {{0.416000, 1.232000, 0}, 360, 0, 0},
309 {{0.048000, 2.016000, 0}, 225, 180, 0},
312 {{-2.128000, 2.112000, 0}, 45, 0, 0},
313 {{0.128000, 1.856000, 0}, 360, 0, 0},
314 {{2.128000, -0.720000, 0}, 180, 180, 0},
315 {{-1.376000, 2.816000, 0}, 360, 0, 0},
316 {{-1.360000, 0.768000, 0}, 45, 180, 0},
317 {{0.128000, 0.336000, 0}, 360, 0, 0},
318 {{0.432000, -2.944000, 0}, 149, 0, 0},
321 {{1.952000, -0.800000, 0}, 225, 0, 0},
322 {{2.064000, -0.816000, 0}, 45, 0, 0},
323 {{0.928000, 0.688000, 0}, 225, 0, 0},
324 {{-1.568000, 3.152000, 0}, 0, 0, 0},
325 {{-1.520000, 1.104000, 0}, 45, 0, 0},
326 {{2.720000, -0.064000, 0}, 225, 0, 0},
327 {{1.968000, 0.672000, 0}, 270, 0, 0},
330 {{2.480000, -0.912000, 0}, 225, 0, 0},
331 {{2.592000, -0.928000, 0}, 45, 0, 0},
332 {{0.352000, 1.280000, 0}, 315, 0, 0},
333 {{-0.688000, 0.336000, 0}, 135, 0, 0},
334 {{1.808000, -0.112000, 0}, 135, 0, 0},
335 {{3.248000, -0.176000, 0}, 225, 0, 0},
336 {{-1.472000, 1.024000, 0}, 225, 0, 0},
339 {{-0.400000, -1.232000, 0}, 270, 0, 0},
340 {{0.400000, -0.640000, 0}, 270, 0, 0},
341 {{1.904000, -3.232000, 0}, 180, 0, 0},
342 {{1.872000, -1.776000, 0}, 225, 0, 0},
343 {{1.552000, 0.656000, 0}, 270, 0, 0},
344 {{1.056000, 1.760000, 0}, 270, 0, 0},
345 {{-0.320000, -1.024000, 0}, 135, 180, 0},
348 {{0.896000, -0.480000, 0}, 0, 0, 0},
349 {{0.128000, -0.720000, 0}, 45, 0, 0},
350 {{0.960000, -1.728000, 0}, 270, 0, 0},
351 {{-1.040000, -1.648000, 0}, 90, 0, 0},
352 {{-0.848000, 2.304000, 0}, 0, 0, 0},
353 {{-0.096000, 0.944000, 0}, 315, 0, 0},
354 {{-1.568000, -1.728000, 0}, 90, 180, 0},
357 {{0.416000, 3.648000, 0}, 270, 0, 0},
358 {{-0.000000, -1.072000, 0}, 331, 0, 0},
359 {{1.360000, 0.528000, 0}, 180, 0, 0},
360 {{0.880000, 0.464000, 0}, 270, 0, 0},
361 {{0.576000, -3.184000, 0}, 151, 0, 0},
362 {{0.864000, 2.576000, 0}, 270, 0, 0},
363 {{-1.120000, 0.528000, 0}, 90, 0, 0},
366 {{-1.056000, -3.456000, 0}, 90, 0, 0},
367 {{0.736000, 2.000000, 0}, 135, 0, 0},
368 {{-1.488000, 1.760000, 0}, 45, 0, 0},
369 {{-0.432000, 0.016000, 0}, 0, 180, 0},
370 {{-0.432000, -0.064000, 0}, 0, 0, 0},
371 {{0.560000, -2.576000, 0}, 225, 0, 0},
372 {{0.032000, 2.656000, 0}, 0, 0, 0},
375 {{-2.800000, -2.304000, 0}, 101, 0, 0},
376 {{1.888000, 2.032000, 0}, 135, 180, 0},
377 {{-1.856000, 2.016000, 0}, 315, 0, 0},
378 {{0.352000, -0.144000, 0}, 315, 180, 0},
379 {{-2.848000, 0.976000, 0}, 0, 0, 0},
380 {{-1.424000, -1.104000, 0}, 236, 0, 0},
381 {{-1.792000, 2.016000, 0}, 45, 0, 0},
384 {{0.864000, 0.880000, 0}, 180, 0, 0},
385 {{0.912000, -2.288000, 0}, 180, 180, 0},
386 {{-1.136000, -0.144000, 0}, 45, 0, 0},
387 {{-1.136000, -3.312000, 0}, 360, 180, 0},
388 {{-1.168000, 1.920000, 0}, 0, 0, 0},
389 {{-1.184000, -1.248000, 0}, 180, 0, 0},
390 {{-1.136000, -0.224000, 0}, 0, 0, 0},
393 {{0.592000, 0.704000, 0}, 90, 0, 0},
394 {{0.576000, -2.496000, 0}, 90, 180, 0},
395 {{2.624000, -1.440000, 0}, 225, 0, 0},
396 {{2.640000, -3.504000, 0}, 270, 180, 0},
397 {{2.656000, 1.712000, 0}, 270, 0, 0},
398 {{0.544000, 0.704000, 0}, 180, 0, 0},
399 {{1.648000, 0.640000, 0}, 0, 0, 0},
402 {{0.448000, -3.344000, 0}, 90, 0, 0},
403 {{-1.616000, 1.984000, 0}, 90, 180, 0},
404 {{-1.584000, 0.928000, 0}, 45, 0, 0},
405 {{-1.600000, -2.288000, 0}, 0, 180, 0},
406 {{1.536000, -1.328000, 0}, 270, 0, 0},
407 {{2.592000, -3.328000, 0}, 180, 0, 0},
408 {{-1.600000, 0.832000, 0}, 0, 0, 0},
411 {{0.608000, 0.880000, 0}, 180, 0, 0},
412 {{0.576000, -2.304000, 0}, 180, 180, 0},
413 {{-1.456000, -0.176000, 0}, 45, 0, 0},
414 {{-1.472000, -3.344000, 0}, 0, 180, 0},
415 {{-1.472000, 1.888000, 0}, 0, 0, 0},
416 {{0.640000, -1.168000, 0}, 180, 0, 0},
417 {{-1.456000, -0.256000, 0}, 0, 0, 0},
420 {{-0.208000, -0.352000, 0}, 225, 0, 0},
421 {{0.528000, 1.856000, 0}, 225, 180, 0},
422 {{-0.176000, -3.904000, 0}, 135, 0, 0},
423 {{-0.880000, 0.384000, 0}, 45, 180, 0},
424 {{-0.192000, -0.384000, 0}, 315, 0, 0},
425 {{0.304000, -2.864000, 0}, 180, 0, 0},
426 {{-0.224000, 2.528000, 0}, 315, 0, 0},
429 {{-0.032000, 0.704000, 0}, 315, 0, 0},
430 {{2.208000, -1.504000, 0}, 225, 180, 0},
431 {{-0.720000, -0.064000, 0}, 0, 0, 0},
432 {{-0.720000, -1.536000, 0}, 45, 180, 0},
433 {{-0.016000, 1.744000, 0}, 315, 180, 0},
434 {{0.464000, 0.736000, 0}, 180, 0, 0},
435 {{1.456000, -0.816000, 0}, 315, 0, 0},
438 {{-0.944000, 1.040000, 0}, 360, 0, 0},
439 {{1.120000, 0.000000, 0}, 180, 180, 0},
440 {{0.080000, -0.048000, 0}, 315, 0, 0},
441 {{0.080000, -1.104000, 0}, 135, 180, 0},
442 {{0.080000, 1.120000, 0}, 315, 180, 0},
443 {{1.120000, 0.048000, 0}, 180, 0, 0},
444 {{0.064000, 0.992000, 0}, 180, 180, 0},
447 {{-0.688000, 0.784000, 0}, 135, 0, 0},
448 {{0.800000, 0.784000, 0}, 135, 0, 0},
449 {{0.512000, -2.512000, 0}, 315, 0, 0},
450 {{1.488000, 0.000000, 0}, 225, 0, 0},
451 {{-1.392000, 0.000000, 0}, 45, 0, 0},
452 {{0.496000, -2.432000, 0}, 180, 0, 0},
453 {{0.480000, -2.496000, 0}, 270, 0, 0},
456 {{-0.992000, -2.160000, 0}, 90, 0, 0},
457 {{-1.040000, -1.152000, 0}, 270, 0, 0},
458 {{0.064000, -2.144000, 0}, 135, 0, 0},
459 {{0.080000, -1.088000, 0}, 90, 0, 0},
460 {{0.032000, -1.072000, 0}, 180, 0, 0},
461 {{0.544000, -3.216000, 0}, 180, 0, 0},
462 {{2.160000, -1.136000, 0}, 270, 0, 0},
465 {{-2.896000, -0.128000, 0}, 45, 0, 0},
466 {{-0.800000, 0.992000, 0}, 135, 0, 0},
467 {{-1.152000, -0.416000, 0}, 225, 0, 0},
468 {{-0.016000, 0.656000, 0}, 315, 0, 0},
469 {{1.456000, -0.736000, 0}, 135, 0, 0},
470 {{2.864000, 0.736000, 0}, 180, 0, 0},
471 {{-0.048000, 1.664000, 0}, 180, 180, 0},
474 {{2.960000, -1.376000, 0}, 270, 0, 0},
475 {{1.952000, -1.312000, 0}, 90, 0, 0},
476 {{-0.096000, 0.720000, 0}, 315, 0, 0},
477 {{-2.112000, -0.320000, 0}, 90, 180, 0},
478 {{1.904000, -0.320000, 0}, 180, 180, 0},
479 {{-0.096000, -1.776000, 0}, 135, 0, 0},
480 {{-3.168000, -2.304000, 0}, 360, 180, 0},
483 {{-1.600000, -1.232000, 0}, 270, 0, 0},
484 {{-1.600000, -0.128000, 0}, 180, 0, 0},
485 {{2.272000, -0.128000, 0}, 225, 0, 0},
486 {{-0.160000, -3.648000, 0}, 315, 180, 0},
487 {{-0.176000, 2.336000, 0}, 135, 180, 0},
488 {{-2.608000, -1.184000, 0}, 90, 0, 0},
489 {{1.280000, -2.208000, 0}, 360, 180, 0}
754 static tangram_shape tsm1 = { {-0.144, -0.72, 0}, 225, false, 0 };
755 static tangram_shape tsm2 = { {0.608, 0.032, 0}, 135, false, 0 };
756 static tangram_shape tm = { {-1.584, 0.72, 0}, 0, false, 0 };
757 static tangram_shape tlg1 = { {-0.112, -0.72, 0}, 315, false, 0 };
758 static tangram_shape tlg2 = { {-0.096, -0.704, 0}, 45, false, 0 };
759 static tangram_shape sq = { {0.592, 0.016, 0}, 225, false, 0 };
760 static tangram_shape rh = { {-0.88, -0.032, 0}, 315, false, 0 };
763 #define DEF_VIEWING_TIME "5"
764 static GLuint viewing_time = 0;
766 static XrmOptionDescRec opts[] = {
767 {"-viewing_time", ".viewing_time", XrmoptionSepArg, 0}
770 static argtype vars[] = {
771 {&viewing_time, "viewing_time", "Viewing Time", DEF_VIEWING_TIME, t_Int}
774 ModeSpecOpt sws_opts = { countof(opts), opts, countof(vars), vars, NULL };
777 static int csi = -1; /* Current Shape index */
779 static void get_solved_puzzle(tangram_shape * tsm1, tangram_shape * tsm2,
780 tangram_shape * tm, tangram_shape * tlg1,
781 tangram_shape * tlg2, tangram_shape * sq,
784 int sz = sizeof(solved) / sizeof(solved[0]);
794 *tsm1 = solved[r][small_triangle1];
798 *tsm2 = solved[r][small_triangle2];
802 *tm = solved[r][medium_triangle];
806 *tlg1 = solved[r][large_triangle1];
810 *tlg2 = solved[r][large_triangle2];
814 *sq = solved[r][square];
818 *rh = solved[r][rhomboid];
823 static bool colors_match(color c1, color c2)
826 if (c1.r == c2.r && c1.g == c2.g && c1.b == c2.b)
831 static color rand_palette(void)
833 int l = sizeof(palette) / sizeof(color);
834 int r = random() % l;
838 static int approach_number(int goal, int current, int step)
843 if (goal > current) {
850 } else if (goal < current) {
862 /* gt - floating point greater than comparison */
863 static bool gt(GLfloat x1, GLfloat x2, GLfloat per)
865 if ((x1 > x2) && (fabs(x1 - x2) > per))
871 /* lt - floating point less than comparison */
872 static bool lt(GLfloat x1, GLfloat x2, GLfloat per)
874 if ((x1 < x2) && (fabs(x1 - x2) > per))
880 /* eq - Check the equality of a pair of floating point numbers to a certain perscision */
881 static bool eq(GLfloat x1, GLfloat x2, GLfloat per)
883 if (fabs(x1 - x2) < per)
890 static GLfloat approach_float(GLfloat goal, GLfloat current,
891 bool * changed, GLfloat per)
894 if (gt(goal, current, per)) {
897 } else if (lt(goal, current, per)) {
904 static bool coords_match(coord c1, coord c2, GLfloat per)
906 if (eq(c1.x, c2.x, per) && eq(c1.y, c2.y, per) && eq(c1.z, c2.z, per))
912 static bool xy_coords_match(coord c1, coord c2, GLfloat per)
914 if (eq(c1.x, c2.x, per) && eq(c1.y, c2.y, per))
922 static void print_shape(char *s, tangram_shape sh)
924 fprintf(stderr, "%s\n", s);
925 fprintf(stderr, "(%f, %f, %f)\n", sh.crd.x, sh.crd.y, sh.crd.z);
926 fprintf(stderr, "%d\n", sh.r);
927 fprintf(stderr, "%d\n", sh.fr);
928 fprintf(stderr, "\n");
932 /* approach_shape - bring use on step closer to the new shape */
933 static tangram_shape approach_shape(tangram_shape old, tangram_shape new,
934 bool * b, char *name)
941 old.fr = approach_number(new.fr, old.fr, 2);
942 if (old.fr != new.fr) {
946 old.r = approach_number(new.r, old.r, 2);
947 if (old.r != new.r) {
951 old.crd.x = approach_float(new.crd.x, old.crd.x, &changed, 0.1);
953 old.crd.x = approach_float(new.crd.x, old.crd.x, &changed, 0.01);
955 old.crd.x = approach_float(new.crd.x, old.crd.x, &changed, 0.001);
957 old.crd.x = approach_float(new.crd.x, old.crd.x, &changed, 0.0001);
959 old.crd.y = approach_float(new.crd.y, old.crd.y, &changed, 0.1);
961 old.crd.y = approach_float(new.crd.y, old.crd.y, &changed, 0.01);
963 old.crd.y = approach_float(new.crd.y, old.crd.y, &changed, 0.001);
965 old.crd.y = approach_float(new.crd.y, old.crd.y, &changed, 0.0001);
967 if (xy_coords_match(new.crd, old.crd, 0.0001)) {
968 old.crd.z = approach_float(new.crd.z, old.crd.z, &changed, 0.1);
971 approach_float(new.crd.z, old.crd.z, &changed, 0.01);
974 approach_float(new.crd.z, old.crd.z, &changed, 0.001);
977 approach_float(new.crd.z, old.crd.z, &changed, 0.0001);
981 if (coords_match(new.crd, old.crd, 0.0001)) {
984 fprintf(stderr, "%s\n", name);
985 print_shape("old", old);
986 print_shape("new", new);
988 old = new; /* pick up the rest of the settings; */
996 static color get_color(void)
998 static color new_color = { 100, 100, 100 };
999 static color old_color = { 100, 100, 100 };
1001 if (colors_match(old_color, new_color)) {
1002 old_color = new_color;
1003 new_color = rand_palette();
1006 if ((random() % 10) == 0) { /* slow down the cycle */
1007 old_color.r = approach_number(new_color.r, old_color.r, 1);
1008 old_color.g = approach_number(new_color.g, old_color.g, 1);
1009 old_color.b = approach_number(new_color.b, old_color.b, 1);
1015 static void explode(tangram_shape * tsm1, tangram_shape * tsm2,
1016 tangram_shape * tm, tangram_shape * tlg1,
1017 tangram_shape * tlg2, tangram_shape * sq,
1037 static void draw_tangram_shape(tangram_shape ts)
1041 glTranslatef(ts.crd.x, ts.crd.y, ts.crd.z);
1042 glRotated(90, 1, 0, 0);
1043 glRotated(ts.fr, 1, 0, 0);
1044 glRotated(ts.r, 0, 1, 0);
1049 static void draw_shapes(void)
1053 color c = get_color();
1054 glColor3ub(c.r, c.g, c.b);
1057 draw_tangram_shape(tsm1);
1059 draw_tangram_shape(tsm2);
1060 draw_tangram_shape(tm);
1061 draw_tangram_shape(tlg1);
1062 draw_tangram_shape(tlg2);
1063 draw_tangram_shape(sq);
1064 draw_tangram_shape(rh);
1068 static void set_perspective(void)
1071 glMatrixMode(GL_PROJECTION);
1073 gluPerspective(60, -1, 0.1, 50);
1074 gluLookAt(0, 5, -5, 0, 0, 0, 0, -1, 0);
1075 glMatrixMode(GL_MODELVIEW);
1080 void reshape_tangram(ModeInfo * mi, int w, int h)
1082 glViewport(0, 0, w, h);
1087 static void rotate_camera(void)
1089 static GLfloat theta[3] = { 1, 1, 1 };
1090 static bool going_down[3] = { false, false, false };
1094 glMatrixMode(GL_PROJECTION);
1096 gluPerspective(60, -1, 0.1, 50);
1099 gluLookAt(0, 5, -5, 0, 0, 0, 0, -1, 0);
1101 glRotatef(theta[0], 1, 0, 0);
1102 glRotatef(theta[1], 0, 1, 0);
1103 glRotatef(theta[2], 0, 0, 1);
1105 glMatrixMode(GL_MODELVIEW);
1109 if (going_down[0] && theta[0] < 0) {
1111 going_down[0] = false;
1112 } else if ((!going_down[0]) && theta[0] > 90) {
1114 going_down[0] = true;
1117 if (theta[1] > 360.0)
1127 static void init_shapes(void)
1129 get_solved_puzzle(&tsm1, &tsm2, &tm, &tlg1, &tlg2, &sq, &rh);
1130 tsm1.dl = get_sm_tri_dl(wire);
1131 tsm2.dl = get_sm_tri_dl(wire);
1132 tm.dl = get_md_tri_dl(wire);
1133 tlg1.dl = get_lg_tri_dl(wire);
1134 tlg2.dl = get_lg_tri_dl(wire);
1135 sq.dl = get_square_dl(wire);
1136 rh.dl = get_rhomboid_dl(wire);
1139 void init_tangram(ModeInfo * mi)
1141 GLfloat pos[4] = { 1, 1, -5, 1.00 };
1142 GLfloat pos2[4] = { 1, 1, 5, 1.00 };
1143 GLfloat lKa[4] = { 0, 0, 0, 1 };
1144 GLfloat lKd[4] = { 1, 1, 1, 1 };
1145 GLfloat lKs[4] = { 1, 1, 1, 1 };
1147 wire = MI_IS_WIREFRAME(mi);
1151 glLightfv(GL_LIGHT0, GL_POSITION, pos);
1152 glLightfv(GL_LIGHT0, GL_AMBIENT, lKa);
1153 glLightfv(GL_LIGHT0, GL_DIFFUSE, lKd);
1154 glLightfv(GL_LIGHT0, GL_SPECULAR, lKs);
1156 glLightfv(GL_LIGHT1, GL_POSITION, pos2);
1157 glLightfv(GL_LIGHT1, GL_AMBIENT, lKa);
1158 glLightfv(GL_LIGHT1, GL_DIFFUSE, lKd);
1159 glLightfv(GL_LIGHT1, GL_SPECULAR, lKs);
1161 glEnable(GL_DEPTH_TEST);
1163 glEnable(GL_LIGHTING);
1164 glEnable(GL_LIGHT0);
1165 glEnable(GL_LIGHT1);
1167 glEnable(GL_COLOR_MATERIAL);
1173 static tangram_shape explode_step(tangram_shape old, tangram_shape new,
1174 bool * b, GLfloat per)
1176 old.crd.z = approach_float(new.crd.z, old.crd.z, b, per);
1177 if (eq(new.crd.z, old.crd.z, per))
1185 void draw_tangram(ModeInfo * mi)
1187 Display *dpy = MI_DISPLAY(mi);
1188 Window window = MI_WINDOW(mi);
1189 static tangram_state state = state_solved;
1190 static tangram_shape n_tsm1, n_tsm2, n_tm, n_tlg1, n_tlg2, n_sq, n_rh;
1191 static bool b_tsm1, b_tsm2, b_tm, b_tlg1, b_tlg2, b_sq, b_rh;
1192 static time_t s_tm = 0;
1197 case state_exploding:
1198 tsm1 = explode_step(tsm1, n_tsm1, &b_tsm1, 0.1);
1199 tsm2 = explode_step(tsm2, n_tsm2, &b_tsm2, 0.1);
1200 tm = explode_step(tm, n_tm, &b_tm, 0.1);
1201 tlg1 = explode_step(tlg1, n_tlg1, &b_tlg1, 0.1);
1202 tlg2 = explode_step(tlg2, n_tlg2, &b_tlg2, 0.1);
1203 sq = explode_step(sq, n_sq, &b_sq, 0.1);
1204 rh = explode_step(rh, n_rh, &b_rh, 0.1);
1205 if (b_tsm1 && b_tsm2 && b_tm && b_tlg1 && b_tlg2 && b_sq && b_rh) {
1206 get_solved_puzzle(&n_tsm1, &n_tsm2, &n_tm, &n_tlg1, &n_tlg2,
1208 state = state_solving;
1214 tsm1 = approach_shape(tsm1, n_tsm1, &b_tsm1, "small 1");
1215 tsm2 = approach_shape(tsm2, n_tsm2, &b_tsm2, "small 2");
1216 tm = approach_shape(tm, n_tm, &b_tm, "medium");
1217 tlg1 = approach_shape(tlg1, n_tlg1, &b_tlg1, "large 1");
1218 tlg2 = approach_shape(tlg2, n_tlg2, &b_tlg2, "large 2");
1219 sq = approach_shape(sq, n_sq, &b_sq, "square");
1220 rh = approach_shape(rh, n_rh, &b_rh, "rhomboid");
1221 if (b_tsm1 && b_tsm2 && b_tm && b_tlg1 && b_tlg2 && b_sq && b_rh) {
1222 state = state_solved;
1228 if (floor(difftime(c_tm, s_tm)) >= viewing_time) {
1229 /*if ((random() % 100) == 0) { */
1230 explode(&n_tsm1, &n_tsm2, &n_tm, &n_tlg1, &n_tlg2, &n_sq,
1233 state = state_exploding;
1239 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1245 glXSwapBuffers(dpy, window);