PaulStoffregen
Well-known member
It's pretty a standard loss leader pricing model. Or more technically "penetration pricing" since it's originating with the manufacturer.
#include <TFT_ILI9163C.h>
/////////////////////////////font data///////////////////////////////
const char standard_font_data[720]= {
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0, // (start)
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 ,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, // (end)
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0, //a (start)
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0, //
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0, //
0 ,5 ,10,10,10,10,10,3 ,0 ,0, //
0 ,0 ,0 ,0 ,0 ,0 ,3 ,10,0 ,0, //
0 ,6 ,10,10,10,10,10,10,0 ,0, //
0 ,10,3 ,0 ,0 ,0 ,3 ,10,0 ,0, //
0 ,10,3 ,0 ,0 ,0 ,3 ,10,0 ,0, //
0 ,5 ,10,10,10,10,10,6 ,8 ,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, //a (end)
0 ,8 ,10,0 ,0 ,0 ,0 ,0 ,0 ,0, //b (start)
0 ,0 ,10,0 ,0 ,0 ,0 ,0 ,0 ,0, //
0 ,0 ,10,3 ,0 ,0 ,0 ,0 ,0 ,0, //
0 ,0 ,10,10,10,10,10,3 ,0 ,0, //
0 ,0 ,10,6 ,0 ,0 ,3 ,10,0 ,0, //
0 ,0 ,10,0 ,0 ,0 ,0 ,10,0 ,0, //
0 ,0 ,10,0 ,0 ,0 ,0 ,10,0 ,0, //
0 ,0 ,10,5 ,0 ,0 ,3 ,10,0 ,0, //
0 ,8 ,10,10,10,10,10,3 ,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, //b (end)
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0, //c (start)
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0, //
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0, //
0 ,0 ,6 ,10,10,10,10,5 ,0 ,0, //
0 ,0 ,10,3 ,0 ,0 ,3 ,10,0 ,0, //
0 ,0 ,10,0 ,0 ,0 ,0 ,0 ,0 ,0, //
0 ,0 ,10,0 ,0 ,0 ,0 ,0 ,0 ,0, //
0 ,0 ,10,3 ,0 ,0 ,3 ,10,0 ,0, //
0 ,0 ,6 ,10,10,10,10,5 ,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, //c (end)
0 ,0 ,0 ,0 ,0 ,0 ,1 ,10,3 ,0, //d (start)
0 ,0 ,0 ,0 ,0 ,0 ,0 ,10,0 ,0, //
0 ,0 ,0 ,0 ,0 ,0 ,1 ,10,0 ,0, //
0 ,0 ,6 ,10,10,10,10,10,0 ,0, //
0 ,0 ,10,3 ,0 ,0 ,3 ,10,0 ,0, //
0 ,0 ,10,0 ,0 ,0 ,0 ,10,0 ,0, //
0 ,0 ,10,0 ,0 ,0 ,0 ,10,0 ,0, //
0 ,0 ,10,3 ,0 ,0 ,3 ,10,0 ,0, //
0 ,0 ,6 ,10,10,10,10,6 ,8 ,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, //d (end)
0 ,0 ,0 ,1 ,6 ,6 ,1 ,0 ,0 ,0, // ! (start)
0 ,0 ,0 ,5 ,10,10,5 ,0 ,0 ,0, //
0 ,0 ,0 ,4 ,10,10,4 ,0 ,0 ,0, //
0 ,0 ,0 ,3 ,10,10,3 ,0 ,0 ,0, //
0 ,0 ,0 ,1 ,10,10,1 ,0 ,0 ,0, //
0 ,0 ,0 ,0 ,10,10,0 ,0 ,0 ,0, //
0 ,0 ,0 ,0 ,8 ,8 ,0 ,0 ,0 ,0, //
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0, //
0 ,0 ,0 ,0 ,2 ,2 ,0 ,0 ,0 ,0, //
0 ,0 ,0 ,0 ,10,10,0 ,0 ,0 ,0, //
0 ,0 ,0 ,0 ,4 ,4 ,0 ,0 ,0 ,0, //
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0, // ! (end)
};
struct {
const uint8_t font_id = 0; //default
const uint8_t font_width = 10;
const uint8_t font_height = 12;
const char *data = standard_font_data;
} standard_font_AA;
//////////////////////////////GPU data/////////////////////
//*************************************************
//drawing functions
//*************************************************
class GPU : public Print {
struct Font_Data{
//font stuff
uint8_t cursor_x = 0, cursor_y = 0, textsize = 1, wrap = 0;
uint16_t textcolor = 0xffff, textbgcolor = 0xffff, fontKern = 1;
const unsigned char * fontData = glcdFont;
uint8_t fontWidth = pgm_read_byte(fontData+0);
uint8_t fontHeight = pgm_read_byte(fontData+1);
uint8_t fontStart = pgm_read_byte(fontData+2);
uint8_t fontLength = pgm_read_byte(fontData+3);
} Font;
//for font-writing
const unsigned char char_map[6] = {' ','a','b','c','d','!'};
struct {
uint8_t font_id = standard_font_AA.font_id; //default
uint8_t font_width = standard_font_AA.font_width;
uint8_t font_height = standard_font_AA.font_height;
const char *data = standard_font_AA.data;
} current_font;
public:
size_t write(uint8_t c) {
if (c == '\n') {
Cursor(Font.textsize*8,0);
} else if (c == '\r') {
// skip em
} else {
drawChar_cont(Font.cursor_x,Font.cursor_y,c,Font.textcolor,Font.textbgcolor,Font.textsize);
Font.cursor_x += 1*(current_font.font_width);
if (Font.wrap && (Font.cursor_x > (128 - Font.textsize*Font.fontWidth))) {
Font.cursor_y += Font.textsize*current_font.font_height;
Font.cursor_x = 0;
}
}
return 1;
}
void drawChar_cont(int16_t x, int16_t y, unsigned char c,uint16_t color, uint16_t bg, uint8_t size) {
if((x >= 127) || // Clip right
(y >= 127) || // Clip bottom
((x + 8 * size - 1) < 0) || // Clip left
((y + 12 * size - 1) < 0)) // Clip top
return;
uint16_t xx = x;
uint16_t yy = y;
uint8_t width = current_font.font_width;
uint8_t height = current_font.font_height;
uint8_t charindex = 0;
bool found = true;
for (uint8_t i =0; i < sizeof(char_map); i++) {
if (char_map[i] == c) {
found = true;
charindex = i;
}
}
if (found) {
uint16_t offset =0;
for (uint8_t i = 0; i < height-1; i++) {
for (uint8_t j = 0; j < width-1; j++){
float pix;
pix = (float)(pgm_read_byte_near(current_font.data+(charindex*(width*height))+offset))/10;
if (pix > 1) {
pix = 1;
}
draw_pixel_AA(xx+j,yy+i,color,pix);
offset++;
}
offset++;
}
}
}
/*
void drawChar_cont(int16_t x, int16_t y, unsigned char c,uint16_t color, uint16_t bg, uint8_t size) {
if((x >= 127) || // Clip right
(y >= 127) || // Clip bottom
((x + 8 * size - 1) < 0) || // Clip left
((y + 12 * size - 1) < 0)) // Clip top
return;
if (c < Font.fontStart || c > Font.fontStart+Font.fontLength) {
c = 0;
} else {
c -= Font.fontStart;
}
uint16_t bitCount = 0;
uint16_t line = 0;
uint16_t i,j;
int fontIndex = (c*(Font.fontWidth*Font.fontHeight)/8)+4;
for (i=0; i<Font.fontHeight; i++ ) {
//uint8_t line;
for (j = 0; j<Font.fontWidth; j++) {
if (bitCount++%8 == 0) line = pgm_read_byte(Font.fontData+fontIndex++);
if (line & 0x80) {
draw_pixel(x+j, y+i, color);
} else if (bg != color) {
draw_pixel(x+j, y+i, bg);
}
line <<= 1;
}
}
}
*/
uint8_t height() {
return s_height;
}
uint8_t width() {
return s_width;
}
private:
struct Ative_Area {
uint16_t active_x1;
uint16_t active_y1;
uint16_t active_x2;
uint16_t active_y2;
double alpha;
} Area;
uint8_t s_width, s_height;
void swap(int16_t &a, int16_t &b) { int16_t t = a; a = b; b = t; }
TFT_ILI9163C tft = TFT_ILI9163C(PIN::TFT_CS, PIN::TFT_DC);
void blend_screen(double AA) {
if (AA > 0.2) {
AA = 0.2;
}
uint16_t bgbuffer[5];
for (int16_t y = -2; y < 130; y++) {
for (int16_t x = -2; x < 130; x++) {
bgbuffer[0] = get_pixel(x,y);
bgbuffer[1] = blendColor(get_pixel(x-1,y),bgbuffer[0], AA); //left pixel
bgbuffer[2] = blendColor(get_pixel(x+1,y),bgbuffer[0], AA); //right pixel
bgbuffer[3] = blendColor(get_pixel(x,y-1),bgbuffer[0], AA); //top pixel
bgbuffer[4] = blendColor(get_pixel(x,y+1),bgbuffer[0], AA); //bottom pixel
draw_pixel(x,y,bgbuffer[0]);
draw_pixel(x-1,y,bgbuffer[1]);
draw_pixel(x+1,y,bgbuffer[2]);
draw_pixel(x,y-1,bgbuffer[3]);
draw_pixel(x,y+1,bgbuffer[4]);
}
}
}
uint16_t blendColor(uint16_t bgpix, uint16_t forepix, float alpha) {
if ( alpha < 0 ) {
return bgpix;
}
if ( alpha > 1) {
return forepix;
}
uint8_t red, green, blue,forered,foregreen,foreblue,finalred,finalgreen,finalblue;
red = (bgpix & 0xf800) >> 11 << 3;
green = (bgpix & 0x7E0) >> 5 << 2;
blue = (bgpix & 0x1F) << 3;
forered = (forepix & 0xf800) >> 11 <<3;
foregreen = (forepix & 0x7E0) >> 5 <<2;
foreblue = (forepix & 0x1F) <<3 ;
finalred = (red * (1 - alpha) + (forered * alpha));
finalgreen = (green * (1 - alpha) + (foregreen * alpha));
finalblue = (blue * (1 - alpha) + (foreblue * alpha));
//return ((finalred / 8) << 11) | ((finalgreen / 4) << 5) | (finalblue / 8);
return (uint16_t)((finalred & 0xF8) << 8) | ((finalgreen & 0xFC) << 3) | (finalblue >> 3);
}
void plot4points_FAT(int16_t cx, int16_t cy, uint16_t x, uint16_t y, uint16_t color,uint8_t fat)
{
fill_circle(cx + x,cy + y,fat,color);
if (x != 0) fill_circle(cx - x,cy + y,fat,color);
if (y != 0) fill_circle(cx + x,cy - y,fat,color);
if (x != 0 && y != 0) fill_circle(cx - x,cy - y,fat,color);
}
void plot4points(int16_t cx, int16_t cy, uint16_t x, uint16_t y, uint16_t color)
{
draw_pixel(cx + x,cy + y,color);
if (x != 0) draw_pixel(cx - x,cy + y,color);
if (y != 0) draw_pixel(cx + x,cy - y,color);
if (x != 0 && y != 0) draw_pixel(cx - x,cy - y,color);
}
void drawHline(int16_t x, int16_t y, int16_t w, uint16_t color) {
do { draw_pixel(x+w-1,y,color); } while (--w > 0);
}
void drawVline(int16_t x, int16_t y, int16_t h, uint16_t color) {
do { draw_pixel(x,y+h-1,color); } while (--h > 0);
}
void drawHline_fat(int16_t x, int16_t y, int16_t w, uint16_t color, uint8_t thickness) {
do { fill_circle(x+w-1,y,thickness,color); } while (--w > 0);
}
void drawVline_fat(int16_t x, int16_t y, int16_t h, uint16_t color, uint8_t thickness) {
do { fill_circle(x,y+h-1, thickness,color); } while (--h > 0);
}
void drawHline_AA(int16_t x, int16_t y, int16_t w, uint16_t color, double AA) {
do { draw_pixel_AA(x+w-1,y,color,AA); } while (--w > 0);
}
void drawVline_AA(int16_t x, int16_t y, int16_t h, uint16_t color, double AA) {
do { draw_pixel_AA(x,y+h-1,color,AA); } while (--h > 0);
}
void plot4points_AA( int cx, int cy, int x, int y, uint16_t color, double alpha) {
draw_pixel(cx + x,cy + y,blendColor(get_pixel(cx + x,cy + y),color,alpha));
if (y != 0) draw_pixel_AA(cx + x,cy - y,color,alpha);
if (x != 0) draw_pixel_AA(cx - x,cy + y,color,alpha);
if (x != 0 && y != 0) draw_pixel_AA(cx - x,cy - y,color,alpha);
}
public:
void begin() {
delay(100);
Area.active_x1 = 0;
Area.active_y1 = 0;
Area.active_x2 = 128;
Area.active_y2 = 128;
s_width = 128;
s_height = 128;
tft.begin();
tft.clearScreen();
tft.setTextColor(WHITE);
tft.setTextSize(1);
// tft.setCursor(33, 0); //128/2=64 - 72/2=31 = 33
// tft.println("Pix-Watch.");
}
void sleepMode(bool enable) {
tft.sleepMode(enable);
}
void setPRINTColor(uint16_t col) {
Font.textcolor = col;
Font.textbgcolor = col;
}
void Cursor(uint8_t x, uint8_t y) {
if (x > 120|| y > 120) {}
else {
Font.cursor_x = x;
Font.cursor_y = y;
}
}
void SetActiveArea(int x,int y, int x1, int y1) {
if (!(x < 0 || x > s_width || y < 0 || y > s_height)) {
Area.active_x1 = x;
Area.active_x2 = x1;
Area.active_y1 = y;
Area.active_y2 = y1;
}
}
int get_x_offset() {
return Area.active_x1;
}
int get_y_offset() {
return Area.active_y1;
}
void draw_rect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color_) {
drawHline(x,y,w,color_);
}
void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color_) {
if (y0 == y1) {
if (x1 > x0) {
drawHline(x0, y0, x1 - x0 + 1, color_);
} else if (x1 < x0) {
drawHline(x0, y0, x0 - x1 + 1, color_);
} else {
draw_pixel(x0,y0,color_);
}
return;
} else if (x0 == x1) {
if (y1 > y0) {
drawVline(x0, y0, y1 - y0 + 1, color_);
} else {
drawVline(x0, y1, y0 - y1 + 1, color_);
}
return;
}
bool steep = abs(y1 - y0) > abs(x1 - x0);
if (steep) {swap(x0, y0); swap(x1, y1);}
if (x0 > x1) {swap(x0, x1); swap(y0, y1);}
int16_t dx, dy;
dx = x1 - x0;
dy = abs(y1 - y0);
int16_t err = dx / 2;
int16_t ystep;
if (y0 < y1) {
ystep = 1;
} else {
ystep = -1;
}
int16_t xbegin = x0;
if (steep) {
for (; x0<=x1; x0++) {
err -= dy;
if (err < 0) {
int16_t len = x0 - xbegin;
if (len) {
drawVline(y0, xbegin, len + 1, color_);
} else {
draw_pixel(y0,x0,color_);
}
xbegin = x0 + 1;
y0 += ystep;
err += dx;
}
}
if (x0 > xbegin + 1) { drawVline(y0, xbegin, x0 - xbegin, color_); }
} else {
for (; x0<=x1; x0++) {
err -= dy;
if (err < 0) {
int16_t len = x0 - xbegin;
if (len) {
drawHline(xbegin, y0, len + 1, color_);
} else {
draw_pixel(x0,y0,color_);
}
xbegin = x0 + 1;
y0 += ystep;
err += dx;
}
}
if (x0 > xbegin + 1) { drawHline(xbegin, y0, x0 - xbegin, color_); }
}
}
void drawLine_fat(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color_, uint8_t thickness) {
if (thickness < 1) {
drawLine(x0,y0,x1,y1,color_);
} else {
if (y0 == y1) {
if (x1 > x0) {
drawHline_fat(x0, y0, x1 - x0 + 1, color_, thickness);
} else if (x1 < x0) {
drawHline_fat(x0, y0, x0 - x1 + 1, color_, thickness);
} else {
fill_circle(x0,y0,thickness, color_);
}
return;
} else if (x0 == x1) {
if (y1 > y0) {
drawVline_fat(x0, y0, y1 - y0 + 1, color_, thickness);
} else {
drawVline_fat(x0, y1, y0 - y1 + 1, color_, thickness);
}
return;
}
bool steep = abs(y1 - y0) > abs(x1 - x0);
if (steep) {swap(x0, y0); swap(x1, y1);}
if (x0 > x1) {swap(x0, x1); swap(y0, y1);}
int16_t dx, dy;
dx = x1 - x0;
dy = abs(y1 - y0);
int16_t err = dx / 2;
int16_t ystep;
if (y0 < y1) {
ystep = 1;
} else {
ystep = -1;
}
int16_t xbegin = x0;
if (steep) {
for (; x0<=x1; x0++) {
err -= dy;
if (err < 0) {
int16_t len = x0 - xbegin;
if (len) {
drawVline_fat(y0, xbegin, len + 1, color_, thickness);
} else {
fill_circle(y0,x0,thickness, color_);
}
xbegin = x0 + 1;
y0 += ystep;
err += dx;
}
}
if (x0 > xbegin + 1) { drawVline_fat(y0, xbegin, x0 - xbegin, color_, thickness); }
} else {
for (; x0<=x1; x0++) {
err -= dy;
if (err < 0) {
int16_t len = x0 - xbegin;
if (len) {
drawHline_fat(xbegin, y0, len + 1, color_, thickness);
} else {
fill_circle(x0,y0,thickness, color_);
}
xbegin = x0 + 1;
y0 += ystep;
err += dx;
}
}
if (x0 > xbegin + 1) { drawHline_fat(xbegin, y0, x0 - xbegin, color_, thickness); }
}
}
}
void draw_circle(int cx, int cy , uint8_t i , uint16_t color) {
int error = -i;
int16_t x = i;
int16_t y = 0;
while (x >= y){
plot4points(cx, cy, x, y, color);
if (x != y) plot4points(cx, cy, y, x, color);
error += y;
++y;
error += y;
if (error >= 0){
--x;
error -= x;
error -= x;
}
}
}
void fill_circle(int16_t x0, int16_t y0 , uint8_t r , uint16_t color_, uint8_t cornername = 3) {
drawVline(x0, y0-r, 2*r+1, color_);
// Used to do circles and roundrects
int16_t f = 1 - r;
int16_t ddF_x = 1;
int16_t ddF_y = -2 * r;
int16_t x = 0;
int16_t y = r;
while (x<y) {
if (f >= 0) {
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
if (cornername & 0x1) {
drawVline(x0+x, y0-y, 2*y+1, color_);
drawVline(x0+y, y0-x, 2*x+1, color_);
}
if (cornername & 0x2) {
drawVline(x0-x, y0-y, 2*y+1, color_);
drawVline(x0-y, y0-x, 2*x+1, color_);
}
}
}
void draw_circle_fat(int16_t cx, int16_t cy , uint8_t i , uint16_t color, uint8_t fat) {
int error = -i;
int16_t x = i;
int16_t y = 0;
while (x >= y){
plot4points_FAT(cx, cy, x, y, color,fat);
if (x != y) plot4points_FAT(cx, cy, y, x, color,fat);
error += y;
++y;
error += y;
if (error >= 0){
--x;
error -= x;
error -= x;
}
}
}
void drawBitmap(int16_t x, int16_t y, int16_t w, int16_t h, const uint16_t *bitmap)
{
int16_t py =y;
int16_t xx =x;
for (int16_t px = 0;px < w*h; px++){//loop trough pixels
if (xx %(x+w) == 0) {
xx=x;
py++;
}
draw_pixel(xx,py,bitmap[px]);//16bit
xx++;
}
}
void fill_rect(int16_t x,int16_t y,int16_t w,int16_t h, uint16_t col) {
for (int yy=y; yy<h; yy++) {
for (int xx = x; xx < w; xx++) {
draw_pixel(xx,yy,col);
}
}
}
void draw_buffer() {
//blend_screen(0.08); //the magic to blend all pixels
tft.drawBuffer();
}
void set_buffer_bg(uint16_t color_) {
//tft.setbufferbg(((((color_ >> 16) & 0xFF) / 8) << 11) | ((((color_ >> 8) & 0xFF) / 4) << 5) | (((color_) & 0xFF) / 8));
tft.setbufferbg(color_);
}
void draw_pixel(int16_t x, int16_t y, uint16_t color) {
if (!(x < Area.active_x1 || x > Area.active_x2 || y < Area.active_y1 || y > Area.active_y2)) {
tft.buffer[x][y] = color;
}
}
uint16_t get_pixel(int16_t x, int16_t y) {
if (x < 0 || x > s_width) return 0x0000;
if (y < 0 || y > s_height) return 0x0000;
return tft.buffer[x][y];
}
void draw_roundrect_AA(int16_t x, int16_t y, int16_t width, int16_t height, int16_t rx, int16_t ry, boolean bordermode,uint16_t col) {
int16_t i;
int32_t a2, b2, ds, dt, dxt, t, s, d;
int16_t xp, yp, xs, ys, dyt, od, xx, yy, xc2, yc2;
float cp;
double sab;
double weight, iweight;
if ((rx < 0) || (ry < 0)) {
return;
}
if (rx == 0) {
drawVline(x, y - ry, y + ry,col);
return;
}
if (ry == 0) {
drawHline(x - rx, y, x + rx,col);
return;
}
a2 = rx * rx;
b2 = ry * ry;
ds = a2 << 1;
dt = b2 << 1;
xc2 = x << 1;
yc2 = y << 1;
sab = sqrt((double)(a2 + b2));
od = (int)round(sab*0.01) + 1;
dxt = (int)round((double)a2 / sab) + od;
t = 0;
s = -2 * a2 * ry;
d = 0;
xp = x + rx;
yp = y;
drawHline(x + rx, y, width - rx-rx+1,col);
drawHline(x + rx, y + height, width - rx-rx+1,col);
drawVline(x + width, y + ry, height-ry-ry+1,col);
drawVline(x, y + ry, height-ry-ry+1,col);
for (i = 1; i <= dxt; i++) {
xp--;
d += t - b2;
if (d >= 0) {
ys = yp - 1;
} else if ((d - s - a2) > 0) {
if (((d << 1) - s - a2) >= 0) {
ys = yp + 1;
} else {
ys = yp;
yp++;
d -= s + a2;
s += ds;
}
} else {
yp++;
ys = yp + 1;
d -= s + a2;
s += ds;
}
t -= dt;
if (s != 0) {
cp = (float) abs(d) / (float) abs(s);
if (cp > 1.0) {
cp = 1.0f;
}
} else {
cp = 1.0f;
}
weight = cp;
iweight = 1 - weight;
if( bordermode ) {
iweight = yp > ys ? 1 : iweight;
weight = ys > yp ? 1 : weight;
}
/* Upper half */
xx = xc2 - xp;
draw_pixel(xp,yp, blendColor(get_pixel(xp,yp),col,iweight));
draw_pixel(xx+width, yp, blendColor(get_pixel(xx+width,yp),col,iweight));
draw_pixel(xp,ys, blendColor(get_pixel(xp,ys),col,weight));
draw_pixel(xx+width, ys, blendColor(get_pixel(xx+width,ys),col,weight));
/* Lower half */
yy = yc2 - yp;
draw_pixel(xp, yy+height, blendColor(get_pixel(xp, yy+height),col,iweight));
draw_pixel(xx+width,yy+height, blendColor(get_pixel(xx+width, yy+height),col,iweight));
yy = yc2 - ys;
draw_pixel(xp, yy+height, blendColor(get_pixel(xp, yy+height),col,weight));
draw_pixel(xx+width, yy+height, blendColor(get_pixel(xx+width, yy+height),col,weight));
}
dyt = (int)round((double)b2 / sab ) + od;
for (i = 1; i <= dyt; i++) {
yp++;
d -= s + a2;
if (d <= 0) {
xs = xp + 1;
} else if ((d + t - b2) < 0) {
if (((d << 1) + t - b2) <= 0) {
xs = xp - 1;
} else {
xs = xp;
xp--;
d += t - b2;
t -= dt;
}
} else {
xp--;
xs = xp - 1;
d += t - b2;
t -= dt;
}
s += ds;
if (t != 0) {
cp = (float) abs(d) / (float) abs(t);
if (cp > 1.0) {
cp = 1.0f;
}
} else {
cp = 1.0f;
}
weight = cp;
iweight = 1 - weight;
/* Left half */
xx = xc2 - xp;
yy = yc2 - yp;
draw_pixel(xp,yp, blendColor(get_pixel(xp,yp),col,iweight));
draw_pixel(xx+width,yp, blendColor(get_pixel(xx+width,yp),col,iweight));
draw_pixel(xp, yy+height, blendColor(get_pixel(xp,yy+height),col,iweight));
draw_pixel(xx+width,yy+height, blendColor(get_pixel(xx+width,yy+height),col,iweight));
/* Right half */
xx = xc2 - xs;
draw_pixel(xs,yp, blendColor(get_pixel(xs,yp),col,weight));
draw_pixel(xx+width, yp, blendColor(get_pixel(xx+width,yp),col,weight));
draw_pixel(xs, yy+height, blendColor(get_pixel(xs,yy+height),col,weight));
draw_pixel(xx+width, yy+height, blendColor(get_pixel(xx+width,yy+height),col,weight));
}
}
void fill_circle_blend(int16_t x0, int16_t y0 , uint8_t r , uint16_t color_, double alpha) {
drawVline_AA(x0, y0-r, 2*r+1, color_, alpha);
// Used to do circles and roundrects
int16_t f = 1 - r;
int16_t ddF_x = 1;
int16_t ddF_y = -2 * r;
int16_t x = 0;
int16_t y = r;
int16_t oldy = r;
for (int8_t offset = x0; offset < x0+r; offset++) {
if (f >= 0) {
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
if (x<=y) {
if (x != y) {
drawVline_AA(x0+x, y0-y, 2*y+1, color_, alpha);
drawVline_AA(x0-x, y0-y, 2*y+1, color_, alpha);
}
if (oldy != y){
drawVline_AA(x0+y, y0-x, 2*x+1, color_, alpha);
drawVline_AA(x0-y, y0-x, 2*x+1, color_, alpha);
oldy = y;
}
}
}
}
void fill_rect_AA(int x,int y,int w,int h, uint16_t col, double alpha, bool depth) {
for (int yy=y; yy<h; yy++) {
for (int xx = x; xx < w; xx++) {
if (depth == 0) {
draw_pixel(xx,yy,blendColor(get_pixel(xx,yy),col,alpha));
} else {
if ((xx == x) || (xx == w) || (yy == y) || (yy == h)) {
draw_pixel(xx,yy,blendColor(get_pixel(xx,yy),col,alpha));
} else {
draw_pixel(xx,yy,col);
}
}
}
}
}
void draw_circle_AA(int16_t x, int16_t y, int16_t radius, boolean bordermode,uint16_t col) {
draw_roundrect_AA(x-radius, y-radius, radius<<1, radius<<1, radius, radius, bordermode,col);
}
void draw_circle_blend(uint8_t cx, uint8_t cy , uint8_t i , uint32_t color, double alpha) {
int error = -i;
int16_t x = i;
int16_t y = 0;
while (x >= y){
plot4points_AA(cx, cy, x, y, color, alpha);
if (x != y) plot4points_AA(cx, cy, y, x, color, alpha);
error += y;
++y;
error += y;
if (error >= 0){
--x;
error -= x;
error -= x;
}
}
}
void draw_pixel_AA(int x,int y, uint16_t color, double a) {
if (x < 0 || x > s_width || y < 0 || y > s_height) {}
else {
tft.buffer[x][y] = blendColor(get_pixel(x,y),color,a);
//put_aa_pixel(x,y,color,a);
}
}
void drawPieEnd_AA(int16_t x, int16_t y, int16_t r, int16_t rs, int16_t re,uint16_t color,float a) {
int16_t cx, cy, d;
rs -= 90;
re -= 90;
if (rs>re) rs -= 360;
for (d=rs+1; d<re+1; d++){
cx = x + cos((d*3.14)/180) * r;
cy = y + sin((d*3.14)/180) * r;
draw_pixel_AA(cx, cy,color,a);
}
}
void drawPieEnd(int16_t x, int16_t y, int16_t r, int16_t rs, int16_t re,uint16_t color,uint8_t size) {
int16_t cx, cy, d;
rs -= 90;
re -= 90;
if (rs>re) rs -= 360;
for (d=rs+1; d<re+1; d++){
cx = x + cos((d*3.14)/180) * r;
cy = y + sin((d*3.14)/180) * r;
fill_circle(cx, cy,size,color);
}
}
};
Hi,
I remember that there were problems with the 3.5. Something with SPI/DMA/Scatter-Gather is not compatible with the 3.6. But there might be a way to bring it to work with the 3.5, too.
16, ILI9341_GMCTRN1, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07,
0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F, // Set Gamma
3, 0xb1, 0x00, 0x10, // FrameRate Control 119Hz
[COLOR=#00ff00][B] 2, ILI9341_MADCTL, MADCTL_MV | MADCTL_BGR, //rotate //ADD THIS LINE[/B][/COLOR]
0
};
Thanks, i have it pretty much working - faster than the original C64, including sound+graphics (currently 2x the speed, but i still have to add some things). I hope i can publish it in march or april.
In the extras folder of the download is a processing sketch that does converts a video to raw 565 + sound.
Your video looks amazing !