/** * Constants */ const byte BLACK = 0; const byte WHITE = 255; const byte DARK_GRAY = 73; const byte GRAY = 146; const byte LIGHT_GRAY = 182; byte selected_color = 255; interface Device { nat handle; } plex Screen implements Device { nat handle; nat width; nat height; nat buffer_size; byte[] buffer; draw() { unsafe { write(this, this.buffer, this.buffer_size); } } } plex Mouse implements Device { nat handle; nat x; nat y; bool left; bool right; bool middle; bool btn4; } /** * Main function */ function main() { Screen screen = open("/dev/screen/0", 0); Mouse mouse = open("/dev/mouse/0", 0); outline_swatch(screen, BLACK, 1, 1); outline_swatch(screen, WHITE, 21, 1); screen.draw(); loop { mouse.refresh(); if (not mouse.left) continue; int box_size = 20; int x = 1; int y = 1; byte color = BLACK; outlined_swatch(screen, color, x, y); set_color(box_size, x, y, mouse.x, mouse.y, color); color = WHITE; x = 21; outlined_swatch(screen, color, x, y); set_color(box_size, x, y, mouse.x, mouse.y, color); screen.draw(); rectangle(screen, selected_color, x, y, 5, 5); } exit(0); } /** * Checks if the click is within the bound and update the selected color if so. */ function set_color(int box_size, int bx, int by, int mx, int my, byte color) { int right = bx + box_size; int bottom = by + box_size; if (mx < bx) return; if (mx > right) return; if (my < by) return; if (my > bottom) return; selected_color = color; return; } /** * Draw a color box with a grey outline, if selected use a darker color */ function outline_swatch(Device screen, byte color, int x, int y) { byte bg_color = GRAY; if (selected_color == color) { bg_color = DARK_GRAY; } rectangle(screen, bg_color, x, y, 20, 20); rectangle(screen, color, x + 2, y + 2, 17, 17); return; } /** * Draw a rectangle */ function rectangle(Device screen, byte color, int x, int y, int width, int height) { // we need unsafe because we are using pointers `&` and `memset` directly // unsafe takes the guardrails off and allows you to access/modify memory directly unsafe { int pixel = y * width + x + &screen.buffer + 4; do (int i = height; i > 0; i--) { int row = pixel + width; memset(screen.buffer, row, color, width); pixel += width; } } return; }