Example for the LPC4088 QSB Base Board

Dependencies:   EALib mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers CubeDemo.cpp Source File

CubeDemo.cpp

00001 /******************************************************************************
00002  * Includes
00003  *****************************************************************************/
00004 
00005 #include "mbed.h"
00006 
00007 #include "LcdController.h"
00008 #include "EaLcdBoard.h"
00009 #include "CubeDemo.h"
00010 
00011 #include "Image.h"
00012 
00013 //#include "wchar.h"
00014 #include <math.h>
00015 
00016 
00017 extern const unsigned char cube_image1[];
00018 extern int cube_image1_sz;
00019 extern const unsigned char cube_image2[];
00020 extern int cube_image2_sz;
00021 
00022 
00023 /******************************************************************************
00024  * Typedefs and defines
00025  *****************************************************************************/
00026 
00027 /******************************************************************************
00028  * Local variables
00029  *****************************************************************************/
00030 
00031 
00032 /******************************************************************************
00033  * External variables
00034  *****************************************************************************/
00035 extern EaLcdBoard lcdBoard;
00036 extern bool abortTest;
00037 
00038 /******************************************************************************
00039  * Local functions
00040  *****************************************************************************/
00041 
00042 
00043 
00044 
00045 /* (c) 2008 by Denis Markovic
00046    I give hereby permission to Anders Rosvall of Embedded Artists to use this function in his ARM7 board
00047    demo program, as long as I'm not hold responsible for bugs in the code and I take not responsibility
00048    for any damage used by that code :-) */
00049 
00050 #define TRIANG_PROJ_SFT 16
00051 
00052 static unsigned short DivTab[] =
00053 {0xffff, 0x7fff, 0x5554, 0x3fff, 0x3332, 0x2aa9, 0x2491,
00054   0x1fff, 0x1c70, 0x1998, 0x1744, 0x1554, 0x13b0, 0x1248, 0x1110,
00055   0x0fff, 0x0f0e, 0x0e37, 0x0d78, 0x0ccb, 0x0c2f, 0x0ba1, 0x0b20,
00056   0x0aa9, 0x0a3c, 0x09d7, 0x097a, 0x0923, 0x08d2, 0x0887, 0x0841,
00057   0x07ff, 0x07c0, 0x0786, 0x074f, 0x071b, 0x06ea, 0x06bb, 0x068f,
00058   0x0665, 0x063d, 0x0617, 0x05f3, 0x05d0, 0x05af, 0x058f, 0x0571,
00059   0x0554, 0x0538, 0x051d, 0x0504, 0x04eb, 0x04d3, 0x04bc, 0x04a6,
00060   0x0491, 0x047c, 0x0468, 0x0455, 0x0443, 0x0431, 0x0420, 0x040f,
00061   0x03ff, 0x03ef, 0x03df, 0x03d1, 0x03c2, 0x03b4, 0x03a7, 0x039a,
00062   0x038d, 0x0380, 0x0374, 0x0368, 0x035d, 0x0352, 0x0347, 0x033c,
00063   0x0332, 0x0328, 0x031e, 0x0314, 0x030b, 0x0302, 0x02f9, 0x02f0,
00064   0x02e7, 0x02df, 0x02d7, 0x02cf, 0x02c7, 0x02bf, 0x02b8, 0x02b0,
00065   0x02a9, 0x02a2, 0x029b, 0x0294, 0x028e, 0x0287, 0x0281, 0x027b,
00066   0x0275, 0x026f, 0x0269, 0x0263, 0x025d, 0x0258, 0x0252, 0x024d,
00067   0x0248, 0x0242, 0x023d, 0x0238, 0x0233, 0x022f, 0x022a, 0x0225,
00068   0x0221, 0x021c, 0x0218, 0x0213, 0x020f, 0x020b, 0x0207, 0x0203,
00069   0x01ff, 0x01fb, 0x01f7, 0x01f3, 0x01ef, 0x01eb, 0x01e8, 0x01e4,
00070   0x01e0, 0x01dd, 0x01d9, 0x01d6, 0x01d3, 0x01cf, 0x01cc, 0x01c9,
00071   0x01c6, 0x01c2, 0x01bf, 0x01bc, 0x01b9, 0x01b6, 0x01b3, 0x01b1,
00072   0x01ae, 0x01ab, 0x01a8, 0x01a5, 0x01a3, 0x01a0, 0x019d, 0x019b,
00073   0x0198, 0x0196, 0x0193, 0x0191, 0x018e, 0x018c, 0x0189, 0x0187,
00074   0x0185, 0x0182, 0x0180, 0x017e, 0x017c, 0x0179, 0x0177, 0x0175,
00075   0x0173, 0x0171, 0x016f, 0x016d, 0x016b, 0x0169, 0x0167, 0x0165,
00076   0x0163, 0x0161, 0x015f, 0x015d, 0x015b, 0x0159, 0x0157, 0x0156,
00077   0x0154, 0x0152, 0x0150, 0x014f, 0x014d, 0x014b, 0x0149, 0x0148,
00078   0x0146, 0x0145, 0x0143, 0x0141, 0x0140, 0x013e, 0x013d, 0x013b,
00079   0x013a, 0x0138, 0x0137, 0x0135, 0x0134, 0x0132, 0x0131, 0x012f,
00080   0x012e, 0x012d, 0x012b, 0x012a, 0x0128, 0x0127, 0x0126, 0x0124,
00081   0x0123, 0x0122, 0x0120, 0x011f, 0x011e, 0x011d, 0x011b, 0x011a,
00082   0x0119, 0x0118, 0x0117, 0x0115, 0x0114, 0x0113, 0x0112, 0x0111,
00083   0x0110, 0x010e, 0x010d, 0x010c, 0x010b, 0x010a, 0x0109, 0x0108,
00084   0x0107, 0x0106, 0x0105, 0x0104, 0x0103, 0x0102, 0x0101, 0x0100,
00085   0x00ff, 0x00fe, 0x00fd, 0x00fc, 0x00fb, 0x00fa, 0x00f9, 0x00f8,
00086   0x00f7, 0x00f6, 0x00f5, 0x00f4, 0x00f3, 0x00f2, 0x00f1, 0x00f0,
00087   0x00ef, 0x00ef, 0x00ee, 0x00ed, 0x00ec, 0x00eb, 0x00ea, 0x00e9,
00088   0x00e9, 0x00e8, 0x00e7, 0x00e6, 0x00e5, 0x00e4, 0x00e4, 0x00e3,
00089   0x00e2, 0x00e1, 0x00e0, 0x00e0, 0x00df, 0x00de, 0x00dd, 0x00dd,
00090   0x00dc, 0x00db, 0x00da, 0x00da, 0x00d9, 0x00d8, 0x00d8, 0x00d7,
00091   0x00d6, 0x00d5, 0x00d5, 0x00d4, 0x00d3, 0x00d3, 0x00d2, 0x00d1,
00092   0x00d1, 0x00d0, 0x00cf, 0x00cf, 0x00ce, 0x00cd, 0x00cd, 0x00cc,
00093   0x00cb, 0x00cb, 0x00ca, 0x00c9, 0x00c9, 0x00c8, 0x00c8, 0x00c7,
00094   0x00c6, 0x00c6, 0x00c5, 0x00c4, 0x00c4, 0x00c3, 0x00c3, 0x00c2,
00095   0x00c2, 0x00c1, 0x00c0, 0x00c0, 0x00bf, 0x00bf, 0x00be, 0x00be,
00096   0x00bd, 0x00bc, 0x00bc, 0x00bb, 0x00bb, 0x00ba, 0x00ba, 0x00b9,
00097   0x00b9, 0x00b8, 0x00b8, 0x00b7, 0x00b7, 0x00b6, 0x00b6, 0x00b5,
00098   0x00b5, 0x00b4, 0x00b4, 0x00b3, 0x00b3, 0x00b2, 0x00b2, 0x00b1,
00099   0x00b1, 0x00b0, 0x00b0, 0x00af, 0x00af, 0x00ae, 0x00ae, 0x00ad,
00100   0x00ad, 0x00ac, 0x00ac, 0x00ab, 0x00ab, 0x00ab, 0x00aa, 0x00aa,
00101   0x00a9, 0x00a9, 0x00a8, 0x00a8, 0x00a7, 0x00a7, 0x00a7, 0x00a6,
00102   0x00a6, 0x00a5, 0x00a5, 0x00a4, 0x00a4, 0x00a4, 0x00a3, 0x00a3,
00103   0x00a2, 0x00a2, 0x00a2, 0x00a1, 0x00a1, 0x00a0, 0x00a0, 0x00a0,
00104   0x009f, 0x009f, 0x009e, 0x009e, 0x009e, 0x009d, 0x009d, 0x009c,
00105   0x009c, 0x009c, 0x009b, 0x009b, 0x009b, 0x009a, 0x009a, 0x0099,
00106   0x0099, 0x0099, 0x0098, 0x0098, 0x0098, 0x0097, 0x0097, 0x0097,
00107   0x0096, 0x0096, 0x0096, 0x0095, 0x0095, 0x0094, 0x0094, 0x0094,
00108   0x0093, 0x0093, 0x0093, 0x0092, 0x0092, 0x0092, 0x0091, 0x0091,
00109   0x0091, 0x0090, 0x0090, 0x0090, 0x008f, 0x008f, 0x008f, 0x008f,
00110   0x008e, 0x008e, 0x008e, 0x008d, 0x008d, 0x008d, 0x008c, 0x008c,
00111   0x008c, 0x008b, 0x008b, 0x008b, 0x008b, 0x008a, 0x008a, 0x008a,
00112   0x0089, 0x0089, 0x0089, 0x0088, 0x0088, 0x0088, 0x0088, 0x0087,
00113   0x0087, 0x0087, 0x0086, 0x0086, 0x0086, 0x0086, 0x0085, 0x0085,
00114   0x0085, 0x0085, 0x0084, 0x0084, 0x0084, 0x0083, 0x0083, 0x0083,
00115   0x0083, 0x0082, 0x0082, 0x0082, 0x0082, 0x0081, 0x0081, 0x0081,
00116   0x0081, 0x0080, 0x0080, 0x0080, 0x0080, 0x007f, 0x007f, 0x007f,
00117 };
00118 
00119 /* (c) 2008 by Denis Markovic
00120    I give hereby permission to Anders Rosvall of Embedded Artists to use this function in his ARM7 board
00121    demo program, as long as I'm not hold responsible for bugs in the code and I take not responsibility
00122    for any damage used by that code :-) */
00123 void CubeDemo::CpPixel16Fast(int xSrc, int ySrc, int x, int y, Surface_t *SrcRP_p, Surface_t *DstRP_p)
00124 {
00125   unsigned short *src_p, *dst_p;
00126 
00127   src_p = (unsigned short *) SrcRP_p->pixels;
00128   dst_p = (unsigned short *) DstRP_p->pixels;
00129 
00130   dst_p[y * DstRP_p->w + x] = src_p[ySrc * SrcRP_p->w + xSrc];
00131 
00132   return;
00133 }
00134 
00135 /* (c) 2008 by Denis Markovic
00136    I give hereby permission to Anders Rosvall of Embedded Artists to use this function in his ARM7 board
00137    demo program, as long as I'm not hold responsible for bugs in the code and I take not responsibility
00138    for any damage used by that code :-)
00139 
00140    Input: SrcRP_p: pointer to type holding width and height and ptr to source pixel data
00141           DstRP_p: pointer to type holding width and height and ptr to destination pixel data (i.e. gfx memory to draw to)
00142           SrcCoords_p: pointer to array holding 3 source coordinates into triangle source accessed through SrcRP_p
00143           DstCoords_p: pointer to array holding 3 destination triangle coordinates in draw buffer which is accessed through DstRP_p
00144 
00145    Description: take triangle from source rectangular picture (raw data, 16 bit) and project it into a triangle
00146                 in the destination picture (also 16 bit)
00147  */
00148 void CubeDemo::TriangleProjectFast(Surface_t *SrcRP_p, Surface_t *DstRP_p, Coord2D_t *SrcCoords_p,  Coord2D_t *DstCoords_p)
00149 {
00150   int TopCoord = 0, MiddleCoord = 1, BottomCoord = 2;
00151   int /*SrcStartX, SrcStartY,*/ x, y, Direction, i, j;
00152   long dxDstBig, dxDstSmall, dxSrcBig, dxSrcSmall, dySrcBig, dySrcSmall, DeltaY;
00153   int DivMultVal;
00154 
00155   /* 1. step: sort dst triangle points */
00156   if(DstCoords_p[1].y <  DstCoords_p[TopCoord].y)
00157   {
00158     TopCoord = 1;
00159     MiddleCoord = 0;
00160   }
00161 
00162   if(DstCoords_p[2].y <  DstCoords_p[TopCoord].y)
00163   {
00164     TopCoord = 2;
00165     BottomCoord = 1;
00166     MiddleCoord = 0;
00167   }
00168 
00169   if(DstCoords_p[BottomCoord].y < DstCoords_p[MiddleCoord].y)
00170   {
00171     int tmp;
00172     tmp = MiddleCoord;
00173     MiddleCoord = BottomCoord;
00174     BottomCoord = tmp;
00175   }
00176 
00177   /* so now we have the 3 sorted dst triangle points in TopCoord, MiddleCoord and BottomCoord
00178      (can be done much more efficient with arithmetics instead of if or use pos/neg direction
00179      vectors later?) */
00180 
00181   /* 2. step: find start and end points for this line in src and dst triangle for each
00182      line; start pt always on a line that originates from middle point; later replace
00183      all div by mult with 1/DeltaY, i.e. only one division, maybe even save 1/... in
00184      Tab as there are not so many possible DeltaY */
00185   DeltaY = (long) DstCoords_p[BottomCoord].y - DstCoords_p[TopCoord].y + 1;
00186 
00187   DivMultVal = ((int) DivTab[DeltaY-1] + 1);
00188 
00189   dxDstBig   = ((long) DstCoords_p[BottomCoord].x - DstCoords_p[TopCoord].x + 1) * DivMultVal;
00190   dySrcBig   = ((long) SrcCoords_p[BottomCoord].y - SrcCoords_p[TopCoord].y + 1) * DivMultVal;
00191   dxSrcBig   = ((long) SrcCoords_p[BottomCoord].x - SrcCoords_p[TopCoord].x + 1) * DivMultVal;
00192 
00193   DeltaY = (long) DstCoords_p[MiddleCoord].y - DstCoords_p[TopCoord].y + 1;
00194 
00195   DivMultVal = ((int) DivTab[DeltaY-1] + 1);
00196 
00197   dxDstSmall = ((long) DstCoords_p[MiddleCoord].x - DstCoords_p[TopCoord].x + 1) * DivMultVal;
00198   dySrcSmall = ((long) SrcCoords_p[MiddleCoord].y - SrcCoords_p[TopCoord].y + 1) * DivMultVal;
00199   dxSrcSmall = ((long) SrcCoords_p[MiddleCoord].x - SrcCoords_p[TopCoord].x + 1) * DivMultVal;
00200 
00201   Direction = 1;
00202   if(dxDstSmall > dxDstBig)
00203     Direction = -1;
00204 
00205   for(y = DstCoords_p[TopCoord].y, i=0; y <= DstCoords_p[MiddleCoord].y; y++, i++)
00206   { /* for each row/line */
00207     long MoveSrcX, MoveSrcY, P1x, P2x, P1y, P2y, SrcDeltaSteps;
00208 
00209     //SrcStartX = SrcCoords_p[TopCoord].x;
00210 
00211     P1x = SrcCoords_p[TopCoord].x + ((i * dxSrcSmall)>>TRIANG_PROJ_SFT);
00212     P1y = SrcCoords_p[TopCoord].y + ((i * dySrcSmall)>>TRIANG_PROJ_SFT);
00213     P2x = SrcCoords_p[TopCoord].x + ((i * dxSrcBig)>>TRIANG_PROJ_SFT);
00214     P2y = SrcCoords_p[TopCoord].y + ((i * dySrcBig)>>TRIANG_PROJ_SFT);
00215 
00216     {
00217       int xx;
00218 
00219       x  = DstCoords_p[TopCoord].x + ((i * dxDstSmall)>>TRIANG_PROJ_SFT);
00220       xx = DstCoords_p[TopCoord].x + ((i * dxDstBig)  >>TRIANG_PROJ_SFT);
00221 
00222       SrcDeltaSteps = xx - x;
00223       if(SrcDeltaSteps < 0)
00224     SrcDeltaSteps = -SrcDeltaSteps;
00225 
00226       SrcDeltaSteps++;
00227 
00228       DivMultVal = ((int) DivTab[SrcDeltaSteps-1] + 1);
00229 
00230       MoveSrcX = (P2x - P1x) * DivMultVal;
00231       MoveSrcY = (P2y - P1y) * DivMultVal;
00232 
00233       x-= Direction;
00234 
00235       P1x <<= TRIANG_PROJ_SFT;
00236       P1y <<= TRIANG_PROJ_SFT;
00237 
00238       do
00239       {
00240     x+= Direction;
00241 
00242     CpPixel16Fast(P1x >>TRIANG_PROJ_SFT, P1y >>TRIANG_PROJ_SFT, x, y, SrcRP_p, DstRP_p);
00243 
00244     P1x += MoveSrcX;
00245     P1y += MoveSrcY;
00246 
00247       } while(x!=xx);
00248     }
00249   }
00250 
00251   /* second part of triangle from middle to bottom */
00252   DeltaY = (long) DstCoords_p[BottomCoord].y - DstCoords_p[MiddleCoord].y+1;
00253 
00254   DivMultVal = ((int) DivTab[DeltaY-1] + 1);
00255 
00256   dxDstSmall = ((long) DstCoords_p[BottomCoord].x - DstCoords_p[MiddleCoord].x + 1) * DivMultVal;
00257   dySrcSmall = ((long) SrcCoords_p[BottomCoord].y - SrcCoords_p[MiddleCoord].y + 1) * DivMultVal;
00258   dxSrcSmall = ((long) SrcCoords_p[BottomCoord].x - SrcCoords_p[MiddleCoord].x + 1) * DivMultVal;
00259 
00260   y--;
00261   i--;
00262 
00263   for(j=0; y <= DstCoords_p[BottomCoord].y; y++, i++, j++)
00264   { /* for each row/line */
00265     long MoveSrcX, MoveSrcY, P1x, P2x, P1y, P2y, SrcDeltaSteps;
00266 
00267     //SrcStartX = SrcCoords_p[MiddleCoord].x;
00268 
00269     P1x = SrcCoords_p[MiddleCoord].x + ((j * dxSrcSmall)>>TRIANG_PROJ_SFT);
00270     P1y = SrcCoords_p[MiddleCoord].y + ((j * dySrcSmall)>>TRIANG_PROJ_SFT);
00271     P2x = SrcCoords_p[TopCoord].x + ((i * dxSrcBig)>>TRIANG_PROJ_SFT);
00272     P2y = SrcCoords_p[TopCoord].y + ((i * dySrcBig)>>TRIANG_PROJ_SFT);
00273 
00274     {
00275       int xx;
00276 
00277       x  = DstCoords_p[MiddleCoord].x + ((j * dxDstSmall)>>TRIANG_PROJ_SFT);
00278       xx = DstCoords_p[TopCoord].x    + ((i * dxDstBig)  >>TRIANG_PROJ_SFT);
00279 
00280       SrcDeltaSteps = xx - x;
00281 
00282       /* todo, fixme: direction should not have to be set here but if we do not
00283          do it here, sometimes calc fails, investigate (problem case: dst coords
00284          250/299, 321/302, 472/308 and src coord 0/0, bike w-1, 0, bike w-1/bike h-1 */
00285       if(SrcDeltaSteps < 0)
00286       {
00287     SrcDeltaSteps = -SrcDeltaSteps;
00288     Direction = -1;
00289       }
00290       else
00291     Direction = 1;
00292 
00293       SrcDeltaSteps++;
00294 
00295       DivMultVal = ((int) DivTab[SrcDeltaSteps-1] + 1);
00296 
00297       MoveSrcX = (P2x - P1x) * DivMultVal;
00298       MoveSrcY = (P2y - P1y) * DivMultVal;
00299 
00300       x-= Direction;
00301 
00302       P1x <<= TRIANG_PROJ_SFT;
00303       P1y <<= TRIANG_PROJ_SFT;
00304 
00305       do
00306       {
00307     x+= Direction;
00308 
00309     CpPixel16Fast(P1x >>TRIANG_PROJ_SFT, P1y >>TRIANG_PROJ_SFT, x, y, SrcRP_p, DstRP_p);
00310 
00311     P1x += MoveSrcX;
00312     P1y += MoveSrcY;
00313 
00314       } while(x!=xx);
00315     }
00316   }
00317 
00318   return;
00319 }
00320 
00321 
00322 short CubeDemo::_sin(short y) const {
00323     static short s1 = 0x6487;
00324     static short s3 = 0x2951;
00325     static short s5 = 0x4f6;
00326     long z, prod, sum;
00327 
00328     z = ((long)y * y) >> 12;
00329     prod = (z * s5) >> 16;
00330     sum = s3 - prod;
00331     prod = (z * sum) >> 16;
00332     sum = s1 - prod;
00333 
00334     // for better accuracy, round here
00335     return (short)((y * sum) >> 13);
00336  }
00337 
00338 short CubeDemo::_cos(short y) const {
00339     static short c0 = 0x7fff;
00340     static short c2 = 0x4eea;
00341     static short c4 = 0x0fc4;
00342     long z, prod, sum;
00343     z = ((long)y * y) >> 12;
00344     prod = (z * c4) >> 16;
00345     sum = c2 - prod;
00346 
00347     // for better accuracy, round here
00348     prod = (z * sum) >> 15;
00349     return (short)(c0 - prod);
00350 }
00351 
00352 short CubeDemo::isine(short x) const {
00353     unsigned short n = (((unsigned short)x + 0x2000) >> 14) & 0x3;
00354     x -= n * 0x4000;
00355     switch(n){
00356         case 0:
00357             return _sin(x);
00358         case 1:
00359             return _cos(x);
00360         case 2:
00361             return - _sin(x);
00362         case 3:
00363             return  - _cos(x);
00364     }
00365     return 0;
00366  }
00367 
00368 
00369 short CubeDemo::icosine(short x) const {
00370     return isine(x + 0x4000);
00371  }
00372 
00373 int32_t CubeDemo::sgn(int32_t val) const
00374 {
00375   if (val > 0) return 1;
00376   else if (val < 0) return -1;
00377   else return 0;
00378 }
00379 
00380 void CubeDemo::createCubeModel(uint32_t radius)
00381 {
00382   uint32_t i,j;
00383   uint32_t theta, dTheta;
00384   static uint8_t cubeConnect[24] = {
00385     0, 1, 2, 3,
00386     1, 5, 6, 2,
00387     5, 4, 7, 6,
00388     4, 0, 3, 7,
00389     4, 5, 1, 0,
00390     3, 2, 6, 7};
00391 
00392   theta  = 0x2000; //PI/4
00393   dTheta = 0x4000; //PI/2
00394 
00395   for(i=0; i<8; i++)
00396   {
00397     cubeModel[i].x = radius * sgn(icosine(theta));
00398     cubeModel[i].y = radius * sgn(isine(theta));
00399     cubeModel[i].z = radius - (2 * radius) * (i / 4);
00400     theta += dTheta;
00401   }
00402 
00403   j=0;
00404   for(i=0; i<6; i++)
00405   {
00406     cubePoly[j].p1 = cubeConnect[i*4 + 3];
00407     cubePoly[j].p2 = cubeConnect[i*4 + 1];
00408     cubePoly[j].p3 = cubeConnect[i*4 + 0];
00409     j++;
00410     cubePoly[j].p1 = cubeConnect[i*4 + 3];
00411     cubePoly[j].p2 = cubeConnect[i*4 + 2];
00412     cubePoly[j].p3 = cubeConnect[i*4 + 1];
00413     j++;
00414   }
00415 }
00416 
00417 void CubeDemo::rotateAndProject(uint16_t rotX, uint16_t rotY, uint16_t rotZ)
00418 {
00419   uint32_t i;
00420   long crx,srx,cry,sry,crz,srz;
00421   long x,y,z,tx,ty,tz;
00422   long distance;
00423 
00424   crx = icosine(rotX);
00425   srx = isine(rotX);
00426   cry = icosine(rotY);
00427   sry = isine(rotY);
00428   crz = icosine(rotZ);
00429   srz = isine(rotZ);
00430   
00431   for (i=0;i<8;i++)
00432   {
00433         //--> rotate around y-axis              
00434 //      var tempX = (this.x * Math.cos(rY)) - (this.z * Math.sin(rY));
00435 //      var tempZ = (this.x * Math.sin(rY)) + (this.z * Math.cos(rY));
00436 
00437         //--> rotate around x-axis      
00438 //      this.dz  =  (tempZ * Math.cos(rX)) - (this.y * Math.sin(rX));
00439 //      var tempY =  (tempZ * Math.sin(rX)) + (this.y * Math.cos(rX));
00440 
00441         //--> rotate around z-axis
00442 //      this.dx =  (tempX * Math.cos(rZ)) + (tempY * Math.sin(rZ));
00443 //      this.dy =  (tempY * Math.cos(rZ)) - (tempX * Math.sin(rZ));
00444         
00445 
00446     x = cubeModel[i].x;
00447     y = cubeModel[i].y;
00448     z = cubeModel[i].z;
00449     
00450         //--> rotate around y-axis
00451     tx = (z*sry + x*cry) / 0x7fff;
00452     tz = (z*cry - x*sry) / 0x7fff;
00453 
00454         //--> rotate around x-axis
00455     cubeModel[i].zr = (y*srx + tz*crx) / 0x7fff;
00456     ty              = (y*crx - tz*srx) / 0x7fff;
00457 
00458         //--> rotate around z-axis
00459     cubeModel[i].xr = (tx*crz - ty*srz) / 0x7fff;
00460     cubeModel[i].yr = (tx*srz + ty*crz) / 0x7fff;
00461 
00462     cubeModel[i].xr -= camX;
00463     cubeModel[i].yr -= camY;
00464     cubeModel[i].zr -= camZ;
00465 
00466     distance = LENS - cubeModel[i].zr;
00467     if (distance > 0)
00468     {
00469       cubeModel[i].scrx = X_OFFSET + (LENS * cubeModel[i].xr) / distance;
00470       cubeModel[i].scry = Y_OFFSET + (LENS * cubeModel[i].yr) / distance;
00471     }
00472   }
00473 }
00474 
00475 void CubeDemo::drawCubeZ(Surface_t *pSourcePicture, uint8_t shades)
00476 {
00477   uint32_t i;
00478   int32_t  x1,x2,x3,y1,y2,y3,/*u1,u2,u3,v1,v2,v3,*/znormal;
00479   
00480   activeFrame.w = this->windowX;
00481   activeFrame.h = this->windowY;
00482   activeFrame.pixels = (uint16_t*)this->pFrmBuf;
00483 
00484   for(i=0; i<12; i++)
00485   {
00486     x1 = cubeModel[cubePoly[i].p1].scrx;  //Get triangles from "projected"
00487     x2 = cubeModel[cubePoly[i].p2].scrx;  //X and Y coords since Znormal
00488     x3 = cubeModel[cubePoly[i].p3].scrx;  //Does not require a Z coord
00489     y1 = cubeModel[cubePoly[i].p1].scry;  //V1= Point1 connected to V2 then
00490     y2 = cubeModel[cubePoly[i].p2].scry;  //V2 to V3 and so on...
00491     y3 = cubeModel[cubePoly[i].p3].scry;
00492 
00493     znormal = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3);
00494     if (znormal > 0)
00495     {
00496       //no texture?
00497       if (pSourcePicture == NULL)
00498       {
00499         if (shades == 0)
00500         {
00501           if ((cubePoly[i].p1 == 0) && (cubePoly[i].p2 == 1))
00502             graphics.put_line( cubeModel[cubePoly[i].p1].scrx, cubeModel[cubePoly[i].p1].scry, cubeModel[cubePoly[i].p2].scrx, cubeModel[cubePoly[i].p2].scry, RED);
00503           else
00504             graphics.put_line( cubeModel[cubePoly[i].p1].scrx, cubeModel[cubePoly[i].p1].scry, cubeModel[cubePoly[i].p2].scrx, cubeModel[cubePoly[i].p2].scry, SMALL_CIRCLE_FRONT_COLOR);
00505           graphics.put_line( cubeModel[cubePoly[i].p2].scrx, cubeModel[cubePoly[i].p2].scry, cubeModel[cubePoly[i].p3].scrx, cubeModel[cubePoly[i].p3].scry, SMALL_CIRCLE_FRONT_COLOR);
00506           graphics.put_line( cubeModel[cubePoly[i].p3].scrx, cubeModel[cubePoly[i].p3].scry, cubeModel[cubePoly[i].p1].scrx, cubeModel[cubePoly[i].p1].scry, SMALL_CIRCLE_FRONT_COLOR);
00507         }
00508         else
00509         {
00510           Coord2D_t SrcCoords[3], DstCoords[3];
00511           Surface_t a;
00512           static uint16_t pix;
00513 
00514           a.w = this->windowX;
00515           a.h = this->windowY;
00516           a.pixels = &pix;
00517           if ((i&1) == 0)
00518           {
00519             if ((znormal / 400) > 31)
00520               pix = 0x1f << 11;
00521             else
00522               pix = (znormal / 400 & 0x1f) << 11;
00523           }
00524           SrcCoords[0].x = 0;
00525           SrcCoords[0].y = 0;
00526           SrcCoords[1].x = 0;
00527           SrcCoords[1].y = 0;
00528           SrcCoords[2].x = 0;
00529           SrcCoords[2].y = 0;
00530           DstCoords[0].x = cubeModel[cubePoly[i].p1].scrx;
00531           DstCoords[0].y = cubeModel[cubePoly[i].p1].scry;
00532           DstCoords[1].x = cubeModel[cubePoly[i].p2].scrx;
00533           DstCoords[1].y = cubeModel[cubePoly[i].p2].scry;
00534           DstCoords[2].x = cubeModel[cubePoly[i].p3].scrx;
00535           DstCoords[2].y = cubeModel[cubePoly[i].p3].scry;
00536           TriangleProjectFast(&a, &activeFrame, SrcCoords, DstCoords);
00537         }
00538       }
00539       
00540       //Render with texture
00541       else
00542       {
00543         Coord2D_t SrcCoords[3], DstCoords[3];
00544 #if 1
00545         /*
00546          *       Image in the file
00547          *  0,0_______ _______ _______
00548          *    |       |       |      *|                   
00549          *    |       |       |       |                   Image as it is used
00550          *    |_______|_______|_______|                 _______ _______ _______ _______
00551          *    |       |       |       |        \       |*      |       |       |       |
00552          *    |       |       |       |         \      |       | top   |       |       |
00553          *    |_______|_______|_______|    ======      |_______|_______|_______|_______|
00554          *    |       |       |       |         /      |       |       |       |       |
00555          *    |       |       |       |        /       | side1 | side2 | side3 | side4 |
00556          *    |_______|_______|_______|                |_______|_______|_______|_______|
00557          *    |       |       |       |                |       |       |       |       |
00558          *    |       |       |       |                |       | bottom|       |       |
00559          *    |_______|_______|_______|                |_______|_______|_______|_______|
00560          *                           150,200
00561          *  All coordinates below are in the left image above and with coordinates 0,0 in the
00562          *  upper left corner and 150,200 in the lower right corner.
00563          *
00564          */
00565 #define XYZ  {49,0},{0,0},{0,50},{50,50}
00566         static Coord2D_t a[24] = {{49,50}, {0,50},  {0,99},  {49,99},            //bottom  6
00567                                   {99,50}, {50,50}, {50,99}, {99,99},            //side2   2
00568                                   {149,50},{100,50},{100,99},{149,99},           //top     5
00569                                   {50,150},{99,150},{99,199},{50,199},           //side4   4
00570                                   {99,49}, {99,0},  {50,0},  {50,49},            //side1   1
00571                                   {99,100},{99,149},{50,149},{50,100}};          //side3   3
00572 #elif 0
00573         static Coord2D_t a[24] = {{49,50}, {0,50},  {0,99},  {49,99},            //bottom  6
00574                                   {99,50}, {50,50}, {50,99}, {99,99},            //side2   2
00575                                   {149,50},{100,50},{100,99},{149,99},           //top     5
00576                                   {99,150},{50,150},{50,199},{99,199},           //side4   4
00577                                   {99,49}, {99,0},  {50,0},  {50,49},            //side1   1
00578                                   {99,149},{99,100},{50,100},{50,149}};          //side3   3
00579 #else                                  
00580         static Coord2D_t a[24] = {{49,50}, {0,50},  {0,99},  {49,99},
00581                                   {99,50}, {50,50}, {50,99}, {99,99},
00582                                   {149,50},{100,50},{100,99},{149,99},
00583                                   {99,199},{50,199},{50,150},{99,150},
00584                                   {50,0},  {99,0},  {99,49}, {50,49},  //top
00585                                   {50,100},{99,100},{99,149},{50,149}};//bottom
00586 #endif                                  
00587 
00588         if (i&1)
00589         {
00590           SrcCoords[0].x = a[(i/2)*4+2].x;
00591           SrcCoords[0].y = a[(i/2)*4+2].y;
00592           SrcCoords[1].x = a[(i/2)*4+3].x;
00593           SrcCoords[1].y = a[(i/2)*4+3].y;
00594           SrcCoords[2].x = a[(i/2)*4+0].x;
00595           SrcCoords[2].y = a[(i/2)*4+0].y;
00596           DstCoords[0].x = cubeModel[cubePoly[i].p1].scrx;
00597           DstCoords[0].y = cubeModel[cubePoly[i].p1].scry;
00598           DstCoords[1].x = cubeModel[cubePoly[i].p2].scrx;
00599           DstCoords[1].y = cubeModel[cubePoly[i].p2].scry;
00600           DstCoords[2].x = cubeModel[cubePoly[i].p3].scrx;
00601           DstCoords[2].y = cubeModel[cubePoly[i].p3].scry;
00602           TriangleProjectFast(pSourcePicture, &activeFrame, SrcCoords, DstCoords);
00603         }
00604         else
00605         {
00606           SrcCoords[0].x = a[(i/2)*4+0].x; //0
00607           SrcCoords[0].y = a[(i/2)*4+0].y; //0
00608           SrcCoords[1].x = a[(i/2)*4+1].x; //31;
00609           SrcCoords[1].y = a[(i/2)*4+1].y; //0;
00610           SrcCoords[2].x = a[(i/2)*4+2].x; //31;
00611           SrcCoords[2].y = a[(i/2)*4+2].y; //31;
00612           DstCoords[0].x = cubeModel[cubePoly[i].p2].scrx;
00613           DstCoords[0].y = cubeModel[cubePoly[i].p2].scry;
00614           DstCoords[1].x = cubeModel[cubePoly[i].p3].scrx;
00615           DstCoords[1].y = cubeModel[cubePoly[i].p3].scry;
00616           DstCoords[2].x = cubeModel[cubePoly[i].p1].scrx;
00617           DstCoords[2].y = cubeModel[cubePoly[i].p1].scry;
00618           TriangleProjectFast(pSourcePicture, &activeFrame, SrcCoords, DstCoords);
00619         }
00620       }
00621     }
00622   }
00623 }
00624 
00625 void CubeDemo::render(uint32_t idx)
00626 {
00627  static uint8_t cnt=0;
00628 
00629   if (cnt == 0)
00630   {
00631     cnt = 1;
00632     pFrmBuf = pFrmBuf1;
00633   }
00634   else if (cnt == 1)
00635   {
00636     cnt = 2;
00637     pFrmBuf = pFrmBuf2;
00638   }
00639   else
00640   {
00641     cnt = 0;
00642     pFrmBuf = pFrmBuf3;
00643   }
00644   
00645   graphics.setFrameBuffer(pFrmBuf);
00646 
00647   // rendering here
00648   memset((void*)(pFrmBuf), BACKGROUND_COLOR, this->windowX * this->windowY * 2);
00649 
00650   rotateAndProject(rx, ry, 0);
00651 
00652   switch(mode)
00653   {
00654   case 0: //draw just points
00655     graphics.put_circle( cubeModel[0].scrx, cubeModel[0].scry, RED,                      2, 1);
00656     graphics.put_circle( cubeModel[1].scrx, cubeModel[1].scry, SMALL_CIRCLE_FRONT_COLOR, 2, 1);
00657     graphics.put_circle( cubeModel[2].scrx, cubeModel[2].scry, GREEN,                    2, 1);
00658     graphics.put_circle( cubeModel[3].scrx, cubeModel[3].scry, SMALL_CIRCLE_FRONT_COLOR, 2, 1);
00659     graphics.put_circle( cubeModel[4].scrx, cubeModel[4].scry, SMALL_CIRCLE_FRONT_COLOR, 2, 1);
00660     graphics.put_circle( cubeModel[5].scrx, cubeModel[5].scry, SMALL_CIRCLE_FRONT_COLOR, 2, 1);
00661     graphics.put_circle( cubeModel[6].scrx, cubeModel[6].scry, SMALL_CIRCLE_FRONT_COLOR, 2, 1);
00662     graphics.put_circle( cubeModel[7].scrx, cubeModel[7].scry, SMALL_CIRCLE_FRONT_COLOR, 2, 1);
00663     break;
00664   case 1: //draw lines points
00665     graphics.put_line( cubeModel[0].scrx, cubeModel[0].scry, cubeModel[1].scrx, cubeModel[1].scry, RED);
00666     graphics.put_line( cubeModel[1].scrx, cubeModel[1].scry, cubeModel[2].scrx, cubeModel[2].scry, SMALL_CIRCLE_FRONT_COLOR);
00667     graphics.put_line( cubeModel[2].scrx, cubeModel[2].scry, cubeModel[3].scrx, cubeModel[3].scry, GREEN);
00668     graphics.put_line( cubeModel[3].scrx, cubeModel[3].scry, cubeModel[0].scrx, cubeModel[0].scry, SMALL_CIRCLE_FRONT_COLOR);
00669 
00670     graphics.put_line( cubeModel[5].scrx, cubeModel[5].scry, cubeModel[4].scrx, cubeModel[4].scry, SMALL_CIRCLE_FRONT_COLOR);
00671     graphics.put_line( cubeModel[4].scrx, cubeModel[4].scry, cubeModel[7].scrx, cubeModel[7].scry, SMALL_CIRCLE_FRONT_COLOR);
00672     graphics.put_line( cubeModel[7].scrx, cubeModel[7].scry, cubeModel[6].scrx, cubeModel[6].scry, SMALL_CIRCLE_FRONT_COLOR);
00673     graphics.put_line( cubeModel[6].scrx, cubeModel[6].scry, cubeModel[5].scrx, cubeModel[5].scry, SMALL_CIRCLE_FRONT_COLOR);
00674 
00675     graphics.put_line( cubeModel[0].scrx, cubeModel[0].scry, cubeModel[4].scrx, cubeModel[4].scry, SMALL_CIRCLE_FRONT_COLOR);
00676     graphics.put_line( cubeModel[1].scrx, cubeModel[1].scry, cubeModel[5].scrx, cubeModel[5].scry, SMALL_CIRCLE_FRONT_COLOR);
00677     graphics.put_line( cubeModel[2].scrx, cubeModel[2].scry, cubeModel[6].scrx, cubeModel[6].scry, SMALL_CIRCLE_FRONT_COLOR);
00678     graphics.put_line( cubeModel[3].scrx, cubeModel[3].scry, cubeModel[7].scrx, cubeModel[7].scry, SMALL_CIRCLE_FRONT_COLOR);
00679     break;
00680   case 2: //draw cube with texture
00681     if (sourcePicture1.pixels == NULL)
00682     {
00683       drawCubeZ( NULL, false);
00684     }
00685     else
00686     {
00687       drawCubeZ( &sourcePicture1, false);
00688     }
00689     break;
00690   case 3: //draw cube with texture
00691     drawCubeZ( NULL, true);
00692     break;
00693   case 4: //draw cube with texture
00694     if (sourcePicture2.pixels == NULL)
00695     {
00696       drawCubeZ( NULL, false);
00697     }
00698     else
00699     {
00700       drawCubeZ( &sourcePicture2, false);
00701     }
00702     break;
00703   case 5: //draw sorted lines
00704     drawCubeZ( NULL, false);
00705     break;
00706   default:
00707     mode = 0;
00708     break;
00709   }
00710   ry += ry_;
00711   rx += rx_;
00712 }
00713 
00714 /***********************************************************************
00715  * Private functions
00716  **********************************************************************/
00717 
00718 void CubeDemo::initialize()
00719 {
00720     mode = 3;
00721     rx   = 0x9000;
00722     ry   = 0;
00723     ry_  = 350;
00724     rx_  = -25; //-3
00725     camX = 0;
00726     camY = 0;
00727     camZ = 128;
00728 
00729     createCubeModel(70);
00730 
00731     Image::ImageData_t d;
00732     if (Image::decode(cube_image1, cube_image1_sz, &d) == 0) {
00733         sourcePicture1.w = d.width;
00734         sourcePicture1.h = d.height;
00735         sourcePicture1.pixels = d.pixels;
00736     }
00737     if (Image::decode(cube_image2, cube_image2_sz, &d) == 0) {
00738         sourcePicture2.w = d.width;
00739         sourcePicture2.h = d.height;
00740         sourcePicture2.pixels = d.pixels;
00741     }
00742 }
00743 
00744 
00745 /******************************************************************************
00746  * Public functions
00747  *****************************************************************************/
00748 CubeDemo::CubeDemo(uint8_t *pFrameBuf, uint16_t dispWidth, uint16_t dispHeight) 
00749     : graphics((uint16_t *)pFrameBuf, dispWidth, dispHeight) {
00750 
00751     this->windowX = dispWidth;
00752     this->windowY = dispHeight;
00753     this->pFrmBuf  = (uint16_t *)pFrameBuf;
00754     this->pFrmBuf1 = (uint16_t *)pFrameBuf;
00755     this->pFrmBuf2 = (uint16_t *)((uint32_t)pFrameBuf + dispWidth*dispHeight*2);
00756     this->pFrmBuf3 = (uint16_t *)((uint32_t)pFrameBuf + dispWidth*dispHeight*4);
00757 
00758     sourcePicture1.w = 0;
00759     sourcePicture1.h = 0;
00760     sourcePicture1.pixels = NULL;
00761     sourcePicture2.w = 0;
00762     sourcePicture2.h = 0;
00763     sourcePicture2.pixels = NULL;
00764         
00765     initialize();
00766 }
00767 
00768 CubeDemo::~CubeDemo()
00769 {
00770   if (sourcePicture1.pixels != NULL) {
00771     free(sourcePicture1.pixels);
00772   }
00773   if (sourcePicture2.pixels != NULL) {
00774     free(sourcePicture2.pixels);
00775   }
00776 }
00777 void CubeDemo::run(uint32_t loops, uint32_t delayMs) {
00778 
00779   printf("CubeDemo, %d loops, %dms delay\n", loops, delayMs);
00780   
00781     for(int32_t n=0;n<loops;n++) {
00782     
00783         mode = ((n/128) % 5);
00784         //mode = 4;
00785     
00786         //render globe
00787         render(n);
00788     
00789         //update framebuffer
00790         lcdBoard.setFrameBuffer((uint32_t)this->pFrmBuf);
00791 
00792         if (abortTest) {
00793             break;
00794         }      
00795       
00796         if (mode == 3)
00797             wait_ms(delayMs-7);
00798         else
00799             wait_ms(delayMs);
00800     }
00801 }
00802