shithub: m8c

Download patch

ref: 7033547e44427f539fa160035ddd00854dabf485
parent: 6a87d487efa3c15e9a43befdec265b8953e71481
parent: 294415147cb9435c37d449deee66da67bac104d1
author: Jonne Kokkonen <jonne.kokkonen@gmail.com>
date: Sat Sep 6 13:54:03 EDT 2025

Merge pull request #205 from laamaa/bugfix/startup-glitches-fixing

initialize renderer before connecting to device, remove obsolete idle_ms config parameter, remove wait_for_device config option

--- a/src/backends/m8_rtmidi.c
+++ b/src/backends/m8_rtmidi.c
@@ -231,8 +231,14 @@
 int m8_enable_display(const unsigned char reset_display) {
   SDL_LogDebug(SDL_LOG_CATEGORY_SYSTEM, "Sending enable command sysex");
   rtmidi_in_set_callback(midi_in, midi_callback, NULL);
+  const unsigned char disconnect_sysex[8] = {0xF0, 0x00, 0x02, 0x61, 0x00, 0x00, 'D', 0xF7};
+  int result =
+      rtmidi_out_send_message(midi_out, &disconnect_sysex[0], sizeof(disconnect_sysex));
+  if (result != 0) {
+    SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Failed to send disconnect");
+  }
   const unsigned char enable_sysex[8] = {0xF0, 0x00, 0x02, 0x61, 0x00, 0x00, 'E', 0xF7};
-  const int result = rtmidi_out_send_message(midi_out, &enable_sysex[0], sizeof(enable_sysex));
+  result = rtmidi_out_send_message(midi_out, &enable_sysex[0], sizeof(enable_sysex));
   if (result != 0) {
     SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Failed to send remote display enable command");
     return 0;
--- a/src/config.c
+++ b/src/config.c
@@ -30,8 +30,6 @@
 
   c.init_fullscreen = 0; // default fullscreen state at load
   c.integer_scaling = 0; // use integer scaling for the user interface
-  c.idle_ms = 10;        // default to high performance
-  c.wait_for_device = 1; // default to exit if device disconnected
   c.wait_packets = 256;  // amount of empty command queue reads before assuming device disconnected
   c.audio_enabled = 0;   // route M8 audio to default output
   c.audio_buffer_size = 0;    // requested audio buffer size in samples: 0 = let SDL decide
@@ -91,7 +89,7 @@
 
   SDL_Log("Writing config file to %s", config_path);
 
-#define INI_LINE_COUNT 51
+#define INI_LINE_COUNT 49
 #define INI_LINE_LENGTH 50
 
   // Entries for the config file
@@ -100,9 +98,6 @@
   snprintf(ini_values[initPointer++], INI_LINE_LENGTH, "[graphics]\n");
   snprintf(ini_values[initPointer++], INI_LINE_LENGTH, "fullscreen=%s\n",
            conf->init_fullscreen ? "true" : "false");
-  snprintf(ini_values[initPointer++], INI_LINE_LENGTH, "idle_ms=%d\n", conf->idle_ms);
-  snprintf(ini_values[initPointer++], INI_LINE_LENGTH, "wait_for_device=%s\n",
-           conf->wait_for_device ? "true" : "false");
   snprintf(ini_values[initPointer++], INI_LINE_LENGTH, "wait_packets=%d\n", conf->wait_packets);
   snprintf(ini_values[initPointer++], INI_LINE_LENGTH, "integer_scaling=%s\n",
            conf->integer_scaling ? "true" : "false");
@@ -237,8 +232,6 @@
 
 void read_graphics_config(const ini_t *ini, config_params_s *conf) {
   const char *param_fs = ini_get(ini, "graphics", "fullscreen");
-  const char *idle_ms = ini_get(ini, "graphics", "idle_ms");
-  const char *param_wait = ini_get(ini, "graphics", "wait_for_device");
   const char *wait_packets = ini_get(ini, "graphics", "wait_packets");
   const char *integer_scaling = ini_get(ini, "graphics", "integer_scaling");
 
@@ -248,16 +241,6 @@
     conf->init_fullscreen = 0;
   }
 
-  if (idle_ms != NULL)
-    conf->idle_ms = SDL_atoi(idle_ms);
-
-  if (param_wait != NULL) {
-    if (strcmpci(param_wait, "true") == 0) {
-      conf->wait_for_device = 1;
-    } else {
-      conf->wait_for_device = 0;
-    }
-  }
   if (wait_packets != NULL)
     conf->wait_packets = SDL_atoi(wait_packets);
 
--- a/src/config.h
+++ b/src/config.h
@@ -10,8 +10,6 @@
   char *filename;
   unsigned int init_fullscreen;
   unsigned int integer_scaling;
-  unsigned int idle_ms;
-  unsigned int wait_for_device;
   unsigned int wait_packets;
   unsigned int audio_enabled;
   unsigned int audio_buffer_size;
--- a/src/main.c
+++ b/src/main.c
@@ -5,6 +5,8 @@
    CFLAGS=-DDEBUG_MSG` */
 // #define DEBUG_MSG
 
+#define APP_VERSION "v2.1.1"
+
 #include <SDL3/SDL.h>
 #define SDL_MAIN_USE_CALLBACKS
 #include <SDL3/SDL_main.h>
@@ -113,16 +115,6 @@
  * @return An unsigned char indicating the connection state of the device.
  *         Returns 1 if the device is connected successfully, or 0 if not connected.
  */
-static unsigned char handle_m8_connection_init(const unsigned char wait_for_device,
-                                               const char *preferred_device) {
-  const unsigned char device_connected = m8_initialize(1, preferred_device);
-  if (!wait_for_device && device_connected == 0) {
-    SDL_LogCritical(SDL_LOG_CATEGORY_ERROR, "Device not detected!");
-    exit(EXIT_FAILURE);
-  }
-  return device_connected;
-}
-
 // Main callback loop - read inputs, process data from the device, render screen
 SDL_AppResult SDL_AppIterate(void *appstate) {
   if (appstate == NULL) {
@@ -137,9 +129,7 @@
     break;
 
   case WAIT_FOR_DEVICE:
-    if (ctx->conf.wait_for_device) {
-      do_wait_for_device(ctx);
-    }
+    do_wait_for_device(ctx);
     break;
 
   case RUN: {
@@ -165,11 +155,22 @@
 
 // Initialize the app: initialize context, configs, renderer controllers and attempt to find M8
 SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
+  SDL_SetAppMetadata("M8C",APP_VERSION,"fi.laamaa.m8c");
+
   char *config_filename = NULL;
 
   // Initialize in-app log capture/overlay
   renderer_log_init();
 
+#ifndef NDEBUG
+  // Show debug messages in the application log
+  SDL_SetLogPriorities(SDL_LOG_PRIORITY_DEBUG);
+  SDL_LogDebug(SDL_LOG_CATEGORY_TEST, "Running a Debug build");
+#else
+  // Show debug messages in the application log
+  SDL_SetLogPriorities(SDL_LOG_PRIORITY_INFO);
+#endif
+
   // Process the application's main callback roughly at 120 Hz
   SDL_SetHint(SDL_HINT_MAIN_CALLBACK_RATE, "120");
 
@@ -182,8 +183,6 @@
   *appstate = ctx;
   ctx->app_state = INITIALIZE;
   ctx->conf = initialize_config(argc, argv, &ctx->preferred_device, &config_filename);
-  ctx->device_connected =
-      handle_m8_connection_init(ctx->conf.wait_for_device, ctx->preferred_device);
 
   if (!renderer_initialize(&ctx->conf)) {
     SDL_LogCritical(SDL_LOG_CATEGORY_ERROR, "Failed to initialize renderer.");
@@ -190,14 +189,8 @@
     return SDL_APP_FAILURE;
   }
 
-#ifndef NDEBUG
-  // Show debug messages in the application log
-  SDL_SetLogPriorities(SDL_LOG_PRIORITY_DEBUG);
-  SDL_LogDebug(SDL_LOG_CATEGORY_TEST, "Running a Debug build");
-#else
-  // Show debug messages in the application log
-  SDL_SetLogPriorities(SDL_LOG_PRIORITY_INFO);
-#endif
+  ctx->device_connected =
+      m8_initialize(1, ctx->preferred_device);
 
   if (gamepads_initialize() < 0) {
     SDL_LogCritical(SDL_LOG_CATEGORY_ERROR, "Failed to initialize game controllers.");
@@ -210,11 +203,10 @@
     }
     ctx->app_state = RUN;
     render_screen(&ctx->conf);
-    m8_reset_display(); // Second reset to avoid display glitches.
   } else {
     SDL_LogCritical(SDL_LOG_CATEGORY_ERROR, "Device not detected.");
     ctx->device_connected = 0;
-    ctx->app_state = ctx->conf.wait_for_device ? WAIT_FOR_DEVICE : QUIT;
+    ctx->app_state = WAIT_FOR_DEVICE;
   }
 
   return SDL_APP_CONTINUE;
--- a/src/render.c
+++ b/src/render.c
@@ -111,7 +111,7 @@
   const int new_hd_texture_height = texture_height * scale_factor;
   if (hd_texture != NULL && new_hd_texture_width == hd_texture_width &&
       new_hd_texture_height == hd_texture_height) {
-    // Texture exists and there is no change in the size, carry on
+    // Texture exists, and there is no change in the size, carry on
     SDL_LogDebug(SDL_LOG_CATEGORY_RENDER, "HD texture size not changed, skipping");
     return;
   }
@@ -151,7 +151,7 @@
 
 // Append a formatted line to the circular log buffer
 static void log_buffer_append_line(const char *line) {
-  if (line == NULL || line[0] == '\0') {
+  if (line[0] == '\0') {
     return;
   }
   const int index = (log_line_start + log_line_count) % LOG_BUFFER_MAX_LINES;
@@ -196,7 +196,7 @@
   log_overlay_needs_redraw = 1;
 }
 
-// Render the log buffer into a texture for overlay display
+// Render the log buffer into a texture for the overlay display
 static void render_log_overlay_texture(void) {
   if (!log_overlay_visible) {
     return;
@@ -225,7 +225,7 @@
   SDL_SetRenderDrawColor(rend, 0, 0, 0, 220);
   SDL_RenderClear(rend);
 
-  // Use small font to fit more lines
+  // Use a small font to fit more lines
   const int prev_font_mode = font_mode;
   inline_font_close();
   inline_font_initialize(fonts[0]);
@@ -236,9 +236,6 @@
   const int usable_width = texture_width - (margin_x * 2);
   const int cols = SDL_max(1, usable_width / (fonts[0]->glyph_x + 1));
 
-  const Uint32 fg = 0xFFFFFF; // light grey
-  const Uint32 bg = 0xFFFFFF; // inprint translates same bg as fg to transparent
-
   // Compute how many text rows fit
   const int max_rows = (texture_height - margin_y * 2) / line_height;
   int rows_needed = max_rows;
@@ -279,7 +276,9 @@
       const char *s = log_lines[cur];
       const size_t len = SDL_strlen(s);
       for (size_t pos = offset; pos < len && y < texture_height;) {
-        size_t remaining = len - pos;
+        const Uint32 bg = 0xFFFFFF;
+        const Uint32 fg = 0xFFFFFF;
+        const size_t remaining = len - pos;
         size_t take = (size_t)cols < remaining ? (size_t)cols : remaining;
         char buf[LOG_LINE_MAX_CHARS];
         if (take >= sizeof(buf)) {
@@ -558,7 +557,7 @@
     return 0;
   }
 
-  if (!SDL_CreateWindowAndRenderer("m8c", texture_width * 2, texture_height * 2,
+  if (!SDL_CreateWindowAndRenderer("M8C", texture_width * 2, texture_height * 2,
                                    SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY |
                                        SDL_WINDOW_OPENGL | conf->init_fullscreen,
                                    &win, &rend)) {
--