Skip to content

Instantly share code, notes, and snippets.

@palaniraja
Last active June 29, 2025 01:30
Show Gist options
  • Save palaniraja/d5a55f9bd1f990410c8a0099844cec91 to your computer and use it in GitHub Desktop.
Save palaniraja/d5a55f9bd1f990410c8a0099844cec91 to your computer and use it in GitHub Desktop.
vibecoding Sudoku for M5PaperS3 with static puzzle
#include <M5GFX.h>
M5GFX display;
// Battery percentage tracking
int last_battery_percent = -1;
unsigned long last_battery_check = 0;
// E-ink friendly colors
#define COLOR_BG TFT_WHITE
#define COLOR_GRID 0xC618 // light gray (RGB565: 19818)
#define COLOR_BOLD TFT_BLACK
#define COLOR_NUM TFT_BLACK
#define COLOR_SEL 0x7BEF // lighter gray (RGB565: 31727)
#define COLOR_FIXED_BG 0x8410 // 50% black (mid-gray RGB565)
#define COLOR_FIXED_FG TFT_BLACK
#define COLOR_HILITE 0xDEFB // very light gray for row/col highlight
// Draw battery percentage at the top right
void drawBatteryPercent(M5GFX& display, int percent, int cell_size) {
int w = display.width();
// Use same font size as digits
int fontSize = (int)((float)cell_size / 16);
display.setTextSize(fontSize);
display.setTextColor(COLOR_NUM, COLOR_BG);
display.setTextDatum(top_right);
char buf[16];
snprintf(buf, sizeof(buf), "%d%%", percent);
// Clear the area first
int text_w = display.textWidth(buf);
display.fillRect(w - text_w - 16, 0, text_w + 16, fontSize + 8, COLOR_BG);
display.drawString(buf, w - 8, 8);
}
// Simple 9x9 Sudoku puzzle (0 = empty)
static constexpr uint8_t sudoku_init[9][9] = {
{5,3,0, 0,7,0, 0,0,0},
{6,0,0, 1,9,5, 0,0,0},
{0,9,8, 0,0,0, 0,6,0},
{8,0,0, 0,6,0, 0,0,3},
{4,0,0, 8,0,3, 0,0,1},
{7,0,0, 0,2,0, 0,0,6},
{0,6,0, 0,0,0, 2,8,0},
{0,0,0, 4,1,9, 0,0,5},
{0,0,0, 0,8,0, 0,7,9}
};
uint8_t sudoku[9][9];
int sel_x = 0, sel_y = 0;
// Store grid geometry for touch handling
int grid_x0, grid_y0, cell_size, grid_size;
// Input bar geometry
int inputbar_x0, inputbar_y0, inputbar_w, inputbar_h, inputbar_cell;
// 9-bit mask for pencilled digits per cell
uint16_t pencil[9][9] = {0};
bool penMode = true; // true = pen, false = pencil
// Sleep button state
bool isSleeping = false;
// Forward declarations for utility functions
void drawButton(M5GFX& display, int x, int y, int w, int h, const char* label, int fontSize, uint16_t fill, uint16_t border, uint16_t text);
int buttonWidth(M5GFX& display, const char* label, int fontSize, int pad);
bool isTouchInButton(int tx, int ty, int x, int y, int w, int h);
void handleInputBarButtons(int tx, int ty, int inputbar_x0, int inputbar_y0, int inputbar_cell, int inputbar_h, int inputbar_w, int inputbar_cell_local, int inputbar_y, int inputbar_h_local);
// Draws Pen/Pencil mode bar above input bar, same sizing as validate/hint
void drawModeBar(M5GFX& display, int modebar_y, int modebar_h, int modebar_cell, int bar_x0) {
const char* penStr = "Pen";
const char* pencilStr = "Pencil";
const char* clearStr = "Clear";
display.setTextSize((float)modebar_cell / 16);
int pen_w = display.textWidth(penStr) + modebar_cell / 2;
int pencil_w = display.textWidth(pencilStr) + modebar_cell / 2;
int clear_w = display.textWidth(clearStr) + modebar_cell / 2;
int pen_x = bar_x0;
int pencil_x = pen_x + pen_w + modebar_cell / 3;
int clear_x = pencil_x + pencil_w + modebar_cell / 3;
// Pen button
display.fillRect(pen_x, modebar_y, pen_w, modebar_h, penMode ? COLOR_SEL : COLOR_GRID);
display.drawRect(pen_x, modebar_y, pen_w, modebar_h, COLOR_BOLD);
display.setTextColor(COLOR_NUM, penMode ? COLOR_SEL : COLOR_GRID);
display.setTextDatum(middle_center);
display.drawString(penStr, pen_x + pen_w / 2, modebar_y + modebar_h / 2);
// Pencil button
display.fillRect(pencil_x, modebar_y, pencil_w, modebar_h, !penMode ? COLOR_SEL : COLOR_GRID);
display.drawRect(pencil_x, modebar_y, pencil_w, modebar_h, COLOR_BOLD);
display.setTextColor(COLOR_NUM, !penMode ? COLOR_SEL : COLOR_GRID);
display.drawString(pencilStr, pencil_x + pencil_w / 2, modebar_y + modebar_h / 2);
// Clear button
display.fillRect(clear_x, modebar_y, clear_w, modebar_h, COLOR_GRID);
display.drawRect(clear_x, modebar_y, clear_w, modebar_h, COLOR_BOLD);
display.setTextColor(COLOR_NUM, COLOR_GRID);
display.drawString(clearStr, clear_x + clear_w / 2, modebar_y + modebar_h / 2);
}
void clearSelectedCell() {
if (sudoku_init[sel_y][sel_x] == 0) {
sudoku[sel_y][sel_x] = 0;
pencil[sel_y][sel_x] = 0;
}
}
void drawPencilBar(M5GFX& display, int pencilbar_y, int pencilbar_h, int pencilbar_cell) {
// Draws the pencilled digits for the selected cell as a bar
int x0 = grid_x0;
uint16_t mask = pencil[sel_y][sel_x];
int shown = 0;
for (int i = 0; i < 9; ++i) {
if (mask & (1 << i)) {
int x = x0 + shown * pencilbar_cell;
display.fillRect(x, pencilbar_y, pencilbar_cell - 2, pencilbar_h, COLOR_BG); // white background
display.drawRect(x, pencilbar_y, pencilbar_cell - 2, pencilbar_h, COLOR_BOLD);
display.setTextColor(COLOR_NUM, COLOR_BG);
display.setTextDatum(middle_center);
display.setTextSize((float)pencilbar_cell / 16);
display.drawNumber(i + 1, x + pencilbar_cell / 2, pencilbar_y + pencilbar_h / 2);
shown++;
}
}
// Fill the rest with background (clear unused slots)
for (int i = shown; i < 9; ++i) {
int x = x0 + i * pencilbar_cell;
display.fillRect(x, pencilbar_y, pencilbar_cell - 2, pencilbar_h, COLOR_GRID);
display.drawRect(x, pencilbar_y, pencilbar_cell - 2, pencilbar_h, COLOR_BOLD);
}
}
void drawPencilDigits(M5GFX& display, int x, int y, uint16_t mask) {
int cell_x = grid_x0 + x * cell_size;
int cell_y = grid_y0 + y * cell_size;
int sub = 3; // 3x3 grid
int sub_w = cell_size / sub;
display.setTextColor(COLOR_NUM, COLOR_BG);
display.setTextDatum(middle_center);
display.setTextSize((float)cell_size / 32);
for (int n = 1; n <= 9; ++n) {
if (mask & (1 << (n - 1))) {
int sx = cell_x + ((n - 1) % 3) * sub_w + sub_w / 2;
int sy = cell_y + ((n - 1) / 3) * sub_w + sub_w / 2;
display.drawNumber(n, sx, sy);
}
}
}
void drawInputBar(M5GFX& display, int inputbar_y, int inputbar_h) {
// Draws 1-9 input bar at the given y, hiding digits present in 3x3 box of selected cell
int w = display.width();
inputbar_x0 = grid_x0;
inputbar_y0 = inputbar_y;
inputbar_w = grid_size;
inputbar_cell = inputbar_w / 9;
// Compute mask of digits present in 3x3 box
int box_x = (sel_x / 3) * 3;
int box_y = (sel_y / 3) * 3;
bool present[10] = {false};
for (int dy = 0; dy < 3; ++dy) {
for (int dx = 0; dx < 3; ++dx) {
int v = sudoku[box_y + dy][box_x + dx];
if (v > 0 && v <= 9) present[v] = true;
}
}
for (int i = 0; i < 9; ++i) {
int x = inputbar_x0 + i * inputbar_cell;
if (present[i + 1]) {
// Hide digit (draw empty)
display.fillRect(x, inputbar_y0, inputbar_cell - 2, inputbar_h, COLOR_GRID);
display.drawRect(x, inputbar_y0, inputbar_cell - 2, inputbar_h, COLOR_BOLD);
} else {
display.fillRect(x, inputbar_y0, inputbar_cell - 2, inputbar_h, COLOR_GRID);
display.drawRect(x, inputbar_y0, inputbar_cell - 2, inputbar_h, COLOR_BOLD);
display.setTextColor(COLOR_NUM, COLOR_GRID);
display.setTextDatum(middle_center);
display.setTextSize((float)inputbar_cell / 16);
display.drawNumber(i + 1, x + inputbar_cell / 2, inputbar_y0 + inputbar_h / 2);
}
}
// Draw Validate and Hint buttons below input bar (fit to string, same font size as digits)
const char* validateStr = "Validate";
const char* hintStr = "Hint";
const char* sleepStr = isSleeping ? "sleeping" : "Sleep";
int fontSize = (float)inputbar_cell / 16;
int pad = inputbar_cell / 2;
int validate_w = buttonWidth(display, validateStr, fontSize, pad);
int hint_w = buttonWidth(display, hintStr, fontSize, pad);
int sleep_w = buttonWidth(display, sleepStr, fontSize, pad);
int btn_h = inputbar_h * 0.7;
int btn_y = inputbar_y0 + inputbar_h + 8;
int btn_x = inputbar_x0;
drawButton(display, btn_x, btn_y, validate_w, btn_h, validateStr, fontSize, COLOR_GRID, COLOR_BOLD, COLOR_NUM);
btn_x += validate_w + inputbar_cell / 3;
drawButton(display, btn_x, btn_y, hint_w, btn_h, hintStr, fontSize, COLOR_GRID, COLOR_BOLD, COLOR_NUM);
btn_x += hint_w + inputbar_cell / 3;
drawButton(display, btn_x, btn_y, sleep_w, btn_h, sleepStr, fontSize, COLOR_GRID, COLOR_BOLD, COLOR_NUM);
}
void drawSudokuGrid(M5GFX& display) {
int w = display.width();
int h = display.height();
grid_size = 540; // Use full width
cell_size = grid_size / 9;
grid_x0 = (w - grid_size) / 2;
// Center grid vertically with all bars
int total_bar_height = cell_size * 1.2 * 3 + cell_size * 0.7 * 1 + 10 + 8 * 3; // input, pencil, mode, validate/hint, paddings
grid_y0 = (h - (grid_size + total_bar_height)) / 2 + 48; // shift down for battery row
// Calculate bar positions
int inputbar_h = cell_size * 1.2;
int modebar_h = inputbar_h * 0.7;
int pencilbar_h = inputbar_h;
int pencilbar_y = grid_y0 + grid_size + 10;
int modebar_y = pencilbar_y + pencilbar_h + 8;
int inputbar_y = modebar_y + modebar_h + 8;
int pencilbar_cell = grid_size / 9;
int modebar_cell = grid_size / 9;
int bar_x0 = grid_x0;
// Background
display.fillRect(0, 48, w, h - 48, COLOR_BG); // leave battery row untouched
// Highlight row and column (full coverage)
for (int i = 0; i < 9; ++i) {
// Row
display.fillRect(grid_x0 + i * cell_size, grid_y0 + sel_y * cell_size, cell_size, cell_size, COLOR_HILITE);
// Column
display.fillRect(grid_x0 + sel_x * cell_size, grid_y0 + i * cell_size, cell_size, cell_size, COLOR_HILITE);
}
// Highlight selected cell
display.fillRect(grid_x0 + sel_x * cell_size, grid_y0 + sel_y * cell_size, cell_size, cell_size, COLOR_SEL);
// Draw grid lines
for (int i = 0; i <= 9; ++i) {
int thick = (i % 3 == 0) ? 3 : 1;
uint16_t color = (i % 3 == 0) ? COLOR_BOLD : COLOR_GRID;
display.fillRect(grid_x0 + i * cell_size - thick/2, grid_y0, thick, grid_size, color);
display.fillRect(grid_x0, grid_y0 + i * cell_size - thick/2, grid_size, thick, color);
}
// Draw numbers (no in-cell pencil digits)
for (int y = 0; y < 9; ++y) {
for (int x = 0; x < 9; ++x) {
int cx = grid_x0 + x * cell_size + cell_size / 2;
int cy = grid_y0 + y * cell_size + cell_size / 2;
if (sudoku_init[y][x] != 0) {
// Fixed digit
display.fillRect(grid_x0 + x * cell_size, grid_y0 + y * cell_size, cell_size, cell_size, COLOR_FIXED_BG);
display.setTextColor(COLOR_FIXED_FG, COLOR_FIXED_BG);
display.setTextDatum(middle_center);
display.setTextSize((float)cell_size / 16);
display.drawNumber(sudoku_init[y][x], cx, cy);
} else if (sudoku[y][x] != 0) {
display.setTextColor(COLOR_NUM, COLOR_BG);
display.setTextDatum(middle_center);
display.setTextSize((float)cell_size / 16);
display.drawNumber(sudoku[y][x], cx, cy);
}
}
}
drawPencilBar(display, pencilbar_y, pencilbar_h, pencilbar_cell);
drawModeBar(display, modebar_y, modebar_h, modebar_cell, bar_x0);
drawInputBar(display, inputbar_y, inputbar_h);
}
// Dummy solution for hint/validation (replace with real solver if needed)
uint8_t solution[9][9] = {
{5,3,4,6,7,8,9,1,2},
{6,7,2,1,9,5,3,4,8},
{1,9,8,3,4,2,5,6,7},
{8,5,9,7,6,1,4,2,3},
{4,2,6,8,5,3,7,9,1},
{7,1,3,9,2,4,8,5,6},
{9,6,1,5,3,7,2,8,4},
{2,8,7,4,1,9,6,3,5},
{3,4,5,2,8,6,1,7,9}
};
void showHint() {
if (sudoku_init[sel_y][sel_x] == 0) {
sudoku[sel_y][sel_x] = solution[sel_y][sel_x];
}
}
void validateCell() {
if (sudoku[sel_y][sel_x] == solution[sel_y][sel_x]) {
// Show green highlight for correct
display.fillRect(grid_x0 + sel_x * cell_size, grid_y0 + sel_y * cell_size, cell_size, cell_size, 0x07E0); // green
drawSudokuGrid(display);
delay(500);
} else {
// Save the old digit
int old_digit = sudoku[sel_y][sel_x];
// Replace with 'x' (show as a string)
display.fillRect(grid_x0 + sel_x * cell_size, grid_y0 + sel_y * cell_size, cell_size, cell_size, 0xF800); // red
display.setTextColor(COLOR_BG, 0xF800);
display.setTextDatum(middle_center);
display.setTextSize((float)cell_size / 16);
int cx = grid_x0 + sel_x * cell_size + cell_size / 2;
int cy = grid_y0 + sel_y * cell_size + cell_size / 2;
display.drawString("x", cx, cy);
delay(2000);
// Restore the old digit
drawSudokuGrid(display);
}
}
void setCell(int value) {
if (penMode) {
if (sudoku_init[sel_y][sel_x] == 0) {
sudoku[sel_y][sel_x] = value;
pencil[sel_y][sel_x] = 0; // clear pencil marks
}
} else {
// Toggle pencil mark
if (sudoku_init[sel_y][sel_x] == 0) {
pencil[sel_y][sel_x] ^= (1 << (value - 1));
}
}
}
void onWakeup() {
isSleeping = false;
drawSudokuGrid(display);
}
void setup(void)
{
display.begin();
display.setRotation(0); // Portrait: 540x960 for M5PaperS3
if (display.isEPD()) {
display.setEpdMode(epd_mode_t::epd_fastest);
display.invertDisplay(true);
display.clear(COLOR_BG);
}
// Copy initial puzzle
for (int y = 0; y < 9; ++y)
for (int x = 0; x < 9; ++x)
sudoku[y][x] = sudoku_init[y][x];
onWakeup();
}
void highlightSameNumbers(int value) {
int w = display.width();
int h = display.height();
grid_size = 540; // Use full width, match main layout
cell_size = grid_size / 9;
grid_x0 = (w - grid_size) / 2;
int total_bar_height = cell_size * 1.2 * 3 + cell_size * 0.7 * 1 + 10 + 8 * 3;
grid_y0 = (h - (grid_size + total_bar_height)) / 2 + 48; // shift down for battery row
int inputbar_h = cell_size * 1.2;
int modebar_h = inputbar_h * 0.7;
int pencilbar_h = inputbar_h;
int pencilbar_y = grid_y0 + grid_size + 10;
int modebar_y = pencilbar_y + pencilbar_h + 8;
int inputbar_y = modebar_y + modebar_h + 8;
// Redraw background, highlights, and grid lines
display.fillRect(0, 0, w, h, COLOR_BG);
for (int i = 0; i < 9; ++i) {
display.fillRect(grid_x0 + i * cell_size, grid_y0 + sel_y * cell_size, cell_size, cell_size, COLOR_HILITE);
display.fillRect(grid_x0 + sel_x * cell_size, grid_y0 + i * cell_size, cell_size, cell_size, COLOR_HILITE);
}
display.fillRect(grid_x0 + sel_x * cell_size, grid_y0 + sel_y * cell_size, cell_size, cell_size, COLOR_SEL);
for (int i = 0; i <= 9; ++i) {
int thick = (i % 3 == 0) ? 3 : 1;
uint16_t color = (i % 3 == 0) ? COLOR_BOLD : COLOR_GRID;
display.fillRect(grid_x0 + i * cell_size - thick/2, grid_y0, thick, grid_size, color);
display.fillRect(grid_x0, grid_y0 + i * cell_size - thick/2, grid_size, thick, color);
}
// Draw numbers, bold for same value
for (int y = 0; y < 9; ++y) {
for (int x = 0; x < 9; ++x) {
int cx = grid_x0 + x * cell_size + cell_size / 2;
int cy = grid_y0 + y * cell_size + cell_size / 2;
int num = (sudoku_init[y][x] != 0) ? sudoku_init[y][x] : sudoku[y][x];
bool isFixed = sudoku_init[y][x] != 0;
if (num != 0) {
float sz = ((num == value) ? ((float)cell_size / 12) : ((float)cell_size / 16));
uint16_t fg = isFixed ? COLOR_FIXED_FG : COLOR_NUM;
uint16_t bg = isFixed ? COLOR_FIXED_BG : COLOR_BG;
display.fillRect(grid_x0 + x * cell_size, grid_y0 + y * cell_size, cell_size, cell_size, bg);
display.setTextColor(fg, bg);
display.setTextDatum(middle_center);
display.setTextSize(sz);
display.drawNumber(num, cx, cy);
}
}
}
// Draw input bar in highlight mode
drawInputBar(display, inputbar_y, inputbar_h);
}
void loop(void)
{
bool redraw = false;
int16_t tx, ty;
int w = display.width();
int h = display.height();
grid_size = 540;
cell_size = grid_size / 9;
grid_x0 = (w - grid_size) / 2;
int total_bar_height = cell_size * 1.2 * 3 + cell_size * 0.7 * 1 + 10 + 8 * 3;
grid_y0 = (h - (grid_size + total_bar_height)) / 2 + 48; // shift down for battery row
int inputbar_h = cell_size * 1.2;
int modebar_h = inputbar_h * 0.7;
int pencilbar_h = inputbar_h;
int pencilbar_y = grid_y0 + grid_size + 10;
int modebar_y = pencilbar_y + pencilbar_h + 8;
int inputbar_y = modebar_y + modebar_h + 8;
int pencilbar_cell = grid_size / 9;
int modebar_cell = grid_size / 9;
int bar_x0 = grid_x0;
int inputbar_x0_local = grid_x0;
int inputbar_w_local = grid_size;
int inputbar_cell_local = inputbar_w_local / 9;
// --- Battery percentage update (every 5 min) ---
unsigned long now = millis();
if (now - last_battery_check >= 3000000UL || last_battery_check == 0) {
int battery_percent = 100;
#ifdef M5PAPER
battery_percent = M5.getBatteryLevel();
#endif
if (battery_percent != last_battery_percent) {
drawBatteryPercent(display, battery_percent, cell_size);
last_battery_percent = battery_percent;
}
last_battery_check = now;
}
if (display.getTouch(&tx, &ty)) {
// Check pencil bar (toggle pencil digits)
if (!penMode && tx >= grid_x0 && tx < grid_x0 + grid_size && ty >= pencilbar_y && ty < pencilbar_y + pencilbar_h) {
int idx = (tx - grid_x0) / pencilbar_cell;
if (idx >= 0 && idx < 9) {
setCell(idx + 1);
redraw = true;
delay(200);
}
}
// Check mode bar (now with Clear button)
const char* penStr = "Pen";
const char* pencilStr = "Pencil";
const char* clearStr = "Clear";
display.setTextSize((float)modebar_cell / 16);
int pen_w = display.textWidth(penStr) + modebar_cell / 2;
int pencil_w = display.textWidth(pencilStr) + modebar_cell / 2;
int clear_w = display.textWidth(clearStr) + modebar_cell / 2;
int pen_x = bar_x0;
int pencil_x = pen_x + pen_w + modebar_cell / 3;
int clear_x = pencil_x + pencil_w + modebar_cell / 3;
if (tx >= pen_x && tx < pen_x + pen_w && ty >= modebar_y && ty < modebar_y + modebar_h) {
penMode = true;
redraw = true;
delay(200);
} else if (tx >= pencil_x && tx < pencil_x + pencil_w && ty >= modebar_y && ty < modebar_y + modebar_h) {
penMode = false;
redraw = true;
delay(200);
} else if (tx >= clear_x && tx < clear_x + clear_w && ty >= modebar_y && ty < modebar_y + modebar_h) {
clearSelectedCell();
redraw = true;
delay(200);
}
// Check if touch is inside grid
else if (tx >= grid_x0 && tx < grid_x0 + grid_size && ty >= grid_y0 && ty < grid_y0 + grid_size) {
int x = (tx - grid_x0) / cell_size;
int y = (ty - grid_y0) / cell_size;
sel_x = x;
sel_y = y;
int selected = (sudoku_init[y][x] != 0) ? sudoku_init[y][x] : sudoku[y][x];
if (selected != 0) {
highlightSameNumbers(selected);
delay(3000);
}
redraw = true;
delay(200);
} else if (tx >= inputbar_x0_local && tx < inputbar_x0_local + inputbar_w_local && ty >= inputbar_y && ty < inputbar_y + inputbar_h) {
int idx = (tx - inputbar_x0_local) / inputbar_cell_local;
if (idx >= 0 && idx < 9) {
setCell(idx + 1);
redraw = true;
delay(200);
}
} else {
handleInputBarButtons(tx, ty, inputbar_x0_local, inputbar_y0, inputbar_cell, inputbar_h, inputbar_w, inputbar_cell_local, inputbar_y, inputbar_h);
}
}
if (redraw) {
drawSudokuGrid(display);
}
}
// Utility: Draw a button with label
void drawButton(M5GFX& display, int x, int y, int w, int h, const char* label, int fontSize, uint16_t fill, uint16_t border, uint16_t text) {
display.fillRect(x, y, w, h, fill);
display.drawRect(x, y, w, h, border);
display.setTextColor(text, fill);
display.setTextDatum(middle_center);
display.setTextSize(fontSize);
display.drawString(label, x + w / 2, y + h / 2);
}
// Utility: Compute button width
int buttonWidth(M5GFX& display, const char* label, int fontSize, int pad) {
display.setTextSize(fontSize);
return display.textWidth(label) + pad;
}
// Utility: Check if touch is inside a button
bool isTouchInButton(int tx, int ty, int x, int y, int w, int h) {
return (tx >= x && tx < x + w && ty >= y && ty < y + h);
}
void handleInputBarButtons(int tx, int ty, int inputbar_x0, int inputbar_y0, int inputbar_cell, int inputbar_h, int inputbar_w, int inputbar_cell_local, int inputbar_y, int inputbar_h_local) {
const char* validateStr = "Validate";
const char* hintStr = "Hint";
const char* sleepStr = isSleeping ? "sleeping" : "Sleep";
int fontSize = (float)inputbar_cell_local / 16;
int pad = inputbar_cell_local / 2;
int validate_w = buttonWidth(display, validateStr, fontSize, pad);
int hint_w = buttonWidth(display, hintStr, fontSize, pad);
int sleep_w = buttonWidth(display, sleepStr, fontSize, pad);
int btn_h = inputbar_h_local * 0.7;
int btn_y = inputbar_y + inputbar_h_local + 8;
int btn_x = inputbar_x0;
if (isTouchInButton(tx, ty, btn_x, btn_y, validate_w, btn_h)) {
validateCell();
drawSudokuGrid(display);
delay(200);
return;
}
btn_x += validate_w + inputbar_cell_local / 3;
if (isTouchInButton(tx, ty, btn_x, btn_y, hint_w, btn_h)) {
showHint();
drawSudokuGrid(display);
delay(200);
return;
}
btn_x += hint_w + inputbar_cell_local / 3;
if (isTouchInButton(tx, ty, btn_x, btn_y, sleep_w, btn_h)) {
isSleeping = true;
drawSudokuGrid(display);
delay(200);
return;
}
}
[platformio]
default_envs = M5PaperS3
[env:M5PaperS3]
platform = [email protected]
board = esp32-s3-devkitm-1
monitor_speed = 115200
framework = arduino
; board_build.partitions = default_16MB.csv
board_upload.flash_size = 16MB
board_upload.maximum_size = 16777216
board_build.arduino.memory_type = qio_opi
build_flags =
-DESP32S3
-DBOARD_HAS_PSRAM
-DCORE_DEBUG_LEVEL=5
-DARDUINO_USB_CDC_ON_BOOT=1
-DARDUINO_USB_MODE=1
lib_deps =
epdiy=https://github.com/vroland/epdiy.git#d84d26ebebd780c4c9d4218d76fbe2727ee42b47
M5Unified=https://github.com/m5stack/M5Unified
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment