finally ported the moire pattern from cyberleiber to master

This commit is contained in:
Christian Kroll 2014-03-21 00:12:30 +01:00
parent 06a53829d4
commit 11a76a1a74
8 changed files with 177 additions and 55 deletions

View File

@ -30,6 +30,10 @@ ifeq ($(ANIMATION_MHERWEG),y)
SRC += mherweg.c SRC += mherweg.c
endif endif
ifeq ($(ANIMATION_MOIRE),y)
SRC += moire.c
endif
ifeq ($(ANIMATION_BREAKOUT),y) ifeq ($(ANIMATION_BREAKOUT),y)
SRC += breakout_demo.c SRC += breakout_demo.c
endif endif

View File

@ -42,6 +42,7 @@ comment "Animations"
dep_bool "Breakout Demo" ANIMATION_BREAKOUT $GAME_BREAKOUT dep_bool "Breakout Demo" ANIMATION_BREAKOUT $GAME_BREAKOUT
dep_bool "Martin Herweg" ANIMATION_MHERWEG $RANDOM_SUPPORT dep_bool "Martin Herweg" ANIMATION_MHERWEG $RANDOM_SUPPORT
dep_bool "Moire" ANIMATION_MOIRE $RANDOM_SUPPORT
dep_bool "Langton Ant" ANIMATION_LTN_ANT $RANDOM_SUPPORT dep_bool "Langton Ant" ANIMATION_LTN_ANT $RANDOM_SUPPORT
dep_bool_menu "Time Display" ANIMATION_TIME $SCROLLTEXT_SUPPORT $LAP_TIME_EXTENSION dep_bool_menu "Time Display" ANIMATION_TIME $SCROLLTEXT_SUPPORT $LAP_TIME_EXTENSION

View File

@ -27,51 +27,6 @@
#define PGM(x) pgm_read_byte(&(x)) #define PGM(x) pgm_read_byte(&(x))
#if NUM_ROWS < 64 && NUM_COLS < 64
/** use 8 bit operands where feasible */
typedef signed char operand_t;
#else
/** use 16 bit operands if either width or height are >= 64 */
typedef int operand_t;
#endif
/**
* An implementation of Bresenham's line drawing algorithm.
* @param p1 first coordinate of the line
* @param p2 second coordinate of the line
* @param color brightness level of the line
*/
static void line(pixel p1,
pixel const p2,
unsigned char const color)
{
operand_t const dx = p1.x < p2.x ? p2.x - p1.x : p1.x - p2.x;
operand_t const sx = p1.x < p2.x ? 1 : -1;
operand_t const dy = p1.y < p2.y ? p2.y - p1.y : p1.y - p2.y;
operand_t const sy = p1.y < p2.y ? 1 : -1;
operand_t error = dx - dy;
while(1)
{
setpixel(p1, color);
if ((p1.x == p2.x) && (p1.y == p2.y))
break;
operand_t const error2 = 2 * error;
if (error2 > -dy)
{
error -= dy;
p1.x += sx;
}
if (error2 < dx)
{
error += dx;
p1.y += sy;
}
}
}
/** /**
* Draws a rectangle at the given coordinates. * Draws a rectangle at the given coordinates.
* @param p coordinate of the rectangle's upper right corner * @param p coordinate of the rectangle's upper right corner

88
src/animations/moire.c Normal file
View File

@ -0,0 +1,88 @@
/**
* \defgroup moire A moire like pattern.
* @{
*/
/**
* @file moire.c
* @brief Implementation of a simple moire like pattern.
* @author Christian Kroll
*/
#include "../config.h"
#include "../pixel.h"
#include "../util.h"
/**
* Number of pixels of the complete border.
*/
#define NUMBER_OF_BORDER_PIXELS (2u * UNUM_COLS + 2u * (UNUM_ROWS - 2u))
/**
* Draws a moire like pattern. Works best if the number of border pixels is a
* multiple of the size of the gradient color map.
*/
void moire(void)
{
// add rotating color map
#if NUMPLANE == 3
static unsigned char const gradient[] = {0, 1, 2, 3, 2, 1};
#else
static unsigned char gradient[NUMPLANE * 2u] = {0};
for (unsigned char i = 1; i <= NUMPLANE; ++i)
{
gradient[i] = i;
gradient[(NUMPLANE * 2) - i] = i;
}
#endif
unsigned int cycles = 30000;
unsigned char pos = 0, color_index = 0;
pixel p1 = (pixel){0 ,0};
while(cycles--)
{
// walk around the border; do that by mapping a linear increasing value
// to appropriate screen coordinates
// first pixel is between top right and top left corner
if (pos < NUM_COLS)
{
p1.x = pos;
}
// first pixel is between top left and bottom left corner
else if (pos < (NUM_COLS + NUM_ROWS - 1))
{
p1.y = pos - (NUM_COLS - 1);
}
// first pixel is between bottom left and bottom right corner
else if (pos < (2 * NUM_COLS + NUM_ROWS - 2))
{
p1.x = 2 * NUM_COLS + NUM_ROWS - 3 - pos;
}
// first pixel is between bottom right and top left corner
else
{
p1.y = 3 * NUM_COLS + NUM_ROWS - 4 - pos;
}
// second pixel in opposite direction
pixel const p2 = (pixel){NUM_COLS - 1 - p1.x, NUM_ROWS - 1 - p1.y};
// draw line right accross the display and switch to next color
line(p1, p2, gradient[color_index++]);
// if we have reached the origin, reset position, rotate color index and
// wait for 40 ms (25 fps) to make the frame visible for human viewers
if (++pos == NUMBER_OF_BORDER_PIXELS)
{
pos = 0;
++color_index;
wait(40);
}
// ensure the color index keeps within bounds
color_index %= (2u * NUMPLANE);
}
}
/*@}*/

19
src/animations/moire.h Normal file
View File

@ -0,0 +1,19 @@
/**
* \defgroup moire A moire like pattern.
* @{
*/
/**
* @file moire.h
* @brief Interface file for a moire pattern implementation.
* @author Christian Kroll
*/
#ifndef MOIRE_H_
#define MOIRE_H_
void moire(void);
#endif /* MOIRE_H_ */
/*@}*/

View File

@ -18,6 +18,7 @@
#include "animations/bitmapscroller/fairydust.h" #include "animations/bitmapscroller/fairydust.h"
#include "animations/fpmath_patterns.h" #include "animations/fpmath_patterns.h"
#include "animations/mherweg.h" #include "animations/mherweg.h"
#include "animations/moire.h"
#include "animations/blackhole.h" #include "animations/blackhole.h"
#include "animations/squares.h" #include "animations/squares.h"
#ifdef ANIMATION_TIME #ifdef ANIMATION_TIME
@ -183,62 +184,68 @@ void display_loop(){
break; break;
#endif #endif
#ifdef ANIMATION_TIME #ifdef ANIMATION_MOIRE
case 15: case 15:
moire();
break;
#endif
#ifdef ANIMATION_TIME
case 16:
time_anim(); time_anim();
break; break;
#endif #endif
#ifdef ANIMATION_LTN_ANT #ifdef ANIMATION_LTN_ANT
case 16: case 17:
ltn_ant(); ltn_ant();
break; break;
#endif #endif
#ifdef ANIMATION_LABORLOGO #ifdef ANIMATION_LABORLOGO
case 17: case 18:
laborlogo(); laborlogo();
break; break;
#endif #endif
#ifdef ANIMATION_AMPHIBIAN #ifdef ANIMATION_AMPHIBIAN
case 18: case 19:
amphibian(); amphibian();
break; break;
#endif #endif
#ifdef ANIMATION_LOGO_OOS #ifdef ANIMATION_LOGO_OOS
case 19: case 20:
logo_OutOfSpec(); logo_OutOfSpec();
break; break;
#endif #endif
#ifdef ANIMATION_FAIRYDUST #ifdef ANIMATION_FAIRYDUST
case 20: case 21:
fairydust(); fairydust();
break; break;
#endif #endif
#ifdef ANIMATION_PLASMA #ifdef ANIMATION_PLASMA
case 21: case 22:
plasma(); plasma();
break; break;
#endif #endif
#ifdef ANIMATION_PSYCHEDELIC #ifdef ANIMATION_PSYCHEDELIC
case 22: case 23:
psychedelic(); psychedelic();
break; break;
#endif #endif
#ifdef ANIMATION_BLACKHOLE #ifdef ANIMATION_BLACKHOLE
case 23: case 24:
blackhole(); blackhole();
break; break;
#endif #endif
#ifdef ANIMATION_SQUARES #ifdef ANIMATION_SQUARES
case 24: case 25:
squares(); squares();
break; break;
#endif #endif

View File

@ -58,3 +58,38 @@ unsigned char get_pixel(pixel p){
return 0!= (pixmap[0][p.y][p.x/8] & shl_table[p.x%8]); return 0!= (pixmap[0][p.y][p.x/8] & shl_table[p.x%8]);
} }
} }
/**
* An implementation of Bresenham's line drawing algorithm.
* @param p1 first coordinate of the line
* @param p2 second coordinate of the line
* @param color brightness level of the line
*/
void line(pixel p1,
pixel const p2,
unsigned char const color)
{
operand_t const dx = p1.x < p2.x ? p2.x - p1.x : p1.x - p2.x;
operand_t const sx = p1.x < p2.x ? 1 : -1;
operand_t const dy = p1.y < p2.y ? p2.y - p1.y : p1.y - p2.y;
operand_t const sy = p1.y < p2.y ? 1 : -1;
operand_t error = dx - dy;
while(1)
{
setpixel(p1, color);
if ((p1.x == p2.x) && (p1.y == p2.y))
break;
operand_t const error2 = 2 * error;
if (error2 > -dy)
{
error -= dy;
p1.x += sx;
}
if (error2 < dx)
{
error += dx;
p1.y += sy;
}
}
}

View File

@ -42,6 +42,15 @@ typedef struct cursor{
pixelmode_t mode; pixelmode_t mode;
} cursor_t; } cursor_t;
#if NUM_ROWS < 64 && NUM_COLS < 64
/** use 8 bit operands where feasible */
typedef signed char operand_t;
#else
/** use 16 bit operands if either width or height are >= 64 */
typedef int operand_t;
#endif
/**************************************************************************** /****************************************************************************
* Pixel routines * Pixel routines
*/ */
@ -79,4 +88,8 @@ static inline void set_cursor(cursor_t* cur, pixel p){
setpixel(p, cur->mode ? 3 : 0); setpixel(p, cur->mode ? 3 : 0);
} }
void line(pixel p1,
pixel const p2,
unsigned char const color);
#endif // PIXEL_H #endif // PIXEL_H