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)) {--
⑨