shithub: m8c

Download patch

ref: 9bfe4ddb18ee77192c57b91c4ef305082588d77e
parent: 3c3a30629a027ee82da82fc63ad0f1eaf17e1498
parent: d6ac873907cc4f8e3b3b0754d88044c239a1fe29
author: Jonne Kokkonen <jonne.kokkonen@gmail.com>
date: Sun Oct 3 14:49:07 EDT 2021

Merge pull request #19 from JeffAlyanak/read-config

Added basic config handling.

--- a/LICENSE
+++ b/LICENSE
@@ -57,3 +57,8 @@
 The software contains portions of public domain code:
 Bitmap font routine by driedfruit, https://github.com/driedfruit/SDL_inprint (SDL2_inprint.h, inprint2.c)
 Serial port code from libserialport's examples (serial.c, serial.h)
+
+-----------
+
+The software contains the Tiny ANSI C ini libary under The MIT License:
+rxi: https://github.com/rxi/ini (ini.h, ini.c)
\ No newline at end of file
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 #Set all your object files (the object files of all the .c files in your project, e.g. main.o my_sub_functions.o )
-OBJ = main.o serial.o slip.o command.o write.o render.o input.o font.o
+OBJ = main.o serial.o slip.o command.o write.o render.o ini.o config.o input.o font.o
 
 #Set any dependant header files so that if they are edited they cause a complete re-compile (e.g. main.h some_subfunctions.h some_definitions_file.h ), or leave blank
-DEPS = serial.h slip.h command.h write.h render.h input.h
+DEPS = serial.h slip.h command.h write.h render.h ini.h config.h input.h
 
 #Any special libraries you are using in your project (e.g. -lbcm2835 -lrt `pkg-config --libs gtk+-3.0` ), or leave blank
 INCLUDES = -lserialport
--- a/README.md
+++ b/README.md
@@ -93,6 +93,12 @@
 
 Enjoy making some nice music!
 
+### Config
+
+The config function is currently a prototype, the config file must be named `config.ini` and must be present in the directory from which you're running the command.
+
+See the `config.ini` file to see the available options.
+
 -----------
 
 ### Bonus: improve performance on the Raspberry Pi
--- /dev/null
+++ b/config.c
@@ -1,0 +1,118 @@
+// Copyright 2021 Jonne Kokkonen
+// Released under the MIT licence, https://opensource.org/licenses/MIT
+
+#include <SDL2/SDL.h>
+#include "config.h"
+
+config_params_s init_config() {
+  config_params_s c;
+
+  c.filename        = "config.ini"; // default config file to load
+  c.init_fullscreen = 0;            // default fullscreen state at load
+
+  c.key_up          = SDL_SCANCODE_UP;
+  c.key_left        = SDL_SCANCODE_LEFT;
+  c.key_down        = SDL_SCANCODE_DOWN;
+  c.key_right       = SDL_SCANCODE_RIGHT;
+  c.key_select      = SDL_SCANCODE_LSHIFT;
+  c.key_select_alt  = SDL_SCANCODE_A;
+  c.key_start       = SDL_SCANCODE_SPACE;
+  c.key_start_alt   = SDL_SCANCODE_S;
+  c.key_opt         = SDL_SCANCODE_LALT;
+  c.key_opt_alt     = SDL_SCANCODE_Z;
+  c.key_edit        = SDL_SCANCODE_LCTRL;
+  c.key_edit_alt    = SDL_SCANCODE_X;
+  c.key_delete      = SDL_SCANCODE_DELETE;
+  c.key_reset       = SDL_SCANCODE_R;
+
+  c.gamepad_up      = SDL_CONTROLLER_BUTTON_DPAD_UP;
+  c.gamepad_left    = SDL_CONTROLLER_BUTTON_DPAD_LEFT;
+  c.gamepad_down    = SDL_CONTROLLER_BUTTON_DPAD_DOWN;
+  c.gamepad_right   = SDL_CONTROLLER_BUTTON_DPAD_RIGHT;
+  c.gamepad_select  = SDL_CONTROLLER_BUTTON_BACK;
+  c.gamepad_start   = SDL_CONTROLLER_BUTTON_START;
+  c.gamepad_opt     = SDL_CONTROLLER_BUTTON_B;
+  c.gamepad_edit    = SDL_CONTROLLER_BUTTON_A;
+  return c;
+}
+
+// Read config 
+void read_config(config_params_s *conf) {
+  // Load the config and read the fullscreen setting from the graphics section
+  ini_t *ini = ini_load(conf->filename);
+  if (ini == NULL) {
+    return;
+  }
+
+  read_graphics_config(ini, conf);
+  read_key_config(ini, conf);
+  read_gamepad_config(ini, conf);
+
+  // Frees the mem used for the config
+  ini_free(ini);
+}
+
+void read_graphics_config(ini_t *ini, config_params_s *conf) {
+  const char *param = ini_get(ini, "graphics", "fullscreen");
+  // This obviously requires the parameter to be a lowercase true to enable fullscreen
+  if ( strcmp(param, "true") == 0 ) {
+    conf->init_fullscreen = 1;
+  }
+  else conf->init_fullscreen = 0;
+}
+
+void read_key_config(ini_t *ini, config_params_s *conf) {
+  // TODO: Some form of validation
+
+  const char *key_up          = ini_get(ini, "keyboard", "key_up");
+  const char *key_left        = ini_get(ini, "keyboard", "key_left");
+  const char *key_down        = ini_get(ini, "keyboard", "key_down");
+  const char *key_right       = ini_get(ini, "keyboard", "key_right");
+  const char *key_select      = ini_get(ini, "keyboard", "key_select");
+  const char *key_select_alt  = ini_get(ini, "keyboard", "key_select_alt");
+  const char *key_start       = ini_get(ini, "keyboard", "key_start");
+  const char *key_start_alt   = ini_get(ini, "keyboard", "key_start_alt");
+  const char *key_opt         = ini_get(ini, "keyboard", "key_opt");
+  const char *key_opt_alt     = ini_get(ini, "keyboard", "key_opt_alt");
+  const char *key_edit        = ini_get(ini, "keyboard", "key_edit");
+  const char *key_edit_alt    = ini_get(ini, "keyboard", "key_edit_alt");
+  const char *key_delete      = ini_get(ini, "keyboard", "key_delete");
+  const char *key_reset       = ini_get(ini, "keyboard", "key_reset");
+
+  conf->key_up          = atoi(key_up);
+  conf->key_left        = atoi(key_left);
+  conf->key_down        = atoi(key_down);
+  conf->key_right       = atoi(key_right);
+  conf->key_select      = atoi(key_select);
+  conf->key_select_alt  = atoi(key_select_alt);
+  conf->key_start       = atoi(key_start);
+  conf->key_start_alt   = atoi(key_start_alt);
+  conf->key_opt         = atoi(key_opt);
+  conf->key_opt_alt     = atoi(key_opt_alt);
+  conf->key_edit        = atoi(key_edit);
+  conf->key_edit_alt    = atoi(key_edit_alt);
+  conf->key_delete      = atoi(key_delete);
+  conf->key_reset       = atoi(key_reset);
+}
+
+void read_gamepad_config(ini_t *ini, config_params_s *conf) {
+  // TODO: Some form of validation
+
+  const char *gamepad_up      = ini_get(ini, "gamepad", "gamepad_up");
+  const char *gamepad_left    = ini_get(ini, "gamepad", "gamepad_left");
+  const char *gamepad_down    = ini_get(ini, "gamepad", "gamepad_down");
+  const char *gamepad_right   = ini_get(ini, "gamepad", "gamepad_right");
+  const char *gamepad_select  = ini_get(ini, "gamepad", "gamepad_select");
+  const char *gamepad_start   = ini_get(ini, "gamepad", "gamepad_start");
+  const char *gamepad_opt     = ini_get(ini, "gamepad", "gamepad_opt");
+  const char *gamepad_edit    = ini_get(ini, "gamepad", "gamepad_edit");
+
+  conf->gamepad_up      = atoi(gamepad_up);
+  conf->gamepad_left    = atoi(gamepad_left);
+  conf->gamepad_down    = atoi(gamepad_down);
+  conf->gamepad_right   = atoi(gamepad_right);
+  conf->gamepad_select  = atoi(gamepad_select);
+  conf->gamepad_start   = atoi(gamepad_start);
+  conf->gamepad_opt     = atoi(gamepad_opt);
+  conf->gamepad_edit    = atoi(gamepad_edit);
+}
\ No newline at end of file
--- /dev/null
+++ b/config.h
@@ -1,0 +1,45 @@
+// Copyright 2021 Jonne Kokkonen
+// Released under the MIT licence, https://opensource.org/licenses/MIT
+
+#ifndef CONFIG_H_
+#define CONFIG_H_
+
+#include "ini.h"
+
+typedef struct config_params_s {
+  char *filename;
+  int init_fullscreen;
+
+  int key_up;
+  int key_left;
+  int key_down;
+  int key_right;
+  int key_select;
+  int key_select_alt;
+  int key_start;
+  int key_start_alt;
+  int key_opt;
+  int key_opt_alt;
+  int key_edit;
+  int key_edit_alt;
+  int key_delete;
+  int key_reset;
+
+  int gamepad_up;
+  int gamepad_left;
+  int gamepad_down;
+  int gamepad_right;
+  int gamepad_select;
+  int gamepad_start;
+  int gamepad_opt;
+  int gamepad_edit;
+} config_params_s;
+
+
+config_params_s init_config();
+void read_config();
+void read_graphics_config(ini_t *config, config_params_s *conf);
+void read_key_config(ini_t *config, config_params_s *conf);
+void read_gamepad_config(ini_t *config, config_params_s *conf);
+
+#endif
\ No newline at end of file
--- /dev/null
+++ b/config.ini
@@ -1,0 +1,33 @@
+[graphics]
+; set this to true to have m8c start fullscreen
+fullscreen=false
+
+[keyboard]
+; these need to be the decimal value of the SDL scancodes.
+; a table exists here: https://github.com/libsdl-org/sdlwiki/blob/main/SDLScancodeLookup.mediawiki
+key_up=82
+key_left=80
+key_down=81
+key_right=79
+key_select=225
+key_select_alt=4
+key_start=44
+key_start_alt=22
+key_opt=226
+key_opt_alt=29
+key_edit=224
+key_edit_alt=27
+key_delete=76
+key_reset=21
+
+[gamepad]
+; these need to be the decimal value of the SDL Controller buttons.
+; a table exists here: https://wiki.libsdl.org/SDL_GameControllerButton
+gamepad_up=11
+gamepad_left=13
+gamepad_down=12
+gamepad_right=14
+gamepad_select=4
+gamepad_start=6
+gamepad_opt=1
+gamepad_edit=0
\ No newline at end of file
--- /dev/null
+++ b/ini.c
@@ -1,0 +1,274 @@
+/**
+ * Copyright (c) 2016 rxi
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "ini.h"
+
+struct ini_t {
+  char *data;
+  char *end;
+};
+
+
+/* Case insensitive string compare */
+static int strcmpci(const char *a, const char *b) {
+  for (;;) {
+    int d = tolower(*a) - tolower(*b);
+    if (d != 0 || !*a) {
+      return d;
+    }
+    a++, b++;
+  }
+}
+
+/* Returns the next string in the split data */
+static char* next(ini_t *ini, char *p) {
+  p += strlen(p);
+  while (p < ini->end && *p == '\0') {
+    p++;
+  }
+  return p;
+}
+
+static void trim_back(ini_t *ini, char *p) {
+  while (p >= ini->data && (*p == ' ' || *p == '\t' || *p == '\r')) {
+    *p-- = '\0';
+  }
+}
+
+static char* discard_line(ini_t *ini, char *p) {
+  while (p < ini->end && *p != '\n') {
+    *p++ = '\0';
+  }
+  return p;
+}
+
+
+static char *unescape_quoted_value(ini_t *ini, char *p) {
+  /* Use `q` as write-head and `p` as read-head, `p` is always ahead of `q`
+   * as escape sequences are always larger than their resultant data */
+  char *q = p;
+  p++;
+  while (p < ini->end && *p != '"' && *p != '\r' && *p != '\n') {
+    if (*p == '\\') {
+      /* Handle escaped char */
+      p++;
+      switch (*p) {
+        default   : *q = *p;    break;
+        case 'r'  : *q = '\r';  break;
+        case 'n'  : *q = '\n';  break;
+        case 't'  : *q = '\t';  break;
+        case '\r' :
+        case '\n' :
+        case '\0' : goto end;
+      }
+
+    } else {
+      /* Handle normal char */
+      *q = *p;
+    }
+    q++, p++;
+  }
+end:
+  return q;
+}
+
+
+/* Splits data in place into strings containing section-headers, keys and
+ * values using one or more '\0' as a delimiter. Unescapes quoted values */
+static void split_data(ini_t *ini) {
+  char *value_start, *line_start;
+  char *p = ini->data;
+
+  while (p < ini->end) {
+    switch (*p) {
+      case '\r':
+      case '\n':
+      case '\t':
+      case ' ':
+        *p = '\0';
+        /* Fall through */
+
+      case '\0':
+        p++;
+        break;
+
+      case '[':
+        p += strcspn(p, "]\n");
+        *p = '\0';
+        break;
+
+      case ';':
+        p = discard_line(ini, p);
+        break;
+
+      default:
+        line_start = p;
+        p += strcspn(p, "=\n");
+
+        /* Is line missing a '='? */
+        if (*p != '=') {
+          p = discard_line(ini, line_start);
+          break;
+        }
+        trim_back(ini, p - 1);
+
+        /* Replace '=' and whitespace after it with '\0' */
+        do {
+          *p++ = '\0';
+        } while (*p == ' ' || *p == '\r' || *p == '\t');
+
+        /* Is a value after '=' missing? */
+        if (*p == '\n' || *p == '\0') {
+          p = discard_line(ini, line_start);
+          break;
+        }
+
+        if (*p == '"') {
+          /* Handle quoted string value */
+          value_start = p;
+          p = unescape_quoted_value(ini, p);
+
+          /* Was the string empty? */
+          if (p == value_start) {
+            p = discard_line(ini, line_start);
+            break;
+          }
+
+          /* Discard the rest of the line after the string value */
+          p = discard_line(ini, p);
+
+        } else {
+          /* Handle normal value */
+          p += strcspn(p, "\n");
+          trim_back(ini, p - 1);
+        }
+        break;
+    }
+  }
+}
+
+
+
+ini_t* ini_load(const char *filename) {
+  ini_t *ini = NULL;
+  FILE *fp = NULL;
+  int n, sz;
+
+  /* Init ini struct */
+  ini = malloc(sizeof(*ini));
+  if (!ini) {
+    goto fail;
+  }
+  memset(ini, 0, sizeof(*ini));
+
+  /* Open file */
+  fp = fopen(filename, "rb");
+  if (!fp) {
+    goto fail;
+  }
+
+  /* Get file size */
+  fseek(fp, 0, SEEK_END);
+  sz = ftell(fp);
+  rewind(fp);
+
+  /* Load file content into memory, null terminate, init end var */
+  ini->data = malloc(sz + 1);
+  ini->data[sz] = '\0';
+  ini->end = ini->data  + sz;
+  n = fread(ini->data, 1, sz, fp);
+  if (n != sz) {
+    goto fail;
+  }
+
+  /* Prepare data */
+  split_data(ini);
+
+  /* Clean up and return */
+  fclose(fp);
+  return ini;
+
+fail:
+  if (fp) fclose(fp);
+  if (ini) ini_free(ini);
+  return NULL;
+}
+
+
+void ini_free(ini_t *ini) {
+  free(ini->data);
+  free(ini);
+}
+
+
+const char* ini_get(ini_t *ini, const char *section, const char *key) {
+  char *current_section = "";
+  char *val;
+  char *p = ini->data;
+
+  if (*p == '\0') {
+    p = next(ini, p);
+  }
+
+  while (p < ini->end) {
+    if (*p == '[') {
+      /* Handle section */
+      current_section = p + 1;
+
+    } else {
+      /* Handle key */
+      val = next(ini, p);
+      if (!section || !strcmpci(section, current_section)) {
+        if (!strcmpci(p, key)) {
+          return val;
+        }
+      }
+      p = val;
+    }
+
+    p = next(ini, p);
+  }
+
+  return NULL;
+}
+
+
+int ini_sget(
+  ini_t *ini, const char *section, const char *key,
+  const char *scanfmt, void *dst
+) {
+  const char *val = ini_get(ini, section, key);
+  if (!val) {
+    return 0;
+  }
+  if (scanfmt) {
+    sscanf(val, scanfmt, dst);
+  } else {
+    *((const char**) dst) = val;
+  }
+  return 1;
+}
--- /dev/null
+++ b/ini.h
@@ -1,0 +1,20 @@
+/**
+ * Copyright (c) 2016 rxi
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MIT license. See `ini.c` for details.
+ */
+
+#ifndef INI_H
+#define INI_H
+
+#define INI_VERSION "0.1.1"
+
+typedef struct ini_t ini_t;
+
+ini_t*      ini_load(const char *filename);
+void        ini_free(ini_t *ini);
+const char* ini_get(ini_t *ini, const char *section, const char *key);
+int         ini_sget(ini_t *ini, const char *section, const char *key, const char *scanfmt, void *dst);
+
+#endif
--- a/input.c
+++ b/input.c
@@ -4,6 +4,7 @@
 #include <SDL2/SDL.h>
 #include <stdio.h>
 
+#include "config.h"
 #include "input.h"
 #include "render.h"
 #include "write.h"
@@ -183,108 +184,62 @@
   return key;
 }
 
-static input_msg_s handle_normal_keys(SDL_Event *event, uint8_t keyvalue) {
+static input_msg_s handle_normal_keys(SDL_Event *event, config_params_s *conf, uint8_t keyvalue) {
   input_msg_s key = {normal, keyvalue};
-  switch (event->key.keysym.scancode) {
 
-  case SDL_SCANCODE_UP:
+  if (event->key.keysym.scancode == conf->key_up) {
     key.value = key_up;
-    break;
-
-  case SDL_SCANCODE_LEFT:
+  } else if (event->key.keysym.scancode == conf->key_left) {
     key.value = key_left;
-    break;
-
-  case SDL_SCANCODE_DOWN:
+  } else if (event->key.keysym.scancode == conf->key_down) {
     key.value = key_down;
-    break;
-
-  case SDL_SCANCODE_RIGHT:
+  } else if (event->key.keysym.scancode == conf->key_right) {
     key.value = key_right;
-    break;
-
-  case SDL_SCANCODE_LSHIFT:
-  case SDL_SCANCODE_A:
+  } else if (event->key.keysym.scancode == conf->key_select || event->key.keysym.scancode == conf->key_select_alt ) {
     key.value = key_select;
-    break;
-
-  case SDL_SCANCODE_SPACE:
-  case SDL_SCANCODE_S:
+  } else if (event->key.keysym.scancode == conf->key_start || event->key.keysym.scancode == conf->key_start_alt) {
     key.value = key_start;
-    break;
-
-  case SDL_SCANCODE_LALT:
-  case SDL_SCANCODE_Z:
+  } else if (event->key.keysym.scancode == conf->key_opt || event->key.keysym.scancode == conf->key_opt_alt) {
     key.value = key_opt;
-    break;
-
-  case SDL_SCANCODE_LCTRL:
-  case SDL_SCANCODE_X:
+  } else if (event->key.keysym.scancode == conf->key_edit || event->key.keysym.scancode == conf->key_edit_alt) {
     key.value = key_edit;
-    break;
-
-  case SDL_SCANCODE_DELETE:
+  } else if (event->key.keysym.scancode == conf->key_delete) {
     key.value = key_opt | key_edit;
-    break;
-
-  case SDL_SCANCODE_R:
+  } else if (event->key.keysym.scancode == conf->key_reset) {
     key = (input_msg_s){special, msg_reset_display};
-    break;
-
-  default:
+  } else {
     key.value = 0;
-    break;
   }
   return key;
 }
 
-static input_msg_s handle_game_controller_buttons(SDL_Event *event,
-                                                  uint8_t keyvalue) {
+static input_msg_s handle_game_controller_buttons(SDL_Event *event, config_params_s *conf, uint8_t keyvalue) {
   input_msg_s key = {normal, keyvalue};
-  switch (event->cbutton.button) {
 
-  case SDL_CONTROLLER_BUTTON_DPAD_UP:
+  if (event->cbutton.button == conf->gamepad_up) {
     key.value = key_up;
-    break;
-
-  case SDL_CONTROLLER_BUTTON_DPAD_DOWN:
-    key.value = key_down;
-    break;
-
-  case SDL_CONTROLLER_BUTTON_DPAD_LEFT:
+  } else if (event->cbutton.button == conf->gamepad_left) {
     key.value = key_left;
-    break;
-
-  case SDL_CONTROLLER_BUTTON_DPAD_RIGHT:
+  } else if (event->cbutton.button == conf->gamepad_down) {
+    key.value = key_down;
+  } else if (event->cbutton.button == conf->gamepad_right) {
     key.value = key_right;
-    break;
-
-  case SDL_CONTROLLER_BUTTON_BACK:
+  } else if (event->cbutton.button == conf->gamepad_select) {
     key.value = key_select;
-    break;
-
-  case SDL_CONTROLLER_BUTTON_START:
+  } else if (event->cbutton.button == conf->gamepad_start) {
     key.value = key_start;
-    break;
-
-  case SDL_CONTROLLER_BUTTON_B:
-    key.value = key_edit;
-    break;
-
-  case SDL_CONTROLLER_BUTTON_A:
+  } else if (event->cbutton.button == conf->gamepad_opt) {
     key.value = key_opt;
-    break;
-
-  default:
+  } else if (event->cbutton.button == conf->gamepad_edit) {
+    key.value = key_edit;
+  } else {
     key.value = 0;
-    break;
   }
-
   return key;
 }
 
 // Handles SDL input events
-void handle_sdl_events() {
+void handle_sdl_events(config_params_s *conf) {
 
   SDL_Event event;
 
@@ -326,7 +281,7 @@
 
   // Normal keyboard inputs
   case SDL_KEYUP:
-    key = handle_normal_keys(&event, 0);
+    key = handle_normal_keys(&event, conf, 0);
 
     if (keyjazz_enabled)
       key = handle_keyjazz(&event, key.value);
@@ -335,7 +290,7 @@
   // Game controller events
   case SDL_CONTROLLERBUTTONDOWN:
   case SDL_CONTROLLERBUTTONUP:
-    key = handle_game_controller_buttons(&event, 0);
+    key = handle_game_controller_buttons(&event, conf, 0);
     break;
 
   default:
@@ -357,12 +312,12 @@
 }
 
 // Returns the currently pressed keys to main
-input_msg_s get_input_msg() {
+input_msg_s get_input_msg(config_params_s *conf) {
 
   key = (input_msg_s){normal, 0};
 
   // Query for SDL events
-  handle_sdl_events();
+  handle_sdl_events(conf);
 
   if (keycode == (key_start|key_select|key_opt|key_edit)){
     key = (input_msg_s){special,msg_reset_display};
--- a/main.c
+++ b/main.c
@@ -4,9 +4,11 @@
 #include <SDL2/SDL.h>
 #include <libserialport.h>
 #include <signal.h>
+#include <string.h>
 #include <unistd.h>
 
 #include "command.h"
+#include "config.h"
 #include "input.h"
 #include "render.h"
 #include "serial.h"
@@ -23,7 +25,13 @@
 void intHandler(int dummy) { run = 0; }
 
 int main(int argc, char *argv[]) {
+  // Initialize the config to defaults read in the params from the
+  // configfile if present
+  config_params_s conf = init_config();
 
+  // TODO: take cli parameter to override default configfile location
+  read_config(&conf);
+
   // allocate memory for serial buffer
   uint8_t *serial_buf = malloc(serial_read_size);
 
@@ -53,7 +61,7 @@
   if (enable_and_reset_display(port) == -1)
     run = 0;
 
-  if (initialize_sdl() == -1)
+  if (initialize_sdl(conf.init_fullscreen) == -1)
     run = 0;
 
   uint8_t prev_input = 0;
@@ -62,7 +70,7 @@
   while (run) {
 
     // get current inputs
-    input_msg_s input = get_input_msg();
+    input_msg_s input = get_input_msg(&conf);
 
     switch (input.type) {
     case normal:
--- a/render.c
+++ b/render.c
@@ -25,7 +25,7 @@
 uint8_t fullscreen = 0;
 
 // Initializes SDL and creates a renderer and required surfaces
-int initialize_sdl() {
+int initialize_sdl(int init_fullscreen) {
 
   ticks = SDL_GetTicks();
 
@@ -40,7 +40,7 @@
   win = SDL_CreateWindow("m8c", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
                          window_width, window_height,
                          SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL |
-                             SDL_WINDOW_RESIZABLE);
+                             SDL_WINDOW_RESIZABLE | init_fullscreen);
 
   rend = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED);
 
--