/************************************************************************* * * Copyright 2008+ Mobile 1UP * All rights reserved. * *************************************************************************/ /* * @(#)application-state-lens.inc */ /************************************************************************* * Structures *************************************************************************/ #define LENS_SIZE 100 #define LENS_ZOOM 25 #define LENS_DX 2 #define LENS_DY 2 #define LENS_MAX_DIFF 4 typedef struct LensRunTime { uint16 *bitmap; struct { int16 x; int16 y; int16 *data; } lens; int16 dx; int16 dy; } LensRunTime; typedef struct LensExtension { LensRunTime *rt; } LensExtension; /************************************************************************* * Globals + Preferences *************************************************************************/ #define GLOBALS_LENS_DEFINE GLOBALS_ACCESS; \ LensExtension *g_lens #define GLOBALS_LENS_ACCESS GLOBALS_ACCESS; \ LensExtension *g_lens = globals -> pExt[STATE_LENS] //------------------------------------------------------------------------ // --== GLOBALS ARE FORBIDDEN! ==-- // // DAL may support the use of globals on some platforms, however, its not // guaranteed that all the destination platforms allow the use of globals // (variable or static data). use the GlobalsType structure as shown. //------------------------------------------------------------------------ /************************************************************************* * Platform Independent Implementation *************************************************************************/ boolean ApplicationStateLensInitialize() { boolean result; GLOBALS_LENS_DEFINE; // default return value result = false; // entry requirements if (globals == NULL) goto ApplicationStateLensInitialize_DONE; g_lens = (LensExtension *)_MemPtrNew(sizeof(LensExtension), false); if (g_lens != NULL) { globals -> pExt[STATE_LENS] = (void *)g_lens; result = true; } ApplicationStateLensInitialize_DONE:; return result; } boolean ApplicationStateLensInit() { boolean result; uint16 resID; int i, j; uint16 *bits, w, h, rb, *dst; char *logo, *p; int32 ix, iy, offset, dist; int32 x, y, r, d; double shift; GLOBALS_LENS_ACCESS; // default return value result = false; // entry requirements if (g_lens == NULL) goto ApplicationStateLensInit_DONE; // allocate the runtime g_lens -> rt = _MemPtrNew(sizeof(LensRunTime), false); if (g_lens -> rt == NULL) goto ApplicationStateLensInit_DONE; // load the background bitmap resID = 0x1001; { // get a pointer to the display _FBGetProperties((void **)&bits, &w, &h, &rb); if (bits != NULL) { logo = (char *)ApplicationResourceLock(resID); if (logo != NULL) { p = logo; // skip over the header (SBCK_6560000wwhh) p += 16; // dump the contents of the background for (j=0; j> 1) - w); } ApplicationResourceUnlock((void *)logo); // the screen must be repainted globals -> dirty = true; } } } // allocate memory for the lens offsets g_lens -> rt -> lens.data = (int16 *)_MemPtrNew(LENS_SIZE * LENS_SIZE * sizeof(int16), false); if (g_lens -> rt -> lens.data == NULL) goto ApplicationStateLensInit_DONE; // lets generate the lens offset matrix r = LENS_SIZE / 2; d = LENS_ZOOM; for (y = 0; y < r; y++) { for (x = 0; x < r; x++) { dist = x*x + y*y - r*r; if (dist < 0) { shift = d / _sqrt(d*d - dist); ix = x * shift - x; iy = y * shift - y; } else { ix = 0; iy = 0; } // we calculate a single quadrant; and mirror offset = (iy * w + ix); g_lens -> rt -> lens.data[(r - y) * LENS_SIZE + r - x] = -offset; g_lens -> rt -> lens.data[(r + y) * LENS_SIZE + r + x] = offset; offset = (-iy * w + ix); g_lens -> rt -> lens.data[(r + y) * LENS_SIZE + r - x] = -offset; g_lens -> rt -> lens.data[(r - y) * LENS_SIZE + r + x] = offset; } } // we must get a mirror image of the display _FBGetProperties((void **)&bits, &w, &h, &rb); g_lens -> rt -> bitmap = _MemPtrNew(w * h * 2, false); if (g_lens -> rt -> bitmap == NULL) goto ApplicationStateLensInit_DONE; dst = g_lens -> rt -> bitmap; for (j=0; j> 1); } // center the lens on display; and define its movement g_lens -> rt -> lens.x = (w - LENS_SIZE) >> 1; g_lens -> rt -> lens.y = (h - LENS_SIZE) >> 1; g_lens -> rt -> dx = LENS_DX; g_lens -> rt -> dy = LENS_DY; // configuration successful result = true; ApplicationStateLensInit_DONE:; return result; } boolean ApplicationStateLensHandleEvent(event *e) { boolean result; uint16 *bits, w, h, rb; uint16 *src, *dst; int16 *p; int x, y; GLOBALS_LENS_ACCESS; // default return value result = false; // entry requirements if ((g_lens == NULL) || (g_lens -> rt == NULL)) goto ApplicationStateLensHandleEvent_DONE; switch (e -> eType) { case _nilEvent: // get a pointer to the display _FBGetProperties((void **)&bits, &w, &h, &rb); // prevent the lens from going outside the screen boundaries if (g_lens -> rt -> lens.x <= LENS_MAX_DIFF) g_lens -> rt -> dx = -g_lens -> rt -> dx; if (g_lens -> rt -> lens.y <= LENS_MAX_DIFF) g_lens -> rt -> dy = -g_lens -> rt -> dy; if (g_lens -> rt -> lens.x > (w - LENS_SIZE - LENS_MAX_DIFF)) g_lens -> rt -> dx = -g_lens -> rt -> dx; if (g_lens -> rt -> lens.y > (h - LENS_SIZE - LENS_MAX_DIFF)) g_lens -> rt -> dy = -g_lens -> rt -> dy; // move the lens g_lens -> rt -> lens.x += g_lens -> rt -> dx; g_lens -> rt -> lens.y += g_lens -> rt -> dy; // copy original background bitmap to the display src = g_lens -> rt -> bitmap; dst = bits; for (y=0; y> 1); } // apply lens distortion src = g_lens -> rt -> bitmap; dst = bits; dst += (g_lens -> rt -> lens.y * (rb >> 1)) + g_lens -> rt -> lens.x; src += (g_lens -> rt -> lens.y * w) + g_lens -> rt -> lens.x; p = g_lens -> rt -> lens.data; for (y = 0; y < LENS_SIZE; y++) { for (x = 0; x < LENS_SIZE; x++) { *dst = *(src + *p++); dst++; src++; } dst += (rb >> 1) - LENS_SIZE; src += w - LENS_SIZE; } // the screen must be repainted globals -> dirty = true; result = true; break; default: break; } ApplicationStateLensHandleEvent_DONE:; return result; } void ApplicationStateLensQuit() { GLOBALS_LENS_ACCESS; // entry requirements if (g_lens == NULL) goto ApplicationStateLensQuit_DONE; // release the bitmap and lens matrix if (g_lens -> rt -> lens.data != NULL) _MemPtrFree(g_lens -> rt -> lens.data); if (g_lens -> rt -> bitmap != NULL) _MemPtrFree(g_lens -> rt -> bitmap); g_lens -> rt -> lens.data = NULL; g_lens -> rt -> bitmap = NULL; if (g_lens -> rt != NULL) _MemPtrFree(g_lens -> rt); g_lens -> rt = NULL; ApplicationStateLensQuit_DONE:; } void ApplicationStateLensTerminate() { GLOBALS_LENS_ACCESS; // entry requirements if (globals == NULL) goto ApplicationStateLensTerminate_DONE; if (g_lens != NULL) _MemPtrFree(g_lens); globals -> pExt[STATE_LENS] = (void *)NULL; ApplicationStateLensTerminate_DONE:; } #undef GLOBALS_LENS_DEFINE #undef GLOBALS_LENS_ACCESS #undef LENS_MAX_DIFF #undef LENS_DY #undef LENS_DX #undef LENS_ZOOM #undef LENS_SIZE /********************************* EOF ***********************************/