1 /*
2 * the Rubik's cube.
3 *
4 * Sed - april 1999 / december 2003.
5 *
6 * This program is in the public domain.
7 *--------------------
8 * The cube related stuff (init, project, rotate, so on)
9 */
10
11 #include "cube.h"
12
13 #include <ctype.h>
14 #include <string.h>
15 #include <math.h>
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <fcntl.h>
21 #include <unistd.h>
22
23 #include "screen.h"
24 #include "fillpoly.h"
25 #include "line.h"
26 #include "device.h"
27
28 /* when you see those globals, you are very allowed to think i began to have hard work
29 * with all those angles, rotations, faces and so on. I am definitly not a good graphical
30 * coder. Am i a good coder in something anyway ?
31 */
32
33 int nb_facettes;
34 int cur_facette;
35
36 typedef struct {
37 double z;
38 double x0, y0, x1, y1, x2, y2, x3, y3;
39 int col, cross;
40 } facette;
41
42 facette f[6*26];
43 int order[6*26];
44 int order1[6*26];
45 double e[8][3]; /* small cube edges */
46
47 static void cube_do_rotate(CUBE *);
48
save_cube(CUBE * c)49 void save_cube(CUBE *c)
50 {
51 static char letter[12] = "XABCDEFI012";
52 static short order[12] = { 0, 1, 2, 3, 4, 5, 6, 7, 10, 9, 8};
53 char name[30];
54 char buffer[80];
55 int i, j, l;
56 int fd;
57
58 sprintf(name, "rubix.%s", formats[FORMAT]);
59 name[9] = '\0';
60 fd = open(name, O_WRONLY|O_CREAT|O_TRUNC, 0644);
61
62 if (fd==-1) {
63 perror("cube.save_cube.open");
64 return;
65 }
66
67 if (write(fd, "%rubix\n\n", 8)!= 8) {
68 write_error:
69 perror("cube.save_cube.write");
70 close(fd);
71 unlink(name);
72 return;
73 }
74
75 if (write(fd, "%colors\n", 8)!= 8) goto write_error;
76 for (i=0; i<11; i++) {
77 sprintf(buffer, "%c = %s\n", letter[i], palette[order[i]]);
78 l = strlen(buffer);
79 if (write(fd, buffer, l)!= l) goto write_error;
80 }
81
82 if (write(fd, "\n%matrix\n\n", 9)!= 9) goto write_error;
83 for (i=0; i<3; i++) {
84 sprintf(buffer, "%14.10f %14.10f %14.10f\n",
85 c->matrix[i][0], c->matrix[i][1], c->matrix[i][2]);
86 l = strlen(buffer);
87 if (write(fd, buffer, l)!= l) goto write_error;
88 }
89
90 if (FORMAT == 0) {
91 if (write(fd, "\n%position\n", 11)!= 11) goto write_error;
92 buffer[0] = buffer[1] = buffer[2] = buffer[3] = buffer[11] = ' ';
93 buffer[7] = '\n'; buffer[8] = buffer[9] = '\0';
94 buffer[4] = '@' + c->cubes[25].colors[1];
95 buffer[5] = '@' + c->cubes[22].colors[1];
96 buffer[6] = '@' + c->cubes[20].colors[1];
97 if (write(fd, buffer, 8)!= 8) goto write_error;
98 buffer[4] = '@' + c->cubes[24].colors[1];
99 buffer[5] = '@' + c->cubes[1].colors[1];
100 buffer[6] = '@' + c->cubes[19].colors[1];
101 if (write(fd, buffer, 8)!= 8) goto write_error;
102 buffer[4] = '@' + c->cubes[23].colors[1];
103 buffer[5] = '@' + c->cubes[21].colors[1];
104 buffer[6] = '@' + c->cubes[18].colors[1];
105 buffer[8] = '\n';
106 if (write(fd, buffer, 9)!= 9) goto write_error;
107 buffer[7] = ' '; buffer[15] = '\n' ; buffer[16] = buffer[17] = '\0';
108 buffer[0] = '@' + c->cubes[25].colors[2];
109 buffer[1] = '@' + c->cubes[24].colors[2];
110 buffer[2] = '@' + c->cubes[23].colors[2];
111 buffer[4] = '@' + c->cubes[23].colors[4];
112 buffer[5] = '@' + c->cubes[21].colors[4];
113 buffer[6] = '@' + c->cubes[18].colors[4];
114 buffer[8] = '@' + c->cubes[18].colors[3];
115 buffer[9] = '@' + c->cubes[19].colors[3];
116 buffer[10]= '@' + c->cubes[20].colors[3];
117 buffer[12]= '@' + c->cubes[20].colors[5];
118 buffer[13]= '@' + c->cubes[22].colors[5];
119 buffer[14]= '@' + c->cubes[25].colors[5];
120 if (write(fd, buffer, 16)!= 16) goto write_error;
121 buffer[0] = '@' + c->cubes[17].colors[2];
122 buffer[1] = '@' + c->cubes[2].colors[2];
123 buffer[2] = '@' + c->cubes[16].colors[2];
124 buffer[4] = '@' + c->cubes[16].colors[4];
125 buffer[5] = '@' + c->cubes[4].colors[4];
126 buffer[6] = '@' + c->cubes[14].colors[4];
127 buffer[8] = '@' + c->cubes[14].colors[3];
128 buffer[9] = '@' + c->cubes[3].colors[3];
129 buffer[10]= '@' + c->cubes[15].colors[3];
130 buffer[12]= '@' + c->cubes[15].colors[5];
131 buffer[13]= '@' + c->cubes[5].colors[5];
132 buffer[14]= '@' + c->cubes[17].colors[5];
133 if (write(fd, buffer, 16)!= 16) goto write_error;
134 buffer[0] = '@' + c->cubes[13].colors[2];
135 buffer[1] = '@' + c->cubes[12].colors[2];
136 buffer[2] = '@' + c->cubes[11].colors[2];
137 buffer[4] = '@' + c->cubes[11].colors[4];
138 buffer[5] = '@' + c->cubes[9].colors[4];
139 buffer[6] = '@' + c->cubes[6].colors[4];
140 buffer[8] = '@' + c->cubes[6].colors[3];
141 buffer[9] = '@' + c->cubes[7].colors[3];
142 buffer[10]= '@' + c->cubes[8].colors[3];
143 buffer[12]= '@' + c->cubes[8].colors[5];
144 buffer[13]= '@' + c->cubes[10].colors[5];
145 buffer[14]= '@' + c->cubes[13].colors[5];
146 buffer[16] = '\n';
147 if (write(fd, buffer, 17)!= 17) goto write_error;
148 buffer[0] = buffer[1] = buffer[2] = ' ';
149 buffer[7] = '\n'; buffer[8] = buffer[9] = '\0';
150 buffer[4] = '@' + c->cubes[11].colors[0];
151 buffer[5] = '@' + c->cubes[9].colors[0];
152 buffer[6] = '@' + c->cubes[6].colors[0];
153 if (write(fd, buffer, 8)!= 8) goto write_error;
154 buffer[4] = '@' + c->cubes[12].colors[0];
155 buffer[5] = '@' + c->cubes[0].colors[0];
156 buffer[6] = '@' + c->cubes[7].colors[0];
157 if (write(fd, buffer, 8)!= 8) goto write_error;
158 buffer[4] = '@' + c->cubes[13].colors[0];
159 buffer[5] = '@' + c->cubes[10].colors[0];
160 buffer[6] = '@' + c->cubes[8].colors[0];
161 if (write(fd, buffer, 8)!= 8) goto write_error;
162 }
163
164 if (FORMAT == 1) {
165 if (write(fd, "\n%numeric\n", 10)!= 10) goto write_error;
166 buffer[6] ='\n';
167 buffer[7] = 0;
168 for (i=0; i<26; i++) {
169 for (j=0; j<6; j++)
170 buffer[j] = '0'+c->cubes[i].colors[j];
171 if (write(fd, buffer, 7)!= 7) goto write_error;
172 }
173 }
174
175 if (FORMAT == 2) {
176 if (write(fd, "\n%generators\n", 13)!= 13) goto write_error;
177 if (write(fd, ".\n", 2)!= 2) goto write_error;
178 }
179
180 if (close(fd)==-1) {
181 perror("cube.save_cube.close");
182 unlink(name);
183 return;
184 }
185 }
186
reset_cube(CUBE * c)187 void reset_cube(CUBE *c)
188 {
189 static double initmatrix[3][3]={
190 {1.0, 0.0, 0.0},
191 {0.0, 1.0, 0.0},
192 {0.0, 0.0, 1.0}};
193 memcpy(c->matrix, initmatrix, 9*sizeof(double));
194 c->center = 4;
195 }
196
get_string(int fd,char * buffer,int max)197 int get_string(int fd, char *buffer, int max)
198 {
199 int i;
200 i = 0;
201 while (i<max) {
202 if (read(fd, buffer+i, 1)!=1) return (i==0)?-1:i;
203 if (buffer[i]==0) break;
204 if (buffer[i]=='\n') break;
205 ++i;
206 }
207 buffer[i] = '\0';
208 return i;
209 }
210
load_cube(CUBE * c,char * name)211 void load_cube(CUBE *c, char *name)
212 {
213 int fd;
214 char buffer[96];
215 char *ptr;
216 char ch;
217 int i, j, k;
218
219 fprintf(stderr, "Trying to load \"%s\"\n", name);
220
221 FORMAT = 0;
222 reset_cube(c);
223 init_cube(c, NULL, 0);
224
225 fd=open(name, O_RDONLY);
226 if (fd==-1) {
227 perror("cube.load_cube.open");
228 return;
229 }
230
231 i = get_string(fd, buffer, 80);
232 if (i==-1 || i>=80) {
233 read_error:
234 perror("cube.load_cube.read");
235 close(fd);
236 return;
237 }
238
239 if (strncmp(buffer, "%rubix", 6)) goto read_error;
240
241 FORMAT = -1;
242 iter:
243 i = 0;
244 buffer[0] = ' ';
245 while (i>=0 && buffer[0]!='%') i = get_string(fd, buffer, 80);
246 finish:
247 if (i==-1) {
248 if (FORMAT==-1) goto read_error;
249 goto end_parsing;
250 }
251 new_section:
252 if (!strncmp(buffer, "%colors", 7)) {
253 iter_colors:
254 i = 0;
255 buffer[0] = ' ';
256 while (i>=0 && isspace(buffer[0])) i = get_string(fd, buffer, 80);
257 if (i==-1) goto finish;
258 if (buffer[0]=='%') goto new_section;
259 buffer[0]=toupper(buffer[0]);
260 ptr = index(buffer, '=');
261 if (ptr) {
262 ++ptr;
263 while (isspace(*ptr)) ++ptr;
264 if (buffer[0]>='A' && buffer[0]<='F') {
265 i = buffer[0] - 'A' + 1;
266 palette[i] = strdup(ptr);
267 }
268 if (buffer[0]=='X')
269 palette[0] = strdup(ptr);
270 if (buffer[0]=='I')
271 palette[7] = strdup(ptr);
272 if (buffer[0]>='0' && buffer[0]<='2') {
273 i = '9' - buffer[0] + 1;
274 palette[i] = strdup(ptr);
275 }
276 }
277 goto iter_colors;
278 } else
279 if (!strncmp(buffer, "%position", 9)) {
280 FORMAT = 0;
281 i = 0;
282 while (i>=0 && i<7) i = get_string(fd, buffer, 80);
283 if (i==-1) goto finish;
284 c->cubes[25].colors[1] = buffer[4] - '@';
285 c->cubes[22].colors[1] = buffer[5] - '@';
286 c->cubes[20].colors[1] = buffer[6] - '@';
287 i = 0;
288 while (i>=0 && i<7) i = get_string(fd, buffer, 80);
289 if (i==-1) goto finish;
290 c->cubes[24].colors[1] = buffer[4] - '@';
291 c->cubes[1].colors[1] = buffer[5] - '@';
292 c->cubes[19].colors[1] = buffer[6] - '@';
293 i = 0;
294 while (i>=0 && i<7) i = get_string(fd, buffer, 80);
295 if (i==-1) goto finish;
296 c->cubes[23].colors[1] = buffer[4] - '@';
297 c->cubes[21].colors[1] = buffer[5] - '@';
298 c->cubes[18].colors[1] = buffer[6] - '@';
299 i = 0;
300 while (i>=0 && i<15) i = get_string(fd, buffer, 80);
301 if (i==-1) goto finish;
302 c->cubes[25].colors[2] = buffer[0] - '@';
303 c->cubes[24].colors[2] = buffer[1] - '@';
304 c->cubes[23].colors[2] = buffer[2] - '@';
305 c->cubes[23].colors[4] = buffer[4] - '@';
306 c->cubes[21].colors[4] = buffer[5] - '@';
307 c->cubes[18].colors[4] = buffer[6] - '@';
308 c->cubes[18].colors[3] = buffer[8] - '@';
309 c->cubes[19].colors[3] = buffer[9] - '@';
310 c->cubes[20].colors[3] = buffer[10] - '@';
311 c->cubes[20].colors[5] = buffer[12] - '@';
312 c->cubes[22].colors[5] = buffer[13] - '@';
313 c->cubes[25].colors[5] = buffer[14] - '@';
314 i = 0;
315 while (i>=0 && i<15) i = get_string(fd, buffer, 80);
316 if (i==-1) goto finish;
317 c->cubes[17].colors[2] = buffer[0] - '@';
318 c->cubes[2].colors[2] = buffer[1] - '@';
319 c->cubes[16].colors[2] = buffer[2] - '@';
320 c->cubes[16].colors[4] = buffer[4] - '@';
321 c->cubes[4].colors[4] = buffer[5] - '@';
322 c->cubes[14].colors[4] = buffer[6] - '@';
323 c->cubes[14].colors[3] = buffer[8] - '@';
324 c->cubes[3].colors[3] = buffer[9] - '@';
325 c->cubes[15].colors[3] = buffer[10] - '@';
326 c->cubes[15].colors[5] = buffer[12] - '@';
327 c->cubes[5].colors[5] = buffer[13] - '@';
328 c->cubes[17].colors[5] = buffer[14] - '@';
329 i = 0;
330 while (i>=0 && i<15) i = get_string(fd, buffer, 80);
331 if (i==-1) goto finish;
332 c->cubes[13].colors[2] = buffer[0] - '@';
333 c->cubes[12].colors[2] = buffer[1] - '@';
334 c->cubes[11].colors[2] = buffer[2] - '@';
335 c->cubes[11].colors[4] = buffer[4] - '@';
336 c->cubes[9].colors[4] = buffer[5] - '@';
337 c->cubes[6].colors[4] = buffer[6] - '@';
338 c->cubes[6].colors[3] = buffer[8] - '@';
339 c->cubes[7].colors[3] = buffer[9] - '@';
340 c->cubes[8].colors[3] = buffer[10] - '@';
341 c->cubes[8].colors[5] = buffer[12] - '@';
342 c->cubes[10].colors[5] = buffer[13] - '@';
343 c->cubes[13].colors[5] = buffer[14] - '@';
344 i = 0;
345 while (i>=0 && i<7) i = get_string(fd, buffer, 80);
346 if (i==-1) goto finish;
347 c->cubes[11].colors[0] = buffer[4] - '@';
348 c->cubes[9].colors[0] = buffer[5] - '@';
349 c->cubes[6].colors[0] = buffer[6] - '@';
350 i = 0;
351 while (i>=0 && i<7) i = get_string(fd, buffer, 80);
352 if (i==-1) goto finish;
353 c->cubes[12].colors[0] = buffer[4] - '@';
354 c->cubes[0].colors[0] = buffer[5] - '@';
355 c->cubes[7].colors[0] = buffer[6] - '@';
356 i = 0;
357 while (i>=0 && i<7) i = get_string(fd, buffer, 80);
358 if (i==-1) goto finish;
359 c->cubes[13].colors[0] = buffer[4] - '@';
360 c->cubes[10].colors[0] = buffer[5] - '@';
361 c->cubes[8].colors[0] = buffer[6] - '@';
362 } else
363 if (!strncmp(buffer, "%numeric", 8)) {
364 FORMAT = 1;
365 k = 0;
366 while (k<26) {
367 i = 0;
368 while (i>=0 && i<6) i = get_string(fd, buffer, 80);
369 if (i>=6) {
370 for (j=0; j<6; j++)
371 c->cubes[k].colors[j] = buffer[j] - '0';
372 k++;
373 }
374 }
375 } else
376 if (!strncmp(buffer, "%generators", 11)) {
377 FORMAT = 2;
378 while (read(fd, &ch, 1)==1) {
379 c->orient = -1;
380 if (ch=='.') break;
381 if ((ch>='a') && (ch<='f')) {
382 c->center = ch-'a';
383 c->orient = 0;
384 } else
385 if ((ch>='A') && (ch<='F')) {
386 c->center = ch-'A';
387 c->orient = 0;
388 }
389 else if (!isspace(ch))
390 fprintf(stderr, "Invalid character : %c\n", ch);
391 if (c->orient>=0)
392 cube_do_rotate(c);
393 }
394 c->orient = 0;
395 } else
396 if (!strncmp(buffer, "%matrix", 7)) {
397 i = 0;
398 while (i>=0 && i<5) i = get_string(fd, buffer, 80);
399 if (i==-1) goto finish;
400 if (sscanf(buffer, "%lg %lg %lg",
401 &c->matrix[0][0],&c->matrix[0][1],&c->matrix[0][2])!=3)
402 goto read_error;
403 i = 0;
404 while (i>=0 && i<5) i = get_string(fd, buffer, 80);
405 if (i==-1) goto finish;
406 if (sscanf(buffer, "%lg %lg %lg",
407 &c->matrix[1][0],&c->matrix[1][1],&c->matrix[1][2])!=3)
408 goto read_error;
409 i = 0;
410 while (i>=0 && i<5) i = get_string(fd, buffer, 80);
411 if (i==-1) goto finish;
412 if (sscanf(buffer, "%lg %lg %lg",
413 &c->matrix[2][0],&c->matrix[2][1],&c->matrix[2][2])!=3)
414 goto read_error;
415 } else goto read_error;
416 goto iter;
417
418 end_parsing:
419 if (close(fd)==-1) {
420 perror("cube.load_cube.close");
421 return;
422 }
423 }
424
425
init_cube(CUBE * c,char * file,int random)426 void init_cube(CUBE *c, char *file, int random)
427 {
428 int i, j;
429 static short initedge[8][3] = {
430 {-1, -1, -1}, /* 0 */
431 {-1, -1, 1}, /* 1 */
432 {-1, 1, -1}, /* 2 */
433 {-1, 1, 1}, /* 3 */
434 { 1, -1, -1}, /* 4 */
435 { 1, -1, 1}, /* 5 */
436 { 1, 1, -1}, /* 6 */
437 { 1, 1, 1}};/* 7 */
438 #define X -1
439 static small_cube initsmallcube[26]=
440 {{x: 0, y: -1, z: 0, colors:{1,X,X,X,X,X}}, /* 0 */
441 {x: 0, y: 1, z: 0, colors:{X,2,X,X,X,X}}, /* 1 */
442 {x: -1, y: 0, z: 0, colors:{X,X,3,X,X,X}}, /* 2 */
443 {x: 1, y: 0, z: 0, colors:{X,X,X,4,X,X}}, /* 3 */
444 {x: 0, y: 0, z: 1, colors:{X,X,X,X,5,X}}, /* 4 */
445 {x: 0, y: 0, z: -1, colors:{X,X,X,X,X,6}}, /* 5 */
446 {x: 1, y: -1, z: 1, colors:{1,X,X,4,5,X}}, /* 6 */
447 {x: 1, y: -1, z: 0, colors:{1,X,X,4,X,X}}, /* 7 */
448 {x: 1, y: -1, z: -1, colors:{1,X,X,4,X,6}}, /* 8 */
449 {x: 0, y: -1, z: 1, colors:{1,X,X,X,5,X}}, /* 9 */
450 {x: 0, y: -1, z: -1, colors:{1,X,X,X,X,6}}, /* 10 */
451 {x: -1, y: -1, z: 1, colors:{1,X,3,X,5,X}}, /* 11 */
452 {x: -1, y: -1, z: 0, colors:{1,X,3,X,X,X}}, /* 12 */
453 {x: -1, y: -1, z: -1, colors:{1,X,3,X,X,6}}, /* 13 */
454 {x: 1, y: 0, z: 1, colors:{X,X,X,4,5,X}}, /* 14 */
455 {x: 1, y: 0, z: -1, colors:{X,X,X,4,X,6}}, /* 15 */
456 {x: -1, y: 0, z: 1, colors:{X,X,3,X,5,X}}, /* 16 */
457 {x: -1, y: 0, z: -1, colors:{X,X,3,X,X,6}}, /* 17 */
458 {x: 1, y: 1, z: 1, colors:{X,2,X,4,5,X}}, /* 18 */
459 {x: 1, y: 1, z: 0, colors:{X,2,X,4,X,X}}, /* 19 */
460 {x: 1, y: 1, z: -1, colors:{X,2,X,4,X,6}}, /* 20 */
461 {x: 0, y: 1, z: 1, colors:{X,2,X,X,5,X}}, /* 21 */
462 {x: 0, y: 1, z: -1, colors:{X,2,X,X,X,6}}, /* 22 */
463 {x: -1, y: 1, z: 1, colors:{X,2,3,X,5,X}}, /* 23 */
464 {x: -1, y: 1, z: 0, colors:{X,2,3,X,X,X}}, /* 24 */
465 {x: -1, y: 1, z: -1, colors:{X,2,3,X,X,6}}};/* 25 */
466 #undef X
467
468 memcpy(c->cubes, initsmallcube, 26*sizeof(small_cube));
469 c->anim = 0;
470 c->orient = 0;
471 c->letters = 0;
472 c->angle = 0;
473 memset(&c->time, 0, sizeof(struct timeval));
474
475 for (i=0; i<26*6; i++)
476 order1[i]=i;
477
478 /* set small cube sizes */
479 for (i=0; i<8; i++)
480 for (j=0; j<3; j++)
481 e[i][j] = EDGE * initedge[i][j];
482
483 /* let's randomize the cube */
484 if (random>0) {
485 struct timeval tt=get_time();
486 srand(tt.tv_sec-c->time.tv_sec+tt.tv_usec-c->time.tv_usec);
487 for (i=0; i<1000; i++) {
488 c->orient=2.0*rand()/(RAND_MAX+1.0);
489 c->rotated=6.0*rand()/(RAND_MAX+1.0);
490 cube_do_rotate(c);
491 }
492 } else if (random==0) {
493 if (file) {
494 load_cube(c, file);
495 return;
496 }
497 }
498 }
499
mulm(double a[3][3],double b[3][3])500 void mulm(double a[3][3], double b[3][3])
501 {
502 int i, j;
503 double r[3][3];
504
505 for (i=0; i<3; i++)
506 for (j=0; j<3; j++)
507 r[i][j]=(a[i][0]*b[0][j]+a[i][1]*b[1][j]+a[i][2]*b[2][j]);
508 memcpy(a, r, 9*sizeof(double));
509 }
510
xmat(double x,double m[3][3])511 void xmat(double x, double m[3][3])
512 {
513 double p[3][3]={{1.0, 0.0, 0.0},
514 {0.0, cos(x),sin(x)},
515 {0.0,-sin(x),cos(x)}};
516 mulm(m, p);
517 }
518
ymat(double y,double m[3][3])519 void ymat(double y, double m[3][3])
520 {
521 double p[3][3]={{cos(y),0.0,-sin(y)},
522 {0.0, 1.0, 0.0},
523 {sin(y),0.0, cos(y)}};
524 mulm(m, p);
525 }
526
zmat(double z,double m[3][3])527 void zmat(double z, double m[3][3])
528 {
529 double p[3][3]={{cos(z),sin(z),0},
530 {-sin(z),cos(z),0},
531 {0,0,1}};
532 mulm(m, p);
533 }
534
clear_facette(void)535 void clear_facette(void)
536 {
537 nb_facettes=0;
538 memcpy(order, order1, sizeof(order));
539 }
540
put_facette(double z,double x0,double y0,double x1,double y1,double x2,double y2,double x3,double y3,int color,int cross)541 void put_facette(double z, double x0, double y0, double x1, double y1,
542 double x2, double y2, double x3, double y3, int color,
543 int cross)
544 {
545 int i;
546
547 cur_facette++;
548
549 if ((x1-x0)*(y2-y0)-(y1-y0)*(x2-x0)>0)
550 return;
551
552 i=nb_facettes++;
553 f[i].z=z;
554 f[i].x0=x0;
555 f[i].y0=y0;
556 f[i].x1=x1;
557 f[i].y1=y1;
558 f[i].x2=x2;
559 f[i].y2=y2;
560 f[i].x3=x3;
561 f[i].y3=y3;
562 f[i].col=color;
563 f[i].cross=cross;
564 }
565
tri_facette(void)566 void tri_facette(void)
567 {
568 /* hehe, the very first time of my i use this gcc feature, the inline function ! Crazy */
569 int cmp(const void *u1, const void *u2) {
570 double z1=f[*(int *)u1].z, z2=f[*(int *)u2].z;
571 if (z1<z2)
572 return -1;
573 return z1>z2;
574 }
575 qsort(order, nb_facettes, sizeof(int), cmp);
576 }
577
show_facette(SCREEN * s)578 void show_facette(SCREEN *s)
579 {
580 extern device d;
581 int i;
582 poly p;
583 line l;
584
585 p.nb_points=4;
586 l.color=pixel[10];
587
588 for(i=0; i<nb_facettes; i++) {
589 p.points[0].x=f[order[i]].x0;
590 p.points[0].y=f[order[i]].y0;
591 p.points[1].x=f[order[i]].x1;
592 p.points[1].y=f[order[i]].y1;
593 p.points[2].x=f[order[i]].x2;
594 p.points[2].y=f[order[i]].y2;
595 p.points[3].x=f[order[i]].x3;
596 p.points[3].y=f[order[i]].y3;
597 p.color = pixel[f[order[i]].col];
598 fillpoly(&d, &p);
599 #if 0
600 fill_triangle_8bpp(f[order[i]].x0, f[order[i]].y0, f[order[i]].x1, f[order[i]].y1,
601 f[order[i]].x2, f[order[i]].y2, f[order[i]].col);
602 fill_triangle_8bpp(f[order[i]].x0, f[order[i]].y0, f[order[i]].x2, f[order[i]].y2,
603 f[order[i]].x3, f[order[i]].y3, f[order[i]].col);
604 #endif
605
606 l.p1.x=f[order[i]].x0; l.p1.y=f[order[i]].y0;
607 l.p2.x=f[order[i]].x1; l.p2.y=f[order[i]].y1;
608 drawline(&d, &l);
609 /* putline_8bpp(f[order[i]].x0, f[order[i]].y0, f[order[i]].x1, f[order[i]].y1, 0); */
610 l.p1.x=f[order[i]].x2; l.p1.y=f[order[i]].y2;
611 l.p2.x=f[order[i]].x1; l.p2.y=f[order[i]].y1;
612 drawline(&d, &l);
613 /* putline_8bpp(f[order[i]].x2, f[order[i]].y2, f[order[i]].x1, f[order[i]].y1, 0); */
614 l.p1.x=f[order[i]].x2; l.p1.y=f[order[i]].y2;
615 l.p2.x=f[order[i]].x3; l.p2.y=f[order[i]].y3;
616 drawline(&d, &l);
617 /* putline_8bpp(f[order[i]].x2, f[order[i]].y2, f[order[i]].x3, f[order[i]].y3, 0); */
618 l.p1.x=f[order[i]].x0; l.p1.y=f[order[i]].y0;
619 l.p2.x=f[order[i]].x3; l.p2.y=f[order[i]].y3;
620 drawline(&d, &l);
621 /* putline_8bpp(f[order[i]].x0, f[order[i]].y0, f[order[i]].x3, f[order[i]].y3, 0); */
622
623 if (f[order[i]].cross) {
624 l.color = pixel[8];
625 l.p1.x=f[order[i]].x0; l.p1.y=f[order[i]].y0;
626 l.p2.x=f[order[i]].x2; l.p2.y=f[order[i]].y2;
627 l.p2.x = (l.p1.x+2*l.p2.x)/3;
628 l.p2.y = (l.p1.y+2*l.p2.y)/3;
629 l.p1.x = (l.p1.x+l.p2.x)/2;
630 l.p1.y = (l.p1.y+l.p2.y)/2;
631 drawline(&d, &l);
632 ++l.p1.x; ++l.p2.x;
633 drawline(&d, &l);
634 ++l.p1.y; ++l.p2.y;
635 drawline(&d, &l);
636 //putline_8bpp(f[order[i]].x0, f[order[i]].y0, f[order[i]].x2, f[order[i]].y2, /*f[order[i]].cross*/0);
637 l.p1.x=f[order[i]].x1; l.p1.y=f[order[i]].y1;
638 l.p2.x=f[order[i]].x3; l.p2.y=f[order[i]].y3;
639 l.p2.x = (l.p1.x+2*l.p2.x)/3;
640 l.p2.y = (l.p1.y+2*l.p2.y)/3;
641 l.p1.x = (l.p1.x+l.p2.x)/2;
642 l.p1.y = (l.p1.y+l.p2.y)/2;
643 drawline(&d, &l);
644 ++l.p1.x; ++l.p2.x;
645 drawline(&d, &l);
646 ++l.p1.y; ++l.p2.y;
647 drawline(&d, &l);
648 //putline_8bpp(f[order[i]].x1, f[order[i]].y1, f[order[i]].x3, f[order[i]].y3, /*f[order[i]].cross*/0);
649 l.color=pixel[10];
650 }
651 }
652 }
653
show_letters(CUBE * big,SCREEN * s)654 void show_letters(CUBE *big, SCREEN *s)
655 {
656 #define M big->matrix
657 small_cube *c;
658 static Pixmap textpix;
659 static int bigendian;
660 XImage *xim = NULL;
661 int i, j, n, u, v, du, dv, dm, dw, dh;
662 char face[2];
663 char p=0, test;
664 double x, y, z, size, ratio;
665
666 if (!big->letters) return;
667 face[1] = '\0';
668 dm = ((XTextWidth(s->font, "M", 1)+7)/8)*8;
669 dh = s->font->max_bounds.ascent+s->font->max_bounds.descent;
670 if (!xim) {
671 GC gc;
672 textpix = XCreatePixmap(s->d, s->w, 6*dm, dh, 1);
673 gc = XCreateGC(s->d, textpix, 0, 0);
674 bigendian = (ImageByteOrder(s->d) == MSBFirst);
675 XSetForeground(s->d, gc, 1);
676 XSetBackground(s->d, gc, 0);
677 XSetFont(s->d, gc, s->font->fid);
678 v = s->font->max_bounds.ascent;
679 for (n=0; n<6; n++) {
680 face[0] = 'A' + n;
681 XDrawImageString(s->d, textpix, gc, n*dm, v, face, 1);
682 }
683 XFreeGC(s->d, gc);
684 xim = XGetImage(s->d, textpix, 0, 0, 6*dm, dh, 1, XYPixmap);
685 XFreePixmap(s->d, textpix);
686 }
687
688 du = XTextWidth(s->font, "A", 1)/2;
689 dv = s->font->max_bounds.ascent/2;
690 size = 1.0 + EDGE;
691 for (n=0; n<6; n++) {
692 c = &big->cubes[n];
693 z = size*(c->x*M[0][2]+ c->y*M[1][2]+ c->z*M[2][2]);
694 if (z>0.5*PERSPECTIVE) {
695 face[0] = 'A' + n;
696 dw = XTextWidth(s->font, face, 1);
697 x = size*(c->x*M[0][0]+ c->y*M[1][0]+ c->z*M[2][0]);
698 y = size*(c->x*M[0][1]+ c->y*M[1][1]+ c->z*M[2][1]);
699 ratio = CUBE_SIZE/(5.0-PERSPECTIVE*z);
700 u = 0.5*SCREEN_X + ratio*x - du;
701 v = 0.5*SCREEN_Y - ratio*y + dv - s->font->max_bounds.ascent;
702 test = (bigendian)? 128 : 1;
703 for (j=0; j<dh; ++j)
704 for (i=0; i<dw; ++i) {
705 if ((i&7) == 0)
706 p = xim->data[j*xim->bytes_per_line+(i+n*dm)/8];
707 if (p&test)
708 XPutPixel(s->im, u+i, v+j, pixel[8]);
709 p = (bigendian)? p<<1 : p>>1;
710 }
711 }
712 }
713 }
714
display_small_cube(CUBE * big,SCREEN * s,int i)715 void display_small_cube(CUBE *big, SCREEN *s, int i)
716 {
717 static short u[6] = { 0, 2, 2, 1, 0, 1};
718 static short v[6] = { 2, 0, 1, 2, 1, 0};
719 // static short opposite[6] = { 1, 0, 3, 2, 5, 4};
720 static short face[6][4]={{0,4,5,1},
721 {2,3,7,6},
722 {0,1,3,2},
723 {4,6,7,5},
724 {1,5,7,3},
725 {0,2,6,4}};
726 static short layers[6][26]={
727 /*0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25*/
728 { 1,-1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,-1,-1,-1,-1,-1,-1,-1,-1},
729 {-1, 1, 0, 0, 0, 0,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1},
730 { 0, 0, 1,-1, 0, 0,-1,-1,-1, 0, 0, 1, 1, 1,-1,-1, 1, 1,-1,-1,-1, 0, 0, 1, 1, 1},
731 { 0, 0,-1, 1, 0, 0, 1, 1, 1, 0, 0,-1,-1,-1, 1, 1,-1,-1, 1, 1, 1, 0, 0,-1,-1,-1},
732 { 0, 0, 0, 0, 1,-1, 1, 0,-1, 1,-1, 1, 0,-1, 1,-1, 1,-1, 1, 0,-1, 1,-1, 1, 0,-1},
733 { 0, 0, 0, 0,-1, 1,-1, 0, 1,-1, 1,-1, 0, 1,-1, 1,-1, 1,-1, 0, 1,-1, 1,-1, 0, 1}};
734
735 double m[3][3];
736 double m1[3][3]={{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}};
737 double p1[8][3];
738 double p2[8][3];
739 double pp[8][2];
740 double ratio;
741 double zm;
742 small_cube *c;
743 int n;
744 //int k;
745
746 memcpy(m, big->matrix, 9*sizeof(double));
747
748 if (big->anim) {
749 n = big->rotated;
750 if (layers[n][i]==1) {
751 m1[u[n]][u[n]] = m1[v[n]][v[n]] = cos(big->angle);
752 m1[u[n]][v[n]] = sin(big->angle);
753 m1[v[n]][u[n]] = -m1[u[n]][v[n]];
754 }
755 }
756
757 c = &big->cubes[i];
758 for (n=0; n<8; n++) {
759 p1[n][0]=(((e[n][0]+c->x)*m1[0][0]+ (e[n][1]+c->y)*m1[1][0]+ (e[n][2]+c->z)*m1[2][0]));
760 p1[n][1]=(((e[n][0]+c->x)*m1[0][1]+ (e[n][1]+c->y)*m1[1][1]+ (e[n][2]+c->z)*m1[2][1]));
761 p1[n][2]=(((e[n][0]+c->x)*m1[0][2]+ (e[n][1]+c->y)*m1[1][2]+ (e[n][2]+c->z)*m1[2][2]));
762 p2[n][0]=((p1[n][0]*m[0][0]+ p1[n][1]*m[1][0]+ p1[n][2]*m[2][0]));
763 p2[n][1]=((p1[n][0]*m[0][1]+ p1[n][1]*m[1][1]+ p1[n][2]*m[2][1]));
764 p2[n][2]=((p1[n][0]*m[0][2]+ p1[n][1]*m[1][2]+ p1[n][2]*m[2][2]));
765 #define x (p2[n][0])
766 #define y (p2[n][1])
767 #define z (p2[n][2])
768 #define Xp (pp[n][0])
769 #define Yp (pp[n][1])
770 /*
771 Xp=320./2.+320./2.*x/(5.*(1.)-z);
772 Yp=120.-240./(2.*240./320.)*y/(5.*(1.)-z);
773 */
774 ratio = CUBE_SIZE/(5.0-PERSPECTIVE*z);
775 Xp = 0.5*SCREEN_X + ratio*x;
776 Yp = 0.5*SCREEN_Y - ratio*y;
777 #undef x
778 #undef y
779 #undef z
780 #undef Xp
781 #undef Yp
782 }
783
784 /* if animation, draw in color 0 any visible internal face
785 from medium layer -- added by J.P. Demailly */
786 if (big->anim==1) {
787 n = big->rotated;
788 if (layers[n][i]==0 && c->colors[n]<0) {
789 zm=p2[face[n][0]][2]+p2[face[n][1]][2]+p2[face[n][2]][2]+p2[face[n][3]][2];
790 put_facette(zm, pp[face[n][0]][0], pp[face[n][0]][1], pp[face[n][1]][0], pp[face[n][1]][1],
791 pp[face[n][2]][0], pp[face[n][2]][1], pp[face[n][3]][0], pp[face[n][3]][1], 7, 0);
792 }
793 }
794
795 if (big->anim==-1) {
796 for (n=0; n<6; n++)
797 if (c->colors[n]>=0) {
798 zm=p2[face[n][0]][2]+p2[face[n][1]][2]+p2[face[n][2]][2]+p2[face[n][3]][2];
799 put_facette(zm, pp[face[n][0]][0], pp[face[n][0]][1], pp[face[n][1]][0], pp[face[n][1]][1],
800 pp[face[n][2]][0], pp[face[n][2]][1], pp[face[n][3]][0], pp[face[n][3]][1], 7, 0);
801 }
802 }
803
804
805 /* draw visible faces */
806 for (n=0; n<6; n++) {
807 /* those tests WILL fail if you move the cube with the mouse while a face rotates */
808 /* so let's go back to the previous situation, where everything was fine */
809 //k = opposite[big->anim ? big->rotated : big->center];
810 //k = opposite[big->center];
811 //if ((n!=k || big->anim==-1) && c->colors[n]>=0) {
812 if (c->colors[n]>=0) {
813 zm=p2[face[n][0]][2]+p2[face[n][1]][2]+p2[face[n][2]][2]+p2[face[n][3]][2];
814 put_facette(zm, pp[face[n][0]][0], pp[face[n][0]][1], pp[face[n][1]][0], pp[face[n][1]][1],
815 pp[face[n][2]][0], pp[face[n][2]][1], pp[face[n][3]][0], pp[face[n][3]][1], c->colors[n],
816 //(big->anim ? i==big->rotated : i==big->center) && (!big->letters));
817 (i==big->center) && (!big->letters));
818 }
819 }
820 }
821
z_middle(CUBE * c,int n)822 double z_middle(CUBE *c, int n)
823 {
824 #define m c->matrix
825 #define x (c->cubes[n].x)
826 #define y (c->cubes[n].y)
827 #define z (c->cubes[n].z)
828 /* well, well, well, i must have done something wrong, it should be
829 * m[2][0]*x+m[2][1]*y+m[2][2]*z, nope ? Well...
830 */
831 return m[0][2]*x+m[1][2]*y+m[2][2]*z;
832 #undef x
833 #undef y
834 #undef z
835 #undef m
836 }
837
place_cross(CUBE * c)838 void place_cross(CUBE *c)
839 {
840 int i=1;
841 int n=0;
842 double z=z_middle(c, 0);
843
844 while(i<6) {
845 double z1=z_middle(c, i);
846 if (z1>z) {
847 n=i;
848 z=z1;
849 }
850 i++;
851 }
852 if (c->anim!=-1)
853 c->center=n;
854 }
855
display_cube(CUBE * c,SCREEN * s)856 void display_cube(CUBE *c, SCREEN *s)
857 {
858 int i;
859
860 if (c->anim)
861 cube_event(c);
862
863 place_cross(c);
864
865 clear_facette();
866
867 for (i=0; i<26; i++)
868 display_small_cube(c, s, i);
869
870 tri_facette();
871 clear_screen(s);
872 show_facette(s);
873 if (c->anim == 0)
874 show_letters(c, s);
875 put_screen(c, s);
876 }
877
878 /* c->orient and c->rotated are used so they must be set to their correct value */
cube_do_rotate(CUBE * c)879 static void cube_do_rotate(CUBE *c)
880 {
881 CUBE old;
882 memcpy(&old, c, sizeof(CUBE));
883 /* gotta change colors, woo woo woo */
884 if (c->orient==0)
885 switch(c->rotated) {
886 case 0 :
887 c->cubes[11].colors[0]=old.cubes[6].colors[0];
888 c->cubes[11].colors[2]=old.cubes[6].colors[4];
889 c->cubes[11].colors[4]=old.cubes[6].colors[3];
890 c->cubes[12].colors[0]=old.cubes[9].colors[0];
891 c->cubes[12].colors[2]=old.cubes[9].colors[4];
892 c->cubes[13].colors[0]=old.cubes[11].colors[0];
893 c->cubes[13].colors[2]=old.cubes[11].colors[4];
894 c->cubes[13].colors[5]=old.cubes[11].colors[2];
895 c->cubes[10].colors[0]=old.cubes[12].colors[0];
896 c->cubes[10].colors[5]=old.cubes[12].colors[2];
897 c->cubes[8].colors[0]=old.cubes[13].colors[0];
898 c->cubes[8].colors[5]=old.cubes[13].colors[2];
899 c->cubes[8].colors[3]=old.cubes[13].colors[5];
900 c->cubes[7].colors[0]=old.cubes[10].colors[0];
901 c->cubes[7].colors[3]=old.cubes[10].colors[5];
902 c->cubes[6].colors[0]=old.cubes[8].colors[0];
903 c->cubes[6].colors[3]=old.cubes[8].colors[5];
904 c->cubes[6].colors[4]=old.cubes[8].colors[3];
905 c->cubes[9].colors[0]=old.cubes[7].colors[0];
906 c->cubes[9].colors[4]=old.cubes[7].colors[3];
907 break;
908 case 1 :
909 c->cubes[18].colors[1]=old.cubes[23].colors[1];
910 c->cubes[18].colors[3]=old.cubes[23].colors[4];
911 c->cubes[18].colors[4]=old.cubes[23].colors[2];
912 c->cubes[21].colors[1]=old.cubes[24].colors[1];
913 c->cubes[21].colors[4]=old.cubes[24].colors[2];
914 c->cubes[23].colors[1]=old.cubes[25].colors[1];
915 c->cubes[23].colors[4]=old.cubes[25].colors[2];
916 c->cubes[23].colors[2]=old.cubes[25].colors[5];
917 c->cubes[24].colors[1]=old.cubes[22].colors[1];
918 c->cubes[24].colors[2]=old.cubes[22].colors[5];
919 c->cubes[25].colors[1]=old.cubes[20].colors[1];
920 c->cubes[25].colors[2]=old.cubes[20].colors[5];
921 c->cubes[25].colors[5]=old.cubes[20].colors[3];
922 c->cubes[22].colors[1]=old.cubes[19].colors[1];
923 c->cubes[22].colors[5]=old.cubes[19].colors[3];
924 c->cubes[20].colors[1]=old.cubes[18].colors[1];
925 c->cubes[20].colors[5]=old.cubes[18].colors[3];
926 c->cubes[20].colors[3]=old.cubes[18].colors[4];
927 c->cubes[19].colors[1]=old.cubes[21].colors[1];
928 c->cubes[19].colors[3]=old.cubes[21].colors[4];
929 break;
930 case 2 :
931 c->cubes[25].colors[2]=old.cubes[23].colors[2];
932 c->cubes[25].colors[1]=old.cubes[23].colors[4];
933 c->cubes[25].colors[5]=old.cubes[23].colors[1];
934 c->cubes[24].colors[2]=old.cubes[16].colors[2];
935 c->cubes[24].colors[1]=old.cubes[16].colors[4];
936 c->cubes[23].colors[2]=old.cubes[11].colors[2];
937 c->cubes[23].colors[1]=old.cubes[11].colors[4];
938 c->cubes[23].colors[4]=old.cubes[11].colors[0];
939 c->cubes[16].colors[2]=old.cubes[12].colors[2];
940 c->cubes[16].colors[4]=old.cubes[12].colors[0];
941 c->cubes[11].colors[2]=old.cubes[13].colors[2];
942 c->cubes[11].colors[4]=old.cubes[13].colors[0];
943 c->cubes[11].colors[0]=old.cubes[13].colors[5];
944 c->cubes[12].colors[2]=old.cubes[17].colors[2];
945 c->cubes[12].colors[0]=old.cubes[17].colors[5];
946 c->cubes[13].colors[2]=old.cubes[25].colors[2];
947 c->cubes[13].colors[0]=old.cubes[25].colors[5];
948 c->cubes[13].colors[5]=old.cubes[25].colors[1];
949 c->cubes[17].colors[2]=old.cubes[24].colors[2];
950 c->cubes[17].colors[5]=old.cubes[24].colors[1];
951 break;
952 case 3 :
953 c->cubes[6].colors[3]=old.cubes[18].colors[3];
954 c->cubes[6].colors[0]=old.cubes[18].colors[4];
955 c->cubes[6].colors[4]=old.cubes[18].colors[1];
956 c->cubes[7].colors[3]=old.cubes[14].colors[3];
957 c->cubes[7].colors[0]=old.cubes[14].colors[4];
958 c->cubes[8].colors[3]=old.cubes[6].colors[3];
959 c->cubes[8].colors[0]=old.cubes[6].colors[4];
960 c->cubes[8].colors[5]=old.cubes[6].colors[0];
961 c->cubes[15].colors[3]=old.cubes[7].colors[3];
962 c->cubes[15].colors[5]=old.cubes[7].colors[0];
963 c->cubes[20].colors[3]=old.cubes[8].colors[3];
964 c->cubes[20].colors[5]=old.cubes[8].colors[0];
965 c->cubes[20].colors[1]=old.cubes[8].colors[5];
966 c->cubes[19].colors[3]=old.cubes[15].colors[3];
967 c->cubes[19].colors[1]=old.cubes[15].colors[5];
968 c->cubes[18].colors[3]=old.cubes[20].colors[3];
969 c->cubes[18].colors[1]=old.cubes[20].colors[5];
970 c->cubes[18].colors[4]=old.cubes[20].colors[1];
971 c->cubes[14].colors[3]=old.cubes[19].colors[3];
972 c->cubes[14].colors[4]=old.cubes[19].colors[1];
973 break;
974 case 4 :
975 c->cubes[11].colors[4]=old.cubes[23].colors[4];
976 c->cubes[11].colors[0]=old.cubes[23].colors[2];
977 c->cubes[11].colors[2]=old.cubes[23].colors[1];
978 c->cubes[9].colors[4]=old.cubes[16].colors[4];
979 c->cubes[9].colors[0]=old.cubes[16].colors[2];
980 c->cubes[6].colors[4]=old.cubes[11].colors[4];
981 c->cubes[6].colors[0]=old.cubes[11].colors[2];
982 c->cubes[6].colors[3]=old.cubes[11].colors[0];
983 c->cubes[14].colors[4]=old.cubes[9].colors[4];
984 c->cubes[14].colors[3]=old.cubes[9].colors[0];
985 c->cubes[18].colors[4]=old.cubes[6].colors[4];
986 c->cubes[18].colors[3]=old.cubes[6].colors[0];
987 c->cubes[18].colors[1]=old.cubes[6].colors[3];
988 c->cubes[21].colors[4]=old.cubes[14].colors[4];
989 c->cubes[21].colors[1]=old.cubes[14].colors[3];
990 c->cubes[23].colors[4]=old.cubes[18].colors[4];
991 c->cubes[23].colors[1]=old.cubes[18].colors[3];
992 c->cubes[23].colors[2]=old.cubes[18].colors[1];
993 c->cubes[16].colors[4]=old.cubes[21].colors[4];
994 c->cubes[16].colors[2]=old.cubes[21].colors[1];
995 break;
996 case 5 :
997 c->cubes[25].colors[5]=old.cubes[13].colors[5];
998 c->cubes[25].colors[1]=old.cubes[13].colors[2];
999 c->cubes[25].colors[2]=old.cubes[13].colors[0];
1000 c->cubes[22].colors[5]=old.cubes[17].colors[5];
1001 c->cubes[22].colors[1]=old.cubes[17].colors[2];
1002 c->cubes[20].colors[5]=old.cubes[25].colors[5];
1003 c->cubes[20].colors[1]=old.cubes[25].colors[2];
1004 c->cubes[20].colors[3]=old.cubes[25].colors[1];
1005 c->cubes[15].colors[5]=old.cubes[22].colors[5];
1006 c->cubes[15].colors[3]=old.cubes[22].colors[1];
1007 c->cubes[8].colors[5]=old.cubes[20].colors[5];
1008 c->cubes[8].colors[3]=old.cubes[20].colors[1];
1009 c->cubes[8].colors[0]=old.cubes[20].colors[3];
1010 c->cubes[10].colors[5]=old.cubes[15].colors[5];
1011 c->cubes[10].colors[0]=old.cubes[15].colors[3];
1012 c->cubes[13].colors[5]=old.cubes[8].colors[5];
1013 c->cubes[13].colors[0]=old.cubes[8].colors[3];
1014 c->cubes[13].colors[2]=old.cubes[8].colors[0];
1015 c->cubes[17].colors[5]=old.cubes[10].colors[5];
1016 c->cubes[17].colors[2]=old.cubes[10].colors[0];
1017 break;
1018 }
1019 else
1020 switch(c->rotated) {
1021 case 0 :
1022 c->cubes[6].colors[0]=old.cubes[11].colors[0];
1023 c->cubes[6].colors[4]=old.cubes[11].colors[2];
1024 c->cubes[6].colors[3]=old.cubes[11].colors[4];
1025 c->cubes[9].colors[0]=old.cubes[12].colors[0];
1026 c->cubes[9].colors[4]=old.cubes[12].colors[2];
1027 c->cubes[11].colors[0]=old.cubes[13].colors[0];
1028 c->cubes[11].colors[4]=old.cubes[13].colors[2];
1029 c->cubes[11].colors[2]=old.cubes[13].colors[5];
1030 c->cubes[12].colors[0]=old.cubes[10].colors[0];
1031 c->cubes[12].colors[2]=old.cubes[10].colors[5];
1032 c->cubes[13].colors[0]=old.cubes[8].colors[0];
1033 c->cubes[13].colors[2]=old.cubes[8].colors[5];
1034 c->cubes[13].colors[5]=old.cubes[8].colors[3];
1035 c->cubes[10].colors[0]=old.cubes[7].colors[0];
1036 c->cubes[10].colors[5]=old.cubes[7].colors[3];
1037 c->cubes[8].colors[0]=old.cubes[6].colors[0];
1038 c->cubes[8].colors[5]=old.cubes[6].colors[3];
1039 c->cubes[8].colors[3]=old.cubes[6].colors[4];
1040 c->cubes[7].colors[0]=old.cubes[9].colors[0];
1041 c->cubes[7].colors[3]=old.cubes[9].colors[4];
1042 break;
1043 case 1 :
1044 c->cubes[23].colors[1]=old.cubes[18].colors[1];
1045 c->cubes[23].colors[4]=old.cubes[18].colors[3];
1046 c->cubes[23].colors[2]=old.cubes[18].colors[4];
1047 c->cubes[24].colors[1]=old.cubes[21].colors[1];
1048 c->cubes[24].colors[2]=old.cubes[21].colors[4];
1049 c->cubes[25].colors[1]=old.cubes[23].colors[1];
1050 c->cubes[25].colors[2]=old.cubes[23].colors[4];
1051 c->cubes[25].colors[5]=old.cubes[23].colors[2];
1052 c->cubes[22].colors[1]=old.cubes[24].colors[1];
1053 c->cubes[22].colors[5]=old.cubes[24].colors[2];
1054 c->cubes[20].colors[1]=old.cubes[25].colors[1];
1055 c->cubes[20].colors[5]=old.cubes[25].colors[2];
1056 c->cubes[20].colors[3]=old.cubes[25].colors[5];
1057 c->cubes[19].colors[1]=old.cubes[22].colors[1];
1058 c->cubes[19].colors[3]=old.cubes[22].colors[5];
1059 c->cubes[18].colors[1]=old.cubes[20].colors[1];
1060 c->cubes[18].colors[3]=old.cubes[20].colors[5];
1061 c->cubes[18].colors[4]=old.cubes[20].colors[3];
1062 c->cubes[21].colors[1]=old.cubes[19].colors[1];
1063 c->cubes[21].colors[4]=old.cubes[19].colors[3];
1064 break;
1065 case 2 :
1066 c->cubes[23].colors[2]=old.cubes[25].colors[2];
1067 c->cubes[23].colors[4]=old.cubes[25].colors[1];
1068 c->cubes[23].colors[1]=old.cubes[25].colors[5];
1069 c->cubes[16].colors[2]=old.cubes[24].colors[2];
1070 c->cubes[16].colors[4]=old.cubes[24].colors[1];
1071 c->cubes[11].colors[2]=old.cubes[23].colors[2];
1072 c->cubes[11].colors[4]=old.cubes[23].colors[1];
1073 c->cubes[11].colors[0]=old.cubes[23].colors[4];
1074 c->cubes[12].colors[2]=old.cubes[16].colors[2];
1075 c->cubes[12].colors[0]=old.cubes[16].colors[4];
1076 c->cubes[13].colors[2]=old.cubes[11].colors[2];
1077 c->cubes[13].colors[0]=old.cubes[11].colors[4];
1078 c->cubes[13].colors[5]=old.cubes[11].colors[0];
1079 c->cubes[17].colors[2]=old.cubes[12].colors[2];
1080 c->cubes[17].colors[5]=old.cubes[12].colors[0];
1081 c->cubes[25].colors[2]=old.cubes[13].colors[2];
1082 c->cubes[25].colors[5]=old.cubes[13].colors[0];
1083 c->cubes[25].colors[1]=old.cubes[13].colors[5];
1084 c->cubes[24].colors[2]=old.cubes[17].colors[2];
1085 c->cubes[24].colors[1]=old.cubes[17].colors[5];
1086 break;
1087 case 3 :
1088 c->cubes[18].colors[3]=old.cubes[6].colors[3];
1089 c->cubes[18].colors[4]=old.cubes[6].colors[0];
1090 c->cubes[18].colors[1]=old.cubes[6].colors[4];
1091 c->cubes[14].colors[3]=old.cubes[7].colors[3];
1092 c->cubes[14].colors[4]=old.cubes[7].colors[0];
1093 c->cubes[6].colors[3]=old.cubes[8].colors[3];
1094 c->cubes[6].colors[4]=old.cubes[8].colors[0];
1095 c->cubes[6].colors[0]=old.cubes[8].colors[5];
1096 c->cubes[7].colors[3]=old.cubes[15].colors[3];
1097 c->cubes[7].colors[0]=old.cubes[15].colors[5];
1098 c->cubes[8].colors[3]=old.cubes[20].colors[3];
1099 c->cubes[8].colors[0]=old.cubes[20].colors[5];
1100 c->cubes[8].colors[5]=old.cubes[20].colors[1];
1101 c->cubes[15].colors[3]=old.cubes[19].colors[3];
1102 c->cubes[15].colors[5]=old.cubes[19].colors[1];
1103 c->cubes[20].colors[3]=old.cubes[18].colors[3];
1104 c->cubes[20].colors[5]=old.cubes[18].colors[1];
1105 c->cubes[20].colors[1]=old.cubes[18].colors[4];
1106 c->cubes[19].colors[3]=old.cubes[14].colors[3];
1107 c->cubes[19].colors[1]=old.cubes[14].colors[4];
1108 break;
1109 case 4 :
1110 c->cubes[23].colors[4]=old.cubes[11].colors[4];
1111 c->cubes[23].colors[2]=old.cubes[11].colors[0];
1112 c->cubes[23].colors[1]=old.cubes[11].colors[2];
1113 c->cubes[16].colors[4]=old.cubes[9].colors[4];
1114 c->cubes[16].colors[2]=old.cubes[9].colors[0];
1115 c->cubes[11].colors[4]=old.cubes[6].colors[4];
1116 c->cubes[11].colors[2]=old.cubes[6].colors[0];
1117 c->cubes[11].colors[0]=old.cubes[6].colors[3];
1118 c->cubes[9].colors[4]=old.cubes[14].colors[4];
1119 c->cubes[9].colors[0]=old.cubes[14].colors[3];
1120 c->cubes[6].colors[4]=old.cubes[18].colors[4];
1121 c->cubes[6].colors[0]=old.cubes[18].colors[3];
1122 c->cubes[6].colors[3]=old.cubes[18].colors[1];
1123 c->cubes[14].colors[4]=old.cubes[21].colors[4];
1124 c->cubes[14].colors[3]=old.cubes[21].colors[1];
1125 c->cubes[18].colors[4]=old.cubes[23].colors[4];
1126 c->cubes[18].colors[3]=old.cubes[23].colors[1];
1127 c->cubes[18].colors[1]=old.cubes[23].colors[2];
1128 c->cubes[21].colors[4]=old.cubes[16].colors[4];
1129 c->cubes[21].colors[1]=old.cubes[16].colors[2];
1130 break;
1131 case 5 :
1132 c->cubes[13].colors[5]=old.cubes[25].colors[5];
1133 c->cubes[13].colors[2]=old.cubes[25].colors[1];
1134 c->cubes[13].colors[0]=old.cubes[25].colors[2];
1135 c->cubes[17].colors[5]=old.cubes[22].colors[5];
1136 c->cubes[17].colors[2]=old.cubes[22].colors[1];
1137 c->cubes[25].colors[5]=old.cubes[20].colors[5];
1138 c->cubes[25].colors[2]=old.cubes[20].colors[1];
1139 c->cubes[25].colors[1]=old.cubes[20].colors[3];
1140 c->cubes[22].colors[5]=old.cubes[15].colors[5];
1141 c->cubes[22].colors[1]=old.cubes[15].colors[3];
1142 c->cubes[20].colors[5]=old.cubes[8].colors[5];
1143 c->cubes[20].colors[1]=old.cubes[8].colors[3];
1144 c->cubes[20].colors[3]=old.cubes[8].colors[0];
1145 c->cubes[15].colors[5]=old.cubes[10].colors[5];
1146 c->cubes[15].colors[3]=old.cubes[10].colors[0];
1147 c->cubes[8].colors[5]=old.cubes[13].colors[5];
1148 c->cubes[8].colors[3]=old.cubes[13].colors[0];
1149 c->cubes[8].colors[0]=old.cubes[13].colors[2];
1150 c->cubes[10].colors[5]=old.cubes[17].colors[5];
1151 c->cubes[10].colors[0]=old.cubes[17].colors[2];
1152 break;
1153 }
1154 }
1155
cube_event(CUBE * c)1156 void cube_event(CUBE *c)
1157 {
1158 #define MAX 300.
1159 struct timeval tt=get_time();
1160 double t=(float)(tt.tv_sec-c->time.tv_sec)*1000.+(float)(tt.tv_usec-c->time.tv_usec)/1000.;
1161
1162 if (t>MAX) {
1163 c->anim = 0;
1164 c->angle = 0.0;
1165 cube_do_rotate(c);
1166 return;
1167 } else
1168 c->angle = M_PI/2.*(t/MAX);
1169
1170 if (c->orient!=0)
1171 c->angle = -c->angle;
1172 }
1173
cube_rotate(SCREEN * s,CUBE * c,double dx,double dy)1174 void cube_rotate(SCREEN *s, CUBE *c, double dx, double dy)
1175 {
1176 if (dx)
1177 xmat(dx, c->matrix);
1178 if (dy)
1179 ymat(dy, c->matrix);
1180 }
1181
cube_generate_rotate(CUBE * c,SCREEN * s,int orient)1182 void cube_generate_rotate(CUBE *c, SCREEN *s, int orient)
1183 {
1184 if (c->anim)
1185 return;
1186
1187 if (s->pause)
1188 return;
1189
1190 c->rotated = c->center;
1191 c->orient=orient;
1192 c->anim=1;
1193 c->time=get_time();
1194 }
1195