home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume37 / mgiccube / part02 < prev    next >
Encoding:
Text File  |  1993-05-15  |  60.9 KB  |  2,087 lines

  1. Newsgroups: comp.sources.misc
  2. From: fleurant@hri.com (P.Fleurant)
  3. Subject: v37i039:  magiccube - a cube simulator for X11/Motif, Part02/05
  4. Message-ID: <1993May10.212951.28595@sparky.imd.sterling.com>
  5. X-Md4-Signature: 11cffb8e3e79fa190532e258f24adf1d
  6. Date: Mon, 10 May 1993 21:29:51 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: fleurant@hri.com (P.Fleurant)
  10. Posting-number: Volume 37, Issue 39
  11. Archive-name: magiccube/part02
  12. Environment: X11, Motif, ANSI-C
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then feed it
  16. # into a shell via "sh file" or similar.  To overwrite existing files,
  17. # type "sh file -c".
  18. # Contents:  cube/cube.c
  19. # Wrapped by kent@sparky on Mon May 10 16:15:40 1993
  20. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  21. echo If this archive is complete, you will see the following message:
  22. echo '          "shar: End of archive 2 (of 5)."'
  23. if test -f 'cube/cube.c' -a "${1}" != "-c" ; then 
  24.   echo shar: Will not clobber existing file \"'cube/cube.c'\"
  25. else
  26.   echo shar: Extracting \"'cube/cube.c'\" \(58594 characters\)
  27.   sed "s/^X//" >'cube/cube.c' <<'END_OF_FILE'
  28. X/*
  29. X * cube.c: This is a cube solver and model of magic cube
  30. X *The following references were used:
  31. X   "The X Window System Programming And Applications with Xt
  32. X   OSF/MOTIF EDITION"
  33. X   by Douglas A Young 
  34. X   Prentice-Hall, 1990.
  35. X   ISBN 0-13-642786-3
  36. X
  37. X   "Mastering Rubik's Cube"
  38. X   by Don Taylor
  39. X   An Owl Book; Holt, Rinehart and Winston, New York, 1980
  40. X   ISBN 0-03-059941-5
  41. X
  42. X-------------------------------------------------------------------
  43. XCopyright (C) 1993 by Pierre A. Fleurant
  44. XPermission is granted to copy and distribute this program
  45. Xwithout charge, provided this copyright notice is included
  46. Xin the copy.
  47. XThis Software is distributed on an as-is basis. There will be
  48. XABSOLUTELY NO WARRANTY for any part of this software to work
  49. Xcorrect. In no case will the author be liable to you for damages
  50. Xcaused by the usage of this software.
  51. X-------------------------------------------------------------------
  52. X */
  53. X
  54. X#include "cube.h"
  55. X#include "common.h"
  56. X
  57. Xmain(argc, argv)
  58. X   int   argc;
  59. X   char *argv[];
  60. X{
  61. X  Widget        toplevel, canvas, framework, command, menubar;
  62. X  Widget        help_button,init_cubik, pristine_button, quit_button;
  63. X  Widget        solve_it_button, load_file_button;
  64. X  graphics_data data;
  65. X  int           n;
  66. X  Arg           wargs[10];
  67. X  widget_data   wdata;
  68. X
  69. X  /* init toolkit, create application context,
  70. X   * open display, create shell. This could be replaced 
  71. X   * by XtInitialize but we need appContext for other functions.
  72. X   */
  73. X  XtToolkitInitialize();
  74. X  appContext = XtCreateApplicationContext();
  75. X  xDisplay = XtOpenDisplay(appContext, "", argv[0], "MagicCb", NULL,0,
  76. X               &argc, argv);
  77. X  toplevel = XtAppCreateShell(appContext, "MagicCube",
  78. X                  applicationShellWidgetClass,
  79. X                  xDisplay,NULL,0);
  80. X  /* put title into arg list */
  81. X  /* set title */
  82. X  n=0;
  83. X  XtSetArg(wargs[n], XtNtitle,"magicCube"); n++;
  84. X  XtSetArg(wargs[n], XtNiconName,"magicCube"); n++;
  85. X  XtSetValues(toplevel,wargs, n);
  86. X  
  87. X  /* Create and Manage widgets */
  88. X  framework = XtCreateManagedWidget("framework", 
  89. X                                    xmFormWidgetClass, 
  90. X                                    toplevel, NULL, 0);
  91. X  /*
  92. X   * Create the column to hold the commands.
  93. X   */
  94. X  command = XtCreateManagedWidget("command", 
  95. X                                  xmRowColumnWidgetClass, 
  96. X                                  framework, NULL, 0);
  97. X  
  98. X  /* add help button and help callbacks */
  99. X  help_button = XtCreateManagedWidget("Help",
  100. X                                      xmPushButtonWidgetClass,
  101. X                                      command, NULL, 0);
  102. X  XtAddCallback(help_button, XmNactivateCallback,
  103. X                xs_help_callback, tophelp_str);
  104. X  
  105. X  /* add init_cubik button callback */
  106. X  init_cubik = XtCreateManagedWidget("Init Cube",
  107. X                                      xmPushButtonWidgetClass,
  108. X                                      command, NULL, 0);
  109. X  XtAddCallback(init_cubik, XmNactivateCallback,
  110. X                xcube_init_cubik, &wdata);
  111. X
  112. X  /*
  113. X   * Create and manage a menubar.
  114. X   */
  115. X  menubar = XmCreateMenuBar(command, "menubar", NULL, 0);
  116. X  XtManageChild(menubar); 
  117. X
  118. X  /* add solve it button and solve it button  callbacks */
  119. X  solve_it_button = XtCreateManagedWidget("Solve",
  120. X                                      xmPushButtonWidgetClass,
  121. X                                      command, NULL, 0);
  122. X  XtAddCallback(solve_it_button, XmNactivateCallback,
  123. X                taylor, &wdata);
  124. X  
  125. X  /* add load_file_button and load_file_button callbacks */
  126. X  load_file_button = XtCreateManagedWidget("Load File",
  127. X                                      xmPushButtonWidgetClass,
  128. X                                      command, NULL, 0);
  129. X  XtAddCallback(load_file_button, XmNactivateCallback,
  130. X                ldfile, &wdata);   /* load  file */
  131. X  
  132. X  /* add pristine and quit buttons */
  133. X  /* This should be the last twoo buttons */
  134. X  pristine_button = XtCreateManagedWidget("Pristine",
  135. X                      xmPushButtonWidgetClass,
  136. X                      command, NULL, 0);
  137. X  XtAddCallback(pristine_button, XmNactivateCallback,
  138. X                init_cube, &wdata);
  139. X  
  140. X  quit_button = XtCreateManagedWidget("Quit",
  141. X                                      xmPushButtonWidgetClass,
  142. X                                      command, NULL, 0);
  143. X  XtAddCallback(quit_button, XmNactivateCallback,
  144. X                quit_it, &wdata);
  145. X  
  146. X  
  147. X  /*
  148. X   * Create the drawing surface
  149. X   */
  150. X  canvas = XtCreateManagedWidget("canvas",
  151. X                                 xmDrawingAreaWidgetClass, 
  152. X                                 framework, NULL, 0);
  153. X
  154. X  XtAddEventHandler(canvas, ButtonPressMask, FALSE,
  155. X                    init_subplane_pattern, &wdata);
  156. X  /*
  157. X   * Create the menu from the description.
  158. X   */
  159. X  xss_create_menu_buttons(NULL, menubar, PulldownData,
  160. X                         XtNumber(PulldownData),&wdata);
  161. X  /* add the call backs for the canvas */
  162. X  XtAddCallback(canvas, XmNexposeCallback, refresh_cube, &wdata);
  163. X
  164. X  /* specify form */
  165. X  n = 0;
  166. X  XtSetArg(wargs[n], XmNtopAttachment,    XmATTACH_FORM);n++;
  167. X  XtSetArg(wargs[n], XmNbottomAttachment, XmATTACH_FORM);n++;
  168. X  XtSetArg(wargs[n], XmNleftAttachment,   XmATTACH_FORM);n++;
  169. X  XtSetValues(command, wargs, n);
  170. X
  171. X  n = 0;
  172. X  XtSetArg(wargs[n], XmNtopAttachment,   XmATTACH_FORM);  n++;
  173. X  XtSetArg(wargs[n], XmNbottomAttachment,XmATTACH_FORM);  n++;
  174. X  XtSetArg(wargs[n], XmNleftAttachment,  XmATTACH_WIDGET);n++;
  175. X  XtSetArg(wargs[n], XmNleftWidget,     command);         n++;
  176. X  XtSetArg(wargs[n], XmNrightAttachment,  XmATTACH_FORM); n++;
  177. X  XtSetValues(canvas, wargs, n);
  178. X
  179. X  /*
  180. X   * Initialize the graphics buffer and other data.
  181. X   */
  182. X  /* init wdata stuff */
  183. X  wdata.toplevel = toplevel;
  184. X  wdata.canvas = canvas;
  185. X  wdata.graph_pointer = &data;
  186. X  init_data(canvas, &data, &wdata);
  187. X
  188. X  /*
  189. X   * Register the seed colors as new patterns 
  190. X   * in preparation for pixmap browser
  191. X   */
  192. X  for(n=0; n < XtNumber(seed_color); n++)
  193. X    xs_register_pattern(toplevel, seed_color[n], fg_bitmap,
  194. X            fg_width, fg_height);
  195. X  
  196. X  XtRealizeWidget(toplevel);
  197. X  init_cube(canvas, &wdata, NULL);
  198. X
  199. X  /*
  200. X   * Establish a passive grab on the drawing canvas window.
  201. X   */
  202. X  XGrabButton(XtDisplay(canvas), AnyButton, AnyModifier, 
  203. X              XtWindow(canvas), TRUE, 
  204. X              ButtonPressMask | ButtonMotionMask | 
  205. X              ButtonReleaseMask,
  206. X              GrabModeAsync, GrabModeAsync,
  207. X              XtWindow(canvas), 
  208. X              XCreateFontCursor(XtDisplay(canvas),
  209. X                                XC_crosshair));
  210. X  XtInstallAllAccelerators(canvas,framework);
  211. X  XtAppMainLoop(appContext);
  212. X}
  213. X
  214. Xinit_data(w, data, wdata)
  215. X     Widget          w;
  216. X     graphics_data  *data;
  217. X     widget_data    *wdata;
  218. X{
  219. X  XGCValues       values;
  220. X  Arg             wargs[5];
  221. X  int             i,j,n;
  222. X  XPoint          short_face[NUM_SUBPLANES][5];
  223. X  double_XPoint   tmp0_face[NUM_SUBPLANES][5];
  224. X  
  225. X  /*
  226. X   * Get the colors the user has set for the widget. 
  227. X   */
  228. X  XtSetArg(wargs[0], XtNforeground, &data->foreground);
  229. X  XtSetArg(wargs[1], XtNbackground, &data->background);
  230. X  XtGetValues(w, wargs,2);
  231. X  /*
  232. X   * Fill in the values structure
  233. X   */  
  234. X  values.foreground = data->foreground;
  235. X  values.background = data->background;
  236. X  values.fill_style = FillTiled;
  237. X  /*
  238. X   * Get the GC used for lines in the cube
  239. X   */
  240. X  data->gc_line = XtGetGC(w, 
  241. X              GCForeground | GCBackground | GCFillStyle,
  242. X              &values);
  243. X  /* 
  244. X   * Get a gc for each subface_color. This will be used
  245. X   * when using XFillPolygon.
  246. X   */
  247. X  for(i=0;i<9;i++){
  248. X    for(j=0;j<6;j++){
  249. X      values.foreground = xss_get_pixel_by_name(w,seed_color[j]);
  250. X      values.background = xss_get_pixel_by_name(w,seed_color[j]);
  251. X      values.fill_style = FillTiled;
  252. X      wdata->subface_gc[i][j] =    XtGetGC(w,
  253. X                    GCForeground | GCBackground | GCFillStyle,
  254. X                    &values);
  255. X    }
  256. X  }
  257. X  /* init pixmap stuff */
  258. X  /*
  259. X   * Get the size of the drawing area.
  260. X   */
  261. X  n=0;
  262. X  XtSetArg(wargs[n], XtNwidth,  &wdata->width); n++;
  263. X  XtSetArg(wargs[n], XtNheight, &wdata->height); n++;
  264. X  XtGetValues(w, wargs, n); 
  265. X  
  266. X  /*
  267. X   * Create a default, writable, graphics context.
  268. X   */
  269. X  wdata->gc = XCreateGC(XtDisplay(w),
  270. X            DefaultRootWindow(XtDisplay(w)),
  271. X            NULL, NULL); 
  272. X  /*
  273. X   *  Initialize the pixmap to NULL.
  274. X   */
  275. X  wdata->pix = NULL;
  276. X
  277. X  /* convert seed_face from CoordModePrevious to CoordModeOrigin */
  278. X  prev_to_org(seed_face);
  279. X  facecpy(cubik_face,seed_face); /* init cubik face: prestine */
  280. X  /* init */
  281. X  cubikcpy(front,seed_front);
  282. X  cubikcpy(left,seed_left);
  283. X  cubikcpy(right,seed_right);
  284. X  cubikcpy(back,seed_back);
  285. X  cubikcpy(top,seed_top);
  286. X  cubikcpy(bottom,seed_bottom);
  287. X  update_cubik(wdata);
  288. X
  289. X  /* The following are used for align_subfaces in init_cubik */
  290. X  init_cornermap();
  291. X  init_edgemap(); 
  292. X
  293. X  /* init regions for init_subplane_pattern callback */
  294. X  /* generate a prestine short_face for 
  295. X  /* values to regular XPoint array */
  296. X  facecpy(rot_face,seed_face);
  297. X  projface(tmp0_face,rot_face);
  298. X  norm_face(tmp0_face);
  299. X  shortface(short_face,tmp0_face);
  300. X  for(i=0; i<9; i++) 
  301. X    wdata->init_cubik_region[i] = XPolygonRegion(short_face[i],XtNumber(short_face[i]),WindingRule);
  302. X}
  303. X
  304. Xvoid quit_it(w, client_data, call_data)
  305. X     Widget   w;
  306. X     char    *client_data;
  307. X     caddr_t  call_data;
  308. X{
  309. X  XtCloseDisplay(XtDisplay(w));
  310. X  exit(0);
  311. X}
  312. X
  313. Xvoid clear_draw(w, wdata, call_data)
  314. X     Widget       w;
  315. X     widget_data *wdata;
  316. X     caddr_t      call_data;
  317. X{
  318. X  /* Clear the canvas */
  319. X  XClearArea(XtDisplay(wdata->toplevel), XtWindow(wdata->canvas), 0, 0, 0, 0, FALSE);
  320. X}
  321. X
  322. Xvoid xs_rot_face(rotated_face,src_face,size_rot_face,degrees)
  323. X     double_XPoint rotated_face[],*src_face;
  324. X     int size_rot_face;
  325. X     double degrees; 
  326. X{
  327. X  /* rotation of axis with fixed origin 
  328. X     x' = x cos(r) + y sin(r)
  329. X     y' = y cos(r) - x sin(r)
  330. X     
  331. X     180degree = PI radians
  332. X
  333. X     degrees:
  334. X
  335. X     /----------
  336. X     |     ^
  337. X     |     |
  338. X     |    /
  339. X     |   / degrees,      
  340. X     |  /  
  341. X     |--         
  342. X     |         
  343. X     |         
  344. X
  345. X     
  346. X   */
  347. X
  348. X  double_XPoint *tmp_xpoint;
  349. X  int i;
  350. X  double radians;
  351. X
  352. X  tmp_xpoint = src_face;
  353. X  radians = degrees * M_PI / 180.0;
  354. X  for(i=0; i < size_rot_face; i++) {
  355. X    rotated_face[i].x = (tmp_xpoint->x * cos(radians) + tmp_xpoint->y * sin(radians));
  356. X    rotated_face[i].y = (tmp_xpoint->y * cos(radians) - tmp_xpoint->x * sin(radians));
  357. X    rotated_face[i].z =  tmp_xpoint->z; 
  358. X    tmp_xpoint++;
  359. X  };
  360. X
  361. X}
  362. X
  363. Xvoid xs_spin_face(spin_face,src_face,size_spin_face,degrees)
  364. X     double_XPoint spin_face[],*src_face;
  365. X     int size_spin_face;
  366. X     double degrees; 
  367. X{
  368. X  /* rotation of z-axis with fixed origin 
  369. X   */
  370. X
  371. X  double_XPoint *tmp_xpoint;
  372. X  int i;
  373. X  double radians;
  374. X
  375. X  tmp_xpoint = src_face;
  376. X  radians = degrees * M_PI / 180.0;
  377. X  for(i=0; i < size_spin_face; i++) {
  378. X    spin_face[i].x = (tmp_xpoint->x * cos(radians) + tmp_xpoint->z * sin(radians));
  379. X    spin_face[i].y =  tmp_xpoint->y;
  380. X    spin_face[i].z = (tmp_xpoint->z * cos(radians) - tmp_xpoint->x * sin(radians));
  381. X    tmp_xpoint++;
  382. X  };
  383. X
  384. X}
  385. X
  386. Xvoid xs_flip_face(flip_face,src_face,size_flip_face,degrees)
  387. X     double_XPoint flip_face[],*src_face;
  388. X     int size_flip_face;
  389. X     double degrees; 
  390. X{
  391. X  /* rotation of x-axis with fixed origin 
  392. X   */
  393. X
  394. X  double_XPoint *tmp_xpoint;
  395. X  int i;
  396. X  double radians;
  397. X
  398. X  tmp_xpoint = src_face;
  399. X  radians = degrees * M_PI / 180.0;
  400. X  for(i=0; i < size_flip_face; i++) {
  401. X    flip_face[i].x =  tmp_xpoint->x;
  402. X    flip_face[i].y = (tmp_xpoint->y * cos(radians) + tmp_xpoint->z * sin(radians));
  403. X    flip_face[i].z = (tmp_xpoint->z * cos(radians) - tmp_xpoint->y * sin(radians));
  404. X    tmp_xpoint++;
  405. X  };
  406. X
  407. X}
  408. X
  409. Xvoid norm_face(dest_face)
  410. X     double_XPoint dest_face[NUM_SUBPLANES][5];
  411. X{
  412. X  /*old way: Normalize the 'rotated face' */
  413. X  /*new: just shift over into 'center' of window */
  414. X  int i,j;
  415. X
  416. X  for (i=0;i<=NUM_SUBPLANES-1;i++)
  417. X    for(j=0;j<=4;j++){
  418. X      dest_face[i][j].x += WINDOW_CENTER_X;
  419. X      dest_face[i][j].y += WINDOW_CENTER_Y;
  420. X    }
  421. X  
  422. X}
  423. X
  424. Xvoid facecpy(dest_face,src_face)
  425. X     double_XPoint dest_face[NUM_SUBPLANES][5],src_face[NUM_SUBPLANES][5];
  426. X{
  427. X  int i,j;
  428. X  
  429. X  for(i=0;i<=NUM_SUBPLANES-1;i++)
  430. X    for(j=0;j<=4;j++){
  431. X      dest_face[i][j].x = src_face[i][j].x;
  432. X      dest_face[i][j].y = src_face[i][j].y;
  433. X      dest_face[i][j].z = src_face[i][j].z;
  434. X    }
  435. X}
  436. X
  437. Xvoid cubikcpy(dest_cubik,src_cubik)
  438. X     int dest_cubik[NUM_CUBIKPLANES],src_cubik[NUM_CUBIKPLANES];
  439. X{
  440. X  int i;
  441. X  
  442. X  for(i=0;i<=NUM_CUBIKPLANES-1;i++)
  443. X    dest_cubik[i] = src_cubik[i];
  444. X}
  445. X
  446. Xvoid lefthand_twist(src_cubik)
  447. X     int src_cubik[NUM_CUBIKPLANES];
  448. X{
  449. X  int temp_subplanes[NUM_CUBIKPLANES];
  450. X
  451. X  temp_subplanes[0]  = src_cubik[2];
  452. X  temp_subplanes[1]  = src_cubik[5];
  453. X  temp_subplanes[2]  = src_cubik[8];
  454. X  temp_subplanes[3]  = src_cubik[1];
  455. X  temp_subplanes[4]  = src_cubik[4];
  456. X  temp_subplanes[5]  = src_cubik[7];
  457. X  temp_subplanes[6]  = src_cubik[0];
  458. X  temp_subplanes[7]  = src_cubik[3];
  459. X  temp_subplanes[8]  = src_cubik[6];
  460. X  cubikcpy(src_cubik,temp_subplanes); 
  461. X
  462. X}
  463. X
  464. Xvoid righthand_twist(src_cubik)
  465. X     int src_cubik[NUM_CUBIKPLANES];
  466. X{
  467. X  int temp_subplanes[NUM_CUBIKPLANES];
  468. X
  469. X  temp_subplanes[0]  = src_cubik[6];
  470. X  temp_subplanes[1]  = src_cubik[3];
  471. X  temp_subplanes[2]  = src_cubik[0];
  472. X  temp_subplanes[3]  = src_cubik[7];
  473. X  temp_subplanes[4]  = src_cubik[4];
  474. X  temp_subplanes[5]  = src_cubik[1];
  475. X  temp_subplanes[6]  = src_cubik[8];
  476. X  temp_subplanes[7]  = src_cubik[5];
  477. X  temp_subplanes[8]  = src_cubik[2];
  478. X  cubikcpy(src_cubik,temp_subplanes); 
  479. X
  480. X}
  481. X
  482. Xvoid update_cubik(wdata)
  483. X     widget_data   *wdata;
  484. X{
  485. X  /* This updates xxx[9,10,...20]
  486. X   * interms of xxx[0,1,...8].
  487. X   * This is called after cubik() in cubik_xxxx(), and in align_subfaces
  488. X   *      
  489. X   */
  490. X
  491. X  int i;
  492. X  
  493. X  front[9]  = top[0];
  494. X  front[10] = top[1];
  495. X  front[11] = top[2];
  496. X  front[12] = right[0];
  497. X  front[13] = right[3];
  498. X  front[14] = right[6];
  499. X
  500. X  front[15] = bottom[0];
  501. X  front[16] = bottom[1];
  502. X  front[17] = bottom[2];
  503. X
  504. X  front[18] = left[0];
  505. X  front[19] = left[3];
  506. X  front[20] = left[6];
  507. X
  508. X  
  509. X  left[9]  = top[0];
  510. X  left[10] = top[3];
  511. X  left[11] = top[6];
  512. X
  513. X  left[12] = front[0];
  514. X  left[13] = front[3];
  515. X  left[14] = front[6];
  516. X
  517. X  left[15] = bottom[0];
  518. X  left[16] = bottom[3];
  519. X  left[17] = bottom[6];
  520. X
  521. X  left[18] = back[0];
  522. X  left[19] = back[3];
  523. X  left[20] = back[6];
  524. X  
  525. X
  526. X  right[9]  = top[2];
  527. X  right[10] = top[5];
  528. X  right[11] = top[8];
  529. X
  530. X  right[12] = front[2];
  531. X  right[13] = front[5];
  532. X  right[14] = front[8];
  533. X
  534. X  right[15] = bottom[2];
  535. X  right[16] = bottom[5];
  536. X  right[17] = bottom[8];
  537. X
  538. X  right[18] = back[2];
  539. X  right[19] = back[5];
  540. X  right[20] = back[8];
  541. X  
  542. X
  543. X  back[9]  = top[6];
  544. X  back[10] = top[7];
  545. X  back[11] = top[8];
  546. X
  547. X  back[12] = right[2];
  548. X  back[13] = right[5];
  549. X  back[14] = right[8];
  550. X
  551. X  back[15] = left[2];
  552. X  back[16] = left[5];
  553. X  back[17] = left[8];
  554. X
  555. X  back[18] = bottom[6];
  556. X  back[19] = bottom[7];
  557. X  back[20] = bottom[8];
  558. X  
  559. X
  560. X  top[9]  = front[0];
  561. X  top[10] = front[1];
  562. X  top[11] = front[2];
  563. X
  564. X  top[12] = right[0];
  565. X  top[13] = right[1];
  566. X  top[14] = right[2];
  567. X
  568. X  top[15] = left[0];
  569. X  top[16] = left[1];
  570. X  top[17] = left[2];
  571. X
  572. X  top[18] = back[0];
  573. X  top[19] = back[1];
  574. X  top[20] = back[2];
  575. X  
  576. X
  577. X  bottom[9]  = front[6];
  578. X  bottom[10] = front[7];
  579. X  bottom[11] = front[8];
  580. X
  581. X  bottom[12] = right[6];
  582. X  bottom[13] = right[7];
  583. X  bottom[14] = right[8];
  584. X
  585. X  bottom[15] = left[6];
  586. X  bottom[16] = left[7];
  587. X  bottom[17] = left[8];
  588. X
  589. X  bottom[18] = back[6];
  590. X  bottom[19] = back[7];
  591. X  bottom[20] = back[8];
  592. X
  593. X  /* update subface_side[][] */
  594. X  for(i=0; i<9; i++){
  595. X    wdata->subface_side[i][0] = front[i]    / 9;
  596. X    wdata->subface_side[i][1] = left[i]     / 9;
  597. X    wdata->subface_side[i][2] = right[i]    / 9;
  598. X    wdata->subface_side[i][3] = back[i]     / 9;
  599. X    wdata->subface_side[i][4] = top[i]      / 9;
  600. X    wdata->subface_side[i][5] = bottom[i]   / 9;
  601. X  }
  602. X}
  603. X
  604. Xvoid prev_to_org(seed_data)
  605. X     double_XPoint seed_data[NUM_SUBPLANES][5];
  606. X{
  607. X  double_XPoint tmp_data[NUM_SUBPLANES][5];
  608. X  int i,j;
  609. X
  610. X  for(i=0;i<=NUM_SUBPLANES-1;i++){
  611. X    tmp_data[i][0].x = seed_data[i][0].x;
  612. X    tmp_data[i][1].x = seed_data[i][0].x + seed_data[i][1].x;
  613. X    tmp_data[i][2].x = seed_data[i][0].x + seed_data[i][1].x + seed_data[i][2].x;
  614. X    tmp_data[i][3].x = seed_data[i][0].x + seed_data[i][1].x + seed_data[i][2].x + seed_data[i][3].x;
  615. X    tmp_data[i][4].x = seed_data[i][0].x + seed_data[i][1].x + seed_data[i][2].x + seed_data[i][3].x + seed_data[i][4].x;
  616. X    
  617. X    tmp_data[i][0].y = seed_data[i][0].y;
  618. X    tmp_data[i][1].y = seed_data[i][0].y + seed_data[i][1].y;
  619. X    tmp_data[i][2].y = seed_data[i][0].y + seed_data[i][1].y + seed_data[i][2].y;
  620. X    tmp_data[i][3].y = seed_data[i][0].y + seed_data[i][1].y + seed_data[i][2].y + seed_data[i][3].y;
  621. X    tmp_data[i][4].y = seed_data[i][0].y + seed_data[i][1].y + seed_data[i][2].y + seed_data[i][3].y + seed_data[i][4].y;
  622. X    
  623. X    tmp_data[i][0].z = seed_data[i][0].z;
  624. X    tmp_data[i][1].z = seed_data[i][0].z + seed_data[i][1].z;
  625. X    tmp_data[i][2].z = seed_data[i][0].z + seed_data[i][1].z + seed_data[i][2].z;
  626. X    tmp_data[i][3].z = seed_data[i][0].z + seed_data[i][1].z + seed_data[i][2].z + seed_data[i][3].z;
  627. X    tmp_data[i][4].z = seed_data[i][0].z + seed_data[i][1].z + seed_data[i][2].z + seed_data[i][3].z + seed_data[i][4].z;
  628. X  }
  629. X  facecpy(seed_data,tmp_data);
  630. X}
  631. X  
  632. Xvoid projface(dest_face,src_face)
  633. X     double_XPoint dest_face[NUM_SUBPLANES][5];
  634. X     double_XPoint src_face[NUM_SUBPLANES][5];
  635. X{
  636. X  double_XPoint tmp_face[NUM_SUBPLANES][5];
  637. X  int i,j;
  638. X  
  639. X  /* Project src_face onto the z=PROJECTION_DEPTH plane.
  640. X   */
  641. X  for(i=0;i<=NUM_SUBPLANES-1;i++)
  642. X    for(j=0;j<=4;j++){
  643. X      /* project onto z=PROJECTION_DEPTH plane */
  644. X      /* project with cube at origin, then shift back */
  645. X      dest_face[i][j].x = (src_face[i][j].x-MR_X-FACE0_WIDTH*1.5)/(src_face[i][j].z/PROJECTION_DEPTH +1)
  646. X                                          +(MR_X+FACE0_WIDTH*1.5);
  647. X      dest_face[i][j].y = (src_face[i][j].y-MR_Y-FACE0_HEIGHT*1.5)/(src_face[i][j].z/PROJECTION_DEPTH +1)
  648. X                                          +(MR_Y+FACE0_HEIGHT*1.5);
  649. X
  650. X      dest_face[i][j].z = src_face[i][j].z;
  651. X    }
  652. X}
  653. X
  654. Xvoid shortface(dest_face,src_face)
  655. X     XPoint dest_face[NUM_SUBPLANES][5];
  656. X     double_XPoint src_face[NUM_SUBPLANES][5];
  657. X{
  658. X  int i,j;
  659. X  
  660. X  /* Convert the double_XPoint array to a plain XPoint array.
  661. X   */
  662. X  for(i=0;i<=NUM_SUBPLANES-1;i++)
  663. X    for(j=0;j<=4;j++){
  664. X      /* Ignore the z plane */
  665. X      dest_face[i][j].x = (short) floor(src_face[i][j].x + .5);
  666. X      dest_face[i][j].y = (short) floor(src_face[i][j].y + .5);
  667. X    }
  668. X}
  669. X
  670. Xvoid depth_sort(draw_order,src_face)
  671. X     int draw_order[NUM_SUBPLANES];
  672. X     double_XPoint src_face[NUM_SUBPLANES][5];
  673. X{
  674. X  struct {
  675. X    double z_value;
  676. X    int    subplane_number;
  677. X  } sort_array[NUM_SUBPLANES];
  678. X  int gap,i,j,subplane_number_temp;
  679. X  double z_temp;
  680. X  
  681. X  /* Depth-sort algorthm for determining which faces are 
  682. X     to be drawn. 
  683. X     Draw_order gives the order of how the subplanes are to be drawn,
  684. X     given the subplane number. 0 is last, NUM_SUBPLANES-1 is first. The 
  685. X     side with the deepest z value gets drawn first.
  686. X     
  687. X     The z value of the center subface of each side is 
  688. X     sorted into asending order. 
  689. X     Then draw_order is set accordingly.
  690. X     */
  691. X  
  692. X  /* init sort_array
  693. X   */
  694. X  for(i=0;i<=NUM_SUBPLANES-1;i++){
  695. X    sort_array[i].z_value = (src_face[i][0].z + src_face[i][2].z)/2; /* center point subplane */
  696. X    sort_array[i].subplane_number = i;
  697. X  }
  698. X  
  699. X  /* use Shell sort method to sort it out */
  700. X  for(gap = NUM_SUBPLANES/2; gap > 0; gap /= 2)
  701. X    for(i = gap; i < NUM_SUBPLANES; i++)
  702. X      for(j = i-gap;j >= 0 && sort_array[j].z_value > sort_array[j+gap].z_value;j -= gap){
  703. X    /* swap `em */
  704. X    z_temp = sort_array[j].z_value;
  705. X    sort_array[j].z_value = sort_array[j+gap].z_value;
  706. X    sort_array[j+gap].z_value = z_temp;
  707. X    subplane_number_temp = sort_array[j].subplane_number;
  708. X    sort_array[j].subplane_number = sort_array[j+gap].subplane_number;
  709. X    sort_array[j+gap].subplane_number = subplane_number_temp;
  710. X      }
  711. X  /* Copy the ascending order into draw_order.
  712. X   */
  713. X  for(i=0;i<NUM_SUBPLANES;i++)
  714. X    draw_order[i]= sort_array[i].subplane_number;
  715. X}
  716. X
  717. Xvoid draw_it(dpy, win, wdata, short_face,draw_order)
  718. X     Display *dpy;
  719. X     Window   win;
  720. X     widget_data *wdata;
  721. X     XPoint short_face[NUM_SUBPLANES][5];
  722. X     int draw_order[NUM_SUBPLANES];
  723. X{
  724. X  int i,k,l;
  725. X  Arg wargs[10];
  726. X
  727. X  /* process other events first */
  728. X  check_events();
  729. X
  730. X  /*
  731. X   *  Get the new window size.
  732. X   */
  733. X  XtSetArg(wargs[0], XtNwidth,  &wdata->width); 
  734. X  XtSetArg(wargs[1], XtNheight, &wdata->height);
  735. X  XtGetValues(wdata->canvas, wargs, 2);
  736. X
  737. X  /*
  738. X   *  Free the old pixmap and create a new pixmap 
  739. X   *  the size of the window.
  740. X   */
  741. X  if(wdata->pix)
  742. X    XFreePixmap(XtDisplay(wdata->canvas), wdata->pix);
  743. X  wdata->pix= XCreatePixmap(XtDisplay(wdata->canvas),
  744. X                DefaultRootWindow(XtDisplay(wdata->canvas)),
  745. X                (Dimension)wdata->width, (Dimension)wdata->height, 
  746. X                DefaultDepthOfScreen(XtScreen(wdata->canvas)));
  747. X  XSetForeground(XtDisplay(wdata->canvas), wdata->gc,
  748. X                 WhitePixelOfScreen(XtScreen(wdata->canvas)));
  749. X  XFillRectangle(XtDisplay(wdata->canvas), wdata->pix, wdata->gc, 0, 0, 
  750. X                 (Dimension)wdata->width,  (Dimension)wdata->height);
  751. X  /*
  752. X   * draw the new cube
  753. X   */
  754. X  /* Draw all the subplanes in the draw order */
  755. X  for(i=NUM_SUBPLANES-1;i>=0;i--){
  756. X    k = draw_order[i] % 9;
  757. X    l = draw_order[i] / 9;
  758. X    XFillPolygon(dpy, wdata->pix, wdata->subface_gc[k][l],
  759. X         short_face[draw_order[i]], XtNumber(short_face[draw_order[i]]),
  760. X         Nonconvex,CoordModeOrigin);
  761. X    XDrawLines(dpy, wdata->pix, wdata->graph_pointer->gc_line,
  762. X           short_face[draw_order[i]], XtNumber(short_face[draw_order[i]]),
  763. X           CoordModeOrigin);
  764. X  }
  765. X  if(XtIsRealized(wdata->canvas) && Draw_Enable)
  766. X    XCopyArea(XtDisplay(wdata->canvas), wdata->pix, XtWindow(wdata->canvas), wdata->gc, 
  767. X          0, 0, wdata->width, wdata->height, 
  768. X          0, 0);
  769. X}
  770. X
  771. Xvoid rot_it(w, wdata, call_data)
  772. X     Widget   w;
  773. X     widget_data *wdata;
  774. X     caddr_t  call_data;
  775. X{
  776. X  Display *dpy = XtDisplay(wdata->canvas);
  777. X  Window   win = XtWindow(wdata->canvas);
  778. X  double_XPoint   tmp0_face[NUM_SUBPLANES][5];
  779. X  XPoint short_face[NUM_SUBPLANES][5];
  780. X  int draw_order[NUM_SUBPLANES];
  781. X  int i;
  782. X
  783. X  rot_angle += Delta_Angle;
  784. X  rot_angle %= 360;
  785. X/*  printf("rot=%d;  spin=%d;  flip=%d;\n",rot_angle,spin_angle,flip_angle);*/
  786. X
  787. X  for(i=0;i<=NUM_SUBPLANES-1;i++)  /* NUM_SUBPLANES subplanes  */ 
  788. X    xs_rot_face(tmp0_face[i],rot_face[i],XtNumber(tmp0_face[i]),Delta_Angle);
  789. X  facecpy(rot_face,tmp0_face);
  790. X  projface(tmp0_face,rot_face);
  791. X  norm_face(tmp0_face); 
  792. X  depth_sort(draw_order,tmp0_face);
  793. X  shortface(short_face,tmp0_face);
  794. X  draw_it(dpy, win, wdata, short_face,draw_order);
  795. X}
  796. X
  797. Xvoid flip_it(w, wdata, call_data)
  798. X     Widget   w;
  799. X     widget_data *wdata;
  800. X     caddr_t  call_data;
  801. X{
  802. X  Display *dpy = XtDisplay(wdata->canvas);
  803. X  Window   win = XtWindow(wdata->canvas);
  804. X  double_XPoint   tmp0_face[NUM_SUBPLANES][5];
  805. X  XPoint short_face[NUM_SUBPLANES][5];
  806. X  int draw_order[NUM_SUBPLANES];
  807. X  int i;
  808. X
  809. X  flip_angle += Delta_Angle;
  810. X  flip_angle %= 360;
  811. X/*  printf("rot=%d;  spin=%d;  flip=%d;\n",rot_angle,spin_angle,flip_angle);*/
  812. X
  813. X  for(i=0;i<=NUM_SUBPLANES-1;i++)  /* NUM_SUBPLANES subplanes  */ 
  814. X    xs_flip_face(tmp0_face[i],rot_face[i],XtNumber(tmp0_face[i]),Delta_Angle);
  815. X  facecpy(rot_face,tmp0_face);
  816. X  projface(tmp0_face,rot_face);
  817. X  norm_face(tmp0_face);
  818. X  depth_sort(draw_order,tmp0_face);
  819. X  shortface(short_face,tmp0_face);
  820. X  draw_it(dpy, win, wdata, short_face,draw_order);
  821. X}
  822. X
  823. Xvoid spin_it(w, wdata, call_data)
  824. X     Widget   w;
  825. X     widget_data *wdata;
  826. X     caddr_t  call_data;
  827. X{
  828. X  Display *dpy = XtDisplay(wdata->canvas);
  829. X  Window   win = XtWindow(wdata->canvas);
  830. X  double_XPoint   tmp0_face[NUM_SUBPLANES][5];
  831. X  XPoint short_face[NUM_SUBPLANES][5];
  832. X  int draw_order[NUM_SUBPLANES];
  833. X  int i;
  834. X
  835. X  spin_angle += Delta_Angle;
  836. X  spin_angle %= 360;
  837. X/*  printf("rot=%d;  spin=%d;  flip=%d;\n",rot_angle,spin_angle,flip_angle);*/
  838. X
  839. X  for(i=0;i<=NUM_SUBPLANES-1;i++)  /* NUM_SUBPLANES subplanes  */ 
  840. X    xs_spin_face(tmp0_face[i],rot_face[i],XtNumber(tmp0_face[i]),Delta_Angle);
  841. X  facecpy(rot_face,tmp0_face);
  842. X  projface(tmp0_face,rot_face);
  843. X  norm_face(tmp0_face);
  844. X  depth_sort(draw_order,tmp0_face);
  845. X  shortface(short_face,tmp0_face);
  846. X  draw_it(dpy, win, wdata, short_face,draw_order);
  847. X}
  848. X
  849. Xvoid init_cube(w, wdata, call_data)
  850. X     Widget   w;
  851. X     widget_data *wdata;
  852. X     caddr_t  call_data;
  853. X{
  854. X  Display *dpy = XtDisplay(wdata->canvas);
  855. X  Window   win = XtWindow(wdata->canvas);
  856. X  XPoint short_face[NUM_SUBPLANES][5];
  857. X  double_XPoint tmp0_face[NUM_SUBPLANES][5];
  858. X  int draw_order[NUM_SUBPLANES];
  859. X  XGCValues       values;
  860. X  int i,j;
  861. X  
  862. X  /* Init subplane_side[][] */
  863. X  /* This is used for init_cubik. */
  864. X  for(i=0; i < 6; i++)
  865. X    for(j=0; j < 9; j++)
  866. X      wdata->subface_side[j][i] = i;
  867. X  
  868. X  /* reset angles */
  869. X  rot_angle = 0;
  870. X  spin_angle = 0;
  871. X  flip_angle = 0;
  872. X  /* re-init subplanes' gc */
  873. X  /* 
  874. X   * Change gc for each subface_color. This will be used
  875. X   * when using XFillPolygon.
  876. X   */
  877. X  for(i=0;i<9;i++){
  878. X    for(j=0;j<6;j++){
  879. X      values.foreground = xss_get_pixel_by_name(w,seed_color[j]);
  880. X      values.background = xss_get_pixel_by_name(w,seed_color[j]);
  881. X      values.fill_style = FillTiled;
  882. X      wdata->subface_gc[i][j] = XtGetGC(w, 
  883. X                    GCForeground | GCBackground | GCFillStyle,
  884. X                    &values);
  885. X    }
  886. X  }
  887. X  
  888. X  /* init cubik face: prestine */
  889. X  facecpy(cubik_face,seed_face); 
  890. X  /* init */
  891. X  cubikcpy(front,seed_front);
  892. X  cubikcpy(left,seed_left);
  893. X  cubikcpy(right,seed_right);
  894. X  cubikcpy(back,seed_back);
  895. X  cubikcpy(top,seed_top);
  896. X  cubikcpy(bottom,seed_bottom);
  897. X  update_cubik(wdata);
  898. X  /* display the seed face only */
  899. X  /* values to regular XPoint array */
  900. X  facecpy(rot_face,seed_face);
  901. X  projface(tmp0_face,rot_face);
  902. X  norm_face(tmp0_face);
  903. X  depth_sort(draw_order,tmp0_face);
  904. X  shortface(short_face,tmp0_face);
  905. X  draw_it(dpy, win, wdata, short_face,draw_order);
  906. X}
  907. X
  908. Xvoid refresh_cube(w, wdata, call_data)
  909. X     Widget          w;
  910. X     widget_data     *wdata;
  911. X     XmDrawingAreaCallbackStruct    *call_data;
  912. X{
  913. X  XExposeEvent  *event = (XExposeEvent *) call_data->event;
  914. X  /*
  915. X   * Extract the exposed area from the event and copy
  916. X   * from the saved pixmap to the window.
  917. X   */
  918. X  if(XtIsRealized(wdata->canvas) && Draw_Enable)
  919. X    XCopyArea(XtDisplay(w), wdata->pix, XtWindow(w), wdata->gc, 
  920. X          event->x, event->y, event->width, event->height, 
  921. X          event->x, event->y);
  922. X}
  923. X
  924. X/*    cubik_front, cubik_left,...callbacks 
  925. X *    These operate on the cube to rotate only the
  926. X *    1/3 of the cube specified. 
  927. X *    Cubik is called 3 times for 3-30degree turns.
  928. X */
  929. Xvoid cubik_front(w,wdata,call_data)
  930. X     Widget   w;
  931. X     widget_data *wdata;
  932. X     caddr_t  call_data;
  933. X{
  934. X  int i;
  935. X  int temp[NUM_CUBIKPLANES];
  936. X
  937. X  for(i=1;i<=3;i++)
  938. X    cubik(w,wdata,call_data,front,xs_rot_face);
  939. X
  940. X  /* Now points in plane 0 are in old plane 6,
  941. X   * points in plane 1, are in old plane 3 etc....
  942. X   * so the data must be swapped so that another 
  943. X   * op starts with the correct 'inited' cube.
  944. X   * Also the ->subface_gc[k][l] graphic contexts 
  945. X   * must be swapped.
  946. X   *  Instead of actually moving double_Xpoint and 
  947. X   * ->subface_gc[k][l] data 
  948. X   * around, we just transform front,
  949. X   * left etc.
  950. X   * After a cubik_front operation, front 
  951. X   * and the OTHER xxxx_subplane arrays that are affected
  952. X   * are updated-transformed.
  953. X   */
  954. X  lefthand_twist(front);
  955. X
  956. X  /* left, top, right, and bottom are affected */
  957. X  temp[0] = left[0];
  958. X  temp[3] = left[3];
  959. X  temp[6] = left[6];
  960. X
  961. X  left[0] = top[2];
  962. X  left[3] = top[1];
  963. X  left[6] = top[0];
  964. X
  965. X  top[0] = right[0]; 
  966. X  top[1] = right[3];
  967. X  top[2] = right[6];
  968. X
  969. X  right[0] = bottom[2];
  970. X  right[3] = bottom[1];
  971. X  right[6] = bottom[0];
  972. X
  973. X  bottom[0] = temp[0];
  974. X  bottom[1] = temp[3];
  975. X  bottom[2] = temp[6];
  976. X
  977. X  update_cubik(wdata);
  978. X}
  979. X
  980. Xvoid cubik_left(w,wdata,call_data)
  981. X     Widget   w;
  982. X     widget_data *wdata;
  983. X     caddr_t  call_data;
  984. X{
  985. X  int i;
  986. X  int temp[NUM_CUBIKPLANES];
  987. X
  988. X  for(i=1;i<=3;i++)
  989. X    cubik(w,wdata,call_data,left,xs_flip_face);
  990. X  
  991. X  /* Now points in plane 0 are in old plane 6,
  992. X   * points in plane 1, are in old plane 3 etc....
  993. X   */
  994. X  righthand_twist(left);
  995. X
  996. X  /* other planes affected */
  997. X  temp[0] = front[0];
  998. X  temp[3] = front[3];
  999. X  temp[6] = front[6];
  1000. X
  1001. X  front[0] = bottom[0];
  1002. X  front[3] = bottom[3];
  1003. X  front[6] = bottom[6];
  1004. X
  1005. X  bottom[0] = back[6]; 
  1006. X  bottom[3] = back[3];
  1007. X  bottom[6] = back[0];
  1008. X
  1009. X  back[0] = top[0];
  1010. X  back[3] = top[3];
  1011. X  back[6] = top[6];
  1012. X
  1013. X  top[0] = temp[6];
  1014. X  top[3] = temp[3];
  1015. X  top[6] = temp[0];
  1016. X
  1017. X  update_cubik(wdata);
  1018. X
  1019. X}
  1020. X
  1021. Xvoid cubik_right(w,wdata,call_data)
  1022. X     Widget   w;
  1023. X     widget_data *wdata;
  1024. X     caddr_t  call_data;
  1025. X{
  1026. X  int i;
  1027. X  int temp[NUM_CUBIKPLANES];
  1028. X
  1029. X  for(i=1;i<=3;i++)
  1030. X    cubik(w,wdata,call_data,right,xs_flip_face);
  1031. X  righthand_twist(right);
  1032. X  /* other planes affected */
  1033. X  temp[2] = front[2];
  1034. X  temp[5] = front[5];
  1035. X  temp[8] = front[8];
  1036. X
  1037. X  front[2] = bottom[2];
  1038. X  front[5] = bottom[5];
  1039. X  front[8] = bottom[8];
  1040. X
  1041. X  bottom[2] = back[8]; 
  1042. X  bottom[5] = back[5];
  1043. X  bottom[8] = back[2];
  1044. X
  1045. X  back[2] = top[2];
  1046. X  back[5] = top[5];
  1047. X  back[8] = top[8];
  1048. X
  1049. X  top[2] = temp[8];
  1050. X  top[5] = temp[5];
  1051. X  top[8] = temp[2];
  1052. X
  1053. X  update_cubik(wdata);
  1054. X}
  1055. X
  1056. Xvoid cubik_back(w,wdata,call_data)
  1057. X     Widget   w;
  1058. X     widget_data *wdata;
  1059. X     caddr_t  call_data;
  1060. X{
  1061. X  int i;
  1062. X  int temp[NUM_CUBIKPLANES];
  1063. X
  1064. X  for(i=1;i<=3;i++)
  1065. X    cubik(w,wdata,call_data,back,xs_rot_face);
  1066. X  lefthand_twist(back);
  1067. X  /* other planes affected */
  1068. X  temp[2] = right[2];
  1069. X  temp[5] = right[5];
  1070. X  temp[8] = right[8];
  1071. X
  1072. X  right[2] = bottom[8];
  1073. X  right[5] = bottom[7];
  1074. X  right[8] = bottom[6];
  1075. X
  1076. X  bottom[6] = left[2]; 
  1077. X  bottom[7] = left[5];
  1078. X  bottom[8] = left[8];
  1079. X
  1080. X  left[2] = top[8];
  1081. X  left[5] = top[7];
  1082. X  left[8] = top[6];
  1083. X
  1084. X  top[6] = temp[2];
  1085. X  top[7] = temp[5];
  1086. X  top[8] = temp[8];
  1087. X
  1088. X  update_cubik(wdata);
  1089. X}
  1090. X
  1091. Xvoid cubik_top(w,wdata,call_data)
  1092. X     Widget   w;
  1093. X     widget_data *wdata;
  1094. X     caddr_t  call_data;
  1095. X{
  1096. X  int i;
  1097. X  int temp[NUM_CUBIKPLANES];
  1098. X
  1099. X  for(i=1;i<=3;i++)
  1100. X    cubik(w,wdata,call_data,top,xs_spin_face);
  1101. X  lefthand_twist(top);
  1102. X  /* other planes affected */
  1103. X  temp[0] = front[0];
  1104. X  temp[1] = front[1];
  1105. X  temp[2] = front[2];
  1106. X
  1107. X  front[0] = right[0];
  1108. X  front[1] = right[1];
  1109. X  front[2] = right[2];
  1110. X
  1111. X  right[0] = back[2]; 
  1112. X  right[1] = back[1];
  1113. X  right[2] = back[0];
  1114. X
  1115. X  back[0] = left[0];
  1116. X  back[1] = left[1];
  1117. X  back[2] = left[2];
  1118. X
  1119. X  left[0] = temp[2];
  1120. X  left[1] = temp[1];
  1121. X  left[2] = temp[0];
  1122. X
  1123. X  update_cubik(wdata);
  1124. X}
  1125. X
  1126. Xvoid cubik_bottom(w,wdata,call_data)
  1127. X     Widget   w;
  1128. X     widget_data *wdata;
  1129. X     caddr_t  call_data;
  1130. X{
  1131. X  int i;
  1132. X  int temp[NUM_CUBIKPLANES];
  1133. X
  1134. X  for(i=1;i<=3;i++)
  1135. X    cubik(w,wdata,call_data,bottom,xs_spin_face);
  1136. X  lefthand_twist(bottom);
  1137. X  /* other planes affected */
  1138. X  temp[6] = front[6];
  1139. X  temp[7] = front[7];
  1140. X  temp[8] = front[8];
  1141. X
  1142. X  front[6] = right[6];
  1143. X  front[7] = right[7];
  1144. X  front[8] = right[8];
  1145. X
  1146. X  right[6] = back[8]; 
  1147. X  right[7] = back[7];
  1148. X  right[8] = back[6];
  1149. X
  1150. X  back[6] = left[6];
  1151. X  back[7] = left[7];
  1152. X  back[8] = left[8];
  1153. X
  1154. X  left[6] = temp[8];
  1155. X  left[7] = temp[7];
  1156. X  left[8] = temp[6];
  1157. X
  1158. X  update_cubik(wdata);
  1159. X}
  1160. X
  1161. X
  1162. Xvoid cubik(w, wdata, call_data, subplanes, xs_op_face)
  1163. X     Widget   w;
  1164. X     widget_data *wdata;
  1165. X     caddr_t  call_data;
  1166. X     int subplanes[21];
  1167. X     void   (*xs_op_face)();
  1168. X{
  1169. X  Display *dpy = XtDisplay(wdata->canvas);
  1170. X  Window   win = XtWindow(wdata->canvas);
  1171. X  double_XPoint   tmp0_face[NUM_SUBPLANES][5];
  1172. X  XPoint short_face[NUM_SUBPLANES][5];
  1173. X  int draw_order[NUM_SUBPLANES];
  1174. X  int i,j;
  1175. X
  1176. X  /* Rotate all the planes and normalize, 
  1177. X   * but only copy the xxxx to the
  1178. X   * the rot_face[] array.
  1179. X   * 
  1180. X   *  Start from cubiked face, (cubik was inited to seed_face in init_data).
  1181. X   * Then after cubikking, return to 
  1182. X   * to the latest rot, spin, and flip angles.
  1183. X   * Update cubik with new rot face
  1184. X   */
  1185. X
  1186. X
  1187. X  /* rotate all of cubik */
  1188. X  for(i=0;i<=NUM_SUBPLANES-1;i++)
  1189. X    xs_op_face(tmp0_face[i],cubik_face[i],XtNumber(tmp0_face[i]),(double)30.0);
  1190. X
  1191. X  /* init rot face back to cubik. This will get roted, spinned, and flipped later */
  1192. X  facecpy(rot_face,cubik_face);
  1193. X  
  1194. X  /* only copy over the planes we want */
  1195. X  for(i=0;i<=NUM_CUBIKPLANES-1;i++) 
  1196. X    for(j=0;j<=4;j++){
  1197. X      rot_face[subplanes[i]][j].x = tmp0_face[subplanes[i]][j].x;
  1198. X      rot_face[subplanes[i]][j].y = tmp0_face[subplanes[i]][j].y;
  1199. X      rot_face[subplanes[i]][j].z = tmp0_face[subplanes[i]][j].z;
  1200. X    }
  1201. X  
  1202. X  /* update cubik */
  1203. X  facecpy(cubik_face,rot_face);
  1204. X
  1205. X
  1206. X  /* now rot, spin, and flip back to the latest angles.
  1207. X   * Note: the order of the rot, spin, and flip angles makes a difference...
  1208. X   * but that info is not available...so cube may not go back to exact position.
  1209. X   */
  1210. X  for(i=0;i<=NUM_SUBPLANES-1;i++)  
  1211. X    xs_rot_face(tmp0_face[i],rot_face[i],XtNumber(tmp0_face[i]),(double)rot_angle);
  1212. X  facecpy(rot_face,tmp0_face);
  1213. X  for(i=0;i<=NUM_SUBPLANES-1;i++)  
  1214. X    xs_spin_face(tmp0_face[i],rot_face[i],XtNumber(tmp0_face[i]),(double)spin_angle);
  1215. X  facecpy(rot_face,tmp0_face);
  1216. X  for(i=0;i<=NUM_SUBPLANES-1;i++)  
  1217. X    xs_flip_face(tmp0_face[i],rot_face[i],XtNumber(tmp0_face[i]),(double)flip_angle);
  1218. X  facecpy(rot_face,tmp0_face);    
  1219. X
  1220. X  /* prep to draw, then draw */
  1221. X  facecpy(tmp0_face,rot_face); /* copy it back to tmp0 */
  1222. X  projface(tmp0_face,rot_face);
  1223. X  norm_face(tmp0_face);
  1224. X  depth_sort(draw_order,tmp0_face);
  1225. X  shortface(short_face,tmp0_face);
  1226. X  draw_it(dpy, win, wdata, short_face,draw_order);
  1227. X}
  1228. X
  1229. Xvoid set_fill_pattern(w, data, call_data)
  1230. X     Widget         w;
  1231. X     graphics_data *data;
  1232. X     XmToggleButtonCallbackStruct  *call_data;
  1233. X{
  1234. X  Pixmap    tile;
  1235. X  int       i,j;
  1236. X  XGCValues values;
  1237. X  Arg       wargs[1];
  1238. X  
  1239. X  /* If not called for the right reason, return */
  1240. X  if(call_data->reason != XmCR_VALUE_CHANGED ||
  1241. X     !call_data->set)
  1242. X    return;
  1243. X
  1244. X  /* userData is the index into seed_color;
  1245. X   * index is same as button number.
  1246. X   */
  1247. X  XtSetArg(wargs[0], XmNuserData, &j);
  1248. X  XtGetValues(w, wargs, 1);
  1249. X  data->init_cubik_color = j;
  1250. X  /* indicate that a fill pattern has been chosen */
  1251. X  Fill_Pattern_Chosen = TRUE;
  1252. X  
  1253. X}
  1254. X
  1255. Xvoid set_cube_side(w, wdata, call_data)
  1256. X     Widget         w;
  1257. X     widget_data    *wdata;
  1258. X     XmToggleButtonCallbackStruct  *call_data;
  1259. X{
  1260. X  XmString  xmstr;
  1261. X  int       i;
  1262. X  Arg       wargs[1];
  1263. X  Cardinal  side_number;
  1264. X  
  1265. X  /* If not called for the right reason, return */
  1266. X  if(call_data->reason != XmCR_VALUE_CHANGED || 
  1267. X     !call_data->set)
  1268. X    return;
  1269. X  
  1270. X  XtSetArg(wargs[0], XmNuserData, &side_number);
  1271. X  XtGetValues(w, wargs, 1);
  1272. X  
  1273. X  wdata->graph_pointer->init_cubik_number = side_number;
  1274. X  /* init */
  1275. X  wdata->graph_pointer->init_cubik_mirror = FALSE;
  1276. X  
  1277. X  /* Crack side picked, then rot, spin, or flip accordingly */
  1278. X  /* orient cube */
  1279. X  Draw_Enable = FALSE;
  1280. X   Delta_Angle = -rot_angle;
  1281. X   rot_it(wdata->canvas, wdata, call_data);
  1282. X   Delta_Angle = -spin_angle;
  1283. X   spin_it(wdata->canvas, wdata, call_data);
  1284. X   Delta_Angle = -flip_angle;
  1285. X   flip_it(wdata->canvas, wdata, call_data);
  1286. X  Draw_Enable = TRUE;
  1287. X  switch(side_number){
  1288. X  case 0: 
  1289. X    /* front */
  1290. X    /* oriented already */
  1291. X    Delta_Angle = 0;
  1292. X    spin_it(wdata->canvas, wdata, call_data);
  1293. X    break;
  1294. X  case 1:
  1295. X    /* left */
  1296. X    Delta_Angle = 270;
  1297. X    spin_it(wdata->canvas, wdata, call_data);
  1298. X    wdata->graph_pointer->init_cubik_mirror = TRUE;
  1299. X    break;
  1300. X  case 2:
  1301. X    /* right */
  1302. X    Delta_Angle = 90;
  1303. X    spin_it(wdata->canvas, wdata, call_data);
  1304. X    break;
  1305. X  case 3:
  1306. X    /* back */
  1307. X    Delta_Angle = 180;
  1308. X    spin_it(wdata->canvas, wdata, call_data);
  1309. X    wdata->graph_pointer->init_cubik_mirror = TRUE;
  1310. X    break;
  1311. X  case 4:
  1312. X    /* top */
  1313. X    Draw_Enable = FALSE;
  1314. X    Delta_Angle = 270;
  1315. X    flip_it(wdata->canvas, wdata, call_data);
  1316. X    Draw_Enable = TRUE;
  1317. X    Delta_Angle = 180;
  1318. X    rot_it(wdata->canvas, wdata, call_data);
  1319. X    wdata->graph_pointer->init_cubik_mirror = TRUE;
  1320. X    break;
  1321. X  case 5:
  1322. X    /* bottom */
  1323. X    Delta_Angle = 90;
  1324. X    flip_it(wdata->canvas, wdata, call_data);
  1325. X    break;
  1326. X  }
  1327. X  /* restore */
  1328. X  Delta_Angle = DEFAULT_DELTA_ANGLE;
  1329. X  /* indicate that a side has be chosen */
  1330. X  Cube_Side_Chosen = TRUE;
  1331. X}
  1332. X
  1333. Xvoid init_subplane_pattern(w, wdata, event)
  1334. X     Widget          w;
  1335. X     widget_data     *wdata;
  1336. X     XEvent          *event;
  1337. X{
  1338. X  int i;
  1339. X  XGCValues values;
  1340. X  int mirror[9];
  1341. X  
  1342. X  /* If not called for the right reason, return */
  1343. X  if(!Cube_Side_Chosen ||
  1344. X     !Fill_Pattern_Chosen)
  1345. X    return;
  1346. X  
  1347. X  /* init mirror */
  1348. X  if(wdata->graph_pointer->init_cubik_mirror){
  1349. X    mirror[0]=2;
  1350. X    mirror[1]=1;
  1351. X    mirror[2]=0;
  1352. X    mirror[3]=5;
  1353. X    mirror[4]=4;
  1354. X    mirror[5]=3;
  1355. X    mirror[6]=8;
  1356. X    mirror[7]=7;
  1357. X    mirror[8]=6;
  1358. X  }
  1359. X  else
  1360. X    for(i=0; i<9; i++)
  1361. X      mirror[i]=i;
  1362. X  
  1363. X  for(i=0; i<9; i++){
  1364. X    /* Can't change the center cube (subplane) */
  1365. X    if(i == 4)
  1366. X      continue;
  1367. X    if(XPointInRegion(wdata->init_cubik_region[i],event->xbutton.x,event->xbutton.y)){
  1368. X      /* Note: To change color of a face after a click, we just brute force change the subface_gc[][]
  1369. X       * of the cube. This is effectively just re-initing the gc to a new color for that face.
  1370. X       *    In align_subfaces, when cubik_face is determined the subface_gc[][]'s get re-inited 
  1371. X       * to their original colors.
  1372. X       */
  1373. X      values.foreground = xss_get_pixel_by_name(w,seed_color[wdata->graph_pointer->init_cubik_color]);
  1374. X      values.background = xss_get_pixel_by_name(w,seed_color[wdata->graph_pointer->init_cubik_color]);
  1375. X      values.fill_style = FillTiled;
  1376. X      wdata->subface_gc[mirror[i]][wdata->graph_pointer->init_cubik_number] = 
  1377. X    XtGetGC(w, 
  1378. X        GCForeground | GCBackground | GCFillStyle,
  1379. X        &values);
  1380. X      /* update subface_side */
  1381. X      wdata->subface_side[mirror[i]][wdata->graph_pointer->init_cubik_number] = wdata->graph_pointer->init_cubik_color;
  1382. X      /* dummy draw */
  1383. X      Delta_Angle = 0;
  1384. X      spin_it(wdata->canvas, wdata, NULL);
  1385. X      /* restore */
  1386. X      Delta_Angle = DEFAULT_DELTA_ANGLE;
  1387. X    }
  1388. X  }
  1389. X}
  1390. X
  1391. Xvoid align_subfaces(w, wdata, call_data)
  1392. X     Widget               w; 
  1393. X     widget_data     *wdata;
  1394. X     XmAnyCallbackStruct *call_data; 
  1395. X{
  1396. X  /* This is called by xcic_done_callback in init_cubik.
  1397. X    
  1398. X     Given the updated wdata->subface_side[][] 
  1399. X     the front[], left[], right[], back[].....
  1400. X     arrays must be `aligned'. If a corner cube 
  1401. X     face changes color, then its other 2 faces
  1402. X     may have to change front[], left[], right[], back[].....
  1403. X     values even though it does not change color.
  1404. X   */
  1405. X
  1406. X  /* There are 8 corner cubes that must have 3
  1407. X     different color faces.
  1408. X     Each corner cube is represented by 3 wdata->subface_side[][]
  1409. X     values.
  1410. X      Using the macros we have:
  1411. X             Front(0),Top(0),Left(0)
  1412. X         Front(2),Top(2),Right(0)
  1413. X         Front(6),Bottom(0),Left(6)
  1414. X         Front(8),Bottom(2), Right(6)
  1415. X         Back(0),Top(6),Left(2)
  1416. X         Back(2),Top(8),Right(2)
  1417. X         Back(6),Bottom(6),Left(8)
  1418. X         Back(8),Bottom(8),Right(8)
  1419. X
  1420. X      These values index to an array which gives the values for the front[], left[]... arrays.
  1421. X
  1422. X     The array is generated in init_data and is called 
  1423. X     struct Corner cornermap[6][6][6]. A warning is printed if values are illegal
  1424. X     (e.g.,  all sides of a corner having the same color.)
  1425. X
  1426. X     cornermap values
  1427. X
  1428. X     indices                      cornermap[][][].
  1429. X     []      []      []          a                b                c
  1430. X     0       0       0           -1(illegal)
  1431. X     0       0       1           -1
  1432. X             .                    .
  1433. X             .                    .
  1434. X             .                    .
  1435. X     FRONT   TOP     LEFT        seed_front[0]    seed_top[0]      seed_left[0]
  1436. X     TOP     FRONT   LEFT        -1
  1437. X     FRONT   LEFT    TOP         -1
  1438. X     TOP     LEFT    FRONT       seed_top[0]      seed_left[0]     seed_front[0]
  1439. X     LEFT    TOP     FRONT       -1
  1440. X     LEFT    FRONT   TOP         seed_left[0]     seed_front[0]    seed_top[0]
  1441. X             .                    .
  1442. X             .                    .
  1443. X             .                    .
  1444. X     BACK    BOTTOM  RIGHT       seed_back[8]     seed_bottom[8]   seed_right[8]
  1445. X             .                    .  
  1446. X             .                    .  
  1447. X             .                    .  
  1448. X
  1449. X     So we can update front[], left[]... arrays in the following manner:
  1450. X
  1451. X          front[0] = cornermap[Front(0)][Top(0)][Left(0)].a
  1452. X      front[2] = cornermap[Front(2)][Top(2)][Left(0)].a
  1453. X               .
  1454. X               .
  1455. X               .
  1456. X      top[0]   = cornermap[Front(0)][Top(0)][Left(0)].b
  1457. X
  1458. X     A test is done for cornermap[][][].a == -1 which indicates an illegal
  1459. X     initialization.
  1460. X
  1461. X   */  
  1462. X     
  1463. X  /* There are 12 edge cubes that must have 2
  1464. X     different color faces.
  1465. X     Each edge cube is represented by 2 wdata->subface_side[][]
  1466. X     values.
  1467. X      Using the macros we have:
  1468. X             Front(1),Top(1)
  1469. X         Front(3),Left(3)
  1470. X         Front(5),Right(3)
  1471. X         Front(7),Bottom(1)
  1472. X         Back(1),Top(7)
  1473. X         Back(3),Left(5)
  1474. X         Back(5),Right(5)
  1475. X         Back(7),Bottom(7)
  1476. X         Right(1),Top(5)
  1477. X         Right(7),Bottom(5)
  1478. X         Bottom(3),Left(7)
  1479. X         Left(1),Top(3)
  1480. X         
  1481. X
  1482. X      These values index to an array which gives the values for the front[], left[]... arrays.
  1483. X
  1484. X     The array is generated in init_data and is called 
  1485. X     struct Edge edgemap[6][6]. A warning is printed if values are illegal
  1486. X     (e.g.,  both sides of an edge cube having the same color.)
  1487. X
  1488. X     edgemap values
  1489. X
  1490. X     indices                  edgemap[][].
  1491. X     []      []               a                b
  1492. X     0       0                -1(illegal)
  1493. X     0       0                -1
  1494. X             .                    .
  1495. X             .                    .
  1496. X             .                    .
  1497. X     FRONT   TOP              seed_front[1]    seed_top[1]     
  1498. X     TOP     FRONT            seed_top[1]      seed_front[1]
  1499. X
  1500. X             .                    .
  1501. X     BACK    BOTTOM           seed_back[7]     seed_bottom[7]  
  1502. X             .                    .  
  1503. X             .                    .  
  1504. X             .                    .  
  1505. X
  1506. X     So we can update front[], left[]... arrays in the following manner:
  1507. X
  1508. X          front[1] = edgemap[Front(1)][Top(1)].a
  1509. X      front[5] = edgemap[Front(5)][Right(3)].a
  1510. X               .
  1511. X               .
  1512. X               .
  1513. X      top[1]   = edgemap[Front(1)][Top(1)].b
  1514. X
  1515. X     A test is done for edgemap[][].a == -1 which indicates an illegal
  1516. X     initialization.
  1517. X
  1518. X
  1519. X
  1520. X     This takes care of the front[], left[]... arrays. 
  1521. X     Next, we have to fix the 
  1522. X          double_XPoint cubik_face[NUM_SUBPLANES][5] array which has the old 
  1523. X     pristine coordinates. The coordinates of the subplanes that have moved
  1524. X     by initialization must also move. 
  1525. X        Using inverse_funct which is the inverse of the front[], left[]... arrays,
  1526. X     the new coordinates in cubik_face[][] are determinesd by the following.
  1527. X        First make a copy of cubik_face[][].
  1528. X                     facecpy(cubikface_cpy,cubik_face);
  1529. X    Proceed to replace old coordinates.
  1530. X                 cubik_face[0][] = cubikface_cpy[inverse_funct[0]][];
  1531. X                 cubik_face[1][] = cubikface_cpy[inverse_funct[1]][];
  1532. X                 cubik_face[2][] = cubikface_cpy[inverse_funct[2]][];
  1533. X                             .
  1534. X                             .
  1535. X                             .
  1536. X                 cubik_face[53][] = cubikface_cpy[inverse_funct[53][];
  1537. X
  1538. X    Inverse_funct is created as follows:
  1539. X                 First make one large array:
  1540. X                 large_array[0] = front[0]
  1541. X                 large_array[1] = front[1]
  1542. X                 large_array[2] = front[2]
  1543. X                             .
  1544. X                             .
  1545. X                             .
  1546. X                 large_array[9] = front[8]
  1547. X                 large_array[10] = left[0]
  1548. X                 large_array[11] = left[1]
  1549. X                 large_array[12] = left[2]
  1550. X                     .
  1551. X                     .
  1552. X                     .
  1553. X             large_array[53] = bottom[8]
  1554. X
  1555. X                     Then load inverse_funct with inverse values.
  1556. X                 for(i=0;i<NUM_SUBPLANES-1;i++)
  1557. X                  inverse_funct[large_array[i]] = i; 
  1558. X
  1559. X     Lastly, the subface_gc[][]'s get re-initied.
  1560. X     
  1561. X   */  
  1562. X
  1563. X
  1564. X  int i,j;
  1565. X  XGCValues       values;
  1566. X  double_XPoint cubikface_cpy[NUM_SUBPLANES][5];
  1567. X
  1568. X  int inverse_funct[NUM_SUBPLANES];
  1569. X  int large_array[NUM_SUBPLANES];
  1570. X
  1571. X  /* corners */
  1572. X  
  1573. X  front[0] = cornermap[Front(0)][Top(0)][Left(0)].a;
  1574. X  top[0] =   cornermap[Front(0)][Top(0)][Left(0)].b;
  1575. X  left[0] =  cornermap[Front(0)][Top(0)][Left(0)].c;
  1576. X  
  1577. X  front[2] = cornermap[Front(2)][Top(2)][Right(0)].a;
  1578. X  top[2] =   cornermap[Front(2)][Top(2)][Right(0)].b;
  1579. X  right[0] = cornermap[Front(2)][Top(2)][Right(0)].c;
  1580. X  
  1581. X  
  1582. X  front[6] = cornermap[Front(6)][Bottom(0)][Left(6)].a;
  1583. X  bottom[0]= cornermap[Front(6)][Bottom(0)][Left(6)].b;
  1584. X  left[6] =  cornermap[Front(6)][Bottom(0)][Left(6)].c;
  1585. X  
  1586. X  
  1587. X  front[8] = cornermap[Front(8)][Bottom(2)][Right(6)].a;
  1588. X  bottom[2]= cornermap[Front(8)][Bottom(2)][Right(6)].b;
  1589. X  right[6] = cornermap[Front(8)][Bottom(2)][Right(6)].c;
  1590. X  
  1591. X  
  1592. X  back[0] =  cornermap[Back(0)][Top(6)][Left(2)].a;
  1593. X  top[6] =   cornermap[Back(0)][Top(6)][Left(2)].b;
  1594. X  left[2] =  cornermap[Back(0)][Top(6)][Left(2)].c;
  1595. X  
  1596. X  
  1597. X  back[2] =  cornermap[Back(2)][Top(8)][Right(2)].a;
  1598. X  top[8] =   cornermap[Back(2)][Top(8)][Right(2)].b;
  1599. X  right[2] = cornermap[Back(2)][Top(8)][Right(2)].c;
  1600. X  
  1601. X  
  1602. X  back[6] =  cornermap[Back(6)][Bottom(6)][Left(8)].a;
  1603. X  bottom[6]= cornermap[Back(6)][Bottom(6)][Left(8)].b;
  1604. X  left[8] =  cornermap[Back(6)][Bottom(6)][Left(8)].c;
  1605. X  
  1606. X  
  1607. X  back[8] =  cornermap[Back(8)][Bottom(8)][Right(8)].a;
  1608. X  bottom[8]= cornermap[Back(8)][Bottom(8)][Right(8)].b;
  1609. X  right[8] = cornermap[Back(8)][Bottom(8)][Right(8)].c;
  1610. X
  1611. X
  1612. X  /* edges */
  1613. X
  1614. X  front[1] = edgemap[Front(1)][Top(1)].a;
  1615. X  top[1] =   edgemap[Front(1)][Top(1)].b;
  1616. X  
  1617. X  front[3] = edgemap[Front(3)][Left(3)].a;
  1618. X  left[3] =  edgemap[Front(3)][Left(3)].b;
  1619. X  
  1620. X  front[5] = edgemap[Front(5)][Right(3)].a;
  1621. X  right[3] = edgemap[Front(5)][Right(3)].b;
  1622. X  
  1623. X  front[7] = edgemap[Front(7)][Bottom(1)].a;
  1624. X  bottom[1]= edgemap[Front(7)][Bottom(1)].b;
  1625. X  
  1626. X  back[1] =  edgemap[Back(1)][Top(7)].a;
  1627. X  top[7] =   edgemap[Back(1)][Top(7)].b;
  1628. X  
  1629. X  back[3] =  edgemap[Back(3)][Left(5)].a;
  1630. X  left[5] =  edgemap[Back(3)][Left(5)].b;
  1631. X  
  1632. X  back[5] =  edgemap[Back(5)][Right(5)].a;
  1633. X  right[5] = edgemap[Back(5)][Right(5)].b;
  1634. X  
  1635. X  back[7] =  edgemap[Back(7)][Bottom(7)].a;
  1636. X  bottom[7]= edgemap[Back(7)][Bottom(7)].b;
  1637. X  
  1638. X  right[1] = edgemap[Right(1)][Top(5)].a;
  1639. X  top[5] =   edgemap[Right(1)][Top(5)].b;
  1640. X  
  1641. X  
  1642. X  right[7] = edgemap[Right(7)][Bottom(5)].a;
  1643. X  bottom[5]= edgemap[Right(7)][Bottom(5)].b;
  1644. X  
  1645. X  bottom[3]= edgemap[Bottom(3)][Left(7)].a;
  1646. X  left[7] =  edgemap[Bottom(3)][Left(7)].b;
  1647. X  
  1648. X  left[1] =  edgemap[Left(1)][Top(3)].a;
  1649. X  top[3] =   edgemap[Left(1)][Top(3)].b;
  1650. X
  1651. X  /* check for bad alignment */
  1652. X  for(i=0;i<=8;i++)
  1653. X    if(front[i]  == -1 ||
  1654. X       left[i]   == -1 ||
  1655. X       right[i]  == -1 ||
  1656. X       back[i]   == -1 ||
  1657. X       top[i]    == -1 ||
  1658. X       bottom[i] == -1){
  1659. X      printf("ERROR BAD INITIALED CUBE\nPREPARE FOR STRANGE CUBE\n");
  1660. X      return;
  1661. X    }
  1662. X  update_cubik(wdata);
  1663. X
  1664. X  /* Create large_array fron front[],left[],... array */
  1665. X  for(i=0;i<9;i++){
  1666. X    large_array[i] = front[i];
  1667. X    large_array[i+9] = left[i];
  1668. X    large_array[i+18] = right[i];
  1669. X    large_array[i+27] = back[i];
  1670. X    large_array[i+36] = top[i];
  1671. X    large_array[i+45] = bottom[i];
  1672. X  }
  1673. X  
  1674. X  /* Create the inverse of large array */
  1675. X  /* (This step could be incorporated into the next step but is kept
  1676. X   *  here for clarity.)
  1677. X   */
  1678. X  for(i=0;i<=NUM_SUBPLANES-1;i++)
  1679. X    inverse_funct[large_array[i]] = i;
  1680. X  
  1681. X  /* save old cubik_face values  */
  1682. X  facecpy(cubikface_cpy,cubik_face);
  1683. X  
  1684. X  /* swap arround the values */
  1685. X  for(i=0;i<=NUM_SUBPLANES-1;i++)
  1686. X    for(j=0;j<5;j++){
  1687. X      cubik_face[i][j].x = cubikface_cpy[inverse_funct[i]][j].x;
  1688. X      cubik_face[i][j].y = cubikface_cpy[inverse_funct[i]][j].y;
  1689. X      cubik_face[i][j].z = cubikface_cpy[inverse_funct[i]][j].z;
  1690. X    }
  1691. X
  1692. X  /* update rot_face  */
  1693. X  facecpy(rot_face,cubik_face);
  1694. X
  1695. X  /* re-init subface_gc's */
  1696. X  /* 
  1697. X   * Get a gc for each subface_color
  1698. X   */
  1699. X  for(i=0;i<9;i++){
  1700. X    for(j=0;j<6;j++){
  1701. X      values.foreground = xss_get_pixel_by_name(w,seed_color[j]);
  1702. X      values.background = xss_get_pixel_by_name(w,seed_color[j]);
  1703. X      values.fill_style = FillTiled;
  1704. X      wdata->subface_gc[i][j] =    XtGetGC(w,
  1705. X                    GCForeground | GCBackground | GCFillStyle,
  1706. X                    &values);
  1707. X    }
  1708. X  }
  1709. X}
  1710. X
  1711. X
  1712. Xvoid init_cornermap()
  1713. X{
  1714. X  int  i,j,k;
  1715. X  
  1716. X  /* See align_subfaces in cube.c for more info on cornermap[][][] */
  1717. X  /* init all to illegal value */
  1718. X  for(i=0;i<6;i++)
  1719. X    for(j=0;j<6;j++)
  1720. X      for(k=0;k<6;k++)
  1721. X    cornermap[i][j][k].a = -1;
  1722. X    
  1723. X  /* brute force initialization ... ugh! */
  1724. X  /* 1 */
  1725. X  cornermap[FRONT][TOP][LEFT].a = seed_front[0];
  1726. X  cornermap[FRONT][TOP][LEFT].b = seed_top[0];
  1727. X  cornermap[FRONT][TOP][LEFT].c = seed_left[0];
  1728. X
  1729. X  cornermap[TOP][LEFT][FRONT].a = seed_top[0];
  1730. X  cornermap[TOP][LEFT][FRONT].b = seed_left[0];
  1731. X  cornermap[TOP][LEFT][FRONT].c = seed_front[0];
  1732. X
  1733. X  cornermap[LEFT][FRONT][TOP].a = seed_left[0];
  1734. X  cornermap[LEFT][FRONT][TOP].b = seed_front[0];
  1735. X  cornermap[LEFT][FRONT][TOP].c = seed_top[0];
  1736. X
  1737. X
  1738. X  cornermap[FRONT][LEFT][TOP].a = seed_front[0];
  1739. X  cornermap[FRONT][LEFT][TOP].c = seed_top[0];
  1740. X  cornermap[FRONT][LEFT][TOP].b = seed_left[0];
  1741. X
  1742. X  cornermap[TOP][FRONT][LEFT].a = seed_top[0];
  1743. X  cornermap[TOP][FRONT][LEFT].c = seed_left[0];
  1744. X  cornermap[TOP][FRONT][LEFT].b = seed_front[0];
  1745. X
  1746. X  cornermap[LEFT][TOP][FRONT].a = seed_left[0];
  1747. X  cornermap[LEFT][TOP][FRONT].c = seed_front[0];
  1748. X  cornermap[LEFT][TOP][FRONT].b = seed_top[0];
  1749. X
  1750. X  /* 2 */
  1751. X  cornermap[FRONT][TOP][RIGHT].a = seed_front[2];
  1752. X  cornermap[FRONT][TOP][RIGHT].b = seed_top[2];
  1753. X  cornermap[FRONT][TOP][RIGHT].c = seed_right[0];
  1754. X
  1755. X  cornermap[TOP][RIGHT][FRONT].a = seed_top[2];
  1756. X  cornermap[TOP][RIGHT][FRONT].b = seed_right[0];
  1757. X  cornermap[TOP][RIGHT][FRONT].c = seed_front[2];
  1758. X
  1759. X  cornermap[RIGHT][FRONT][TOP].a = seed_right[0];
  1760. X  cornermap[RIGHT][FRONT][TOP].b = seed_front[2];
  1761. X  cornermap[RIGHT][FRONT][TOP].c = seed_top[2];
  1762. X
  1763. X
  1764. X  cornermap[FRONT][RIGHT][TOP].a = seed_front[2];
  1765. X  cornermap[FRONT][RIGHT][TOP].c = seed_top[2];
  1766. X  cornermap[FRONT][RIGHT][TOP].b = seed_right[0];
  1767. X
  1768. X  cornermap[TOP][FRONT][RIGHT].a = seed_top[2];
  1769. X  cornermap[TOP][FRONT][RIGHT].c = seed_right[0];
  1770. X  cornermap[TOP][FRONT][RIGHT].b = seed_front[2];
  1771. X
  1772. X  cornermap[RIGHT][TOP][FRONT].a = seed_right[0];
  1773. X  cornermap[RIGHT][TOP][FRONT].c = seed_front[2];
  1774. X  cornermap[RIGHT][TOP][FRONT].b = seed_top[2];
  1775. X
  1776. X  /* 3 */
  1777. X  cornermap[FRONT][BOTTOM][LEFT].a = seed_front[6];
  1778. X  cornermap[FRONT][BOTTOM][LEFT].b = seed_bottom[0];
  1779. X  cornermap[FRONT][BOTTOM][LEFT].c = seed_left[6];
  1780. X
  1781. X  cornermap[BOTTOM][LEFT][FRONT].a = seed_bottom[0];
  1782. X  cornermap[BOTTOM][LEFT][FRONT].b = seed_left[6];
  1783. X  cornermap[BOTTOM][LEFT][FRONT].c = seed_front[6];
  1784. X
  1785. X  cornermap[LEFT][FRONT][BOTTOM].a = seed_left[6];
  1786. X  cornermap[LEFT][FRONT][BOTTOM].b = seed_front[6];
  1787. X  cornermap[LEFT][FRONT][BOTTOM].c = seed_bottom[0];
  1788. X
  1789. X
  1790. X  cornermap[FRONT][LEFT][BOTTOM].a = seed_front[6];
  1791. X  cornermap[FRONT][LEFT][BOTTOM].c = seed_bottom[0];
  1792. X  cornermap[FRONT][LEFT][BOTTOM].b = seed_left[6];
  1793. X
  1794. X  cornermap[BOTTOM][FRONT][LEFT].a = seed_bottom[0];
  1795. X  cornermap[BOTTOM][FRONT][LEFT].c = seed_left[6];
  1796. X  cornermap[BOTTOM][FRONT][LEFT].b = seed_front[6];
  1797. X
  1798. X  cornermap[LEFT][BOTTOM][FRONT].a = seed_left[6];
  1799. X  cornermap[LEFT][BOTTOM][FRONT].c = seed_front[6];
  1800. X  cornermap[LEFT][BOTTOM][FRONT].b = seed_bottom[0];
  1801. X
  1802. X  /* 4 */
  1803. X  cornermap[FRONT][BOTTOM][RIGHT].a = seed_front[8];
  1804. X  cornermap[FRONT][BOTTOM][RIGHT].b = seed_bottom[2];
  1805. X  cornermap[FRONT][BOTTOM][RIGHT].c = seed_right[6];
  1806. X
  1807. X  cornermap[BOTTOM][RIGHT][FRONT].a = seed_bottom[2];
  1808. X  cornermap[BOTTOM][RIGHT][FRONT].b = seed_right[6];
  1809. X  cornermap[BOTTOM][RIGHT][FRONT].c = seed_front[8];
  1810. X
  1811. X  cornermap[RIGHT][FRONT][BOTTOM].a = seed_right[6];
  1812. X  cornermap[RIGHT][FRONT][BOTTOM].b = seed_front[8];
  1813. X  cornermap[RIGHT][FRONT][BOTTOM].c = seed_bottom[2];
  1814. X
  1815. X
  1816. X  cornermap[FRONT][RIGHT][BOTTOM].a = seed_front[8];
  1817. X  cornermap[FRONT][RIGHT][BOTTOM].c = seed_bottom[2];
  1818. X  cornermap[FRONT][RIGHT][BOTTOM].b = seed_right[6];
  1819. X
  1820. X  cornermap[BOTTOM][FRONT][RIGHT].a = seed_bottom[2];
  1821. X  cornermap[BOTTOM][FRONT][RIGHT].c = seed_right[6];
  1822. X  cornermap[BOTTOM][FRONT][RIGHT].b = seed_front[8];
  1823. X
  1824. X  cornermap[RIGHT][BOTTOM][FRONT].a = seed_right[6];
  1825. X  cornermap[RIGHT][BOTTOM][FRONT].c = seed_front[8];
  1826. X  cornermap[RIGHT][BOTTOM][FRONT].b = seed_bottom[2];
  1827. X
  1828. X
  1829. X  /* 5 */
  1830. X  cornermap[BACK][TOP][LEFT].a = seed_back[0];
  1831. X  cornermap[BACK][TOP][LEFT].b = seed_top[6];
  1832. X  cornermap[BACK][TOP][LEFT].c = seed_left[2];
  1833. X
  1834. X  cornermap[TOP][LEFT][BACK].a = seed_top[6];
  1835. X  cornermap[TOP][LEFT][BACK].b = seed_left[2];
  1836. X  cornermap[TOP][LEFT][BACK].c = seed_back[0];
  1837. X
  1838. X  cornermap[LEFT][BACK][TOP].a = seed_left[2];
  1839. X  cornermap[LEFT][BACK][TOP].b = seed_back[0];
  1840. X  cornermap[LEFT][BACK][TOP].c = seed_top[6];
  1841. X
  1842. X
  1843. X  cornermap[BACK][LEFT][TOP].a = seed_back[0];
  1844. X  cornermap[BACK][LEFT][TOP].c = seed_top[6];
  1845. X  cornermap[BACK][LEFT][TOP].b = seed_left[2];
  1846. X
  1847. X  cornermap[TOP][BACK][LEFT].a = seed_top[6];
  1848. X  cornermap[TOP][BACK][LEFT].c = seed_left[2];
  1849. X  cornermap[TOP][BACK][LEFT].b = seed_back[0];
  1850. X
  1851. X  cornermap[LEFT][TOP][BACK].a = seed_left[2];
  1852. X  cornermap[LEFT][TOP][BACK].c = seed_back[0];
  1853. X  cornermap[LEFT][TOP][BACK].b = seed_top[6];
  1854. X
  1855. X  /* 6 */
  1856. X  cornermap[BACK][TOP][RIGHT].a = seed_back[2];
  1857. X  cornermap[BACK][TOP][RIGHT].b = seed_top[8];
  1858. X  cornermap[BACK][TOP][RIGHT].c = seed_right[2];
  1859. X
  1860. X  cornermap[TOP][RIGHT][BACK].a = seed_top[8];
  1861. X  cornermap[TOP][RIGHT][BACK].b = seed_right[2];
  1862. X  cornermap[TOP][RIGHT][BACK].c = seed_back[2];
  1863. X
  1864. X  cornermap[RIGHT][BACK][TOP].a = seed_right[2];
  1865. X  cornermap[RIGHT][BACK][TOP].b = seed_back[2];
  1866. X  cornermap[RIGHT][BACK][TOP].c = seed_top[8];
  1867. X
  1868. X
  1869. X  cornermap[BACK][RIGHT][TOP].a = seed_back[2];
  1870. X  cornermap[BACK][RIGHT][TOP].c = seed_top[8];
  1871. X  cornermap[BACK][RIGHT][TOP].b = seed_right[2];
  1872. X
  1873. X  cornermap[TOP][BACK][RIGHT].a = seed_top[8];
  1874. X  cornermap[TOP][BACK][RIGHT].c = seed_right[2];
  1875. X  cornermap[TOP][BACK][RIGHT].b = seed_back[2];
  1876. X
  1877. X  cornermap[RIGHT][TOP][BACK].a = seed_right[2];
  1878. X  cornermap[RIGHT][TOP][BACK].c = seed_back[2];
  1879. X  cornermap[RIGHT][TOP][BACK].b = seed_top[8];
  1880. X
  1881. X  /* 7 */
  1882. X  cornermap[BACK][BOTTOM][LEFT].a = seed_back[6];
  1883. X  cornermap[BACK][BOTTOM][LEFT].b = seed_bottom[6];
  1884. X  cornermap[BACK][BOTTOM][LEFT].c = seed_left[8];
  1885. X
  1886. X  cornermap[BOTTOM][LEFT][BACK].a = seed_bottom[6];
  1887. X  cornermap[BOTTOM][LEFT][BACK].b = seed_left[8];
  1888. X  cornermap[BOTTOM][LEFT][BACK].c = seed_back[6];
  1889. X
  1890. X  cornermap[LEFT][BACK][BOTTOM].a = seed_left[8];
  1891. X  cornermap[LEFT][BACK][BOTTOM].b = seed_back[6];
  1892. X  cornermap[LEFT][BACK][BOTTOM].c = seed_bottom[6];
  1893. X
  1894. X
  1895. X  cornermap[BACK][LEFT][BOTTOM].a = seed_back[6];
  1896. X  cornermap[BACK][LEFT][BOTTOM].c = seed_bottom[6];
  1897. X  cornermap[BACK][LEFT][BOTTOM].b = seed_left[8];
  1898. X
  1899. X  cornermap[BOTTOM][BACK][LEFT].a = seed_bottom[6];
  1900. X  cornermap[BOTTOM][BACK][LEFT].c = seed_left[8];
  1901. X  cornermap[BOTTOM][BACK][LEFT].b = seed_back[6];
  1902. X
  1903. X  cornermap[LEFT][BOTTOM][BACK].a = seed_left[8];
  1904. X  cornermap[LEFT][BOTTOM][BACK].c = seed_back[6];
  1905. X  cornermap[LEFT][BOTTOM][BACK].b = seed_bottom[6];
  1906. X
  1907. X  /* 8 */
  1908. X  cornermap[BACK][BOTTOM][RIGHT].a = seed_back[8];
  1909. X  cornermap[BACK][BOTTOM][RIGHT].b = seed_bottom[8];
  1910. X  cornermap[BACK][BOTTOM][RIGHT].c = seed_right[8];
  1911. X
  1912. X  cornermap[BOTTOM][RIGHT][BACK].a = seed_bottom[8];
  1913. X  cornermap[BOTTOM][RIGHT][BACK].b = seed_right[8];
  1914. X  cornermap[BOTTOM][RIGHT][BACK].c = seed_back[8];
  1915. X
  1916. X  cornermap[RIGHT][BACK][BOTTOM].a = seed_right[8];
  1917. X  cornermap[RIGHT][BACK][BOTTOM].b = seed_back[8];
  1918. X  cornermap[RIGHT][BACK][BOTTOM].c = seed_bottom[8];
  1919. X
  1920. X
  1921. X  cornermap[BACK][RIGHT][BOTTOM].a = seed_back[8];
  1922. X  cornermap[BACK][RIGHT][BOTTOM].c = seed_bottom[8];
  1923. X  cornermap[BACK][RIGHT][BOTTOM].b = seed_right[8];
  1924. X
  1925. X  cornermap[BOTTOM][BACK][RIGHT].a = seed_bottom[8];
  1926. X  cornermap[BOTTOM][BACK][RIGHT].c = seed_right[8];
  1927. X  cornermap[BOTTOM][BACK][RIGHT].b = seed_back[8];
  1928. X
  1929. X  cornermap[RIGHT][BOTTOM][BACK].a = seed_right[8];
  1930. X  cornermap[RIGHT][BOTTOM][BACK].c = seed_back[8];
  1931. X  cornermap[RIGHT][BOTTOM][BACK].b = seed_bottom[8];
  1932. X
  1933. X}
  1934. X
  1935. Xvoid init_edgemap()
  1936. X{
  1937. X  int  i,j;
  1938. X  
  1939. X  /* See align_subfaces in cube.c for more info on edgemap[][] */
  1940. X  /* init all to illegal value */
  1941. X  for(i=0;i<6;i++)
  1942. X    for(j=0;j<6;j++)
  1943. X      edgemap[i][j].a = -1;
  1944. X    
  1945. X  /* brute force initialization ... ugh! */
  1946. X  /* 1 */
  1947. X  edgemap[FRONT][TOP].a = seed_front[1];
  1948. X  edgemap[FRONT][TOP].b = seed_top[1];
  1949. X
  1950. X  edgemap[TOP][FRONT].a = seed_top[1];
  1951. X  edgemap[TOP][FRONT].b = seed_front[1];
  1952. X
  1953. X  /* 2 */
  1954. X  edgemap[FRONT][LEFT].a = seed_front[3];
  1955. X  edgemap[FRONT][LEFT].b = seed_left[3];
  1956. X
  1957. X  edgemap[LEFT][FRONT].a = seed_left[3];
  1958. X  edgemap[LEFT][FRONT].b = seed_front[3];
  1959. X
  1960. X  /* 3 */
  1961. X  edgemap[FRONT][RIGHT].a = seed_front[5];
  1962. X  edgemap[FRONT][RIGHT].b = seed_right[3];
  1963. X
  1964. X  edgemap[RIGHT][FRONT].a = seed_right[3];
  1965. X  edgemap[RIGHT][FRONT].b = seed_front[5];
  1966. X
  1967. X  /* 4 */
  1968. X  edgemap[FRONT][BOTTOM].a = seed_front[7];
  1969. X  edgemap[FRONT][BOTTOM].b = seed_bottom[1];
  1970. X
  1971. X  edgemap[BOTTOM][FRONT].a = seed_bottom[1];
  1972. X  edgemap[BOTTOM][FRONT].b = seed_front[7];
  1973. X
  1974. X  /* 5 */
  1975. X  edgemap[BACK][TOP].a = seed_back[1];
  1976. X  edgemap[BACK][TOP].b = seed_top[7];
  1977. X
  1978. X  edgemap[TOP][BACK].a = seed_top[7];
  1979. X  edgemap[TOP][BACK].b = seed_back[1];
  1980. X
  1981. X  /* 6 */
  1982. X  edgemap[BACK][LEFT].a = seed_back[3];
  1983. X  edgemap[BACK][LEFT].b = seed_left[5];
  1984. X
  1985. X  edgemap[LEFT][BACK].a = seed_left[5];
  1986. X  edgemap[LEFT][BACK].b = seed_back[3];
  1987. X
  1988. X  /* 7 */
  1989. X  edgemap[BACK][RIGHT].a = seed_back[5];
  1990. X  edgemap[BACK][RIGHT].b = seed_right[5];
  1991. X
  1992. X  edgemap[RIGHT][BACK].a = seed_right[5];
  1993. X  edgemap[RIGHT][BACK].b = seed_back[5];
  1994. X
  1995. X  /* 8 */
  1996. X  edgemap[BACK][BOTTOM].a = seed_back[7];
  1997. X  edgemap[BACK][BOTTOM].b = seed_bottom[7];
  1998. X
  1999. X  edgemap[BOTTOM][BACK].a = seed_bottom[7];
  2000. X  edgemap[BOTTOM][BACK].b = seed_back[7];
  2001. X
  2002. X  /* 9 */
  2003. X  edgemap[RIGHT][TOP].a = seed_right[1];
  2004. X  edgemap[RIGHT][TOP].b = seed_top[5];
  2005. X
  2006. X  edgemap[TOP][RIGHT].a = seed_top[5];
  2007. X  edgemap[TOP][RIGHT].b = seed_right[1];
  2008. X
  2009. X  /* 10 */
  2010. X  edgemap[RIGHT][BOTTOM].a = seed_right[7];
  2011. X  edgemap[RIGHT][BOTTOM].b = seed_bottom[5];
  2012. X
  2013. X  edgemap[BOTTOM][RIGHT].a = seed_bottom[5];
  2014. X  edgemap[BOTTOM][RIGHT].b = seed_right[7];
  2015. X
  2016. X  /* 11 */
  2017. X  edgemap[LEFT][BOTTOM].a = seed_left[7];
  2018. X  edgemap[LEFT][BOTTOM].b = seed_bottom[3];
  2019. X
  2020. X  edgemap[BOTTOM][LEFT].a = seed_bottom[3];
  2021. X  edgemap[BOTTOM][LEFT].b = seed_left[7];
  2022. X
  2023. X  /* 12 */
  2024. X  edgemap[LEFT][TOP].a = seed_left[1];
  2025. X  edgemap[LEFT][TOP].b = seed_top[3];
  2026. X  
  2027. X  edgemap[TOP][LEFT].a = seed_top[3];
  2028. X  edgemap[TOP][LEFT].b = seed_left[1];
  2029. X  
  2030. X}
  2031. X/* check_events:
  2032. X * This checks for Expose events and processes them.
  2033. X * Check_events is used in draw_it. 
  2034. X * When cube is being solved, expose events are checked for
  2035. X * and processed so that the buttons can be visible after
  2036. X * the the buttons have been 'exposed'. This could happen 
  2037. X * when windows get circulated through a stack during
  2038. X * the time the cube is solved.
  2039. X * 
  2040. X * test_for_event is a predicate procedure used by XCheckIfEvent.
  2041. X */
  2042. X
  2043. XBool test_for_event(display,event,event_type)
  2044. X     Display *display;
  2045. X     XEvent *event;
  2046. X     int    event_type;
  2047. X{
  2048. X  if(event->type == event_type)
  2049. X    return(True);
  2050. X  else
  2051. X    return(False);
  2052. X}
  2053. X
  2054. Xvoid check_events()
  2055. X{
  2056. X  if(XtAppPending(appContext) & XtIMXEvent){
  2057. X    XEvent event;
  2058. X    if(XCheckIfEvent(xDisplay,&event,test_for_event,Expose))
  2059. X      XtDispatchEvent(&event);
  2060. X  }
  2061. X}
  2062. X
  2063. END_OF_FILE
  2064.   if test 58594 -ne `wc -c <'cube/cube.c'`; then
  2065.     echo shar: \"'cube/cube.c'\" unpacked with wrong size!
  2066.   fi
  2067.   # end of 'cube/cube.c'
  2068. fi
  2069. echo shar: End of archive 2 \(of 5\).
  2070. cp /dev/null ark2isdone
  2071. MISSING=""
  2072. for I in 1 2 3 4 5 ; do
  2073.     if test ! -f ark${I}isdone ; then
  2074.     MISSING="${MISSING} ${I}"
  2075.     fi
  2076. done
  2077. if test "${MISSING}" = "" ; then
  2078.     echo You have unpacked all 5 archives.
  2079.     rm -f ark[1-9]isdone
  2080. else
  2081.     echo You still must unpack the following archives:
  2082.     echo "        " ${MISSING}
  2083. fi
  2084. exit 0
  2085. exit 0 # Just in case...
  2086.