Doug Domke
Published © GPL3+

Wio Paint

This "software only" project does a nice job of showing what the Seeed Wio Terminal can do. A small screen but a functional paint program.

IntermediateFull instructions provided4 hours52
Wio Paint

Things used in this project

Hardware components

Wio Terminal
Seeed Studio Wio Terminal
×1
Wio Terminal Chassis - Battery (650mAh)
Seeed Studio Wio Terminal Chassis - Battery (650mAh)
Optional
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Code

Wio Paint

Arduino
Source code for Wio Paint program
#include "SPI.h"
#include "TFT_eSPI.h"

TFT_eSPI screen = TFT_eSPI();  // TFT graphic object instance

#define TFT_AQUA 0x07FF  // add these colors to stardard palatte 
#define TFT_DARK_ORANGE 0xFC60
#define TFT_BROWN 0xA145
#define TFT_GREY 0xAD55

const uint16_t colors[11] = {TFT_RED, TFT_DARK_ORANGE, TFT_YELLOW, TFT_GREEN,
                       TFT_AQUA, TFT_BLUE, TFT_MAGENTA, TFT_BROWN,
                       TFT_GREY, TFT_WHITE, TFT_BLACK
                      };
// global variables                      
uint16_t myColor = TFT_RED;
int colorChoice = 0;  // index of selected color
int cursorX = 27, cursorY = 1;  // current location of the cursor
int myX, myY;  // previous location of cursor
uint16_t underCursor[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; // for current cursor
uint16_t underCursor2[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};  // for previous cursor
uint16_t myScreen[320][240] = {0}; // used for "undo" only
long myTime; // used with millis() to blink the cursor
int cursorStatus = 0;  // controls preserving screen content under the cursor
int myFunction = 8;  // index of selected function
int widthCount = 3;  // index of selected line width
bool buttonEnable = true;  // are buttons active?
bool pointSet = false;  // has the first cursor position been set?
int xx1,xx2,yy1,yy2; // creates the area to store for the "undo" function
int xMin, yMin, xLen, yLen;  // used to properly configure rectangles and squares

void setup() {
  Serial.begin(9600);
  // enable the buttons
  pinMode(WIO_5S_UP, INPUT_PULLUP);
  pinMode(WIO_5S_DOWN, INPUT_PULLUP);
  pinMode(WIO_5S_LEFT, INPUT_PULLUP);
  pinMode(WIO_5S_RIGHT, INPUT_PULLUP);
  pinMode(WIO_5S_PRESS, INPUT_PULLUP);
  pinMode(WIO_KEY_A, INPUT_PULLUP);
  pinMode(WIO_KEY_B, INPUT_PULLUP);
  pinMode(WIO_KEY_C, INPUT_PULLUP);
  screen.init();
  screen.setRotation(3);
  initialize();  // clear the screen and set up menus
}  // end of setup

// Main loop does two things: blink the cursor and monitor the buttons
void loop() {
  if (cursorStatus == 0 ) {
    saveUnderCursor(cursorX, cursorY);
    cursorStatus = 1;
    if (myColor == TFT_BLACK) screen.fillRect(cursorX - 1, cursorY - 1, 3, 3, TFT_WHITE);
    else screen.fillRect(cursorX - 1, cursorY - 1, 3, 3, myColor);
  }
  if (millis() > myTime + 499 && cursorStatus == 1) {
    displayUnderCursor(cursorX, cursorY);
    cursorStatus = 2;
  }
  if (millis() > myTime + 999) {
    myTime = millis();
    cursorStatus = 0;
  }

  if (buttonEnable = true && digitalRead(WIO_5S_UP) == LOW) {
    buttonEnable = false;
    if (cursorY > 1) moveCursor(cursorX, cursorY - 1);
    delay(250);
    while (digitalRead(WIO_5S_UP) == LOW) {
      if (cursorY > 1) moveCursor(cursorX, cursorY - 1);
    }
  }
  else if (buttonEnable = true && digitalRead(WIO_5S_DOWN) == LOW) {
    buttonEnable = false;
    if (cursorY < 236)moveCursor(cursorX, cursorY + 1);
    delay(250);
    while (digitalRead(WIO_5S_DOWN) == LOW) {
      if (cursorY < 236)moveCursor(cursorX, cursorY + 1);
    }
  }
  else if (buttonEnable = true && digitalRead(WIO_5S_LEFT) == LOW) {
    buttonEnable = false;
    if (cursorX > 27)moveCursor(cursorX - 1, cursorY);
    delay(250);
    while (digitalRead(WIO_5S_LEFT) == LOW) {
      if (cursorX > 27)moveCursor(cursorX - 1, cursorY);
    }

  }
  else if (buttonEnable = true && digitalRead(WIO_5S_RIGHT) == LOW) {
    buttonEnable = false;
    if (cursorX < 286)moveCursor(cursorX + 1, cursorY);
    delay(250);
    while (digitalRead(WIO_5S_RIGHT) == LOW) {
      if (cursorX < 286)moveCursor(cursorX + 1, cursorY);
    }
  }
  // PRESS FUNCTION
  else if (buttonEnable = true && digitalRead(WIO_5S_PRESS) == LOW) {
    buttonEnable = false;
    if (myFunction == 0) draw_Dot();
    else if (myFunction == 1) draw_Line();
    else if (myFunction == 2) draw_Square();
    else if (myFunction == 3) fill_Square();
    else if (myFunction == 4) draw_Rectangle();
    else if (myFunction == 5) fill_Rectangle();
    else if (myFunction == 6) draw_Circle();
    else if (myFunction == 7) fill_Circle();
    else if (myFunction == 8) initialize();

    while (digitalRead(WIO_5S_PRESS) == LOW) {}
  }
  else if (buttonEnable = true && digitalRead(WIO_KEY_C) == LOW) { // select color
    buttonEnable = false;
    delay(250);
    if (digitalRead(WIO_KEY_A) == LOW) {
      retrieveScreen(xx1,yy1,xx2,yy2);  // Undo function when buttons A and C are both pushed
    }
    else advanceColor();
    while (digitalRead(WIO_KEY_C) == LOW) {}
  }
  else if (buttonEnable = true && digitalRead(WIO_KEY_B) == LOW) { // select color
    buttonEnable = false;
    advanceFunction();
    while (digitalRead(WIO_KEY_B) == LOW) {}
  }
  else if (buttonEnable = true && digitalRead(WIO_KEY_A) == LOW) {
    buttonEnable = false;
    delay(250);
    if (digitalRead(WIO_KEY_C) == LOW) {
      retrieveScreen(xx1,yy1,xx2,yy2);   // Undo function when buttons A and C are both pushed
    }
    else advanceLineWidth();
    while (digitalRead(WIO_KEY_A) == LOW) {}
  }
  buttonEnable = true;
} // end of loop

// set up color palette
void colorMenu() {
  screen.fillRect(0, 1, 18, 18, TFT_RED);
  screen.fillRect(0, 21, 18, 18, TFT_DARK_ORANGE);
  screen.fillRect(0, 41, 18, 18, TFT_YELLOW);
  screen.fillRect(0, 61, 18, 18, TFT_GREEN);
  screen.fillRect(0, 81, 18, 18, TFT_AQUA);
  screen.fillRect(0, 101, 18, 18, TFT_BLUE);
  screen.fillRect(0, 121, 18, 18, TFT_MAGENTA);
  screen.fillRect(0, 141, 18, 18, TFT_BROWN);
  screen.fillRect(0, 161, 18, 18, TFT_GREY);
  screen.fillRect(0, 181, 18, 18, TFT_WHITE);
  screen.drawRect(0, 201, 18, 18, TFT_WHITE);
}

void advanceColor() {
  screen.fillRect(20, colorChoice * 20 + 1, 4, 18, TFT_WHITE);
  if (colorChoice > 0) screen.fillRect(20, colorChoice * 20 - 19, 4, 18, TFT_BLACK);
  else screen.fillRect(20, 201, 4, 18, TFT_BLACK);
  myColor = colors[colorChoice];
  colorChoice ++;
  if (colorChoice > 10) colorChoice = 0;
}

//set up the function menu
void functionMenu() {
  screen.drawRect(298, 1, 20, 20, TFT_WHITE);
  screen.drawRect(300, 3, 16, 16, TFT_BLACK);
  screen.fillRect(306, 10, 2, 2, TFT_YELLOW); // point
  screen.drawRect(298, 21, 20, 20, TFT_WHITE);
  screen.drawRect(300, 23, 16, 16, TFT_BLACK);
  screen.fillRect(302, 30, 12, 2, TFT_YELLOW); // line
  screen.drawRect(298, 41, 20, 20, TFT_WHITE);
  screen.drawRect(300, 43, 16, 16, TFT_BLACK);
  screen.drawRect(305, 48, 6, 6, TFT_YELLOW); // draw square
  screen.drawRect(298, 61, 20, 20, TFT_WHITE);
  screen.drawRect(300, 63, 16, 16, TFT_BLACK);
  screen.fillRect(305, 68, 6, 6, TFT_YELLOW); // fill square
  screen.drawRect(298, 81, 20, 20, TFT_WHITE);
  screen.drawRect(300, 83, 16, 16, TFT_BLACK);
  screen.drawRect(302, 88, 12, 6, TFT_YELLOW); // draw rectangle
  screen.drawRect(298, 101, 20, 20, TFT_WHITE);
  screen.drawRect(300, 103, 16, 16, TFT_BLACK);
  screen.fillRect(302, 108, 12, 6, TFT_YELLOW); // fill rectangle
  screen.drawRect(298, 121, 20, 20, TFT_WHITE);
  screen.drawRect(300, 123, 16, 16, TFT_BLACK);
  screen.drawCircle(308, 130, 5, TFT_YELLOW); // draw circle
  screen.drawRect(298, 141, 20, 20, TFT_WHITE);
  screen.drawRect(300, 143, 16, 16, TFT_BLACK);
  screen.fillCircle(308, 150, 5, TFT_YELLOW); // fill circle
  screen.drawRect(298, 161, 20, 20, TFT_WHITE);
  screen.fillRect(300, 163, 16, 16, TFT_MAGENTA);
}

void advanceFunction() {
  myFunction ++;
  if (myFunction > 8) myFunction = 0;
  screen.fillRect(292, myFunction * 20 + 1, 4, 18, TFT_WHITE);
  if (myFunction > 0) screen.fillRect(292, myFunction * 20 - 19, 4, 18, TFT_BLACK);
  else screen.fillRect(292, 161, 4, 18, TFT_BLACK);
  pointSet = false;
}

//set up the line width menu
void lineWidthMenu() {
  screen.drawRect(298, 191, 20, 30, TFT_WHITE);
  screen.fillRect(300, 193, 16, 26, TFT_BLACK);
  screen.drawLine(308, 195, 308, 217, TFT_YELLOW);
}

void advanceLineWidth() {
  widthCount ++;
  if (widthCount > 3) widthCount = 0;
  if (widthCount == 0) screen.fillRect(300, 193, 16, 26, TFT_BLACK);
  screen.fillRect(308 - widthCount, 195, widthCount * 2 + 1, 22, TFT_YELLOW);
}

// moves the cursor to a new position, restoring content under the cursor in its old position
void moveCursor(int curX, int curY) {
  displayUnderCursor(cursorX, cursorY);  // put content under the cursor on the display
  saveUnderCursor(curX, curY);  // save the content on the display in the new cursor position
  cursorX = curX; cursorY = curY; // set cursor to its new position
  // show the cursor in its new position for 25 msec.
  if (myColor == TFT_BLACK) screen.fillRect(cursorX - 1, cursorY - 1, 3, 3, TFT_WHITE);
  else screen.fillRect(cursorX - 1, cursorY - 1, 3, 3, myColor);
  delay(25);
  // then put the content under the cursor back on the display
  displayUnderCursor(cursorX, cursorY);
}

// stores a portion of the screen content in support of UNDO
void saveScreen(int xx3, int yy3, int xx4, int yy4) {
  displayUnderCursor(cursorX, cursorY);
  for (int x = xx3; x < xx4+1; x++) {
    for (int y = yy3; y < yy4+1; y++) {
      myScreen[x][y] = screen.readPixel(x, y);
    }
  }
}

// retrieves a previously saved postion of the screen in support of UNDO
void retrieveScreen(int xx3, int yy3, int xx4, int yy4) {
  for (int x = xx3; x < xx4+1; x++) {
    for (int y = yy3; y < yy4+1; y++) {
      screen.drawPixel(x, y, myScreen[x][y]);
    }
  }
}

// fresh start - clear the entire screen, set up all the menus, initiallize key variables
void initialize() {
  screen.fillScreen(TFT_BLACK);
  myColor = TFT_RED;
  cursorStatus = 0;
  colorChoice = 0;
  myFunction = 8;
  widthCount = 0;
  myTime = millis();
  colorMenu();
  advanceColor();
  functionMenu();
  advanceFunction();
  lineWidthMenu();
  advanceLineWidth();
  cursorX = 27; cursorY = 1;
  pointSet = false;
}

// for most graphics, two points are needed - this setup up the first point
// it marks that position, but first save the content under the cursor.
void setFirstPoint() {
  myX = cursorX;
  myY = cursorY; 
  displayUnderCursor(cursorX, cursorY);
  saveUnderCursor2(cursorX, cursorY);
  screen.fillRect(cursorX-1, cursorY-1, 3, 3, myColor);
  cursorX += 6;
  pointSet = true;
}

// draws a dot, the size of which is determined by line width setting
void draw_Dot() {
  xx1 = cursorX-3; yy1= cursorY-3;  xx2 = cursorX+3; yy2= cursorY+3;
  saveScreen(xx1,yy1,xx2,yy2);  // save for undo
  displayUnderCursor(cursorX - 1, cursorY - 1);
  if (widthCount > 2) screen.fillRect(cursorX - 3, cursorY - 3, 7, 7, myColor);
  else if (widthCount > 1) screen.fillRect(cursorX - 2, cursorY - 2, 5, 5, myColor);
  else if (widthCount > 0) screen.fillRect(cursorX - 1, cursorY - 1, 3, 3, myColor);
  else screen.drawPixel(cursorX, cursorY, myColor);
  saveUnderCursor(cursorX, cursorY);
}

// draws a line, the width of which is approximately determined by the line width setting
void draw_Line() {
  if (pointSet == false) {
    setFirstPoint();
    return;
  }
  else {
    displayUnderCursor2(myX, myY);
    displayUnderCursor(cursorX, cursorY);
    xx1 = myX; yy1 = myY;  
    xx2 = cursorX; yy2 = cursorY;
    // for undo function, we need to get boundries in proper order
    // xx1 must be less than xx2, yy1 must be less that yy2
    // and they must take line width into account
    if (xx2 < xx1) {
      int temp = xx2;
      xx2 = xx1;
      xx1 = temp;    
    }
    if (yy2 < yy1) {
      int temp = yy2;
      yy2 = yy1;
      yy1 = temp;    
    }
    xx1 -= 4 ; yy1 -= 4; xx2 += 4; yy2 += 4;
    saveScreen(xx1,yy1,xx2,yy2);  // save for undo
    screen.drawLine(myX, myY, cursorX, cursorY, myColor);
    float slope = (float)abs(myY - cursorY) / (float)abs(myX - cursorX);
    if (widthCount > 0) {
      if (slope > 0.5) {
        screen.drawLine(myX - 1, myY, cursorX - 1, cursorY, myColor);
        screen.drawLine(myX + 1, myY, cursorX + 1, cursorY, myColor);
      }
      if (slope < 2) {
        screen.drawLine(myX, myY - 1, cursorX, cursorY - 1, myColor);
        screen.drawLine(myX, myY + 1, cursorX, cursorY + 1, myColor);
      }
    }
    if (widthCount > 1) {
      if (slope > 0.5) {
        screen.drawLine(myX - 2, myY, cursorX - 2, cursorY, myColor);
        screen.drawLine(myX + 2, myY, cursorX + 2, cursorY, myColor);
      }
      if (slope < 2) {
        screen.drawLine(myX, myY - 2, cursorX, cursorY - 2, myColor);
        screen.drawLine(myX, myY + 2, cursorX, cursorY + 2, myColor);
      }
    }
    if (widthCount > 2) {
      if (slope > 0.5) {
        screen.drawLine(myX - 3, myY, cursorX - 3, cursorY, myColor);
        screen.drawLine(myX + 3, myY, cursorX + 3, cursorY, myColor);
      }
      if (slope < 2) {
        screen.drawLine(myX, myY - 3, cursorX, cursorY - 3, myColor);
        screen.drawLine(myX, myY + 3, cursorX, cursorY + 3, myColor);
      }
    }
    pointSet = false;
    saveUnderCursor(cursorX, cursorY);
  }
}

// find the minX, minY, xLen,and yLen of a square given any two opposite corners
// cleans up the dimensions of a square, regardless of how user defined it.
void fixXYsqr(int myX1, int myY1, int cursorX1, int cursorY1){
  int sqrSize = abs(myX1 - cursorX1);
  if (abs(myY1 - cursorY1) < sqrSize) sqrSize = abs(myY1 - cursorY1);
  if (myX1 < cursorX1) xMin = myX1; 
  else xMin = myX1-sqrSize;
  xLen = sqrSize; 
  if (myY1 < cursorY1) yMin = myY1; 
  else yMin = myY1-sqrSize;
  yLen = sqrSize; 
}

//  draw the outline of a square with line width set by line width menu
void draw_Square() {
  if (pointSet == false) {
    setFirstPoint();
    return;
  }
  else {
    displayUnderCursor2(myX, myY);
    displayUnderCursor(cursorX, cursorY);
    fixXYsqr(myX, myY, cursorX, cursorY);
    int sqrSize = abs(myX - cursorX);
    if (abs(myY - cursorY) < sqrSize) sqrSize = abs(myY - cursorY);
    xx1 = xMin-3; yy1 = yMin-3; xx2 = xMin+sqrSize+3; yy2 = yMin+sqrSize+3;
    saveScreen(xx1,yy1,xx2,yy2);  // save for Undo
    screen.drawRect(xMin, yMin, sqrSize, sqrSize, myColor);
    if (widthCount > 0) {
      screen.drawRect(xMin - 1, yMin - 1, sqrSize + 2, sqrSize + 2, myColor);
      screen.drawRect(xMin + 1, yMin + 1, sqrSize - 2, sqrSize - 2, myColor);
    }
    if (widthCount > 1) {
      screen.drawRect(xMin - 2, yMin - 2, sqrSize + 4, sqrSize + 4, myColor);
      screen.drawRect(xMin + 2, yMin + 2, sqrSize - 4, sqrSize - 4, myColor);
    }
    if (widthCount > 2) {
      screen.drawRect(xMin - 3, yMin - 3,  sqrSize + 6, sqrSize + 6, myColor);
      screen.drawRect(xMin + 3, yMin + 3, sqrSize - 6, sqrSize - 6, myColor);
    }
    pointSet = false;
    saveUnderCursor(cursorX, cursorY);
  }
}

// draw a filled in square
void fill_Square() {
  if (pointSet == false) {
    setFirstPoint();
    return;
  }
  else {
    displayUnderCursor2(myX, myY);
    displayUnderCursor(cursorX, cursorY);
    fixXYsqr(myX, myY, cursorX, cursorY);
    int sqrSize = abs(myX - cursorX);
    if (abs(myY - cursorY) < sqrSize) sqrSize = abs(myY - cursorY);
    xx1 = xMin; yy1 = yMin; xx2 = xMin+sqrSize; yy2 = yMin+sqrSize;
    saveScreen(xx1,yy1,xx2,yy2);
    screen.fillRect(xMin, yMin, sqrSize, sqrSize, myColor);
    pointSet = false;
    saveUnderCursor(cursorX, cursorY);
  }
}

// find the minX, minY, xLen,and yLen of a rectangle given any two opposite corners
// cleans up the dimensions of a rectangle, regardless of how user defined it.
void fixXYrect(int myX1, int myY1, int cursorX1, int cursorY1){
  if (myX1 < cursorX1) xMin = myX1; 
  else xMin = cursorX1;
  xLen = abs(cursorX1-myX1); 
  if (myY1 < cursorY1) yMin = myY1; 
  else yMin = cursorY1;
  yLen = abs(cursorY1-myY1); 
}

//  draw the outline of a rectangle with line width set by line width menu
void draw_Rectangle() {
  if (pointSet == false) {
    setFirstPoint();
    return;
  }
  else {
    displayUnderCursor2(myX, myY);
    displayUnderCursor(cursorX, cursorY);
    fixXYrect(myX, myY, cursorX, cursorY);
    xx1 = xMin-3; yy1 = yMin-3; xx2 = xMin+xLen+3; yy2 = yMin+yLen+3;
    saveScreen(xx1,yy1,xx2,yy2);
    screen.drawRect(xMin, yMin, xLen, yLen, myColor);
    if (widthCount > 0) {
      screen.drawRect(xMin - 1, yMin - 1, xLen + 2, yLen + 2, myColor);
      screen.drawRect(xMin + 1, yMin + 1, xLen - 2, yLen - 2, myColor);
    }
    if (widthCount > 1) {
      screen.drawRect(xMin - 2, yMin - 2, xLen + 4, yLen + 4, myColor);
      screen.drawRect(xMin + 2, yMin + 2, xLen - 4, yLen - 4, myColor);
    }
    if (widthCount > 2) {
      screen.drawRect(xMin - 3, yMin - 3, xLen + 6, yLen + 6, myColor);
      screen.drawRect(xMin + 3, yMin + 3, xLen - 6, yLen - 6, myColor);
    }
    pointSet = false;
    saveUnderCursor(cursorX, cursorY);
  }
}

// draw a filled in rectangle
void fill_Rectangle() {
  if (pointSet == false) {
    setFirstPoint();
    return;
  }
  else {
    displayUnderCursor2(myX - 1, myY - 1);
    displayUnderCursor(cursorX, cursorY);
    fixXYrect(myX, myY, cursorX, cursorY);
    xx1 = xMin; yy1 = yMin; xx2 = xMin+xLen; yy2 = yMin+yLen;
    saveScreen(xx1,yy1,xx2,yy2);  // save for undo
    screen.fillRect(xMin, yMin, xLen, yLen, myColor);
    pointSet = false;
    saveUnderCursor(cursorX, cursorY);
  }
}

//  draw the outline of a circle with line width set by line width menu
void draw_Circle() {
  if (pointSet == false) {
    setFirstPoint();
    return;
  }
  else {
    displayUnderCursor2(myX, myY);
    displayUnderCursor(cursorX, cursorY);
    int myRadius = sqrt(((cursorX - myX) * (cursorX - myX)) + 
                   ((cursorY - myY) * (cursorY - myY)));
    xx1 = myX - myRadius - 3; yy1 = myY - myRadius - 3;  
    xx2 = myX + myRadius + 3; yy2 = myY + myRadius + 3;
    saveScreen(xx1,yy1,xx2,yy2); // save for undo
    screen.drawCircle(myX, myY, myRadius, myColor);
    if (widthCount > 0) {
      screen.drawCircle(myX, myY, myRadius - 1, myColor);
      screen.drawCircle(myX, myY, myRadius + 1, myColor);
    }
    if (widthCount > 1) {
      screen.drawCircle(myX, myY, myRadius - 2, myColor);
      screen.drawCircle(myX, myY, myRadius + 2, myColor);
    }
    if (widthCount > 2) {
      screen.drawCircle(myX, myY, myRadius - 3, myColor);
      screen.drawCircle(myX, myY, myRadius + 3, myColor);
    }
    pointSet = false;
    saveUnderCursor(cursorX, cursorY);
  }
}

// draw a filled in circle
void fill_Circle() {
  if (pointSet == false) {
    setFirstPoint();
    return;
  }
  else {
    displayUnderCursor2(myX, myY);
    displayUnderCursor(cursorX, cursorY);
    int myRadius = sqrt(((cursorX - myX) * (cursorX - myX)) + 
                   ((cursorY - myY) * (cursorY - myY)));
    xx1 = myX - myRadius; yy1 = myY - myRadius;  
    xx2 = myX + myRadius; yy2 = myY + myRadius;
    saveScreen(xx1,yy1,xx2,yy2); // save for undo
    screen.fillCircle(myX, myY, myRadius, myColor);
    pointSet = false;
    saveUnderCursor(cursorX, cursorY);
  }
}

// put saved content under the cursor back onto the display
void displayUnderCursor(int curX, int curY) {
  // restore old content from under the cursor
  screen.drawPixel(curX - 1, curY - 1, underCursor[0][0]);
  screen.drawPixel(curX,   curY - 1, underCursor[1][0]);
  screen.drawPixel(curX + 1, curY - 1, underCursor[2][0]);
  screen.drawPixel(curX - 1, curY  , underCursor[0][1]);
  screen.drawPixel(curX  , curY  , underCursor[1][1]);
  screen.drawPixel(curX + 1, curY  , underCursor[2][1]);
  screen.drawPixel(curX - 1, curY + 1, underCursor[0][2]);
  screen.drawPixel(curX  , curY + 1, underCursor[1][2]);
  screen.drawPixel(curX + 1, curY + 1, underCursor[2][2]);
}

// save the content under the cursor before displaying cursor
void saveUnderCursor(int curX, int curY) {
  // save new content under the cursor
  underCursor[0][0] = screen.readPixel(curX - 1, curY - 1);
  underCursor[1][0] = screen.readPixel(curX  , curY - 1);
  underCursor[2][0] = screen.readPixel(curX + 1, curY - 1);
  underCursor[0][1] = screen.readPixel(curX - 1, curY  );
  underCursor[1][1] = screen.readPixel(curX  , curY  );
  underCursor[2][1] = screen.readPixel(curX + 1, curY  );
  underCursor[0][2] = screen.readPixel(curX - 1, curY + 1);
  underCursor[1][2] = screen.readPixel(curX  , curY + 1);
  underCursor[2][2] = screen.readPixel(curX + 1, curY + 1);
}

// display content that was under the first point marked for a new graphic
void displayUnderCursor2(int curX, int curY) {
  // restore old content from under the cursor
  screen.drawPixel(curX - 1, curY - 1, underCursor2[0][0]);
  screen.drawPixel(curX,   curY - 1, underCursor2[1][0]);
  screen.drawPixel(curX + 1, curY - 1, underCursor2[2][0]);
  screen.drawPixel(curX - 1, curY  , underCursor2[0][1]);
  screen.drawPixel(curX  , curY  , underCursor2[1][1]);
  screen.drawPixel(curX + 1, curY  , underCursor2[2][1]);
  screen.drawPixel(curX - 1, curY + 1, underCursor2[0][2]);
  screen.drawPixel(curX  , curY + 1, underCursor2[1][2]);
  screen.drawPixel(curX + 1, curY + 1, underCursor2[2][2]);
}

// save the screen content under the cursor before marking first point for a new graphic
void saveUnderCursor2(int curX, int curY) {
  // save new content under the cursor
  underCursor2[0][0] = screen.readPixel(curX - 1, curY - 1);
  underCursor2[1][0] = screen.readPixel(curX  , curY - 1);
  underCursor2[2][0] = screen.readPixel(curX + 1, curY - 1);
  underCursor2[0][1] = screen.readPixel(curX - 1, curY  );
  underCursor2[1][1] = screen.readPixel(curX  , curY  );
  underCursor2[2][1] = screen.readPixel(curX + 1, curY  );
  underCursor2[0][2] = screen.readPixel(curX - 1, curY + 1);
  underCursor2[1][2] = screen.readPixel(curX  , curY + 1);
  underCursor2[2][2] = screen.readPixel(curX + 1, curY + 1);
}

Credits

Doug Domke

Doug Domke

28 projects • 100 followers

Comments