From ff94030fcf44e2057ec8721c28d0140a78c37cd8 Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Mon, 22 Jan 2024 18:54:13 +0100 Subject: [PATCH 1/2] applied google's clang format --- .clang-format | 258 +++++++++ src/AlphaNumeric.cpp | 1207 +++++++++++++++++++----------------------- src/AlphaNumeric.h | 84 +-- src/Config.cpp | 35 +- src/DMD.cpp | 804 ++++++++++++++-------------- src/FrameUtil.cpp | 459 ++++++++-------- src/FrameUtil.h | 65 +-- src/Logger.cpp | 38 +- src/Logger.h | 14 +- src/Pixelcade.cpp | 479 ++++++++--------- src/Pixelcade.h | 101 ++-- src/Serum.cpp | 146 +++-- src/Serum.h | 54 +- src/test.cpp | 142 +++-- 14 files changed, 2023 insertions(+), 1863 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..91e8793 --- /dev/null +++ b/.clang-format @@ -0,0 +1,258 @@ +--- +Language: Cpp +# BasedOnStyle: Google +AccessModifierOffset: -1 +AlignAfterOpenBracket: Align +AlignArrayOfStructures: None +AlignConsecutiveAssignments: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + PadOperators: true +AlignConsecutiveBitFields: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + PadOperators: false +AlignConsecutiveDeclarations: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + PadOperators: false +AlignConsecutiveMacros: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + PadOperators: false +AlignEscapedNewlines: Left +AlignOperands: Align +AlignTrailingComments: + Kind: Always + OverEmptyLines: 0 +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortEnumsOnASingleLine: true +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: WithoutElse +AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: Yes +AttributeMacros: + - __capability +BinPackArguments: true +BinPackParameters: true +BitFieldColonSpacing: Both +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterExternBlock: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakAfterAttributes: Never +BreakAfterJavaFieldAnnotations: false +BreakArrays: true +BreakBeforeBinaryOperators: None +BreakBeforeConceptDeclarations: Always +BreakBeforeBraces: Attach +BreakBeforeInlineASMColon: OnlyMultiline +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeColon +BreakInheritanceList: BeforeColon +BreakStringLiterals: true +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: true +DisableFormat: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IfMacros: + - KJ_IF_MAYBE +IncludeBlocks: Regroup +IncludeCategories: + - Regex: '^' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '^<.*\.h>' + Priority: 1 + SortPriority: 0 + CaseSensitive: false + - Regex: '^<.*' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '.*' + Priority: 3 + SortPriority: 0 + CaseSensitive: false +IncludeIsMainRegex: '([-_](test|unittest))?$' +IncludeIsMainSourceRegex: '' +IndentAccessModifiers: false +IndentCaseBlocks: false +IndentCaseLabels: true +IndentExternBlock: AfterExternBlock +IndentGotoLabels: true +IndentPPDirectives: None +IndentRequiresClause: true +IndentWidth: 2 +IndentWrappedFunctionNames: false +InsertBraces: false +InsertNewlineAtEOF: false +InsertTrailingCommas: None +IntegerLiteralSeparator: + Binary: 0 + BinaryMinDigits: 0 + Decimal: 0 + DecimalMinDigits: 0 + Hex: 0 + HexMinDigits: 0 +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +LambdaBodyIndentation: Signature +LineEnding: DeriveLF +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Never +ObjCBlockIndentWidth: 2 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PackConstructorInitializers: NextLine +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakOpenParenthesis: 0 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyIndentedWhitespace: 0 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Left +PPIndentWidth: -1 +QualifierAlignment: Leave +RawStringFormats: + - Language: Cpp + Delimiters: + - cc + - CC + - cpp + - Cpp + - CPP + - 'c++' + - 'C++' + CanonicalDelimiter: '' + BasedOnStyle: google + - Language: TextProto + Delimiters: + - pb + - PB + - proto + - PROTO + EnclosingFunctions: + - EqualsProto + - EquivToProto + - PARSE_PARTIAL_TEXT_PROTO + - PARSE_TEST_PROTO + - PARSE_TEXT_PROTO + - ParseTextOrDie + - ParseTextProtoOrDie + - ParseTestProto + - ParsePartialTestProto + CanonicalDelimiter: pb + BasedOnStyle: google +ReferenceAlignment: Pointer +ReflowComments: true +RemoveBracesLLVM: false +RemoveSemicolon: false +RequiresClausePosition: OwnLine +RequiresExpressionIndentation: OuterScope +SeparateDefinitionBlocks: Leave +ShortNamespaceLines: 1 +SortIncludes: CaseSensitive +SortJavaStaticImport: Before +SortUsingDeclarations: LexicographicNumeric +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceAroundPointerQualifiers: Default +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeParensOptions: + AfterControlStatements: true + AfterForeachMacros: true + AfterFunctionDefinitionName: false + AfterFunctionDeclarationName: false + AfterIfMacros: true + AfterOverloadedOperator: false + AfterRequiresInClause: false + AfterRequiresInExpression: false + BeforeNonEmptyParentheses: false +SpaceBeforeRangeBasedForLoopColon: true +SpaceBeforeSquareBrackets: false +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: Never +SpacesInConditionalStatement: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: -1 +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Auto +StatementAttributeLikeMacros: + - Q_EMIT +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseTab: Never +WhitespaceSensitiveMacros: + - BOOST_PP_STRINGIZE + - CF_SWIFT_NAME + - NS_SWIFT_NAME + - PP_STRINGIZE + - STRINGIZE +... diff --git a/src/AlphaNumeric.cpp b/src/AlphaNumeric.cpp index 0fa62e7..bd259db 100644 --- a/src/AlphaNumeric.cpp +++ b/src/AlphaNumeric.cpp @@ -12,703 +12,612 @@ namespace DMDUtil { const uint8_t AlphaNumeric::SegSizes[8][16] = { - {5,5,5,5,5,5,2,2,5,5,5,2,5,5,5,1}, - {5,5,5,5,5,5,5,2,0,0,0,0,0,0,0,0}, - {5,5,5,5,5,5,5,2,5,5,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, - {5,2,2,5,2,2,5,2,0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, - {5,5,5,5,5,5,3,2,5,5,5,3,5,5,5,1} -}; + {5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 2, 5, 5, 5, 1}, + {5, 5, 5, 5, 5, 5, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0}, + {5, 5, 5, 5, 5, 5, 5, 2, 5, 5, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {5, 2, 2, 5, 2, 2, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {5, 5, 5, 5, 5, 5, 3, 2, 5, 5, 5, 3, 5, 5, 5, 1}}; const uint8_t AlphaNumeric::Segs[8][17][5][2] = { - /* alphanumeric display characters */ - { - {{1,0},{2,0},{3,0},{4,0},{5,0}}, // 0 top - {{6,0},{6,1},{6,2},{6,3},{6,4}}, // 1 right top - {{6,6},{6,7},{6,8},{6,9},{6,10}}, // 2 right bottom - {{1,10},{2,10},{3,10},{4,10},{5,10}}, // 3 bottom - {{0,6},{0,7},{0,8},{0,9},{0,10}}, // 4 left bottom - {{0,0},{0,1},{0,2},{0,3},{0,4}}, // 5 left top - {{1,5},{2,5},{0,0},{0,0},{0,0}}, // 6 middle left - {{7,9},{7,10},{0,0},{0,0},{0,0}}, // 7 comma - {{0,0},{1,1},{1,2},{2,3},{2,4}}, // 8 diag top left - {{3,0},{3,1},{3,2},{3,3},{3,4}}, // 9 center top - {{6,0},{5,1},{5,2},{4,3},{4,4}}, // 10 diag top right - {{4,5},{5,5},{0,0},{0,0},{0,0}}, // 11 middle right - {{4,6},{4,7},{5,8},{5,9},{6,10}}, // 12 diag bottom right - {{3,6},{3,7},{3,8},{3,9},{3,10}}, // 13 center bottom - {{0,10},{2,6},{2,7},{1,8},{1,9}}, // 14 diag bottom left - {{7,10},{0,0},{0,0},{0,0},{0,0}} // 15 period - }, - /* 8 segment LED characters */ - { - {{1,0},{2,0},{3,0},{4,0},{5,0}}, // 0 top - {{6,0},{6,1},{6,2},{6,3},{6,4}}, // 1 right top - {{6,6},{6,7},{6,8},{6,9},{6,10}}, // 2 right bottom - {{1,10},{2,10},{3,10},{4,10},{5,10}}, // 3 bottom - {{0,6},{0,7},{0,8},{0,9},{0,10}}, // 4 left bottom - {{0,0},{0,1},{0,2},{0,3},{0,4}}, // 5 left top - {{1,5},{2,5},{3,5},{4,5},{5,5}}, // 6 middle - {{7,9},{7,10},{0,0},{0,0},{0,0}}, // 7 comma - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}} - }, - /* 10 segment LED characters */ - { - {{1,0},{2,0},{3,0},{4,0},{5,0}}, // 0 top - {{6,0},{6,1},{6,2},{6,3},{6,4}}, // 1 right top - {{6,6},{6,7},{6,8},{6,9},{6,10}}, // 2 right bottom - {{1,10},{2,10},{3,10},{4,10},{5,10}}, // 3 bottom - {{0,6},{0,7},{0,8},{0,9},{0,10}}, // 4 left bottom - {{0,0},{0,1},{0,2},{0,3},{0,4}}, // 5 left top - {{1,5},{2,5},{3,5},{4,5},{5,5}}, // 6 middle - {{7,9},{7,10},{0,0},{0,0},{0,0}}, // 7 comma - {{3,0},{3,1},{3,2},{3,3},{3,4}}, // 8 diag top - {{3,6},{3,7},{3,8},{3,9},{3,10}}, // 9 diag bottom - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}} - }, - /* alphanumeric display characters (reversed comma with period) */ - { - {{1,0},{2,0},{3,0},{4,0},{5,0}}, - {{6,0},{6,1},{6,2},{6,3},{6,4}}, - {{6,6},{6,7},{6,8},{6,9},{6,10}}, - {{1,10},{2,10},{3,10},{4,10},{5,10}}, - {{0,6},{0,7},{0,8},{0,9},{0,10}}, - {{0,0},{0,1},{0,2},{0,3},{0,4}}, - {{1,5},{2,5},{0,0},{0,0},{0,0}}, - {{7,9},{7,10},{0,0},{0,0},{0,0}}, - {{0,0},{1,1},{1,2},{2,3},{2,4}}, - {{3,0},{3,1},{3,2},{3,3},{3,4}}, - {{6,0},{5,1},{5,2},{4,3},{4,4}}, - {{4,5},{5,5},{0,0},{0,0},{0,0}}, - {{4,6},{4,7},{5,8},{5,9},{6,10}}, - {{3,6},{3,7},{3,8},{3,9},{3,10}}, - {{0,10},{2,6},{2,7},{1,8},{1,9}}, - {{7,10},{0,0},{0,0},{0,0},{0,0}} - }, - /* 8 segment LED characters with dots instead of commas */ - { - {{1,0},{2,0},{3,0},{4,0},{5,0}}, - {{6,0},{6,1},{6,2},{6,3},{6,4}}, - {{6,6},{6,7},{6,8},{6,9},{6,10}}, - {{1,10},{2,10},{3,10},{4,10},{5,10}}, - {{0,6},{0,7},{0,8},{0,9},{0,10}}, - {{0,0},{0,1},{0,2},{0,3},{0,4}}, - {{1,5},{2,5},{3,5},{4,5},{5,5}}, - {{7,9},{7,10},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}} - }, - /* 8 segment LED characters SMALL */ - { - {{1,0},{2,0},{3,0},{4,0},{5,0}}, // 0 top - {{6,1},{6,2},{0,0},{0,0},{0,0}}, // 1 top right - {{6,4},{6,5},{0,0},{0,0},{0,0}}, // 2 bottom right - {{1,6},{2,6},{3,6},{4,6},{5,6}}, // 3 bottom - {{0,4},{0,5},{0,0},{0,0},{0,0}}, // 4 bottom left - {{0,1},{0,2},{0,0},{0,0},{0,0}}, // 5 top left - {{1,3},{2,3},{3,3},{4,3},{5,3}}, // 6 middle - {{7,5},{7,6},{0,0},{0,0},{0,0}}, // 7 commy - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}} - }, - /* 10 segment LED characters SMALL */ - { - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}}, - {{0,0},{0,0},{0,0},{0,0},{0,0}} - }, - /* alphanumeric display characters 6pixel width*/ - { - {{0,0},{1,0},{2,0},{3,0},{4,0}}, - {{4,0},{4,1},{4,2},{4,3},{4,4}}, - {{4,6},{4,7},{4,8},{4,9},{4,10}}, - {{0,10},{1,10},{2,10},{3,10},{4,10}}, - {{0,6},{0,7},{0,8},{0,9},{0,10}}, - {{0,0},{0,1},{0,2},{0,3},{0,4}}, - {{0,5},{1,5},{2,5},{0,0},{0,0}}, - {{5,9},{5,10},{0,0},{0,0},{0,0}}, - {{0,0},{1,1},{1,2},{2,3},{2,4}}, - {{2,0},{2,1},{2,2},{2,3},{2,4}}, - {{4,0},{3,1},{3,2},{2,3},{2,4}}, - {{2,5},{3,5},{4,5},{0,0},{0,0}}, - {{2,6},{2,7},{3,8},{3,9},{4,10}}, - {{2,6},{2,7},{2,8},{2,9},{2,10}}, - {{0,10},{2,6},{2,7},{1,8},{1,9}}, - {{5,10},{0,0},{0,0},{0,0},{0,0}} - } -}; - -AlphaNumeric::AlphaNumeric() -{ - memset(m_frameBuffer, 0, sizeof(m_frameBuffer)); + /* alphanumeric display characters */ + { + {{1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}}, // 0 top + {{6, 0}, {6, 1}, {6, 2}, {6, 3}, {6, 4}}, // 1 right top + {{6, 6}, {6, 7}, {6, 8}, {6, 9}, {6, 10}}, // 2 right bottom + {{1, 10}, {2, 10}, {3, 10}, {4, 10}, {5, 10}}, // 3 bottom + {{0, 6}, {0, 7}, {0, 8}, {0, 9}, {0, 10}}, // 4 left bottom + {{0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}}, // 5 left top + {{1, 5}, {2, 5}, {0, 0}, {0, 0}, {0, 0}}, // 6 middle left + {{7, 9}, {7, 10}, {0, 0}, {0, 0}, {0, 0}}, // 7 comma + {{0, 0}, {1, 1}, {1, 2}, {2, 3}, {2, 4}}, // 8 diag top left + {{3, 0}, {3, 1}, {3, 2}, {3, 3}, {3, 4}}, // 9 center top + {{6, 0}, {5, 1}, {5, 2}, {4, 3}, {4, 4}}, // 10 diag top right + {{4, 5}, {5, 5}, {0, 0}, {0, 0}, {0, 0}}, // 11 middle right + {{4, 6}, {4, 7}, {5, 8}, {5, 9}, {6, 10}}, // 12 diag bottom right + {{3, 6}, {3, 7}, {3, 8}, {3, 9}, {3, 10}}, // 13 center bottom + {{0, 10}, {2, 6}, {2, 7}, {1, 8}, {1, 9}}, // 14 diag bottom left + {{7, 10}, {0, 0}, {0, 0}, {0, 0}, {0, 0}} // 15 period + }, + /* 8 segment LED characters */ + {{{1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}}, // 0 top + {{6, 0}, {6, 1}, {6, 2}, {6, 3}, {6, 4}}, // 1 right top + {{6, 6}, {6, 7}, {6, 8}, {6, 9}, {6, 10}}, // 2 right bottom + {{1, 10}, {2, 10}, {3, 10}, {4, 10}, {5, 10}}, // 3 bottom + {{0, 6}, {0, 7}, {0, 8}, {0, 9}, {0, 10}}, // 4 left bottom + {{0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}}, // 5 left top + {{1, 5}, {2, 5}, {3, 5}, {4, 5}, {5, 5}}, // 6 middle + {{7, 9}, {7, 10}, {0, 0}, {0, 0}, {0, 0}}, // 7 comma + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}}, + /* 10 segment LED characters */ + {{{1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}}, // 0 top + {{6, 0}, {6, 1}, {6, 2}, {6, 3}, {6, 4}}, // 1 right top + {{6, 6}, {6, 7}, {6, 8}, {6, 9}, {6, 10}}, // 2 right bottom + {{1, 10}, {2, 10}, {3, 10}, {4, 10}, {5, 10}}, // 3 bottom + {{0, 6}, {0, 7}, {0, 8}, {0, 9}, {0, 10}}, // 4 left bottom + {{0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}}, // 5 left top + {{1, 5}, {2, 5}, {3, 5}, {4, 5}, {5, 5}}, // 6 middle + {{7, 9}, {7, 10}, {0, 0}, {0, 0}, {0, 0}}, // 7 comma + {{3, 0}, {3, 1}, {3, 2}, {3, 3}, {3, 4}}, // 8 diag top + {{3, 6}, {3, 7}, {3, 8}, {3, 9}, {3, 10}}, // 9 diag bottom + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}}, + /* alphanumeric display characters (reversed comma with period) */ + {{{1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}}, + {{6, 0}, {6, 1}, {6, 2}, {6, 3}, {6, 4}}, + {{6, 6}, {6, 7}, {6, 8}, {6, 9}, {6, 10}}, + {{1, 10}, {2, 10}, {3, 10}, {4, 10}, {5, 10}}, + {{0, 6}, {0, 7}, {0, 8}, {0, 9}, {0, 10}}, + {{0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}}, + {{1, 5}, {2, 5}, {0, 0}, {0, 0}, {0, 0}}, + {{7, 9}, {7, 10}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {1, 1}, {1, 2}, {2, 3}, {2, 4}}, + {{3, 0}, {3, 1}, {3, 2}, {3, 3}, {3, 4}}, + {{6, 0}, {5, 1}, {5, 2}, {4, 3}, {4, 4}}, + {{4, 5}, {5, 5}, {0, 0}, {0, 0}, {0, 0}}, + {{4, 6}, {4, 7}, {5, 8}, {5, 9}, {6, 10}}, + {{3, 6}, {3, 7}, {3, 8}, {3, 9}, {3, 10}}, + {{0, 10}, {2, 6}, {2, 7}, {1, 8}, {1, 9}}, + {{7, 10}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}}, + /* 8 segment LED characters with dots instead of commas */ + {{{1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}}, + {{6, 0}, {6, 1}, {6, 2}, {6, 3}, {6, 4}}, + {{6, 6}, {6, 7}, {6, 8}, {6, 9}, {6, 10}}, + {{1, 10}, {2, 10}, {3, 10}, {4, 10}, {5, 10}}, + {{0, 6}, {0, 7}, {0, 8}, {0, 9}, {0, 10}}, + {{0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}}, + {{1, 5}, {2, 5}, {3, 5}, {4, 5}, {5, 5}}, + {{7, 9}, {7, 10}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}}, + /* 8 segment LED characters SMALL */ + {{{1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}}, // 0 top + {{6, 1}, {6, 2}, {0, 0}, {0, 0}, {0, 0}}, // 1 top right + {{6, 4}, {6, 5}, {0, 0}, {0, 0}, {0, 0}}, // 2 bottom right + {{1, 6}, {2, 6}, {3, 6}, {4, 6}, {5, 6}}, // 3 bottom + {{0, 4}, {0, 5}, {0, 0}, {0, 0}, {0, 0}}, // 4 bottom left + {{0, 1}, {0, 2}, {0, 0}, {0, 0}, {0, 0}}, // 5 top left + {{1, 3}, {2, 3}, {3, 3}, {4, 3}, {5, 3}}, // 6 middle + {{7, 5}, {7, 6}, {0, 0}, {0, 0}, {0, 0}}, // 7 commy + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}}, + /* 10 segment LED characters SMALL */ + {{{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}}, + /* alphanumeric display characters 6pixel width*/ + {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}}, + {{4, 0}, {4, 1}, {4, 2}, {4, 3}, {4, 4}}, + {{4, 6}, {4, 7}, {4, 8}, {4, 9}, {4, 10}}, + {{0, 10}, {1, 10}, {2, 10}, {3, 10}, {4, 10}}, + {{0, 6}, {0, 7}, {0, 8}, {0, 9}, {0, 10}}, + {{0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}}, + {{0, 5}, {1, 5}, {2, 5}, {0, 0}, {0, 0}}, + {{5, 9}, {5, 10}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {1, 1}, {1, 2}, {2, 3}, {2, 4}}, + {{2, 0}, {2, 1}, {2, 2}, {2, 3}, {2, 4}}, + {{4, 0}, {3, 1}, {3, 2}, {2, 3}, {2, 4}}, + {{2, 5}, {3, 5}, {4, 5}, {0, 0}, {0, 0}}, + {{2, 6}, {2, 7}, {3, 8}, {3, 9}, {4, 10}}, + {{2, 6}, {2, 7}, {2, 8}, {2, 9}, {2, 10}}, + {{0, 10}, {2, 6}, {2, 7}, {1, 8}, {1, 9}}, + {{5, 10}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}}}; + +AlphaNumeric::AlphaNumeric() { + memset(m_frameBuffer, 0, sizeof(m_frameBuffer)); } -uint8_t* AlphaNumeric::Render(AlphaNumericLayout layout, const uint16_t* const seg_data) -{ - if (layout != AlphaNumericLayout::__2x7Num_2x7Num_10x1Num) - Render(layout, seg_data, nullptr); - else - Render(layout, seg_data, seg_data + 32); +uint8_t* AlphaNumeric::Render(AlphaNumericLayout layout, + const uint16_t* const seg_data) { + if (layout != AlphaNumericLayout::__2x7Num_2x7Num_10x1Num) + Render(layout, seg_data, nullptr); + else + Render(layout, seg_data, seg_data + 32); - return m_frameBuffer; + return m_frameBuffer; } -uint8_t* AlphaNumeric::Render(AlphaNumericLayout layout, const uint16_t* const seg_data, const uint16_t* const seg_data2) -{ - Clear(); - - switch (layout) { - case AlphaNumericLayout::__2x16Alpha: - Render2x16Alpha(seg_data); - break; - case AlphaNumericLayout::__2x20Alpha: - Render2x20Alpha(seg_data); - break; - case AlphaNumericLayout::__2x7Alpha_2x7Num: - Render2x7Alpha_2x7Num(seg_data); - break; - case AlphaNumericLayout::__2x7Alpha_2x7Num_4x1Num: - Render2x7Alpha_2x7Num_4x1Num(seg_data); - break; - case AlphaNumericLayout::__2x7Num_2x7Num_4x1Num: - Render2x7Num_2x7Num_4x1Num(seg_data); - break; - case AlphaNumericLayout::__2x7Num_2x7Num_10x1Num: - Render2x7Num_2x7Num_10x1Num(seg_data, seg_data2); - break; - case AlphaNumericLayout::__2x7Num_2x7Num_4x1Num_gen7: - Render2x7Num_2x7Num_4x1Num_gen7(seg_data); - break; - case AlphaNumericLayout::__2x7Num10_2x7Num10_4x1Num: - Render2x7Num10_2x7Num10_4x1Num(seg_data); - break; - case AlphaNumericLayout::__2x6Num_2x6Num_4x1Num: - Render2x6Num_2x6Num_4x1Num(seg_data); - break; - case AlphaNumericLayout::__2x6Num10_2x6Num10_4x1Num: - Render2x6Num10_2x6Num10_4x1Num(seg_data); - break; - case AlphaNumericLayout::__4x7Num10: - Render4x7Num10(seg_data); - break; - case AlphaNumericLayout::__6x4Num_4x1Num: - Render6x4Num_4x1Num(seg_data); - break; - case AlphaNumericLayout::__2x7Num_4x1Num_1x16Alpha: - Render2x7Num_4x1Num_1x16Alpha(seg_data); - break; - case AlphaNumericLayout::__1x16Alpha_1x16Num_1x7Num: - Render1x16Alpha_1x16Num_1x7Num(seg_data); - break; - case AlphaNumericLayout::__1x7Num_1x16Alpha_1x16Num: - Render1x7Num_1x16Alpha_1x16Num(seg_data); - break; - case AlphaNumericLayout::__1x16Alpha_1x16Num_1x7Num_1x4Num: - Render1x16Alpha_1x16Num_1x7Num_1x4Num(seg_data); - break; - default: - break; - } - - return m_frameBuffer; +uint8_t* AlphaNumeric::Render(AlphaNumericLayout layout, + const uint16_t* const seg_data, + const uint16_t* const seg_data2) { + Clear(); + + switch (layout) { + case AlphaNumericLayout::__2x16Alpha: + Render2x16Alpha(seg_data); + break; + case AlphaNumericLayout::__2x20Alpha: + Render2x20Alpha(seg_data); + break; + case AlphaNumericLayout::__2x7Alpha_2x7Num: + Render2x7Alpha_2x7Num(seg_data); + break; + case AlphaNumericLayout::__2x7Alpha_2x7Num_4x1Num: + Render2x7Alpha_2x7Num_4x1Num(seg_data); + break; + case AlphaNumericLayout::__2x7Num_2x7Num_4x1Num: + Render2x7Num_2x7Num_4x1Num(seg_data); + break; + case AlphaNumericLayout::__2x7Num_2x7Num_10x1Num: + Render2x7Num_2x7Num_10x1Num(seg_data, seg_data2); + break; + case AlphaNumericLayout::__2x7Num_2x7Num_4x1Num_gen7: + Render2x7Num_2x7Num_4x1Num_gen7(seg_data); + break; + case AlphaNumericLayout::__2x7Num10_2x7Num10_4x1Num: + Render2x7Num10_2x7Num10_4x1Num(seg_data); + break; + case AlphaNumericLayout::__2x6Num_2x6Num_4x1Num: + Render2x6Num_2x6Num_4x1Num(seg_data); + break; + case AlphaNumericLayout::__2x6Num10_2x6Num10_4x1Num: + Render2x6Num10_2x6Num10_4x1Num(seg_data); + break; + case AlphaNumericLayout::__4x7Num10: + Render4x7Num10(seg_data); + break; + case AlphaNumericLayout::__6x4Num_4x1Num: + Render6x4Num_4x1Num(seg_data); + break; + case AlphaNumericLayout::__2x7Num_4x1Num_1x16Alpha: + Render2x7Num_4x1Num_1x16Alpha(seg_data); + break; + case AlphaNumericLayout::__1x16Alpha_1x16Num_1x7Num: + Render1x16Alpha_1x16Num_1x7Num(seg_data); + break; + case AlphaNumericLayout::__1x7Num_1x16Alpha_1x16Num: + Render1x7Num_1x16Alpha_1x16Num(seg_data); + break; + case AlphaNumericLayout::__1x16Alpha_1x16Num_1x7Num_1x4Num: + Render1x16Alpha_1x16Num_1x7Num_1x4Num(seg_data); + break; + default: + break; + } + + return m_frameBuffer; } -void AlphaNumeric::SmoothDigitCorners(const int x, const int y) -{ - if (GetPixel(x, 1 + y) && GetPixel(1 + x, y)) - DrawPixel(0 + x, y, 0); - if (GetPixel(x + 6, 1 + y) && GetPixel(5 + x, y)) - DrawPixel(6 + x, y, 0); - if (GetPixel(x, 9 + y) && GetPixel(1 + x, 10 + y)) - DrawPixel(0 + x, 10 + y, 0); - if (GetPixel(x + 6, 9 + y) && GetPixel(5 + x, 10 + y)) - DrawPixel(6 + x, 10 + y, 0); +void AlphaNumeric::SmoothDigitCorners(const int x, const int y) { + if (GetPixel(x, 1 + y) && GetPixel(1 + x, y)) DrawPixel(0 + x, y, 0); + if (GetPixel(x + 6, 1 + y) && GetPixel(5 + x, y)) DrawPixel(6 + x, y, 0); + if (GetPixel(x, 9 + y) && GetPixel(1 + x, 10 + y)) + DrawPixel(0 + x, 10 + y, 0); + if (GetPixel(x + 6, 9 + y) && GetPixel(5 + x, 10 + y)) + DrawPixel(6 + x, 10 + y, 0); } -void AlphaNumeric::SmoothDigitCorners6Px(const int x, const int y) -{ - if (GetPixel(x, 1 + y) && GetPixel(1 + x, y)) - DrawPixel(0 + x, y, 0); - if (GetPixel(x + 4, 1 + y) && GetPixel(3 + x, y)) - DrawPixel(4 + x, y, 0); - if (GetPixel(x, 9 + y) && GetPixel(1 + x, 10 + y)) - DrawPixel(0 + x, 10 + y, 0); - if (GetPixel(x + 4, 9 + y) && GetPixel(3 + x, 10 + y)) - DrawPixel(4 + x, 10 + y, 0); +void AlphaNumeric::SmoothDigitCorners6Px(const int x, const int y) { + if (GetPixel(x, 1 + y) && GetPixel(1 + x, y)) DrawPixel(0 + x, y, 0); + if (GetPixel(x + 4, 1 + y) && GetPixel(3 + x, y)) DrawPixel(4 + x, y, 0); + if (GetPixel(x, 9 + y) && GetPixel(1 + x, 10 + y)) + DrawPixel(0 + x, 10 + y, 0); + if (GetPixel(x + 4, 9 + y) && GetPixel(3 + x, 10 + y)) + DrawPixel(4 + x, 10 + y, 0); } -void AlphaNumeric::DrawSegment(const int x, const int y, const uint8_t type, const uint16_t seg, const uint8_t colour) -{ - for (int i = 0; i < SegSizes[type][seg]; i++) - DrawPixel(Segs[type][seg][i][0] + x, Segs[type][seg][i][1] + y, colour); +void AlphaNumeric::DrawSegment(const int x, const int y, const uint8_t type, + const uint16_t seg, const uint8_t colour) { + for (int i = 0; i < SegSizes[type][seg]; i++) + DrawPixel(Segs[type][seg][i][0] + x, Segs[type][seg][i][1] + y, colour); } -bool AlphaNumeric::GetPixel(const int x, const int y) const -{ - return m_frameBuffer[y * 128 + x] > 0; +bool AlphaNumeric::GetPixel(const int x, const int y) const { + return m_frameBuffer[y * 128 + x] > 0; } -void AlphaNumeric::DrawPixel(const int x, const int y, const uint8_t colour) -{ - m_frameBuffer[y * 128 + x] = colour; +void AlphaNumeric::DrawPixel(const int x, const int y, const uint8_t colour) { + m_frameBuffer[y * 128 + x] = colour; } -void AlphaNumeric::Clear() -{ - memset(m_frameBuffer, 0, sizeof(m_frameBuffer)); +void AlphaNumeric::Clear() { memset(m_frameBuffer, 0, sizeof(m_frameBuffer)); } + +void AlphaNumeric::Render2x16Alpha(const uint16_t* const seg_data) { + for (int i = 0; i < 16; i++) { + for (int j = 0; j < 16; j++) { + if ((seg_data[i] >> j) & 0x1) DrawSegment(i * 8, 2, 0, j, 3); + if ((seg_data[i + 16] >> j) & 0x1) DrawSegment(i * 8, 19, 0, j, 3); + } + SmoothDigitCorners(i * 8, 2); + SmoothDigitCorners(i * 8, 19); + } } -void AlphaNumeric::Render2x16Alpha(const uint16_t* const seg_data) -{ - for (int i = 0; i < 16; i++) { - for (int j = 0; j < 16; j++) { - if ((seg_data[i] >> j) & 0x1) - DrawSegment(i * 8, 2, 0, j, 3); - if ((seg_data[i + 16] >> j) & 0x1) - DrawSegment(i * 8, 19, 0, j, 3); - } - SmoothDigitCorners(i * 8, 2); - SmoothDigitCorners(i * 8, 19); - } +void AlphaNumeric::Render2x20Alpha(const uint16_t* const seg_data) { + for (int i = 0; i < 20; i++) { + for (int j = 0; j < 16; j++) { + if ((seg_data[i] >> j) & 0x1) DrawSegment((i * 6) + 4, 2, 7, j, 3); + if ((seg_data[i + 20] >> j) & 0x1) DrawSegment((i * 6) + 4, 19, 7, j, 3); + } + SmoothDigitCorners6Px((i * 6) + 4, 2); + SmoothDigitCorners6Px((i * 6) + 4, 19); + } } -void AlphaNumeric::Render2x20Alpha(const uint16_t* const seg_data) -{ - for (int i = 0; i < 20; i++) { - for (int j = 0; j < 16; j++) { - if ((seg_data[i] >> j) & 0x1) - DrawSegment((i * 6) + 4, 2, 7, j, 3); - if ((seg_data[i + 20] >> j) & 0x1) - DrawSegment((i * 6) + 4, 19, 7, j, 3); - } - SmoothDigitCorners6Px((i * 6) + 4, 2); - SmoothDigitCorners6Px((i * 6) + 4, 19); - } +void AlphaNumeric::Render2x7Alpha_2x7Num(const uint16_t* const seg_data) { + for (int i = 0; i < 14; i++) { + for (int j = 0; j < 16; j++) { + // 2x7 alphanumeric + if ((seg_data[i] >> j) & 0x1) + DrawSegment((i + ((i < 7) ? 0 : 2)) * 8, 2, 0, j, 3); + // 2x7 numeric + if ((seg_data[i + 14] >> j) & 0x1) + DrawSegment((i + ((i < 7) ? 0 : 2)) * 8, 19, 1, j, 3); + } + SmoothDigitCorners((i + ((i < 7) ? 0 : 2)) * 8, 2); + SmoothDigitCorners((i + ((i < 7) ? 0 : 2)) * 8, 19); + } } -void AlphaNumeric::Render2x7Alpha_2x7Num(const uint16_t* const seg_data) -{ - for (int i = 0; i < 14; i++) { - for (int j = 0; j < 16; j++) { - // 2x7 alphanumeric - if ((seg_data[i] >> j) & 0x1) - DrawSegment((i + ((i < 7) ? 0 : 2)) * 8, 2, 0, j, 3); - // 2x7 numeric - if ((seg_data[i + 14] >> j) & 0x1) - DrawSegment((i + ((i < 7) ? 0 : 2)) * 8, 19, 1, j, 3); - } - SmoothDigitCorners((i + ((i < 7) ? 0 : 2)) * 8, 2); - SmoothDigitCorners((i + ((i < 7) ? 0 : 2)) * 8, 19); - } +void AlphaNumeric::Render2x7Alpha_2x7Num_4x1Num( + const uint16_t* const seg_data) { + for (int i = 0; i < 14; i++) { + for (int j = 0; j < 16; j++) { + // 2x7 alphanumeric + if ((seg_data[i] >> j) & 0x1) + DrawSegment((i + ((i < 7) ? 0 : 2)) * 8, 0, 0, j, 3); + // 2x7 numeric + if ((seg_data[i + 14] >> j) & 0x1) + DrawSegment((i + ((i < 7) ? 0 : 2)) * 8, 21, 1, j, 3); + } + SmoothDigitCorners((i + ((i < 7) ? 0 : 2)) * 8, 0); + SmoothDigitCorners((i + ((i < 7) ? 0 : 2)) * 8, 21); + } + // 4x1 numeric small + for (int j = 0; j < 16; j++) { + if ((seg_data[28] >> j) & 0x1) DrawSegment(8, 12, 5, j, 3); + if ((seg_data[29] >> j) & 0x1) DrawSegment(16, 12, 5, j, 3); + if ((seg_data[30] >> j) & 0x1) DrawSegment(32, 12, 5, j, 3); + if ((seg_data[31] >> j) & 0x1) DrawSegment(40, 12, 5, j, 3); + } } -void AlphaNumeric::Render2x7Alpha_2x7Num_4x1Num(const uint16_t* const seg_data) -{ - for (int i = 0; i < 14; i++) { - for (int j = 0; j < 16; j++) { - // 2x7 alphanumeric - if ((seg_data[i] >> j) & 0x1) - DrawSegment((i + ((i < 7) ? 0 : 2)) * 8, 0, 0, j, 3); - // 2x7 numeric - if ((seg_data[i + 14] >> j) & 0x1) - DrawSegment((i + ((i < 7) ? 0 : 2)) * 8, 21, 1, j, 3); - } - SmoothDigitCorners((i + ((i < 7) ? 0 : 2)) * 8, 0); - SmoothDigitCorners((i + ((i < 7) ? 0 : 2)) * 8, 21); - } - // 4x1 numeric small - for (int j = 0; j < 16; j++) { - if ((seg_data[28] >> j) & 0x1) - DrawSegment(8, 12, 5, j, 3); - if ((seg_data[29] >> j) & 0x1) - DrawSegment(16, 12, 5, j, 3); - if ((seg_data[30] >> j) & 0x1) - DrawSegment(32, 12, 5, j, 3); - if ((seg_data[31] >> j) & 0x1) - DrawSegment(40, 12, 5, j, 3); - } +void AlphaNumeric::Render2x6Num_2x6Num_4x1Num(const uint16_t* const seg_data) { + for (int i = 0; i < 12; i++) { + for (int j = 0; j < 16; j++) { + // 2x6 numeric + if ((seg_data[i] >> j) & 0x1) + DrawSegment((i + ((i < 6) ? 0 : 4)) * 8, 0, 1, j, 3); + + // 2x6 numeric + if ((seg_data[i + 12] >> j) & 0x1) + DrawSegment((i + ((i < 6) ? 0 : 4)) * 8, 12, 1, j, 3); + } + SmoothDigitCorners((i + ((i < 6) ? 0 : 4)) * 8, 0); + SmoothDigitCorners((i + ((i < 6) ? 0 : 4)) * 8, 12); + } + // 4x1 numeric small + for (int j = 0; j < 16; j++) { + if ((seg_data[24] >> j) & 0x1) DrawSegment(8, 24, 5, j, 3); + if ((seg_data[25] >> j) & 0x1) DrawSegment(16, 24, 5, j, 3); + if ((seg_data[26] >> j) & 0x1) DrawSegment(32, 24, 5, j, 3); + if ((seg_data[27] >> j) & 0x1) DrawSegment(40, 24, 5, j, 3); + } } -void AlphaNumeric::Render2x6Num_2x6Num_4x1Num(const uint16_t* const seg_data) -{ - for (int i = 0; i < 12; i++) { - for (int j = 0; j < 16; j++) { - // 2x6 numeric - if ((seg_data[i] >> j) & 0x1) - DrawSegment((i + ((i < 6) ? 0 : 4)) * 8, 0, 1, j, 3); - - // 2x6 numeric - if ((seg_data[i + 12] >> j) & 0x1) - DrawSegment((i + ((i < 6) ? 0 : 4)) * 8, 12, 1, j, 3); - } - SmoothDigitCorners((i + ((i < 6) ? 0 : 4)) * 8, 0); - SmoothDigitCorners((i + ((i < 6) ? 0 : 4)) * 8, 12); - } - // 4x1 numeric small - for (int j = 0; j < 16; j++) { - if ((seg_data[24] >> j) & 0x1) - DrawSegment(8, 24, 5, j, 3); - if ((seg_data[25] >> j) & 0x1) - DrawSegment(16, 24, 5, j, 3); - if ((seg_data[26] >> j) & 0x1) - DrawSegment(32, 24, 5, j, 3); - if ((seg_data[27] >> j) & 0x1) - DrawSegment(40, 24, 5, j, 3); - } +void AlphaNumeric::Render2x6Num10_2x6Num10_4x1Num( + const uint16_t* const seg_data) { + for (int i = 0; i < 12; i++) { + for (int j = 0; j < 16; j++) { + // 2x6 numeric + if ((seg_data[i] >> j) & 0x1) + DrawSegment((i + ((i < 6) ? 0 : 4)) * 8, 0, 2, j, 3); + // 2x6 numeric + if ((seg_data[i + 12] >> j) & 0x1) + DrawSegment((i + ((i < 6) ? 0 : 4)) * 8, 20, 2, j, 3); + } + SmoothDigitCorners((i + ((i < 6) ? 0 : 4)) * 8, 0); + SmoothDigitCorners((i + ((i < 6) ? 0 : 4)) * 8, 20); + } + // 4x1 numeric small + for (int j = 0; j < 16; j++) { + if ((seg_data[24] >> j) & 0x1) DrawSegment(8, 12, 5, j, 3); + if ((seg_data[25] >> j) & 0x1) DrawSegment(16, 12, 5, j, 3); + if ((seg_data[26] >> j) & 0x1) DrawSegment(32, 12, 5, j, 3); + if ((seg_data[27] >> j) & 0x1) DrawSegment(40, 12, 5, j, 3); + } } -void AlphaNumeric::Render2x6Num10_2x6Num10_4x1Num(const uint16_t* const seg_data) -{ - for (int i = 0; i < 12; i++) { - for (int j = 0; j < 16; j++) { - // 2x6 numeric - if ((seg_data[i] >> j) & 0x1) - DrawSegment((i + ((i < 6) ? 0 : 4)) * 8, 0, 2, j, 3); - // 2x6 numeric - if ((seg_data[i + 12] >> j) & 0x1) - DrawSegment((i + ((i < 6) ? 0 : 4)) * 8, 20, 2, j, 3); - } - SmoothDigitCorners((i + ((i < 6) ? 0 : 4)) * 8, 0); - SmoothDigitCorners((i + ((i < 6) ? 0 : 4)) * 8, 20); - } - // 4x1 numeric small - for (int j = 0; j < 16; j++) { - if ((seg_data[24] >> j) & 0x1) - DrawSegment(8, 12, 5, j, 3); - if ((seg_data[25] >> j) & 0x1) - DrawSegment(16, 12, 5, j, 3); - if ((seg_data[26] >> j) & 0x1) - DrawSegment(32, 12, 5, j, 3); - if ((seg_data[27] >> j) & 0x1) - DrawSegment(40, 12, 5, j, 3); - } +void AlphaNumeric::Render2x7Num_2x7Num_4x1Num(const uint16_t* const seg_data) { + for (int i = 0; i < 14; i++) { + for (int j = 0; j < 16; j++) { + // 2x7 numeric + if ((seg_data[i] >> j) & 0x1) + DrawSegment((i + ((i < 7) ? 0 : 2)) * 8, 0, 1, j, 3); + // 2x7 numeric + if ((seg_data[i + 14] >> j) & 0x1) + DrawSegment((i + ((i < 7) ? 0 : 2)) * 8, 12, 1, j, 3); + } + SmoothDigitCorners((i + ((i < 7) ? 0 : 2)) * 8, 0); + SmoothDigitCorners((i + ((i < 7) ? 0 : 2)) * 8, 12); + } + // 4x1 numeric small + for (int j = 0; j < 16; j++) { + if ((seg_data[28] >> j) & 0x1) DrawSegment(16, 24, 5, j, 3); + if ((seg_data[29] >> j) & 0x1) DrawSegment(24, 24, 5, j, 3); + if ((seg_data[30] >> j) & 0x1) DrawSegment(40, 24, 5, j, 3); + if ((seg_data[31] >> j) & 0x1) DrawSegment(48, 24, 5, j, 3); + } } -void AlphaNumeric::Render2x7Num_2x7Num_4x1Num(const uint16_t* const seg_data) -{ - for (int i = 0; i < 14; i++) { - for (int j = 0; j < 16; j++) { - // 2x7 numeric - if ((seg_data[i] >> j) & 0x1) - DrawSegment((i + ((i < 7) ? 0 : 2)) * 8, 0, 1, j, 3); - // 2x7 numeric - if ((seg_data[i + 14] >> j) & 0x1) - DrawSegment((i + ((i < 7) ? 0 : 2)) * 8, 12, 1, j, 3); - } - SmoothDigitCorners((i + ((i < 7) ? 0 : 2)) * 8, 0); - SmoothDigitCorners((i + ((i < 7) ? 0 : 2)) * 8, 12); - } - // 4x1 numeric small - for (int j = 0; j < 16; j++) { - if ((seg_data[28] >> j) & 0x1) - DrawSegment(16, 24, 5, j, 3); - if ((seg_data[29] >> j) & 0x1) - DrawSegment(24, 24, 5, j, 3); - if ((seg_data[30] >> j) & 0x1) - DrawSegment(40, 24, 5, j, 3); - if ((seg_data[31] >> j) & 0x1) - DrawSegment(48, 24, 5, j, 3); - } +void AlphaNumeric::Render2x7Num_2x7Num_10x1Num( + const uint16_t* const seg_data, const uint16_t* const extra_seg_data) { + for (int i = 0; i < 14; i++) { + for (int j = 0; j < 16; j++) { + // 2x7 numeric + if ((seg_data[i] >> j) & 0x1) + DrawSegment((i + ((i < 7) ? 0 : 2)) * 8, 0, 1, j, 3); + // 2x7 numeric + if ((seg_data[i + 14] >> j) & 0x1) + DrawSegment((i + ((i < 7) ? 0 : 2)) * 8, 12, 1, j, 3); + } + SmoothDigitCorners((i + ((i < 7) ? 0 : 2)) * 8, 0); + SmoothDigitCorners((i + ((i < 7) ? 0 : 2)) * 8, 12); + } + // 10x1 numeric small + for (int j = 0; j < 16; j++) { + if ((seg_data[28] >> j) & 0x1) DrawSegment(16, 24, 5, j, 3); + if ((seg_data[29] >> j) & 0x1) DrawSegment(24, 24, 5, j, 3); + if ((seg_data[30] >> j) & 0x1) DrawSegment(40, 24, 5, j, 3); + if ((seg_data[31] >> j) & 0x1) DrawSegment(48, 24, 5, j, 3); + if ((extra_seg_data[0] >> j) & 0x1) DrawSegment(64, 24, 5, j, 3); + if ((extra_seg_data[1] >> j) & 0x1) DrawSegment(72, 24, 5, j, 3); + if ((extra_seg_data[2] >> j) & 0x1) DrawSegment(88, 24, 5, j, 3); + if ((extra_seg_data[3] >> j) & 0x1) DrawSegment(96, 24, 5, j, 3); + if ((extra_seg_data[4] >> j) & 0x1) DrawSegment(112, 24, 5, j, 3); + if ((extra_seg_data[5] >> j) & 0x1) DrawSegment(120, 24, 5, j, 3); + } } -void AlphaNumeric::Render2x7Num_2x7Num_10x1Num(const uint16_t* const seg_data, const uint16_t* const extra_seg_data) -{ - for (int i = 0; i < 14; i++) { - for (int j = 0; j < 16; j++) { - // 2x7 numeric - if ((seg_data[i] >> j) & 0x1) - DrawSegment((i + ((i < 7) ? 0 : 2)) * 8, 0, 1, j, 3); - // 2x7 numeric - if ((seg_data[i + 14] >> j) & 0x1) - DrawSegment((i + ((i < 7) ? 0 : 2)) * 8, 12, 1, j, 3); - } - SmoothDigitCorners((i + ((i < 7) ? 0 : 2)) * 8, 0); - SmoothDigitCorners((i + ((i < 7) ? 0 : 2)) * 8, 12); - } - // 10x1 numeric small - for (int j = 0; j < 16; j++) { - if ((seg_data[28] >> j) & 0x1) - DrawSegment(16, 24, 5, j, 3); - if ((seg_data[29] >> j) & 0x1) - DrawSegment(24, 24, 5, j, 3); - if ((seg_data[30] >> j) & 0x1) - DrawSegment(40, 24, 5, j, 3); - if ((seg_data[31] >> j) & 0x1) - DrawSegment(48, 24, 5, j, 3); - if ((extra_seg_data[0] >> j) & 0x1) - DrawSegment(64, 24, 5, j, 3); - if ((extra_seg_data[1] >> j) & 0x1) - DrawSegment(72, 24, 5, j, 3); - if ((extra_seg_data[2] >> j) & 0x1) - DrawSegment(88, 24, 5, j, 3); - if ((extra_seg_data[3] >> j) & 0x1) - DrawSegment(96, 24, 5, j, 3); - if ((extra_seg_data[4] >> j) & 0x1) - DrawSegment(112, 24, 5, j, 3); - if ((extra_seg_data[5] >> j) & 0x1) - DrawSegment(120, 24, 5, j, 3); - } +void AlphaNumeric::Render2x7Num_2x7Num_4x1Num_gen7( + const uint16_t* const seg_data) { + for (int i = 0; i < 14; i++) { + for (int j = 0; j < 16; j++) { + // 2x7 numeric + if ((seg_data[i] >> j) & 0x1) + DrawSegment((i + ((i < 7) ? 0 : 2)) * 8, 21, 1, j, 3); + // 2x7 numeric + if ((seg_data[i + 14] >> j) & 0x1) + DrawSegment((i + ((i < 7) ? 0 : 2)) * 8, 1, 1, j, 3); + } + SmoothDigitCorners((i + ((i < 7) ? 0 : 2)) * 8, 21); + SmoothDigitCorners((i + ((i < 7) ? 0 : 2)) * 8, 1); + } + // 4x1 numeric small + for (int j = 0; j < 16; j++) { + if ((seg_data[28] >> j) & 0x1) DrawSegment(8, 13, 5, j, 3); + if ((seg_data[29] >> j) & 0x1) DrawSegment(16, 13, 5, j, 3); + if ((seg_data[30] >> j) & 0x1) DrawSegment(32, 13, 5, j, 3); + if ((seg_data[31] >> j) & 0x1) DrawSegment(40, 13, 5, j, 3); + } } -void AlphaNumeric::Render2x7Num_2x7Num_4x1Num_gen7(const uint16_t* const seg_data) -{ - for (int i = 0; i < 14; i++) { - for (int j = 0; j < 16; j++) { - // 2x7 numeric - if ((seg_data[i] >> j) & 0x1) - DrawSegment((i + ((i < 7) ? 0 : 2)) * 8, 21, 1, j, 3); - // 2x7 numeric - if ((seg_data[i + 14] >> j) & 0x1) - DrawSegment((i + ((i < 7) ? 0 : 2)) * 8, 1, 1, j, 3); - } - SmoothDigitCorners((i + ((i < 7) ? 0 : 2)) * 8, 21); - SmoothDigitCorners((i + ((i < 7) ? 0 : 2)) * 8, 1); - } - // 4x1 numeric small - for (int j = 0; j < 16; j++) { - if ((seg_data[28] >> j) & 0x1) - DrawSegment(8, 13, 5, j, 3); - if ((seg_data[29] >> j) & 0x1) - DrawSegment(16, 13, 5, j, 3); - if ((seg_data[30] >> j) & 0x1) - DrawSegment(32, 13, 5, j, 3); - if ((seg_data[31] >> j) & 0x1) - DrawSegment(40, 13, 5, j, 3); - } +void AlphaNumeric::Render2x7Num10_2x7Num10_4x1Num( + const uint16_t* const seg_data) { + for (int i = 0; i < 14; i++) { + for (int j = 0; j < 16; j++) { + // 2x7 numeric + if ((seg_data[i] >> j) & 0x1) + DrawSegment((i + ((i < 7) ? 0 : 2)) * 8, 0, 2, j, 3); + // 2x7 numeric + if ((seg_data[i + 14] >> j) & 0x1) + DrawSegment((i + ((i < 7) ? 0 : 2)) * 8, 20, 2, j, 3); + } + SmoothDigitCorners((i + ((i < 7) ? 0 : 2)) * 8, 0); + SmoothDigitCorners((i + ((i < 7) ? 0 : 2)) * 8, 20); + } + // 4x1 numeric small + for (int j = 0; j < 16; j++) { + if ((seg_data[28] >> j) & 0x1) DrawSegment(8, 12, 5, j, 3); + if ((seg_data[29] >> j) & 0x1) DrawSegment(16, 12, 5, j, 3); + if ((seg_data[30] >> j) & 0x1) DrawSegment(32, 12, 5, j, 3); + if ((seg_data[31] >> j) & 0x1) DrawSegment(40, 12, 5, j, 3); + } } -void AlphaNumeric::Render2x7Num10_2x7Num10_4x1Num(const uint16_t* const seg_data) -{ - for (int i = 0; i < 14; i++) { - for (int j = 0; j < 16; j++) { - // 2x7 numeric - if ((seg_data[i] >> j) & 0x1) - DrawSegment((i + ((i < 7) ? 0 : 2)) * 8, 0, 2, j, 3); - // 2x7 numeric - if ((seg_data[i + 14] >> j) & 0x1) - DrawSegment((i + ((i < 7) ? 0 : 2)) * 8, 20, 2, j, 3); - } - SmoothDigitCorners((i + ((i < 7) ? 0 : 2)) * 8, 0); - SmoothDigitCorners((i + ((i < 7) ? 0 : 2)) * 8, 20); - } - // 4x1 numeric small - for (int j = 0; j < 16; j++) { - if ((seg_data[28] >> j) & 0x1) - DrawSegment(8, 12, 5, j, 3); - if ((seg_data[29] >> j) & 0x1) - DrawSegment(16, 12, 5, j, 3); - if ((seg_data[30] >> j) & 0x1) - DrawSegment(32, 12, 5, j, 3); - if ((seg_data[31] >> j) & 0x1) - DrawSegment(40, 12, 5, j, 3); - } +void AlphaNumeric::Render4x7Num10(const uint16_t* const seg_data) { + for (int i = 0; i < 14; i++) { + for (int j = 0; j < 16; j++) { + // 2x7 numeric10 + if ((seg_data[i] >> j) & 0x1) + DrawSegment((i + ((i < 7) ? 0 : 2)) * 8, 1, 2, j, 3); + // 2x7 numeric10 + if ((seg_data[i + 14] >> j) & 0x1) + DrawSegment((i + ((i < 7) ? 0 : 2)) * 8, 13, 2, j, 3); + } + SmoothDigitCorners((i + ((i < 7) ? 0 : 2)) * 8, 1); + SmoothDigitCorners((i + ((i < 7) ? 0 : 2)) * 8, 13); + } } -void AlphaNumeric::Render4x7Num10(const uint16_t* const seg_data) -{ - for (int i = 0; i < 14; i++) { - for (int j = 0; j < 16; j++) { - // 2x7 numeric10 - if ((seg_data[i] >> j) & 0x1) - DrawSegment((i + ((i < 7) ? 0 : 2)) * 8, 1, 2, j, 3); - // 2x7 numeric10 - if ((seg_data[i + 14] >> j) & 0x1) - DrawSegment((i + ((i < 7) ? 0 : 2)) * 8, 13, 2, j, 3); - } - SmoothDigitCorners((i + ((i < 7) ? 0 : 2)) * 8, 1); - SmoothDigitCorners((i + ((i < 7) ? 0 : 2)) * 8, 13); - } +void AlphaNumeric::Render6x4Num_4x1Num(const uint16_t* const seg_data) { + for (int i = 0; i < 8; i++) { + for (int j = 0; j < 16; j++) { + // 2x4 numeric + if ((seg_data[i] >> j) & 0x1) + DrawSegment((i + ((i < 4) ? 0 : 2)) * 8, 1, 5, j, 3); + // 2x4 numeric + if ((seg_data[i + 8] >> j) & 0x1) + DrawSegment((i + ((i < 4) ? 0 : 2)) * 8, 9, 5, j, 3); + // 2x4 numeric + if ((seg_data[i + 16] >> j) & 0x1) + DrawSegment((i + ((i < 4) ? 0 : 2)) * 8, 17, 5, j, 3); + } + SmoothDigitCorners((i + ((i < 4) ? 0 : 2)) * 8, 1); + SmoothDigitCorners((i + ((i < 4) ? 0 : 2)) * 8, 9); + SmoothDigitCorners((i + ((i < 4) ? 0 : 2)) * 8, 17); + } + // 4x1 numeric small + for (int j = 0; j < 16; j++) { + if ((seg_data[24] >> j) & 0x1) DrawSegment(16, 25, 5, j, 3); + if ((seg_data[25] >> j) & 0x1) DrawSegment(24, 25, 5, j, 3); + if ((seg_data[26] >> j) & 0x1) DrawSegment(48, 25, 5, j, 3); + if ((seg_data[27] >> j) & 0x1) DrawSegment(56, 25, 5, j, 3); + } } -void AlphaNumeric::Render6x4Num_4x1Num(const uint16_t* const seg_data) -{ - for (int i = 0; i < 8; i++) { - for (int j = 0; j < 16; j++) { - // 2x4 numeric - if ((seg_data[i] >> j) & 0x1) - DrawSegment((i + ((i < 4) ? 0 : 2)) * 8, 1, 5, j, 3); - // 2x4 numeric - if ((seg_data[i + 8] >> j) & 0x1) - DrawSegment((i + ((i < 4) ? 0 : 2)) * 8, 9, 5, j, 3); - // 2x4 numeric - if ((seg_data[i + 16] >> j) & 0x1) - DrawSegment((i + ((i < 4) ? 0 : 2)) * 8, 17, 5, j, 3); - } - SmoothDigitCorners((i + ((i < 4) ? 0 : 2)) * 8, 1); - SmoothDigitCorners((i + ((i < 4) ? 0 : 2)) * 8, 9); - SmoothDigitCorners((i + ((i < 4) ? 0 : 2)) * 8, 17); - } - // 4x1 numeric small - for (int j = 0; j < 16; j++) { - if ((seg_data[24] >> j) & 0x1) - DrawSegment(16, 25, 5, j, 3); - if ((seg_data[25] >> j) & 0x1) - DrawSegment(24, 25, 5, j, 3); - if ((seg_data[26] >> j) & 0x1) - DrawSegment(48, 25, 5, j, 3); - if ((seg_data[27] >> j) & 0x1) - DrawSegment(56, 25, 5, j, 3); - } +void AlphaNumeric::Render2x7Num_4x1Num_1x16Alpha( + const uint16_t* const seg_data) { + for (int i = 0; i < 14; i++) { + for (int j = 0; j < 16; j++) { + // 2x7 numeric + if ((seg_data[i] >> j) & 0x1) + DrawSegment((i + ((i < 7) ? 0 : 2)) * 8, 0, 1, j, 3); + } + SmoothDigitCorners((i + ((i < 7) ? 0 : 2)) * 8, 0); + } + // 4x1 numeric small + for (int j = 0; j < 16; j++) { + if ((seg_data[14] >> j) & 0x1) DrawSegment(16, 12, 5, j, 3); + if ((seg_data[15] >> j) & 0x1) DrawSegment(24, 12, 5, j, 3); + if ((seg_data[16] >> j) & 0x1) DrawSegment(40, 12, 5, j, 3); + if ((seg_data[17] >> j) & 0x1) DrawSegment(48, 12, 5, j, 3); + } + // 1x16 alphanumeric + for (int i = 0; i < 12; i++) { + for (int j = 0; j < 16; j++) { + if ((seg_data[i + 18] >> j) & 0x1) DrawSegment((i * 8) + 16, 21, 0, j, 3); + } + SmoothDigitCorners((i * 8) + 16, 21); + } } -void AlphaNumeric::Render2x7Num_4x1Num_1x16Alpha(const uint16_t* const seg_data) -{ - for (int i = 0; i < 14; i++) { - for (int j = 0; j < 16; j++) { - // 2x7 numeric - if ((seg_data[i] >> j) & 0x1) - DrawSegment((i + ((i < 7) ? 0 : 2)) * 8, 0, 1, j, 3); - } - SmoothDigitCorners((i + ((i < 7) ? 0 : 2)) * 8, 0); - } - // 4x1 numeric small - for (int j = 0; j < 16; j++) { - if ((seg_data[14] >> j) & 0x1) - DrawSegment(16, 12, 5, j, 3); - if ((seg_data[15] >> j) & 0x1) - DrawSegment(24, 12, 5, j, 3); - if ((seg_data[16] >> j) & 0x1) - DrawSegment(40, 12, 5, j, 3); - if ((seg_data[17] >> j) & 0x1) - DrawSegment(48, 12, 5, j, 3); - } - // 1x16 alphanumeric - for (int i = 0; i < 12; i++) { - for (int j = 0; j < 16; j++) { - if ((seg_data[i + 18] >> j) & 0x1) - DrawSegment((i * 8) + 16, 21, 0, j, 3); - } - SmoothDigitCorners((i * 8) + 16, 21); - } +void AlphaNumeric::Render1x16Alpha_1x16Num_1x7Num( + const uint16_t* const seg_data) { + // 1x16 alphanumeric + for (int i = 0; i < 16; i++) { + for (int j = 0; j < 16; j++) { + if ((seg_data[i] >> j) & 0x1) DrawSegment((i * 8), 9, 0, j, 3); + } + SmoothDigitCorners((i * 8), 9); + } + + // 1x16 numeric + for (int i = 0; i < 16; i++) { + for (int j = 0; j < 16; j++) { + if ((seg_data[i + 16] >> j) & 0x1) DrawSegment((i * 8), 21, 1, j, 3); + } + SmoothDigitCorners((i * 8), 21); + } + + // 1x7 numeric small + for (int i = 0; i < 7; i++) { + for (int j = 0; j < 16; j++) { + if ((seg_data[i + 32] >> j) & 0x1) DrawSegment((i * 8) + 68, 1, 5, j, 3); + } + } } -void AlphaNumeric::Render1x16Alpha_1x16Num_1x7Num(const uint16_t* const seg_data) -{ - // 1x16 alphanumeric - for (int i = 0; i < 16; i++) { - for (int j = 0; j < 16; j++) { - if ((seg_data[i] >> j) & 0x1) - DrawSegment((i * 8), 9, 0, j, 3); - } - SmoothDigitCorners((i * 8), 9); - } - - // 1x16 numeric - for (int i = 0; i < 16; i++) { - for (int j = 0; j < 16; j++) { - if ((seg_data[i + 16] >> j) & 0x1) - DrawSegment((i * 8), 21, 1, j, 3); - } - SmoothDigitCorners((i * 8), 21); - } - - // 1x7 numeric small - for (int i = 0; i < 7; i++) { - for (int j = 0; j < 16; j++) { - if ((seg_data[i + 32] >> j) & 0x1) - DrawSegment((i * 8) + 68, 1, 5, j, 3); - } - } +void AlphaNumeric::Render1x7Num_1x16Alpha_1x16Num( + const uint16_t* const seg_data) { + // 1x16 alphanumeric + for (int i = 0; i < 16; i++) { + for (int j = 0; j < 16; j++) { + if ((seg_data[i + 8] >> j) & 0x1) DrawSegment((i * 8), 9, 0, j, 3); + } + SmoothDigitCorners((i * 8), 9); + } + // 1x16 numeric + for (int i = 0; i < 16; i++) { + for (int j = 0; j < 16; j++) { + if ((seg_data[i + 24] >> j) & 0x1) DrawSegment((i * 8), 21, 1, j, 3); + } + SmoothDigitCorners((i * 8), 21); + } + // 1x7 numeric small + for (int i = 0; i < 7; i++) { + for (int j = 0; j < 16; j++) { + if ((seg_data[i + 1] >> j) & 0x1) DrawSegment((i * 8) + 68, 1, 5, j, 3); + } + } } -void AlphaNumeric::Render1x7Num_1x16Alpha_1x16Num(const uint16_t* const seg_data) -{ - // 1x16 alphanumeric - for (int i = 0; i < 16; i++) { - for (int j = 0; j < 16; j++) { - if ((seg_data[i+8] >> j) & 0x1) - DrawSegment((i * 8), 9, 0, j, 3); - } - SmoothDigitCorners((i * 8), 9); - } - // 1x16 numeric - for (int i = 0; i < 16; i++) { - for (int j = 0; j < 16; j++) { - if ((seg_data[i + 24] >> j) & 0x1) - DrawSegment((i * 8), 21, 1, j, 3); - } - SmoothDigitCorners((i * 8), 21); - } - // 1x7 numeric small - for (int i = 0; i < 7; i++) { - for (int j = 0; j < 16; j++) { - if ((seg_data[i+1] >> j) & 0x1) - DrawSegment((i * 8) + 68, 1, 5, j, 3); - } - } +void AlphaNumeric::Render1x16Alpha_1x16Num_1x7Num_1x4Num( + const uint16_t* const seg_data) { + // 1x16 alphanumeric + for (int i = 0; i < 16; i++) { + for (int j = 0; j < 16; j++) { + if ((seg_data[i + 11] >> j) & 0x1) DrawSegment((i * 8), 9, 0, j, 3); + } + SmoothDigitCorners((i * 8), 9); + } + // 1x16 numeric + for (int i = 0; i < 16; i++) { + for (int j = 0; j < 16; j++) { + if ((seg_data[i + 27] >> j) & 0x1) DrawSegment((i * 8), 21, 1, j, 3); + } + SmoothDigitCorners((i * 8), 21); + } + // 1x4 numeric small + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 16; j++) { + if ((seg_data[i + 7] >> j) & 0x1) DrawSegment((i * 8) + 4, 1, 5, j, 3); + } + } + // 1x7 numeric small + for (int i = 0; i < 7; i++) { + for (int j = 0; j < 16; j++) { + if ((seg_data[i] >> j) & 0x1) DrawSegment((i * 8) + 68, 1, 5, j, 3); + } + } } -void AlphaNumeric::Render1x16Alpha_1x16Num_1x7Num_1x4Num(const uint16_t* const seg_data) -{ - // 1x16 alphanumeric - for (int i = 0; i < 16; i++) { - for (int j = 0; j < 16; j++) { - if ((seg_data[i + 11] >> j) & 0x1) - DrawSegment((i * 8), 9, 0, j, 3); - } - SmoothDigitCorners((i * 8), 9); - } - // 1x16 numeric - for (int i = 0; i < 16; i++) { - for (int j = 0; j < 16; j++) { - if ((seg_data[i + 27] >> j) & 0x1) - DrawSegment((i * 8), 21, 1, j, 3); - } - SmoothDigitCorners((i * 8), 21); - } - // 1x4 numeric small - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 16; j++) { - if ((seg_data[i + 7] >> j) & 0x1) - DrawSegment((i * 8)+4, 1, 5, j, 3); - } - } - // 1x7 numeric small - for (int i = 0; i < 7; i++) { - for (int j = 0; j < 16; j++) { - if ((seg_data[i] >> j) & 0x1) - DrawSegment((i * 8)+68, 1, 5, j, 3); - } - } -} - -} \ No newline at end of file +} // namespace DMDUtil diff --git a/src/AlphaNumeric.h b/src/AlphaNumeric.h index 92b326b..87a194e 100644 --- a/src/AlphaNumeric.h +++ b/src/AlphaNumeric.h @@ -7,50 +7,52 @@ #pragma once -#include "DMDUtil/DMD.h" - #include +#include "DMDUtil/DMD.h" + namespace DMDUtil { -class AlphaNumeric -{ -public: - AlphaNumeric(); - ~AlphaNumeric() {} - - uint8_t* Render(AlphaNumericLayout layout, const uint16_t* const seg_data); - uint8_t* Render(AlphaNumericLayout layout, const uint16_t* const seg_data, const uint16_t* const seg_data2); - -private: - void SmoothDigitCorners(const int x, const int y); - void SmoothDigitCorners6Px(const int x, const int y); - void DrawSegment(const int x, const int y, const uint8_t type, const uint16_t seg, const uint8_t colour); - bool GetPixel(const int x, const int y) const; - void DrawPixel(const int x, const int y, const uint8_t colour); - void Clear(); - - void Render2x16Alpha(const uint16_t* const seg_data); - void Render2x20Alpha(const uint16_t* const seg_data); - void Render2x7Alpha_2x7Num(const uint16_t* const seg_data); - void Render2x7Alpha_2x7Num_4x1Num(const uint16_t* const seg_data); - void Render2x6Num_2x6Num_4x1Num(const uint16_t* const seg_data); - void Render2x6Num10_2x6Num10_4x1Num(const uint16_t* const seg_data); - void Render2x7Num_2x7Num_4x1Num(const uint16_t* const seg_data); - void Render2x7Num_2x7Num_10x1Num(const uint16_t* const seg_data, const uint16_t* const extra_seg_data); - void Render2x7Num_2x7Num_4x1Num_gen7(const uint16_t* const seg_data); - void Render2x7Num10_2x7Num10_4x1Num(const uint16_t* const seg_data); - void Render4x7Num10(const uint16_t* const seg_data); - void Render6x4Num_4x1Num(const uint16_t* const seg_data); - void Render2x7Num_4x1Num_1x16Alpha(const uint16_t* const seg_data); - void Render1x16Alpha_1x16Num_1x7Num(const uint16_t* const seg_data); - void Render1x7Num_1x16Alpha_1x16Num(const uint16_t* const seg_data); - void Render1x16Alpha_1x16Num_1x7Num_1x4Num(const uint16_t* const seg_data); - - uint8_t m_frameBuffer[4096]; - - static const uint8_t SegSizes[8][16]; - static const uint8_t Segs[8][17][5][2]; +class AlphaNumeric { + public: + AlphaNumeric(); + ~AlphaNumeric() {} + + uint8_t* Render(AlphaNumericLayout layout, const uint16_t* const seg_data); + uint8_t* Render(AlphaNumericLayout layout, const uint16_t* const seg_data, + const uint16_t* const seg_data2); + + private: + void SmoothDigitCorners(const int x, const int y); + void SmoothDigitCorners6Px(const int x, const int y); + void DrawSegment(const int x, const int y, const uint8_t type, + const uint16_t seg, const uint8_t colour); + bool GetPixel(const int x, const int y) const; + void DrawPixel(const int x, const int y, const uint8_t colour); + void Clear(); + + void Render2x16Alpha(const uint16_t* const seg_data); + void Render2x20Alpha(const uint16_t* const seg_data); + void Render2x7Alpha_2x7Num(const uint16_t* const seg_data); + void Render2x7Alpha_2x7Num_4x1Num(const uint16_t* const seg_data); + void Render2x6Num_2x6Num_4x1Num(const uint16_t* const seg_data); + void Render2x6Num10_2x6Num10_4x1Num(const uint16_t* const seg_data); + void Render2x7Num_2x7Num_4x1Num(const uint16_t* const seg_data); + void Render2x7Num_2x7Num_10x1Num(const uint16_t* const seg_data, + const uint16_t* const extra_seg_data); + void Render2x7Num_2x7Num_4x1Num_gen7(const uint16_t* const seg_data); + void Render2x7Num10_2x7Num10_4x1Num(const uint16_t* const seg_data); + void Render4x7Num10(const uint16_t* const seg_data); + void Render6x4Num_4x1Num(const uint16_t* const seg_data); + void Render2x7Num_4x1Num_1x16Alpha(const uint16_t* const seg_data); + void Render1x16Alpha_1x16Num_1x7Num(const uint16_t* const seg_data); + void Render1x7Num_1x16Alpha_1x16Num(const uint16_t* const seg_data); + void Render1x16Alpha_1x16Num_1x7Num_1x4Num(const uint16_t* const seg_data); + + uint8_t m_frameBuffer[4096]; + + static const uint8_t SegSizes[8][16]; + static const uint8_t Segs[8][17][5][2]; }; -} \ No newline at end of file +} // namespace DMDUtil diff --git a/src/Config.cpp b/src/Config.cpp index a1886c9..bc097c4 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -4,27 +4,24 @@ namespace DMDUtil { Config* Config::m_pInstance = nullptr; -Config* Config::GetInstance() -{ - if (!m_pInstance) - m_pInstance = new Config(); +Config* Config::GetInstance() { + if (!m_pInstance) m_pInstance = new Config(); - return m_pInstance; + return m_pInstance; } -Config::Config() -{ - m_altColor = true; - m_altColorPath.clear(); - m_zedmd = true; - m_zedmdDevice.clear(); - m_zedmdDebug = false; - m_zedmdRgbOrder = -1; - m_zedmdBrightness = -1; - m_zedmdSaveSettings = false; - m_pixelcade = true; - m_pixelcadeDevice.clear(); - m_logCallback = nullptr; +Config::Config() { + m_altColor = true; + m_altColorPath.clear(); + m_zedmd = true; + m_zedmdDevice.clear(); + m_zedmdDebug = false; + m_zedmdRgbOrder = -1; + m_zedmdBrightness = -1; + m_zedmdSaveSettings = false; + m_pixelcade = true; + m_pixelcadeDevice.clear(); + m_logCallback = nullptr; } -} \ No newline at end of file +} // namespace DMDUtil diff --git a/src/DMD.cpp b/src/DMD.cpp index 7378c22..3f69d43 100644 --- a/src/DMD.cpp +++ b/src/DMD.cpp @@ -1,496 +1,490 @@ #include "DMDUtil/DMD.h" + #include "DMDUtil/Config.h" -#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || defined(__ANDROID__)) +#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || \ + (defined(TARGET_OS_TV) && TARGET_OS_TV))) || \ + defined(__ANDROID__)) #include "Pixelcade.h" #endif +#include + #include "AlphaNumeric.h" #include "FrameUtil.h" #include "Logger.h" - #include "Serum.h" #include "ZeDMD.h" -#include - namespace DMDUtil { -void ZEDMDCALLBACK ZeDMDLogCallback(const char* format, va_list args, const void* pUserData) -{ - char buffer[1024]; - vsnprintf(buffer, sizeof(buffer), format, args); +void ZEDMDCALLBACK ZeDMDLogCallback(const char* format, va_list args, + const void* pUserData) { + char buffer[1024]; + vsnprintf(buffer, sizeof(buffer), format, args); - Log("%s", buffer); + Log("%s", buffer); } bool DMD::m_finding = false; -DMD::DMD(int width, int height, bool sam, const char* name) -{ - m_width = width; - m_height = height; - m_length = width * height; - m_sam = sam; - m_pData = (uint8_t*)malloc(m_length); - memset(m_pData, 0, m_length); - m_pRGB24Data = (uint8_t*)malloc(m_length * 3); - memset(m_pRGB24Data, 0, m_length * 3); - memset(m_segData1, 0, 128 * sizeof(uint16_t)); - memset(m_segData2, 0, 128 * sizeof(uint16_t)); - m_pLevelData = (uint8_t*)malloc(m_length); - memset(m_pLevelData, 0, m_length); - m_pRGB32Data = (uint32_t*)malloc(m_length * sizeof(uint32_t)); - memset(m_pRGB32Data, 0, m_length * sizeof(uint32_t)); - m_pRGB565Data = (uint16_t*)malloc(m_length * sizeof(uint16_t)); - memset(m_pRGB565Data, 0, m_length * sizeof(uint16_t)); - memset(m_palette, 0, 192); - m_pAlphaNumeric = new AlphaNumeric(); - m_pSerum = (Config::GetInstance()->IsAltColor() && name != nullptr && name[0] != '\0') ? Serum::Load(name) : nullptr; - m_pZeDMD = nullptr; -#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || defined(__ANDROID__)) - m_pPixelcade = nullptr; +DMD::DMD(int width, int height, bool sam, const char* name) { + m_width = width; + m_height = height; + m_length = width * height; + m_sam = sam; + m_pData = (uint8_t*)malloc(m_length); + memset(m_pData, 0, m_length); + m_pRGB24Data = (uint8_t*)malloc(m_length * 3); + memset(m_pRGB24Data, 0, m_length * 3); + memset(m_segData1, 0, 128 * sizeof(uint16_t)); + memset(m_segData2, 0, 128 * sizeof(uint16_t)); + m_pLevelData = (uint8_t*)malloc(m_length); + memset(m_pLevelData, 0, m_length); + m_pRGB32Data = (uint32_t*)malloc(m_length * sizeof(uint32_t)); + memset(m_pRGB32Data, 0, m_length * sizeof(uint32_t)); + m_pRGB565Data = (uint16_t*)malloc(m_length * sizeof(uint16_t)); + memset(m_pRGB565Data, 0, m_length * sizeof(uint16_t)); + memset(m_palette, 0, 192); + m_pAlphaNumeric = new AlphaNumeric(); + m_pSerum = (Config::GetInstance()->IsAltColor() && name != nullptr && + name[0] != '\0') + ? Serum::Load(name) + : nullptr; + m_pZeDMD = nullptr; +#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || \ + (defined(TARGET_OS_TV) && TARGET_OS_TV))) || \ + defined(__ANDROID__)) + m_pPixelcade = nullptr; #endif - m_pThread = nullptr; - m_running = false; - m_updated = false; + m_pThread = nullptr; + m_running = false; + m_updated = false; - FindDevices(); + FindDevices(); - Run(); + Run(); } -DMD::~DMD() -{ - if (m_pThread) { - m_running = false; - - m_pThread->join(); - delete m_pThread; - m_pThread = nullptr; - } - - while (!m_updates.empty()) { - DMDUpdate* const pUpdate = m_updates.front(); - m_updates.pop(); - free(pUpdate->pData); - free(pUpdate->pData2); - delete pUpdate; - } - - free(m_pData); - free(m_pRGB24Data); - free(m_pLevelData); - free(m_pRGB32Data); - free(m_pRGB565Data); - delete m_pAlphaNumeric; - delete m_pSerum; - delete m_pZeDMD; -#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || defined(__ANDROID__)) - delete m_pPixelcade; +DMD::~DMD() { + if (m_pThread) { + m_running = false; + + m_pThread->join(); + delete m_pThread; + m_pThread = nullptr; + } + + while (!m_updates.empty()) { + DMDUpdate* const pUpdate = m_updates.front(); + m_updates.pop(); + free(pUpdate->pData); + free(pUpdate->pData2); + delete pUpdate; + } + + free(m_pData); + free(m_pRGB24Data); + free(m_pLevelData); + free(m_pRGB32Data); + free(m_pRGB565Data); + delete m_pAlphaNumeric; + delete m_pSerum; + delete m_pZeDMD; +#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || \ + (defined(TARGET_OS_TV) && TARGET_OS_TV))) || \ + defined(__ANDROID__)) + delete m_pPixelcade; #endif } -bool DMD::IsFinding() -{ - return m_finding; -} +bool DMD::IsFinding() { return m_finding; } -bool DMD::HasDisplay() const -{ -#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || defined(__ANDROID__)) - return (m_pZeDMD != nullptr) || (m_pPixelcade != nullptr); +bool DMD::HasDisplay() const { +#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || \ + (defined(TARGET_OS_TV) && TARGET_OS_TV))) || \ + defined(__ANDROID__)) + return (m_pZeDMD != nullptr) || (m_pPixelcade != nullptr); #else - return (m_pZeDMD != nullptr); + return (m_pZeDMD != nullptr); #endif } -void DMD::UpdateData(const uint8_t* pData, int depth, uint8_t r, uint8_t g, uint8_t b) -{ - DMDUpdate* const pUpdate = new DMDUpdate(); - memset(pUpdate, 0, sizeof(DMDUpdate)); - pUpdate->mode = DmdMode::Data; - pUpdate->depth = depth; - if (pData) { - pUpdate->pData = malloc(m_length); - memcpy(pUpdate->pData, pData, m_length); - } - pUpdate->r = r; - pUpdate->g = g; - pUpdate->b = b; - - { - std::lock_guard lock(m_mutex); - m_updates.push(pUpdate); - } +void DMD::UpdateData(const uint8_t* pData, int depth, uint8_t r, uint8_t g, + uint8_t b) { + DMDUpdate* const pUpdate = new DMDUpdate(); + memset(pUpdate, 0, sizeof(DMDUpdate)); + pUpdate->mode = DmdMode::Data; + pUpdate->depth = depth; + if (pData) { + pUpdate->pData = malloc(m_length); + memcpy(pUpdate->pData, pData, m_length); + } + pUpdate->r = r; + pUpdate->g = g; + pUpdate->b = b; + + { + std::lock_guard lock(m_mutex); + m_updates.push(pUpdate); + } } -void DMD::UpdateRGB24Data(const uint8_t* pData, int depth, uint8_t r, uint8_t g, uint8_t b) -{ - DMDUpdate* const pUpdate = new DMDUpdate(); - memset(pUpdate, 0, sizeof(DMDUpdate)); - pUpdate->mode = DmdMode::RGB24; - pUpdate->depth = depth; - if (pData) { - pUpdate->pData = malloc(m_length * 3); - memcpy(pUpdate->pData, pData, m_length * 3); - } - pUpdate->r = r; - pUpdate->g = g; - pUpdate->b = b; - - { - std::lock_guard lock(m_mutex); - m_updates.push(pUpdate); - } +void DMD::UpdateRGB24Data(const uint8_t* pData, int depth, uint8_t r, uint8_t g, + uint8_t b) { + DMDUpdate* const pUpdate = new DMDUpdate(); + memset(pUpdate, 0, sizeof(DMDUpdate)); + pUpdate->mode = DmdMode::RGB24; + pUpdate->depth = depth; + if (pData) { + pUpdate->pData = malloc(m_length * 3); + memcpy(pUpdate->pData, pData, m_length * 3); + } + pUpdate->r = r; + pUpdate->g = g; + pUpdate->b = b; + + { + std::lock_guard lock(m_mutex); + m_updates.push(pUpdate); + } } -void DMD::UpdateAlphaNumericData(AlphaNumericLayout layout, const uint16_t* pData1, const uint16_t* pData2, uint8_t r, uint8_t g, uint8_t b) -{ - DMDUpdate* const pUpdate = new DMDUpdate(); - memset(pUpdate, 0, sizeof(DMDUpdate)); - pUpdate->mode = DmdMode::AlphaNumeric; - pUpdate->layout = layout; - pUpdate->depth = 2; - pUpdate->pData = malloc(128 * sizeof(uint16_t)); - memcpy(pUpdate->pData, pData1, 128 * sizeof(uint16_t)); - if (pData2) { - pUpdate->pData2 = malloc(128 * sizeof(uint16_t)); - memcpy(pUpdate->pData2, pData2, 128 * sizeof(uint16_t)); - } - pUpdate->r = r; - pUpdate->g = g; - pUpdate->b = b; - - { - std::lock_guard lock(m_mutex); - m_updates.push(pUpdate); - } +void DMD::UpdateAlphaNumericData(AlphaNumericLayout layout, + const uint16_t* pData1, const uint16_t* pData2, + uint8_t r, uint8_t g, uint8_t b) { + DMDUpdate* const pUpdate = new DMDUpdate(); + memset(pUpdate, 0, sizeof(DMDUpdate)); + pUpdate->mode = DmdMode::AlphaNumeric; + pUpdate->layout = layout; + pUpdate->depth = 2; + pUpdate->pData = malloc(128 * sizeof(uint16_t)); + memcpy(pUpdate->pData, pData1, 128 * sizeof(uint16_t)); + if (pData2) { + pUpdate->pData2 = malloc(128 * sizeof(uint16_t)); + memcpy(pUpdate->pData2, pData2, 128 * sizeof(uint16_t)); + } + pUpdate->r = r; + pUpdate->g = g; + pUpdate->b = b; + + { + std::lock_guard lock(m_mutex); + m_updates.push(pUpdate); + } } -void DMD::FindDevices() -{ - if (m_finding) - return; - - m_finding = true; - - new std::thread([this]() { - ZeDMD* pZeDMD = nullptr; -#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || defined(__ANDROID__)) - Pixelcade* pPixelcade = nullptr; +void DMD::FindDevices() { + if (m_finding) return; + + m_finding = true; + + new std::thread([this]() { + ZeDMD* pZeDMD = nullptr; +#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || \ + (defined(TARGET_OS_TV) && TARGET_OS_TV))) || \ + defined(__ANDROID__)) + Pixelcade* pPixelcade = nullptr; #endif - Config* const pConfig = Config::GetInstance(); - if (pConfig->IsZeDMD()) { - pZeDMD = new ZeDMD(); - pZeDMD->SetLogCallback(ZeDMDLogCallback, nullptr); + Config* const pConfig = Config::GetInstance(); + if (pConfig->IsZeDMD()) { + pZeDMD = new ZeDMD(); + pZeDMD->SetLogCallback(ZeDMDLogCallback, nullptr); - if (pConfig->GetZeDMDDevice() != nullptr && pConfig->GetZeDMDDevice()[0] != '\0') - pZeDMD->SetDevice(pConfig->GetZeDMDDevice()); + if (pConfig->GetZeDMDDevice() != nullptr && + pConfig->GetZeDMDDevice()[0] != '\0') + pZeDMD->SetDevice(pConfig->GetZeDMDDevice()); - if (pZeDMD->Open(m_width, m_height)) { - if (pConfig->IsZeDMDDebug()) - pZeDMD->EnableDebug(); + if (pZeDMD->Open(m_width, m_height)) { + if (pConfig->IsZeDMDDebug()) pZeDMD->EnableDebug(); - if (pConfig->GetZeDMDRGBOrder() != -1) - pZeDMD->SetRGBOrder(pConfig->GetZeDMDRGBOrder()); + if (pConfig->GetZeDMDRGBOrder() != -1) + pZeDMD->SetRGBOrder(pConfig->GetZeDMDRGBOrder()); - if (pConfig->GetZeDMDBrightness() != -1) - pZeDMD->SetBrightness(pConfig->GetZeDMDBrightness()); + if (pConfig->GetZeDMDBrightness() != -1) + pZeDMD->SetBrightness(pConfig->GetZeDMDBrightness()); - if (pConfig->IsZeDMDSaveSettings()) - pZeDMD->SaveSettings(); - } - else { - delete pZeDMD; - pZeDMD = nullptr; - } + if (pConfig->IsZeDMDSaveSettings()) pZeDMD->SaveSettings(); + } else { + delete pZeDMD; + pZeDMD = nullptr; } - -#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || defined(__ANDROID__)) - if (pConfig->IsPixelcade()) - pPixelcade = Pixelcade::Connect(pConfig->GetPixelcadeDevice(), m_width, m_height); + } + +#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || \ + (defined(TARGET_OS_TV) && TARGET_OS_TV))) || \ + defined(__ANDROID__)) + if (pConfig->IsPixelcade()) + pPixelcade = + Pixelcade::Connect(pConfig->GetPixelcadeDevice(), m_width, m_height); #endif - m_pZeDMD = pZeDMD; -#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || defined(__ANDROID__)) - m_pPixelcade = pPixelcade; + m_pZeDMD = pZeDMD; +#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || \ + (defined(TARGET_OS_TV) && TARGET_OS_TV))) || \ + defined(__ANDROID__)) + m_pPixelcade = pPixelcade; #endif - m_finding = false; - }); + m_finding = false; + }); } -void DMD::Run() -{ - if (m_running) - return; - - m_running = true; - - m_pThread = new std::thread([this]() { - Log("DMD run thread starting"); - - DmdMode mode = DmdMode::Unknown; - - while (m_running) { - DMDUpdate* pUpdate = nullptr; - - { - std::lock_guard lock(m_mutex); - if (!m_updates.empty()) { - pUpdate = m_updates.front(); - m_updates.pop(); - } - } - - if (pUpdate) { - const bool update = (mode != pUpdate->mode); - mode = pUpdate->mode; - - if (mode == DmdMode::Data) - UpdateData(pUpdate, update); - else if (mode == DmdMode::RGB24) - UpdateRGB24Data(pUpdate, update); - else if (mode == DmdMode::AlphaNumeric) - UpdateAlphaNumericData(pUpdate, update); - - free(pUpdate->pData); - free(pUpdate->pData2); - delete pUpdate; - } - else - std::this_thread::sleep_for(std::chrono::milliseconds(1)); +void DMD::Run() { + if (m_running) return; + + m_running = true; + + m_pThread = new std::thread([this]() { + Log("DMD run thread starting"); + + DmdMode mode = DmdMode::Unknown; + + while (m_running) { + DMDUpdate* pUpdate = nullptr; + + { + std::lock_guard lock(m_mutex); + if (!m_updates.empty()) { + pUpdate = m_updates.front(); + m_updates.pop(); + } } - Log("DMD run thread finished"); - }); + if (pUpdate) { + const bool update = (mode != pUpdate->mode); + mode = pUpdate->mode; + + if (mode == DmdMode::Data) + UpdateData(pUpdate, update); + else if (mode == DmdMode::RGB24) + UpdateRGB24Data(pUpdate, update); + else if (mode == DmdMode::AlphaNumeric) + UpdateAlphaNumericData(pUpdate, update); + + free(pUpdate->pData); + free(pUpdate->pData2); + delete pUpdate; + } else + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + + Log("DMD run thread finished"); + }); } -bool DMD::UpdatePalette(const DMDUpdate* pUpdate) -{ - if (pUpdate->depth != 2 && pUpdate->depth != 4) - return false; +bool DMD::UpdatePalette(const DMDUpdate* pUpdate) { + if (pUpdate->depth != 2 && pUpdate->depth != 4) return false; - uint8_t palette[192]; - memcpy(palette, m_palette, 192); + uint8_t palette[192]; + memcpy(palette, m_palette, 192); - memset(m_palette, 0, 192); + memset(m_palette, 0, 192); - const float r = (float)pUpdate->r; - const float g = (float)pUpdate->g; - const float b = (float)pUpdate->b; + const float r = (float)pUpdate->r; + const float g = (float)pUpdate->g; + const float b = (float)pUpdate->b; - const int colors = (pUpdate->depth == 2) ? 4 : 16; - int pos = 0; + const int colors = (pUpdate->depth == 2) ? 4 : 16; + int pos = 0; - for (int i = 0; i < colors; i++) { - float perc = FrameUtil::CalcBrightness((float)i / (float)(colors - 1)); - m_palette[pos++] = (uint8_t)(r * perc); - m_palette[pos++] = (uint8_t)(g * perc); - m_palette[pos++] = (uint8_t)(b * perc); - } + for (int i = 0; i < colors; i++) { + float perc = FrameUtil::CalcBrightness((float)i / (float)(colors - 1)); + m_palette[pos++] = (uint8_t)(r * perc); + m_palette[pos++] = (uint8_t)(g * perc); + m_palette[pos++] = (uint8_t)(b * perc); + } - return (memcmp(m_palette, palette, 192) != 0); + return (memcmp(m_palette, palette, 192) != 0); } -void DMD::UpdateData(const DMDUpdate* pUpdate, bool update) -{ - uint8_t* const pData = (uint8_t*)pUpdate->pData; - - if (pData) { - if (pUpdate->depth == 2) { - for (int i = 0; i < m_length; i++) - m_pLevelData[i] = LEVELS_WPC[pData[i]]; - } - else if (pUpdate->depth == 4) { - if (!m_sam) { - for (int i = 0; i < m_length; i++) - m_pLevelData[i] = LEVELS_GTS3[pData[i]]; - } - else { - for (int i = 0; i < m_length; i++) - m_pLevelData[i] = LEVELS_SAM[pData[i]]; - } +void DMD::UpdateData(const DMDUpdate* pUpdate, bool update) { + uint8_t* const pData = (uint8_t*)pUpdate->pData; + + if (pData) { + if (pUpdate->depth == 2) { + for (int i = 0; i < m_length; i++) m_pLevelData[i] = LEVELS_WPC[pData[i]]; + } else if (pUpdate->depth == 4) { + if (!m_sam) { + for (int i = 0; i < m_length; i++) + m_pLevelData[i] = LEVELS_GTS3[pData[i]]; + } else { + for (int i = 0; i < m_length; i++) + m_pLevelData[i] = LEVELS_SAM[pData[i]]; } - } - - if (!m_pSerum) { - if (pData) { - if (memcmp(m_pData, pData, m_length) != 0) { - memcpy(m_pData, pData, m_length); - update = true; - } + } + } + + if (!m_pSerum) { + if (pData) { + if (memcmp(m_pData, pData, m_length) != 0) { + memcpy(m_pData, pData, m_length); + update = true; } - - if (UpdatePalette(pUpdate)) - update = true; - } - else if (m_pSerum->Convert(pData, m_pData, m_palette)) { - // if we have serum, run a conversion, and if success, we have an update (needed for rotations) - // serum will take care of updating the data buffer - update = true; - } - - if (!update) - return; - - for (int i = 0; i < m_length; i++) { - int pos = m_pData[i] * 3; - uint32_t r = m_palette[pos ]; - uint32_t g = m_palette[pos+1]; - uint32_t b = m_palette[pos+2]; - - m_pRGB32Data[i] = r | g << 8 | b << 16 | 0xFFu << 24; - m_pRGB565Data[i] = (uint16_t)(((r & 0xF8u) << 8) | ((g & 0xFCu) << 3) | (b >> 3)); - } - - if (m_pZeDMD) { - if (m_pSerum) { - m_pZeDMD->SetPalette(m_palette, 64); - m_pZeDMD->RenderColoredGray6(m_pData, nullptr); - } - else { - if (pUpdate->depth == 2) { - m_pZeDMD->SetPalette(m_palette, 4); - m_pZeDMD->RenderGray2(m_pData); - } - else { - m_pZeDMD->SetPalette(m_palette, 16); - m_pZeDMD->RenderGray4(m_pData); - } + } + + if (UpdatePalette(pUpdate)) update = true; + } else if (m_pSerum->Convert(pData, m_pData, m_palette)) { + // if we have serum, run a conversion, and if success, we have an update + // (needed for rotations) serum will take care of updating the data buffer + update = true; + } + + if (!update) return; + + for (int i = 0; i < m_length; i++) { + int pos = m_pData[i] * 3; + uint32_t r = m_palette[pos]; + uint32_t g = m_palette[pos + 1]; + uint32_t b = m_palette[pos + 2]; + + m_pRGB32Data[i] = r | g << 8 | b << 16 | 0xFFu << 24; + m_pRGB565Data[i] = + (uint16_t)(((r & 0xF8u) << 8) | ((g & 0xFCu) << 3) | (b >> 3)); + } + + if (m_pZeDMD) { + if (m_pSerum) { + m_pZeDMD->SetPalette(m_palette, 64); + m_pZeDMD->RenderColoredGray6(m_pData, nullptr); + } else { + if (pUpdate->depth == 2) { + m_pZeDMD->SetPalette(m_palette, 4); + m_pZeDMD->RenderGray2(m_pData); + } else { + m_pZeDMD->SetPalette(m_palette, 16); + m_pZeDMD->RenderGray4(m_pData); } - } + } + } -#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || defined(__ANDROID__)) - if (m_pPixelcade) - m_pPixelcade->Update(m_pRGB565Data); +#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || \ + (defined(TARGET_OS_TV) && TARGET_OS_TV))) || \ + defined(__ANDROID__)) + if (m_pPixelcade) m_pPixelcade->Update(m_pRGB565Data); #endif - m_updated = true; + m_updated = true; } -void DMD::UpdateRGB24Data(const DMDUpdate* pUpdate, bool update) -{ - uint8_t* const pData = (uint8_t*)pUpdate->pData; +void DMD::UpdateRGB24Data(const DMDUpdate* pUpdate, bool update) { + uint8_t* const pData = (uint8_t*)pUpdate->pData; - if (pUpdate->depth != 24) { - if (UpdatePalette(pUpdate)) - update = true; - } + if (pUpdate->depth != 24) { + if (UpdatePalette(pUpdate)) update = true; + } - if (memcmp(m_pRGB24Data, pData, m_length * 3) != 0) - update = true; + if (memcmp(m_pRGB24Data, pData, m_length * 3) != 0) update = true; - if (!update) - return; + if (!update) return; - memcpy(m_pRGB24Data, pData, m_length * 3); + memcpy(m_pRGB24Data, pData, m_length * 3); - int pos = 0; - for (int i = 0; i < m_length; i++) { - uint32_t r = m_pRGB24Data[pos++]; - uint32_t g = m_pRGB24Data[pos++]; - uint32_t b = m_pRGB24Data[pos++]; + int pos = 0; + for (int i = 0; i < m_length; i++) { + uint32_t r = m_pRGB24Data[pos++]; + uint32_t g = m_pRGB24Data[pos++]; + uint32_t b = m_pRGB24Data[pos++]; - if (pUpdate->depth != 24) { - int v = (int)(0.2126f * (float)r + 0.7152f * (float)g + 0.0722f * (float)b); - if (v > 255) - v = 255; + if (pUpdate->depth != 24) { + int v = + (int)(0.2126f * (float)r + 0.7152f * (float)g + 0.0722f * (float)b); + if (v > 255) v = 255; - uint8_t level; - if (pUpdate->depth == 2) - level = (uint8_t)(v >> 6); - else - level = (uint8_t)(v >> 4); + uint8_t level; + if (pUpdate->depth == 2) + level = (uint8_t)(v >> 6); + else + level = (uint8_t)(v >> 4); - m_pLevelData[i] = level; + m_pLevelData[i] = level; - int pos2 = level * 3; + int pos2 = level * 3; - r = m_palette[pos2 ]; - g = m_palette[pos2+1]; - b = m_palette[pos2+2]; - } + r = m_palette[pos2]; + g = m_palette[pos2 + 1]; + b = m_palette[pos2 + 2]; + } - m_pRGB32Data[i] = r | g << 8 | b << 16 | 0xFFu << 24; - m_pRGB565Data[i] = (uint16_t)(((r & 0xF8u) << 8) | ((g & 0xFCu) << 3) | (b >> 3)); - } + m_pRGB32Data[i] = r | g << 8 | b << 16 | 0xFFu << 24; + m_pRGB565Data[i] = + (uint16_t)(((r & 0xF8u) << 8) | ((g & 0xFCu) << 3) | (b >> 3)); + } - if (pUpdate->depth == 2) { - if (m_pZeDMD) { - m_pZeDMD->SetPalette(m_palette, 4); - m_pZeDMD->RenderGray2(m_pLevelData); - } - } - else if (pUpdate->depth == 4) { - if (m_pZeDMD) { - m_pZeDMD->SetPalette(m_palette, 16); - m_pZeDMD->RenderGray4(m_pLevelData); - } - } - else if (pUpdate->depth == 24) { - if (m_pZeDMD) - m_pZeDMD->RenderRgb24((uint8_t*)m_pRGB24Data); - } - -#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || defined(__ANDROID__)) - if (m_pPixelcade) - m_pPixelcade->Update(m_pRGB565Data); + if (pUpdate->depth == 2) { + if (m_pZeDMD) { + m_pZeDMD->SetPalette(m_palette, 4); + m_pZeDMD->RenderGray2(m_pLevelData); + } + } else if (pUpdate->depth == 4) { + if (m_pZeDMD) { + m_pZeDMD->SetPalette(m_palette, 16); + m_pZeDMD->RenderGray4(m_pLevelData); + } + } else if (pUpdate->depth == 24) { + if (m_pZeDMD) m_pZeDMD->RenderRgb24((uint8_t*)m_pRGB24Data); + } + +#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || \ + (defined(TARGET_OS_TV) && TARGET_OS_TV))) || \ + defined(__ANDROID__)) + if (m_pPixelcade) m_pPixelcade->Update(m_pRGB565Data); #endif - m_updated = true; + m_updated = true; } -void DMD::UpdateAlphaNumericData(const DMDUpdate* pUpdate, bool update) -{ - if (memcmp(m_segData1, pUpdate->pData, 128 * sizeof(uint16_t)) != 0) { - memcpy(m_segData1, pUpdate->pData, 128 * sizeof(uint16_t)); - update = true; - } - - if (pUpdate->pData2 && memcmp(m_segData2, pUpdate->pData2, 128 * sizeof(uint16_t)) != 0) { - memcpy(m_segData2, pUpdate->pData2, 128 * sizeof(uint16_t)); - update = true; - } - - if (UpdatePalette(pUpdate)) - update = true; - - if (!update) - return; - - uint8_t* pData; - - if (pUpdate->pData2) - pData = m_pAlphaNumeric->Render(pUpdate->layout, (const uint16_t*)m_segData1, (const uint16_t*)m_segData2); - else - pData = m_pAlphaNumeric->Render(pUpdate->layout, (const uint16_t*)m_segData1); - - for (int i = 0; i < m_length; i++) - m_pLevelData[i] = LEVELS_WPC[pData[i]]; - - for (int i = 0; i < m_length; i++) { - int pos = pData[i] * 3; - uint32_t r = m_palette[pos ]; - uint32_t g = m_palette[pos+1]; - uint32_t b = m_palette[pos+2]; - - m_pRGB32Data[i] = r | g << 8 | b << 16 | 0xFFu << 24; - m_pRGB565Data[i] = (uint16_t)(((r & 0xF8u) << 8) | ((g & 0xFCu) << 3) | (b >> 3)); - } - - if (m_pZeDMD) { - m_pZeDMD->SetPalette(m_palette, 4); - m_pZeDMD->RenderGray2(pData); - } - -#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || defined(__ANDROID__)) - if (m_pPixelcade) - m_pPixelcade->Update(m_pRGB565Data); +void DMD::UpdateAlphaNumericData(const DMDUpdate* pUpdate, bool update) { + if (memcmp(m_segData1, pUpdate->pData, 128 * sizeof(uint16_t)) != 0) { + memcpy(m_segData1, pUpdate->pData, 128 * sizeof(uint16_t)); + update = true; + } + + if (pUpdate->pData2 && + memcmp(m_segData2, pUpdate->pData2, 128 * sizeof(uint16_t)) != 0) { + memcpy(m_segData2, pUpdate->pData2, 128 * sizeof(uint16_t)); + update = true; + } + + if (UpdatePalette(pUpdate)) update = true; + + if (!update) return; + + uint8_t* pData; + + if (pUpdate->pData2) + pData = + m_pAlphaNumeric->Render(pUpdate->layout, (const uint16_t*)m_segData1, + (const uint16_t*)m_segData2); + else + pData = + m_pAlphaNumeric->Render(pUpdate->layout, (const uint16_t*)m_segData1); + + for (int i = 0; i < m_length; i++) m_pLevelData[i] = LEVELS_WPC[pData[i]]; + + for (int i = 0; i < m_length; i++) { + int pos = pData[i] * 3; + uint32_t r = m_palette[pos]; + uint32_t g = m_palette[pos + 1]; + uint32_t b = m_palette[pos + 2]; + + m_pRGB32Data[i] = r | g << 8 | b << 16 | 0xFFu << 24; + m_pRGB565Data[i] = + (uint16_t)(((r & 0xF8u) << 8) | ((g & 0xFCu) << 3) | (b >> 3)); + } + + if (m_pZeDMD) { + m_pZeDMD->SetPalette(m_palette, 4); + m_pZeDMD->RenderGray2(pData); + } + +#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || \ + (defined(TARGET_OS_TV) && TARGET_OS_TV))) || \ + defined(__ANDROID__)) + if (m_pPixelcade) m_pPixelcade->Update(m_pRGB565Data); #endif - m_updated = true; + m_updated = true; } -} \ No newline at end of file +} // namespace DMDUtil diff --git a/src/FrameUtil.cpp b/src/FrameUtil.cpp index c504633..b3067a4 100644 --- a/src/FrameUtil.cpp +++ b/src/FrameUtil.cpp @@ -1,228 +1,231 @@ -/* - * Portions of this code was derived from DMDExt - * - * https://github.com/freezy/dmd-extensions/blob/master/LibDmd/Common/FrameUtil.cs - */ - -#include "FrameUtil.h" - -#include -#include -#include - -namespace DMDUtil { - -inline int FrameUtil::MapAdafruitIndex(int x, int y, int width, int height, int numLogicalRows) -{ - int logicalRowLengthPerMatrix = 32 * 32 / 2 / numLogicalRows; - int logicalRow = y % numLogicalRows; - int dotPairsPerLogicalRow = width * height / numLogicalRows / 2; - int widthInMatrices = width / 32; - int matrixX = x / 32; - int matrixY = y / 32; - int totalMatrices = width * height / 1024; - int matrixNumber = totalMatrices - ((matrixY + 1) * widthInMatrices) + matrixX; - int indexWithinMatrixRow = x % logicalRowLengthPerMatrix; - int index = logicalRow * dotPairsPerLogicalRow - + matrixNumber * logicalRowLengthPerMatrix + indexWithinMatrixRow; - return index; -} - -void FrameUtil::SplitIntoRgbPlanes(const uint16_t* rgb565, int rgb565Size, int width, int numLogicalRows, uint8_t* dest, ColorMatrix colorMatrix) -{ - constexpr int pairOffset = 16; - int height = rgb565Size / width; - int subframeSize = rgb565Size / 2; - - for (int x = 0; x < width; ++x) { - for (int y = 0; y < height; ++y) { - if (y % (pairOffset * 2) >= pairOffset) - continue; - - int inputIndex0 = y * width + x; - int inputIndex1 = inputIndex0 + pairOffset * width; - - uint16_t color0 = rgb565[inputIndex0]; - uint16_t color1 = rgb565[inputIndex1]; - - int r0 = 0, r1 = 0, g0 = 0, g1 = 0, b0 = 0, b1 = 0; - switch (colorMatrix) { - case ColorMatrix::Rgb: - r0 = (color0 >> 13) /*& 0x7*/; - g0 = (color0 >> 8) /*& 0x7*/; - b0 = (color0 >> 2) /*& 0x7*/; - r1 = (color1 >> 13) /*& 0x7*/; - g1 = (color1 >> 8) /*& 0x7*/; - b1 = (color1 >> 2) /*& 0x7*/; - break; - - case ColorMatrix::Rbg: - r0 = (color0 >> 13) /*& 0x7*/; - b0 = (color0 >> 8) /*& 0x7*/; - g0 = (color0 >> 2) /*& 0x7*/; - r1 = (color1 >> 13) /*& 0x7*/; - b1 = (color1 >> 8) /*& 0x7*/; - g1 = (color1 >> 2) /*& 0x7*/; - break; - } - - for (int subframe = 0; subframe < 3; ++subframe) { - uint8_t dotPair = - (r0 & 1) << 5 | - (g0 & 1) << 4 | - (b0 & 1) << 3 | - (r1 & 1) << 2 | - (g1 & 1) << 1 | - (b1 & 1); - int indexWithinSubframe = MapAdafruitIndex(x, y, width, height, numLogicalRows); - int indexWithinOutput = subframe * subframeSize + indexWithinSubframe; - dest[indexWithinOutput] = dotPair; - r0 >>= 1; - g0 >>= 1; - b0 >>= 1; - r1 >>= 1; - g1 >>= 1; - b1 >>= 1; - } - } - } -} - -inline uint16_t FrameUtil::InterpolateRgb565Color(uint16_t color1, uint16_t color2, float ratio) -{ - //ratio *= ratio*(3.0f-2.0f*ratio); // = biquintic - - int red1 = (int)color1 >> 11; - int green1 = ((int)color1 >> 5) & 0x3F; - int blue1 = (int)color1 & 0x1F; - - int red2 = (int)color2 >> 11; - int green2 = ((int)color2 >> 5) & 0x3F; - int blue2 = (int)color2 & 0x1F; - - int red = red1 + static_cast((float)(red2 - red1) * ratio); - int green = green1 + static_cast((float)(green2 - green1) * ratio); - int blue = blue1 + static_cast((float)(blue2 - blue1) * ratio); - - red = std::min(std::max(red, 0), 0x1F); - green = std::min(std::max(green, 0), 0x3F); - blue = std::min(std::max(blue, 0), 0x1F); - - return (uint16_t)((red << 11) | (green << 5) | blue); -} - -inline uint16_t FrameUtil::InterpolatedRgb565Pixel(const uint16_t* src, float srcX, float srcY, int srcWidth, int srcHeight) -{ - int x = (int)srcX; - int y = (int)srcY; - float xDiff = srcX - (float)x; - float yDiff = srcY - (float)y; - - //xDiff *= xDiff*(3.0f-2.0f*xDiff); // = biquintic - //yDiff *= yDiff*(3.0f-2.0f*yDiff); - - const int offs = y * srcWidth + x; - int a = src[offs]; - int b = (x < srcWidth - 1) ? src[offs + 1] : a; - int c = (y < srcHeight - 1) ? src[offs + srcWidth] : a; - int d = (x < srcWidth - 1 && y < srcHeight - 1) ? src[offs + srcWidth + 1] : c; - - int red1 = a >> 11; - int green1 = (a >> 5) & 0x3F; - int blue1 = a & 0x1F; - - int red2 = b >> 11; - int green2 = (b >> 5) & 0x3F; - int blue2 = b & 0x1F; - - float redab = (float)red1 + (float)(red2 - red1) * xDiff; - float greenab = (float)green1 + (float)(green2 - green1) * xDiff; - float blueab = (float)blue1 + (float)(blue2 - blue1) * xDiff; - - red1 = c >> 11; - green1 = (c >> 5) & 0x3F; - blue1 = c & 0x1F; - - red2 = d >> 11; - green2 = (d >> 5) & 0x3F; - blue2 = d & 0x1F; - - float redcd = (float)red1 + (float)(red2 - red1) * xDiff; - float greencd = (float)green1 + (float)(green2 - green1) * xDiff; - float bluecd = (float)blue1 + (float)(blue2 - blue1) * xDiff; - - float red = redab + (redcd - redab) * yDiff; - float green = greenab + (greencd - greenab) * yDiff; - float blue = blueab + (bluecd - blueab) * yDiff; - - red = std::min(std::max(red, 0.f), (float)0x1F); - green = std::min(std::max(green, 0.f), (float)0x3F); - blue = std::min(std::max(blue, 0.f), (float)0x1F); - - return (uint16_t)(((int)red << 11) | ((int)green << 5) | (int)blue); -} - -void FrameUtil::ResizeRgb565Bilinear(const uint16_t* src, int srcWidth, int srcHeight, uint16_t* dest, int destWidth, int destHeight) -{ - memset(dest, 0, destWidth * destHeight * sizeof(uint16_t)); - - float srcAspect = (float)srcWidth / (float)srcHeight; - float destAspect = (float)destWidth / (float)destHeight; - int scaledWidth, scaledHeight; - - if (srcAspect > destAspect) { - scaledWidth = destWidth; - scaledHeight = (int)((float)destWidth / srcAspect); - } - else { - scaledHeight = destHeight; - scaledWidth = (int)((float)destHeight * srcAspect); - } - - int offsetX = (destWidth - scaledWidth) / 2; - int offsetY = (destHeight - scaledHeight) / 2; - int offs = offsetX + offsetY * destWidth; - - for (int y = 0; y < scaledHeight; ++y) { - for (int x = 0; x < scaledWidth; ++x) { - float srcX = ((float)x + 0.5f) * ((float)srcWidth / (float)scaledWidth) - 0.5f; - float srcY = ((float)y + 0.5f) * ((float)srcHeight / (float)scaledHeight) - 0.5f; - - srcX = std::max(0.0f, std::min(srcX, static_cast(srcWidth - 1))); - srcY = std::max(0.0f, std::min(srcY, static_cast(srcHeight - 1))); - - dest[y * destWidth + offs + x] = InterpolatedRgb565Pixel(src, srcX, srcY, srcWidth, srcHeight); - } - } -} - -float FrameUtil::CalcBrightness(float x) -{ - // function to improve the brightness with fx=ax²+bc+c, f(0)=0, f(1)=1, f'(1.1)=0 - return (-x * x + 2.1f * x) / 1.1f; -} - -std::string FrameUtil::HexDump(const uint8_t* data, size_t size) -{ - constexpr int bytesPerLine = 32; - - std::stringstream ss; - - for (size_t i = 0; i < size; i += bytesPerLine) { - for (size_t j = i; j < i + bytesPerLine && j < size; ++j) - ss << std::setw(2) << std::setfill('0') << std::hex << static_cast(data[j]) << ' '; - - for (size_t j = i; j < i + bytesPerLine && j < size; ++j) { - char ch = data[j]; - if (ch < 32 || ch > 126) - ch = '.'; - ss << ch; - } - - ss << std::endl; - } - - return ss.str(); -} - -} \ No newline at end of file +/* + * Portions of this code was derived from DMDExt + * + * https://github.com/freezy/dmd-extensions/blob/master/LibDmd/Common/FrameUtil.cs + */ + +#include "FrameUtil.h" + +#include +#include +#include + +namespace DMDUtil { + +inline int FrameUtil::MapAdafruitIndex(int x, int y, int width, int height, + int numLogicalRows) { + int logicalRowLengthPerMatrix = 32 * 32 / 2 / numLogicalRows; + int logicalRow = y % numLogicalRows; + int dotPairsPerLogicalRow = width * height / numLogicalRows / 2; + int widthInMatrices = width / 32; + int matrixX = x / 32; + int matrixY = y / 32; + int totalMatrices = width * height / 1024; + int matrixNumber = + totalMatrices - ((matrixY + 1) * widthInMatrices) + matrixX; + int indexWithinMatrixRow = x % logicalRowLengthPerMatrix; + int index = logicalRow * dotPairsPerLogicalRow + + matrixNumber * logicalRowLengthPerMatrix + indexWithinMatrixRow; + return index; +} + +void FrameUtil::SplitIntoRgbPlanes(const uint16_t* rgb565, int rgb565Size, + int width, int numLogicalRows, uint8_t* dest, + ColorMatrix colorMatrix) { + constexpr int pairOffset = 16; + int height = rgb565Size / width; + int subframeSize = rgb565Size / 2; + + for (int x = 0; x < width; ++x) { + for (int y = 0; y < height; ++y) { + if (y % (pairOffset * 2) >= pairOffset) continue; + + int inputIndex0 = y * width + x; + int inputIndex1 = inputIndex0 + pairOffset * width; + + uint16_t color0 = rgb565[inputIndex0]; + uint16_t color1 = rgb565[inputIndex1]; + + int r0 = 0, r1 = 0, g0 = 0, g1 = 0, b0 = 0, b1 = 0; + switch (colorMatrix) { + case ColorMatrix::Rgb: + r0 = (color0 >> 13) /*& 0x7*/; + g0 = (color0 >> 8) /*& 0x7*/; + b0 = (color0 >> 2) /*& 0x7*/; + r1 = (color1 >> 13) /*& 0x7*/; + g1 = (color1 >> 8) /*& 0x7*/; + b1 = (color1 >> 2) /*& 0x7*/; + break; + + case ColorMatrix::Rbg: + r0 = (color0 >> 13) /*& 0x7*/; + b0 = (color0 >> 8) /*& 0x7*/; + g0 = (color0 >> 2) /*& 0x7*/; + r1 = (color1 >> 13) /*& 0x7*/; + b1 = (color1 >> 8) /*& 0x7*/; + g1 = (color1 >> 2) /*& 0x7*/; + break; + } + + for (int subframe = 0; subframe < 3; ++subframe) { + uint8_t dotPair = (r0 & 1) << 5 | (g0 & 1) << 4 | (b0 & 1) << 3 | + (r1 & 1) << 2 | (g1 & 1) << 1 | (b1 & 1); + int indexWithinSubframe = + MapAdafruitIndex(x, y, width, height, numLogicalRows); + int indexWithinOutput = subframe * subframeSize + indexWithinSubframe; + dest[indexWithinOutput] = dotPair; + r0 >>= 1; + g0 >>= 1; + b0 >>= 1; + r1 >>= 1; + g1 >>= 1; + b1 >>= 1; + } + } + } +} + +inline uint16_t FrameUtil::InterpolateRgb565Color(uint16_t color1, + uint16_t color2, + float ratio) { + // ratio *= ratio*(3.0f-2.0f*ratio); // = biquintic + + int red1 = (int)color1 >> 11; + int green1 = ((int)color1 >> 5) & 0x3F; + int blue1 = (int)color1 & 0x1F; + + int red2 = (int)color2 >> 11; + int green2 = ((int)color2 >> 5) & 0x3F; + int blue2 = (int)color2 & 0x1F; + + int red = red1 + static_cast((float)(red2 - red1) * ratio); + int green = green1 + static_cast((float)(green2 - green1) * ratio); + int blue = blue1 + static_cast((float)(blue2 - blue1) * ratio); + + red = std::min(std::max(red, 0), 0x1F); + green = std::min(std::max(green, 0), 0x3F); + blue = std::min(std::max(blue, 0), 0x1F); + + return (uint16_t)((red << 11) | (green << 5) | blue); +} + +inline uint16_t FrameUtil::InterpolatedRgb565Pixel(const uint16_t* src, + float srcX, float srcY, + int srcWidth, + int srcHeight) { + int x = (int)srcX; + int y = (int)srcY; + float xDiff = srcX - (float)x; + float yDiff = srcY - (float)y; + + // xDiff *= xDiff*(3.0f-2.0f*xDiff); // = biquintic + // yDiff *= yDiff*(3.0f-2.0f*yDiff); + + const int offs = y * srcWidth + x; + int a = src[offs]; + int b = (x < srcWidth - 1) ? src[offs + 1] : a; + int c = (y < srcHeight - 1) ? src[offs + srcWidth] : a; + int d = + (x < srcWidth - 1 && y < srcHeight - 1) ? src[offs + srcWidth + 1] : c; + + int red1 = a >> 11; + int green1 = (a >> 5) & 0x3F; + int blue1 = a & 0x1F; + + int red2 = b >> 11; + int green2 = (b >> 5) & 0x3F; + int blue2 = b & 0x1F; + + float redab = (float)red1 + (float)(red2 - red1) * xDiff; + float greenab = (float)green1 + (float)(green2 - green1) * xDiff; + float blueab = (float)blue1 + (float)(blue2 - blue1) * xDiff; + + red1 = c >> 11; + green1 = (c >> 5) & 0x3F; + blue1 = c & 0x1F; + + red2 = d >> 11; + green2 = (d >> 5) & 0x3F; + blue2 = d & 0x1F; + + float redcd = (float)red1 + (float)(red2 - red1) * xDiff; + float greencd = (float)green1 + (float)(green2 - green1) * xDiff; + float bluecd = (float)blue1 + (float)(blue2 - blue1) * xDiff; + + float red = redab + (redcd - redab) * yDiff; + float green = greenab + (greencd - greenab) * yDiff; + float blue = blueab + (bluecd - blueab) * yDiff; + + red = std::min(std::max(red, 0.f), (float)0x1F); + green = std::min(std::max(green, 0.f), (float)0x3F); + blue = std::min(std::max(blue, 0.f), (float)0x1F); + + return (uint16_t)(((int)red << 11) | ((int)green << 5) | (int)blue); +} + +void FrameUtil::ResizeRgb565Bilinear(const uint16_t* src, int srcWidth, + int srcHeight, uint16_t* dest, + int destWidth, int destHeight) { + memset(dest, 0, destWidth * destHeight * sizeof(uint16_t)); + + float srcAspect = (float)srcWidth / (float)srcHeight; + float destAspect = (float)destWidth / (float)destHeight; + int scaledWidth, scaledHeight; + + if (srcAspect > destAspect) { + scaledWidth = destWidth; + scaledHeight = (int)((float)destWidth / srcAspect); + } else { + scaledHeight = destHeight; + scaledWidth = (int)((float)destHeight * srcAspect); + } + + int offsetX = (destWidth - scaledWidth) / 2; + int offsetY = (destHeight - scaledHeight) / 2; + int offs = offsetX + offsetY * destWidth; + + for (int y = 0; y < scaledHeight; ++y) { + for (int x = 0; x < scaledWidth; ++x) { + float srcX = + ((float)x + 0.5f) * ((float)srcWidth / (float)scaledWidth) - 0.5f; + float srcY = + ((float)y + 0.5f) * ((float)srcHeight / (float)scaledHeight) - 0.5f; + + srcX = std::max(0.0f, std::min(srcX, static_cast(srcWidth - 1))); + srcY = std::max(0.0f, std::min(srcY, static_cast(srcHeight - 1))); + + dest[y * destWidth + offs + x] = + InterpolatedRgb565Pixel(src, srcX, srcY, srcWidth, srcHeight); + } + } +} + +float FrameUtil::CalcBrightness(float x) { + // function to improve the brightness with fx=ax²+bc+c, f(0)=0, f(1)=1, + // f'(1.1)=0 + return (-x * x + 2.1f * x) / 1.1f; +} + +std::string FrameUtil::HexDump(const uint8_t* data, size_t size) { + constexpr int bytesPerLine = 32; + + std::stringstream ss; + + for (size_t i = 0; i < size; i += bytesPerLine) { + for (size_t j = i; j < i + bytesPerLine && j < size; ++j) + ss << std::setw(2) << std::setfill('0') << std::hex + << static_cast(data[j]) << ' '; + + for (size_t j = i; j < i + bytesPerLine && j < size; ++j) { + char ch = data[j]; + if (ch < 32 || ch > 126) ch = '.'; + ss << ch; + } + + ss << std::endl; + } + + return ss.str(); +} + +} // namespace DMDUtil diff --git a/src/FrameUtil.h b/src/FrameUtil.h index 2d37aeb..cadbf4b 100644 --- a/src/FrameUtil.h +++ b/src/FrameUtil.h @@ -1,30 +1,35 @@ -/* - * Portions of this code was derived from DMDExt - * - * https://github.com/freezy/dmd-extensions/blob/master/LibDmd/Common/FrameUtil.cs - */ - -#pragma once - -#include -#include - -namespace DMDUtil { - -enum class ColorMatrix { - Rgb, - Rbg -}; - -class FrameUtil { -public: - static inline int MapAdafruitIndex(int x, int y, int width, int height, int numLogicalRows); - static void SplitIntoRgbPlanes(const uint16_t* rgb565, int rgb565Size, int width, int numLogicalRows, uint8_t* dest, ColorMatrix colorMatrix = ColorMatrix::Rgb); - static inline uint16_t InterpolateRgb565Color(uint16_t color1, uint16_t color2, float ratio); - static inline uint16_t InterpolatedRgb565Pixel(const uint16_t* src, float srcX, float srcY, int srcWidth, int srcHeight); - static void ResizeRgb565Bilinear(const uint16_t* src, int srcWidth, int srcHeight, uint16_t* dest, int destWidth, int destHeight); - static float CalcBrightness(float x); - static std::string HexDump(const uint8_t* data, size_t size); -}; - -} \ No newline at end of file +/* + * Portions of this code was derived from DMDExt + * + * https://github.com/freezy/dmd-extensions/blob/master/LibDmd/Common/FrameUtil.cs + */ + +#pragma once + +#include +#include + +namespace DMDUtil { + +enum class ColorMatrix { Rgb, Rbg }; + +class FrameUtil { + public: + static inline int MapAdafruitIndex(int x, int y, int width, int height, + int numLogicalRows); + static void SplitIntoRgbPlanes(const uint16_t* rgb565, int rgb565Size, + int width, int numLogicalRows, uint8_t* dest, + ColorMatrix colorMatrix = ColorMatrix::Rgb); + static inline uint16_t InterpolateRgb565Color(uint16_t color1, + uint16_t color2, float ratio); + static inline uint16_t InterpolatedRgb565Pixel(const uint16_t* src, + float srcX, float srcY, + int srcWidth, int srcHeight); + static void ResizeRgb565Bilinear(const uint16_t* src, int srcWidth, + int srcHeight, uint16_t* dest, int destWidth, + int destHeight); + static float CalcBrightness(float x); + static std::string HexDump(const uint8_t* data, size_t size); +}; + +} // namespace DMDUtil diff --git a/src/Logger.cpp b/src/Logger.cpp index d74e125..651d3cb 100644 --- a/src/Logger.cpp +++ b/src/Logger.cpp @@ -1,20 +1,18 @@ -#include "Logger.h" - -#include "DMDUtil/Config.h" - -namespace DMDUtil { - -void Log(const char *format, ...) -{ - DMDUtil_LogCallback logCallback = Config::GetInstance()->GetLogCallback(); - - if (!logCallback) - return; - - va_list args; - va_start(args, format); - (*(logCallback))(format, args); - va_end(args); -} - -} \ No newline at end of file +#include "Logger.h" + +#include "DMDUtil/Config.h" + +namespace DMDUtil { + +void Log(const char *format, ...) { + DMDUtil_LogCallback logCallback = Config::GetInstance()->GetLogCallback(); + + if (!logCallback) return; + + va_list args; + va_start(args, format); + (*(logCallback))(format, args); + va_end(args); +} + +} // namespace DMDUtil diff --git a/src/Logger.h b/src/Logger.h index 0ce85cc..5e9f432 100644 --- a/src/Logger.h +++ b/src/Logger.h @@ -1,7 +1,7 @@ -#pragma once - -namespace DMDUtil { - -void Log(const char *format, ...); - -} +#pragma once + +namespace DMDUtil { + +void Log(const char *format, ...); + +} diff --git a/src/Pixelcade.cpp b/src/Pixelcade.cpp index 25767b7..51c134c 100644 --- a/src/Pixelcade.cpp +++ b/src/Pixelcade.cpp @@ -1,239 +1,240 @@ -/* - * Portions of this code was derived from DMDExt - * - * https://github.com/freezy/dmd-extensions/blob/master/LibDmd/Output/Pixelcade/Pixelcade.cs - */ - -#include "Pixelcade.h" -#include "FrameUtil.h" -#include "Logger.h" - -#include -#include -#include - -namespace DMDUtil { - -Pixelcade::Pixelcade(struct sp_port* pSerialPort, int width, int height) -{ - m_pSerialPort = pSerialPort; - m_width = width; - m_height = height; - m_length = width * height; - m_pThread = nullptr; - m_running = false; - - Run(); -} - -Pixelcade::~Pixelcade() -{ - if (m_pThread) { - m_running = false; - - m_pThread->join(); - delete m_pThread; - m_pThread = nullptr; - } - - while (!m_frames.empty()) { - free(m_frames.front()); - m_frames.pop(); - } -} - -Pixelcade* Pixelcade::Connect(const char* pDevice, int width, int height) -{ - Pixelcade* pPixelcade = nullptr; - - if (pDevice && *pDevice != 0) { - Log("Connecting to Pixelcade on %s...", pDevice); - - pPixelcade = Open(pDevice, width, height); - - if (!pPixelcade) - Log("Unable to connect to Pixelcade on %s", pDevice); - } - else { - Log("Searching for Pixelcade..."); - - struct sp_port** ppPorts; - enum sp_return result = sp_list_ports(&ppPorts); - if (result == SP_OK) { - for (int i = 0; ppPorts[i]; i++) { - pPixelcade = Open(sp_get_port_name(ppPorts[i]), width, height); - if (pPixelcade) - break; - } - sp_free_port_list(ppPorts); - } - - if (!pPixelcade) - Log("Unable to find Pixelcade"); - } - - return pPixelcade; -} - -Pixelcade* Pixelcade::Open(const char* pDevice, int width, int height) -{ - struct sp_port* pSerialPort = nullptr; - enum sp_return result = sp_get_port_by_name(pDevice, &pSerialPort); - if (result != SP_OK) - return nullptr; - - result = sp_open(pSerialPort, SP_MODE_READ_WRITE); - if (result != SP_OK) { - sp_free_port(pSerialPort); - return nullptr; - } - - sp_set_baudrate(pSerialPort, 115200); - sp_set_bits(pSerialPort, 8); - sp_set_parity(pSerialPort, SP_PARITY_NONE); - sp_set_stopbits(pSerialPort, 1); - sp_set_xon_xoff(pSerialPort, SP_XONXOFF_DISABLED); - - sp_set_dtr(pSerialPort, SP_DTR_OFF); - sp_set_rts(pSerialPort, SP_RTS_ON); - - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - - sp_set_dtr(pSerialPort, SP_DTR_ON); - - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - - unsigned char response[29]; - - result = sp_blocking_read(pSerialPort, response, 29, PIXELCADE_COMMAND_READ_TIMEOUT); - if (response[0] != PIXELCADE_RESPONSE_ESTABLE_CONNECTION) { - sp_close(pSerialPort); - sp_free_port(pSerialPort); - //Log("Pixelcade: expected new connection to return 0x0, but got 0x%02d", response[0]); - return nullptr; - } - - if (response[1] != 'I' || response[2] != 'O' || response[3] != 'I' || response[4] != 'O') { - sp_close(pSerialPort); - sp_free_port(pSerialPort); - //Log("Pixelcade: expected magic code to equal IOIO but got %c%c%c%c", response[1], response[2], response[3], response[4]); - return nullptr; - } - - char hardwareId[9] = {0}; - memcpy(hardwareId, response + 5, 8); - - char bootloaderId[9] = {0}; - memcpy(bootloaderId, response + 13, 8); - - char firmware[9] = {0}; - memcpy(firmware, response + 21, 8); - - Log("Pixelcade found: device=%s, Hardware ID=%s, Bootloader ID=%s, Firmware=%s", pDevice, hardwareId, bootloaderId, firmware); - - return new Pixelcade(pSerialPort, width, height); -} - -void Pixelcade::Update(uint16_t* pData) -{ - uint16_t* pFrame = (uint16_t*)malloc(m_length * sizeof(uint16_t)); - memcpy(pFrame, pData, m_length * sizeof(uint16_t)); - - { - std::lock_guard lock(m_mutex); - m_frames.push(pFrame); - } -} - -void Pixelcade::EnableRgbLedMatrix(int shifterLen32, int rows) -{ - uint8_t data[2] = { PIXELCADE_COMMAND_RGB_LED_MATRIX_ENABLE, (uint8_t)((shifterLen32 & 0x0F) | ((rows == 8 ? 0 : 1) << 4)) }; - sp_blocking_write(m_pSerialPort, data, 2, 0); -} - -void Pixelcade::Run() -{ - if (m_running) - return; - - m_running = true; - - m_pThread = new std::thread([this]() { - Log("Pixelcade run thread starting"); - EnableRgbLedMatrix(4, 16); - - int errors = 0; - - while (m_running) { - uint16_t* pFrame = nullptr; - - { - std::lock_guard lock(m_mutex); - if (!m_frames.empty()) { - pFrame = m_frames.front(); - m_frames.pop(); - } - - while (m_frames.size() > PIXELCADE_MAX_QUEUE_FRAMES) { - free(m_frames.front()); - m_frames.pop(); - } - } - - if (pFrame) { - uint8_t planes[128 * 32 * 3 / 2]; - if (m_width == 128 && m_height == 32) - FrameUtil::SplitIntoRgbPlanes(pFrame, 128 * 32, 128, 16, (uint8_t*)planes); - else { - uint16_t scaledFrame[128 * 32]; - FrameUtil::ResizeRgb565Bilinear(pFrame, m_width, m_height, scaledFrame, 128, 32); - FrameUtil::SplitIntoRgbPlanes(scaledFrame, 128 * 32, 128, 16, (uint8_t*)planes); - } - - static uint8_t command = PIXELCADE_COMMAND_RGB_LED_MATRIX_FRAME; - sp_blocking_write(m_pSerialPort, &command, 1, PIXELCADE_COMMAND_WRITE_TIMEOUT); - - enum sp_return response = sp_blocking_write(m_pSerialPort, planes, 128 * 32 * 3 / 2, PIXELCADE_COMMAND_WRITE_TIMEOUT); - - if (response > 0) { - if (errors > 0) { - Log("Communication to Pixelcade restored after %d frames", errors); - errors = 0; - } - } - else if (response == 0) { - if (errors++ > PIXELCADE_MAX_NO_RESPONSE) { - Log("Error while transmitting to Pixelcade: no response for the past %d frames", PIXELCADE_MAX_NO_RESPONSE); - m_running = false; - } - } - else if (response == SP_ERR_FAIL) { - char* pMessage = sp_last_error_message(); - Log("Error while transmitting to Pixelcade: %s", pMessage); - sp_free_error_message(pMessage); - m_running = false; - } - } - else - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - } - - sp_flush(m_pSerialPort, SP_BUF_BOTH); - - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - - sp_set_dtr(m_pSerialPort, SP_DTR_OFF); - sp_set_rts(m_pSerialPort, SP_RTS_OFF); - - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - - sp_close(m_pSerialPort); - sp_free_port(m_pSerialPort); - - m_pSerialPort = nullptr; - - Log("Pixelcade run thread finished"); - }); -} - -} \ No newline at end of file +/* + * Portions of this code was derived from DMDExt + * + * https://github.com/freezy/dmd-extensions/blob/master/LibDmd/Output/Pixelcade/Pixelcade.cs + */ + +#include "Pixelcade.h" + +#include +#include +#include + +#include "FrameUtil.h" +#include "Logger.h" + +namespace DMDUtil { + +Pixelcade::Pixelcade(struct sp_port* pSerialPort, int width, int height) { + m_pSerialPort = pSerialPort; + m_width = width; + m_height = height; + m_length = width * height; + m_pThread = nullptr; + m_running = false; + + Run(); +} + +Pixelcade::~Pixelcade() { + if (m_pThread) { + m_running = false; + + m_pThread->join(); + delete m_pThread; + m_pThread = nullptr; + } + + while (!m_frames.empty()) { + free(m_frames.front()); + m_frames.pop(); + } +} + +Pixelcade* Pixelcade::Connect(const char* pDevice, int width, int height) { + Pixelcade* pPixelcade = nullptr; + + if (pDevice && *pDevice != 0) { + Log("Connecting to Pixelcade on %s...", pDevice); + + pPixelcade = Open(pDevice, width, height); + + if (!pPixelcade) Log("Unable to connect to Pixelcade on %s", pDevice); + } else { + Log("Searching for Pixelcade..."); + + struct sp_port** ppPorts; + enum sp_return result = sp_list_ports(&ppPorts); + if (result == SP_OK) { + for (int i = 0; ppPorts[i]; i++) { + pPixelcade = Open(sp_get_port_name(ppPorts[i]), width, height); + if (pPixelcade) break; + } + sp_free_port_list(ppPorts); + } + + if (!pPixelcade) Log("Unable to find Pixelcade"); + } + + return pPixelcade; +} + +Pixelcade* Pixelcade::Open(const char* pDevice, int width, int height) { + struct sp_port* pSerialPort = nullptr; + enum sp_return result = sp_get_port_by_name(pDevice, &pSerialPort); + if (result != SP_OK) return nullptr; + + result = sp_open(pSerialPort, SP_MODE_READ_WRITE); + if (result != SP_OK) { + sp_free_port(pSerialPort); + return nullptr; + } + + sp_set_baudrate(pSerialPort, 115200); + sp_set_bits(pSerialPort, 8); + sp_set_parity(pSerialPort, SP_PARITY_NONE); + sp_set_stopbits(pSerialPort, 1); + sp_set_xon_xoff(pSerialPort, SP_XONXOFF_DISABLED); + + sp_set_dtr(pSerialPort, SP_DTR_OFF); + sp_set_rts(pSerialPort, SP_RTS_ON); + + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + sp_set_dtr(pSerialPort, SP_DTR_ON); + + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + unsigned char response[29]; + + result = sp_blocking_read(pSerialPort, response, 29, + PIXELCADE_COMMAND_READ_TIMEOUT); + if (response[0] != PIXELCADE_RESPONSE_ESTABLE_CONNECTION) { + sp_close(pSerialPort); + sp_free_port(pSerialPort); + // Log("Pixelcade: expected new connection to return 0x0, but got 0x%02d", + // response[0]); + return nullptr; + } + + if (response[1] != 'I' || response[2] != 'O' || response[3] != 'I' || + response[4] != 'O') { + sp_close(pSerialPort); + sp_free_port(pSerialPort); + // Log("Pixelcade: expected magic code to equal IOIO but got %c%c%c%c", + // response[1], response[2], response[3], response[4]); + return nullptr; + } + + char hardwareId[9] = {0}; + memcpy(hardwareId, response + 5, 8); + + char bootloaderId[9] = {0}; + memcpy(bootloaderId, response + 13, 8); + + char firmware[9] = {0}; + memcpy(firmware, response + 21, 8); + + Log("Pixelcade found: device=%s, Hardware ID=%s, Bootloader ID=%s, " + "Firmware=%s", + pDevice, hardwareId, bootloaderId, firmware); + + return new Pixelcade(pSerialPort, width, height); +} + +void Pixelcade::Update(uint16_t* pData) { + uint16_t* pFrame = (uint16_t*)malloc(m_length * sizeof(uint16_t)); + memcpy(pFrame, pData, m_length * sizeof(uint16_t)); + + { + std::lock_guard lock(m_mutex); + m_frames.push(pFrame); + } +} + +void Pixelcade::EnableRgbLedMatrix(int shifterLen32, int rows) { + uint8_t data[2] = { + PIXELCADE_COMMAND_RGB_LED_MATRIX_ENABLE, + (uint8_t)((shifterLen32 & 0x0F) | ((rows == 8 ? 0 : 1) << 4))}; + sp_blocking_write(m_pSerialPort, data, 2, 0); +} + +void Pixelcade::Run() { + if (m_running) return; + + m_running = true; + + m_pThread = new std::thread([this]() { + Log("Pixelcade run thread starting"); + EnableRgbLedMatrix(4, 16); + + int errors = 0; + + while (m_running) { + uint16_t* pFrame = nullptr; + + { + std::lock_guard lock(m_mutex); + if (!m_frames.empty()) { + pFrame = m_frames.front(); + m_frames.pop(); + } + + while (m_frames.size() > PIXELCADE_MAX_QUEUE_FRAMES) { + free(m_frames.front()); + m_frames.pop(); + } + } + + if (pFrame) { + uint8_t planes[128 * 32 * 3 / 2]; + if (m_width == 128 && m_height == 32) + FrameUtil::SplitIntoRgbPlanes(pFrame, 128 * 32, 128, 16, + (uint8_t*)planes); + else { + uint16_t scaledFrame[128 * 32]; + FrameUtil::ResizeRgb565Bilinear(pFrame, m_width, m_height, + scaledFrame, 128, 32); + FrameUtil::SplitIntoRgbPlanes(scaledFrame, 128 * 32, 128, 16, + (uint8_t*)planes); + } + + static uint8_t command = PIXELCADE_COMMAND_RGB_LED_MATRIX_FRAME; + sp_blocking_write(m_pSerialPort, &command, 1, + PIXELCADE_COMMAND_WRITE_TIMEOUT); + + enum sp_return response = + sp_blocking_write(m_pSerialPort, planes, 128 * 32 * 3 / 2, + PIXELCADE_COMMAND_WRITE_TIMEOUT); + + if (response > 0) { + if (errors > 0) { + Log("Communication to Pixelcade restored after %d frames", errors); + errors = 0; + } + } else if (response == 0) { + if (errors++ > PIXELCADE_MAX_NO_RESPONSE) { + Log("Error while transmitting to Pixelcade: no response for the " + "past %d frames", + PIXELCADE_MAX_NO_RESPONSE); + m_running = false; + } + } else if (response == SP_ERR_FAIL) { + char* pMessage = sp_last_error_message(); + Log("Error while transmitting to Pixelcade: %s", pMessage); + sp_free_error_message(pMessage); + m_running = false; + } + } else + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + + sp_flush(m_pSerialPort, SP_BUF_BOTH); + + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + sp_set_dtr(m_pSerialPort, SP_DTR_OFF); + sp_set_rts(m_pSerialPort, SP_RTS_OFF); + + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + sp_close(m_pSerialPort); + sp_free_port(m_pSerialPort); + + m_pSerialPort = nullptr; + + Log("Pixelcade run thread finished"); + }); +} + +} // namespace DMDUtil diff --git a/src/Pixelcade.h b/src/Pixelcade.h index 20df139..b7abeed 100644 --- a/src/Pixelcade.h +++ b/src/Pixelcade.h @@ -1,51 +1,50 @@ -/* - * Portions of this code was derived from DMDExt - * - * https://github.com/freezy/dmd-extensions/blob/master/LibDmd/Output/Pixelcade/Pixelcade.cs - */ - -#pragma once - -#include "libserialport.h" - -#include -#include -#include -#include - -#define PIXELCADE_RESPONSE_ESTABLE_CONNECTION 0x00 -#define PIXELCADE_COMMAND_RGB_LED_MATRIX_FRAME 0x1F -#define PIXELCADE_COMMAND_RGB_LED_MATRIX_ENABLE 0x1E -#define PIXELCADE_COMMAND_READ_TIMEOUT 100 -#define PIXELCADE_COMMAND_WRITE_TIMEOUT 100 -#define PIXELCADE_MAX_QUEUE_FRAMES 4 -#define PIXELCADE_MAX_NO_RESPONSE 20 - -namespace DMDUtil { - -class Pixelcade -{ -public: - Pixelcade(struct sp_port* pSerialPort, int width, int height); - ~Pixelcade(); - - static Pixelcade* Connect(const char* pDevice, int width, int height); - void Update(uint16_t* pData); - -private: - static Pixelcade* Open(const char* pDevice, int width, int height); - void Run(); - void EnableRgbLedMatrix(int shifterLen32, int rows); - - struct sp_port* m_pSerialPort; - int m_width; - int m_height; - int m_length; - - std::thread* m_pThread; - std::queue m_frames; - std::mutex m_mutex; - bool m_running; -}; - -} \ No newline at end of file +/* + * Portions of this code was derived from DMDExt + * + * https://github.com/freezy/dmd-extensions/blob/master/LibDmd/Output/Pixelcade/Pixelcade.cs + */ + +#pragma once + +#include +#include +#include +#include + +#include "libserialport.h" + +#define PIXELCADE_RESPONSE_ESTABLE_CONNECTION 0x00 +#define PIXELCADE_COMMAND_RGB_LED_MATRIX_FRAME 0x1F +#define PIXELCADE_COMMAND_RGB_LED_MATRIX_ENABLE 0x1E +#define PIXELCADE_COMMAND_READ_TIMEOUT 100 +#define PIXELCADE_COMMAND_WRITE_TIMEOUT 100 +#define PIXELCADE_MAX_QUEUE_FRAMES 4 +#define PIXELCADE_MAX_NO_RESPONSE 20 + +namespace DMDUtil { + +class Pixelcade { + public: + Pixelcade(struct sp_port* pSerialPort, int width, int height); + ~Pixelcade(); + + static Pixelcade* Connect(const char* pDevice, int width, int height); + void Update(uint16_t* pData); + + private: + static Pixelcade* Open(const char* pDevice, int width, int height); + void Run(); + void EnableRgbLedMatrix(int shifterLen32, int rows); + + struct sp_port* m_pSerialPort; + int m_width; + int m_height; + int m_length; + + std::thread* m_pThread; + std::queue m_frames; + std::mutex m_mutex; + bool m_running; +}; + +} // namespace DMDUtil diff --git a/src/Serum.cpp b/src/Serum.cpp index be0ea94..e46f5f9 100644 --- a/src/Serum.cpp +++ b/src/Serum.cpp @@ -1,74 +1,72 @@ -#include "Serum.h" -#include "serum-decode.h" -#include "DMDUtil/Config.h" -#include "Logger.h" - -#include - -namespace DMDUtil { - -bool Serum::m_isLoaded = false; - -Serum::Serum(int width, int height) -{ - m_width = width; - m_height = height; - m_length = width * height; - m_pFrame = (uint8_t*)malloc(m_length); - memset(m_pFrame, 0, m_length); -} - -Serum::~Serum() -{ - free(m_pFrame); - - Serum_Dispose(); - - m_isLoaded = false; -} - -Serum* Serum::Load(const std::string& romName) -{ - if (m_isLoaded) - return nullptr; - - std::string altColorPath = Config::GetInstance()->GetAltColorPath(); - - if (altColorPath.empty()) - return nullptr; - - int width; - int height; - unsigned int numColors; - unsigned int numTriggers; - - if (!Serum_Load(altColorPath.c_str(), romName.c_str(), &width, &height, &numColors, &numTriggers)) { - Serum_Dispose(); - return nullptr; - } - - Log("Serum loaded: romName=%s, width=%d, height=%d, numColors=%d, numTriggers=%d", romName.c_str(), width, height, numColors, numTriggers); - - m_isLoaded = true; - - return new Serum(width, height); -} - -bool Serum::Convert(uint8_t* pFrame, uint8_t* pDstFrame, uint8_t* pDstPalette) -{ - if (pFrame) - memcpy(m_pFrame, pFrame, m_length); - - unsigned int triggerId; - - if (Serum_ColorizeOrApplyRotations(pFrame ? m_pFrame : nullptr, m_width, m_height, m_palette, &triggerId)) { - memcpy(pDstFrame, m_pFrame, m_length); - memcpy(pDstPalette, m_palette, 192); - - return true; - } - - return false; -}; - -} +#include "Serum.h" + +#include + +#include "DMDUtil/Config.h" +#include "Logger.h" +#include "serum-decode.h" + +namespace DMDUtil { + +bool Serum::m_isLoaded = false; + +Serum::Serum(int width, int height) { + m_width = width; + m_height = height; + m_length = width * height; + m_pFrame = (uint8_t*)malloc(m_length); + memset(m_pFrame, 0, m_length); +} + +Serum::~Serum() { + free(m_pFrame); + + Serum_Dispose(); + + m_isLoaded = false; +} + +Serum* Serum::Load(const std::string& romName) { + if (m_isLoaded) return nullptr; + + std::string altColorPath = Config::GetInstance()->GetAltColorPath(); + + if (altColorPath.empty()) return nullptr; + + int width; + int height; + unsigned int numColors; + unsigned int numTriggers; + + if (!Serum_Load(altColorPath.c_str(), romName.c_str(), &width, &height, + &numColors, &numTriggers)) { + Serum_Dispose(); + return nullptr; + } + + Log("Serum loaded: romName=%s, width=%d, height=%d, numColors=%d, " + "numTriggers=%d", + romName.c_str(), width, height, numColors, numTriggers); + + m_isLoaded = true; + + return new Serum(width, height); +} + +bool Serum::Convert(uint8_t* pFrame, uint8_t* pDstFrame, uint8_t* pDstPalette) { + if (pFrame) memcpy(m_pFrame, pFrame, m_length); + + unsigned int triggerId; + + if (Serum_ColorizeOrApplyRotations(pFrame ? m_pFrame : nullptr, m_width, + m_height, m_palette, &triggerId)) { + memcpy(pDstFrame, m_pFrame, m_length); + memcpy(pDstPalette, m_palette, 192); + + return true; + } + + return false; +}; + +} // namespace DMDUtil diff --git a/src/Serum.h b/src/Serum.h index 7808de9..2c17a93 100644 --- a/src/Serum.h +++ b/src/Serum.h @@ -1,27 +1,27 @@ -#pragma once - -#include -#include - -namespace DMDUtil { - -class Serum { -public: - ~Serum(); - - static Serum* Load(const std::string& romName); - bool Convert(uint8_t* pFrame, uint8_t* pDstFrame, uint8_t* pDstPalette); - -private: - Serum(int width, int height); - - int m_width; - int m_height; - int m_length; - uint8_t* m_pFrame; - uint8_t m_palette[64 * 3]; - - static bool m_isLoaded; -}; - -} \ No newline at end of file +#pragma once + +#include +#include + +namespace DMDUtil { + +class Serum { + public: + ~Serum(); + + static Serum* Load(const std::string& romName); + bool Convert(uint8_t* pFrame, uint8_t* pDstFrame, uint8_t* pDstPalette); + + private: + Serum(int width, int height); + + int m_width; + int m_height; + int m_length; + uint8_t* m_pFrame; + uint8_t m_palette[64 * 3]; + + static bool m_isLoaded; +}; + +} // namespace DMDUtil diff --git a/src/test.cpp b/src/test.cpp index b86d184..722fa1b 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -1,104 +1,100 @@ -#include "DMDUtil/DMDUtil.h" - #include #include -void DMDUTILCALLBACK LogCallback(const char* format, va_list args) -{ - char buffer[1024]; - vsnprintf(buffer, sizeof(buffer), format, args); - printf("%s\n", buffer); +#include "DMDUtil/DMDUtil.h" + +void DMDUTILCALLBACK LogCallback(const char* format, va_list args) { + char buffer[1024]; + vsnprintf(buffer, sizeof(buffer), format, args); + printf("%s\n", buffer); } -uint8_t* CreateImage(int width, int height, int depth) -{ - uint8_t* pImage = (uint8_t*)malloc(width * height); - int pos = 0; - for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) - pImage[pos++] = x % ((depth == 2) ? 4 : 16); - } +uint8_t* CreateImage(int width, int height, int depth) { + uint8_t* pImage = (uint8_t*)malloc(width * height); + int pos = 0; + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) pImage[pos++] = x % ((depth == 2) ? 4 : 16); + } - return pImage; + return pImage; } -uint8_t* CreateImageRGB24(int width, int height) -{ - uint8_t* pImage = (uint8_t*)malloc(width * height * 3); - for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) { - int index = (y * width + x) * 3; - pImage[index++] = (uint8_t)(255 * x / width); - pImage[index++] = (uint8_t)(255 * y / height); - pImage[index] = (uint8_t)(128); - } - } - - return pImage; +uint8_t* CreateImageRGB24(int width, int height) { + uint8_t* pImage = (uint8_t*)malloc(width * height * 3); + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { + int index = (y * width + x) * 3; + pImage[index++] = (uint8_t)(255 * x / width); + pImage[index++] = (uint8_t)(255 * y / height); + pImage[index] = (uint8_t)(128); + } + } + + return pImage; } int main(int argc, const char* argv[]) { - DMDUtil::Config* pConfig = DMDUtil::Config::GetInstance(); - pConfig->SetLogCallback(LogCallback); + DMDUtil::Config* pConfig = DMDUtil::Config::GetInstance(); + pConfig->SetLogCallback(LogCallback); - int width = 128; - int height = 32; + int width = 128; + int height = 32; - DMDUtil::DMD* pDmd = new DMDUtil::DMD(width, height); + DMDUtil::DMD* pDmd = new DMDUtil::DMD(width, height); - printf("Finding displays...\n"); + printf("Finding displays...\n"); - while (DMDUtil::DMD::IsFinding()) - std::this_thread::sleep_for(std::chrono::milliseconds(100)); + while (DMDUtil::DMD::IsFinding()) + std::this_thread::sleep_for(std::chrono::milliseconds(100)); - if (!pDmd->HasDisplay()) { - printf("No displays to render.\n"); - delete pDmd; - return 1; - } + if (!pDmd->HasDisplay()) { + printf("No displays to render.\n"); + delete pDmd; + return 1; + } - printf("Rendering...\n"); + printf("Rendering...\n"); - uint8_t* pImage2 = CreateImage(pDmd->GetWidth(), pDmd->GetHeight(), 2); - uint8_t* pImage4 = CreateImage(pDmd->GetWidth(), pDmd->GetHeight(), 4); - uint8_t* pImage24 = CreateImageRGB24(pDmd->GetWidth(), pDmd->GetHeight()); + uint8_t* pImage2 = CreateImage(pDmd->GetWidth(), pDmd->GetHeight(), 2); + uint8_t* pImage4 = CreateImage(pDmd->GetWidth(), pDmd->GetHeight(), 4); + uint8_t* pImage24 = CreateImageRGB24(pDmd->GetWidth(), pDmd->GetHeight()); - for (int i = 0; i < 4; i++) { - pDmd->UpdateData(pImage2, 2, 255, 0, 0); - std::this_thread::sleep_for(std::chrono::milliseconds(200)); + for (int i = 0; i < 4; i++) { + pDmd->UpdateData(pImage2, 2, 255, 0, 0); + std::this_thread::sleep_for(std::chrono::milliseconds(200)); - pDmd->UpdateData(pImage2, 2, 0, 255, 0); - std::this_thread::sleep_for(std::chrono::milliseconds(200)); + pDmd->UpdateData(pImage2, 2, 0, 255, 0); + std::this_thread::sleep_for(std::chrono::milliseconds(200)); - pDmd->UpdateData(pImage2, 2, 0, 0, 255); - std::this_thread::sleep_for(std::chrono::milliseconds(200)); + pDmd->UpdateData(pImage2, 2, 0, 0, 255); + std::this_thread::sleep_for(std::chrono::milliseconds(200)); - pDmd->UpdateData(pImage2, 2, 255, 255, 255); - std::this_thread::sleep_for(std::chrono::milliseconds(200)); + pDmd->UpdateData(pImage2, 2, 255, 255, 255); + std::this_thread::sleep_for(std::chrono::milliseconds(200)); - pDmd->UpdateData(pImage4, 4, 255, 0, 0); - std::this_thread::sleep_for(std::chrono::milliseconds(200)); + pDmd->UpdateData(pImage4, 4, 255, 0, 0); + std::this_thread::sleep_for(std::chrono::milliseconds(200)); - pDmd->UpdateData(pImage4, 4, 0, 255, 0); - std::this_thread::sleep_for(std::chrono::milliseconds(200)); + pDmd->UpdateData(pImage4, 4, 0, 255, 0); + std::this_thread::sleep_for(std::chrono::milliseconds(200)); - pDmd->UpdateData(pImage4, 4, 0, 0, 255); - std::this_thread::sleep_for(std::chrono::milliseconds(200)); + pDmd->UpdateData(pImage4, 4, 0, 0, 255); + std::this_thread::sleep_for(std::chrono::milliseconds(200)); - pDmd->UpdateData(pImage4, 4, 255, 255, 255); - std::this_thread::sleep_for(std::chrono::milliseconds(200)); + pDmd->UpdateData(pImage4, 4, 255, 255, 255); + std::this_thread::sleep_for(std::chrono::milliseconds(200)); - pDmd->UpdateRGB24Data(pImage24, 24, 0, 0, 0); - std::this_thread::sleep_for(std::chrono::milliseconds(200)); - } + pDmd->UpdateRGB24Data(pImage24, 24, 0, 0, 0); + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + } - printf("Finished rendering\n"); + printf("Finished rendering\n"); - free(pImage2); - free(pImage4); - free(pImage24); + free(pImage2); + free(pImage4); + free(pImage24); - delete pDmd; + delete pDmd; - return 0; -} \ No newline at end of file + return 0; +} From b801211069a824a1efd9194cde57997813239007 Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Mon, 22 Jan 2024 19:17:45 +0100 Subject: [PATCH 2/2] formatted header files --- include/DMDUtil/Config.h | 96 ++++++++++--------- include/DMDUtil/DMD.h | 190 +++++++++++++++++++------------------- include/DMDUtil/DMDUtil.h | 18 ++-- 3 files changed, 158 insertions(+), 146 deletions(-) diff --git a/include/DMDUtil/Config.h b/include/DMDUtil/Config.h index c64f51c..ce1efd6 100644 --- a/include/DMDUtil/Config.h +++ b/include/DMDUtil/Config.h @@ -8,56 +8,60 @@ #define DMDUTILCALLBACK #endif -#include #include +#include -typedef void(DMDUTILCALLBACK *DMDUtil_LogCallback)(const char *format, va_list args); +typedef void(DMDUTILCALLBACK* DMDUtil_LogCallback)(const char* format, + va_list args); namespace DMDUtil { -class DMDUTILAPI Config -{ -public: - static Config* GetInstance(); - bool IsAltColor() const { return m_altColor; } - void SetAltColor(bool altColor) { m_altColor = altColor; } - void SetAltColorPath(const char* path) { m_altColorPath = path; } - bool IsZeDMD() const { return m_zedmd; } - void SetZeDMD(bool zedmd) { m_zedmd = zedmd; } - const char* GetZeDMDDevice() const { return m_zedmdDevice.c_str(); } - void SetZeDMDDevice(const char* port) { m_zedmdDevice = port; } - bool IsZeDMDDebug() const { return m_zedmdDebug; } - void SetZeDMDDebug(bool debug) { m_zedmdDebug = debug; } - int GetZeDMDRGBOrder() const { return m_zedmdRgbOrder; } - void SetZeDMDRGBOrder(int rgbOrder) { m_zedmdRgbOrder = rgbOrder; } - int GetZeDMDBrightness() const { return m_zedmdBrightness; } - void SetZeDMDBrightness(int brightness) { m_zedmdBrightness = brightness; } - bool IsZeDMDSaveSettings() const { return m_zedmdSaveSettings; } - void SetZeDMDSaveSettings(bool saveSettings) { m_zedmdSaveSettings = saveSettings; } - bool IsPixelcade() const { return m_pixelcade; } - void SetPixelcade(bool pixelcade) { m_pixelcade = pixelcade; } - void SetPixelcadeDevice(const char* port) { m_pixelcadeDevice = port; } - const char* GetPixelcadeDevice() const { return m_pixelcadeDevice.c_str(); } - const DMDUtil_LogCallback GetLogCallback() const { return m_logCallback; } - void SetLogCallback(DMDUtil_LogCallback callback) { m_logCallback = callback; } - const char* GetAltColorPath() const { return m_altColorPath.c_str(); } - -private: - Config(); - ~Config() {} - - static Config* m_pInstance; - bool m_altColor; - std::string m_altColorPath; - bool m_zedmd; - std::string m_zedmdDevice; - bool m_zedmdDebug; - int m_zedmdRgbOrder; - int m_zedmdBrightness; - bool m_zedmdSaveSettings; - bool m_pixelcade; - std::string m_pixelcadeDevice; - DMDUtil_LogCallback m_logCallback; +class DMDUTILAPI Config { + public: + static Config* GetInstance(); + bool IsAltColor() const { return m_altColor; } + void SetAltColor(bool altColor) { m_altColor = altColor; } + void SetAltColorPath(const char* path) { m_altColorPath = path; } + bool IsZeDMD() const { return m_zedmd; } + void SetZeDMD(bool zedmd) { m_zedmd = zedmd; } + const char* GetZeDMDDevice() const { return m_zedmdDevice.c_str(); } + void SetZeDMDDevice(const char* port) { m_zedmdDevice = port; } + bool IsZeDMDDebug() const { return m_zedmdDebug; } + void SetZeDMDDebug(bool debug) { m_zedmdDebug = debug; } + int GetZeDMDRGBOrder() const { return m_zedmdRgbOrder; } + void SetZeDMDRGBOrder(int rgbOrder) { m_zedmdRgbOrder = rgbOrder; } + int GetZeDMDBrightness() const { return m_zedmdBrightness; } + void SetZeDMDBrightness(int brightness) { m_zedmdBrightness = brightness; } + bool IsZeDMDSaveSettings() const { return m_zedmdSaveSettings; } + void SetZeDMDSaveSettings(bool saveSettings) { + m_zedmdSaveSettings = saveSettings; + } + bool IsPixelcade() const { return m_pixelcade; } + void SetPixelcade(bool pixelcade) { m_pixelcade = pixelcade; } + void SetPixelcadeDevice(const char* port) { m_pixelcadeDevice = port; } + const char* GetPixelcadeDevice() const { return m_pixelcadeDevice.c_str(); } + const DMDUtil_LogCallback GetLogCallback() const { return m_logCallback; } + void SetLogCallback(DMDUtil_LogCallback callback) { + m_logCallback = callback; + } + const char* GetAltColorPath() const { return m_altColorPath.c_str(); } + + private: + Config(); + ~Config() {} + + static Config* m_pInstance; + bool m_altColor; + std::string m_altColorPath; + bool m_zedmd; + std::string m_zedmdDevice; + bool m_zedmdDebug; + int m_zedmdRgbOrder; + int m_zedmdBrightness; + bool m_zedmdSaveSettings; + bool m_pixelcade; + std::string m_pixelcadeDevice; + DMDUtil_LogCallback m_logCallback; }; -} \ No newline at end of file +} // namespace DMDUtil \ No newline at end of file diff --git a/include/DMDUtil/DMD.h b/include/DMDUtil/DMD.h index 7165023..099720a 100644 --- a/include/DMDUtil/DMD.h +++ b/include/DMDUtil/DMD.h @@ -9,10 +9,10 @@ #endif #include +#include +#include #include #include -#include -#include #if defined(__APPLE__) #include @@ -23,105 +23,109 @@ class ZeDMD; namespace DMDUtil { enum class AlphaNumericLayout { - NoLayout, - __2x16Alpha, - __2x20Alpha, - __2x7Alpha_2x7Num, - __2x7Alpha_2x7Num_4x1Num, - __2x7Num_2x7Num_4x1Num, - __2x7Num_2x7Num_10x1Num, - __2x7Num_2x7Num_4x1Num_gen7, - __2x7Num10_2x7Num10_4x1Num, - __2x6Num_2x6Num_4x1Num, - __2x6Num10_2x6Num10_4x1Num, - __4x7Num10, - __6x4Num_4x1Num, - __2x7Num_4x1Num_1x16Alpha, - __1x16Alpha_1x16Num_1x7Num, - __1x7Num_1x16Alpha_1x16Num, - __1x16Alpha_1x16Num_1x7Num_1x4Num + NoLayout, + __2x16Alpha, + __2x20Alpha, + __2x7Alpha_2x7Num, + __2x7Alpha_2x7Num_4x1Num, + __2x7Num_2x7Num_4x1Num, + __2x7Num_2x7Num_10x1Num, + __2x7Num_2x7Num_4x1Num_gen7, + __2x7Num10_2x7Num10_4x1Num, + __2x6Num_2x6Num_4x1Num, + __2x6Num10_2x6Num10_4x1Num, + __4x7Num10, + __6x4Num_4x1Num, + __2x7Num_4x1Num_1x16Alpha, + __1x16Alpha_1x16Num_1x7Num, + __1x7Num_1x16Alpha_1x16Num, + __1x16Alpha_1x16Num_1x7Num_1x4Num }; class AlphaNumeric; class Serum; class Pixelcade; -class DMDUTILAPI DMD -{ -public: - DMD(int width, int height, bool sam = false, const char* name = nullptr); - ~DMD(); - - static bool IsFinding(); - bool HasDisplay() const; - int GetWidth() const { return m_width; } - int GetHeight() const { return m_height; } - int GetLength() const { return m_length; } - bool IsUpdated() const { return m_updated; } - void ResetUpdated() { m_updated = false; } - void UpdateData(const uint8_t* pData, int depth, uint8_t r, uint8_t g, uint8_t b); - void UpdateRGB24Data(const uint8_t* pData, int depth, uint8_t r, uint8_t g, uint8_t b); - void UpdateAlphaNumericData(AlphaNumericLayout layout, const uint16_t* pData1, const uint16_t* pData2, uint8_t r, uint8_t g, uint8_t b); - const uint8_t* GetLevelData() const { return m_pLevelData; } - const uint32_t* GetRGB32Data() const { return m_pRGB32Data; } - -private: - enum class DmdMode { - Unknown, - Data, - RGB24, - AlphaNumeric - }; - - struct DMDUpdate { - DmdMode mode; - AlphaNumericLayout layout; - int depth; - void* pData; - void* pData2; - uint8_t r; - uint8_t g; - uint8_t b; - }; - - static constexpr uint8_t LEVELS_WPC[] = { 0x14, 0x21, 0x43, 0x64 }; - static constexpr uint8_t LEVELS_GTS3[] = { 0x00, 0x1E, 0x23, 0x28, 0x2D, 0x32, 0x37, 0x3C, 0x41, 0x46, 0x4B, 0x50, 0x55, 0x5A, 0x5F, 0x64 }; - static constexpr uint8_t LEVELS_SAM[] = { 0x00, 0x14, 0x19, 0x1E, 0x23, 0x28, 0x2D, 0x32, 0x37, 0x3C, 0x41, 0x46, 0x4B, 0x50, 0x5A, 0x64 }; - - void FindDevices(); - void Run(); - void Stop(); - bool UpdatePalette(const DMDUpdate* pUpdate); - void UpdateData(const DMDUpdate* pUpdate, bool update); - void UpdateRGB24Data(const DMDUpdate* pUpdate, bool update); - void UpdateAlphaNumericData(const DMDUpdate* pUpdate, bool update); - - int m_width; - int m_height; - int m_length; - bool m_sam; - uint8_t* m_pData; - uint8_t* m_pRGB24Data; - uint16_t m_segData1[128]; - uint16_t m_segData2[128]; - uint8_t* m_pLevelData; - uint32_t* m_pRGB32Data; - uint16_t* m_pRGB565Data; - uint8_t m_palette[192]; - AlphaNumeric* m_pAlphaNumeric; - Serum* m_pSerum; - ZeDMD* m_pZeDMD; -#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || defined(__ANDROID__)) - Pixelcade* m_pPixelcade; +class DMDUTILAPI DMD { + public: + DMD(int width, int height, bool sam = false, const char* name = nullptr); + ~DMD(); + + static bool IsFinding(); + bool HasDisplay() const; + int GetWidth() const { return m_width; } + int GetHeight() const { return m_height; } + int GetLength() const { return m_length; } + bool IsUpdated() const { return m_updated; } + void ResetUpdated() { m_updated = false; } + void UpdateData(const uint8_t* pData, int depth, uint8_t r, uint8_t g, + uint8_t b); + void UpdateRGB24Data(const uint8_t* pData, int depth, uint8_t r, uint8_t g, + uint8_t b); + void UpdateAlphaNumericData(AlphaNumericLayout layout, const uint16_t* pData1, + const uint16_t* pData2, uint8_t r, uint8_t g, + uint8_t b); + const uint8_t* GetLevelData() const { return m_pLevelData; } + const uint32_t* GetRGB32Data() const { return m_pRGB32Data; } + + private: + enum class DmdMode { Unknown, Data, RGB24, AlphaNumeric }; + + struct DMDUpdate { + DmdMode mode; + AlphaNumericLayout layout; + int depth; + void* pData; + void* pData2; + uint8_t r; + uint8_t g; + uint8_t b; + }; + + static constexpr uint8_t LEVELS_WPC[] = {0x14, 0x21, 0x43, 0x64}; + static constexpr uint8_t LEVELS_GTS3[] = {0x00, 0x1E, 0x23, 0x28, 0x2D, 0x32, + 0x37, 0x3C, 0x41, 0x46, 0x4B, 0x50, + 0x55, 0x5A, 0x5F, 0x64}; + static constexpr uint8_t LEVELS_SAM[] = {0x00, 0x14, 0x19, 0x1E, 0x23, 0x28, + 0x2D, 0x32, 0x37, 0x3C, 0x41, 0x46, + 0x4B, 0x50, 0x5A, 0x64}; + + void FindDevices(); + void Run(); + void Stop(); + bool UpdatePalette(const DMDUpdate* pUpdate); + void UpdateData(const DMDUpdate* pUpdate, bool update); + void UpdateRGB24Data(const DMDUpdate* pUpdate, bool update); + void UpdateAlphaNumericData(const DMDUpdate* pUpdate, bool update); + + int m_width; + int m_height; + int m_length; + bool m_sam; + uint8_t* m_pData; + uint8_t* m_pRGB24Data; + uint16_t m_segData1[128]; + uint16_t m_segData2[128]; + uint8_t* m_pLevelData; + uint32_t* m_pRGB32Data; + uint16_t* m_pRGB565Data; + uint8_t m_palette[192]; + AlphaNumeric* m_pAlphaNumeric; + Serum* m_pSerum; + ZeDMD* m_pZeDMD; +#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || \ + (defined(TARGET_OS_TV) && TARGET_OS_TV))) || \ + defined(__ANDROID__)) + Pixelcade* m_pPixelcade; #endif - bool m_updated; + bool m_updated; - std::thread* m_pThread; - std::queue m_updates; - std::mutex m_mutex; - bool m_running; + std::thread* m_pThread; + std::queue m_updates; + std::mutex m_mutex; + bool m_running; - static bool m_finding; + static bool m_finding; }; -} +} // namespace DMDUtil diff --git a/include/DMDUtil/DMDUtil.h b/include/DMDUtil/DMDUtil.h index e3963c6..febcdd3 100644 --- a/include/DMDUtil/DMDUtil.h +++ b/include/DMDUtil/DMDUtil.h @@ -1,14 +1,18 @@ #pragma once -#define DMDUTIL_VERSION_MAJOR 0 // X Digits -#define DMDUTIL_VERSION_MINOR 1 // Max 2 Digits -#define DMDUTIL_VERSION_PATCH 0 // Max 2 Digits +#define DMDUTIL_VERSION_MAJOR 0 // X Digits +#define DMDUTIL_VERSION_MINOR 1 // Max 2 Digits +#define DMDUTIL_VERSION_PATCH 0 // Max 2 Digits #define _DMDUTIL_STR(x) #x #define DMDUTIL_STR(x) _DMDUTIL_STR(x) -#define DMDUTIL_VERSION DMDUTIL_STR(DMDUTIL_VERSION_MAJOR) "." DMDUTIL_STR(DMDUTIL_VERSION_MINOR) "." DMDUTIL_STR(DMDUTIL_VERSION_PATCH) -#define DMDUTIL_MINOR_VERSION DMDUTIL_STR(DMDUTIL_VERSION_MAJOR) "." DMDUTIL_STR(DMDUTIL_VERSION_MINOR) +#define DMDUTIL_VERSION \ + DMDUTIL_STR(DMDUTIL_VERSION_MAJOR) \ + "." DMDUTIL_STR(DMDUTIL_VERSION_MINOR) "." DMDUTIL_STR( \ + DMDUTIL_VERSION_PATCH) +#define DMDUTIL_MINOR_VERSION \ + DMDUTIL_STR(DMDUTIL_VERSION_MAJOR) "." DMDUTIL_STR(DMDUTIL_VERSION_MINOR) -#include "DMD.h" -#include "Config.h" \ No newline at end of file +#include "Config.h" +#include "DMD.h" \ No newline at end of file