Skip to content

Commit

Permalink
Proof of concept for building on 64-bit systems
Browse files Browse the repository at this point in the history
  • Loading branch information
Cat-Ion committed Nov 2, 2020
1 parent 219011b commit 272188f
Show file tree
Hide file tree
Showing 13 changed files with 157 additions and 64 deletions.
24 changes: 12 additions & 12 deletions src/eez/gui/assets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,29 +45,29 @@ static Assets g_externalAssets;
static Assets *g_fixPointersAssets;

void StyleList_fixPointers() {
g_fixPointersAssets->styles->first = (Style *)((uint8_t *)g_fixPointersAssets->styles + (uint32_t)g_fixPointersAssets->styles->first);
g_fixPointersAssets->styles->first = (const Style *)((uint8_t *)&*g_fixPointersAssets->styles + (uint32_t)g_fixPointersAssets->styles->first);
}

void WidgetList_fixPointers(WidgetList &widgetList) {
widgetList.first = (Widget *)((uint8_t *)g_fixPointersAssets->document + (uint32_t)widgetList.first);
widgetList.first = (Widget *)((uint8_t *)&*g_fixPointersAssets->document + (uint32_t)widgetList.first);
for (uint32_t i = 0; i < widgetList.count; ++i) {
Widget_fixPointers((Widget *)widgetList.first + i);
Widget_fixPointers((Widget *)&widgetList.first[i]);
}
}

void ColorList_fixPointers(ColorList &colorList) {
colorList.first = (uint16_t *)((uint8_t *)g_fixPointersAssets->colorsData + (uint32_t)colorList.first);
colorList.first = (uint16_t *)((uint8_t *)&*g_fixPointersAssets->colorsData + (uint32_t)colorList.first);
}

void Theme_fixPointers(Theme *theme) {
theme->name = (const char *)((uint8_t *)g_fixPointersAssets->colorsData + (uint32_t)theme->name);
theme->name = (const char *)((uint8_t *)&*g_fixPointersAssets->colorsData + (uint32_t)theme->name);
ColorList_fixPointers(theme->colors);
}

void ThemeList_fixPointers(ThemeList &themeList) {
themeList.first = (Theme *)((uint8_t *)g_fixPointersAssets->colorsData + (uint32_t)themeList.first);
themeList.first = (Theme *)((uint8_t *)&*g_fixPointersAssets->colorsData + (uint32_t)themeList.first);
for (uint32_t i = 0; i < themeList.count; ++i) {
Theme_fixPointers((Theme *)themeList.first + i);
Theme_fixPointers(const_cast<Theme*>(&themeList.first[i]));
}
}

Expand All @@ -78,7 +78,7 @@ void ColorsData_fixPointers() {

void NameList_fixPointers(NameList *nameList) {
if (nameList) {
nameList->first = (const char **)((uint8_t *)nameList + (uint32_t)nameList->first);
nameList->first = ((uint8_t *)&*nameList + (uint32_t)nameList->first);
for (uint32_t i = 0; i < nameList->count; i++) {
nameList->first[i] = (const char *)((uint8_t *)nameList + (uint32_t)nameList->first[i]);
}
Expand Down Expand Up @@ -130,7 +130,7 @@ static FixPointersFunctionType *g_fixWidgetPointersFunctions[] = {
// };

void Widget_fixPointers(Widget *widget) {
widget->specific = (void *)((uint8_t *)g_fixPointersAssets->document + (uint32_t)widget->specific);
widget->specific = (void *)((uint8_t *)&*g_fixPointersAssets->document + (uint32_t)widget->specific);
if (*g_fixWidgetPointersFunctions[widget->type]) {
(*g_fixWidgetPointersFunctions[widget->type])(widget, g_fixPointersAssets);
}
Expand Down Expand Up @@ -188,14 +188,14 @@ const uint8_t *getFontData(int fontID) {
if (fontID == 0) {
return 0;
}
return g_mainAssets.fontsData + ((uint32_t *)g_mainAssets.fontsData)[fontID - 1];
return g_mainAssets.fontsData + ((uint32_t *)&*g_mainAssets.fontsData)[fontID - 1];
}

const Bitmap *getBitmap(int bitmapID) {
if (bitmapID > 0) {
return (const Bitmap *)(g_mainAssets.bitmapsData + ((uint32_t *)g_mainAssets.bitmapsData)[bitmapID - 1]);
return (const Bitmap *)(g_mainAssets.bitmapsData + ((uint32_t *)&*g_mainAssets.bitmapsData)[bitmapID - 1]);
} else if (bitmapID < 0) {
return (const Bitmap *)(g_externalAssets.bitmapsData + ((uint32_t *)g_externalAssets.bitmapsData)[-bitmapID - 1]);
return (const Bitmap *)(g_externalAssets.bitmapsData + ((uint32_t *)&*g_externalAssets.bitmapsData)[-bitmapID - 1]);
}
return nullptr;
}
Expand Down
2 changes: 1 addition & 1 deletion src/eez/gui/assets.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ int16_t getDataIdFromName(const char *name);
int getExternalAssetsFirstPageId();

#define GET_WIDGET_PROPERTY(widget, propertyName, type) ((type)widget->propertyName)
#define GET_WIDGET_LIST_ELEMENT(list, index) ((list).first + (index))
#define GET_WIDGET_LIST_ELEMENT(list, index) &((list).first[index])

bool loadExternalAssets(const char *filePath, int *err);

Expand Down
131 changes: 112 additions & 19 deletions src/eez/gui/widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@

#pragma once

#include <type_traits>
#include <eez/gui/geometry.h>
#include <eez/memory.h>

namespace eez {
namespace gui {
Expand Down Expand Up @@ -56,6 +58,97 @@ enum ValueTypes {

typedef void (*EnumWidgetsCallback)(const WidgetCursor &widgetCursor);

template<typename T, bool is_void>
struct AssetsPtrImpl;

/* 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<typename T>
struct AssetsPtrImpl<T, false>
{
/* Default constructors initialize to an invalid pointer */
AssetsPtrImpl() = default;
AssetsPtrImpl(std::nullptr_t v) {};
/* Can accept void or T pointers. Store the offset to MEMORY_BEGIN. */
AssetsPtrImpl(T * p) : val(reinterpret_cast<const uint8_t*>(p) - MEMORY_BEGIN) {}
AssetsPtrImpl(void * p) : val(reinterpret_cast<const uint8_t*>(p) - MEMORY_BEGIN) {}

/* Conversion to an int return the raw value */
operator uint32_t() const { return val; }

/* Implicit conversion to a T pointer */
operator T*() const { return ptr(); }

/* Implicit conversions to void pointers */
operator void*() const { return ptr(); }
operator const void*() const { return ptr(); }

/* Dereferencing operators */
T* operator->() { return ptr(); }
const T* operator->() const { return ptr(); }

/* Array access */
T& operator[](uint32_t i) { return ptr()[i]; }
const T& operator[](uint32_t i) const { return ptr()[i]; }

/* Implement addition of ints just like 'normal' pointers */
T* operator+(int i) { return &ptr()[i]; }
T* operator+(unsigned i) { return &ptr()[i]; }

/* Calculate the pointer, return a null pointer if the value is invalid */
T* ptr() const {
if (val == 0xFFFFFFFF) {
return 0;
} else {
return (T*)(MEMORY_BEGIN + val);
}
}

uint32_t val{0xFFFFFFFF};
};

/* Template specialization for void pointers that does not allow dereferencing */
template<typename T>
struct AssetsPtrImpl<T, true>
{
AssetsPtrImpl() = default;
AssetsPtrImpl(std::nullptr_t) {};
AssetsPtrImpl(T* p) : val(reinterpret_cast<const uint8_t*>(p) - MEMORY_BEGIN) {}
operator uint32_t() const { return val; }
operator T*() const { return reinterpret_cast<T*>(MEMORY_BEGIN + val); }

/* Implicit conversions to convert to any pointer type */
template<typename U> operator U() const { return (U)(T*)(*this); }
uint32_t val{0xFFFFFFFF};
};

/* This struct chooses the type used for AssetsPtr<T> - by default it uses an AssetsPtrImpl<> */
template<typename T, uint32_t ptrSize>
struct AssetsPtrChooser
{
using type = AssetsPtrImpl<T, std::is_void<T>::value>;
};

/* On 32-bit systems, we can just use raw pointers */
template<typename T>
struct AssetsPtrChooser<T, 4>
{
using type = T*;
};

/* Utility typedef that delegates to AssetsPtrChooser */
template<typename T>
using AssetsPtr = typename AssetsPtrChooser<T, sizeof(void*)>::type;

struct Widget;
struct Assets;

Expand Down Expand Up @@ -110,15 +203,15 @@ struct Style {
uint8_t padding_right;
uint8_t padding_bottom;
uint8_t padding_left;
uint8_t margin_top;
uint8_t margin_right;
uint8_t margin_bottom;
uint8_t margin_left;
uint8_t margin_top;
uint8_t margin_right;
uint8_t margin_bottom;
uint8_t margin_left;
};

struct StyleList {
uint32_t count;
const Style *first;
AssetsPtr<const Style> first;
};

void StyleList_fixPointers(StyleList &styleList);
Expand All @@ -134,14 +227,14 @@ struct Widget {
int16_t w;
int16_t h;
uint16_t style;
const void *specific;
AssetsPtr<const void> specific;
};

void Widget_fixPointers(Widget *widget);
void Widget_fixPointers(Widget* widget);

struct WidgetList {
uint32_t count;
const Widget *first;
AssetsPtr<const Widget> first;
};

void WidgetList_fixPointers(WidgetList &widgetList);
Expand All @@ -165,21 +258,21 @@ struct Document {

struct ColorList {
uint32_t count;
const uint16_t *first;
AssetsPtr<const uint16_t> first;
};

void ColorList_fixPointers(ColorList &colorList);

struct Theme {
const char *name;
AssetsPtr<const char> name;
ColorList colors;
};

void Theme_fixPointers(Theme *theme);

struct ThemeList {
uint32_t count;
const Theme *first;
AssetsPtr<const Theme> first;
};

void ThemeList_fixPointers(ThemeList &themeList);
Expand All @@ -193,17 +286,17 @@ struct Colors {

struct NameList {
uint32_t count;
const char **first;
AssetsPtr<AssetsPtr<const char>> first;
};

struct Assets {
Document *document;
StyleList *styles;
uint8_t *fontsData;
uint8_t *bitmapsData;
Colors *colorsData;
NameList *actionNames;
NameList *dataItemNames;
AssetsPtr<Document> document;
AssetsPtr<StyleList> styles;
AssetsPtr<uint8_t> fontsData;
AssetsPtr<uint8_t> bitmapsData;
AssetsPtr<Colors> colorsData;
AssetsPtr<NameList> actionNames;
AssetsPtr<NameList> dataItemNames;
};

////////////////////////////////////////////////////////////////////////////////
Expand Down
4 changes: 2 additions & 2 deletions src/eez/gui/widgets/button.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace gui {

FixPointersFunctionType BUTTON_fixPointers = [](Widget *widget, Assets *assets) {
ButtonWidget *buttonWidget = (ButtonWidget *)widget->specific;
buttonWidget->text = (const char *)((uint8_t *)assets->document + (uint32_t)buttonWidget->text);
buttonWidget->text = (const char *)((uint8_t *)(void *)assets->document + (uint32_t)buttonWidget->text);
};

EnumFunctionType BUTTON_enum = nullptr;
Expand Down Expand Up @@ -79,4 +79,4 @@ OnKeyboardFunctionType BUTTON_onKeyboard = nullptr;
} // namespace gui
} // namespace eez

#endif
#endif
4 changes: 2 additions & 2 deletions src/eez/gui/widgets/button.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ namespace eez {
namespace gui {

struct ButtonWidget {
const char *text;
AssetsPtr<const char> text;
int16_t enabled;
uint16_t disabledStyle;
};

} // namespace gui
} // namespace eez
} // namespace eez
8 changes: 4 additions & 4 deletions src/eez/gui/widgets/grid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ namespace gui {

struct GridWidget {
uint8_t gridFlow; // GRID_FLOW_ROW or GRID_FLOW_COLUMN
const Widget *itemWidget;
AssetsPtr<const Widget> itemWidget;
};

FixPointersFunctionType GRID_fixPointers = [](Widget *widget, Assets *assets) {
GridWidget *gridWidget = (GridWidget *)widget->specific;
gridWidget->itemWidget = (Widget *)((uint8_t *)assets->document + (uint32_t)gridWidget->itemWidget);
Widget_fixPointers((Widget *)gridWidget->itemWidget);
gridWidget->itemWidget = (Widget *)((uint8_t *)(void *)assets->document + (uint32_t)gridWidget->itemWidget);
Widget_fixPointers((Widget *)&*gridWidget->itemWidget);
};

EnumFunctionType GRID_enum = [](WidgetCursor &widgetCursor, EnumWidgetsCallback callback) {
Expand Down Expand Up @@ -148,4 +148,4 @@ OnKeyboardFunctionType GRID_onKeyboard = nullptr;
} // namespace gui
} // namespace eez

#endif
#endif
8 changes: 4 additions & 4 deletions src/eez/gui/widgets/list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ namespace gui {

struct ListWidget {
uint8_t listType; // LIST_TYPE_VERTICAL or LIST_TYPE_HORIZONTAL
const Widget *itemWidget;
AssetsPtr<const Widget> itemWidget;
uint8_t gap;
};

FixPointersFunctionType LIST_fixPointers = [](Widget *widget, Assets *assets) {
ListWidget *listWidget = (ListWidget *)widget->specific;
listWidget->itemWidget = (Widget *)((uint8_t *)assets->document + (uint32_t)listWidget->itemWidget);
Widget_fixPointers((Widget *)listWidget->itemWidget);
listWidget->itemWidget = (Widget *)((uint8_t *)(void *)assets->document + (uint32_t)listWidget->itemWidget);
Widget_fixPointers((Widget *)&*listWidget->itemWidget);
};

EnumFunctionType LIST_enum = [](WidgetCursor &widgetCursor, EnumWidgetsCallback callback) {
Expand Down Expand Up @@ -137,4 +137,4 @@ OnKeyboardFunctionType LIST_onKeyboard = nullptr;
} // namespace gui
} // namespace eez

#endif
#endif
6 changes: 3 additions & 3 deletions src/eez/gui/widgets/multiline_text.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ namespace eez {
namespace gui {

struct MultilineTextWidget {
const char *text;
AssetsPtr<const char> text;
int16_t firstLineIndent;
int16_t hangingIndent;
};

FixPointersFunctionType MULTILINE_TEXT_fixPointers = [](Widget *widget, Assets *assets) {
MultilineTextWidget *multilineTextWidget = (MultilineTextWidget *)widget->specific;
multilineTextWidget->text = (const char *)((uint8_t *)assets->document + (uint32_t)multilineTextWidget->text);
multilineTextWidget->text = (const char *)((uint8_t *)(void *)assets->document + (uint32_t)multilineTextWidget->text);
};

EnumFunctionType MULTILINE_TEXT_enum = nullptr;
Expand Down Expand Up @@ -86,4 +86,4 @@ OnKeyboardFunctionType MULTILINE_TEXT_onKeyboard = nullptr;
} // namespace gui
} // namespace eez

#endif
#endif
Loading

0 comments on commit 272188f

Please sign in to comment.