Display digits/dots fix + config setting via http [PERSISTENCE NOT WORKING]
This commit is contained in:
parent
12c089f7b9
commit
542c90dc92
@ -37,7 +37,7 @@
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<svg width="800" height="325" id="display">
|
<svg width="800" height="325" id="display" style="background-color: black">
|
||||||
</svg>
|
</svg>
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
@ -121,7 +121,8 @@
|
|||||||
segment.setAttribute("y", y + "vw");
|
segment.setAttribute("y", y + "vw");
|
||||||
segment.setAttribute("width", S + "vw");
|
segment.setAttribute("width", S + "vw");
|
||||||
segment.setAttribute("height", S + "vw");
|
segment.setAttribute("height", S + "vw");
|
||||||
segment.setAttribute("fill", "#555");
|
segment.setAttribute("stroke", "magenta");
|
||||||
|
segment.setAttribute("fill", "none");
|
||||||
segment.setAttribute("id", "segment" + segments.length);
|
segment.setAttribute("id", "segment" + segments.length);
|
||||||
display.appendChild(segment);
|
display.appendChild(segment);
|
||||||
segments.push(segment);
|
segments.push(segment);
|
||||||
@ -152,7 +153,18 @@
|
|||||||
socket.timeout = 1;
|
socket.timeout = 1;
|
||||||
socket.addEventListener('open', _ => console.log('websocket connected'));
|
socket.addEventListener('open', _ => console.log('websocket connected'));
|
||||||
socket.addEventListener('message', event => {
|
socket.addEventListener('message', event => {
|
||||||
event.data.split(',').filter((color, index) => color !== '').forEach((color, index) => segments[index].setAttribute("fill", "#" + color));
|
const len = event.data.length;
|
||||||
|
let index = 0;
|
||||||
|
let start = 0;
|
||||||
|
while (start < len) {
|
||||||
|
const end = start + 3;
|
||||||
|
const color = event.data.substring(start, end);
|
||||||
|
const segment = segments[index];
|
||||||
|
segment.setAttribute("fill", "#" + color)
|
||||||
|
segment.setAttribute("stroke", "none");
|
||||||
|
index++;
|
||||||
|
start = end;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
socket.addEventListener('close', _ => {
|
socket.addEventListener('close', _ => {
|
||||||
console.log('websocket disconnected');
|
console.log('websocket disconnected');
|
||||||
|
|||||||
@ -9,6 +9,8 @@ class App {
|
|||||||
|
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
|
const String path;
|
||||||
|
|
||||||
JsonDocument configJson;
|
JsonDocument configJson;
|
||||||
|
|
||||||
JsonObject config = configJson.to<JsonObject>();
|
JsonObject config = configJson.to<JsonObject>();
|
||||||
@ -17,8 +19,9 @@ class App {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
explicit App(const char *name)
|
explicit App(const char *name) :
|
||||||
: name(name) {
|
name(name),
|
||||||
|
path(String("/") + name + ".json") {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,16 +77,25 @@ public:
|
|||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool setConfig(const String& key, const String& valueStr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T configRead(const char *key, T fallback) {
|
T configGet(const char *key, T fallback) {
|
||||||
if (config[key].is<T>()) {
|
if (config[key].is<T>()) {
|
||||||
return config[key].as<T>();
|
return config[key].as<T>();
|
||||||
}
|
}
|
||||||
return fallback;
|
return fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void configSet(const char *key, T value) {
|
||||||
|
config[key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void _start() {
|
virtual void _start() {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
@ -104,14 +116,51 @@ protected:
|
|||||||
dirty = true;
|
dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
void configLoad() {
|
void configLoad() {
|
||||||
const auto path = String("/apps/") + name + ".json";
|
|
||||||
configJson.clear();
|
configJson.clear();
|
||||||
auto file = LittleFS.open(path, "r");
|
auto file = LittleFS.open(path, "r");
|
||||||
deserializeJson(configJson, file);
|
if (!file) {
|
||||||
|
error("failed to open file for config read: %s", path.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deserializeJson(configJson, file)) {
|
||||||
|
info("config loaded: %s", path.c_str());
|
||||||
|
} else {
|
||||||
|
error("failed to load config: %s", path.c_str());
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
|
|
||||||
config = configJson.to<JsonObject>();
|
config = configJson.to<JsonObject>();
|
||||||
|
|
||||||
|
char buffer[256];
|
||||||
|
serializeJsonPretty(configJson, buffer, sizeof buffer);
|
||||||
|
Serial.println(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void configSave() {
|
||||||
|
auto file = LittleFS.open(path, "w");
|
||||||
|
if (!file) {
|
||||||
|
error("failed to open file for config write: %s", path.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (serializeJson(configJson, file)) {
|
||||||
|
info("config written: %s", path.c_str());
|
||||||
|
} else {
|
||||||
|
error("failed to write config: %s", path.c_str());
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
auto file2 = LittleFS.open(path, "r");
|
||||||
|
if (file2) {
|
||||||
|
while (file2.available()) {
|
||||||
|
Serial.write(file2.read());
|
||||||
|
}
|
||||||
|
file2.close();
|
||||||
|
} else {
|
||||||
|
Serial.println("Failed to open file2 for reading");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -47,10 +47,24 @@ public:
|
|||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool setConfig(const String& key, const String& valueStr) override {
|
||||||
|
if (key.equals(CONFIG_SECONDS_KEY)) {
|
||||||
|
const auto seconds = valueStr.toInt();
|
||||||
|
const auto newMillis = seconds * 1000;
|
||||||
|
if (seconds > 0 && configMillis != newMillis) {
|
||||||
|
configMillis = newMillis;
|
||||||
|
configSet(CONFIG_SECONDS_KEY, seconds);
|
||||||
|
configSave();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void _start() override {
|
void _start() override {
|
||||||
configMillis = configRead<unsigned long>(CONFIG_SECONDS_KEY,CONFIG_SECONDS_DEFAULT) * 1000;
|
configMillis = configGet<unsigned long>(CONFIG_SECONDS_KEY, CONFIG_SECONDS_DEFAULT) * 1000;
|
||||||
totalMillis = configMillis;
|
totalMillis = configMillis;
|
||||||
setState(PAUSE);
|
setState(PAUSE);
|
||||||
}
|
}
|
||||||
@ -83,7 +97,7 @@ protected:
|
|||||||
|
|
||||||
if (blinkIntervalMillis > 0) {
|
if (blinkIntervalMillis > 0) {
|
||||||
const auto now = millis();
|
const auto now = millis();
|
||||||
if (now - blinkMillis > 500) {
|
if (now - blinkMillis > blinkIntervalMillis) {
|
||||||
blinkMillis = now;
|
blinkMillis = now;
|
||||||
blinkState = !blinkState;
|
blinkState = !blinkState;
|
||||||
markDirty();
|
markDirty();
|
||||||
@ -104,24 +118,34 @@ protected:
|
|||||||
|
|
||||||
void draw() override {
|
void draw() override {
|
||||||
display.clear();
|
display.clear();
|
||||||
|
if (state == PAUSE) {
|
||||||
|
display.setColor(BLUE);
|
||||||
|
} else if (totalMillis * 2 >= configMillis) {
|
||||||
|
display.setColor(GREEN);
|
||||||
|
} else if (totalMillis >= 10 * 1000) {
|
||||||
|
display.setColor(YELLOW);
|
||||||
|
} else {
|
||||||
|
display.setColor(RED);
|
||||||
|
}
|
||||||
if (blinkIntervalMillis == 0 || blinkState) {
|
if (blinkIntervalMillis == 0 || blinkState) {
|
||||||
if (totalMinutes > 0) {
|
if (totalMinutes > 0) {
|
||||||
display.setColor(totalMillis < configMillis / 2 ? YELLOW : GREEN);
|
|
||||||
display.printf("%2d:%02d", totalMinutes, partSeconds);
|
display.printf("%2d:%02d", totalMinutes, partSeconds);
|
||||||
info("%2d:%02d", totalMinutes, partSeconds);
|
info("%2d:%02d", totalMinutes, partSeconds);
|
||||||
} else if (totalMillis > 0) {
|
} else if (totalMillis > 0) {
|
||||||
display.setColor(RED);
|
|
||||||
display.printf("%2d.%02d", partSeconds, partCentis);
|
display.printf("%2d.%02d", partSeconds, partCentis);
|
||||||
} else {
|
} else {
|
||||||
display.printf("00:00");
|
display.printf("00:00");
|
||||||
}
|
}
|
||||||
} else if (state == PAUSE) {
|
} else if (state == PAUSE) {
|
||||||
info("PAUS", totalMinutes, partSeconds);
|
display.printf("PAUS");
|
||||||
}
|
}
|
||||||
display.flush();
|
display.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void confirm() override {
|
void confirm() override {
|
||||||
|
if (state == END) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (state == PAUSE) {
|
if (state == PAUSE) {
|
||||||
setState(MINUTES);
|
setState(MINUTES);
|
||||||
} else {
|
} else {
|
||||||
@ -157,7 +181,7 @@ private:
|
|||||||
blinkEnable(0);
|
blinkEnable(0);
|
||||||
break;
|
break;
|
||||||
case END:
|
case END:
|
||||||
blinkEnable(100);
|
blinkEnable(500);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
info("state changed to %s", getStateName());
|
info("state changed to %s", getStateName());
|
||||||
@ -166,11 +190,16 @@ private:
|
|||||||
|
|
||||||
const char *getStateName() const {
|
const char *getStateName() const {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case PAUSE: return "PAUSE";
|
case PAUSE:
|
||||||
case MINUTES: return "MINUTES";
|
return "PAUSE";
|
||||||
case SECONDS: return "SECONDS";
|
case MINUTES:
|
||||||
case END: return "END";
|
return "MINUTES";
|
||||||
default: return "[???]";
|
case SECONDS:
|
||||||
|
return "SECONDS";
|
||||||
|
case END:
|
||||||
|
return "END";
|
||||||
|
default:
|
||||||
|
return "[???]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
#include "filesystem.h"
|
#include "filesystem.h"
|
||||||
|
|
||||||
|
#include <FS.h>
|
||||||
#include <LittleFS.h>
|
#include <LittleFS.h>
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
void filesystemMount() {
|
void filesystemMount() {
|
||||||
if (LittleFS.begin(true)) {
|
if (LittleFS.begin()) {
|
||||||
info("filesystem mounted");
|
info("filesystem mounted: %3d%% used", (int) round(100.0 * (LittleFS.usedBytes()) / LittleFS.totalBytes()));
|
||||||
} else {
|
} else {
|
||||||
error("failed to mount filesystem");
|
error("failed to mount filesystem");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,45 +16,65 @@ void httpIndex(AsyncWebServerRequest *request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void httpActionLeft(AsyncWebServerRequest *request) {
|
void httpActionLeft(AsyncWebServerRequest *request) {
|
||||||
request->send(200);
|
|
||||||
if (app != nullptr) {
|
if (app != nullptr) {
|
||||||
app->left();
|
app->left();
|
||||||
}
|
}
|
||||||
|
request->send(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
void httpActionUp(AsyncWebServerRequest *request) {
|
void httpActionUp(AsyncWebServerRequest *request) {
|
||||||
request->send(200);
|
|
||||||
if (app != nullptr) {
|
if (app != nullptr) {
|
||||||
app->up();
|
app->up();
|
||||||
}
|
}
|
||||||
|
request->send(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
void httpActionDown(AsyncWebServerRequest *request) {
|
void httpActionDown(AsyncWebServerRequest *request) {
|
||||||
request->send(200);
|
|
||||||
if (app != nullptr) {
|
if (app != nullptr) {
|
||||||
app->down();
|
app->down();
|
||||||
}
|
}
|
||||||
|
request->send(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
void httpActionRight(AsyncWebServerRequest *request) {
|
void httpActionRight(AsyncWebServerRequest *request) {
|
||||||
request->send(200);
|
|
||||||
if (app != nullptr) {
|
if (app != nullptr) {
|
||||||
app->right();
|
app->right();
|
||||||
}
|
}
|
||||||
|
request->send(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
void httpActionCancel(AsyncWebServerRequest *request) {
|
void httpActionCancel(AsyncWebServerRequest *request) {
|
||||||
request->send(200);
|
|
||||||
if (app != nullptr) {
|
if (app != nullptr) {
|
||||||
app->cancel();
|
app->cancel();
|
||||||
}
|
}
|
||||||
|
request->send(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
void httpActionConfirm(AsyncWebServerRequest *request) {
|
void httpActionConfirm(AsyncWebServerRequest *request) {
|
||||||
request->send(200);
|
|
||||||
if (app != nullptr) {
|
if (app != nullptr) {
|
||||||
app->confirm();
|
app->confirm();
|
||||||
}
|
}
|
||||||
|
request->send(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
void httpAppConfig(AsyncWebServerRequest *request) {
|
||||||
|
if (!request->hasArg("key")) {
|
||||||
|
error("missing parameter 'key'");
|
||||||
|
request->send(400);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!request->hasArg("value")) {
|
||||||
|
error("missing parameter 'value'");
|
||||||
|
request->send(400);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (app != nullptr) {
|
||||||
|
if (app->setConfig(request->arg("key"), request->arg("value"))) {
|
||||||
|
request->send(200);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
request->send(400);
|
||||||
}
|
}
|
||||||
|
|
||||||
void httpSetup() {
|
void httpSetup() {
|
||||||
@ -91,6 +111,7 @@ void httpSetup() {
|
|||||||
server.on("/action/right", HTTP_GET, httpActionRight);
|
server.on("/action/right", HTTP_GET, httpActionRight);
|
||||||
server.on("/action/cancel", HTTP_GET, httpActionCancel);
|
server.on("/action/cancel", HTTP_GET, httpActionCancel);
|
||||||
server.on("/action/confirm", HTTP_GET, httpActionConfirm);
|
server.on("/action/confirm", HTTP_GET, httpActionConfirm);
|
||||||
|
server.on("/app/config", HTTP_GET, httpAppConfig);
|
||||||
server.begin();
|
server.begin();
|
||||||
websocketStarted = true;
|
websocketStarted = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
|
#include <LittleFS.h>
|
||||||
|
|
||||||
#include "clock.h"
|
#include "clock.h"
|
||||||
|
|
||||||
@ -23,6 +24,7 @@ void execute(const char *cmd) {
|
|||||||
info(" reboot");
|
info(" reboot");
|
||||||
info(" reconnect");
|
info(" reconnect");
|
||||||
info(" time");
|
info(" time");
|
||||||
|
info(" ls");
|
||||||
} else if (strcmp(cmd, "network") == 0) {
|
} else if (strcmp(cmd, "network") == 0) {
|
||||||
info("NETWORK");
|
info("NETWORK");
|
||||||
info(" %-10s %s", "mac:", WiFi.macAddress().c_str());
|
info(" %-10s %s", "mac:", WiFi.macAddress().c_str());
|
||||||
@ -47,27 +49,30 @@ void execute(const char *cmd) {
|
|||||||
info(" %-10s %s", "real:", getClockStr());
|
info(" %-10s %s", "real:", getClockStr());
|
||||||
info(" %-10s %s", "startup:", getStartupStr());
|
info(" %-10s %s", "startup:", getStartupStr());
|
||||||
info(" %-10s %s", "uptime:", getUptimeStr());
|
info(" %-10s %s", "uptime:", getUptimeStr());
|
||||||
|
} else if (strcmp(cmd, "ls") == 0) {
|
||||||
|
info("TODO");
|
||||||
} else {
|
} else {
|
||||||
info("UNKNOWN COMMAND: %s", cmd);
|
info("UNKNOWN COMMAND: %s", cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void logLoop() {
|
void logLoop() {
|
||||||
static char cmd[64];
|
static char buffer[64];
|
||||||
static auto write = cmd;
|
static auto write = buffer;
|
||||||
if (Serial.available() > 0) {
|
if (Serial.available() > 0) {
|
||||||
const auto c = static_cast<char>(Serial.read());
|
const auto c = static_cast<char>(Serial.read());
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
case 10:
|
||||||
|
break;
|
||||||
case 13:
|
case 13:
|
||||||
Serial.print(c);
|
Serial.print(c);
|
||||||
execute(cmd);
|
execute(buffer);
|
||||||
write = cmd;
|
write = buffer;
|
||||||
*write = 0;
|
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
if (write > cmd) {
|
if (write > buffer) {
|
||||||
Serial.print(c);
|
Serial.print(c);
|
||||||
*write-- = 0;
|
write--;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -76,6 +81,7 @@ void logLoop() {
|
|||||||
write++;
|
write++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
*write = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -12,20 +12,19 @@
|
|||||||
#define PIXELS_PER_SEGMENT 3
|
#define PIXELS_PER_SEGMENT 3
|
||||||
#define SEGMENTS_PER_DIGIT 7
|
#define SEGMENTS_PER_DIGIT 7
|
||||||
#define PIXELS_PER_DOT 1
|
#define PIXELS_PER_DOT 1
|
||||||
#define DOTS_PER_DIGIT 4
|
#define DOT_COUNT 4
|
||||||
#define DIGITS 4
|
#define DIGITS 4
|
||||||
#define MAX_STR_LEN (2 * DIGITS - 1)
|
|
||||||
#define PIXELS_PER_DIGIT_SEGMENTS (PIXELS_PER_SEGMENT * SEGMENTS_PER_DIGIT)
|
#define PIXELS_PER_DIGIT (PIXELS_PER_SEGMENT * SEGMENTS_PER_DIGIT)
|
||||||
#define PIXELS_PER_DIGIT_DOTS (PIXELS_PER_DOT * DOTS_PER_DIGIT)
|
#define TOTAL_DOT_PIXEL_COUNT (PIXELS_PER_DOT * DOT_COUNT)
|
||||||
#define PIXELS_PER_DIGIT_AND_DOTS (PIXELS_PER_DIGIT_SEGMENTS + PIXELS_PER_DIGIT_DOTS)
|
#define TOTAL_PIXEL_COUNT (DIGITS * PIXELS_PER_DIGIT + TOTAL_DOT_PIXEL_COUNT)
|
||||||
#define PIXEL_COUNT (DIGITS * PIXELS_PER_DIGIT_AND_DOTS - PIXELS_PER_DIGIT_DOTS)
|
#define TOTAL_PIXEL_BYTE_COUNT (TOTAL_PIXEL_COUNT * sizeof(Color))
|
||||||
#define PIXEL_BYTE_COUNT (PIXEL_COUNT * sizeof(Color))
|
|
||||||
|
|
||||||
class Display {
|
class Display {
|
||||||
|
|
||||||
// Adafruit_NeoPixel leds;
|
// Adafruit_NeoPixel leds;
|
||||||
|
|
||||||
Color pixels[PIXEL_COUNT] = {};
|
Color pixels[TOTAL_PIXEL_COUNT] = {};
|
||||||
|
|
||||||
Color color = WHITE;
|
Color color = WHITE;
|
||||||
|
|
||||||
@ -38,8 +37,8 @@ public:
|
|||||||
flush();
|
flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setColor(const Color color) {
|
void setColor(const Color newColor) {
|
||||||
this->color = color;
|
this->color = newColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setBrightness(const int brightness) {
|
void setBrightness(const int brightness) {
|
||||||
@ -47,7 +46,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
memset(pixels, 0, PIXEL_BYTE_COUNT);
|
memset(pixels, 0, TOTAL_PIXEL_BYTE_COUNT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void flush() {
|
void flush() {
|
||||||
@ -66,55 +65,58 @@ public:
|
|||||||
char buffer[512];
|
char buffer[512];
|
||||||
char *b = buffer;
|
char *b = buffer;
|
||||||
for (const auto& pixel: pixels) {
|
for (const auto& pixel: pixels) {
|
||||||
b += snprintf(b, sizeof buffer - (b - buffer), "%02X%02X%02X,", pixel.r, pixel.g, pixel.b);
|
b += snprintf(b, sizeof buffer - (b - buffer), "%X%X%X", pixel.r / 16, pixel.g / 16, pixel.b / 16);
|
||||||
}
|
}
|
||||||
websocketSend(buffer);
|
websocketSend(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
int printf(const char *format, ...) {
|
void printf(const char *format, ...) {
|
||||||
char buffer[MAX_STR_LEN + 1];
|
char buffer[64];
|
||||||
|
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
vsnprintf(buffer, sizeof buffer, format, args);
|
vsnprintf(buffer, sizeof buffer, format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
return print(buffer);
|
print(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
int print(const char *str) {
|
void print(const char *str) {
|
||||||
auto pixel = 0;
|
auto digit = 0;
|
||||||
for (auto character = str; *character != 0 && character - str < MAX_STR_LEN; character++) {
|
for (auto c = str; *c != 0 && digit < 4; c++) {
|
||||||
pixel = print(pixel, *character);
|
switch (*c) {
|
||||||
}
|
|
||||||
return pixel;
|
|
||||||
}
|
|
||||||
|
|
||||||
int print(const int pixel, const char character) {
|
|
||||||
switch (character) {
|
|
||||||
case '\'':
|
case '\'':
|
||||||
case '"':
|
case '"':
|
||||||
case '`':
|
case '`':
|
||||||
case '.':
|
case '.':
|
||||||
return printDots(pixel, false, false, false, true);
|
printDots(false, false, false, true);
|
||||||
|
digit = 2;
|
||||||
|
break;
|
||||||
case ',':
|
case ',':
|
||||||
return printDots(pixel, false, false, true, true);
|
printDots(false, false, true, true);
|
||||||
|
digit = 2;
|
||||||
|
break;
|
||||||
case ':':
|
case ':':
|
||||||
return printDots(pixel, false, true, true, false);
|
printDots(false, true, true, false);
|
||||||
|
digit = 2;
|
||||||
|
break;
|
||||||
case ';':
|
case ';':
|
||||||
return printDots(pixel, false, true, true, true);
|
printDots(false, true, true, true);
|
||||||
|
digit = 2;
|
||||||
|
break;
|
||||||
case '|':
|
case '|':
|
||||||
return printDots(pixel, true, true, true, true);
|
printDots(true, true, true, true);
|
||||||
|
digit = 2;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return printCharacter(pixel, character);
|
printCharacter(digit++, *c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int printDots(int pixel, const bool dot0, const bool dot1, const bool dot2, const bool dot3) {
|
void printDots(const bool dot0, const bool dot1, const bool dot2, const bool dot3) {
|
||||||
pixel = pixel / PIXELS_PER_DIGIT_AND_DOTS - PIXELS_PER_DIGIT_DOTS;
|
auto pixel = PIXELS_PER_DIGIT * 2;
|
||||||
if (pixel < 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (dot0) {
|
if (dot0) {
|
||||||
pixels[pixel] = color;
|
pixels[pixel] = color;
|
||||||
}
|
}
|
||||||
@ -130,11 +132,10 @@ public:
|
|||||||
if (dot3) {
|
if (dot3) {
|
||||||
pixels[pixel] = color;
|
pixels[pixel] = color;
|
||||||
}
|
}
|
||||||
return pixel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int printCharacter(int pixel, const char character) {
|
void printCharacter(int digit, const char character) {
|
||||||
pixel = pixel / PIXELS_PER_DIGIT_AND_DOTS;
|
auto pixel = digit * PIXELS_PER_DIGIT + (digit >= 2 ? TOTAL_DOT_PIXEL_COUNT : 0);
|
||||||
const auto symbol = getSymbol(character);
|
const auto symbol = getSymbol(character);
|
||||||
for (auto s = *symbol; s < *symbol + SYMBOL_SIZE; s++) {
|
for (auto s = *symbol; s < *symbol + SYMBOL_SIZE; s++) {
|
||||||
if (*s) {
|
if (*s) {
|
||||||
@ -145,7 +146,6 @@ public:
|
|||||||
pixel += 3;
|
pixel += 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pixel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user