You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

155 lines
4.3 KiB

#include <stdint.h>
#include <assert.h>
#include "../compat/pgmspace.h"
#include "../random/prng.h"
#include "../util.h"
#include "../autoconf.h"
#include "../pixel.h"
#define PRB(a) pgm_read_byte(&(a))
#define BITMAP_WIDTH 48
#define BITMAP_HEIGHT 48
#define VIEWPORT_WIDTH 16
#define VIEWPORT_HEIGHT 16
#define XDOMAIN (BITMAP_WIDTH - VIEWPORT_WIDTH)
#define YDOMAIN (BITMAP_HEIGHT - VIEWPORT_HEIGHT)
#define FRAME_TICK 75
#define FRAMECOUNT 400
static uint16_t laborlogo_getLine(const uint8_t x,
const uint8_t y)
{
assert(x <= BITMAP_WIDTH - VIEWPORT_WIDTH);
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}};
uint16_t nLine;
uint8_t nAlignment = x % 8;
if (nAlignment == 0)
{
nLine = PRB(nBitmap[y][x / 8]) << 8;
nLine |= PRB((nBitmap[y][x / 8 + 1]));
}
else
{
nLine = PRB(nBitmap[y][x / 8]) << (8 + nAlignment);
nLine |= PRB(nBitmap[y][x / 8 + 1]) << nAlignment;
nLine |= PRB(nBitmap[y][x / 8 + 2]) >> (8 - nAlignment);
}
return nLine;
}
static void laborlogo_drawViewport(const uint8_t nBitmapX,
const uint8_t nBitmapY)
{
assert(nBitmapX <= XDOMAIN);
assert(nBitmapY <= YDOMAIN);
for (uint8_t nVPortY = 0; nVPortY < 16; ++nVPortY)
{
uint16_t nLineBuffer = laborlogo_getLine(nBitmapX, nVPortY + nBitmapY);
for (int8_t nVPortX = 0; nVPortX < 16; ++nVPortX)
{
if ((0x0001 << nVPortX) & nLineBuffer)
{
setpixel((pixel){nVPortX, nVPortY}, 3);
}
else
{
setpixel((pixel){nVPortX, nVPortY}, 0);
}
}
}
}
static void laborlogo_recalcVectors(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()
{
uint16_t nCycles = FRAMECOUNT;
int8_t x = random8() % (XDOMAIN + 1);
int8_t y = random8() % (YDOMAIN + 1);
int8_t dx = 0;
int8_t dy = 0;
while (nCycles-- != 0)
{
laborlogo_drawViewport(x ,y);
laborlogo_recalcVectors(x, y, &dx, &dy);
x += dx;
y += dy;
wait(FRAME_TICK);
}
}