embed important system files in Desktop.esx

This commit is contained in:
nakst 2021-08-28 20:40:28 +01:00
parent c21ad35db4
commit be6d633223
27 changed files with 126 additions and 74 deletions

View File

@ -109,7 +109,7 @@ void Draw(Texture *texture,
void CreateTexture(Texture *texture, const char *cName) {
size_t dataBytes;
const void *data = EsEmbeddedFileGet(cName, &dataBytes);
const void *data = EsEmbeddedFileGet(cName, -1, &dataBytes);
texture->bits = (uint32_t *) EsImageLoad(data, dataBytes, &texture->width, &texture->height, 4);
EsAssert(texture->bits);
}
@ -277,7 +277,7 @@ void LoadRoom() {
UpdateRoomName();
roomName[6] = '_';
const uint8_t *buffer = (const uint8_t *) EsEmbeddedFileGet(roomName);
const uint8_t *buffer = (const uint8_t *) EsEmbeddedFileGet(roomName, -1);
for (int i = 0; i < MAX_ENTITIES; i++) {
if (!state.entities[i].isUsed || state.entities[i].isDestroyed) continue;

View File

@ -129,7 +129,7 @@ const EsStyle stylePanel = {
int TestCanvasMessage(EsElement *, EsMessage *message) {
if (message->type == ES_MSG_PAINT) {
size_t dataBytes;
const void *data = EsEmbeddedFileGet("test", &dataBytes);
const void *data = EsEmbeddedFileGet("test", -1, &dataBytes);
if (data) EsDrawVectorFile(message->painter, EsPainterBoundsClient(message->painter), data, dataBytes);
} else if (message->type == ES_MSG_GET_WIDTH) {
message->measure.width = 256;

View File

@ -66,8 +66,9 @@ struct EnumString { const char *cName; int value; };
extern "C" uintptr_t ProcessorTLSRead(uintptr_t offset);
struct EsFileStore {
#define FILE_STORE_HANDLE (1)
#define FILE_STORE_PATH (2)
#define FILE_STORE_HANDLE (1)
#define FILE_STORE_PATH (2)
#define FILE_STORE_EMBEDDED_FILE (3)
uint8_t type;
bool operationComplete;
@ -148,6 +149,7 @@ void UndoManagerDestroy(EsUndoManager *manager);
int TextGetStringWidth(const EsTextStyle *style, const char *string, size_t stringBytes);
struct APIInstance *InstanceSetup(EsInstance *instance);
EsTextStyle TextPlanGetPrimaryStyle(EsTextPlan *plan);
EsFileStore *FileStoreCreateFromEmbeddedFile(const char *path, size_t pathBytes);
EsFileStore *FileStoreCreateFromPath(const char *path, size_t pathBytes);
struct ProcessMessageTiming {
@ -561,7 +563,7 @@ void FileStoreCloseHandle(EsFileStore *fileStore) {
if (fileStore->handle) {
EsHandleClose(fileStore->handle);
}
} else if (fileStore->type == FILE_STORE_PATH) {
} else if (fileStore->type == FILE_STORE_PATH || fileStore->type == FILE_STORE_EMBEDDED_FILE) {
// The path is stored after the file store allocation.
}
@ -580,6 +582,18 @@ EsFileStore *FileStoreCreateFromPath(const char *path, size_t pathBytes) {
return fileStore;
}
EsFileStore *FileStoreCreateFromEmbeddedFile(const char *name, size_t nameBytes) {
EsFileStore *fileStore = (EsFileStore *) EsHeapAllocate(sizeof(EsFileStore) + nameBytes, false);
EsMemoryZero(fileStore, sizeof(EsFileStore));
fileStore->type = FILE_STORE_EMBEDDED_FILE;
fileStore->handles = 1;
fileStore->error = ES_SUCCESS;
fileStore->path = (char *) (fileStore + 1);
fileStore->pathBytes = nameBytes;
EsMemoryCopy(fileStore->path, name, nameBytes);
return fileStore;
}
void InstanceCreateFileStore(APIInstance *instance, EsHandle handle) {
if (instance->fileStore) FileStoreCloseHandle(instance->fileStore);
instance->fileStore = (EsFileStore *) EsHeapAllocate(sizeof(EsFileStore), true);
@ -1098,13 +1112,11 @@ extern "C" void _start(EsProcessStartupInformation *_startupInformation) {
0, sizeof(GlobalData), desktop ? ES_MAP_OBJECT_READ_WRITE : ES_MAP_OBJECT_READ_ONLY);
}
bool uiProcess = false;
bool uiProcess = true; // TODO Determine this properly.
if (desktop) {
EsPrint("Reached Desktop process.\n");
uiProcess = true;
// Process messages until we find the boot file system.
while (!api.foundBootFileSystem) {
@ -1121,15 +1133,10 @@ extern "C" void _start(EsProcessStartupInformation *_startupInformation) {
char *path;
path = EsSystemConfigurationReadString(EsLiteral("general"), EsLiteral("fonts_path"));
NodeOpen(path, EsCStringLength(path), ES_FLAGS_DEFAULT, &node);
NodeOpen(path, EsCStringLength(path), ES_NODE_DIRECTORY, &node);
NodeAddMountPoint(EsLiteral("|Fonts:"), node.handle, false);
EsHeapFree(path);
path = EsSystemConfigurationReadString(EsLiteral("general"), EsLiteral("themes_path"));
NodeOpen(path, EsCStringLength(path), ES_FLAGS_DEFAULT, &node);
NodeAddMountPoint(EsLiteral("|Themes:"), node.handle, false);
EsHeapFree(path);
SettingsUpdateGlobalAndWindowManager();
} else {
EsHandle initialMountPointsBuffer = EsSyscall(ES_SYSCALL_PROCESS_GET_CREATION_ARGUMENT, ES_CURRENT_PROCESS, CREATION_ARGUMENT_INITIAL_MOUNT_POINTS, 0, 0);
@ -1139,10 +1146,6 @@ extern "C" void _start(EsProcessStartupInformation *_startupInformation) {
for (uintptr_t i = 0; i < initialMountPointCount; i++) {
NodeAddMountPoint(initialMountPoints[i].prefix, initialMountPoints[i].prefixBytes, initialMountPoints[i].base, true);
if (0 == EsStringCompareRaw(initialMountPoints[i].prefix, initialMountPoints[i].prefixBytes, EsLiteral("|Themes:"))) {
uiProcess = true;
}
}
EsHeapFree(initialMountPoints);
@ -1159,11 +1162,11 @@ extern "C" void _start(EsProcessStartupInformation *_startupInformation) {
theming.scale = api.systemConstants[ES_SYSTEM_CONSTANT_UI_SCALE] / 100.0f;
size_t pathBytes, fileBytes;
char *path = EsSystemConfigurationReadString(EsLiteral("ui"), EsLiteral("theme"), &pathBytes);
void *file = EsFileMap(path, pathBytes, &fileBytes, ES_MAP_OBJECT_READ_ONLY);
size_t fileBytes;
const void *file = EsEmbeddedFileGet(EsLiteral("Theme.dat"), &fileBytes);
EsAssert(ThemeLoadData(file, fileBytes));
EsHeapFree(path);
iconManagement.standardPack = (const uint8_t *) EsEmbeddedFileGet(EsLiteral("Icons.dat"), &iconManagement.standardPackSize);
theming.cursors.width = ES_THEME_CURSORS_WIDTH;
theming.cursors.height = ES_THEME_CURSORS_HEIGHT;
@ -1490,23 +1493,31 @@ void EsInstanceSetActiveUndoManager(EsInstance *_instance, EsUndoManager *manage
EsCommandSetDisabled(EsCommandByID(manager->instance, ES_COMMAND_REDO), !manager->redoStack.Length());
}
const void *EsEmbeddedFileGet(const char *cName, size_t *byteCount) {
uint64_t name = CalculateCRC64(cName, EsCStringLength(cName));
const void *EsEmbeddedFileGet(const char *_name, ptrdiff_t nameBytes, size_t *byteCount) {
// TODO It's probably a bad idea to let applications load embedded files from Desktop.
uint64_t name = CalculateCRC64(_name, nameBytes == -1 ? EsCStringLength(_name) : nameBytes);
const BundleHeader *header = (const BundleHeader *) BUNDLE_FILE_MAP_ADDRESS;
const BundleFile *files = (const BundleFile *) (header + 1);
for (uintptr_t i = 0; i < 2; i++) {
if (i == 0 && (api.startupInformation->isDesktop || !api.startupInformation->isBundle)) {
continue;
}
if (header->signature != BUNDLE_SIGNATURE) {
return nullptr;
}
const BundleHeader *header = (const BundleHeader *) (i ? BUNDLE_FILE_DESKTOP_MAP_ADDRESS : BUNDLE_FILE_MAP_ADDRESS);
const BundleFile *files = (const BundleFile *) (header + 1);
for (uintptr_t i = 0; i < header->fileCount; i++) {
if (files[i].nameCRC64 == name) {
if (byteCount) {
*byteCount = files[i].bytes;
if (header->signature != BUNDLE_SIGNATURE) {
return nullptr;
}
for (uintptr_t i = 0; i < header->fileCount; i++) {
if (files[i].nameCRC64 == name) {
if (byteCount) {
*byteCount = files[i].bytes;
}
return (const uint8_t *) header + files[i].offset;
}
return (const uint8_t *) header + files[i].offset;
}
}

View File

@ -28,7 +28,7 @@
// TODO Only let File Manager read the file_type sections of the system configuration.
// TODO Restarting Desktop if it crashes.
// TODO Make sure applications can't delete |Fonts: and |Themes:.
// TODO Make sure applications can't delete |Fonts:.
// TODO Handle open document deletion.
#define MSG_SETUP_DESKTOP_UI ((EsMessageType) (ES_MSG_USER_START + 1))
@ -983,7 +983,6 @@ bool ApplicationInstanceStart(int64_t applicationID, EsApplicationStartupInforma
arguments.permissions |= ES_PERMISSION_GET_VOLUME_INFORMATION;
} else {
initialMountPoints.Add(*NodeFindMountPoint(EsLiteral("|Themes:")));
initialMountPoints.Add(*NodeFindMountPoint(EsLiteral("|Fonts:")));
}
@ -2038,7 +2037,7 @@ void DesktopMessage2(EsMessage *message, uint8_t *buffer, EsBuffer *pipe) {
desktop.installedApplications.Add(application);
ApplicationInstanceCreate(application->id, nullptr, nullptr);
}
} else if (buffer[0] == DESKTOP_MSG_UNHANDLED_KEY_EVENT) {
} else if (buffer[0] == DESKTOP_MSG_UNHANDLED_KEY_EVENT && instance->tab) {
_EsMessageWithObject message;
EsSyscall(ES_SYSCALL_WINDOW_GET_EMBED_KEYBOARD, instance->tab->window->handle, (uintptr_t) &message, 0, 0);

View File

@ -1907,7 +1907,7 @@ function void EsINIZeroTerminate(EsINIState *s);
// File systems.
function const void *EsEmbeddedFileGet(const char *cName, size_t *byteCount = ES_NULL);
function const void *EsEmbeddedFileGet(STRING name, size_t *byteCount = ES_NULL);
function ptrdiff_t EsDirectoryEnumerateChildren(STRING path, EsDirectoryChild **buffer); // Free buffer with EsHeapFree. Returns number of children.

View File

@ -237,7 +237,7 @@ ES_EXTERN_C void _start();
#if defined(ES_API) || defined(KERNEL)
struct EsProcessStartupInformation {
bool isDesktop;
bool isDesktop, isBundle;
uintptr_t applicationStartAddress;
uintptr_t tlsImageStart;
uintptr_t tlsImageBytes;
@ -255,6 +255,7 @@ struct _EsPOSIXSyscall {
#ifdef ARCH_X86_64
#define BUNDLE_FILE_MAP_ADDRESS (0x100000000UL)
#define BUNDLE_FILE_DESKTOP_MAP_ADDRESS (0xF0000000UL)
#endif
struct BundleHeader {

View File

@ -290,6 +290,14 @@ void *EsFileStoreReadAll(EsFileStore *file, size_t *fileSize) {
return EsFileReadAllFromHandle(file->handle, fileSize, &file->error);
} else if (file->type == FILE_STORE_PATH) {
return EsFileReadAll(file->path, file->pathBytes, fileSize, &file->error);
} else if (file->type == FILE_STORE_EMBEDDED_FILE) {
size_t _fileSize;
const void *data = EsEmbeddedFileGet(file->path, file->pathBytes, &_fileSize);
void *copy = EsHeapAllocate(_fileSize, false);
if (!copy) return nullptr;
if (fileSize) *fileSize = _fileSize;
EsMemoryCopy(copy, data, _fileSize);
return copy;
} else {
EsAssert(false);
return nullptr;
@ -321,6 +329,10 @@ EsFileOffsetDifference EsFileStoreGetSize(EsFileStore *file) {
} else {
return -1;
}
} else if (file->type == FILE_STORE_EMBEDDED_FILE) {
size_t size;
EsEmbeddedFileGet(file->path, file->pathBytes, &size);
return size;
} else {
EsAssert(false);
return 0;
@ -335,6 +347,8 @@ void *EsFileStoreMap(EsFileStore *file, size_t *fileSize, uint32_t flags) {
return EsObjectMap(file->handle, 0, size, flags);
} else if (file->type == FILE_STORE_PATH) {
return EsFileMap(file->path, file->pathBytes, fileSize, flags);
} else if (file->type == FILE_STORE_EMBEDDED_FILE) {
return (void *) EsEmbeddedFileGet(file->path, file->pathBytes, fileSize);
} else {
EsAssert(false);
return nullptr;

View File

@ -506,7 +506,12 @@ void FontInitialise() {
}
size_t fileIndex = weight - 1 + italic * 9;
entry.files[fileIndex] = FileStoreCreateFromPath(item->value, item->valueBytes);
if (item->valueBytes && item->value[0] == ':') {
entry.files[fileIndex] = FileStoreCreateFromEmbeddedFile(item->value + 1, item->valueBytes - 1);
} else {
entry.files[fileIndex] = FileStoreCreateFromPath(item->value, item->valueBytes);
}
}
}
@ -1255,13 +1260,6 @@ bool EsDrawStandardIcon(EsPainter *painter, uint32_t id, int size, EsRectangle r
if (!id) return false;
id--;
if (!iconManagement.standardPack) {
size_t pathBytes;
char *path = EsSystemConfigurationReadString(EsLiteral("ui"), EsLiteral("icon_pack"), &pathBytes);
iconManagement.standardPack = (uint8_t *) EsFileMap(path, pathBytes, &iconManagement.standardPackSize, ES_MAP_OBJECT_READ_ONLY);
EsHeapFree(path);
}
{
// Center the icon.

View File

@ -1370,7 +1370,7 @@ const char *GetConstantString(const char *cKey) {
return !value || !byteCount || value[byteCount - 1] ? nullptr : value;
}
bool ThemeLoadData(void *buffer, size_t byteCount) {
bool ThemeLoadData(const void *buffer, size_t byteCount) {
EsBuffer data = {};
data.in = (const uint8_t *) buffer;
data.bytes = byteCount;

View File

@ -132,7 +132,11 @@ EsError KLoadELF(KNode *node, KLoadedExecutable *executable) {
&& header.fileCount < 0x100000
&& header.fileCount * sizeof(BundleFile) + sizeof(BundleHeader) < fileSize) {
if (!header.mapAddress) {
header.mapAddress = BUNDLE_FILE_MAP_ADDRESS;
if (executable->isDesktop) {
header.mapAddress = BUNDLE_FILE_DESKTOP_MAP_ADDRESS;
} else {
header.mapAddress = BUNDLE_FILE_MAP_ADDRESS;
}
}
#ifdef ARCH_X86_64
@ -177,6 +181,8 @@ EsError KLoadELF(KNode *node, KLoadedExecutable *executable) {
if (executableOffset >= fileSize || !found) {
return ES_ERROR_UNSUPPORTED_EXECUTABLE;
}
executable->isBundle = true;
}
}

View File

@ -251,6 +251,8 @@ struct KLoadedExecutable {
uintptr_t tlsImageStart;
uintptr_t tlsImageBytes;
uintptr_t tlsBytes; // All bytes after the image are to be zeroed.
bool isDesktop, isBundle;
};
EsError KLoadELF(struct KNode *node, KLoadedExecutable *executable);

View File

@ -574,6 +574,7 @@ void NewProcess() {
"New process %d %x, '%z'.\n", thisProcess->id, thisProcess, thisProcess->cExecutableName);
KLoadedExecutable api = {};
api.isDesktop = true;
EsError loadError = ES_SUCCESS;
{
@ -621,6 +622,7 @@ void NewProcess() {
success = false;
} else {
startupInformation->isDesktop = thisProcess == desktopProcess;
startupInformation->isBundle = application.isBundle;
startupInformation->applicationStartAddress = application.startAddress;
startupInformation->tlsImageStart = application.tlsImageStart;
startupInformation->tlsImageBytes = application.tlsImageBytes;

View File

Before

Width:  |  Height:  |  Size: 862 KiB

After

Width:  |  Height:  |  Size: 862 KiB

View File

Before

Width:  |  Height:  |  Size: 426 KiB

After

Width:  |  Height:  |  Size: 426 KiB

View File

Before

Width:  |  Height:  |  Size: 260 KiB

After

Width:  |  Height:  |  Size: 260 KiB

View File

Before

Width:  |  Height:  |  Size: 428 KiB

After

Width:  |  Height:  |  Size: 428 KiB

View File

Before

Width:  |  Height:  |  Size: 238 KiB

After

Width:  |  Height:  |  Size: 238 KiB

View File

Before

Width:  |  Height:  |  Size: 500 KiB

After

Width:  |  Height:  |  Size: 500 KiB

View File

Before

Width:  |  Height:  |  Size: 528 KiB

After

Width:  |  Height:  |  Size: 528 KiB

View File

@ -2,7 +2,6 @@
; General settings.
startup_sound=0:/Essence/Media/Startup Sound.wav
fonts_path=0:/Essence/Fonts
themes_path=0:/Essence/Themes
temporary_path=0:/Essence/Temporary
settings_path=0:/Settings
default_user_documents_path=0:/
@ -14,8 +13,6 @@ scroll_lines_per_notch=3
[ui]
; User interface settings that are accessible by all applications.
theme=|Themes:/Theme.dat
icon_pack=|Themes:/elementary Icons.dat
font_fallback=Inter
font_sans=Inter
font_serif=Inter

View File

@ -43,7 +43,7 @@ char **argv;
#include "build_common.h"
BuildFont fonts[] = {
{ "Inter", "Sans", "Latn,Grek,Cyrl", (FontFile []) {
{ "Inter", "Inter License.txt", "Sans", "Latn,Grek,Cyrl", (FontFile []) {
{ "1", "Inter Thin.otf" },
{ "1i", "Inter Thin Italic.otf" },
{ "2", "Inter Extra Light.otf" },
@ -65,7 +65,7 @@ BuildFont fonts[] = {
{},
} },
{ "Hack", "Mono", "Latn,Grek,Cyrl", (FontFile []) {
{ "Hack", "Hack License.md", "Mono", "Latn,Grek,Cyrl", (FontFile []) {
{ "4", "Hack Regular.ttf" },
{ "4i", "Hack Regular Italic.ttf" },
{ "7", "Hack Bold.ttf" },
@ -241,7 +241,7 @@ void Compile(uint32_t flags, int partitionSize, const char *volumeLabel) {
while (fonts[fontIndex].files) {
BuildFont *font = fonts + fontIndex;
fprintf(f, "[@font %s]\ncategory=%s\nscripts=%s\n", font->name, font->category, font->scripts);
fprintf(f, "[@font %s]\ncategory=%s\nscripts=%s\nlicense=%s\n", font->name, font->category, font->scripts, font->license);
uintptr_t fileIndex = 0;
while (font->files[fileIndex].path) {
@ -336,7 +336,7 @@ void Build(bool enableOptimisations, bool compile) {
srand(time(NULL));
printf("Build started...\n");
CallSystem("mkdir -p root root/Applications root/Applications/POSIX root/Applications/POSIX/bin "
"root/Applications/POSIX/lib root/Applications/POSIX/include root/Essence/Modules");
"root/Applications/POSIX/lib root/Applications/POSIX/include ");
#if 0
if (_installationIdentifier) {

View File

@ -41,6 +41,7 @@ typedef struct FontFile {
typedef struct BuildFont {
const char *name;
const char *license;
const char *category;
const char *scripts;
FontFile *files;

View File

@ -429,7 +429,7 @@ typedef struct BundleInput {
uint64_t alignment;
} BundleInput;
bool MakeBundle(const char *outputFile, BundleInput *inputFiles, size_t inputFileCount) {
bool MakeBundle(const char *outputFile, BundleInput *inputFiles, size_t inputFileCount, uint64_t mapAddress) {
File output = FileOpen(outputFile, 'w');
if (output.error) {
@ -445,7 +445,6 @@ bool MakeBundle(const char *outputFile, BundleInput *inputFiles, size_t inputFil
FileWrite(output, sizeof(uint32_t), &fileCount);
uint32_t zero = 0;
FileWrite(output, sizeof(uint32_t), &zero);
uint64_t mapAddress = 0;
FileWrite(output, sizeof(uint64_t), &mapAddress);
for (uintptr_t i = 0; i < fileCount; i++) {
@ -540,16 +539,37 @@ int nextID = 1;
Application *applications;
const char **kernelModules;
#define ADD_BUNDLE_INPUT(_path, _name, _alignment) do { \
BundleInput bundleInputFile = {}; \
bundleInputFile.path = _path; \
bundleInputFile.name = _name; \
bundleInputFile.alignment = _alignment; \
arrput(application->bundleInputFiles, bundleInputFile); \
} while (0)
void BuildDesktop(Application *application) {
ExecuteForApp(application, toolchainNasm, "-felf64", "desktop/api.s", "-MD", "bin/api1.d", "-o", "bin/api1.o", "-Fdwarf");
ExecuteForApp(application, toolchainCXX, "-MD", "-c", "desktop/api.cpp", "-o", "bin/api2.o", ArgString(commonCompileFlags));
ExecuteForApp(application, toolchainCXX, "-MD", "-c", "desktop/posix.cpp", "-o", "bin/api3.o", ArgString(commonCompileFlags));
ExecuteForApp(application, toolchainCC, "-o", "bin/Desktop", "bin/crti.o", "bin/crtbegin.o",
"bin/api1.o", "bin/api2.o", "bin/api3.o", "bin/crtend.o", "bin/crtn.o",
ArgString(apiLinkFlags1), ArgString(apiLinkFlags2), ArgString(apiLinkFlags3));
ExecuteForApp(application, toolchainStrip, "-o", "bin/Desktop.no_symbols", "--strip-all", "bin/Desktop");
ExecuteForApp(application, toolchainStrip, "-o", "root/Essence/Desktop.esx", "--strip-all", "bin/Desktop");
for (uintptr_t i = 0; i < arrlenu(fontLines); i++) {
if (fontLines[i].key[0] == '.' || 0 == strcmp(fontLines[i].key, "license")) {
char buffer[4096];
snprintf(buffer, sizeof(buffer), "res/Fonts/%s", fontLines[i].value);
ADD_BUNDLE_INPUT(strdup(buffer), fontLines[i].value, 16);
}
}
ADD_BUNDLE_INPUT("res/Themes/Theme.dat", "Theme.dat", 16);
ADD_BUNDLE_INPUT("res/Themes/elementary Icons.dat", "Icons.dat", 16);
ADD_BUNDLE_INPUT("res/Themes/elementary Icons License.txt", "Icons License.txt", 16);
ADD_BUNDLE_INPUT("bin/Desktop.no_symbols", "Executable (x86_64)", 0x1000);
MakeBundle("root/Essence/Desktop.esx", application->bundleInputFiles, arrlenu(application->bundleInputFiles), 0);
}
void BuildApplication(Application *application) {
@ -610,11 +630,7 @@ void BuildApplication(Application *application) {
ArgString(applicationLinkFlags), "-T", linkerScript);
ExecuteForApp(application, toolchainStrip, "-o", strippedFile, "--strip-all", symbolFile);
BundleInput bundleInputFile = {};
bundleInputFile.path = strippedFile;
bundleInputFile.name = "Executable (x86_64)";
bundleInputFile.alignment = 0x1000;
arrput(application->bundleInputFiles, bundleInputFile);
ADD_BUNDLE_INPUT(strippedFile, "Executable (x86_64)", 0x1000);
// Convert any files for the bundle marked with a '!'.
@ -638,7 +654,7 @@ void BuildApplication(Application *application) {
}
}
MakeBundle(executable, application->bundleInputFiles, arrlenu(application->bundleInputFiles));
MakeBundle(executable, application->bundleInputFiles, arrlenu(application->bundleInputFiles), 0);
}
}
@ -836,7 +852,7 @@ void OutputSystemConfiguration() {
FilePrintFormat(file, "%s=|Fonts:/%.*s.dat\n", fontLines[i].key, (int) fontLines[i].valueBytes - 4, fontLines[i].value);
#endif
} else {
FilePrintFormat(file, "%s=|Fonts:/%s\n", fontLines[i].key, fontLines[i].value);
FilePrintFormat(file, "%s=:%s\n", fontLines[i].key, fontLines[i].value);
}
} else {
size_t bytes = EsINIFormat(fontLines + i, buffer, sizeof(buffer));
@ -859,6 +875,7 @@ void BuildModule(Application *application) {
if (!application->builtin) {
char target[4096];
snprintf(target, sizeof(target), "root/Essence/Modules/%s.ekm", application->name);
MakeDirectory("root/Essence/Modules");
MoveFile(output, target);
}
}
@ -1139,8 +1156,15 @@ void Install(const char *driveFile, uint64_t partitionSize, const char *partitio
ImportNode root = {};
CreateImportNode("root", &root);
CreateImportNode("res/Themes", ImportNodeMakeDirectory(ImportNodeFindChild(&root, "Essence"), "Themes"));
CreateImportNode("res/Media", ImportNodeMakeDirectory(ImportNodeFindChild(&root, "Essence"), "Media"));
CreateImportNode("res/Sample Images", ImportNodeMakeDirectory(&root, "Sample Images"));
{
ImportNode child = {};
child.isFile = true;
child.name = "A Study in Scarlet.txt";
child.path = "res/A Study in Scarlet.txt";
arrput(root.children, child);
}
if (convertFonts) {
ImportNode *fontsFolder = ImportNodeMakeDirectory(ImportNodeFindChild(&root, "Essence"), "Fonts");
@ -1153,8 +1177,6 @@ void Install(const char *driveFile, uint64_t partitionSize, const char *partitio
ImportNodeAddFile(fontsFolder, strdup(destination), strdup(source));
}
}
} else {
CreateImportNode("res/Fonts", ImportNodeMakeDirectory(ImportNodeFindChild(&root, "Essence"), "Fonts"));
}
MountVolume();
@ -1389,7 +1411,6 @@ int main(int argc, char **argv) {
MakeDirectory("root/Applications/POSIX/tmp");
MakeDirectory("root/Applications/POSIX/lib/linker");
MakeDirectory("root/Essence");
MakeDirectory("root/Essence/Modules");
if (!skipHeaderGeneration) {
HeaderGeneratorMain(1, NULL);