/** * @file display_draw.c * Provides functions for drawing to the display * * Copyright (C) 2018 Clyne Sullivan * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include volatile uint8_t lock = 0; #define LOCK while (lock) { delay(5); } task_hold(1); lock = 1 #define UNLOCK task_hold(0); lock = 0 static unsigned int curx = 0; static unsigned int cury = 0; static unsigned int curxo = 0; static unsigned int curyo = 0; extern const unsigned char inconsolata24[192 * 156 * 2 + 1]; void task_cursor(void) { while (1) { int x = curxo + curx * 12; int y = curyo + cury * 26; dsp_rect(x, y + 24, 12, 1, 0xFFFF); delay(300); dsp_rect(x, y + 24, 12, 1, 0); delay(300); } } void dsp_cursoron(void) { task_start(task_cursor, 512); } void dsp_putchar(int c) { LOCK; if (c == '\n') { curx = 0; if (++cury == 12) { UNLOCK; dsp_rect(0, 0, LCD_WIDTH, LCD_HEIGHT, 0); cury = 0; } UNLOCK; return; } else if (c == '\b') { if (curx > 0) curx--; UNLOCK; dsp_rect(curxo + curx * 12, curyo + cury * 26, 12, 26, 0); return; } if (c > 0x7F) goto end; unsigned int start = ((c - ' ') / 16 * 192 * 26 + (c % 16) * 12) * 2; unsigned int x = curxo + curx * 12; unsigned int y = curyo + cury * 26; dsp_set_addr(x, y, x + 11, y + 25); // for each row for (unsigned int i = 0; i < 26; i++) { // for each column for (int j = 12 * 2 - 1; j >= 0; j--) dsp_write_data(inconsolata24[start + (i * 192 * 2) + j]); } if (++curx == 40) { curx = 0; if (++cury == 12) { UNLOCK; dsp_rect(0, 0, LCD_WIDTH, LCD_HEIGHT, 0); LOCK; cury = 0; } } end: UNLOCK; } void dsp_puts(const char *s) { unsigned int i = 0; while (s[i]) dsp_putchar(s[i++]); } void dsp_cpos(int x, int y) { curx = x; cury = y; } void dsp_coff(int x, int y) { curxo = x; curyo = y; } void dsp_rect(int x, int y, int w, int h, uint16_t color) { dsp_set_addr(x, y, x + w - 1, y + h - 1); int countdown = w * h; LOCK; do { dsp_write_data(color >> 8); dsp_write_data(color & 0xFF); } while (countdown--); UNLOCK; } void dsp_pixel(int x, int y, uint16_t color) { LOCK; dsp_set_addr(x, y, x, y); dsp_write_data(color >> 8); dsp_write_data(color & 0xFF); UNLOCK; } void dsp_line(int x, int y, int i, int j, uint16_t color) { int dx = i - x; int sx = dx >= 0 ? 1 : -1; int dy = j - y; int sy = dy >= 0 ? 1 : -1; if (dx < 0) dx *= -1; if (dy < 0) dy *= -1; int err = (dx > dy ? dx : -dy) / 2; int e2; while (1) { dsp_pixel(x, y, color); if (x == i && y == j) break; e2 = err; if (e2 > -dx) { err -= dy; x += sx; } if (e2 < dy) { err += dx; y += sy; } } }