home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 Mobile / Chip_Mobile_2001.iso / palm / business / cube3d / cube3D.exe / cube3D / src / cube3D.c next >
C/C++ Source or Header  |  2000-12-26  |  13KB  |  350 lines

  1. /*
  2.  * @(#)cube3D.c
  3.  *
  4.  * Copyright 1999-2000, Aaron Ardiri (mailto:aaron@ardiri.com)
  5.  * All rights reserved.
  6.  *
  7.  * The  source code  outlines a number of basic Palm Computing Programming
  8.  * principles and you  should be able to take the core structure and write 
  9.  * a large complex program. It is distributed WITHOUT ANY WARRANTY; use it
  10.  * "AS IS" and at your own risk.
  11.  *
  12.  * The code presented is Copyright 1999-2000 by Aaron Ardiri. It should be
  13.  * used for  educational purposes only.  You  shall not modify  the Cube3D 
  14.  * source code in any way and  re-distribute it as your  own,  however you
  15.  * are free to use  the code as  a guide for  developing  programs  on the 
  16.  * Palm Computing Platform.
  17.  */
  18.  
  19. #include "palm.h"
  20.  
  21. // global variable structure
  22. typedef struct
  23. {
  24.   Coord vertex[8][3];
  25.   Int16 dx, dy, dz;
  26. } CubeGlobals;
  27.  
  28. // interface
  29. static void CubePerspectiveConversion(Coord, Coord, Coord, Coord *, Coord *);
  30. static void CubeRotationAboutX(Coord, Coord, Coord, 
  31.                                Coord *, Coord *, Coord *, Int16);
  32. static void CubeRotationAboutY(Coord, Coord, Coord, 
  33.                                Coord *, Coord *, Coord *, Int16);
  34. static void CubeRotationAboutZ(Coord, Coord, Coord, 
  35.                                Coord *, Coord *, Coord *, Int16);
  36.  
  37. /**
  38.  * sin(x) table for 0 <= x < 360
  39.  * - values are generated using a 32 bit "fixed" type datatype
  40.  */
  41. static fixed
  42. sin_table[] = 
  43. {
  44. 0x00000000, 0x00000004, 0x00000008, 0x0000000d, 
  45. 0x00000011, 0x00000016, 0x0000001a, 0x0000001f, 
  46. 0x00000023, 0x00000028, 0x0000002c, 0x00000030, 
  47. 0x00000035, 0x00000039, 0x0000003d, 0x00000042, 
  48. 0x00000046, 0x0000004a, 0x0000004f, 0x00000053, 
  49. 0x00000057, 0x0000005b, 0x0000005f, 0x00000064, 
  50. 0x00000068, 0x0000006c, 0x00000070, 0x00000074, 
  51. 0x00000078, 0x0000007c, 0x00000080, 0x00000083, 
  52. 0x00000087, 0x0000008b, 0x0000008f, 0x00000092, 
  53. 0x00000096, 0x0000009a, 0x0000009d, 0x000000a1, 
  54. 0x000000a4, 0x000000a7, 0x000000ab, 0x000000ae, 
  55. 0x000000b1, 0x000000b5, 0x000000b8, 0x000000bb, 
  56. 0x000000be, 0x000000c1, 0x000000c4, 0x000000c6, 
  57. 0x000000c9, 0x000000cc, 0x000000cf, 0x000000d1, 
  58. 0x000000d4, 0x000000d6, 0x000000d9, 0x000000db, 
  59. 0x000000dd, 0x000000df, 0x000000e2, 0x000000e4, 
  60. 0x000000e6, 0x000000e8, 0x000000e9, 0x000000eb, 
  61. 0x000000ed, 0x000000ee, 0x000000f0, 0x000000f2, 
  62. 0x000000f3, 0x000000f4, 0x000000f6, 0x000000f7, 
  63. 0x000000f8, 0x000000f9, 0x000000fa, 0x000000fb, 
  64. 0x000000fc, 0x000000fc, 0x000000fd, 0x000000fe, 
  65. 0x000000fe, 0x000000ff, 0x000000ff, 0x000000ff, 
  66. 0x000000ff, 0x000000ff, 0x00000100, 0x000000ff, 
  67. 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 
  68. 0x000000fe, 0x000000fe, 0x000000fd, 0x000000fc, 
  69. 0x000000fc, 0x000000fb, 0x000000fa, 0x000000f9, 
  70. 0x000000f8, 0x000000f7, 0x000000f6, 0x000000f4, 
  71. 0x000000f3, 0x000000f2, 0x000000f0, 0x000000ee, 
  72. 0x000000ed, 0x000000eb, 0x000000e9, 0x000000e8, 
  73. 0x000000e6, 0x000000e4, 0x000000e2, 0x000000df, 
  74. 0x000000dd, 0x000000db, 0x000000d9, 0x000000d6, 
  75. 0x000000d4, 0x000000d1, 0x000000cf, 0x000000cc, 
  76. 0x000000c9, 0x000000c6, 0x000000c4, 0x000000c1, 
  77. 0x000000be, 0x000000bb, 0x000000b8, 0x000000b5, 
  78. 0x000000b1, 0x000000ae, 0x000000ab, 0x000000a7, 
  79. 0x000000a4, 0x000000a1, 0x0000009d, 0x0000009a, 
  80. 0x00000096, 0x00000092, 0x0000008f, 0x0000008b, 
  81. 0x00000087, 0x00000083, 0x0000007f, 0x0000007c, 
  82. 0x00000078, 0x00000074, 0x00000070, 0x0000006c, 
  83. 0x00000068, 0x00000064, 0x0000005f, 0x0000005b, 
  84. 0x00000057, 0x00000053, 0x0000004f, 0x0000004a, 
  85. 0x00000046, 0x00000042, 0x0000003d, 0x00000039, 
  86. 0x00000035, 0x00000030, 0x0000002c, 0x00000028, 
  87. 0x00000023, 0x0000001f, 0x0000001a, 0x00000016, 
  88. 0x00000011, 0x0000000d, 0x00000008, 0x00000004, 
  89. 0x00000000, 0xfffffffc, 0xfffffff8, 0xfffffff3, 
  90. 0xffffffef, 0xffffffea, 0xffffffe6, 0xffffffe1, 
  91. 0xffffffdd, 0xffffffd8, 0xffffffd4, 0xffffffd0, 
  92. 0xffffffcb, 0xffffffc7, 0xffffffc3, 0xffffffbe, 
  93. 0xffffffba, 0xffffffb6, 0xffffffb1, 0xffffffad, 
  94. 0xffffffa9, 0xffffffa5, 0xffffffa1, 0xffffff9c, 
  95. 0xffffff98, 0xffffff94, 0xffffff90, 0xffffff8c, 
  96. 0xffffff88, 0xffffff84, 0xffffff80, 0xffffff7d, 
  97. 0xffffff79, 0xffffff75, 0xffffff71, 0xffffff6e, 
  98. 0xffffff6a, 0xffffff66, 0xffffff63, 0xffffff5f, 
  99. 0xffffff5c, 0xffffff59, 0xffffff55, 0xffffff52, 
  100. 0xffffff4f, 0xffffff4b, 0xffffff48, 0xffffff45, 
  101. 0xffffff42, 0xffffff3f, 0xffffff3c, 0xffffff3a, 
  102. 0xffffff37, 0xffffff34, 0xffffff31, 0xffffff2f, 
  103. 0xffffff2c, 0xffffff2a, 0xffffff27, 0xffffff25, 
  104. 0xffffff23, 0xffffff21, 0xffffff1e, 0xffffff1c, 
  105. 0xffffff1a, 0xffffff18, 0xffffff17, 0xffffff15, 
  106. 0xffffff13, 0xffffff12, 0xffffff10, 0xffffff0e, 
  107. 0xffffff0d, 0xffffff0c, 0xffffff0a, 0xffffff09, 
  108. 0xffffff08, 0xffffff07, 0xffffff06, 0xffffff05, 
  109. 0xffffff04, 0xffffff04, 0xffffff03, 0xffffff02, 
  110. 0xffffff02, 0xffffff01, 0xffffff01, 0xffffff01, 
  111. 0xffffff01, 0xffffff01, 0xffffff00, 0xffffff01, 
  112. 0xffffff01, 0xffffff01, 0xffffff01, 0xffffff01, 
  113. 0xffffff02, 0xffffff02, 0xffffff03, 0xffffff04, 
  114. 0xffffff04, 0xffffff05, 0xffffff06, 0xffffff07, 
  115. 0xffffff08, 0xffffff09, 0xffffff0a, 0xffffff0c, 
  116. 0xffffff0d, 0xffffff0e, 0xffffff10, 0xffffff12, 
  117. 0xffffff13, 0xffffff15, 0xffffff17, 0xffffff18, 
  118. 0xffffff1a, 0xffffff1c, 0xffffff1e, 0xffffff21, 
  119. 0xffffff23, 0xffffff25, 0xffffff27, 0xffffff2a, 
  120. 0xffffff2c, 0xffffff2f, 0xffffff31, 0xffffff34, 
  121. 0xffffff37, 0xffffff3a, 0xffffff3c, 0xffffff3f, 
  122. 0xffffff42, 0xffffff45, 0xffffff48, 0xffffff4b, 
  123. 0xffffff4f, 0xffffff52, 0xffffff55, 0xffffff59, 
  124. 0xffffff5c, 0xffffff5f, 0xffffff63, 0xffffff66, 
  125. 0xffffff6a, 0xffffff6e, 0xffffff71, 0xffffff75, 
  126. 0xffffff79, 0xffffff7d, 0xffffff81, 0xffffff84, 
  127. 0xffffff88, 0xffffff8c, 0xffffff90, 0xffffff94, 
  128. 0xffffff98, 0xffffff9c, 0xffffffa1, 0xffffffa5, 
  129. 0xffffffa9, 0xffffffad, 0xffffffb1, 0xffffffb6, 
  130. 0xffffffba, 0xffffffbe, 0xffffffc3, 0xffffffc7, 
  131. 0xffffffcb, 0xffffffd0, 0xffffffd4, 0xffffffd8, 
  132. 0xffffffdd, 0xffffffe1, 0xffffffe6, 0xffffffea, 
  133. 0xffffffef, 0xfffffff3, 0xfffffff8, 0xfffffffc, 
  134. };
  135. #define ABS(a) (((a) > 0) ? (a) : -(a))
  136. static fixed cos_fx(Int16 deg) { return sin_table[ABS((deg+90)%360)]; }
  137. static fixed sin_fx(Int16 deg) { return sin_table[ABS(deg%360)]; }
  138.  
  139. /**
  140.  * Initialize the Cube3D engine.
  141.  *
  142.  * @param size the size of the cube.
  143.  */  
  144. void   
  145. CubeInitialize(Coord size)
  146. {
  147.   CubeGlobals *globals;
  148.  
  149.   // create the globals object, and register it
  150.   globals = (CubeGlobals *)MemPtrNew(sizeof(CubeGlobals));
  151.   MemSet(globals, sizeof(CubeGlobals), 0);
  152.   FtrSet(appCreator, ftrCubeGlobals, (UInt32)globals);
  153.  
  154.   // setup our cube (hardcoded sizes here :P)
  155.   globals->vertex[0][0] = -size;
  156.   globals->vertex[0][1] =  size;
  157.   globals->vertex[0][2] = -size;
  158.   globals->vertex[1][0] = -size;
  159.   globals->vertex[1][1] =  size;
  160.   globals->vertex[1][2] =  size;
  161.   globals->vertex[2][0] =  size;
  162.   globals->vertex[2][1] =  size;
  163.   globals->vertex[2][2] =  size;
  164.   globals->vertex[3][0] =  size;
  165.   globals->vertex[3][1] =  size;
  166.   globals->vertex[3][2] = -size;
  167.   globals->vertex[4][0] = -size;
  168.   globals->vertex[4][1] = -size;
  169.   globals->vertex[4][2] = -size;
  170.   globals->vertex[5][0] = -size;
  171.   globals->vertex[5][1] = -size;
  172.   globals->vertex[5][2] =  size;
  173.   globals->vertex[6][0] =  size;
  174.   globals->vertex[6][1] = -size;
  175.   globals->vertex[6][2] =  size;
  176.   globals->vertex[7][0] =  size;
  177.   globals->vertex[7][1] = -size;
  178.   globals->vertex[7][2] = -size;
  179.  
  180.   // reset the "angle" parameters
  181.   globals->dx = globals->dy = globals->dz = 0;
  182. }
  183.  
  184. /**
  185.  * Animate the Cube3D engine.
  186.  */
  187. void
  188. CubeAnimate()
  189. {
  190.   CubeGlobals *globals;
  191.   Coord       vertex[8][3];
  192.   Coord       points[8][2];
  193.   UInt16      i;
  194.  
  195.   // get a globals reference
  196.   FtrGet(appCreator, ftrCubeGlobals, (UInt32 *)&globals);
  197.  
  198.   // perform the "rotation" of the cube
  199.   for (i=0; i<8; i++) {
  200.     CubeRotationAboutX(
  201.       globals->vertex[i][0], globals->vertex[i][1], globals->vertex[i][2], 
  202.       &vertex[i][0],         &vertex[i][1],         &vertex[i][2],
  203.       globals->dx
  204.     );
  205.     CubeRotationAboutY(
  206.       vertex[i][0],          vertex[i][1],          vertex[i][2], 
  207.       &vertex[i][0],         &vertex[i][1],         &vertex[i][2],
  208.       globals->dy
  209.     );
  210.     CubeRotationAboutZ(
  211.       vertex[i][0],          vertex[i][1],          vertex[i][2], 
  212.       &vertex[i][0],         &vertex[i][1],         &vertex[i][2],
  213.       globals->dz
  214.     );
  215.   }
  216.  
  217.   // adjust the rotation angles
  218.   globals->dx += 2;
  219.   globals->dy += 1;
  220.   globals->dz += 3;
  221.  
  222.   // convert the cube from 3D to 2D using perspective geometry
  223.   for (i=0; i<8; i++) {
  224.  
  225.     CubePerspectiveConversion(vertex[i][0],  vertex[i][1],  vertex[i][2],
  226.                               &points[i][0], &points[i][1]);
  227.  
  228.     points[i][0] = points[i][0] + 80;
  229.     points[i][1] = 64 - points[i][1];  // position (0,0,0) in center
  230.                                        // - visible area is 160x128
  231.   }
  232.  
  233.   // draw the "cube"
  234.   WinDrawLine(points[0][0], points[0][1], points[1][0], points[1][1]);
  235.   WinDrawLine(points[0][0], points[0][1], points[3][0], points[3][1]);
  236.   WinDrawLine(points[0][0], points[0][1], points[4][0], points[4][1]);
  237.   WinDrawLine(points[2][0], points[2][1], points[1][0], points[1][1]);
  238.   WinDrawLine(points[2][0], points[2][1], points[3][0], points[3][1]);
  239.   WinDrawLine(points[2][0], points[2][1], points[6][0], points[6][1]);
  240.   WinDrawLine(points[5][0], points[5][1], points[1][0], points[1][1]);
  241.   WinDrawLine(points[5][0], points[5][1], points[4][0], points[4][1]);
  242.   WinDrawLine(points[5][0], points[5][1], points[6][0], points[6][1]);
  243.   WinDrawLine(points[7][0], points[7][1], points[3][0], points[3][1]);
  244.   WinDrawLine(points[7][0], points[7][1], points[4][0], points[4][1]);
  245.   WinDrawLine(points[7][0], points[7][1], points[6][0], points[6][1]);
  246. }
  247.  
  248. /**
  249.  * Terminate the Cube3D engine.
  250.  */
  251. void   
  252. CubeTerminate()
  253. {
  254.   CubeGlobals *globals;
  255.  
  256.   // get a globals reference
  257.   FtrGet(appCreator, ftrCubeGlobals, (UInt32 *)&globals);
  258.  
  259.   // clean up memory
  260.   MemPtrFree(globals);
  261.  
  262.   // unregister global data
  263.   FtrUnregister(appCreator, ftrCubeGlobals);
  264. }
  265.  
  266. /**
  267.  * Perform a simple perspective translation of a 3D point to 2D.
  268.  *
  269.  * @param x the x co-ordinate of the source point
  270.  * @param y the y co-ordinate of the source point
  271.  * @param z the z co-ordinate of the source point
  272.  * @param newX the x co-ordinate pointer of the rotated point
  273.  * @param newY the y co-ordinate pointer of the rotated point
  274.  */
  275. static void 
  276. CubePerspectiveConversion(Coord     x, Coord     y, Coord     z, 
  277.                           Coord *newX, Coord *newY)
  278. {
  279.   fixed _x, _y, _z;
  280.  
  281.   // NB: 333 and 250 value combinations give a good depth of field :))
  282.  
  283.   _x = itofx(x);
  284.   _y = itofx(-y);
  285.   _z = Addfx(itofx(-z), itofx(333));
  286.  
  287.   *newX = fxtoi(Divfx(Mulfx(itofx(250), _x), _z));
  288.   *newY = fxtoi(Divfx(Mulfx(itofx(250), _y), _z));
  289. }
  290.  
  291. /**
  292.  * Rotate a 3D point around the X plane.
  293.  *
  294.  * @param x the x co-ordinate of the source point
  295.  * @param y the y co-ordinate of the source point
  296.  * @param z the z co-ordinate of the source point
  297.  * @param newX the x co-ordinate pointer of the rotated point
  298.  * @param newY the y co-ordinate pointer of the rotated point
  299.  * @param newZ the z co-ordinate pointer of the rotated point
  300.  * @param d the angle of rotation.
  301.  */
  302. static void 
  303. CubeRotationAboutX(Coord     x, Coord     y, Coord     z, 
  304.                    Coord *newX, Coord *newY, Coord *newZ, Int16 d)
  305. {
  306.   *newX = x;
  307.   *newY = fxtoi(Addfx(Mulfx( cos_fx(d),itofx(y)),Mulfx( sin_fx(d),itofx(z))));
  308.   *newZ = fxtoi(Addfx(Mulfx(-sin_fx(d),itofx(y)),Mulfx( cos_fx(d),itofx(z))));
  309. }
  310.  
  311. /**
  312.  * Rotate a 3D point around the Y plane.
  313.  *
  314.  * @param x the x co-ordinate of the source point
  315.  * @param y the y co-ordinate of the source point
  316.  * @param z the z co-ordinate of the source point
  317.  * @param newX the x co-ordinate pointer of the rotated point
  318.  * @param newY the y co-ordinate pointer of the rotated point
  319.  * @param newZ the z co-ordinate pointer of the rotated point
  320.  * @param d the angle of rotation.
  321.  */
  322. static void 
  323. CubeRotationAboutY(Coord     x, Coord     y, Coord     z, 
  324.                    Coord *newX, Coord *newY, Coord *newZ, Int16 d)
  325. {
  326.   *newX = fxtoi(Addfx(Mulfx( cos_fx(d),itofx(x)),Mulfx(-sin_fx(d),itofx(z))));
  327.   *newY = y;
  328.   *newZ = fxtoi(Addfx(Mulfx( sin_fx(d),itofx(x)),Mulfx( cos_fx(d),itofx(z))));
  329. }
  330.  
  331. /**
  332.  * Rotate a 3D point around the Z plane.
  333.  *
  334.  * @param x the x co-ordinate of the source point
  335.  * @param y the y co-ordinate of the source point
  336.  * @param z the z co-ordinate of the source point
  337.  * @param newX the x co-ordinate pointer of the rotated point
  338.  * @param newY the y co-ordinate pointer of the rotated point
  339.  * @param newZ the z co-ordinate pointer of the rotated point
  340.  * @param d the angle of rotation.
  341.  */
  342. static void 
  343. CubeRotationAboutZ(Coord     x, Coord     y, Coord     z, 
  344.                    Coord *newX, Coord *newY, Coord *newZ, Int16 d)
  345. {
  346.   *newX = fxtoi(Addfx(Mulfx( cos_fx(d),itofx(x)),Mulfx( sin_fx(d),itofx(y))));
  347.   *newY = fxtoi(Addfx(Mulfx(-sin_fx(d),itofx(x)),Mulfx( cos_fx(d),itofx(y))));
  348.   *newZ = z;
  349. }
  350.