27
27
#include "display.h"
30
#define MAX_MESSAGE_LENGTH 64
33
// the buffer for the message
34
static char _message_buffer[ MAX_MESSAGE_LENGTH ];
36
// the current message
37
static PString _message( _message_buffer, sizeof( _message_buffer ) );
40
static char _glyph_cache[ 8 ];
42
// the character the current cached glyph is for
43
static char _glyph_cache_char;
49
static unsigned long _last_millis;
51
// duration last frame (in case we can't calculate it this frame!)
52
static unsigned long _duration;
54
// scroll position (in segments )
55
static signed long _scroll;
59
void cache_glyph( char c )
30
TextRenderer &TextRenderer::get_instance()
32
static TextRenderer text_renderer;
37
PString &TextRenderer::get_pstring()
41
_last_millis = ::millis();
42
_scroll = -TEXT_DISPLAY_SEGMENTS;
48
void TextRenderer::draw_reset()
50
// how many milliseconds have elapsed since last frame?
51
unsigned long millis = ::millis();
52
if( millis > _last_millis )
53
_duration = millis - _last_millis;
54
_last_millis = millis;
57
_scroll += ( _duration * TEXT_SCROLL_SPEED / 1000 );
58
if( _scroll > (signed long)_message.length() * 8 * TEXT_SCALE )
59
_scroll -= (signed long)_message.length() * 8 * TEXT_SCALE + TEXT_DISPLAY_SEGMENTS;
63
void TextRenderer::draw_scroll( int segment )
65
segment = xform_segment( segment );
69
render( (long)segment + _scroll );
73
TextRenderer::TextRenderer()
75
_message( _message_buffer, sizeof( _message_buffer ) ),
76
_glyph_cache_char( '\0' ),
82
int TextRenderer::xform_segment( int segment )
84
if( segment < TEXT_DISPLAY_SEGMENTS / 2 )
85
return segment + TEXT_DISPLAY_SEGMENTS / 2;
86
else if( segment >= NUM_SEGMENTS - TEXT_DISPLAY_SEGMENTS / 2 )
87
return segment - ( NUM_SEGMENTS - TEXT_DISPLAY_SEGMENTS / 2 );
93
void TextRenderer::render( int x )
106
char c = ( pos >= 0 && pos < (signed)_message.length() )? _message[ pos ] : ' ';
107
if( c != _glyph_cache_char ) {
108
_glyph_cache_char = c;
109
get_glyph( c, _glyph_cache );
113
char col_data = _glyph_cache[ x % 8 ];
114
for( int a = 0; a < 8; a++ )
115
Display::led( 8 - a, ( col_data & ( 1 << a ) )? true : false );
119
void TextRenderer::get_glyph( char c, char *glyph )
61
121
static char fonts[][ 66 * 8 ] PROGMEM = {
357
// space? or copy glyph from progmem?
359
memset( _glyph_cache, 0, 8 );
361
memcpy_P( _glyph_cache, &( fonts[ _font ][ pos * 8 ] ), 8 );
365
// convert segment to display-space segment
366
int xform_segment( int segment )
368
if( segment < TEXT_DISPLAY_SEGMENTS / 2 )
369
return segment + TEXT_DISPLAY_SEGMENTS / 2;
370
else if( segment >= NUM_SEGMENTS - TEXT_DISPLAY_SEGMENTS / 2 )
371
return segment - ( NUM_SEGMENTS - TEXT_DISPLAY_SEGMENTS / 2 );
377
// draw a column of pixels from the current message
389
// make sure the correct glyph is cached
391
cache_glyph( ( pos >= 0 && pos < (signed)_message.length() )? _message[ pos ] : ' ' );
394
char col_data = _glyph_cache[ x % 8 ];
395
for( int a = 0; a < 8; a++ )
396
Display::led( 8 - a, ( col_data & ( 1 << a ) )? true : false );
400
PString &TextRenderer::get_pstring()
404
_last_millis = ::millis();
405
_scroll = -TEXT_DISPLAY_SEGMENTS;
411
void TextRenderer::draw_reset()
413
// how many milliseconds have elapsed since last frame?
414
unsigned long millis = ::millis();
415
if( millis > _last_millis )
416
_duration = millis - _last_millis;
417
_last_millis = millis;
419
// move on scroll pos
420
_scroll += ( _duration * TEXT_SCROLL_SPEED / 1000 );
421
if( _scroll > (signed long)_message.length() * 8 * TEXT_SCALE )
422
_scroll -= (signed long)_message.length() * 8 * TEXT_SCALE + TEXT_DISPLAY_SEGMENTS;
426
void TextRenderer::draw_scroll( int segment )
428
segment = xform_segment( segment );
432
render( (long)segment + _scroll );
412
memset( glyph, 0, 8 );
414
memcpy_P( glyph, &( fonts[ _font ][ pos * 8 ] ), 8 );