drawing routine improved (faster + eliminated 38 bytes), double buffering now mandatory
This commit is contained in:
parent
f97edbfa34
commit
df83dbb8ac
|
@ -59,8 +59,6 @@ comment "Animations"
|
||||||
|
|
||||||
mainmenu_option next_comment
|
mainmenu_option next_comment
|
||||||
comment "Fixed-point math patterns"
|
comment "Fixed-point math patterns"
|
||||||
bool "Double Buffering" FP_DOUBLE_BUFFERING 1
|
|
||||||
|
|
||||||
bool "Plasma" ANIMATION_PLASMA $ANIMATION_FIXEDPOINT
|
bool "Plasma" ANIMATION_PLASMA $ANIMATION_FIXEDPOINT
|
||||||
int "Additional Frame Delay (in ms) For Plasma" FP_PLASMA_DELAY 1
|
int "Additional Frame Delay (in ms) For Plasma" FP_PLASMA_DELAY 1
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
#include "../pixel.h"
|
#include "../pixel.h"
|
||||||
#include "../util.h"
|
#include "../util.h"
|
||||||
|
@ -19,24 +18,6 @@
|
||||||
|
|
||||||
|
|
||||||
#ifdef DOXYGEN
|
#ifdef DOXYGEN
|
||||||
/**
|
|
||||||
* Double buffering helps in reducing the effect of visibly redrawing every
|
|
||||||
* frame. With this option turned on, a frame is rendered into an off-screen
|
|
||||||
* buffer first and then copied to the actual frame buffer in one piece.
|
|
||||||
* However, given the borg's graphics architecture, half painted frames may
|
|
||||||
* still occur, but they are barely noticeable with this option enabled.
|
|
||||||
*
|
|
||||||
* Turn this off if you prefer speed over beauty.
|
|
||||||
*/
|
|
||||||
#define FP_DOUBLE_BUFFERING
|
|
||||||
#endif DOXYGEN
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef FP_LOW_PRECISION
|
|
||||||
#undef FP_LOW_PRECISION
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if NUM_COLS <= 16 && NUM_ROWS <= 16
|
|
||||||
/**
|
/**
|
||||||
* Low precision means that we use Q10.5 values and 16 bit types for almost
|
* Low precision means that we use Q10.5 values and 16 bit types for almost
|
||||||
* every calculation (with multiplication and division as notable exceptions
|
* every calculation (with multiplication and division as notable exceptions
|
||||||
|
@ -52,8 +33,20 @@
|
||||||
* square root, sine, cosine, multiplication etc. utilize 32 bit types.
|
* square root, sine, cosine, multiplication etc. utilize 32 bit types.
|
||||||
*/
|
*/
|
||||||
#define FP_LOW_PRECISION
|
#define FP_LOW_PRECISION
|
||||||
|
#endif /* DOXYGEN */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef FP_LOW_PRECISION
|
||||||
|
#undef FP_LOW_PRECISION
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// low precision for displays where each dimension is less than or equal to 16
|
||||||
|
#if NUM_COLS <= 16 && NUM_ROWS <= 16
|
||||||
|
#define FP_LOW_PRECISION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef FP_LOW_PRECISION
|
#ifdef FP_LOW_PRECISION
|
||||||
/** This is the type we expect ordinary integers to be. */
|
/** This is the type we expect ordinary integers to be. */
|
||||||
typedef int16_t ordinary_int_t;
|
typedef int16_t ordinary_int_t;
|
||||||
|
@ -330,12 +323,6 @@ typedef unsigned char (*fpmath_pattern_func_t)(unsigned char const x,
|
||||||
fixp_t const t,
|
fixp_t const t,
|
||||||
void *const r);
|
void *const r);
|
||||||
|
|
||||||
#ifdef FP_DOUBLE_BUFFERING
|
|
||||||
# define BUFFER pixmap_buffer
|
|
||||||
#else
|
|
||||||
# define BUFFER pixmap
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws an animated two dimensional graph for a given function f(x, y, t).
|
* Draws an animated two dimensional graph for a given function f(x, y, t).
|
||||||
|
@ -346,42 +333,51 @@ typedef unsigned char (*fpmath_pattern_func_t)(unsigned char const x,
|
||||||
* @param fpPattern Function which generates a pattern depending on x, y and t.
|
* @param fpPattern Function which generates a pattern depending on x, y and t.
|
||||||
* @param r A pointer to persistent data required by the fpPattern function.
|
* @param r A pointer to persistent data required by the fpPattern function.
|
||||||
*/
|
*/
|
||||||
static void fixPattern(fixp_t const t_start,
|
static void fixDrawPattern(fixp_t const t_start,
|
||||||
fixp_t const t_stop,
|
fixp_t const t_stop,
|
||||||
fixp_t const t_delta,
|
fixp_t const t_delta,
|
||||||
int const frame_delay,
|
int const frame_delay,
|
||||||
fpmath_pattern_func_t fpPattern,
|
fpmath_pattern_func_t fpPattern,
|
||||||
void *r)
|
void *r)
|
||||||
{
|
{
|
||||||
#ifdef FP_DOUBLE_BUFFERING
|
|
||||||
// double buffering to reduce half painted pictures
|
|
||||||
unsigned char pixmap_buffer[NUMPLANE][NUM_ROWS][LINEBYTES];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (fixp_t t = t_start; t < t_stop; t += t_delta)
|
for (fixp_t t = t_start; t < t_stop; t += t_delta)
|
||||||
{
|
{
|
||||||
|
// For performance reasons we draw the pattern to an off-screen buffer
|
||||||
|
// without distributing bits of higher planes down to lower ones. This
|
||||||
|
// is done afterwards when the off-screen contents are copied to the
|
||||||
|
// actual frame buffer.
|
||||||
|
unsigned char pOffScreen[NUMPLANE + 1][NUM_ROWS][LINEBYTES] = {{{0}}};
|
||||||
for (unsigned char y = 0; y < NUM_ROWS; ++y)
|
for (unsigned char y = 0; y < NUM_ROWS; ++y)
|
||||||
{
|
{
|
||||||
unsigned char nChunk[NUMPLANE + 1][LINEBYTES] = {{0}};
|
for (unsigned char x = 0; x < (LINEBYTES * 8u); ++x)
|
||||||
for (unsigned char x = 0; x < (LINEBYTES * 8); ++x)
|
|
||||||
{
|
{
|
||||||
assert (y < 16);
|
pOffScreen[fpPattern(x, y, t, r)][y][x / 8] |= shl_table[x % 8];
|
||||||
nChunk[fpPattern(x, y, t, r) - 1][x / 8u] |= shl_table[x % 8u];
|
|
||||||
}
|
|
||||||
for (unsigned char p = NUMPLANE; p--;)
|
|
||||||
{
|
|
||||||
for (unsigned char col = LINEBYTES; col--;)
|
|
||||||
{
|
|
||||||
nChunk[p][col] |= nChunk[p + 1][col];
|
|
||||||
BUFFER[p][y][col] = nChunk[p][col];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FP_DOUBLE_BUFFERING
|
// better safe than sorry
|
||||||
memcpy(pixmap, pixmap_buffer, sizeof(pixmap));
|
#if ((NUM_ROWS * LINEBYTES) < 256)
|
||||||
|
typedef unsigned char bitmap_offset_t;
|
||||||
|
#else
|
||||||
|
typedef unsigned int bitmap_offset_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Here we transcribe the off-screen contents to the actual frame buffer
|
||||||
|
// by distributing down 8 bits in parallel (per iteration).
|
||||||
|
for (bitmap_offset_t nOffset = sizeof(pixmap[0]); nOffset--;)
|
||||||
|
{
|
||||||
|
// for whatever reason, gcc produces leaner code if "p" is of type
|
||||||
|
// "unsigned int" as opposed to "unsigned char"
|
||||||
|
for (unsigned int p = NUMPLANE; p--;)
|
||||||
|
{
|
||||||
|
(&pixmap[p][0][0])[nOffset] =
|
||||||
|
(&pOffScreen[p + 1][0][0])[nOffset];
|
||||||
|
(&pOffScreen[p][0][0])[nOffset] |=
|
||||||
|
(&pOffScreen[p + 1][0][0])[nOffset];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait a moment to ensure that the current frame is visible
|
||||||
wait(frame_delay);
|
wait(frame_delay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -471,12 +467,12 @@ void plasma(void)
|
||||||
{
|
{
|
||||||
fixp_plasma_t r;
|
fixp_plasma_t r;
|
||||||
#ifndef __AVR__
|
#ifndef __AVR__
|
||||||
fixPattern(0, fixScaleUp(75), 0.1 * FIX, 80, fixAnimPlasma, &r);
|
fixDrawPattern(0, fixScaleUp(75), 0.1 * FIX, 15, fixAnimPlasma, &r);
|
||||||
#else
|
#else
|
||||||
#ifndef FP_PLASMA_DELAY
|
#ifndef FP_PLASMA_DELAY
|
||||||
#define FP_PLASMA_DELAY 1
|
#define FP_PLASMA_DELAY 1
|
||||||
#endif
|
#endif
|
||||||
fixPattern(0, fixScaleUp(60), 0.1 * FIX,
|
fixDrawPattern(0, fixScaleUp(60), 0.1 * FIX,
|
||||||
FP_PLASMA_DELAY, fixAnimPlasma, &r);
|
FP_PLASMA_DELAY, fixAnimPlasma, &r);
|
||||||
#endif /* __AVR__ */
|
#endif /* __AVR__ */
|
||||||
}
|
}
|
||||||
|
@ -539,12 +535,12 @@ void psychedelic(void)
|
||||||
{
|
{
|
||||||
fixp_psychedelic_t r;
|
fixp_psychedelic_t r;
|
||||||
#ifndef __AVR__
|
#ifndef __AVR__
|
||||||
fixPattern(0, fixScaleUp(75), 0.1 * FIX, 80, fixAnimPsychedelic, &r);
|
fixDrawPattern(0, fixScaleUp(75), 0.1 * FIX, 30, fixAnimPsychedelic, &r);
|
||||||
#else
|
#else
|
||||||
#ifndef FP_PSYCHO_DELAY
|
#ifndef FP_PSYCHO_DELAY
|
||||||
#define FP_PSYCHO_DELAY 15
|
#define FP_PSYCHO_DELAY 15
|
||||||
#endif
|
#endif
|
||||||
fixPattern(0, fixScaleUp(60), 0.1 * FIX, FP_PSYCHO_DELAY,
|
fixDrawPattern(0, fixScaleUp(60), 0.1 * FIX, FP_PSYCHO_DELAY,
|
||||||
fixAnimPsychedelic, &r);
|
fixAnimPsychedelic, &r);
|
||||||
#endif /* __AVR__ */
|
#endif /* __AVR__ */
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue