/* * EEZ Modular Firmware * Copyright (C) 2015-present, Envox d.o.o. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include #include namespace eez { namespace gui { static const uint32_t HEADER_TAG = 0x7A65657E; static const uint8_t PROJECT_VERSION_V2 = 2; static const uint8_t PROJECT_VERSION_V3 = 3; static const uint8_t ASSETS_TYPE_FIRMWARE = 1; static const uint8_t ASSETS_TYPE_FIRMWARE_MODULE = 2; static const uint8_t ASSETS_TYPE_RESOURCE = 3; static const uint8_t ASSETS_TYPE_APPLET = 4; static const uint8_t ASSETS_TYPE_DASHBOARD = 5; struct Header { uint32_t tag; // HEADER_TAG uint8_t projectMajorVersion; uint8_t projectMinorVersion; uint8_t assetsType; uint8_t reserved; uint32_t decompressedSize; }; extern bool g_isMainAssetsLoaded; extern Assets *g_mainAssets; extern Assets *g_externalAssets; //////////////////////////////////////////////////////////////////////////////// /* This template is used (on 64-bit systems) to pack asset pointers into 32-bit values. * All pointers are relative to MEMORY_BEGIN. * This way, the assets created by Studio can be used without having to fix all * the sizes - Studio creates 32-bit pointers that are relative to the * beginning of the assets, which the firmware rewrites to global pointers * during initialization. On a 32-bit system this works just fine, but for a * 64-bit system the pointers have different sizes and this breaks. By * inserting a 'middleman' structure that stores the pointers as a 32-bit * offset to MEMORY_BEGIN, we can keep the pointer sizes and initialization * code the same. */ template struct AssetsPtrImpl { /* Conversion to a T pointer */ operator T*() { return ptr(); } operator const T*() const { return ptr(); } /* Dereferencing operators */ T* operator->() { return ptr(); } const T* operator->() const { return ptr(); } void operator=(T* ptr) { if (ptr != nullptr) { offset = (uint8_t *)ptr - MEMORY_BEGIN; } else { offset = 0; } } uint32_t offset = 0; private: T* ptr() { return offset ? (T *)(MEMORY_BEGIN + offset) : nullptr; } const T* ptr() const { return offset ? (const T *)(MEMORY_BEGIN + offset) : nullptr; } }; /* This struct chooses the type used for AssetsPtr - by default it uses an AssetsPtrImpl<> */ template struct AssetsPtrChooser { using type = AssetsPtrImpl; }; /* On 32-bit systems, we can just use raw pointers */ template struct AssetsPtrChooser { using type = T*; }; /* Utility typedef that delegates to AssetsPtrChooser */ template using AssetsPtr = typename AssetsPtrChooser::type; //////////////////////////////////////////////////////////////////////////////// template struct ListOfAssetsPtr { /* Array access */ T* operator[](uint32_t i) { return item(i); } const T* operator[](uint32_t i) const { return item(i); } uint32_t count = 0; AssetsPtr> items; private: T* item(int i) { return static_cast(static_cast *>(items)[i]); } const T* item(int i) const { return static_cast(static_cast *>(items)[i]); } }; template struct ListOfFundamentalType { /* Array access */ T& operator[](uint32_t i) { return ptr()[i]; } const T& operator[](uint32_t i) const { return ptr()[i]; } uint32_t count; AssetsPtr items; private: T *ptr() { return static_cast(items); } }; //////////////////////////////////////////////////////////////////////////////// struct Settings { uint16_t displayWidth; uint16_t displayHeight; }; //////////////////////////////////////////////////////////////////////////////// #define WIDGET_FLAG_PIN_TO_LEFT (1 << 0) #define WIDGET_FLAG_PIN_TO_RIGHT (1 << 1) #define WIDGET_FLAG_PIN_TO_TOP (1 << 2) #define WIDGET_FLAG_PIN_TO_BOTTOM (1 << 3) #define WIDGET_FLAG_FIX_WIDTH (1 << 4) #define WIDGET_FLAG_FIX_HEIGHT (1 << 5) #define WIDGET_TIMELINE_PROPERTY_X (1 << 0) #define WIDGET_TIMELINE_PROPERTY_Y (1 << 1) #define WIDGET_TIMELINE_PROPERTY_WIDTH (1 << 2) #define WIDGET_TIMELINE_PROPERTY_HEIGHT (1 << 3) #define WIDGET_TIMELINE_PROPERTY_OPACITY (1 << 4) #define EASING_FUNC_LINEAR 0 #define EASING_FUNC_IN_QUAD 1 #define EASING_FUNC_OUT_QUAD 2 #define EASING_FUNC_IN_OUT_QUAD 3 #define EASING_FUNC_IN_CUBIC 4 #define EASING_FUNC_OUT_CUBIC 5 #define EASING_FUNC_IN_OUT_CUBIC 6 #define EASING_FUNC_IN__QUART 7 #define EASING_FUNC_OUT_QUART 8 #define EASING_FUNC_IN_OUT_QUART 9 #define EASING_FUNC_IN_QUINT 10 #define EASING_FUNC_OUT_QUINT 11 #define EASING_FUNC_IN_OUT_QUINT 12 #define EASING_FUNC_IN_SINE 13 #define EASING_FUNC_OUT_SINE 14 #define EASING_FUNC_IN_OUT_SINE 15 #define EASING_FUNC_IN_EXPO 16 #define EASING_FUNC_OUT_EXPO 17 #define EASING_FUNC_IN_OUT_EXPO 18 #define EASING_FUNC_IN_CIRC 19 #define EASING_FUNC_OUT_CIRC 20 #define EASING_FUNC_IN_OUT_CIRC 21 #define EASING_FUNC_IN_BACK 22 #define EASING_FUNC_OUT_BACK 23 #define EASING_FUNC_IN_OUT_BACK 24 #define EASING_FUNC_IN_ELASTIC 25 #define EASING_FUNC_OUT_ELASTIC 26 #define EASING_FUNC_IN_OUT_ELASTIC 27 #define EASING_FUNC_IN_BOUNCE 28 #define EASING_FUNC_OUT_BOUNCE 29 #define EASING_FUNC_IN_OUT_BOUNCE 30 struct TimelineKeyframe { float start; float end; uint32_t enabledProperties; int16_t x; int16_t y; int16_t width; int16_t height; float opacity; uint8_t xEasingFunc; uint8_t yEasingFunc; uint8_t widthEasingFunc; uint8_t heightEasingFunc; uint8_t opacityEasingFunc; uint8_t reserved1; uint8_t reserved2; uint8_t reserved3; }; struct Widget { uint16_t type; int16_t data; int16_t visible; int16_t action; int16_t x; int16_t y; int16_t width; int16_t height; int16_t style; uint16_t flags; ListOfAssetsPtr timeline; }; #define SHADOW_FLAG (1 << 0) #define CLOSE_PAGE_IF_TOUCHED_OUTSIDE_FLAG (1 << 1) #define PAGE_IS_USED_AS_CUSTOM_WIDGET (1 << 2) #define PAGE_CONTAINER (1 << 3) #define PAGE_SCALE_TO_FIT (1 << 4) struct PageAsset : public Widget { ListOfAssetsPtr widgets; uint16_t flags; int16_t overlay; }; //////////////////////////////////////////////////////////////////////////////// #define STYLE_FLAGS_HORZ_ALIGN_MASK 0x7 #define STYLE_FLAGS_HORZ_ALIGN_LEFT 0 #define STYLE_FLAGS_HORZ_ALIGN_RIGHT 1 #define STYLE_FLAGS_HORZ_ALIGN_CENTER 2 #define STYLE_FLAGS_VERT_ALIGN_MASK (0x7 << 3) #define STYLE_FLAGS_VERT_ALIGN_TOP (0 << 3) #define STYLE_FLAGS_VERT_ALIGN_BOTTOM (1 << 3) #define STYLE_FLAGS_VERT_ALIGN_CENTER (2 << 3) #define STYLE_FLAGS_BLINK (1 << 6) struct Style { uint16_t flags; // STYLE_FLAGS_... uint16_t backgroundColor; uint16_t color; uint16_t activeBackgroundColor; uint16_t activeColor; uint16_t focusBackgroundColor; uint16_t focusColor; uint8_t borderSizeTop; uint8_t borderSizeRight; uint8_t borderSizeBottom; uint8_t borderSizeLeft; uint16_t borderColor; uint8_t borderRadiusTLX; uint8_t borderRadiusTLY; uint8_t borderRadiusTRX; uint8_t borderRadiusTRY; uint8_t borderRadiusBLX; uint8_t borderRadiusBLY; uint8_t borderRadiusBRX; uint8_t borderRadiusBRY; uint8_t font; uint8_t opacity; // 0 - 255 uint8_t paddingTop; uint8_t paddingRight; uint8_t paddingBottom; uint8_t paddingLeft; int16_t backgroundImage; }; //////////////////////////////////////////////////////////////////////////////// struct GlyphData { int8_t dx; // DWIDTH (-128 indicated empty glyph) uint8_t width; // BBX width uint8_t height; // BBX height int8_t x; // BBX xoffset int8_t y; // BBX yoffset uint8_t reserved1; uint8_t reserved2; uint8_t reserved3; uint8_t pixels[1]; }; struct GlyphsGroup { uint32_t encoding; uint32_t glyphIndex; uint32_t length; }; struct FontData { uint8_t ascent; uint8_t descent; uint8_t reserved1; uint8_t reserved2; uint32_t encodingStart; uint32_t encodingEnd; ListOfAssetsPtr groups; ListOfAssetsPtr glyphs; }; //////////////////////////////////////////////////////////////////////////////// struct Bitmap { int16_t w; int16_t h; int16_t bpp; int16_t reserved; const uint8_t pixels[1]; }; //////////////////////////////////////////////////////////////////////////////// struct Theme { AssetsPtr name; ListOfFundamentalType colors; }; struct Colors { ListOfAssetsPtr themes; ListOfFundamentalType colors; }; //////////////////////////////////////////////////////////////////////////////// static const uint16_t EXPR_EVAL_INSTRUCTION_TYPE_MASK = 0x0007 << 13; static const uint16_t EXPR_EVAL_INSTRUCTION_PARAM_MASK = 0xFFFF >> 3; static const uint16_t EXPR_EVAL_INSTRUCTION_TYPE_PUSH_CONSTANT = (0 << 13); static const uint16_t EXPR_EVAL_INSTRUCTION_TYPE_PUSH_INPUT = (1 << 13); static const uint16_t EXPR_EVAL_INSTRUCTION_TYPE_PUSH_LOCAL_VAR = (2 << 13); static const uint16_t EXPR_EVAL_INSTRUCTION_TYPE_PUSH_GLOBAL_VAR = (3 << 13); static const uint16_t EXPR_EVAL_INSTRUCTION_TYPE_PUSH_OUTPUT = (4 << 13); static const uint16_t EXPR_EVAL_INSTRUCTION_ARRAY_ELEMENT = (5 << 13); static const uint16_t EXPR_EVAL_INSTRUCTION_TYPE_OPERATION = (6 << 13); static const uint16_t EXPR_EVAL_INSTRUCTION_TYPE_END = (7 << 13); struct Property { uint8_t evalInstructions[1]; }; struct Connection { uint16_t targetComponentIndex; uint16_t targetInputIndex; }; struct ComponentOutput { ListOfAssetsPtr connections; uint32_t isSeqOut; }; static const uint16_t BREAKPOINT_ENABLED = 1; static const uint16_t BREAKPOINT_DISABLED = 2; struct Component { uint16_t type; uint16_t breakpoint; // These are indexes to Flow::componentInputs. // We use this to check if component is ready to run (i.e. all mandatory inputs have a value). ListOfFundamentalType inputs; ListOfAssetsPtr properties; ListOfAssetsPtr outputs; int16_t errorCatchOutput; uint16_t reserved; }; struct WidgetDataItem { int16_t componentIndex; int16_t propertyValueIndex; }; struct WidgetActionItem { int16_t componentIndex; int16_t componentOutputIndex; }; #define COMPONENT_INPUT_FLAG_IS_SEQ_INPUT (1 << 0) #define COMPONENT_INPUT_FLAG_IS_OPTIONAL (1 << 1) typedef uint8_t ComponentInput; struct Flow { ListOfAssetsPtr components; ListOfAssetsPtr localVariables; // List of all component inputs of all components in this flow // When flow state is created we reserve this many Value's in memory // to keep the latest value of component input. ListOfFundamentalType componentInputs; ListOfAssetsPtr widgetDataItems; ListOfAssetsPtr widgetActions; }; struct FlowDefinition { ListOfAssetsPtr flows; ListOfAssetsPtr constants; ListOfAssetsPtr globalVariables; }; struct Language { AssetsPtr languageID; ListOfAssetsPtr translations; }; //////////////////////////////////////////////////////////////////////////////// struct Assets { uint8_t projectMajorVersion; uint8_t projectMinorVersion; uint8_t assetsType; uint8_t external; AssetsPtr settings; ListOfAssetsPtr pages; ListOfAssetsPtr