ref: 6c6b32b7c6a8a4b8e99984dd1e7edbb3a21deae0
parent: 1f9ae6caf2d4947d65d67e2d4fa850304f810f2c
author: Bloop Click <103341015+bloopclick@users.noreply.github.com>
date: Sat May 21 15:44:42 EDT 2022
Improve idle performance and other enhancements - Add dirty flag to only render after draw commands - Modify oscilloscope draw command to suppress empty redraws - Add ability to make a debug build from the command line - Slightly optimize byte copies to SLIP parser
--- a/Makefile
+++ b/Makefile
@@ -10,7 +10,7 @@
#Set any compiler flags you want to use (e.g. -I/usr/include/somefolder `pkg-config --cflags gtk+-3.0` ), or leave blank
-CFLAGS = $(shell pkg-config --cflags sdl2 libserialport) -Wall -O2 -pipe -I.
+local_CFLAGS = $(CFLAGS) $(shell pkg-config --cflags sdl2 libserialport) -Wall -O2 -pipe -I.
#Set the compiler you are using ( gcc for C or g++ for C++ )
CC = gcc
@@ -20,12 +20,12 @@
#define a rule that applies to all files ending in the .o suffix, which says that the .o file depends upon the .c version of the file and all the .h files included in the DEPS macro. Compile each object file
%.o: %$(EXTENSION) $(DEPS)
- $(CC) -c -o $@ $< $(CFLAGS)
+ $(CC) -c -o $@ $< $(local_CFLAGS)
#Combine them into the output file
#Set your desired exe output file name here
m8c: $(OBJ)
- $(CC) -o $@ $^ $(CFLAGS) $(INCLUDES)
+ $(CC) -o $@ $^ $(local_CFLAGS) $(INCLUDES)
font.c: inline_font.h
@echo "#include <SDL.h>" > $@-tmp1
@@ -35,7 +35,7 @@
@rm $@-tmp2
@mv $@-tmp1 $@
@echo "[~cat] inline_font.h inprint2.c > font.c"
-# $(CC) -c -o font.o font.c $(CFLAGS)
+# $(CC) -c -o font.o font.c $(local_CFLAGS)
#Cleanup
.PHONY: clean
--- a/main.c
+++ b/main.c
@@ -1,6 +1,9 @@
// Copyright 2021 Jonne Kokkonen
// Released under the MIT licence, https://opensource.org/licenses/MIT
+// Uncomment this line to enable debug messages or call make with `make CFLAGS=-DDEBUG_MSG`
+// #define DEBUG_MSG
+
#include <SDL.h>
#include <libserialport.h>
#include <signal.h>
@@ -64,6 +67,10 @@
if (initialize_sdl(conf.init_fullscreen, conf.init_use_gpu) == -1)
run = 0;
+ #ifdef DEBUG_MSG
+ SDL_LogSetAllPriority(SDL_LOG_PRIORITY_DEBUG);
+ #endif
+
uint8_t prev_input = 0;
// main loop
@@ -106,8 +113,6 @@
}
}
-
- int total_received_bytes = 0;
while (1) {// read serial port
int bytes_read = sp_blocking_read(port, serial_buf, serial_read_size, 1);
@@ -117,11 +122,11 @@
run = 0;
break;
} else if (bytes_read > 0) {- total_received_bytes += bytes_read;
- for (int i = 0; i < bytes_read; i++) {- uint8_t rx = serial_buf[i];
+ uint8_t *cur = serial_buf;
+ const uint8_t *end = serial_buf+bytes_read;
+ while (cur<end) {// process the incoming bytes into commands and draw them
- int n = slip_read_byte(&slip, rx);
+ int n = slip_read_byte(&slip, *(cur++));
if (n != SLIP_NO_ERROR) { if (n == SLIP_ERROR_INVALID_PACKET) {reset_display(port);
@@ -134,9 +139,7 @@
break;
}
}
- if (total_received_bytes > 0) {- render_screen();
- }
+ render_screen();
}
// exit, clean up
--- a/render.c
+++ b/render.c
@@ -20,6 +20,8 @@
static int fps;
uint8_t fullscreen = 0;
+static uint8_t dirty = 0;
+
// Initializes SDL and creates a renderer and required surfaces
int initialize_sdl(int init_fullscreen, int init_use_gpu) {ticks = SDL_GetTicks();
@@ -55,8 +57,7 @@
SDL_LogSetAllPriority(SDL_LOG_PRIORITY_INFO);
- // Uncomment this for debug level logging
- // SDL_LogSetAllPriority(SDL_LOG_PRIORITY_DEBUG);
+ dirty = 1;
return 1;
}
@@ -73,6 +74,8 @@
SDL_SetWindowFullscreen(win, fullscreen_state ? 0 : SDL_WINDOW_FULLSCREEN);
SDL_ShowCursor(fullscreen_state);
+
+ dirty = 1;
}
int draw_character(struct draw_character_command *command) {@@ -91,6 +94,8 @@
fgcolor, bgcolor);
}
+ dirty = 1;
+
return 1;
}
@@ -115,31 +120,49 @@
SDL_SetRenderDrawColor(rend, command->color.r, command->color.g,
command->color.b, 0xFF);
SDL_RenderFillRect(rend, &render_rect);
+
+ dirty = 1;
}
void draw_waveform(struct draw_oscilloscope_waveform_command *command) {- const SDL_Rect wf_rect = {0, 0, 320, 21};+ static uint8_t wfm_cleared = 0;
- SDL_SetRenderDrawColor(rend, background_color.r, background_color.g,
- background_color.b, background_color.a);
- SDL_RenderFillRect(rend, &wf_rect);
+ // If the waveform is not being displayed and it's already been cleared, skip rendering it
+ if (! (wfm_cleared && command->waveform_size == 0)) {- SDL_SetRenderDrawColor(rend, command->color.r, command->color.g,
- command->color.b, 255);
+ const SDL_Rect wf_rect = {0, 0, 320, 21};- // Create a SDL_Point array of the waveform pixels for batch drawing
- SDL_Point waveform_points[command->waveform_size];
+ SDL_SetRenderDrawColor(rend, background_color.r, background_color.g,
+ background_color.b, background_color.a);
+ SDL_RenderFillRect(rend, &wf_rect);
- for (int i = 0; i < command->waveform_size; i++) {- // Limit value because the oscilloscope commands seem to glitch occasionally
- if (command->waveform[i] > 20)
- command->waveform[i] = 20;
- waveform_points[i].x = i;
- waveform_points[i].y = command->waveform[i];
- }
+ SDL_SetRenderDrawColor(rend, command->color.r, command->color.g,
+ command->color.b, 255);
- SDL_RenderDrawPoints(rend, waveform_points, command->waveform_size);
+ // Create a SDL_Point array of the waveform pixels for batch drawing
+ SDL_Point waveform_points[command->waveform_size];
+
+ for (int i = 0; i < command->waveform_size; i++) {+ // Limit value because the oscilloscope commands seem to glitch occasionally
+ if (command->waveform[i] > 20)
+ command->waveform[i] = 20;
+ waveform_points[i].x = i;
+ waveform_points[i].y = command->waveform[i];
+ }
+
+ SDL_RenderDrawPoints(rend, waveform_points, command->waveform_size);
+
+ // The packet we just drew was an empty waveform
+ if (command->waveform_size == 0) {+ wfm_cleared = 1;
+ }
+ else {+ wfm_cleared = 0;
+ }
+
+ dirty = 1;
+ }
}
void display_keyjazz_overlay(uint8_t show, uint8_t base_octave) {@@ -175,10 +198,13 @@
draw_rectangle(&drc);
}
+
+ dirty = 1;
}
void render_screen() {- if (SDL_GetTicks() - ticks > 14) {+ if (dirty && (SDL_GetTicks() - ticks > 14)) {+ dirty = 0;
ticks = SDL_GetTicks();
SDL_SetRenderTarget(rend, NULL);
SDL_SetRenderDrawColor(rend, 0, 0, 0, 0);
--
⑨