|
|
|
|
@ -1,6 +1,7 @@ |
|
|
|
|
#include "monoformat_parseonly.hpp" |
|
|
|
|
#include "monoformat_parsehelpers.hpp" |
|
|
|
|
#include "monoformat_fontreader.hpp" |
|
|
|
|
#include "monoformat_bithelpers.hpp" |
|
|
|
|
|
|
|
|
|
#include <string_view> |
|
|
|
|
#include <string> |
|
|
|
|
@ -58,10 +59,15 @@ static std::expected<AlwaysDrawnSectionMetaData, ParseError> parseAlwaysDrawnSec |
|
|
|
|
data = data.subspan(*size - 8); |
|
|
|
|
|
|
|
|
|
AlwaysDrawnSectionMetaData result; |
|
|
|
|
result.drawOnFront = (((*flags) >> 0u) & 0x01u) == 0x01u; |
|
|
|
|
result.drawOnBack = (((*flags) >> 0u) & 0x02u) == 0x02u; |
|
|
|
|
result.clearBeforeDrawing = (((*flags) >> 0u) & 0x04u) == 0x04u; |
|
|
|
|
result.drawOnFront = isBitSet(*flags, 0); |
|
|
|
|
result.drawOnBack = isBitSet(*flags, 1); |
|
|
|
|
result.clearBeforeDrawing = isBitSet(*flags, 2); |
|
|
|
|
result.elementData = sectionData; |
|
|
|
|
|
|
|
|
|
#if defined(DEBUG) |
|
|
|
|
std::cerr << "[Debug] AlwaysDrawnSection, drawOnFront = " << result.drawOnFront << ", drawOnBack = " << result.drawOnBack << ", clearBeforeDrawing = " << result.clearBeforeDrawing << ", element data size = " << result.elementData.size() << " bytes" << std::endl; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -100,12 +106,17 @@ static std::expected<TimeBasedDrawnSectionMetaData, ParseError> parseTimeBasedDr |
|
|
|
|
data = data.subspan(*size - 24); |
|
|
|
|
|
|
|
|
|
TimeBasedDrawnSectionMetaData result; |
|
|
|
|
result.base.drawOnFront = (((*flags) >> 0u) & 0x01u) == 0x01u; |
|
|
|
|
result.base.drawOnBack = (((*flags) >> 0u) & 0x02u) == 0x02u; |
|
|
|
|
result.base.clearBeforeDrawing = (((*flags) >> 0u) & 0x04u) == 0x04u; |
|
|
|
|
result.base.drawOnFront = isBitSet(*flags, 0); |
|
|
|
|
result.base.drawOnBack = isBitSet(*flags, 1); |
|
|
|
|
result.base.clearBeforeDrawing = isBitSet(*flags, 2); |
|
|
|
|
result.base.elementData = sectionData; |
|
|
|
|
result.startTimestamp = std::bit_cast<std::int64_t>(*startTimestamp); |
|
|
|
|
result.endTimestamp = std::bit_cast<std::int64_t>(*endTimestamp); |
|
|
|
|
|
|
|
|
|
#if defined(DEBUG) |
|
|
|
|
std::cerr << "[Debug] TimeBasedDrawnSection, drawOnFront = " << result.base.drawOnFront << ", drawOnBack = " << result.base.drawOnBack << ", clearBeforeDrawing = " << result.base.clearBeforeDrawing << ", element data size = " << result.base.elementData.size() << " bytes, timestamp between " << result.startTimestamp << " and " << result.endTimestamp << std::endl; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -135,6 +146,10 @@ static std::expected<std::span<std::byte const>, ParseError> parseCustomFontSect |
|
|
|
|
auto fontData = data.subspan(0, *size - 8); |
|
|
|
|
data = data.subspan(*size - 8); |
|
|
|
|
|
|
|
|
|
#if defined(DEBUG) |
|
|
|
|
std::cerr << "[Debug] CustomFontSection, font data size = " << *actualSize << " bytes" << std::endl; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
return readBuffer(fontData, *actualSize); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -292,6 +307,10 @@ std::expected<void, ParseError> handleImage(std::span<std::byte const>& buffer, |
|
|
|
|
buffer = buffer.subspan(rounded - imageSize); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if defined(DEBUG) |
|
|
|
|
std::cerr << "[Debug] - Image, x = " << (*x) << ", y = " << (*y) << ", width = " << (*width) << ", height = " << (*height) << std::endl; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
std::ignore = animationTick; |
|
|
|
|
std::ignore = currentTimestamp; |
|
|
|
|
std::ignore = customFonts; |
|
|
|
|
@ -345,15 +364,22 @@ std::expected<void, ParseError> handleAnimation(std::span<std::byte const>& buff |
|
|
|
|
return std::unexpected(reserved_.error()); |
|
|
|
|
} |
|
|
|
|
std::size_t imageSize = ((*width) * (*height) + 8 - 1) / 8; |
|
|
|
|
auto imageData = readBuffer(buffer, imageSize); |
|
|
|
|
auto imageData = readBuffer(buffer, imageSize * (*numberOfFrames)); |
|
|
|
|
if (!imageData) { |
|
|
|
|
return std::unexpected(reserved_.error()); |
|
|
|
|
} |
|
|
|
|
std::size_t rounded = (imageSize + 4 - 1) / 4 * 4; |
|
|
|
|
if (imageSize < rounded) { |
|
|
|
|
buffer = buffer.subspan(rounded - imageSize); |
|
|
|
|
std::size_t rounded = (imageSize * (*numberOfFrames) + 4 - 1) / 4 * 4; |
|
|
|
|
if (imageSize * (*numberOfFrames) < rounded) { |
|
|
|
|
buffer = buffer.subspan(rounded - imageSize * (*numberOfFrames)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if defined(DEBUG) |
|
|
|
|
std::cerr << "[Debug] - Animation, x = " << (*x) << ", y = " << (*y) << ", width = " << (*width) << ", height = " << (*height) |
|
|
|
|
<< ", numberOfFrames = " << (*numberOfFrames) |
|
|
|
|
<< ", updateInterval = " << (*updateInterval) |
|
|
|
|
<< std::endl; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
if (*numberOfFrames == 0) { |
|
|
|
|
return {}; |
|
|
|
|
} |
|
|
|
|
@ -426,14 +452,22 @@ std::expected<void, ParseError> handleHScrollImage(std::span<std::byte const>& b |
|
|
|
|
auto ownImage = ConstMemoryOneBitBuffer{*imageData, *contentWidth, *height}; |
|
|
|
|
ClippedImage target{screen, *x, *y, *width, *height}; |
|
|
|
|
|
|
|
|
|
#if defined(DEBUG) |
|
|
|
|
std::cerr << "[Debug] - HScrollImage, x = " << (*x) << ", y = " << (*y) << ", width = " << (*width) << ", height = " << (*height) |
|
|
|
|
<< ", contentWidth = " << (*contentWidth) |
|
|
|
|
<< ", scrollSpeed = " << int(*scrollSpeed) |
|
|
|
|
<< ", flags = " << int(*flags) |
|
|
|
|
<< std::endl; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
if (*contentWidth == 0) { |
|
|
|
|
return {}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool restarting = ((*flags) & 0x01) == 0x00; |
|
|
|
|
bool invert = ((*flags) & 0x02) == 0x02; |
|
|
|
|
bool padBefore = ((*flags) & 0x04) == 0x04; |
|
|
|
|
bool padAfter = ((*flags) & 0x08) == 0x08; |
|
|
|
|
bool restarting = !isBitSet(*flags, 0); |
|
|
|
|
bool invert = isBitSet(*flags, 1); |
|
|
|
|
bool padBefore = isBitSet(*flags, 2); |
|
|
|
|
bool padAfter = isBitSet(*flags, 3); |
|
|
|
|
|
|
|
|
|
if (!padBefore && !padAfter && *contentWidth < *width) { |
|
|
|
|
std::int16_t offset = invert ? (*width - *contentWidth) : 0; |
|
|
|
|
@ -581,14 +615,22 @@ std::expected<void, ParseError> handleVScrollImage(std::span<std::byte const>& b |
|
|
|
|
auto ownImage = ConstMemoryOneBitBuffer{*imageData, *width, *contentHeight}; |
|
|
|
|
ClippedImage target{screen, *x, *y, *width, *height}; |
|
|
|
|
|
|
|
|
|
#if defined(DEBUG) |
|
|
|
|
std::cerr << "[Debug] - VScrollImage, x = " << (*x) << ", y = " << (*y) << ", width = " << (*width) << ", height = " << (*height) |
|
|
|
|
<< ", contentHeight = " << (*contentHeight) |
|
|
|
|
<< ", scrollSpeed = " << int(*scrollSpeed) |
|
|
|
|
<< ", flags = " << int(*flags) |
|
|
|
|
<< std::endl; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
if (*contentHeight == 0) { |
|
|
|
|
return {}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool restarting = ((*flags) & 0x01) == 0x00; |
|
|
|
|
bool invert = ((*flags) & 0x02) == 0x02; |
|
|
|
|
bool padBefore = ((*flags) & 0x04) == 0x04; |
|
|
|
|
bool padAfter = ((*flags) & 0x08) == 0x08; |
|
|
|
|
bool restarting = !isBitSet(*flags, 0); |
|
|
|
|
bool invert = isBitSet(*flags, 1); |
|
|
|
|
bool padBefore = isBitSet(*flags, 2); |
|
|
|
|
bool padAfter = isBitSet(*flags, 3); |
|
|
|
|
|
|
|
|
|
if (!padBefore && !padAfter && *contentHeight < *height) { |
|
|
|
|
std::int16_t offset = invert ? (*height - *contentHeight) : 0; |
|
|
|
|
@ -720,6 +762,12 @@ std::expected<void, ParseError> handleLine(std::span<std::byte const>& buffer, O |
|
|
|
|
return std::unexpected(flags.error()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if defined(DEBUG) |
|
|
|
|
std::cerr << "[Debug] - Line, originX = " << (*originX) << ", originY = " << (*originY) << ", targetX = " << (*targetX) << ", targetY = " << (*targetY) |
|
|
|
|
<< ", lineStyle = " << int(*lineStyle) |
|
|
|
|
<< std::endl; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
std::int32_t dx = static_cast<std::int32_t>(*targetX) - static_cast<std::int32_t>(*originX); |
|
|
|
|
std::int32_t dy = static_cast<std::int32_t>(*targetY) - static_cast<std::int32_t>(*originY); |
|
|
|
|
bool value = true; |
|
|
|
|
@ -785,9 +833,16 @@ std::expected<void, ParseError> handleClippedText(std::span<std::byte const>& bu |
|
|
|
|
} |
|
|
|
|
std::string_view text{reinterpret_cast<char const*>(textData->data()), *textLength}; |
|
|
|
|
|
|
|
|
|
#if defined(DEBUG) |
|
|
|
|
std::cerr << "[Debug] - ClippedText, x = " << (*x) << ", y = " << (*y) << ", width = " << (*width) << ", height = " << (*height) |
|
|
|
|
<< ", fontIndex = " << int(*fontIndex) |
|
|
|
|
<< ", text = \"" << text << "\"" |
|
|
|
|
<< std::endl; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
std::span<std::byte const> fontData; |
|
|
|
|
if ((*fontIndex) & 0x8000u) { |
|
|
|
|
fontIndex = (*fontIndex) & ~0x8000u; |
|
|
|
|
if (isBitSet(*fontIndex, 15)) { |
|
|
|
|
unsetBit(*fontIndex, 15); |
|
|
|
|
if (*fontIndex >= customFonts.size()) { |
|
|
|
|
return {}; |
|
|
|
|
} |
|
|
|
|
@ -854,9 +909,18 @@ std::expected<void, ParseError> handleHScrollText(std::span<std::byte const>& bu |
|
|
|
|
} |
|
|
|
|
std::string_view text{reinterpret_cast<char const*>(textData->data()), *textLength}; |
|
|
|
|
|
|
|
|
|
#if defined(DEBUG) |
|
|
|
|
std::cerr << "[Debug] - HScrollText, x = " << (*x) << ", y = " << (*y) << ", width = " << (*width) << ", height = " << (*height) |
|
|
|
|
<< ", scrollSpeed = " << int(*scrollSpeed) |
|
|
|
|
<< ", flags = " << int(*flags) |
|
|
|
|
<< ", fontIndex = " << int(*fontIndex) |
|
|
|
|
<< ", text = \"" << text << "\"" |
|
|
|
|
<< std::endl; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
std::span<std::byte const> fontData; |
|
|
|
|
if ((*fontIndex) & 0x8000u) { |
|
|
|
|
fontIndex = (*fontIndex) & ~0x8000u; |
|
|
|
|
if (isBitSet(*fontIndex, 15)) { |
|
|
|
|
unsetBit(*fontIndex, 15); |
|
|
|
|
if (*fontIndex >= customFonts.size()) { |
|
|
|
|
return {}; |
|
|
|
|
} |
|
|
|
|
@ -880,10 +944,10 @@ std::expected<void, ParseError> handleHScrollText(std::span<std::byte const>& bu |
|
|
|
|
return {}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool restarting = ((*flags) & 0x01) == 0x00; |
|
|
|
|
bool invert = ((*flags) & 0x02) == 0x02; |
|
|
|
|
bool padBefore = ((*flags) & 0x04) == 0x04; |
|
|
|
|
bool padAfter = ((*flags) & 0x08) == 0x08; |
|
|
|
|
bool restarting = !isBitSet(*flags, 0); |
|
|
|
|
bool invert = isBitSet(*flags, 1); |
|
|
|
|
bool padBefore = isBitSet(*flags, 2); |
|
|
|
|
bool padAfter = isBitSet(*flags, 3); |
|
|
|
|
|
|
|
|
|
if (!padBefore && !padAfter && contentWidth < *width) { |
|
|
|
|
std::uint16_t offset = invert ? (*width - contentWidth) : 0; |
|
|
|
|
@ -994,9 +1058,17 @@ std::expected<void, ParseError> handleCurrentTime(std::span<std::byte const>& bu |
|
|
|
|
return std::unexpected(flags.error()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if defined(DEBUG) |
|
|
|
|
std::cerr << "[Debug] - CurrentTime, x = " << (*x) << ", y = " << (*y) << ", width = " << (*width) << ", height = " << (*height) |
|
|
|
|
<< ", fontIndex = " << int(*fontIndex) |
|
|
|
|
<< ", utcOffset = " << int(*utcOffset) |
|
|
|
|
<< ", flags = " << int(*flags) |
|
|
|
|
<< std::endl; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
std::span<std::byte const> fontData; |
|
|
|
|
if ((*fontIndex) & 0x8000u) { |
|
|
|
|
fontIndex = (*fontIndex) & ~0x8000u; |
|
|
|
|
if (isBitSet(*fontIndex, 15)) { |
|
|
|
|
unsetBit(*fontIndex, 15); |
|
|
|
|
if (*fontIndex >= customFonts.size()) { |
|
|
|
|
return {}; |
|
|
|
|
} |
|
|
|
|
@ -1009,10 +1081,10 @@ std::expected<void, ParseError> handleCurrentTime(std::span<std::byte const>& bu |
|
|
|
|
} |
|
|
|
|
ClippedImage target{screen, *x, *y, *width, *height}; |
|
|
|
|
|
|
|
|
|
bool use12h = ((*flags) & 0x01u) == 0x01u; |
|
|
|
|
bool showHours = ((*flags) & 0x02u) == 0x02u; |
|
|
|
|
bool showMinutes = ((*flags) & 0x04u) == 0x04u; |
|
|
|
|
bool showSeconds = ((*flags) & 0x08u) == 0x08u; |
|
|
|
|
bool use12h = isBitSet(*flags, 0); |
|
|
|
|
bool showHours = isBitSet(*flags, 1); |
|
|
|
|
bool showMinutes = isBitSet(*flags, 2); |
|
|
|
|
bool showSeconds = isBitSet(*flags, 3); |
|
|
|
|
if (showHours && showSeconds) { |
|
|
|
|
showMinutes = true; |
|
|
|
|
} |
|
|
|
|
|