Replaced deprecated variables CONTRIBDIR, BINDIR and
[AROS-Contrib.git] / fish / 362_rubik / draw.c
bloba49c2c36e611959b7313df292675f3119215e8dc
1 /* drawing stuff for rubik.c M.J.Round 3rd Feb 90 */
3 #include "header.c"
5 #define y1 myy1
7 extern struct GfxBase * GfxBase;
8 int twistlist[21];
9 int x1,y1,x2,y2,x3,y3;
11 int tr [120] = /* transformations for 90 degree side rotates */
13 0,2,8,6,
14 1,5,7,3,
15 18,45,29,42,
16 19,48,28,39,
17 20,51,27,36,
19 9,11,17,15,
20 10,14,16,12,
21 24,47,35,44,
22 25,50,34,41,
23 26,53,33,38,
25 18,20,26,24,
26 19,23,25,21,
27 0,45,11,38,
28 1,46,10,37,
29 2,47,9,36,
31 27,29,35,33,
32 28,32,34,30,
33 6,51,17,44,
34 7,52,16,43,
35 8,53,15,42,
37 36,38,44,42,
38 37,41,43,39,
39 18,9,33,6,
40 21,12,30,3,
41 24,15,27,0,
43 45,47,53,51,
44 46,50,52,48,
45 20,11,35,8,
46 23,14,32,5,
47 26,17,29,2
50 extern struct points point; /* holds posn.s of all points */
51 extern struct points start;
52 extern struct one_square square[56];
53 extern struct Window *wnd1;
54 extern struct Window *wnd2;
55 extern struct Window *window;
56 extern struct Screen *scr1;
57 extern struct Screen *scr2;
58 extern struct Screen *screen;
60 extern int viewdist;
61 extern short xcent,ycent;
62 extern short angle(short, short, unsigned short);
63 extern unsigned short hypoten (short, short);
64 extern unsigned short scaling;
66 extern void roll (short);
67 extern void yaw (short);
68 extern void pitch (short);
69 extern void fb (short, short);
70 extern void bt (short, short);
71 extern void lr (short, short);
73 void twist (short ident, short amount)
74 /* ident = 0 to 5 for front,back,(bottom),(top),left,right */
75 /* amount = -1, +1 or +2 (90 degree twists) */
77 short c;
78 unsigned short i,j,k;
80 if (amount > 0)
82 for (i = 0; i<amount; i++)
84 for (j = ident * 20; j < ident * 20 + 20; j += 4)
86 c = (square[tr[j]]).colour;
87 for (k = j; k < (j + 3); k++)
88 (square[tr[k]]).colour = (square[tr[k+1]]).colour;
89 (square[tr[j+3]]).colour = c;
93 else
95 for (i = 0; i < (-amount); i++)
97 for (j = ident * 20; j < ident * 20 + 20; j += 4)
99 c = (square[tr[j+3]]).colour;
100 for (k = j + 3; k > j; k--)
101 (square[tr[k]]).colour = (square[tr[k-1]]).colour;
102 (square[tr[j]]).colour = c;
108 /* return true if a square is clockwise else false */
109 int clockwise(register int i)
111 register int d;
112 short x,y,ang1,ang2;
113 unsigned short r;
115 d=(viewdist+(square[i].corner[0]->z)) << scaling;
116 x1 = xcent+(viewdist*square[i].corner[0]->x)/d;
117 y1 = ycent+(viewdist*square[i].corner[0]->y)/d;
119 d=(viewdist+(square[i].corner[1]->z)) << scaling;
120 x2 = xcent+(viewdist*square[i].corner[1]->x)/d;
121 y2 = ycent+(viewdist*square[i].corner[1]->y)/d;
123 d=(viewdist+(square[i].corner[2]->z)) << scaling;
124 x3 = xcent+(viewdist*square[i].corner[2]->x)/d;
125 y3 = ycent+(viewdist*square[i].corner[2]->y)/d;
127 x = x2-x1;
128 y = y2-y1;
130 ang1 = ang2 = 0;
132 if (x || y)
133 ang1 = angle(x, y, (r = hypoten (x, y)));
135 x = x3-x2;
136 y = y3-y2;
138 if (x || y)
139 ang2 = angle(x, y, (r = hypoten (x, y)));
141 d = ang1-ang2;
143 if (d > 180)
144 d -= 360;
146 if (d < -179)
147 d += 360;
149 return (d > 0);
153 void draw_square(register int i)
155 register int d;
157 SetAPen (window->RPort,square[i].colour);
158 SetDrMd(window->RPort, JAM1);
160 AreaMove (window->RPort,x1,y1);
161 AreaDraw (window->RPort,x2,y2);
162 AreaDraw (window->RPort,x3,y3);
163 d=(viewdist+(square[i].corner[3]->z)) << scaling;
164 AreaDraw
166 window->RPort,
167 xcent+(viewdist*square[i].corner[3]->x)/d,
168 ycent+(viewdist*square[i].corner[3]->y)/d
170 AreaEnd (window->RPort);
173 /* this routine renders the cube with roll, yaw and pitch alpha, beta, gamma
174 if twists is non-zero, <layer> is rotated delta degrees at a time, through
175 <twists> 90 degree twists.
177 void showcube
179 short alpha,
180 short beta,
181 short gamma,
182 short layer,
183 short twists,
184 short delta
187 int i,j;
188 short theta = 0;
192 point = start; /* this copies the 'zeroed' cube to the workspace */
194 if (twists)
196 theta += (twists > 0) ? -delta : delta;
198 if ((theta <= -90) || (theta >= 90))
200 theta = (twists > 0) ? 1 : -1;
201 twist (layer,theta);
202 twists -= theta;
203 theta = 0;
205 else
207 switch (layer)
209 case 0:
210 case 1:
211 fb(layer,theta);
212 break;
213 case 2:
214 case 3:
215 bt((short)(layer-2),theta);
216 break;
217 default:
218 lr((short)(layer-4),theta);
219 break;
224 if (alpha)
225 roll (alpha);
226 if (beta)
227 yaw (beta);
228 if (gamma)
229 pitch (gamma);
231 SetAPen(window->RPort,7);
232 RectFill(window->RPort,2,10,190,198);
234 if (theta == 0)
236 for (i=0; i<54; i++)
237 if (clockwise(i))
238 draw_square(i);
239 else if ((i % 3) == 0)
240 i += 2;
242 else if (clockwise(54))
244 draw_square(54);
246 for (i=0; i<21; i++)
247 if (clockwise(twistlist[i]))
248 draw_square(twistlist[i]);
249 else if ((i % 3) == 0)
250 i += 2;
252 j = 0;
254 for (i=0; i<54; i++)
256 while ((j < 21) && ((twistlist[j]) < i))
257 j++;
259 if ((j > 20) || (i != twistlist[j]))
261 if (clockwise(i))
262 draw_square(i);
263 else if ((i % 3) == 0)
264 i += 2;
268 else
270 if (clockwise(55)) /* need this to get corners */
271 draw_square(55);
273 j = 0;
275 for (i=0; i<54; i++)
277 while ((j < 21) && ((twistlist[j]) < i))
278 j++;
280 if ((j > 20) || (i != twistlist[j]))
282 if (clockwise(i))
283 draw_square(i);
284 else if ((i % 3) == 0)
285 i += 2;
289 for (i=0; i<21; i++)
290 if (clockwise(twistlist[i]))
291 draw_square(twistlist[i]);
292 else if ((i % 3) == 0)
293 i += 2;
296 ScreenToFront(screen);
298 if (screen == scr1)
300 screen = scr2;
301 window = wnd2;
303 else
305 screen = scr1;
306 window = wnd1;
308 } while (twists);
312 int whatsquare(int x, int y) /* returns square number, or -1 */
314 struct Window *viswindow;
315 int colour,i;
317 if (y<12 || x>190)
318 return(-1);
320 if (window == wnd1)
321 viswindow = wnd2;
322 else
323 viswindow = wnd1;
325 for (i = 0; i < 4 && (colour = ReadPixel(viswindow->RPort,x,y)) == 0; i++)
327 switch (i)
329 case 0:
330 x += 2;
331 break;
332 case 1:
333 y += 2;
334 break;
335 case 3:
336 x -= 2;
337 break;
339 } /* find a nearby square if they click on the lines */
341 if (colour <= 0 || colour == 7)
342 return (-1);
344 ClipBlit
346 viswindow->RPort,2,10, /* source posn */
347 window->RPort,2,10, /* dest posn */
348 188,188, /* size */
349 0xc0 /* direct copy */
352 SetAPen(window->RPort,7);
353 Flood (window->RPort,1,x,y);
355 for (i=0; i<54; i++)
356 if (clockwise(i))
358 draw_square(i);
359 if (ReadPixel(window->RPort,x,y) != 7)
360 return(i);
364 return (-1);
367 int paints(int x, int y, int pen) /* returns square number, or -1 */
369 struct Window *viswindow;
370 int colour,i;
372 if (y<12 || x>190)
373 return(-1);
375 if (window == wnd1)
376 viswindow = wnd2;
377 else
378 viswindow = wnd1;
380 for (i = 0; i < 4 && (colour = ReadPixel(viswindow->RPort,x,y)) == 0; i++)
382 switch (i)
384 case 0:
385 x += 2;
386 break;
387 case 1:
388 y += 2;
389 break;
390 case 3:
391 x -= 2;
392 break;
394 } /* find a nearby square if they click on the lines */
396 if (colour <= 0 || colour == 7)
397 return (-1);
399 SetAPen(viswindow->RPort,pen);
400 Flood (viswindow->RPort,1,x,y);
402 return (whatsquare(x,y));
405 void findangles (short *alpha, short *beta, short *gamma)
407 short x,y,z;
409 y = ((point.xyz [0] [0] [5]).y + (point.xyz [5] [5] [5]).y)/2;
410 z = ((point.xyz [0] [0] [5]).z + (point.xyz [5] [5] [5]).z)/2;
412 pitch ((short) -(*gamma = -angle (z,y,hypoten (z,y))));
414 x = ((point.xyz [0] [0] [5]).x + (point.xyz [5] [5] [5]).x)/2;
415 z = ((point.xyz [0] [0] [5]).z + (point.xyz [5] [5] [5]).z)/2;
417 yaw ((short) -(*beta = -angle (z,x,hypoten (z,x))));
419 x = ((point.xyz [0] [5] [0]).x + (point.xyz [5] [5] [5]).x)/2;
420 y = ((point.xyz [0] [5] [0]).y + (point.xyz [5] [5] [5]).y)/2;
422 *alpha = -angle (y,x,hypoten (y,x));