161 lines
3.4 KiB
C
161 lines
3.4 KiB
C
#include "display.h"
|
|
|
|
#include <stddef.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include "ili9341.h"
|
|
|
|
#define CHAR_W_SMALL 6
|
|
#define CHAR_H_SMALL 8
|
|
#define CHAR_W_LARGE 12
|
|
#define CHAR_H_LARGE 16
|
|
|
|
static bool s_inited = false;
|
|
|
|
static int text_width_px(const char *text, int char_w)
|
|
{
|
|
if (text == NULL) {
|
|
return 0;
|
|
}
|
|
return (int)strlen(text) * char_w;
|
|
}
|
|
|
|
esp_err_t display_init(void)
|
|
{
|
|
if (s_inited) {
|
|
return ESP_OK;
|
|
}
|
|
|
|
ESP_ERROR_CHECK(ili9341_init());
|
|
s_inited = true;
|
|
return display_clear(RGB565_BLACK);
|
|
}
|
|
|
|
esp_err_t display_fill_rect(int x, int y, int w, int h, uint16_t color)
|
|
{
|
|
if (!s_inited) {
|
|
return ESP_ERR_INVALID_STATE;
|
|
}
|
|
|
|
if (w <= 0 || h <= 0) {
|
|
return ESP_OK;
|
|
}
|
|
|
|
if (x >= DISPLAY_WIDTH || y >= DISPLAY_HEIGHT) {
|
|
return ESP_OK;
|
|
}
|
|
|
|
if (x < 0) {
|
|
w += x;
|
|
x = 0;
|
|
}
|
|
if (y < 0) {
|
|
h += y;
|
|
y = 0;
|
|
}
|
|
|
|
if (x + w > DISPLAY_WIDTH) {
|
|
w = DISPLAY_WIDTH - x;
|
|
}
|
|
if (y + h > DISPLAY_HEIGHT) {
|
|
h = DISPLAY_HEIGHT - y;
|
|
}
|
|
|
|
if (w <= 0 || h <= 0) {
|
|
return ESP_OK;
|
|
}
|
|
|
|
for (int py = y; py < y + h; ++py) {
|
|
for (int px = x; px < x + w; ++px) {
|
|
ESP_ERROR_CHECK(ili9341_draw_pixel((uint16_t)px, (uint16_t)py, color));
|
|
}
|
|
}
|
|
|
|
return ESP_OK;
|
|
}
|
|
|
|
esp_err_t display_clear(uint16_t color)
|
|
{
|
|
if (!s_inited) {
|
|
return ESP_ERR_INVALID_STATE;
|
|
}
|
|
|
|
ili9341_fill_screen(color);
|
|
return ESP_OK;
|
|
}
|
|
|
|
esp_err_t display_draw_text_small(int x, int y, const char *text, uint16_t fg, uint16_t bg)
|
|
{
|
|
if (!s_inited) {
|
|
return ESP_ERR_INVALID_STATE;
|
|
}
|
|
if (text == NULL) {
|
|
return ESP_ERR_INVALID_ARG;
|
|
}
|
|
|
|
ili9341_draw_text(x, y, text, fg, bg);
|
|
return ESP_OK;
|
|
}
|
|
|
|
esp_err_t display_draw_text(int x, int y, const char *text, uint16_t fg, uint16_t bg)
|
|
{
|
|
if (!s_inited) {
|
|
return ESP_ERR_INVALID_STATE;
|
|
}
|
|
if (text == NULL) {
|
|
return ESP_ERR_INVALID_ARG;
|
|
}
|
|
|
|
ili9341_draw_text(x, y, text, fg, bg);
|
|
return ESP_OK;
|
|
}
|
|
|
|
esp_err_t display_draw_text_centered(int y, const char *text, uint16_t fg, uint16_t bg)
|
|
{
|
|
int w = text_width_px(text, CHAR_W_LARGE);
|
|
int x = (DISPLAY_WIDTH - w) / 2;
|
|
if (x < 0) {
|
|
x = 0;
|
|
}
|
|
return display_draw_text(x, y, text, fg, bg);
|
|
}
|
|
|
|
esp_err_t display_draw_text_small_centered(int y, const char *text, uint16_t fg, uint16_t bg)
|
|
{
|
|
int w = text_width_px(text, CHAR_W_SMALL);
|
|
int x = (DISPLAY_WIDTH - w) / 2;
|
|
if (x < 0) {
|
|
x = 0;
|
|
}
|
|
return display_draw_text_small(x, y, text, fg, bg);
|
|
}
|
|
|
|
esp_err_t display_draw_text_inverse(int x, int y, const char *text, uint16_t bg, uint16_t fg)
|
|
{
|
|
return display_draw_text_small(x, y, text, fg, bg);
|
|
}
|
|
|
|
esp_err_t display_draw_button_status(int btn_id, bool pressed)
|
|
{
|
|
if (!s_inited) {
|
|
return ESP_ERR_INVALID_STATE;
|
|
}
|
|
|
|
const int slot_w = DISPLAY_WIDTH / 3;
|
|
const int slot_h = 22;
|
|
const int x = btn_id * slot_w;
|
|
const int y = DISPLAY_HEIGHT - slot_h;
|
|
|
|
uint16_t fill = pressed ? RGB565_RED : RGB565_DIM_GRAY;
|
|
uint16_t text = RGB565_WHITE;
|
|
|
|
ESP_ERROR_CHECK(display_fill_rect(x, y, slot_w - 1, slot_h - 1, fill));
|
|
|
|
char label[8];
|
|
snprintf(label, sizeof(label), "D%d", btn_id);
|
|
ESP_ERROR_CHECK(display_draw_text_small(x + (slot_w / 2) - 6, y + 7, label, text, fill));
|
|
|
|
return ESP_OK;
|
|
}
|