Changes to create Arduboy2 library from Arduboy

Based on Arduboy library V1.2 development as of April 2, 2016

- Class Arduboy2 replaces class Arduboy.
- Removed files ab_printer.h and ab_printer.cpp. Integrated their
  functionality into class Arduboy2 (as with Arduboy V1.1).
- Added new text functions:
  - getCursorX(), getCursorY() to get the current cursor position.
  - setTextColor(), setTextBackground() to allow inverted text
    (black on white).
  - clear() is overridden to set the cursor to 0, 0 in addition to clearing
    the screen buffer.
- New Class: Arduboy2Base which contains most of the Arduboy functions and
  is inherited by Arduboy2. It doesn't inherit Print, and doesn't include
  text display and cursor control functions. Using it instead of Arduboy2,
  in sketches that don't use text functions, frees up some code space.
- Function drawChar() is in Arduboy2 instead of Arduboy2Base.
- Made setRGBled() static. Not making it static was an oversight.

("Tunes" functions are still moved to the separate ArduboyPlaytune library,
as they were in Arduboy V1.2)
This commit is contained in:
Scott Allen 2016-05-27 17:43:58 -04:00
parent b71b2815b2
commit 54c1fb79ba
9 changed files with 219 additions and 207 deletions

View File

@ -5,6 +5,7 @@
- Ross (@rogosher) - Ross (@rogosher)
- Andrew (@ace-dent) - Andrew (@ace-dent)
- Josh Goebel (@yyyc514) - Josh Goebel (@yyyc514)
- Scott Allen (@MLXXXp)
# Included code from other open source projects # Included code from other open source projects

View File

@ -1,8 +1,9 @@
Software License Agreement (BSD License) Software License Agreement (BSD License)
Copyright (c) 2015, Kevin "Arduboy" Bates Copyright (c) 2016, Kevin "Arduboy" Bates
Copyright (c) 2015, Chris Martinez Copyright (c) 2016, Chris Martinez
Copyright (c) 2015, Josh Goebel Copyright (c) 2016, Josh Goebel
Copyright (c) 2016, Scott Allen
All rights reserved. All rights reserved.
Please see CONTRIBUTORS.md for license information and copyright Please see CONTRIBUTORS.md for license information and copyright

View File

@ -1,9 +1,9 @@
name=Arduboy name=Arduboy2
version=1.2.0-alpha version=0.9.0
author=Chris J. Martinez, Kevin Bates, Josh Goebel, Scott Allen, Ross O. Shoger author=Chris J. Martinez, Kevin Bates, Josh Goebel, Scott Allen, Ross O. Shoger
maintainer=Ross O. Shoger ros@arduboy.com maintainer=Ross O. Shoger ros@arduboy.com
sentence=The Arduboy core library. sentence=The Arduboy core library.
paragraph=This library is for content creation on the Arduboy, a portable gaming platform. The library provides access to the sound, display, and input of the Arduboy. paragraph=This library is for content creation on the Arduboy, a portable gaming platform. The library provides access to the sound, display, and input of the Arduboy.
category=Other category=Other
url=https://github.com/arduboy/arduboy url=https://github.com/arduboy/arduboy2
architectures=avr architectures=avr

View File

@ -1,8 +1,12 @@
#include "Arduboy.h" #include "Arduboy2.h"
#include "glcdfont.c"
#include "ab_logo.c" #include "ab_logo.c"
#include "glcdfont.c"
Arduboy::Arduboy() //========================================
//========== class Arduboy2Base ==========
//========================================
Arduboy2Base::Arduboy2Base()
{ {
// frame management // frame management
setFrameRate(60); setFrameRate(60);
@ -15,7 +19,7 @@ Arduboy::Arduboy()
// lastFrameDurationMs // lastFrameDurationMs
} }
void Arduboy::start() // deprecated void Arduboy2Base::start() // deprecated
{ {
begin(); begin();
} }
@ -23,7 +27,7 @@ void Arduboy::start() // deprecated
// functions called here should be public so users can create their // functions called here should be public so users can create their
// own init functions if they need different behavior than `begin` // own init functions if they need different behavior than `begin`
// provides by default // provides by default
void Arduboy::begin() void Arduboy2Base::begin()
{ {
boot(); // raw hardware boot(); // raw hardware
@ -37,7 +41,7 @@ void Arduboy::begin()
audio.begin(); audio.begin();
} }
void Arduboy::flashlight() void Arduboy2Base::flashlight()
{ {
// sendLCDCommand(OLED_ALL_PIXELS_ON); // smaller than allPixelsOn() // sendLCDCommand(OLED_ALL_PIXELS_ON); // smaller than allPixelsOn()
blank(); blank();
@ -48,7 +52,7 @@ void Arduboy::flashlight()
setRGBled(0,0,0); setRGBled(0,0,0);
} }
void Arduboy::bootLogo() void Arduboy2Base::bootLogo()
{ {
// setRGBled(10,0,0); // setRGBled(10,0,0);
for(int8_t y = -18; y<=24; y++) { for(int8_t y = -18; y<=24; y++) {
@ -71,18 +75,18 @@ void Arduboy::bootLogo()
/* Frame management */ /* Frame management */
void Arduboy::setFrameRate(uint8_t rate) void Arduboy2Base::setFrameRate(uint8_t rate)
{ {
frameRate = rate; frameRate = rate;
eachFrameMillis = 1000/rate; eachFrameMillis = 1000/rate;
} }
bool Arduboy::everyXFrames(uint8_t frames) bool Arduboy2Base::everyXFrames(uint8_t frames)
{ {
return frameCount % frames == 0; return frameCount % frames == 0;
} }
bool Arduboy::nextFrame() bool Arduboy2Base::nextFrame()
{ {
long now = millis(); long now = millis();
uint8_t remaining; uint8_t remaining;
@ -129,19 +133,19 @@ bool Arduboy::nextFrame()
return post_render; return post_render;
} }
int Arduboy::cpuLoad() int Arduboy2Base::cpuLoad()
{ {
return lastFrameDurationMs*100 / eachFrameMillis; return lastFrameDurationMs*100 / eachFrameMillis;
} }
void Arduboy::initRandomSeed() void Arduboy2Base::initRandomSeed()
{ {
power_adc_enable(); // ADC on power_adc_enable(); // ADC on
randomSeed(~rawADC(ADC_TEMP) * ~rawADC(ADC_VOLTAGE) * ~micros() + micros()); randomSeed(~rawADC(ADC_TEMP) * ~rawADC(ADC_VOLTAGE) * ~micros() + micros());
power_adc_disable(); // ADC off power_adc_disable(); // ADC off
} }
uint16_t Arduboy::rawADC(byte adc_bits) uint16_t Arduboy2Base::rawADC(byte adc_bits)
{ {
ADMUX = adc_bits; ADMUX = adc_bits;
// we also need MUX5 for temperature check // we also need MUX5 for temperature check
@ -158,17 +162,17 @@ uint16_t Arduboy::rawADC(byte adc_bits)
/* Graphics */ /* Graphics */
void Arduboy::clearDisplay() // deprecated void Arduboy2Base::clearDisplay() // deprecated
{ {
clear(); clear();
} }
void Arduboy::clear() void Arduboy2Base::clear()
{ {
fillScreen(BLACK); fillScreen(BLACK);
} }
void Arduboy::drawPixel(int x, int y, uint8_t color) void Arduboy2Base::drawPixel(int x, int y, uint8_t color)
{ {
#ifdef PIXEL_SAFE_MODE #ifdef PIXEL_SAFE_MODE
if (x < 0 || x > (WIDTH-1) || y < 0 || y > (HEIGHT-1)) if (x < 0 || x > (WIDTH-1) || y < 0 || y > (HEIGHT-1))
@ -188,14 +192,14 @@ void Arduboy::drawPixel(int x, int y, uint8_t color)
} }
} }
uint8_t Arduboy::getPixel(uint8_t x, uint8_t y) uint8_t Arduboy2Base::getPixel(uint8_t x, uint8_t y)
{ {
uint8_t row = y / 8; uint8_t row = y / 8;
uint8_t bit_position = y % 8; uint8_t bit_position = y % 8;
return (sBuffer[(row*WIDTH) + x] & _BV(bit_position)) >> bit_position; return (sBuffer[(row*WIDTH) + x] & _BV(bit_position)) >> bit_position;
} }
void Arduboy::drawCircle(int16_t x0, int16_t y0, uint8_t r, uint8_t color) void Arduboy2Base::drawCircle(int16_t x0, int16_t y0, uint8_t r, uint8_t color)
{ {
int16_t f = 1 - r; int16_t f = 1 - r;
int16_t ddF_x = 1; int16_t ddF_x = 1;
@ -232,7 +236,7 @@ void Arduboy::drawCircle(int16_t x0, int16_t y0, uint8_t r, uint8_t color)
} }
} }
void Arduboy::drawCircleHelper void Arduboy2Base::drawCircleHelper
(int16_t x0, int16_t y0, uint8_t r, uint8_t cornername, uint8_t color) (int16_t x0, int16_t y0, uint8_t r, uint8_t cornername, uint8_t color)
{ {
int16_t f = 1 - r; int16_t f = 1 - r;
@ -277,13 +281,13 @@ void Arduboy::drawCircleHelper
} }
} }
void Arduboy::fillCircle(int16_t x0, int16_t y0, uint8_t r, uint8_t color) void Arduboy2Base::fillCircle(int16_t x0, int16_t y0, uint8_t r, uint8_t color)
{ {
drawFastVLine(x0, y0-r, 2*r+1, color); drawFastVLine(x0, y0-r, 2*r+1, color);
fillCircleHelper(x0, y0, r, 3, 0, color); fillCircleHelper(x0, y0, r, 3, 0, color);
} }
void Arduboy::fillCircleHelper void Arduboy2Base::fillCircleHelper
(int16_t x0, int16_t y0, uint8_t r, uint8_t cornername, int16_t delta, (int16_t x0, int16_t y0, uint8_t r, uint8_t cornername, int16_t delta,
uint8_t color) uint8_t color)
{ {
@ -321,7 +325,7 @@ void Arduboy::fillCircleHelper
} }
} }
void Arduboy::drawLine void Arduboy2Base::drawLine
(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint8_t color) (int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint8_t color)
{ {
// bresenham's algorithm - thx wikpedia // bresenham's algorithm - thx wikpedia
@ -372,7 +376,7 @@ void Arduboy::drawLine
} }
} }
void Arduboy::drawRect void Arduboy2Base::drawRect
(int16_t x, int16_t y, uint8_t w, uint8_t h, uint8_t color) (int16_t x, int16_t y, uint8_t w, uint8_t h, uint8_t color)
{ {
drawFastHLine(x, y, w, color); drawFastHLine(x, y, w, color);
@ -381,7 +385,7 @@ void Arduboy::drawRect
drawFastVLine(x+w-1, y, h, color); drawFastVLine(x+w-1, y, h, color);
} }
void Arduboy::drawFastVLine void Arduboy2Base::drawFastVLine
(int16_t x, int16_t y, uint8_t h, uint8_t color) (int16_t x, int16_t y, uint8_t h, uint8_t color)
{ {
int end = y+h; int end = y+h;
@ -391,7 +395,7 @@ void Arduboy::drawFastVLine
} }
} }
void Arduboy::drawFastHLine void Arduboy2Base::drawFastHLine
(int16_t x, int16_t y, uint8_t w, uint8_t color) (int16_t x, int16_t y, uint8_t w, uint8_t color)
{ {
// Do bounds/limit checks // Do bounds/limit checks
@ -438,7 +442,7 @@ void Arduboy::drawFastHLine
} }
} }
void Arduboy::fillRect void Arduboy2Base::fillRect
(int16_t x, int16_t y, uint8_t w, uint8_t h, uint8_t color) (int16_t x, int16_t y, uint8_t w, uint8_t h, uint8_t color)
{ {
// stupidest version - update in subclasses if desired! // stupidest version - update in subclasses if desired!
@ -448,7 +452,7 @@ void Arduboy::fillRect
} }
} }
void Arduboy::fillScreen(uint8_t color) void Arduboy2Base::fillScreen(uint8_t color)
{ {
// C version : // C version :
// //
@ -486,7 +490,7 @@ void Arduboy::fillScreen(uint8_t color)
); );
} }
void Arduboy::drawRoundRect void Arduboy2Base::drawRoundRect
(int16_t x, int16_t y, uint8_t w, uint8_t h, uint8_t r, uint8_t color) (int16_t x, int16_t y, uint8_t w, uint8_t h, uint8_t r, uint8_t color)
{ {
// smarter version // smarter version
@ -501,7 +505,7 @@ void Arduboy::drawRoundRect
drawCircleHelper(x+r, y+h-r-1, r, 8, color); drawCircleHelper(x+r, y+h-r-1, r, 8, color);
} }
void Arduboy::fillRoundRect void Arduboy2Base::fillRoundRect
(int16_t x, int16_t y, uint8_t w, uint8_t h, uint8_t r, uint8_t color) (int16_t x, int16_t y, uint8_t w, uint8_t h, uint8_t r, uint8_t color)
{ {
// smarter version // smarter version
@ -512,7 +516,7 @@ void Arduboy::fillRoundRect
fillCircleHelper(x+r, y+r, r, 2, h-2*r-1, color); fillCircleHelper(x+r, y+r, r, 2, h-2*r-1, color);
} }
void Arduboy::drawTriangle void Arduboy2Base::drawTriangle
(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t color) (int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t color)
{ {
drawLine(x0, y0, x1, y1, color); drawLine(x0, y0, x1, y1, color);
@ -520,7 +524,7 @@ void Arduboy::drawTriangle
drawLine(x2, y2, x0, y0, color); drawLine(x2, y2, x0, y0, color);
} }
void Arduboy::fillTriangle void Arduboy2Base::fillTriangle
(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t color) (int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t color)
{ {
@ -623,7 +627,7 @@ void Arduboy::fillTriangle
} }
} }
void Arduboy::drawBitmap void Arduboy2Base::drawBitmap
(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t w, uint8_t h, (int16_t x, int16_t y, const uint8_t *bitmap, uint8_t w, uint8_t h,
uint8_t color) uint8_t color)
{ {
@ -663,10 +667,10 @@ void Arduboy::drawBitmap
} }
void Arduboy::drawSlowXYBitmap void Arduboy2Base::drawSlowXYBitmap
(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t w, uint8_t h, uint8_t color) (int16_t x, int16_t y, const uint8_t *bitmap, uint8_t w, uint8_t h, uint8_t color)
{ {
// no need to dar at all of we're offscreen // no need to draw at all of we're offscreen
if (x+w < 0 || x > WIDTH-1 || y+h < 0 || y > HEIGHT-1) if (x+w < 0 || x > WIDTH-1 || y+h < 0 || y > HEIGHT-1)
return; return;
@ -681,16 +685,82 @@ void Arduboy::drawSlowXYBitmap
} }
void Arduboy::drawChar void Arduboy2Base::display()
(int16_t x, int16_t y, unsigned char c, uint8_t color, uint8_t bg, uint8_t size) {
this->paintScreen(sBuffer);
}
unsigned char* Arduboy2Base::getBuffer()
{
return sBuffer;
}
boolean Arduboy2Base::pressed(uint8_t buttons)
{
return (buttonsState() & buttons) == buttons;
}
boolean Arduboy2Base::notPressed(uint8_t buttons)
{
return (buttonsState() & buttons) == 0;
}
void Arduboy2Base::swap(int16_t& a, int16_t& b)
{
int temp = a;
a = b;
b = temp;
}
Arduboy2::Arduboy2()
{
cursor_x = 0;
cursor_y = 0;
textColor = 1;
textBackground = 0;
textSize = 1;
textWrap = 0;
}
//====================================
//========== class Arduboy2 ==========
//====================================
size_t Arduboy2::write(uint8_t c)
{
if (c == '\n')
{
cursor_y += textSize * 8;
cursor_x = 0;
}
else if (c == '\r')
{
// skip em
}
else
{
drawChar(cursor_x, cursor_y, c, textColor, textBackground, textSize);
cursor_x += textSize * 6;
if (textWrap && (cursor_x > (WIDTH - textSize * 6)))
{
// calling ourselves recursively for 'newline' is
// 12 bytes smaller than doing the same math here
write('\n');
}
}
}
void Arduboy2::drawChar
(int16_t x, int16_t y, unsigned char c, uint8_t color, uint8_t bg, uint8_t size)
{ {
boolean draw_background = bg != color; boolean draw_background = bg != color;
if ((x >= WIDTH) || // Clip right if ((x >= WIDTH) || // Clip right
(y >= HEIGHT) || // Clip bottom (y >= HEIGHT) || // Clip bottom
((x + 5 * size - 1) < 0) || // Clip left ((x + 5 * size - 1) < 0) || // Clip left
((y + 8 * size - 1) < 0) // Clip top ((y + 8 * size - 1) < 0) // Clip top
) )
{ {
return; return;
} }
@ -723,30 +793,43 @@ void Arduboy::drawChar
} }
} }
void Arduboy::display() void Arduboy2::setCursor(int16_t x, int16_t y)
{ {
this->paintScreen(sBuffer); cursor_x = x;
cursor_y = y;
} }
unsigned char* Arduboy::getBuffer() uint16_t Arduboy2::getCursorX() {
{ return cursor_x;
return sBuffer;
} }
boolean Arduboy::pressed(uint8_t buttons) uint16_t Arduboy2::getCursorY() {
{ return cursor_y;
return (buttonsState() & buttons) == buttons;
} }
boolean Arduboy::notPressed(uint8_t buttons) void Arduboy2::setTextColor(uint8_t color)
{ {
return (buttonsState() & buttons) == 0; textColor = color;
} }
void Arduboy::swap(int16_t& a, int16_t& b) void Arduboy2::setTextBackground(uint8_t bg)
{ {
int temp = a; textBackground = bg;
a = b; }
b = temp;
void Arduboy2::setTextSize(uint8_t s)
{
// size must always be 1 or higher
textSize = max(1, s);
}
void Arduboy2::setTextWrap(boolean w)
{
textWrap = w;
}
void Arduboy2::clear() {
Arduboy2Base::clear();
cursor_x = cursor_y = 0;
} }

View File

@ -1,8 +1,7 @@
#ifndef Arduboy_h #ifndef Arduboy2_h
#define Arduboy_h #define Arduboy2_h
#include "core/core.h" #include "core/core.h"
#include "ab_printer.h"
#include <Print.h> #include <Print.h>
#include <limits.h> #include <limits.h>
@ -10,7 +9,7 @@
// For a version number in the form of x.y.z the value of the define will be // For a version number in the form of x.y.z the value of the define will be
// ((x * 10000) + (y * 100) + (z)) as a decimal number. // ((x * 10000) + (y * 100) + (z)) as a decimal number.
// So, it will read as xxxyyzz, with no leading zeros on x. // So, it will read as xxxyyzz, with no leading zeros on x.
#define ARDUBOY_LIB_VER 10200 #define ARDUBOY_LIB_VER 20000
// EEPROM settings // EEPROM settings
#define EEPROM_VERSION 0 #define EEPROM_VERSION 0
@ -36,10 +35,16 @@
#define ADC_TEMP (_BV(REFS0) | _BV(REFS1) | _BV(MUX2) | _BV(MUX1) | _BV(MUX0)) #define ADC_TEMP (_BV(REFS0) | _BV(REFS1) | _BV(MUX2) | _BV(MUX1) | _BV(MUX0))
class Arduboy : public ArduboyCore //==================================
//========== Arduboy2Base ==========
//==================================
class Arduboy2Base : public ArduboyCore
{ {
public: public:
Arduboy(); Arduboy2Base();
ArduboyAudio audio;
/// Returns true if the button mask passed in is pressed. /// Returns true if the button mask passed in is pressed.
/** /**
@ -54,21 +59,17 @@ public:
boolean notPressed(uint8_t buttons); boolean notPressed(uint8_t buttons);
/// Initialize hardware, boot logo, boot utilities, etc. /// Initialize hardware, boot logo, boot utilities, etc.
void begin();
/// Init just hardware, no logo, no boot utilities.
/** /**
* Look at the source for `begin()` and just rip out what you do not * To free up some code space for use by the sketch, you can use "boot()"
* need and start there. Calling just `boot()` might work also * instead of "begin()" to eliminate some of the some of the things that
* depending on your requirements. * aren't really required, such as displaying the boot logo.
* *
* The minimum recommended `begin` replacement: * Look at the source for "begin()" and after calling "boot()" call
* * whatever functions "begin()" does that you still want to keep.
* arduboy.boot() // raw hardware init * If your sketch uses the speaker, it's probably a good idea to at least
* arduboy.audio.begin() // if you need audio * call "audio.begin()".
*/ */
// void boot(); // defined in core.cpp void begin();
void start() __attribute__((deprecated, warning("use begin() instead"))); void start() __attribute__((deprecated, warning("use begin() instead")));
/// Scrolls in the Arduboy logo /// Scrolls in the Arduboy logo
@ -161,12 +162,9 @@ public:
*/ */
void drawSlowXYBitmap(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t w, uint8_t h, uint8_t color); void drawSlowXYBitmap(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t w, uint8_t h, uint8_t color);
/// Draws an ASCII character at a point. /// Get a pointer to the display buffer.
void drawChar(int16_t x, int16_t y, unsigned char c, uint8_t color, uint8_t bg, uint8_t size);
unsigned char* getBuffer(); unsigned char* getBuffer();
/// Seeds the random number generator with entropy from the temperature, voltage reading, and microseconds since boot. /// Seeds the random number generator with entropy from the temperature, voltage reading, and microseconds since boot.
/** /**
* This method is still most effective when called semi-randomly such * This method is still most effective when called semi-randomly such
@ -178,8 +176,6 @@ public:
/// Swap the references of two pointers. /// Swap the references of two pointers.
void swap(int16_t& a, int16_t& b); void swap(int16_t& a, int16_t& b);
ArduboyAudio audio;
void setFrameRate(uint8_t rate); void setFrameRate(uint8_t rate);
bool nextFrame(); bool nextFrame();
bool everyXFrames(uint8_t frames); bool everyXFrames(uint8_t frames);
@ -205,13 +201,61 @@ public:
protected: protected:
unsigned char sBuffer[(HEIGHT*WIDTH)/8]; unsigned char sBuffer[(HEIGHT*WIDTH)/8];
};
//==============================
//========== Arduboy2 ==========
//==============================
class Arduboy2 : public Print, public Arduboy2Base
{
public:
Arduboy2();
/// Writes a single ASCII character to the screen.
virtual size_t write(uint8_t);
/// Draws an ASCII character at a point.
void drawChar(int16_t x, int16_t y, unsigned char c, uint8_t color, uint8_t bg, uint8_t size);
/// Sets the location of the text cursor.
void setCursor(int16_t x, int16_t y);
/// Get the text cursor X position
uint16_t getCursorX();
/// Get the text cursor Y position
uint16_t getCursorY();
/// Sets the text foreground color
void setTextColor(uint8_t color);
/// Sets the text background color
void setTextBackground(uint8_t bg);
/// Set the text size
/**
* Individual ASCII characters are 6x8 pixels
* (5x7 with spacing on two edges). The size is a pixel multiplier,
* so a size of 2 means each character will be 12x16, etc.
*/
void setTextSize(uint8_t s);
/// Sets whether text will wrap at screen edges.
void setTextWrap(boolean w);
/// Clears the display and sets the cursor to 0, 0
void clear();
protected: protected:
int16_t cursor_x; int16_t cursor_x;
int16_t cursor_y; int16_t cursor_y;
uint8_t textsize; uint8_t textColor;
boolean wrap; // If set, 'wrap' text at right edge of display uint8_t textBackground;
uint8_t textSize;
boolean textWrap; // If set, 'wrap' text at right edge of display
}; };
#endif #endif

View File

@ -1,54 +0,0 @@
#include "Arduboy.h"
#include "ab_printer.h"
#include "glcdfont.c"
AbPrinter::AbPrinter(Arduboy &ab)
{
arduboy = &ab;
// font rendering
cursor_x = 0;
cursor_y = 0;
size = 1;
}
size_t AbPrinter::write(uint8_t c)
{
if (c == '\n')
{
cursor_y += size*8;
cursor_x = 0;
}
else if (c == '\r')
{
// skip em
}
else
{
arduboy->drawChar(cursor_x, cursor_y, c, 1, 0, size);
cursor_x += size*6;
if (wrap && (cursor_x > (WIDTH - size*6)))
{
// calling ourselves recursively for 'newline' is
// 12 bytes smaller than doing the same math here
write('\n');
}
}
}
void AbPrinter::setCursor(int16_t x, int8_t y)
{
cursor_x = x;
cursor_y = y;
}
void AbPrinter::setSize(uint8_t s)
{
// size must always be 1 or higher
size = max(1,s);
}
void AbPrinter::setWrap(boolean w)
{
wrap = w;
}

View File

@ -1,63 +0,0 @@
#ifndef AbPrinter_h
#define AbPrinter_h
#include <Arduino.h>
#include "Arduboy.h"
#include <Print.h>
class Arduboy;
/// Separate class to break out Print subclassing
/**
* This is necessary because C++ keeps a virtual function lookup table around
* for the virtual function "write" that the Print subclass requires. That
* single reference to the "write" function in the vtable means "write" will
* always be compiled and including in the final ouput (even if it's never
* actually used in your sketch) - which means it's dependencies are also
# included:
*
* - drawChar
* - font (256 bytes!)
* - drawRect (for large font 'pixels')
* - cursor_x, cursor_y, wrap_mode, etc.
*
* This quickly adds up to 1 to 2kb of wasted space that many graphics
* based games never take advantage of. By breaking printing out into a
* separate class we prevent this. If you need it use it, if not then it
* will get dropped by the compiler during building.
*
*/
class AbPrinter : public Print
{
public:
AbPrinter(Arduboy &ab);
/// Writes a single ASCII character to the screen.
virtual size_t write(uint8_t);
/// Sets the location of the screen cursor.
void setCursor(int16_t x, int8_t y);
/// Set text size
/**
* As mentioned in drawChar(), individual ASCII characters are 6x8 pixels
* (5x7 with spacing on two edges). The size is a pixel multiplier,
* so a size of 2 means each character will be 12x16, etc.
*/
void setSize(uint8_t s);
/// Sets whether text will wrap at screen edges.
void setWrap(boolean w);
private:
Arduboy *arduboy;
protected:
int16_t cursor_x;
int8_t cursor_y;
uint8_t size;
boolean wrap; // If set, 'wrap' text at right edge of display
};
#endif

View File

@ -1,4 +1,4 @@
#include "Arduboy.h" #include "Arduboy2.h"
#include "audio.h" #include "audio.h"
bool ArduboyAudio::audio_enabled = false; bool ArduboyAudio::audio_enabled = false;

View File

@ -255,7 +255,7 @@ public:
void static sendLCDCommand(uint8_t command); void static sendLCDCommand(uint8_t command);
/// set the light output of the RGB LEB /// set the light output of the RGB LEB
void setRGBled(uint8_t red, uint8_t green, uint8_t blue); void static setRGBled(uint8_t red, uint8_t green, uint8_t blue);
/// boots the hardware /// boots the hardware
/** /**