#include #include #include "../compat/pgmspace.h" #include "../random/prng.h" #include "../util.h" #include "../autoconf.h" #include "../pixel.h" #define PB(a) pgm_read_byte(&(a)) #define BITMAP_WIDTH 48 #define BITMAP_HEIGHT 48 #if NUM_COLS > BITMAP_WIDTH #define VIEWPORT_WIDTH BITMAP_WIDTH #else #define VIEWPORT_WIDTH NUM_COLS #endif #if NUM_ROWS > BITMAP_HEIGHT #define VIEWPORT_HEIGHT BITMAP_HEIGHT #else #define VIEWPORT_HEIGHT NUM_ROWS #endif #define XDOMAIN (BITMAP_WIDTH - VIEWPORT_WIDTH) #define YDOMAIN (BITMAP_HEIGHT - VIEWPORT_HEIGHT) #define CHUNKDOMAIN (BITMAP_WIDTH - 8) #define CHUNKCOUNT (((VIEWPORT_WIDTH - 1) / 8) + 1) #define FRAME_TICK 75 #define FRAMECOUNT 400 static uint8_t laborlogo_getChunk(const uint8_t x, const uint8_t y) { assert(x <= CHUNKDOMAIN); assert(y < BITMAP_HEIGHT); static const uint8_t nBitmap[48][6] PROGMEM = {{0xFF, 0xFF, 0xE0, 0x07, 0xFF, 0xFF}, {0xFF, 0xFF, 0x00, 0xF8, 0xFF, 0xFF}, {0xFF, 0xF8, 0x00, 0xFF, 0x1F, 0xFF}, {0xFF, 0xF0, 0x00, 0xFF, 0xEF, 0xFF}, {0xFF, 0xC0, 0x00, 0xFF, 0xF3, 0xFF}, {0xFF, 0x80, 0x00, 0xFF, 0xFD, 0xFF}, {0xFF, 0x00, 0x00, 0xFF, 0xFE, 0xFF}, {0xFE, 0x00, 0x03, 0x3F, 0xFF, 0x7F}, {0xFC, 0x00, 0x04, 0xDF, 0xFF, 0xBF}, {0xF8, 0x00, 0x08, 0xEF, 0xFF, 0xDF}, {0xF0, 0x00, 0x10, 0xF7, 0xFF, 0xEF}, {0xF0, 0x00, 0x10, 0xF7, 0xFF, 0xEF}, {0xE0, 0xC0, 0x10, 0xF7, 0xFF, 0xF7}, {0xC0, 0xC0, 0x10, 0xF7, 0xFF, 0xFB}, {0xC0, 0x40, 0x08, 0xEF, 0xFF, 0xFB}, {0xC0, 0x40, 0x04, 0xDF, 0xFF, 0xFB}, {0x80, 0x40, 0x03, 0x3F, 0xFF, 0xFD}, {0x87, 0xFC, 0x00, 0xFF, 0xFF, 0xFD}, {0x84, 0x0C, 0x00, 0xFF, 0xFF, 0xFD}, {0x04, 0x00, 0x1F, 0x07, 0xFF, 0xFE}, {0x04, 0x00, 0x10, 0xF7, 0xFF, 0xFE}, {0x04, 0x00, 0x10, 0xF7, 0xFF, 0xFE}, {0xFF, 0x80, 0x10, 0xF7, 0xFF, 0xFE}, {0x00, 0x80, 0x10, 0xF7, 0xFF, 0xFE}, {0x00, 0x80, 0x10, 0xF7, 0xFF, 0xFE}, {0x00, 0x80, 0x10, 0xF7, 0xFF, 0xFE}, {0x00, 0x80, 0x10, 0xF7, 0xFF, 0xFE}, {0x00, 0x80, 0x10, 0xF7, 0xFF, 0xFE}, {0x00, 0x80, 0x10, 0xF7, 0xFF, 0xFE}, {0xBF, 0xFC, 0x10, 0xF7, 0xFF, 0xFD}, {0xB0, 0x0C, 0x10, 0xF7, 0xFF, 0xFD}, {0x80, 0x00, 0x10, 0xF7, 0xFF, 0xFD}, {0xC0, 0x00, 0x10, 0xF7, 0xFF, 0xFB}, {0xC0, 0x00, 0x10, 0xF7, 0xFF, 0xFB}, {0xC0, 0x00, 0x10, 0xF7, 0xFF, 0xFB}, {0xE0, 0x00, 0x10, 0xF7, 0xFF, 0xF7}, {0xF0, 0x00, 0x10, 0xF7, 0xFF, 0xEF}, {0xF0, 0x00, 0x10, 0xF7, 0xFF, 0xEF}, {0xF8, 0x00, 0x10, 0xF7, 0xFF, 0xDF}, {0xFC, 0x00, 0x10, 0xF7, 0xFF, 0xBF}, {0xFE, 0x00, 0x1F, 0x07, 0xFF, 0x7F}, {0xFF, 0x00, 0x00, 0xFF, 0xFE, 0xFF}, {0xFF, 0x80, 0x00, 0xFF, 0xFD, 0xFF}, {0xFF, 0xC0, 0x00, 0xFF, 0xF3, 0xFF}, {0xFF, 0xF0, 0x00, 0xFF, 0xEF, 0xFF}, {0xFF, 0xF8, 0x00, 0xFF, 0x1F, 0xFF}, {0xFF, 0xFF, 0x00, 0xF8, 0xFF, 0xFF}, {0xFF, 0xFF, 0xE0, 0x07, 0xFF, 0xFF}}; uint8_t nChunk; uint8_t nAlignment = x % 8; if (nAlignment == 0) { nChunk = PB(nBitmap[y][x / 8]); } else { nChunk = PB(nBitmap[y][x / 8]) << nAlignment; nChunk |= PB(nBitmap[y][x / 8 + 1]) >> (8 - nAlignment); } return nChunk; } static void laborlogo_drawViewport(const uint8_t nBitmapX, const uint8_t nBitmapY) { assert(nBitmapX <= XDOMAIN); assert(nBitmapY <= YDOMAIN); for (int8_t y = 0; y < VIEWPORT_HEIGHT; ++y) { for (int8_t x = VIEWPORT_WIDTH; x > 0; x -= 8) { uint8_t nChunk; if ((nBitmapX + x - 8) >= 0) { nChunk = laborlogo_getChunk(nBitmapX + x - 8, nBitmapY + y); pixmap[2][y][CHUNKCOUNT - 1 - ((x - 1) / 8)] = nChunk; } else { nChunk = laborlogo_getChunk(nBitmapX, nBitmapY + y) >> (8 - x); pixmap[2][y][CHUNKCOUNT - 1] = nChunk; } } } } static void laborlogo_recalcVector(const int8_t x, const int8_t y, int8_t *const pdx, int8_t *const pdy) { if (((x + *pdx) > (XDOMAIN)) || ((x + *pdx) < 0)) { *pdx = random8() % 2 * (x < (XDOMAIN / 2) ? 1 : -1); } if (((y + *pdy) > (YDOMAIN)) || ((y + *pdy) < 0)) { *pdy = random8() % 2 * (y < (YDOMAIN / 2) ? 1 : -1); } if (*pdx == 0 && *pdy == 0) { *pdx = (x < (XDOMAIN / 2) ? 1 : -1); *pdy = (y < (YDOMAIN / 2) ? 1 : -1); } } void laborlogo() { int8_t x = random8() % (XDOMAIN + 1); int8_t y = random8() % (YDOMAIN + 1); int8_t dx = 0; int8_t dy = 0; clear_screen(0); for (uint16_t nCycles = FRAMECOUNT; nCycles > 0; --nCycles) { laborlogo_drawViewport(x, y); laborlogo_recalcVector(x, y, &dx, &dy); #if BITMAP_WIDTH > VIEWPORT_WIDTH x += dx; #endif #if BITMAP_HEIGHT > VIEWPORT_HEIGHT y += dy; #endif wait(FRAME_TICK); } }