mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[bootloader/storage] new bootloader and fix python issue
This commit is contained in:
@@ -1,20 +1,22 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <ion.h>
|
||||
#include <ion/timing.h>
|
||||
|
||||
#include <bootloader/interface.h>
|
||||
#include <bootloader/messages.h>
|
||||
#include <bootloader/slot.h>
|
||||
#include <bootloader/boot.h>
|
||||
|
||||
#include "computer.h"
|
||||
#include "cable.h"
|
||||
|
||||
namespace Bootloader {
|
||||
|
||||
void Interface::drawImage(KDContext* ctx, const Image* image, int offset) {
|
||||
const uint8_t* data;
|
||||
void Interface::drawImage(KDContext * ctx, const Image * image, int offset) {
|
||||
const uint8_t * data;
|
||||
size_t size;
|
||||
size_t pixelBufferSize;
|
||||
|
||||
if (image != nullptr) {
|
||||
data = image->compressedPixelData();
|
||||
size = image->compressedPixelDataSize();
|
||||
@@ -39,44 +41,281 @@ void Interface::drawImage(KDContext* ctx, const Image* image, int offset) {
|
||||
ctx->fillRectWithPixels(bounds, pixelBuffer, nullptr);
|
||||
}
|
||||
|
||||
void Interface::draw() {
|
||||
void Interface::drawHeader() {
|
||||
KDContext * ctx = KDIonContext::sharedContext();
|
||||
ctx->fillRect(KDRect(0,0,320,240), KDColorBlack);
|
||||
drawImage(ctx, ImageStore::Computer, 70);
|
||||
drawImage(ctx, ImageStore::Cable, 172);
|
||||
ctx->fillRect(KDRect(0, 0, 320, 240), KDColorWhite);
|
||||
drawImage(ctx, ImageStore::Computer, 25);
|
||||
KDSize fontSize = KDFont::LargeFont->glyphSize();
|
||||
int initPos = (320 - fontSize.width() * strlen(Messages::mainTitle)) / 2;
|
||||
ctx->drawString(Messages::mainTitle, KDPoint(initPos, ImageStore::Computer->height() + fontSize.height() + 10), KDFont::LargeFont, KDColorBlack, KDColorWhite);
|
||||
}
|
||||
|
||||
ctx->drawString("Slot A:", KDPoint(0, 0), KDFont::SmallFont, KDColorWhite, KDColorBlack);
|
||||
ctx->drawString("Slot B:", KDPoint(0, 13), KDFont::SmallFont, KDColorWhite, KDColorBlack);
|
||||
ctx->drawString("Current:", KDPoint(0, 26), KDFont::SmallFont, KDColorWhite, KDColorBlack);
|
||||
void Interface::drawMenu() {
|
||||
// Get the context
|
||||
KDContext * ctx = KDIonContext::sharedContext();
|
||||
// Clear the screen
|
||||
ctx->fillRect(KDRect(0, 0, 320, 240), KDColorWhite);
|
||||
// Draw the image
|
||||
drawImage(ctx, ImageStore::Computer, 25);
|
||||
// Get the font size
|
||||
KDSize largeSize = KDFont::LargeFont->glyphSize();
|
||||
KDSize smallSize = KDFont::SmallFont->glyphSize();
|
||||
// Draw the title
|
||||
int initPos = (320 - largeSize.width() * strlen(Messages::mainMenuTitle)) / 2;
|
||||
ctx->drawString(Messages::mainMenuTitle, KDPoint(initPos, ImageStore::Computer->height() + largeSize.height() + 10), KDFont::LargeFont, KDColorBlack, KDColorWhite);
|
||||
|
||||
if (Boot::mode() == BootMode::SlotA) {
|
||||
ctx->drawString("Slot A", KDPoint(63, 26), KDFont::SmallFont, KDColorWhite, KDColorBlack);
|
||||
} else if (Boot::mode() == BootMode::SlotB) {
|
||||
ctx->drawString("Slot B", KDPoint(63, 26), KDFont::SmallFont, KDColorWhite, KDColorBlack);
|
||||
}
|
||||
// Initialize the slot list
|
||||
Slot slots[3] = {Slot::A(), Slot::Khi(), Slot::B()};
|
||||
char indexes[3] = {'1', '2', '3'};
|
||||
|
||||
Slot slots[2] = {Slot::A(), Slot::B()};
|
||||
// Set the khi slot index, improve this when Khi will have a dedicated header
|
||||
const uint8_t khiIndex = 2 - 1;
|
||||
|
||||
for(uint8_t i = 0; i < 2; i++) {
|
||||
// Get the start y position
|
||||
int y = ImageStore::Computer->height() + (largeSize.height() + 10) + (smallSize.height() + 10);
|
||||
|
||||
// Iterate over the slot list
|
||||
for (uint8_t i = 0; i < sizeof(indexes) / sizeof(indexes[0]); i++) {
|
||||
// Get the slot from the list
|
||||
Slot slot = slots[i];
|
||||
|
||||
// Get the "X - " string
|
||||
char converted[] = {indexes[i], ' ', '-', ' ', '\0'};
|
||||
// Setup the margin
|
||||
int x = 10;
|
||||
// If the slot is valid, draw the slot
|
||||
if (slot.kernelHeader()->isValid() && slot.userlandHeader()->isValid()) {
|
||||
// Draw the slot number
|
||||
ctx->drawString(converted, KDPoint(x, y), KDFont::SmallFont, KDColorBlack, KDColorWhite);
|
||||
// Increment the x position
|
||||
x += strlen(converted) * smallSize.width();
|
||||
// Draw the slot version
|
||||
ctx->drawString(slot.userlandHeader()->version(), KDPoint(x, y), KDFont::SmallFont, KDColorBlack, KDColorWhite);
|
||||
// Increment the x position
|
||||
x += strlen(slot.userlandHeader()->version()) * smallSize.width() + smallSize.width() * 2;
|
||||
// Draw the slot commit
|
||||
ctx->drawString(slot.kernelHeader()->patchLevel(), KDPoint(x, y), KDFont::SmallFont, KDColorBlack, KDColorWhite);
|
||||
// Increment the x position
|
||||
x += strlen(slot.kernelHeader()->patchLevel()) * smallSize.width() + smallSize.width();
|
||||
|
||||
const char * OSName = "";
|
||||
const char * OSVersion = "";
|
||||
// If the slot is Upsilon, draw the slot name
|
||||
if (slot.userlandHeader()->isOmega() && slot.userlandHeader()->isUpsilon()) {
|
||||
ctx->drawString("Upsilon", KDPoint(56, i*13), KDFont::SmallFont, KDColorWhite, KDColorBlack);
|
||||
ctx->drawString(slot.userlandHeader()->upsilonVersion(), KDPoint(112, i*13), KDFont::SmallFont, KDColorWhite, KDColorBlack);
|
||||
// Set the OS name
|
||||
OSName = Messages::upsilon;
|
||||
// Set the OS version
|
||||
OSVersion = slot.userlandHeader()->upsilonVersion();
|
||||
} else if (slot.userlandHeader()->isOmega()) {
|
||||
ctx->drawString("Omega", KDPoint(56, i*13), KDFont::SmallFont, KDColorWhite, KDColorBlack);
|
||||
ctx->drawString(slot.userlandHeader()->omegaVersion(), KDPoint(112, i*13), KDFont::SmallFont, KDColorWhite, KDColorBlack);
|
||||
// Get if slot is Khi
|
||||
bool isKhi = (i == khiIndex);
|
||||
// If the slot is Khi, draw the slot name (Khi)
|
||||
if (isKhi) {
|
||||
// Set the OS name
|
||||
OSName = Messages::khi;
|
||||
} else {
|
||||
// Set the OS name
|
||||
OSName = Messages::omega;
|
||||
}
|
||||
// Set the OS version
|
||||
OSVersion = slot.userlandHeader()->omegaVersion();
|
||||
} else {
|
||||
ctx->drawString("Epsilon", KDPoint(56, i*13), KDFont::SmallFont, KDColorWhite, KDColorBlack);
|
||||
ctx->drawString(slot.userlandHeader()->version(), KDPoint(112, i*13), KDFont::SmallFont, KDColorWhite, KDColorBlack);
|
||||
// Set the OS name
|
||||
OSName = Messages::epsilon;
|
||||
}
|
||||
ctx->drawString(slot.kernelHeader()->patchLevel(), KDPoint(168, i*13), KDFont::SmallFont, KDColorWhite, KDColorBlack);
|
||||
// Draw the OS name
|
||||
ctx->drawString(OSName, KDPoint(x, y), KDFont::SmallFont, KDColorBlack, KDColorWhite);
|
||||
// Increment the x position
|
||||
x += strlen(OSName) * smallSize.width() + smallSize.width();
|
||||
// Draw the OS version
|
||||
ctx->drawString(OSVersion, KDPoint(x, y), KDFont::SmallFont, KDColorBlack, KDColorWhite);
|
||||
// Else, the slot is invalid
|
||||
} else {
|
||||
ctx->drawString("Invalid", KDPoint(56, i*13), KDFont::SmallFont, KDColorWhite, KDColorBlack);
|
||||
ctx->drawString(Messages::invalidSlot, KDPoint(10, y), KDFont::SmallFont, KDColorBlack, KDColorWhite);
|
||||
}
|
||||
// Increment the y position
|
||||
y += smallSize.height() + 10;
|
||||
}
|
||||
|
||||
// Draw the DFU message
|
||||
ctx->drawString(Messages::dfuText, KDPoint(10, y), KDFont::SmallFont, KDColorBlack, KDColorWhite);
|
||||
|
||||
// Increment the y position
|
||||
y += smallSize.height() + 10;
|
||||
// Draw the about message
|
||||
ctx->drawString(Messages::aboutText, KDPoint(10, y), KDFont::SmallFont, KDColorBlack, KDColorWhite);
|
||||
|
||||
// Reboot is disabled for now
|
||||
// y += smallSize.height() + 10;
|
||||
// ctx->drawString(Messages::rebootText, KDPoint(10, y), KDFont::SmallFont, KDColorBlack, KDColorWhite);
|
||||
|
||||
// Draw the footer
|
||||
initPos = (320 - smallSize.width() * strlen(Messages::mainTitle)) / 2;
|
||||
ctx->drawString(Messages::mainTitle, KDPoint(initPos, 240 - smallSize.height() - 10), KDFont::SmallFont, KDColorBlack, KDColorWhite);
|
||||
}
|
||||
|
||||
void Interface::drawFlasher() {
|
||||
Interface::drawHeader();
|
||||
KDContext * ctx = KDIonContext::sharedContext();
|
||||
int y = ImageStore::Computer->height() + (KDFont::LargeFont->glyphSize().height() + 10) + (KDFont::SmallFont->glyphSize().height() + 10);
|
||||
int initPos = (320 - KDFont::SmallFont->glyphSize().width() * strlen(Messages::dfuSubtitle)) / 2;
|
||||
ctx->drawString(Messages::dfuSubtitle, KDPoint(initPos, y), KDFont::SmallFont, KDColorBlack, KDColorWhite);
|
||||
}
|
||||
|
||||
void Interface::drawLoading() {
|
||||
KDContext * ctx = KDIonContext::sharedContext();
|
||||
ctx->fillRect(KDRect(0, 0, 320, 240), KDColorWhite);
|
||||
drawImage(ctx, ImageStore::Computer, 25);
|
||||
Ion::Timing::msleep(250);
|
||||
KDSize fontSize = KDFont::LargeFont->glyphSize();
|
||||
int initPos = (320 - fontSize.width() * strlen(Messages::mainTitle)) / 2;
|
||||
for (uint8_t i = 0; i < strlen(Messages::mainTitle); i++) {
|
||||
char tmp[2] = {Messages::mainTitle[i], '\0'};
|
||||
ctx->drawString(tmp, KDPoint(initPos + i * (fontSize.width()), ImageStore::Computer->height() + fontSize.height() + 10), KDFont::LargeFont, KDColorBlack, KDColorWhite);
|
||||
Ion::Timing::msleep(50);
|
||||
}
|
||||
Ion::Timing::msleep(500);
|
||||
}
|
||||
|
||||
void Interface::drawAbout() {
|
||||
drawHeader();
|
||||
// Create the list of about messages
|
||||
// TODO: Move it to messages.h
|
||||
char aboutMessages[][38] = {
|
||||
"This is the bootloader of",
|
||||
"the Upsilon Calculator.",
|
||||
"It is used to install",
|
||||
"and select the OS",
|
||||
"to boot."
|
||||
};
|
||||
// Get the context
|
||||
KDContext * ctx = KDIonContext::sharedContext();
|
||||
// Get the start Y position
|
||||
KDSize largeSize = KDFont::LargeFont->glyphSize();
|
||||
KDSize smallSize = KDFont::SmallFont->glyphSize();
|
||||
int y = ImageStore::Computer->height() + (largeSize.height() + 10) + (smallSize.height() + 10);
|
||||
// Iterate over the list and draw each message
|
||||
for (uint8_t i = 0; i < sizeof(aboutMessages) / sizeof(aboutMessages[0]); i++) {
|
||||
// Get the message
|
||||
char * actualMessage = aboutMessages[i];
|
||||
// Get the start X position
|
||||
int initPos = (320 - KDFont::SmallFont->glyphSize().width() * strlen(actualMessage)) / 2;
|
||||
// Draw the message
|
||||
ctx->drawString(actualMessage, KDPoint(initPos, y), KDFont::SmallFont, KDColorBlack, KDColorWhite);
|
||||
// Increment the Y position
|
||||
y += smallSize.height() + 10;
|
||||
}
|
||||
|
||||
ctx->drawString(Messages::bootloaderVersion, KDPoint((320 - KDFont::SmallFont->glyphSize().width() * strlen(Messages::bootloaderVersion)) / 2, y), KDFont::SmallFont, KDColorBlack, KDColorWhite);
|
||||
|
||||
}
|
||||
|
||||
void Interface::drawCrash(const char * error) {
|
||||
KDContext * ctx = KDIonContext::sharedContext();
|
||||
ctx->fillRect(KDRect(0, 0, 320, 240), KDColorWhite);
|
||||
drawImage(ctx, ImageStore::Computer, 25);
|
||||
KDSize fontSize = KDFont::LargeFont->glyphSize();
|
||||
int initPos = (320 - fontSize.width() * strlen(Messages::crashTitle)) / 2;
|
||||
ctx->drawString(Messages::crashTitle, KDPoint(initPos, ImageStore::Computer->height() + fontSize.height() + 10), KDFont::LargeFont, KDColorBlack, KDColorWhite);
|
||||
initPos = (320 - KDFont::SmallFont->glyphSize().width() * strlen(error)) / 2;
|
||||
ctx->drawString(error, KDPoint(initPos, ImageStore::Computer->height() + fontSize.height() + 10 + KDFont::SmallFont->glyphSize().height() + 10), KDFont::SmallFont, KDColorBlack, KDColorWhite);
|
||||
initPos = (320 - KDFont::SmallFont->glyphSize().width() * strlen(Messages::crashText1)) / 2;
|
||||
ctx->drawString(Messages::crashText1, KDPoint(initPos, ImageStore::Computer->height() + fontSize.height() + 10 + KDFont::SmallFont->glyphSize().height() + 10 + KDFont::SmallFont->glyphSize().height() + 10 + 20), KDFont::SmallFont, KDColorBlack, KDColorWhite);
|
||||
initPos = (320 - KDFont::SmallFont->glyphSize().width() * strlen(Messages::crashText2)) / 2;
|
||||
ctx->drawString(Messages::crashText2, KDPoint(initPos, ImageStore::Computer->height() + fontSize.height() + 10 + KDFont::SmallFont->glyphSize().height() + 10 + KDFont::SmallFont->glyphSize().height() + 10 + 20 + KDFont::SmallFont->glyphSize().height() + 10), KDFont::SmallFont, KDColorBlack, KDColorWhite);
|
||||
}
|
||||
|
||||
void Interface::drawRecovery() {
|
||||
KDContext * ctx = KDIonContext::sharedContext();
|
||||
ctx->fillRect(KDRect(0, 0, 320, 240), KDColorWhite);
|
||||
drawImage(ctx, ImageStore::Computer, 25);
|
||||
KDSize fontSize = KDFont::LargeFont->glyphSize();
|
||||
int initPos = (320 - fontSize.width() * strlen(Messages::recoveryTitle)) / 2;
|
||||
int y = ImageStore::Computer->height() + fontSize.height() + 5;
|
||||
ctx->drawString(Messages::recoveryTitle, KDPoint(initPos, y), KDFont::LargeFont, KDColorBlack, KDColorWhite);
|
||||
initPos = (320 - KDFont::SmallFont->glyphSize().width() * strlen(Messages::recoveryText1)) / 2;
|
||||
y += fontSize.height() + 5;
|
||||
ctx->drawString(Messages::recoveryText1, KDPoint(initPos, y), KDFont::SmallFont, KDColorBlack, KDColorWhite);
|
||||
initPos = (320 - KDFont::SmallFont->glyphSize().width() * strlen(Messages::recoveryText2)) / 2;
|
||||
y += fontSize.height() + 5;
|
||||
ctx->drawString(Messages::recoveryText2, KDPoint(initPos, y), KDFont::SmallFont, KDColorBlack, KDColorWhite);
|
||||
initPos = (320 - KDFont::SmallFont->glyphSize().width() * strlen(Messages::recoveryText3)) / 2;
|
||||
y += fontSize.height() + 5;
|
||||
ctx->drawString(Messages::recoveryText3, KDPoint(initPos, y), KDFont::SmallFont, KDColorBlack, KDColorWhite);
|
||||
initPos = (320 - KDFont::SmallFont->glyphSize().width() * strlen(Messages::recoveryText4)) / 2;
|
||||
y += fontSize.height() + 5;
|
||||
ctx->drawString(Messages::recoveryText4, KDPoint(initPos, y), KDFont::SmallFont, KDColorBlack, KDColorWhite);
|
||||
initPos = (320 - KDFont::SmallFont->glyphSize().width() * strlen(Messages::recoveryText5)) / 2;
|
||||
y += fontSize.height() + 5;
|
||||
ctx->drawString(Messages::recoveryText5, KDPoint(initPos, y), KDFont::SmallFont, KDColorBlack, KDColorWhite);
|
||||
}
|
||||
|
||||
void Interface::drawInstallerSelection() {
|
||||
// Get the context
|
||||
KDContext * ctx = KDIonContext::sharedContext();
|
||||
// Clear the screen
|
||||
ctx->fillRect(KDRect(0, 0, 320, 240), KDColorWhite);
|
||||
// Draw the image
|
||||
drawImage(ctx, ImageStore::Computer, 25);
|
||||
// Get the font size
|
||||
KDSize largeSize = KDFont::LargeFont->glyphSize();
|
||||
KDSize smallSize = KDFont::SmallFont->glyphSize();
|
||||
// Get the start x position
|
||||
int initPos = (320 - largeSize.width() * strlen(Messages::installerSelectionTitle)) / 2;
|
||||
// Get the start y position
|
||||
int y = ImageStore::Computer->height() + largeSize.height() + 10;
|
||||
// Draw the title
|
||||
ctx->drawString(Messages::installerSelectionTitle, KDPoint(initPos, y), KDFont::LargeFont, KDColorBlack, KDColorWhite);
|
||||
// Increment the y position
|
||||
y += largeSize.height() + 5;
|
||||
// Get the y position of the subtitle
|
||||
initPos = (320 - KDFont::SmallFont->glyphSize().width() * strlen(Messages::installerText1)) / 2;
|
||||
// Draw the subtitle
|
||||
ctx->drawString(Messages::installerText1, KDPoint(initPos, y), KDFont::SmallFont, KDColorBlack, KDColorWhite);
|
||||
// Increment the y position
|
||||
y += smallSize.height() + 10;
|
||||
// Set the start x position
|
||||
initPos = 10;
|
||||
// Draw the first button (slot flash)
|
||||
ctx->drawString(Messages::installerText2, KDPoint(initPos, y), KDFont::SmallFont, KDColorBlack, KDColorWhite);
|
||||
// Increment the y position
|
||||
y += smallSize.height() + 10;
|
||||
// Draw the second button (bootloader flash)
|
||||
ctx->drawString(Messages::installerText3, KDPoint(initPos, y), KDFont::SmallFont, KDColorBlack, KDColorWhite);
|
||||
}
|
||||
|
||||
void Interface::drawBLUpdate() {
|
||||
Interface::drawHeader();
|
||||
KDContext * ctx = KDIonContext::sharedContext();
|
||||
int y = ImageStore::Computer->height() + (KDFont::LargeFont->glyphSize().height() + 10) + (KDFont::SmallFont->glyphSize().height() + 10);
|
||||
int initPos = (320 - KDFont::SmallFont->glyphSize().width() * strlen(Messages::bootloaderSubtitle)) / 2;
|
||||
ctx->drawString(Messages::bootloaderSubtitle, KDPoint(initPos, y), KDFont::SmallFont, KDColorBlack, KDColorWhite);
|
||||
}
|
||||
|
||||
void Interface::drawEpsilonAdvertisement() {
|
||||
KDContext * ctx = KDIonContext::sharedContext();
|
||||
ctx->fillRect(KDRect(0, 0, 320, 240), KDColorRed);
|
||||
drawImage(ctx, ImageStore::Computer, 25);
|
||||
KDSize fontSize = KDFont::LargeFont->glyphSize();
|
||||
int initPos = (320 - fontSize.width() * strlen(Messages::epsilonWarningTitle)) / 2;
|
||||
int y = ImageStore::Computer->height() + fontSize.height() + 15;
|
||||
ctx->drawString(Messages::epsilonWarningTitle, KDPoint(initPos, y), KDFont::LargeFont, KDColorWhite, KDColorRed);
|
||||
initPos = (320 - fontSize.width() * strlen(Messages::epsilonWarningText1)) / 2;
|
||||
y += fontSize.height() + 5;
|
||||
ctx->drawString(Messages::epsilonWarningText1, KDPoint(initPos, y), KDFont::LargeFont, KDColorWhite, KDColorRed);
|
||||
initPos = (320 - KDFont::SmallFont->glyphSize().width() * strlen(Messages::epsilonWarningText2)) / 2;
|
||||
y += fontSize.height() + 2;
|
||||
ctx->drawString(Messages::epsilonWarningText2, KDPoint(initPos, y), KDFont::SmallFont, KDColorWhite, KDColorRed);
|
||||
initPos = (320 - KDFont::SmallFont->glyphSize().width() * strlen(Messages::epsilonWarningText3)) / 2;
|
||||
y += KDFont::SmallFont->glyphSize().height() + 5;
|
||||
ctx->drawString(Messages::epsilonWarningText3, KDPoint(initPos, y), KDFont::SmallFont, KDColorWhite, KDColorRed);
|
||||
initPos = (320 - KDFont::SmallFont->glyphSize().width() * strlen(Messages::epsilonWarningText4)) / 2;
|
||||
y += KDFont::SmallFont->glyphSize().height() + 10;
|
||||
ctx->drawString(Messages::epsilonWarningText4, KDPoint(initPos, y), KDFont::SmallFont, KDColorWhite, KDColorRed);
|
||||
y += KDFont::SmallFont->glyphSize().height() + 10;
|
||||
initPos = (320 - KDFont::SmallFont->glyphSize().width() * strlen(Messages::epsilonWarningText5)) / 2;
|
||||
ctx->drawString(Messages::epsilonWarningText5, KDPoint(initPos, y), KDFont::SmallFont, KDColorWhite, KDColorRed);
|
||||
y += KDFont::SmallFont->glyphSize().height() + 5;
|
||||
ctx->drawString(Messages::epsilonWarningText6, KDPoint(initPos, y), KDFont::SmallFont, KDColorWhite, KDColorRed);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user