shithub: m8c

Download patch

ref: 46458850aca23f4a4cdd4587e7ed2086474bcffc
parent: 02832de008c7e904f7d1a9847fc2f0094ff149d3
author: Jonne Kokkonen <jonne.kokkonen@gmail.com>
date: Sat Mar 1 15:47:09 EST 2025

audio support

--- a/src/audio.c
+++ b/src/audio.c
@@ -5,100 +5,155 @@
 #include <SDL3/SDL.h>
 #include <stdint.h>
 
-static SDL_AudioDeviceID devid_in = 0;
-static SDL_AudioDeviceID devid_out = 0;
+SDL_AudioStream *audio_stream_in, *audio_stream_out;
 
 static unsigned int audio_paused = 0;
 static unsigned int audio_initialized = 0;
+static SDL_AudioSpec audio_spec_in = {SDL_AUDIO_S16LE, 2, 44100};
+static SDL_AudioSpec audio_spec_out = {SDL_AUDIO_S16LE, 2, 44100};
 
-void toggle_audio(const unsigned int audio_buffer_size, const char *output_device_name) {
-  /*if (!audio_initialized) {
-    audio_init(audio_buffer_size, output_device_name);
+static void SDLCALL audio_cb_out(void *userdata, SDL_AudioStream *stream, int length, int unused) {
+  // suppress compiler warnings
+  (void)userdata;
+  (void)length;
+  (void)unused;
+
+  const int bytes_available = SDL_GetAudioStreamAvailable(audio_stream_in);
+  if (bytes_available == -1) {
+    SDL_LogError(SDL_LOG_CATEGORY_AUDIO,
+                 "Error getting available audio stream bytes: %s, destroying audio",
+                 SDL_GetError());
+    audio_destroy();
     return;
   }
-  audio_paused = !audio_paused;
-  SDL_PauseAudioDevice(devid_in, audio_paused);
-  SDL_PauseAudioDevice(devid_out, audio_paused);
-  SDL_Log(audio_paused ? "Audio paused" : "Audio resumed");*/
+
+  Uint8 *src_audio_data = SDL_malloc(bytes_available);
+  const int bytes_read = SDL_GetAudioStreamData(audio_stream_in, src_audio_data, bytes_available);
+  if (bytes_read == bytes_available) {
+    SDL_PutAudioStreamData(stream, src_audio_data, bytes_read);
+  } else {
+    SDL_LogError(SDL_LOG_CATEGORY_AUDIO,
+                 "Error getting available audio stream bytes: %s, destroying audio",
+                 SDL_GetError());
+    audio_destroy();
+  }
+  SDL_free(src_audio_data);
 }
 
-void SDLCALL audio_cb_in(void *userdata, uint8_t *stream, int len) {
-  /*(void)userdata; // suppress compiler warning
-  SDL_QueueAudio(devid_out, stream, len);*/
+void toggle_audio(const char *output_device_name, unsigned int audio_buffer_size) {
+  if (!audio_initialized) {
+    audio_init(output_device_name, audio_buffer_size);
+    return;
+  }
+  if (audio_paused) {
+    SDL_ResumeAudioStreamDevice(audio_stream_out);
+    SDL_ResumeAudioStreamDevice(audio_stream_in);
+  } else {
+    SDL_PauseAudioStreamDevice(audio_stream_in);
+    SDL_PauseAudioStreamDevice(audio_stream_out);
+  }
+  audio_paused = !audio_paused;
+  SDL_Log(audio_paused ? "Audio paused" : "Audio resumed");
 }
 
-int audio_init(const unsigned int audio_buffer_size, const char *output_device_name) {
+int audio_init(const char *output_device_name, const unsigned int audio_buffer_size) {
 
-  /*
-  int m8_device_id = -1;
-
   // wait for system to initialize possible new audio devices
   SDL_Delay(500);
 
-  const int devcount_in = SDL_GetNumAudioDevices(SDL_TRUE);
+  int num_devices_in, num_devices_out;
+  SDL_AudioDeviceID m8_device_id = 0;
+  SDL_AudioDeviceID output_device_id = 0;
 
-  if (devcount_in < 1) {
-    SDL_Log("No audio capture devices, SDL Error: %s", SDL_GetError());
+  SDL_AudioDeviceID *devices_in = SDL_GetAudioRecordingDevices(&num_devices_in);
+  if (!devices_in) {
+    SDL_LogError(SDL_LOG_CATEGORY_AUDIO, "No audio capture devices, SDL Error: %s", SDL_GetError());
     return 0;
   }
-  for (int i = 0; i < devcount_in; i++) {
-    // Check if input device exists before doing anything else
-    SDL_LogDebug(SDL_LOG_CATEGORY_AUDIO, "%s", SDL_GetAudioDeviceName(i, SDL_TRUE));
-    if (SDL_strstr(SDL_GetAudioDeviceName(i, SDL_TRUE), "M8") != NULL) {
-      SDL_Log("M8 Audio Input device found: %s", SDL_GetAudioDeviceName(i, SDL_TRUE));
-      m8_device_id = i;
+
+  SDL_AudioDeviceID *devices_out = SDL_GetAudioPlaybackDevices(&num_devices_out);
+  if (!devices_out) {
+    SDL_LogError(SDL_LOG_CATEGORY_AUDIO, "No audio playback devices, SDL Error: %s",
+                 SDL_GetError());
+    return 0;
+  }
+
+  for (int i = 0; i < num_devices_in; i++) {
+    const SDL_AudioDeviceID instance_id = devices_in[i];
+    const char *device_name = SDL_GetAudioDeviceName(instance_id);
+    SDL_LogDebug(SDL_LOG_CATEGORY_AUDIO, "%s", device_name);
+    if (SDL_strstr(device_name, "M8") != NULL) {
+      SDL_Log("M8 Audio Input device found: %s", device_name);
+      m8_device_id = instance_id;
     }
   }
-  if (m8_device_id == -1) {
+
+  if (output_device_name != NULL) {
+    for (int i = 0; i < num_devices_out; i++) {
+      const SDL_AudioDeviceID instance_id = devices_out[i];
+      const char *device_name = SDL_GetAudioDeviceName(instance_id);
+      SDL_LogInfo(SDL_LOG_CATEGORY_AUDIO, "%s", device_name);
+      if (SDL_strcasestr(device_name, output_device_name) != NULL) {
+        SDL_Log("Requested output device found: %s", device_name);
+        output_device_id = instance_id;
+      }
+    }
+  }
+
+  SDL_free(devices_in);
+  SDL_free(devices_out);
+
+  if (!output_device_id) {
+    output_device_id = SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK;
+  }
+
+  if (!m8_device_id) {
     // forget about it
     SDL_Log("Cannot find M8 audio input device");
     return 0;
   }
 
-  SDL_AudioSpec want_in, have_in, want_out, have_out;
+  char audio_buffer_size_str[256];
+  SDL_snprintf(audio_buffer_size_str, sizeof(audio_buffer_size_str), "%d", audio_buffer_size);
+  SDL_SetHint(SDL_HINT_AUDIO_DEVICE_SAMPLE_FRAMES, audio_buffer_size_str);
 
-  // Open output device first to avoid possible Directsound errors
-  SDL_zero(want_out);
-  want_out.freq = 44100;
-  want_out.format = SDL_AUDIO_S16LE;
-  want_out.channels = 2;
-  devid_out =
-      SDL_OpenAudioDevice(output_device_name, 0, &want_out, &have_out, SDL_AUDIO_ALLOW_ANY_CHANGE);
-  if (devid_out == 0) {
-    SDL_Log("Failed to open output: %s", SDL_GetError());
+  audio_stream_out =
+      SDL_OpenAudioDeviceStream(output_device_id, &audio_spec_out, audio_cb_out, NULL);
+
+  if (!audio_stream_out) {
+    SDL_LogError(SDL_LOG_CATEGORY_AUDIO, "Error opening audio output device: %s", SDL_GetError());
     return 0;
   }
+  SDL_Log("Audiospec Out: format %d, channels %d, rate %d", audio_spec_out.format,
+          audio_spec_out.channels, audio_spec_out.freq);
 
-  SDL_zero(want_in);
-  want_in.freq = 44100;
-  want_in.format = SDL_AUDIO_S16LE;
-  want_in.channels = 2;
-  devid_in = SDL_OpenAudioDevice(SDL_GetAudioDeviceName(m8_device_id, SDL_TRUE), SDL_TRUE, &want_in,
-                                 &have_in, SDL_AUDIO_ALLOW_ANY_CHANGE);
-  if (devid_in == 0) {
-    SDL_Log("Failed to open M8 audio device, SDL Error: %s", SDL_GetError());
+  audio_stream_in = SDL_OpenAudioDeviceStream(m8_device_id, &audio_spec_in, NULL, NULL);
+  if (!audio_stream_in) {
+    SDL_LogError(SDL_LOG_CATEGORY_AUDIO, "Error opening audio input device: %s", SDL_GetError());
+    SDL_DestroyAudioStream(audio_stream_out);
     return 0;
   }
+  SDL_Log("Audiospec In: format %d, channels %d, rate %d", audio_spec_in.format,
+          audio_spec_in.channels, audio_spec_in.freq);
 
-  // Start audio processing
-  SDL_Log("Opening audio devices");
+  SDL_SetAudioStreamFormat(audio_stream_in, &audio_spec_in, &audio_spec_out);
 
+  SDL_ResumeAudioStreamDevice(audio_stream_out);
+  SDL_ResumeAudioStreamDevice(audio_stream_in);
+
   audio_paused = 0;
   audio_initialized = 1;
 
-  return 1;*/
+  return 1;
 }
 
 void audio_destroy() {
-  /*if (!audio_initialized)
+  if (!audio_initialized)
     return;
   SDL_Log("Closing audio devices");
-  SDL_PauseAudioDevice(devid_in);
-  SDL_PauseAudioDevice(devid_out);
-  SDL_CloseAudioDevice(devid_in);
-  SDL_CloseAudioDevice(devid_out);
-
-  audio_initialized = 0;*/
+  SDL_DestroyAudioStream(audio_stream_in);
+  SDL_DestroyAudioStream(audio_stream_out);
+  audio_initialized = 0;
 }
 
 #endif
--- a/src/audio.h
+++ b/src/audio.h
@@ -3,8 +3,9 @@
 #ifndef AUDIO_H
 #define AUDIO_H
 
-int audio_init(unsigned int audio_buffer_size, const char *output_device_name);
-void toggle_audio(unsigned int audio_buffer_size, const char *output_device_name);
+int audio_init(const char *output_device_name, unsigned int audio_buffer_size);
+void toggle_audio(const char *output_device_name, unsigned int audio_buffer_size);
+void process_audio();
 void audio_destroy();
 
 #endif
--- a/src/command.c
+++ b/src/command.c
@@ -27,7 +27,7 @@
 };
 
 static void dump_packet(const uint32_t size, const uint8_t *recv_buf) {
-  for (uint16_t a = 0; a < size; a++) {
+  for (uint32_t a = 0; a < size; a++) {
     SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "0x%02X ", recv_buf[a]);
   }
   SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "\n");
--- a/src/config.h
+++ b/src/config.h
@@ -14,7 +14,7 @@
   unsigned int wait_packets;
   unsigned int audio_enabled;
   unsigned int audio_buffer_size;
-  const char *audio_device_name;
+  char *audio_device_name;
 
   unsigned int key_up;
   unsigned int key_left;
--- a/src/fx_cube.c
+++ b/src/fx_cube.c
@@ -58,8 +58,8 @@
 
   SDL_Texture *og_target = SDL_GetRenderTarget(fx_renderer);
 
-  texture_size.x = SDL_GetNumberProperty(SDL_GetTextureProperties(og_target),SDL_PROP_TEXTURE_WIDTH_NUMBER, 0);
-  texture_size.y = SDL_GetNumberProperty(SDL_GetTextureProperties(og_target),SDL_PROP_TEXTURE_HEIGHT_NUMBER, 0);
+  texture_size.x = (int)SDL_GetNumberProperty(SDL_GetTextureProperties(og_target),SDL_PROP_TEXTURE_WIDTH_NUMBER, 0);
+  texture_size.y = (int)SDL_GetNumberProperty(SDL_GetTextureProperties(og_target),SDL_PROP_TEXTURE_HEIGHT_NUMBER, 0);
 
   texture_cube = SDL_CreateTexture(fx_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET,
                                    texture_size.x, texture_size.y);
@@ -104,9 +104,9 @@
   SDL_RenderClear(fx_renderer);
 
   const unsigned int seconds = SDL_GetTicks() / 1000;
-  const float scalefactor = 1 + SDL_sinf(seconds) * 0.005;
+  const float scale_factor = 1 + SDL_sinf((float)seconds) * (float)0.005;
 
-  scale(scalefactor, scalefactor, scalefactor);
+  scale(scale_factor, scale_factor, scale_factor);
   rotate_cube(M_PI / 180, M_PI / 270);
 
   for (int i = 0; i < 12; i++) {
--- a/src/ini.c
+++ b/src/ini.c
@@ -106,7 +106,6 @@
 /* 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(const ini_t *ini) {
-  char *value_start, *line_start;
   char *p = ini->data;
 
   while (p < ini->end) {
@@ -132,7 +131,7 @@
       break;
 
     default:
-      line_start = p;
+      char *line_start = p;
       p += strcspn(p, "=\n");
 
       /* Is line missing a '='? */
@@ -155,7 +154,7 @@
 
       if (*p == '"') {
         /* Handle quoted string value */
-        value_start = p;
+        char *value_start = p;
         p = unescape_quoted_value(ini, p);
 
         /* Was the string empty? */
--- a/src/inprint2.c
+++ b/src/inprint2.c
@@ -51,14 +51,15 @@
 void inrenderer(SDL_Renderer *renderer) { selected_renderer = renderer; }
 
 void infont(SDL_Texture *font) {
-  int w, h;
 
   if (font == NULL) {
     return;
   }
 
-  w = SDL_GetNumberProperty(SDL_GetTextureProperties(font),SDL_PROP_TEXTURE_WIDTH_NUMBER, 0);
-  h = SDL_GetNumberProperty(SDL_GetTextureProperties(font),SDL_PROP_TEXTURE_HEIGHT_NUMBER, 0);
+  const int w =
+      (int)SDL_GetNumberProperty(SDL_GetTextureProperties(font), SDL_PROP_TEXTURE_WIDTH_NUMBER, 0);
+  const int h =
+      (int)SDL_GetNumberProperty(SDL_GetTextureProperties(font), SDL_PROP_TEXTURE_HEIGHT_NUMBER, 0);
 
   selected_font = font;
   selected_font_w = w;
@@ -83,10 +84,10 @@
 
   static uint32_t previous_fgcolor;
 
-  d_rect.x = x;
-  d_rect.y = y;
-  s_rect.w = selected_font_w / CHARACTERS_PER_ROW;
-  s_rect.h = selected_font_h / CHARACTERS_PER_COLUMN;
+  d_rect.x = (float)x;
+  d_rect.y = (float)y;
+  s_rect.w = (float)selected_font_w / CHARACTERS_PER_ROW;
+  s_rect.h = (float)selected_font_h / CHARACTERS_PER_COLUMN;
   d_rect.w = s_rect.w;
   d_rect.h = s_rect.h;
 
@@ -94,7 +95,7 @@
     dst = selected_renderer;
 
   for (; *str; str++) {
-    int ascii_code = (int)*str;
+    const int ascii_code = (int)*str;
     int id = ascii_code - font_offset;
 
 #if (CHARACTERS_PER_COLUMN != 1)
@@ -103,11 +104,11 @@
     s_rect.x = col * s_rect.w;
     s_rect.y = row * s_rect.h;
 #else
-    s_rect.x = id * s_rect.w;
+    s_rect.x = (float)id * s_rect.w;
     s_rect.y = 0;
 #endif
     if (id + font_offset == '\n') {
-      d_rect.x = x;
+      d_rect.x = (float)x;
       d_rect.y += s_rect.h + 1;
       continue;
     }
@@ -121,8 +122,8 @@
                              (bgcolor & 0x0000FF00) >> 8, bgcolor & 0x000000FF,
                              0xFF);
       bg_rect = d_rect;
-      bg_rect.w = selected_inline_font->glyph_x;
-      bg_rect.h = selected_inline_font->glyph_y;
+      bg_rect.w = (float)selected_inline_font->glyph_x;
+      bg_rect.h = (float)selected_inline_font->glyph_y;
 
       SDL_RenderFillRect(dst, &bg_rect);
     }
@@ -130,7 +131,7 @@
     if (ascii_code != 32) {
       SDL_RenderTexture(dst, selected_font, &s_rect, &d_rect);
     }
-    d_rect.x += selected_inline_font->glyph_x + 1;
+    d_rect.x += (float)selected_inline_font->glyph_x + 1;
   }
 }
 SDL_Texture *get_inline_font(void) { return selected_font; }
--- a/src/input.c
+++ b/src/input.c
@@ -197,9 +197,9 @@
     prev_key_analog = key_analog;
   }
 
-  input_msg_s gcmsg = gamecontrollers_handle_special_messages(conf);
-  if (gcmsg.type == special) {
-    key = gcmsg;
+  const input_msg_s gamepad_msg = gamecontrollers_handle_special_messages(conf);
+  if (gamepad_msg.type == special) {
+    key = gamepad_msg;
   }
 
   while (SDL_PollEvent(&event)) {
@@ -305,8 +305,7 @@
        handle_sdl_events(), the value is stored in keycode variable */
     const input_msg_s input = (input_msg_s){key.type, keycode, 0, 0};
     return input;
-  } else {
-    // Special event keys already have the correct keycode baked in
-    return key;
   }
+  // Special event keys already have the correct keycode baked in
+  return key;
 }
--- a/src/main.c
+++ b/src/main.c
@@ -12,8 +12,8 @@
 #include "audio.h"
 #include "command.h"
 #include "config.h"
-#include "input.h"
 #include "gamecontrollers.h"
+#include "input.h"
 #include "render.h"
 #include "serial.h"
 #include "slip.h"
@@ -95,9 +95,9 @@
     SDL_Quit();
     return 1;
   }
-    run = QUIT;
+  run = QUIT;
 
-  // initial scan for (existing) game controllers
+  // initial scan for (existing) gamepads
   gamecontrollers_initialize();
 
 #ifdef DEBUG_MSG
@@ -112,7 +112,7 @@
     if (port_inited == 1 && enable_and_reset_display() == 1) {
       // if audio routing is enabled, try to initialize audio devices
       if (conf.audio_enabled == 1) {
-        audio_init(conf.audio_buffer_size, conf.audio_device_name);
+        audio_init(conf.audio_device_name, conf.audio_buffer_size);
         // if audio is enabled, reset the display for second time to avoid glitches
         reset_display();
       }
@@ -155,7 +155,7 @@
           if (run == WAIT_FOR_DEVICE && init_serial(0, preferred_device) == 1) {
 
             if (conf.audio_enabled == 1) {
-              if (audio_init(conf.audio_buffer_size, conf.audio_device_name) == 0) {
+              if (audio_init(conf.audio_device_name, conf.audio_buffer_size) == 0) {
                 SDL_Log("Cannot initialize audio");
                 conf.audio_enabled = 0;
               }
@@ -220,7 +220,7 @@
           prev_input = input.value;
           switch (input.value) {
           case msg_quit:
-            SDL_Log("Received msg_quit from input device.");
+            SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "Received msg_quit from input device.");
             run = 0;
             break;
           case msg_reset_display:
@@ -227,7 +227,8 @@
             reset_display();
             break;
           case msg_toggle_audio:
-            toggle_audio(conf.audio_buffer_size, conf.audio_device_name);
+            conf.audio_enabled = !conf.audio_enabled;
+            toggle_audio(conf.audio_device_name,conf.audio_buffer_size);
             break;
           default:
             break;
@@ -292,13 +293,14 @@
   // main loop end
 
   // exit, clean up
-  SDL_Log("Shutting down\n");
+  SDL_Log("Shutting down");
   if (conf.audio_enabled == 1) {
     audio_destroy();
   }
   gamecontrollers_close();
   close_renderer();
-  if (port_inited == 1) close_serial_port();
+  if (port_inited == 1)
+    close_serial_port();
   SDL_free(serial_buf);
   SDL_Quit();
   return 0;
--- a/src/render.c
+++ b/src/render.c
@@ -22,7 +22,7 @@
 SDL_Window *win;
 SDL_Renderer *rend;
 SDL_Texture *main_texture;
-SDL_Color background_color = (SDL_Color){.r = 0x00, .g = 0x00, .b = 0x00, .a = 0x00};
+SDL_Color global_background_color = (SDL_Color){.r = 0x00, .g = 0x00, .b = 0x00, .a = 0x00};
 SDL_RendererLogicalPresentation scaling_mode = SDL_LOGICAL_PRESENTATION_INTEGER_SCALE;
 
 static uint32_t ticks_fps;
@@ -46,7 +46,7 @@
 // Initializes SDL and creates a renderer and required surfaces
 int initialize_sdl(const unsigned int init_fullscreen) {
 
-  if (SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_EVENTS|SDL_INIT_GAMEPAD) == false) {
+  if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_EVENTS | SDL_INIT_GAMEPAD) == false) {
     SDL_LogCritical(SDL_LOG_CATEGORY_ERROR, "SDL_Init: %s\n", SDL_GetError());
     return false;
   }
@@ -54,24 +54,23 @@
   // SDL documentation recommends this
   atexit(SDL_Quit);
 
-  win = SDL_CreateWindow(
-      "m8c", texture_width * 2, texture_height * 2,
-      SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | init_fullscreen);
+  win = SDL_CreateWindow("m8c", texture_width * 2, texture_height * 2,
+                         SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | init_fullscreen);
 
-  rend =
-      SDL_CreateRenderer(win, NULL);
+  rend = SDL_CreateRenderer(win, NULL);
 
   SDL_SetRenderLogicalPresentation(rend, texture_width, texture_height, scaling_mode);
 
   main_texture = NULL;
-
   main_texture = SDL_CreateTexture(rend, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET,
-                                  texture_width, texture_height);
+                                   texture_width, texture_height);
 
+  SDL_SetTextureScaleMode(main_texture, SDL_SCALEMODE_NEAREST);
+
   SDL_SetRenderTarget(rend, main_texture);
 
-  SDL_SetRenderDrawColor(rend, background_color.r, background_color.g, background_color.b,
-                         background_color.a);
+  SDL_SetRenderDrawColor(rend, global_background_color.r, global_background_color.g,
+                         global_background_color.b, global_background_color.a);
 
   SDL_RenderClear(rend);
 
@@ -90,27 +89,28 @@
   prepare_inline_font(font);
 }
 
-static void check_and_adjust_window_and_texture_size(const int new_width,
-                                                     const int new_height) {
+static void check_and_adjust_window_and_texture_size(const int new_width, const int new_height) {
 
-  int h, w;
+  if (texture_width == new_width && texture_height == new_height) {
+    return;
+  }
 
+  int window_h, window_w;
+
   texture_width = new_width;
   texture_height = new_height;
 
   // Query window size and resize if smaller than default
-  SDL_GetWindowSize(win, &w, &h);
-  if (w < texture_width * 2 || h < texture_height * 2) {
+  SDL_GetWindowSize(win, &window_w, &window_h);
+  if (window_w < texture_width * 2 || window_h < texture_height * 2) {
     SDL_SetWindowSize(win, texture_width * 2, texture_height * 2);
   }
 
   SDL_DestroyTexture(main_texture);
-
   SDL_SetRenderLogicalPresentation(rend, texture_width, texture_height, scaling_mode);
-
   main_texture = SDL_CreateTexture(rend, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET,
-                                  texture_width, texture_height);
-
+                                   texture_width, texture_height);
+  SDL_SetTextureScaleMode(main_texture, SDL_SCALEMODE_NEAREST);
   SDL_SetRenderTarget(rend, main_texture);
 }
 
@@ -183,8 +183,7 @@
      both*/
 
   inprint(rend, (char *)&command->c, command->pos.x,
-          command->pos.y + text_offset_y + screen_offset_y, fgcolor,
-          bgcolor);
+          command->pos.y + text_offset_y + screen_offset_y, fgcolor, bgcolor);
 
   dirty = 1;
 
@@ -195,21 +194,21 @@
 
   SDL_FRect render_rect;
 
-  render_rect.x = command->pos.x;
-  render_rect.y = command->pos.y + screen_offset_y;
+  render_rect.x = (float)command->pos.x;
+  render_rect.y = (float)(command->pos.y + screen_offset_y);
   render_rect.h = command->size.height;
   render_rect.w = command->size.width;
 
   // Background color changed
-  if (render_rect.x == 0 && render_rect.y <= 0 && render_rect.w == texture_width &&
-      render_rect.h >= texture_height) {
+  if (render_rect.x == 0 && render_rect.y <= 0 && render_rect.w == (float)texture_width &&
+      render_rect.h >= (float)texture_height) {
     SDL_LogDebug(SDL_LOG_CATEGORY_SYSTEM, "BG color change: %d %d %d", command->color.r,
                  command->color.g, command->color.b);
-    background_color.r = command->color.r;
-    background_color.g = command->color.g;
-    background_color.b = command->color.b;
-    background_color.a = 0xFF;
-    SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "x:%i, y:%i, w:%i, h:%i", render_rect.x,
+    global_background_color.r = command->color.r;
+    global_background_color.g = command->color.g;
+    global_background_color.b = command->color.b;
+    global_background_color.a = 0xFF;
+    SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "x:%f, y:%f, w:%f, h:%f", render_rect.x,
                  render_rect.y, render_rect.w, render_rect.h);
 
 #ifdef __ANDROID__
@@ -229,26 +228,25 @@
   static uint8_t wfm_cleared = 0;
   static int prev_waveform_size = 0;
 
-  // If the waveform is not being displayed and it's already been cleared, skip
-  // rendering it
+  // If the waveform is not being displayed, and it's already been cleared, skip rendering it
   if (!(wfm_cleared && command->waveform_size == 0)) {
 
     SDL_FRect wf_rect;
     if (command->waveform_size > 0) {
-      wf_rect.x = texture_width - command->waveform_size;
+      wf_rect.x = (float)(texture_width - command->waveform_size);
       wf_rect.y = 0;
       wf_rect.w = command->waveform_size;
-      wf_rect.h = waveform_max_height + 1;
+      wf_rect.h = (float)(waveform_max_height + 1);
     } else {
-      wf_rect.x = texture_width - prev_waveform_size;
+      wf_rect.x = (float)(texture_width - prev_waveform_size);
       wf_rect.y = 0;
-      wf_rect.w = prev_waveform_size;
-      wf_rect.h = waveform_max_height + 1;
+      wf_rect.w = (float)prev_waveform_size;
+      wf_rect.h = (float)(waveform_max_height + 1);
     }
     prev_waveform_size = command->waveform_size;
 
-    SDL_SetRenderDrawColor(rend, background_color.r, background_color.g, background_color.b,
-                           background_color.a);
+    SDL_SetRenderDrawColor(rend, global_background_color.r, global_background_color.g,
+                           global_background_color.b, global_background_color.a);
     SDL_RenderFillRect(rend, &wf_rect);
 
     SDL_SetRenderDrawColor(rend, command->color.r, command->color.g, command->color.b, 255);
@@ -257,12 +255,11 @@
     SDL_FPoint waveform_points[command->waveform_size];
 
     for (int i = 0; i < command->waveform_size; i++) {
-      // Limit value because the oscilloscope commands seem to glitch
-      // occasionally
+      // Limit value to avoid random glitches
       if (command->waveform[i] > waveform_max_height) {
         command->waveform[i] = waveform_max_height;
       }
-      waveform_points[i].x = i + wf_rect.x;
+      waveform_points[i].x = (float)i + wf_rect.x;
       waveform_points[i].y = command->waveform[i];
     }
 
@@ -284,17 +281,17 @@
 
   const Uint16 overlay_offset_x = texture_width - (fonts[font_mode]->glyph_x * 7 + 1);
   const Uint16 overlay_offset_y = texture_height - (fonts[font_mode]->glyph_y + 1);
-  const Uint32 bgcolor =
-      background_color.r << 16 | background_color.g << 8 | background_color.b;
+  const Uint32 bg_color =
+      global_background_color.r << 16 | global_background_color.g << 8 | global_background_color.b;
 
   if (show) {
     char overlay_text[7];
     snprintf(overlay_text, sizeof(overlay_text), "%02X %u", velocity, base_octave);
-    inprint(rend, overlay_text, overlay_offset_x, overlay_offset_y, 0xC8C8C8, bgcolor);
+    inprint(rend, overlay_text, overlay_offset_x, overlay_offset_y, 0xC8C8C8, bg_color);
     inprint(rend, "*", overlay_offset_x + (fonts[font_mode]->glyph_x * 5 + 5), overlay_offset_y,
-            0xFF0000, bgcolor);
+            0xFF0000, bg_color);
   } else {
-    inprint(rend, "      ", overlay_offset_x, overlay_offset_y, 0xC8C8C8, bgcolor);
+    inprint(rend, "      ", overlay_offset_x, overlay_offset_y, 0xC8C8C8, bg_color);
   }
 
   dirty = 1;
@@ -305,8 +302,8 @@
     dirty = 0;
     SDL_SetRenderTarget(rend, NULL);
 
-    SDL_SetRenderDrawColor(rend, background_color.r, background_color.g, background_color.b,
-                           background_color.a);
+    SDL_SetRenderDrawColor(rend, global_background_color.r, global_background_color.g,
+                           global_background_color.b, global_background_color.a);
 
     SDL_RenderClear(rend);
     SDL_RenderTexture(rend, main_texture, NULL, NULL);
--- a/src/serial.c
+++ b/src/serial.c
@@ -196,7 +196,7 @@
   SDL_Log("Reset display\n");
 
   const char buf[1] = {'R'};
-  int result = sp_blocking_write(m8_port, buf, 1, 5);
+  const int result = sp_blocking_write(m8_port, buf, 1, 5);
   if (result != 1) {
     SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Error resetting M8 display, code %d", result);
     return 0;
@@ -244,7 +244,7 @@
 int send_msg_controller(const uint8_t input) {
   const char buf[2] = {'C', input};
   const size_t nbytes = 2;
-  int result = sp_blocking_write(m8_port, buf, nbytes, 5);
+  const int result = sp_blocking_write(m8_port, buf, nbytes, 5);
   if (result != nbytes) {
     SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Error sending input, code %d", result);
     return -1;
@@ -257,7 +257,7 @@
     velocity = 0x7F;
   const char buf[3] = {'K', note, velocity};
   const size_t nbytes = 3;
-  int result = sp_blocking_write(m8_port, buf, nbytes, 5);
+  const int result = sp_blocking_write(m8_port, buf, nbytes, 5);
   if (result != nbytes) {
     SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Error sending keyjazz, code %d", result);
     return -1;
--