From 7dcfdd236039c5a8e29e6b9b68e9db9d12e88b2e Mon Sep 17 00:00:00 2001 From: Mikhail Yudin Date: Tue, 8 Aug 2023 01:29:41 +0700 Subject: [PATCH] feat: redesign, fixed dots for numbers --- libs/lcd/lcd.hpp | 487 ++++++++++++++++---------------- src/spectrum_fagci/spectrum.hpp | 36 +-- 2 files changed, 269 insertions(+), 254 deletions(-) diff --git a/libs/lcd/lcd.hpp b/libs/lcd/lcd.hpp index 1320faa..22ef78f 100644 --- a/libs/lcd/lcd.hpp +++ b/libs/lcd/lcd.hpp @@ -1,275 +1,286 @@ #pragma once -#include #include +#include -struct ILcd -{ - virtual void UpdateScreen() = 0; +struct ILcd { + virtual void UpdateScreen() = 0; }; -template -struct IBitmap -{ - constexpr IBitmap(const unsigned char *_pBuffStart) : pBuffStart(_pBuffStart){}; - static constexpr auto SizeX = _SizeX; - static constexpr auto SizeY = _SizeY; - static constexpr auto LineHeight = _LineHeight; - static constexpr auto Lines = _SizeX / _LineHeight; - static constexpr unsigned short GetCoursorPosition(unsigned char u8Line, unsigned char u8XPos) - { - return (u8Line * SizeX) + u8XPos; - } +template +struct IBitmap { + constexpr IBitmap(const unsigned char *_pBuffStart) + : pBuffStart(_pBuffStart){}; + static constexpr auto SizeX = _SizeX; + static constexpr auto SizeY = _SizeY; + static constexpr auto LineHeight = _LineHeight; + static constexpr auto Lines = _SizeX / _LineHeight; + static constexpr unsigned short GetCoursorPosition(unsigned char u8Line, + unsigned char u8XPos) { + return (u8Line * SizeX) + u8XPos; + } - virtual bool GetPixel(unsigned char u8X, unsigned char u8Y) const = 0; - virtual void SetPixel(unsigned char u8X, unsigned char u8Y) const = 0; - virtual void *GetCoursorData(unsigned short u16CoursorPosition) const { return nullptr; } - virtual void ClearAll() = 0; - const unsigned char *pBuffStart; + virtual bool GetPixel(unsigned char u8X, unsigned char u8Y) const = 0; + virtual void SetPixel(unsigned char u8X, unsigned char u8Y) const = 0; + virtual void *GetCoursorData(unsigned short u16CoursorPosition) const { + return nullptr; + } + virtual void ClearAll() = 0; + const unsigned char *pBuffStart; }; -struct IFont -{ - virtual bool GetPixel(char c8Character, unsigned char u8X, unsigned char u8Y) const = 0; - virtual unsigned char *GetRaw(char c8Character) const = 0; - virtual unsigned char GetSizeX(char c8Character) const = 0; - virtual unsigned char GetSizeY(char c8Character) const = 0; +struct IFont { + virtual bool GetPixel(char c8Character, unsigned char u8X, + unsigned char u8Y) const = 0; + virtual unsigned char *GetRaw(char c8Character) const = 0; + virtual unsigned char GetSizeX(char c8Character) const = 0; + virtual unsigned char GetSizeY(char c8Character) const = 0; }; -template -class CDisplay -{ +template class CDisplay { public: - constexpr CDisplay(BitmapType &_Bitmap) - : Bitmap(_Bitmap), pCurrentFont(nullptr), u16CoursorPosition(0) - { - } + constexpr CDisplay(BitmapType &_Bitmap) + : Bitmap(_Bitmap), pCurrentFont(nullptr), u16CoursorPosition(0) {} - void SetCoursor(unsigned char u8Line, unsigned char u8X) const - { - u16CoursorPosition = (u8Line * Bitmap.SizeX) + u8X; - } + void SetCoursor(unsigned char u8Line, unsigned char u8X) const { + u16CoursorPosition = (u8Line * Bitmap.SizeX) + u8X; + } - void SetCoursorXY(unsigned char x, unsigned char y) const - { - u16CoursorPosition = x + (y << 4); - } + void SetCoursorXY(unsigned char x, unsigned char y) const { + u16CoursorPosition = x + (y << 4); + } - void SetFont(const IFont *pFont) const - { - pCurrentFont = pFont; - } + void SetFont(const IFont *pFont) const { pCurrentFont = pFont; } - void DrawLine(int sx, int ex, int ny) - { - for (int i = sx; i <= ex; i++) - { - if (i < Bitmap.SizeX && ny < Bitmap.SizeY) - { - Bitmap.SetPixel(i, ny); - } + void DrawLine(int sx, int ex, int ny) { + for (int i = sx; i <= ex; i++) { + if (i < Bitmap.SizeX && ny < Bitmap.SizeY) { + Bitmap.SetPixel(i, ny); } - } + } + } - void DrawHLine(int sy, int ey, int nx, bool bCropped = false) - { - for (int i = sy; i <= ey; i++) - { - if (i < Bitmap.SizeY && nx < Bitmap.SizeX && (!bCropped || i % 2)) - { - Bitmap.SetPixel(nx, i); - } + void DrawHLine(int sy, int ey, int nx, bool bCropped = false) { + for (int i = sy; i <= ey; i++) { + if (i < Bitmap.SizeY && nx < Bitmap.SizeX && (!bCropped || i % 2)) { + Bitmap.SetPixel(nx, i); } - } + } + } - void DrawCircle(unsigned char cx, unsigned char cy, unsigned int r, bool bFilled = false) - { - int x = 0; - int y = r; - int d = 3 - 2 * r; - if (!r) - return; + void DrawCircle(unsigned char cx, unsigned char cy, unsigned int r, + bool bFilled = false) { + int x = 0; + int y = r; + int d = 3 - 2 * r; + if (!r) + return; - while (y >= x) - { - // when bFilled is true, draw lines to fill the circle - if (bFilled) - { - DrawLine(cx - x, cx + x, cy - y); - DrawLine(cx - y, cx + y, cy - x); - DrawLine(cx - x, cx + x, cy + y); - DrawLine(cx - y, cx + y, cy + x); - } - else - { - if (cx + x < Bitmap.SizeX && cy + y < Bitmap.SizeY) - Bitmap.SetPixel(cx + x, cy - y); // 1st quarter - if (cx + y < Bitmap.SizeX && cy + x < Bitmap.SizeY) - Bitmap.SetPixel(cx + y, cy - x); // 2nd quarter - if (cx - x >= 0 && cy + y < Bitmap.SizeY) - Bitmap.SetPixel(cx - x, cy - y); // 3rd quarter - if (cx - y >= 0 && cy + x < Bitmap.SizeY) - Bitmap.SetPixel(cx - y, cy - x); // 4th quarter - if (cx + x < Bitmap.SizeX && cy + y < Bitmap.SizeY) - Bitmap.SetPixel(cx + x, cy + y); // 5th quarter - if (cx + y < Bitmap.SizeX && cy - x >= 0) - Bitmap.SetPixel(cx + y, cy + x); // 6th quarter - if (cx - x >= 0 && cy - y >= 0) - Bitmap.SetPixel(cx - x, cy + y); // 7th quarter - if (cx - y >= 0 && cy - x >= 0) - Bitmap.SetPixel(cx - y, cy + x); // 8th quarter - } - x++; - if (d < 0) - d += 4 * x + 6; - else - { - y--; - d += 4 * (x - y) + 10; - } + while (y >= x) { + // when bFilled is true, draw lines to fill the circle + if (bFilled) { + DrawLine(cx - x, cx + x, cy - y); + DrawLine(cx - y, cx + y, cy - x); + DrawLine(cx - x, cx + x, cy + y); + DrawLine(cx - y, cx + y, cy + x); + } else { + if (cx + x < Bitmap.SizeX && cy + y < Bitmap.SizeY) + Bitmap.SetPixel(cx + x, cy - y); // 1st quarter + if (cx + y < Bitmap.SizeX && cy + x < Bitmap.SizeY) + Bitmap.SetPixel(cx + y, cy - x); // 2nd quarter + if (cx - x >= 0 && cy + y < Bitmap.SizeY) + Bitmap.SetPixel(cx - x, cy - y); // 3rd quarter + if (cx - y >= 0 && cy + x < Bitmap.SizeY) + Bitmap.SetPixel(cx - y, cy - x); // 4th quarter + if (cx + x < Bitmap.SizeX && cy + y < Bitmap.SizeY) + Bitmap.SetPixel(cx + x, cy + y); // 5th quarter + if (cx + y < Bitmap.SizeX && cy - x >= 0) + Bitmap.SetPixel(cx + y, cy + x); // 6th quarter + if (cx - x >= 0 && cy - y >= 0) + Bitmap.SetPixel(cx - x, cy + y); // 7th quarter + if (cx - y >= 0 && cy - x >= 0) + Bitmap.SetPixel(cx - y, cy + x); // 8th quarter } - } - - void DrawRectangle(unsigned char sx, unsigned char sy, unsigned char width, unsigned char height, bool bFilled) - { - unsigned char maxX = (sx + width < Bitmap.SizeX) ? sx + width : Bitmap.SizeX; - unsigned char maxY = (sy + height < Bitmap.SizeY) ? sy + height : Bitmap.SizeY; - - // Draw vertical lines - for (unsigned char y = sy; y < maxY; y++) - { - Bitmap.SetPixel(sx, y); - Bitmap.SetPixel(maxX - 1, y); + x++; + if (d < 0) + d += 4 * x + 6; + else { + y--; + d += 4 * (x - y) + 10; } + } + } - // Draw horizontal lines - for (unsigned char x = sx; x < maxX; x++) - { - Bitmap.SetPixel(x, sy); - Bitmap.SetPixel(x, maxY - 1); + void DrawRectangle(unsigned char sx, unsigned char sy, unsigned char width, + unsigned char height, bool bFilled) { + unsigned char maxX = + (sx + width < Bitmap.SizeX) ? sx + width : Bitmap.SizeX; + unsigned char maxY = + (sy + height < Bitmap.SizeY) ? sy + height : Bitmap.SizeY; + + // Draw vertical lines + for (unsigned char y = sy; y < maxY; y++) { + Bitmap.SetPixel(sx, y); + Bitmap.SetPixel(maxX - 1, y); + } + + // Draw horizontal lines + for (unsigned char x = sx; x < maxX; x++) { + Bitmap.SetPixel(x, sy); + Bitmap.SetPixel(x, maxY - 1); + } + + // If filled, draw horizontal lines within the rectangle + if (bFilled) { + for (unsigned char x = sx + 1; x < maxX - 1; x++) { + for (unsigned char y = sy + 1; y < maxY - 1; y++) { + Bitmap.SetPixel(x, y); + } } + } + } - // If filled, draw horizontal lines within the rectangle - if (bFilled) - { - for (unsigned char x = sx + 1; x < maxX - 1; x++) - { - for (unsigned char y = sy + 1; y < maxY - 1; y++) - { - Bitmap.SetPixel(x, y); - } - } - } - } - - unsigned char PrintCharacter(const char c8Character) const - { - if (!pCurrentFont) - { - return 0; - } - - const auto *const pFontRawData = pCurrentFont->GetRaw(c8Character); - auto *pCoursorPosition = Bitmap.GetCoursorData(u16CoursorPosition); - auto const CopySize = pCurrentFont->GetSizeY(c8Character) * (BitmapType::LineHeight / 8); - if (pCoursorPosition && !(BitmapType::LineHeight % 8)) - { - if (pFontRawData) - memcpy(pCoursorPosition, pFontRawData, CopySize); - else - memset(pCoursorPosition, 0, CopySize); - } - - u16CoursorPosition += pCurrentFont->GetSizeY(c8Character); + unsigned char PrintCharacter(const char c8Character) const { + if (!pCurrentFont) { return 0; - } + } - void Print(const char *C8String) const - { - for (unsigned char i = 0; i < strlen(C8String); i++) - { - PrintCharacter(C8String[i]); + const auto *const pFontRawData = pCurrentFont->GetRaw(c8Character); + auto *pCoursorPosition = Bitmap.GetCoursorData(u16CoursorPosition); + auto const CopySize = + pCurrentFont->GetSizeY(c8Character) * (BitmapType::LineHeight / 8); + if (pCoursorPosition && !(BitmapType::LineHeight % 8)) { + if (pFontRawData) + memcpy(pCoursorPosition, pFontRawData, CopySize); + else + memset(pCoursorPosition, 0, CopySize); + } + + u16CoursorPosition += pCurrentFont->GetSizeY(c8Character); + return 0; + } + + void Print(const char *C8String) const { + for (unsigned char i = 0; i < strlen(C8String); i++) { + PrintCharacter(C8String[i]); + } + } + + unsigned char PrintFixedDigtsNumer(int s32Number, unsigned char u8Digts) { + char U8NumBuff[32]; + memset(U8NumBuff, 0, sizeof(U8NumBuff)); + + char *pString = U8NumBuff + u8Digts; + *pString = '\0'; + + if (s32Number < 0) { + U8NumBuff[0] = '-'; + s32Number = -s32Number; + } + + while (u8Digts--) { + *--pString = '0' + (s32Number % 10); + s32Number /= 10; + } + + Print(U8NumBuff); + return u8Digts * pCurrentFont->GetSizeX('0'); + } + + static constexpr int powersOfTen[9] = { + 1, // 10^0 + 10, // 10^1 + 100, // 10^2 + 1000, // 10^3 + 10000, // 10^4 + 100000, // 10^5 + 1000000, // 10^6 + 10000000, // 10^7 + 100000000 // 10^8 + }; + void PrintFixedDigitsNumber2(int s32Number, unsigned char u8DigsToCut = 2, + unsigned char u8FixedDigtsCnt = 0) { + char U8NumBuff[11] = {0}; // 9 digits, sign, and null terminator + int startIdx = 0; + bool isNegative = false; + + if (s32Number < 0) { + PrintCharacter('-'); + // U8NumBuff[0] = '-'; + s32Number = -s32Number; + // isNegative = true; + } + + for (int i = 8; i >= u8DigsToCut; + --i) // assuming powersOfTen is an array of powers of 10 + { + int digit = 0; + while (s32Number >= powersOfTen[i]) { + s32Number -= powersOfTen[i]; + ++digit; } - } + U8NumBuff[isNegative + (8 - i)] = '0' + digit; - unsigned char PrintFixedDigtsNumer(int s32Number, unsigned char u8Digts) - { - char U8NumBuff[32]; - memset(U8NumBuff, 0, sizeof(U8NumBuff)); + // We found the first non-zero digit + if (digit != 0 && startIdx == (isNegative ? 1 : 0)) + startIdx = isNegative + (8 - i); + } - char *pString = U8NumBuff + u8Digts; - *pString = '\0'; + // If the number was 0, we write a single 0. + if (startIdx == (isNegative ? 1 : 0)) + U8NumBuff[isNegative] = '0'; - if (s32Number < 0) - { - U8NumBuff[0] = '-'; - s32Number = -s32Number; + // Print the string from the start index + if (u8FixedDigtsCnt) { + startIdx = 9 - u8DigsToCut - u8FixedDigtsCnt; + } + + Print(U8NumBuff + startIdx); + } + void PrintFixedDigitsNumber3(int s32Number, unsigned char u8DigsToCut = 2, + unsigned char u8FixedDigtsCnt = 0, + unsigned char pointAt = 128) { + char U8NumBuff[11] = {0}; // 9 digits, sign, and null terminator + unsigned char startIdx = 0; + + for (unsigned char i = 8; i >= u8DigsToCut; --i) { + int digit = 0; + while (s32Number >= powersOfTen[i]) { + s32Number -= powersOfTen[i]; + ++digit; } + U8NumBuff[8 - i] = '0' + digit; - while (u8Digts--) - { - *--pString = '0' + (s32Number % 10); - s32Number /= 10; + // We found the first non-zero digit + if (digit != 0 && startIdx == 0) + startIdx = 8 - i; + } + + // If the number was 0, we write a single 0. + /* if (startIdx == 0) + U8NumBuff[0] = '0'; */ + + // Print the string from the start index + if (u8FixedDigtsCnt) { + startIdx = 9 - u8DigsToCut - u8FixedDigtsCnt; + } + + const char *str = U8NumBuff + startIdx; + const char len = strlen(str); + const char dot[1] = {64}; + for (unsigned char i = 0; i < len; i++) { + if (pointAt == len - i) { + u16CoursorPosition++; + auto *pCoursorPosition = Bitmap.GetCoursorData(u16CoursorPosition); + memcpy(pCoursorPosition, dot, 1); + u16CoursorPosition++; } - - Print(U8NumBuff); - return u8Digts * pCurrentFont->GetSizeX('0'); - } - - static constexpr int powersOfTen[9] = { - 1, // 10^0 - 10, // 10^1 - 100, // 10^2 - 1000, // 10^3 - 10000, // 10^4 - 100000, // 10^5 - 1000000, // 10^6 - 10000000, // 10^7 - 100000000 // 10^8 - }; - void PrintFixedDigitsNumber2(int s32Number, unsigned char u8DigsToCut = 2, unsigned char u8FixedDigtsCnt = 0) - { - char U8NumBuff[11] = {0}; // 9 digits, sign, and null terminator - int startIdx = 0; - bool isNegative = false; - - if (s32Number < 0) - { - PrintCharacter('-'); - // U8NumBuff[0] = '-'; - s32Number = -s32Number; - // isNegative = true; - } - - for (int i = 8; i >= u8DigsToCut; --i) // assuming powersOfTen is an array of powers of 10 - { - int digit = 0; - while (s32Number >= powersOfTen[i]) - { - s32Number -= powersOfTen[i]; - ++digit; - } - U8NumBuff[isNegative + (8 - i)] = '0' + digit; - - // We found the first non-zero digit - if (digit != 0 && startIdx == (isNegative ? 1 : 0)) - startIdx = isNegative + (8 - i); - } - - // If the number was 0, we write a single 0. - if (startIdx == (isNegative ? 1 : 0)) - U8NumBuff[isNegative] = '0'; - - // Print the string from the start index - if (u8FixedDigtsCnt) - { - startIdx = 9 - u8DigsToCut - u8FixedDigtsCnt; - } - - Print(U8NumBuff + startIdx); - } + PrintCharacter(str[i]); + } + } private: - const BitmapType &Bitmap; - mutable const IFont *pCurrentFont; - mutable unsigned short u16CoursorPosition; + const BitmapType &Bitmap; + mutable const IFont *pCurrentFont; + mutable unsigned short u16CoursorPosition; }; diff --git a/src/spectrum_fagci/spectrum.hpp b/src/spectrum_fagci/spectrum.hpp index 25a85da..508e35b 100644 --- a/src/spectrum_fagci/spectrum.hpp +++ b/src/spectrum_fagci/spectrum.hpp @@ -82,22 +82,25 @@ public: void DrawNums() { Display.SetCoursorXY(0, 0); - Display.PrintFixedDigitsNumber2(scanDelay, 0); + Display.PrintFixedDigitsNumber3(scanDelay, 2, 2, 1); - Display.SetCoursorXY(51, 0); - Display.PrintFixedDigitsNumber2(GetBW()); + Display.SetCoursorXY(112, 0); + Display.PrintFixedDigitsNumber3(GetBW(), 4, 2, 1); /* Display.SetCoursorXY(0, 0); Display.PrintFixedDigitsNumber2(rssiMinV, 0); */ - Display.SetCoursorXY(86, 0); - Display.PrintFixedDigitsNumber2(peakF); + Display.SetCoursorXY(44, 0); + Display.PrintFixedDigitsNumber3(peakF, 2, 6, 3); - Display.SetCoursorXY(44, 48); - Display.PrintFixedDigitsNumber2(currentFreq); + Display.SetCoursorXY(0, 48); + Display.PrintFixedDigitsNumber3(GetFStart(), 4, 4, 1); - Display.SetCoursorXY(100, 48); - Display.PrintFixedDigitsNumber2(frequencyChangeStep); + Display.SetCoursorXY(98, 48); + Display.PrintFixedDigitsNumber3(GetFEnd(), 4, 4, 1); + + Display.SetCoursorXY(57, 48); + Display.PrintFixedDigitsNumber3(frequencyChangeStep, 4, 2, 1); /* Display.SetCoursorXY(0, 8); Display.PrintFixedDigitsNumber2(rssiMaxV, 0); */ @@ -112,7 +115,7 @@ public: void DrawTicks() { // center - gDisplayBuffer[BarPos + 64] = 0b10101000; + gDisplayBuffer[BarPos + 64] = 0b00111000; } void DrawArrow(u8 x) { @@ -126,11 +129,11 @@ public: void OnKey(u8 key) { switch (key) { - case 3: + case 14: UpdateRssiTriggerLevel(1); DelayMs(90); break; - case 9: + case 15: UpdateRssiTriggerLevel(-1); DelayMs(90); break; @@ -151,18 +154,18 @@ public: rssiMin = 255; } break; - case 2: + case 3: UpdateBWMul(1); resetBlacklist = true; break; - case 8: + case 9: UpdateBWMul(-1); resetBlacklist = true; break; - case 14: + case 2: UpdateFreqChangeStep(100_KHz); break; - case 15: + case 8: UpdateFreqChangeStep(-100_KHz); break; case 11: // up @@ -307,6 +310,7 @@ private: u16 GetScanStep() { return 25_KHz >> (2 >> bwMul); } u32 GetBW() { return 200_KHz << bwMul; } u32 GetFStart() { return currentFreq - (100_KHz << bwMul); } + u32 GetFEnd() { return currentFreq + (100_KHz << bwMul); } u8 BWMul2XDiv() { return clamp(4 - bwMul, 0, 2); } u8 GetMeasurementsCount() {