I have quickly converted some nice ‘snowing’ code from the early nineties, based on the game ‘Creatures 2’ on the C64.
It’s quite nice, so here you go…
#include "Arduboy.h"
Arduboy arduboy;
// snow flake data
const byte PROGMEM frames[60]={
4,8,12,16,12,8,4,0,
24,20,24,28,32,36,32,28,
56,52,48,44,40,44,48,52,
44,48,52,56,52,48,44,40,
64,68,72,76,80,76,72,68,
64,60,76,80,76,72,68,64,
60,64,68,72,96,100,96,92,
88,84,88,92};
const byte PROGMEM flkimage[104] ={
192,224,96,0,0,96,112,48,
0,0,60,24,0,6,14,12,
3,7,6,0,128,192,64,0,
0,64,96,32,0,0,24,24,
0,2,6,4,1,3,2,0,
192,128,0,0,0,192,64,0,
0,0,48,0,0,12,8,0,
12,4,0,0,128,128,0,0,
0,128,64,0,0,0,96,0,
0,0,48,0,0,16,32,0,
16,16,0,0,128,0,0,0,
0,128,0,0,0,0,64,0,
0,32,0,0,32,0,0,0,
};
char offset[18]={
1,0,8,3,3,6,6,6,
6,6,5,5,5,4,0,0,
1,3};
unsigned char mx[18]={
7,7,9,7,7,9,7,7,
9,7,7,9,7,9,7,7,
7,7};
unsigned char fptrs[18]={
8,16,32,52,24,42,16,8,
42,24,52,32,16,32,8,8,
0,0};
unsigned char vert[18]={
168,24,144,160,16,88,128,120,
40,8,56,176,104,56,80,152,
152,96};
unsigned char countdn[18]={
0,5,1,5,2,2,4,3,
2,1,6,5,5,3,2,2,
1,0};
unsigned char spead[18]={
5,5,5,5,5,5,5,6,
6,6,6,6,6,4,4,4,
3,2};
unsigned char tempimg[72]={
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0};
long int frameNumber=0;
unsigned char rowStart[16];
#define maxHeight 56
unsigned char snowRow[maxHeight];
void setup() {
arduboy.begin();
arduboy.setFrameRate(30);
arduboy.clear();
arduboy.initRandomSeed();
for(char t=0; t<18; t++){
vert[t]=random(maxHeight>>1);
if(t%1==0){vert[t]<<=1;}
}
for(char t=0; t<16; t++){
rowStart[t]=(random(maxHeight>>1));
if(t%1==0){rowStart[t]<<=1;}
}
}
void loop() {
frameNumber++;
// pause render until it's time for the next frame
if (!(arduboy.nextFrame()))
return;
updateSnow();
arduboy.display();
}
void updateSnow(){
// Main snow-feild code
unsigned char ctr=0;
unsigned char stp = 1;
for(unsigned char loop=17; loop>stp+7; loop-=stp){ // 17
countdn[loop]--;
if(countdn[loop]==0){
countdn[loop]=spead[loop];
//remove old flake image
int y = vert[loop];
int a=0;
for(a=0; a<4; a++){
snowRow[y] &= (255-tempimg[loop*4+a]);
y++; if(y>=maxHeight){y=0;} // was 176
}//a
// rem calculate new vertical position
// rem (vert) & frame number (offset)
vert[loop]++;
if(vert[loop]>=maxHeight){vert[loop]=0;}
offset[loop]--;
if(offset[loop]<0){offset[loop]=mx[loop];}
// rem get next frame of animation
y=pgm_read_byte(&frames[fptrs[loop]+offset[loop]]);
for(a=0; a<4; a++){
tempimg[loop*4+a]=pgm_read_byte(&flkimage[y+a]);
}
// rem add new frame at new position
y=vert[loop];
for(a=0; a<4; a++){
snowRow[y] |= tempimg[loop*4+a];
y++; if(y>=maxHeight){y=0;}
}
} // countdn
}// loop
for(char x=0; x<16; x++){
for(char y=0; y<maxHeight; y++){
char p = rowStart[x]+y;
if(p>=maxHeight){p-=maxHeight;}
for(char t=0; t<8; t++){
arduboy.drawPixel(t+(x*8),y,snowRow[p] & (1<<t));
}
}
}
}
I’ve only tested on my Arduboy clone, but it doesn’t do anything weird, so should work for everyone.