EmbeddedArtists AB / Mbed 2 deprecated app_lcdboard_demo_globe

Dependencies:   EALib mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers GlobeDemo.cpp Source File

GlobeDemo.cpp

00001 /******************************************************************************
00002  * Includes
00003  *****************************************************************************/
00004 
00005 #include "mbed.h"
00006 
00007 #include "LcdController.h"
00008 #include "EaLcdBoard.h"
00009 #include "GlobeDemo.h"
00010 
00011 #include <math.h>
00012 
00013 //#include "wchar.h"
00014 
00015 /******************************************************************************
00016  * Typedefs and defines
00017  *****************************************************************************/
00018 
00019 #define NUM_OF_DOTS 50
00020 
00021 /******************************************************************************
00022  * Local variables
00023  *****************************************************************************/
00024 
00025 
00026 /******************************************************************************
00027  * External variables
00028  *****************************************************************************/
00029 extern EaLcdBoard lcdBoard;
00030 extern bool abortTest;
00031 
00032 /******************************************************************************
00033  * Local functions
00034  *****************************************************************************/
00035 
00036 // Vertex structure
00037 typedef struct
00038 {
00039 #ifdef USE_FLOAT
00040   float x, y, z;
00041 #else
00042   long x, y, z;
00043 #endif
00044 }tVertex;
00045 
00046 // Transformed vertices
00047 tVertex *gRVtx;
00048 
00049 #ifdef USE_FLOAT
00050 // Original vertices
00051 static tVertex *gVtx;
00052 #else
00053 static const tVertex gVtx[NUM_OF_DOTS] = {
00054 {-21585, 17597, -17265},
00055 {28493, -7790, 14183},
00056 {13031, 27845, 11338},
00057 {10822, 29162, -10304},
00058 {19517, -25865, -4876},
00059 {1283, 30949, -10687},
00060 {-23097, 12297, 19723},
00061 {-17162, 1188, 27888},
00062 {-29007, -1547, 15163},
00063 {-8182, -31729, -197},
00064 {11599, -28575, -11073},
00065 {25963, 12182, 15850},
00066 {106, 10547, -31023},
00067 {-24312, 3053, -21755},
00068 {9966, -18803, -24916},
00069 {17598, -6037, -26973},
00070 {23321, 17149, -15353},
00071 {-3265, 8867, -31376},
00072 {-23639, 13701, 18087},
00073 {-2433, -22123, -24049},
00074 {21284, -11349, -22179},
00075 {-21407, 24683, -2486},
00076 {-32011, -4336, 5495},
00077 {-20191, 22605, 12450},
00078 {14752, -23540, 17376},
00079 {-8961, -17292, -26351},
00080 {-18078, 13561, -23727},
00081 {10730, -23639, 19994},
00082 {-18718, 17555, 20376},
00083 {13626, -22837, 19144},
00084 {-24695, -19036, -10073},
00085 {11935, 22275, 20859},
00086 {-2182, -28801, -15474},
00087 {21428, -21867, -11678},
00088 {-19601, 21558, -14991},
00089 {24512, 10876, -18830},
00090 {12385, 27881, 11956},
00091 {26982, 15618, -10088},
00092 {-16954, 19591, 20061},
00093 {-6027, 22699, -22850},
00094 {5453, 28825, -14598},
00095 {-20155, -16252, -20083},
00096 {-15962, 11757, -26089},
00097 {-29175, -11289, -9750},
00098 {-15370, 604, -28933},
00099 {26009, 19868, -1575},
00100 {24722, -17277, -12806},
00101 {-4527, 25836, -19639},
00102 {-22224, 10442, 21697},
00103 {-10388, 24393, -19255}};
00104 #endif
00105 
00106 unsigned short GlobeDemo::isqrt(unsigned long a) const {
00107     unsigned long temp;
00108     long e;
00109     unsigned long x = 0;
00110     if((a & 0xffff0000) != 0)
00111         x = 444 + a / 26743;
00112     else if((a & 0xff00) != 0)
00113         x = 21 + a / 200;
00114     else
00115         x = 1 + a / 12;
00116     do{
00117         temp = a / x;
00118         e = (x - temp) / 2;
00119         x = (x + temp) / 2;
00120     }
00121     while(e != 0);
00122     return (unsigned short)x;
00123 }
00124 
00125 short GlobeDemo::_sin(short y) const {
00126     static short s1 = 0x6487;
00127     static short s3 = 0x2951;
00128     static short s5 = 0x4f6;
00129     long z, prod, sum;
00130 
00131     z = ((long)y * y) >> 12;
00132     prod = (z * s5) >> 16;
00133     sum = s3 - prod;
00134     prod = (z * sum) >> 16;
00135     sum = s1 - prod;
00136 
00137     // for better accuracy, round here
00138     return (short)((y * sum) >> 13);
00139  }
00140 
00141 short GlobeDemo::_cos(short y) const {
00142     static short c0 = 0x7fff;
00143     static short c2 = 0x4eea;
00144     static short c4 = 0x0fc4;
00145     long z, prod, sum;
00146     z = ((long)y * y) >> 12;
00147     prod = (z * c4) >> 16;
00148     sum = c2 - prod;
00149 
00150     // for better accuracy, round here
00151     prod = (z * sum) >> 15;
00152     return (short)(c0 - prod);
00153 }
00154 
00155 short GlobeDemo::isine(short x) const {
00156     unsigned short n = (((unsigned short)x + 0x2000) >> 14) & 0x3;
00157     x -= n * 0x4000;
00158     switch(n){
00159         case 0:
00160             return _sin(x);
00161         case 1:
00162             return _cos(x);
00163         case 2:
00164             return - _sin(x);
00165         case 3:
00166             return  - _cos(x);
00167     }
00168     return 0;
00169  }
00170 
00171 
00172 short GlobeDemo::icosine(short x) const {
00173     return isine(x + 0x4000);
00174  }
00175 
00176 void GlobeDemo::initialize()
00177 {
00178 //  gVtx = (tVertex*)malloc(sizeof(tVertex) * NUM_OF_DOTS);
00179   gRVtx = (tVertex*)malloc(sizeof(tVertex) * NUM_OF_DOTS);
00180 
00181 #ifdef USE_FLOAT
00182   int i;
00183   for (i = 0; i < NUM_OF_DOTS; i++)
00184   {
00185     gVtx[i].x = (rand() % 32768) - 16384.0f;
00186     gVtx[i].y = (rand() % 32768) - 16384.0f;
00187     gVtx[i].z = (rand() % 32768) - 16384.0f;
00188     float len = (float)sqrt(gVtx[i].x * gVtx[i].x + 
00189                             gVtx[i].y * gVtx[i].y + 
00190                             gVtx[i].z * gVtx[i].z);
00191     if (len != 0)
00192     {
00193       gVtx[i].x /= len;
00194       gVtx[i].y /= len;
00195       gVtx[i].z /= len;
00196     }
00197   }
00198 #endif
00199 }
00200 
00201 #ifdef USE_FLOAT
00202 void GlobeDemo::rotate_z(float angle)
00203 {
00204   float ca = (float)cos(angle);
00205   float sa = (float)sin(angle);
00206   int i;
00207   for (i = 0; i < NUM_OF_DOTS; i++)
00208   {
00209     float x = gRVtx[i].x * ca - gRVtx[i].y * sa;
00210     float y = gRVtx[i].x * sa + gRVtx[i].y * ca;
00211     gRVtx[i].x = x;
00212     gRVtx[i].y = y;
00213   }
00214 }
00215 
00216 void GlobeDemo::rotate_y(float angle)
00217 {
00218   float ca = (float)cos(angle);
00219   float sa = (float)sin(angle);
00220   int i
00221   for (i = 0; i < NUM_OF_DOTS; i++)
00222   {
00223     float z = gRVtx[i].z * ca - gRVtx[i].x * sa;
00224     float x = gRVtx[i].z * sa + gRVtx[i].x * ca;
00225     gRVtx[i].z = z;
00226     gRVtx[i].x = x;
00227   }
00228 }
00229 #else
00230 void GlobeDemo::rotate_z(uint32_t angle)
00231 {
00232   uint32_t i;
00233   long x,y,ca,sa;
00234 
00235   ca = icosine(angle);
00236   sa = isine(angle);
00237   for (i = 0; i < NUM_OF_DOTS; i++)
00238   {
00239     x = (gRVtx[i].x * ca - gRVtx[i].y * sa) / 0x7fff;
00240     y = (gRVtx[i].x * sa + gRVtx[i].y * ca) / 0x7fff;
00241     gRVtx[i].x = x;
00242     gRVtx[i].y = y;
00243   }
00244 }
00245 
00246 void GlobeDemo::rotate_y(uint32_t angle)
00247 {
00248   uint32_t i;
00249   long x,z,ca,sa;
00250 
00251   ca = icosine(angle);
00252   sa = isine(angle);
00253   for (i = 0; i < NUM_OF_DOTS; i++)
00254   {
00255     z = (gRVtx[i].z * ca - gRVtx[i].x * sa) / 0x7fff;
00256     x = (gRVtx[i].z * sa + gRVtx[i].x * ca) / 0x7fff;
00257     gRVtx[i].z = z;
00258     gRVtx[i].x = x;
00259   }
00260 }
00261 #endif
00262 
00263 #if 0
00264 void GlobeDemo::rotate_x(float angle)
00265 {
00266   float ca = (float)cos(angle);
00267   float sa = (float)sin(angle);
00268   int i;
00269   for (i = 0; i < NUM_OF_DOTS; i++)
00270   {
00271     float y = gRVtx[i].y * ca - gRVtx[i].z * sa;
00272     float z = gRVtx[i].y * sa + gRVtx[i].z * ca;
00273     gRVtx[i].y = y;
00274     gRVtx[i].z = z;
00275   }
00276 }
00277 #endif
00278 
00279 void GlobeDemo::render(uint32_t idx)
00280 {
00281   uint32_t i;
00282 #ifdef USE_FLOAT
00283   float rotz;
00284   float roty;
00285 #else
00286   uint32_t rotz;
00287   uint32_t roty;
00288 #endif
00289 
00290  static uint8_t cnt=0;
00291 
00292   if (cnt == 0)
00293   {
00294     cnt = 1;
00295     pFrmBuf = pFrmBuf1;
00296   }
00297   else if (cnt == 1)
00298   {
00299     cnt = 2;
00300     pFrmBuf = pFrmBuf2;
00301   }
00302   else
00303   {
00304     cnt = 0;
00305     pFrmBuf = pFrmBuf3;
00306   }
00307 
00308   graphics.setFrameBuffer(pFrmBuf);
00309 
00310   // rendering here
00311   memset((void*)(pFrmBuf), BACKGROUND_COLOR, this->windowX * this->windowY * 2);
00312 
00313 //  lcd_fillcircle(myLcdHnd, WIDTH / 2, HEIGHT / 2, HEIGHT / 4, LARGE_CIRCLE_COLOR);
00314   graphics.put_circle(this->windowX / 2, this->windowY / 2, LARGE_CIRCLE_COLOR, this->windowY / 4, 1);
00315 
00316   memcpy(gRVtx, gVtx, sizeof(tVertex) * NUM_OF_DOTS);
00317 
00318 #ifdef USE_FLOAT
00319   rotz = idx /*tick*/ * 0.0005f;
00320   roty = idx /*tick*/ * 0.0020f;
00321 #else
00322   rotz = idx /*tick*/ * 50*5;
00323   roty = idx /*tick*/ * 200*5;
00324 #endif
00325   rotate_y(roty);
00326   rotate_z(rotz);
00327 
00328   for (i = 0; i < NUM_OF_DOTS; i++)
00329   {
00330     uint16_t c = SMALL_CIRCLE_FRONT_COLOR;
00331 
00332     if (gRVtx[i].z < 0)
00333       c = SMALL_CIRCLE_BACK_COLOR;
00334 #if 0
00335     lcd_point(myLcdHnd,
00336               (int)((gRVtx[i].x * (HEIGHT / 4)) / 0x7fff + WIDTH  / 2),
00337               (int)((gRVtx[i].y * (HEIGHT / 4)) / 0x7fff + HEIGHT / 2),
00338               c);
00339 #else
00340 //    lcd_fillcircle(myLcdHnd,
00341 //                   (int)((gRVtx[i].x * (HEIGHT / 4)) / 0x7fff + WIDTH / 2),
00342 //                   (int)((gRVtx[i].y * (HEIGHT / 4)) / 0x7fff + HEIGHT / 2),
00343 //                   2,
00344 //                   c);
00345     graphics.put_circle((int)((gRVtx[i].x * (this->windowY / 4)) / 0x7fff + this->windowX / 2), (int)((gRVtx[i].y * (this->windowY / 4)) / 0x7fff + this->windowY / 2), c, 2, 1);
00346 
00347 #endif
00348   } 
00349 #ifdef USE_FLOAT
00350   lcd_fillcircle(myLcdHnd,
00351                  (int)((WIDTH / 3) * cos(rotz) + WIDTH / 2),
00352                  (int)((WIDTH / 3) * sin(rotz) + HEIGHT / 2),
00353                  6,
00354                  SMALL_CIRCLE_FRONT_COLOR);
00355 #else
00356 //  lcd_fillcircle(myLcdHnd,
00357 //                 (int)(((HEIGHT / 3) * icosine(rotz))/0x7fff + WIDTH / 2),
00358 //                 (int)(((HEIGHT / 3) * isine(rotz))  /0x7fff + HEIGHT / 2),
00359 //                 7,
00360 //                 SMALL_CIRCLE_FRONT_COLOR);
00361     graphics.put_circle((int)(((this->windowY / 3) * icosine(rotz))/0x7fff + this->windowX / 2), (int)(((this->windowY / 3) * isine(rotz))  /0x7fff + this->windowY / 2), SMALL_CIRCLE_FRONT_COLOR, 7, 1);
00362 #endif
00363 }
00364 
00365 
00366 /******************************************************************************
00367  * Public functions
00368  *****************************************************************************/
00369 GlobeDemo::GlobeDemo(uint8_t *pFrameBuf, uint16_t dispWidth, uint16_t dispHeight) 
00370     : graphics((uint16_t *)pFrameBuf, dispWidth, dispHeight) {
00371 
00372     this->windowX = dispWidth;
00373     this->windowY = dispHeight;
00374     this->pFrmBuf  = (uint16_t *)pFrameBuf;
00375     this->pFrmBuf1 = (uint16_t *)pFrameBuf;
00376     this->pFrmBuf2 = (uint16_t *)((uint32_t)pFrameBuf + dispWidth*dispHeight*2);
00377     this->pFrmBuf3 = (uint16_t *)((uint32_t)pFrameBuf + dispWidth*dispHeight*4);
00378 
00379     initialize();
00380 }
00381 
00382 void GlobeDemo::run(uint32_t loops, uint32_t delayMs) {
00383 
00384   printf("GlobeDemo, %d loops, %dms delay\n", loops, delayMs);
00385   
00386     for(int32_t n=0;n<loops;n++) {
00387     
00388         //render globe
00389         render(n);
00390     
00391         //update framebuffer
00392         lcdBoard.setFrameBuffer((uint32_t)this->pFrmBuf);
00393 
00394         if (abortTest) {
00395             break;
00396         }
00397       
00398         wait_ms(delayMs);
00399     }
00400     free(gRVtx);
00401 }
00402