Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions l0dables/EXPORTS
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,4 @@ getMeshSizes
getMesh
readFile
work_queue
lcdGetBuffer
2 changes: 1 addition & 1 deletion l0dables/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
C1D=cube.c1d blinky.c1d invaders.c1d mandel.c1d snake.c1d snake2.c1d bricks.c1d schedule.c1d ws2812b.c1d battery.c1d fire.c1d colorp.c1d tetris.c1d sysinfo.c1d colors.c1d 0xb.c1d
C1D=cube.c1d blinky.c1d invaders.c1d mandel.c1d snake.c1d snake2.c1d bricks.c1d schedule.c1d ws2812b.c1d battery.c1d fire.c1d colorp.c1d tetris.c1d sysinfo.c1d colors.c1d 0xb.c1d blurn.c1d

N1K=nick_scr0ll.n1k nick_w0rpcore.n1k nick_matrix.n1k nick_plain.n1k nick_invaders.n1k nick_anim.n1k nick_image.n1k nick_netz39.n1k nick_life.n1k nick_colplasm.n1k nick_ledbow.n1k

Expand Down
211 changes: 211 additions & 0 deletions l0dables/blurn.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
/* blurn -- underdamped blur animation for the rad1o

This is the little sister of https://github.com/neeels/burnscope

(c) Neels Hofmeyr <neels@hofmeyr.de> (2015)
Published under the GNU General Public License v2
*/

#include <stdlib.h>

#include <r0ketlib/display.h>
#include <r0ketlib/keyin.h>
#include <r0ketlib/render.h>

#include "usetable.h"

typedef unsigned int uint;
typedef float pixel_t;

static void add_copy(uint8_t* from, pixel_t* to, uint N, int ofs)
{
uint8_t* from_pos = from;
uint8_t* from_end = from + N;
pixel_t* to_pos = to;
uint8_t* s;
pixel_t* d;
if (ofs < 0) {
from_pos += -ofs;
for (s = from, d = to + N - (-ofs);
s < from_pos;
s ++, d ++) {
*d += *s;
}
}
else
if (ofs > 0) {
to_pos += ofs;
from_end -= ofs;
for (s = from_end, d = to;
d < to_pos;
s ++, d ++) {
*d += *s;
}
}

for (s = from_pos, d = to_pos;
s < from_end;
s ++, d ++) {
*d += *s;
}
}

void ram(void)
{


// Note: N has to be low enough for memory reasons.
#define W RESX
#define H 55
#define Y ((RESY - 2*H)/2)
#define N (W*H)
#define RESN (RESX*RESY)

pixel_t pixels[N];
uint8_t* lcd = lcdGetBuffer();

// the blur algorithm reads back from the screen buffer. So if I'm
// displaying the plain image Y pixels lower, I also need to read back Y
// pixels lower.
uint8_t* lcd_from = lcd + Y * RESX;

lcdFill(0);

setIntFont(&Font_7x8);
setTextColor(0, 0b11111100);
lcdSetCrsr(0, 0);
lcdPrintln("blurn");
lcdPrintln("underdamped blur");
lcdNl();
lcdPrintln("DOWN/UP cool down");
lcdPrintln("LEFT/RIGHT heat up");
lcdPrintln("ENTER exit");
lcdNl();
lcdPrintln("any key to start");
lcdDisplay();

uint random_seed; // hopefully some random value...
uint debounce;

// wait for initial key release after program started.
debounce = 0;
while (debounce < 100) {
if (getInputRaw() == BTN_NONE)
debounce ++;
else
debounce = 0;
random_seed ++;
}

// wait for user to press a button to acknowledge greeting.
debounce = 0;
while (debounce < 100) {
if (getInputRaw() != BTN_NONE)
debounce ++;
else
debounce = 0;
random_seed ++;
}

// and wait for another release to start the loop.
debounce = 0;
while (debounce < 100) {
if (getInputRaw() == BTN_NONE)
debounce ++;
else
debounce = 0;
random_seed ++;
}


lcdFill(0);
srand(random_seed);
for (uint i = 0; i < N; i++) {
pixels[i] = rand();
}

while (1) {
{
// draw in screen resolution and repeat the high res image
uint lcd_pos = 0;
while (lcd_pos < RESN) {
// a mirrored strip up to position Y
for (int pixels_pos = N-(W * (H - Y))-W; (pixels_pos >= 0) && (lcd_pos < RESN);) {
uint row_end = pixels_pos + W;
for (; pixels_pos < row_end; pixels_pos ++, lcd_pos ++) {
lcd[lcd_pos] = (uint8_t)pixels[pixels_pos];
}
pixels_pos -= 2 * W;
}

// this is the plain image at position Y
for (uint pixels_pos = 0; (pixels_pos < N) && (lcd_pos < RESN); pixels_pos ++, lcd_pos ++) {
lcd[lcd_pos] = (uint8_t)pixels[pixels_pos];
}

// another mirrored strip below plain image at Y
for (int pixels_pos = N-W; (pixels_pos >= 0) && (lcd_pos < RESN);) {
uint row_end = pixels_pos + W;
for (; pixels_pos < row_end; pixels_pos ++, lcd_pos ++) {
lcd[lcd_pos] = (uint8_t)pixels[pixels_pos];
}
pixels_pos -= 2 * W;
}

// and another forward strip if there's any more space.
for (uint pixels_pos = 0; (pixels_pos < N) && (lcd_pos < RESN); pixels_pos ++, lcd_pos ++) {
lcd[lcd_pos] = (uint8_t)pixels[pixels_pos];
}

}
}
lcdDisplay();

add_copy(lcd_from, pixels, N, 1);
add_copy(lcd_from, pixels, N, -1);
add_copy(lcd_from, pixels, N, W);
add_copy(lcd_from, pixels, N, - W);
add_copy(lcd_from, pixels, N, W + 1);
add_copy(lcd_from, pixels, N, W - 1);
add_copy(lcd_from, pixels, N, - W + 1);
add_copy(lcd_from, pixels, N, - W - 1);

switch (getInputRaw()) {
default:
case BTN_NONE:
// for some reason I can't divide by a floar variable.
// So I have to have this loop twice with separate variables.
for (uint i = 0; i < N; i++) {
pixels[i] /= 8.92;
}
break;

case BTN_DOWN:
for (uint i = 0; i < N; i++) {
pixels[i] /= 9.04;
}
break;

case BTN_UP:
for (uint i = 0; i < N; i++) {
pixels[i] /= 9.15;
}
break;

case BTN_RIGHT:
for (uint i = 0; i < N; i++) {
pixels[i] /= 8.58;
}
break;

case BTN_LEFT:
for (uint i = 0; i < N; i++) {
pixels[i] /= 8.67;
}
break;

case BTN_ENTER:
return;
}
}
}
5 changes: 5 additions & 0 deletions r0ketlib/display.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,3 +228,8 @@ void lcdShift(int x, int y, int wrap) {
while(y-->0)
lcdShiftV(dir, wrap);
}

uint8_t* lcdGetBuffer(void)
{
return lcdBuffer;
}
1 change: 1 addition & 0 deletions r0ketlib/display.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ void lcdShift(int x, int y, int wrap);
void lcdSetContrast(int c);
void lcdSetRotation(char doit);
void lcdRotate(void);
uint8_t* lcdGetBuffer();

void lcd_select();
void lcd_deselect();
Expand Down