180 lines
4.6 KiB
C
180 lines
4.6 KiB
C
#include <stdint.h>
|
|
#include <assert.h>
|
|
#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);
|
|
}
|
|
}
|