From eae7442610215e55ea350c65aab4ab3869111014 Mon Sep 17 00:00:00 2001 From: Benji Dial Date: Fri, 19 Feb 2021 22:24:08 -0500 Subject: kernel settings file --- src/kernel/settings.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 src/kernel/settings.c (limited to 'src/kernel/settings.c') diff --git a/src/kernel/settings.c b/src/kernel/settings.c new file mode 100644 index 0000000..699196b --- /dev/null +++ b/src/kernel/settings.c @@ -0,0 +1,91 @@ +#include "window.h" +#include "drive.h" +#include "panic.h" +#include "util.h" + +#include + +#define SETTINGS_FILE "sys/settings.pls" + +static struct { + uint32_t main_start; + uint32_t main_entries; + uint32_t names_start; + uint32_t data_start; +} settings_header; + +enum { + ST_SZ_STRING = 0x00, + ST_COLOR = 0x01 +}; + +struct main_entry { + uint32_t name_offset; + uint8_t name_len; + uint8_t type; + uint16_t pad; + union { + struct { + uint32_t data_offset; + uint32_t length; + } as_string; + struct pixel as_pixel; + }; +} __attribute__ ((__packed__)); + +static file_id_t fid; +static uint32_t main_end; + +void init_settings() { + fid = drives->get_file(drives, SETTINGS_FILE); + if (!fid) + PANIC("could not open settings file at \"" SETTINGS_FILE "\"."); + + fmcpy(&settings_header, drives, fid, 0, 16); + + main_end = settings_header.main_start + settings_header.main_entries * sizeof(struct main_entry); +} + +bool try_find_setting(const char *name, struct main_entry *entry_out) { + uint16_t name_len = 0; + while (name[name_len]) + if (++name_len == 256) + return false; + + for (uint32_t i = settings_header.main_start; i < main_end; i += sizeof(struct main_entry)) { + fmcpy(entry_out, drives, fid, i, sizeof(struct main_entry)); + if (entry_out->name_len != name_len) + continue; + char found_name[255]; + fmcpy(found_name, drives, fid, settings_header.names_start + entry_out->name_offset, name_len); + for (uint8_t j = 0; j < name_len; ++j) + if (found_name[j] != name[j]) + goto lc; + return true; + lc: + ; + } + + return false; +} + +bool try_get_sz_setting(const char *name, char *out, uint32_t max_len, uint32_t *len_out) { + struct main_entry entry; + if (!try_find_setting(name, &entry) || (entry.type != ST_SZ_STRING)) + return false; + + const uint32_t len = entry.as_string.length > max_len ? max_len : entry.as_string.length; + fmcpy(out, drives, fid, settings_header.data_start + entry.as_string.data_offset, len); + out[len] = '\0'; + *len_out = len; + return true; +} + +bool try_get_color_setting(const char *name, struct pixel *out) { + struct main_entry entry; + if (!try_find_setting(name, &entry) || (entry.type != ST_COLOR)) + return false; + + *out = entry.as_pixel; + return true; +} \ No newline at end of file -- cgit v1.2.3