summaryrefslogtreecommitdiff
path: root/src/kernel/settings.c
diff options
context:
space:
mode:
authorBenji Dial <benji6283@gmail.com>2021-02-19 22:24:08 -0500
committerBenji Dial <benji6283@gmail.com>2021-02-19 22:24:08 -0500
commiteae7442610215e55ea350c65aab4ab3869111014 (patch)
tree601aa476e52a5e3bb3b352df7e781d3aa11c090b /src/kernel/settings.c
parentcba9eec34b205c760f16f7171b58bfc906723b72 (diff)
downloadportland-os-eae7442610215e55ea350c65aab4ab3869111014.tar.gz
kernel settings file
Diffstat (limited to 'src/kernel/settings.c')
-rw-r--r--src/kernel/settings.c91
1 files changed, 91 insertions, 0 deletions
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 <stdint.h>
+
+#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