ref: 6430599b7e26909012aa0c0aea52880394d43060
parent: d8cdc6cdff93dd09fe6c138b41877aef3edcb86c
author: Jonne Kokkonen <jonne.kokkonen@gmail.com>
date: Tue May 31 17:16:22 EDT 2022
add possibility to wait for device insertion and detect disconnetion
--- 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 ini.o config.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 fx_cube.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 ini.h config.h input.h
+DEPS = serial.h slip.h command.h write.h render.h ini.h config.h input.h fx_cube.h
#Any special libraries you are using in your project (e.g. -lbcm2835 -lrt `pkg-config --libs gtk+-3.0` ), or leave blank
INCLUDES = $(shell pkg-config --libs sdl2 libserialport)
--- a/config.c
+++ b/config.c
@@ -22,9 +22,11 @@
c.filename = "config.ini"; // default config file to load
- c.init_fullscreen = 0; // default fullscreen state at load
- c.init_use_gpu = 1; // default to use hardware acceleration
- c.idle_ms = 10; // default to high performance
+ c.init_fullscreen = 0; // default fullscreen state at load
+ c.init_use_gpu = 1; // default to use hardware acceleration
+ c.idle_ms = 10; // default to high performance
+ c.wait_for_device =
+ 1; // default to classic startup behaviour (exit if device disconnected)
c.key_up = SDL_SCANCODE_UP;
c.key_left = SDL_SCANCODE_LEFT;
@@ -72,7 +74,7 @@
SDL_Log("Writing config file to %s", config_path);- const unsigned int INI_LINE_COUNT = 36;
+ const unsigned int INI_LINE_COUNT = 37;
// Entries for the config file
char ini_values[INI_LINE_COUNT][50];
@@ -82,6 +84,8 @@
conf->init_fullscreen ? "true" : "false");
sprintf(ini_values[initPointer++], "use_gpu=%s\n",
conf->init_use_gpu ? "true" : "false");
+ sprintf(ini_values[initPointer++], "wait_for_device=%s\n",
+ conf->wait_for_device ? "true" : "false");
sprintf(ini_values[initPointer++], "idle_ms=%d\n", conf->idle_ms);
sprintf(ini_values[initPointer++], "[keyboard]\n");
sprintf(ini_values[initPointer++], "key_up=%d\n", conf->key_up);
@@ -89,7 +93,8 @@
sprintf(ini_values[initPointer++], "key_down=%d\n", conf->key_down);
sprintf(ini_values[initPointer++], "key_right=%d\n", conf->key_right);
sprintf(ini_values[initPointer++], "key_select=%d\n", conf->key_select);
- sprintf(ini_values[initPointer++], "key_select_alt=%d\n", conf->key_select_alt);
+ sprintf(ini_values[initPointer++], "key_select_alt=%d\n",
+ conf->key_select_alt);
sprintf(ini_values[initPointer++], "key_start=%d\n", conf->key_start);
sprintf(ini_values[initPointer++], "key_start_alt=%d\n", conf->key_start_alt);
sprintf(ini_values[initPointer++], "key_opt=%d\n", conf->key_opt);
@@ -103,7 +108,8 @@
sprintf(ini_values[initPointer++], "gamepad_left=%d\n", conf->gamepad_left);
sprintf(ini_values[initPointer++], "gamepad_down=%d\n", conf->gamepad_down);
sprintf(ini_values[initPointer++], "gamepad_right=%d\n", conf->gamepad_right);
- sprintf(ini_values[initPointer++], "gamepad_select=%d\n", conf->gamepad_select);
+ sprintf(ini_values[initPointer++], "gamepad_select=%d\n",
+ conf->gamepad_select);
sprintf(ini_values[initPointer++], "gamepad_start=%d\n", conf->gamepad_start);
sprintf(ini_values[initPointer++], "gamepad_opt=%d\n", conf->gamepad_opt);
sprintf(ini_values[initPointer++], "gamepad_edit=%d\n", conf->gamepad_edit);
@@ -165,7 +171,7 @@
// Frees the mem used for the config
ini_free(ini);
- //Write any new default options after loading
+ // Write any new default options after loading
write_config(conf);
}
@@ -173,6 +179,7 @@
const char *param_fs = ini_get(ini, "graphics", "fullscreen");
const char *param_gpu = ini_get(ini, "graphics", "use_gpu");
const char *idle_ms = ini_get(ini, "graphics", "idle_ms");
+ const char *param_wait = ini_get(ini, "graphics", "wait_for_device");
if (strcmpci(param_fs, "true") == 0) {conf->init_fullscreen = 1;
@@ -179,7 +186,7 @@
} else
conf->init_fullscreen = 0;
- if(param_gpu != NULL){+ if (param_gpu != NULL) { if (strcmpci(param_gpu, "true") == 0) {conf->init_use_gpu = 1;
} else
@@ -186,9 +193,16 @@
conf->init_use_gpu = 0;
}
- if (idle_ms)
+ 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;
+ }
+ }
}
void read_key_config(ini_t *ini, config_params_s *conf) {@@ -291,10 +305,17 @@
else
conf->gamepad_analog_invert = 0;
- if (gamepad_analog_axis_updown) conf->gamepad_analog_axis_updown = SDL_atoi(gamepad_analog_axis_updown);
- if (gamepad_analog_axis_leftright) conf->gamepad_analog_axis_leftright = SDL_atoi(gamepad_analog_axis_leftright);
- if (gamepad_analog_axis_select) conf->gamepad_analog_axis_select = SDL_atoi(gamepad_analog_axis_select);
- if (gamepad_analog_axis_start) conf->gamepad_analog_axis_start = SDL_atoi(gamepad_analog_axis_start);
- if (gamepad_analog_axis_opt) conf->gamepad_analog_axis_opt = SDL_atoi(gamepad_analog_axis_opt);
- if (gamepad_analog_axis_edit) conf->gamepad_analog_axis_edit = SDL_atoi(gamepad_analog_axis_edit);
+ if (gamepad_analog_axis_updown)
+ conf->gamepad_analog_axis_updown = SDL_atoi(gamepad_analog_axis_updown);
+ if (gamepad_analog_axis_leftright)
+ conf->gamepad_analog_axis_leftright =
+ SDL_atoi(gamepad_analog_axis_leftright);
+ if (gamepad_analog_axis_select)
+ conf->gamepad_analog_axis_select = SDL_atoi(gamepad_analog_axis_select);
+ if (gamepad_analog_axis_start)
+ conf->gamepad_analog_axis_start = SDL_atoi(gamepad_analog_axis_start);
+ if (gamepad_analog_axis_opt)
+ conf->gamepad_analog_axis_opt = SDL_atoi(gamepad_analog_axis_opt);
+ if (gamepad_analog_axis_edit)
+ conf->gamepad_analog_axis_edit = SDL_atoi(gamepad_analog_axis_edit);
}
--- a/config.h
+++ b/config.h
@@ -11,6 +11,7 @@
int init_fullscreen;
int init_use_gpu;
int idle_ms;
+ int wait_for_device;
int key_up;
int key_left;
--- a/config.ini.sample
+++ b/config.ini.sample
@@ -8,6 +8,10 @@
fullscreen=false
; set this to false to run m8c in software rendering mode (may be useful for Raspberry Pi)
use_gpu=true
+; the delay amount in ms in the main loop, decrease value for faster operation, increase value if too much cpu usage
+idle_ms = 10
+; show a spinning cube if device is not inserted
+wait_for_device = true
[keyboard]
; these need to be the decimal value of the SDL scancodes.
--- /dev/null
+++ b/fx_cube.c
@@ -1,0 +1,137 @@
+#include <SDL.h>
+#include "SDL2_inprint.h"
+
+#define target_width 320
+#define target_height 240
+static SDL_Texture *texture_cube;
+static SDL_Texture *texture_text;
+static SDL_Texture *texture_gradient;
+static SDL_Renderer *fx_renderer;
+static SDL_Color line_color;
+
+const char *text_m8c = "M8C";
+const char *text_disconnected = "DEVICE DISCONNECTED";
+
+static const float center_x = target_width / 2;
+static const float center_y = target_height / 2;
+
+static const float default_nodes[8][3] = {+ {-1, -1, -1}, {-1, -1, 1}, {-1, 1, -1}, {-1, 1, 1},+ {1, -1, -1}, {1, -1, 1}, {1, 1, -1}, {1, 1, 1}};+
+static int edges[12][2] = {{0, 1}, {1, 3}, {3, 2}, {2, 0}, {4, 5}, {5, 7},+ {7, 6}, {6, 4}, {0, 4}, {1, 5}, {2, 6}, {3, 7}};+
+static float nodes[8][3];
+
+static void scale(float factor0, float factor1, float factor2) {+ for (int i = 0; i < 8; i++) {+ nodes[i][0] *= factor0;
+ nodes[i][1] *= factor1;
+ nodes[i][2] *= factor2;
+ }
+}
+
+static void rotate_cube(float angle_x, float angle_y) {+ float sin_x = SDL_sin(angle_x);
+ float cos_x = SDL_cos(angle_x);
+ float sin_y = SDL_sin(angle_y);
+ float cos_y = SDL_cos(angle_y);
+ for (int i = 0; i < 8; i++) {+ float x = nodes[i][0];
+ float y = nodes[i][1];
+ float z = nodes[i][2];
+
+ nodes[i][0] = x * cos_x - z * sin_x;
+ nodes[i][2] = z * cos_x + x * sin_x;
+
+ z = nodes[i][2];
+
+ nodes[i][1] = y * cos_y - z * sin_y;
+ nodes[i][2] = z * cos_y + y * sin_y;
+ }
+}
+
+void fx_cube_init(SDL_Renderer *target_renderer, SDL_Color foreground_color) {+
+ fx_renderer = target_renderer;
+ line_color = foreground_color;
+
+ texture_cube =
+ SDL_CreateTexture(fx_renderer, SDL_PIXELFORMAT_ARGB8888,
+ SDL_TEXTUREACCESS_TARGET, target_width, target_height);
+ texture_text =
+ SDL_CreateTexture(fx_renderer, SDL_PIXELFORMAT_ARGB8888,
+ SDL_TEXTUREACCESS_TARGET, target_width, target_height);
+
+ SDL_Texture *og_target = SDL_GetRenderTarget(fx_renderer);
+
+ SDL_SetRenderTarget(fx_renderer, texture_text);
+
+ inprint(fx_renderer, text_disconnected, 168, 230, 0xFFFFFF, 0x000000);
+ inprint(fx_renderer, text_m8c, 2, 2, 0xFFFFFF, 0x000000);
+
+ /* Create a texture for making a linear gradient. Scaling settings make the 2
+ pixels into a gradient. This requires OpenGL or Direct3d though. */
+ SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1");
+ texture_gradient = SDL_CreateTexture(fx_renderer, SDL_PIXELFORMAT_ARGB8888,
+ SDL_TEXTUREACCESS_TARGET, 1, 2);
+ SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0");
+
+ SDL_SetRenderTarget(fx_renderer, texture_gradient);
+ SDL_RenderClear(fx_renderer);
+ SDL_SetRenderDrawColor(fx_renderer, 0, 0, 0, 200);
+ SDL_RenderDrawPoint(fx_renderer, 0, 1);
+ SDL_SetRenderDrawColor(fx_renderer, 0, 0, 0, SDL_ALPHA_TRANSPARENT);
+ SDL_RenderDrawPoint(fx_renderer, 0, 0);
+ SDL_SetRenderTarget(fx_renderer, og_target);
+
+ // Initialize default nodes
+ SDL_memcpy(nodes, default_nodes, sizeof(default_nodes));
+
+ scale(50, 50, 50);
+ rotate_cube(M_PI / 4, SDL_atan(SDL_sqrt(2)));
+
+ SDL_SetTextureBlendMode(texture_cube, SDL_BLENDMODE_BLEND);
+ SDL_SetTextureBlendMode(texture_gradient, SDL_BLENDMODE_BLEND);
+ SDL_SetTextureBlendMode(texture_text, SDL_BLENDMODE_BLEND);
+}
+
+void fx_cube_destroy() {+ SDL_DestroyTexture(texture_cube);
+ SDL_DestroyTexture(texture_gradient);
+ SDL_DestroyTexture(texture_text);
+}
+
+void fx_cube_update() {+ SDL_Point points[24];
+ int points_counter = 0;
+ SDL_Texture *og_texture = SDL_GetRenderTarget(fx_renderer);
+
+ SDL_SetRenderTarget(fx_renderer, texture_cube);
+ SDL_SetRenderDrawColor(fx_renderer, 0, 0, 0, 200);
+ SDL_RenderClear(fx_renderer);
+
+ int seconds = SDL_GetTicks() / 1000;
+ float scalefactor = 1 + (SDL_sin(seconds) * 0.01);
+
+ scale(scalefactor, scalefactor, scalefactor);
+ rotate_cube(M_PI / 180, M_PI / 270);
+
+ for (int i = 0; i < 12; i++) {+ float *p1 = nodes[edges[i][0]];
+ float *p2 = nodes[edges[i][1]];
+ points[points_counter++] =
+ (SDL_Point){p1[0] + center_x, nodes[edges[i][0]][1] + center_y};+ points[points_counter++] = (SDL_Point){p2[0] + center_x, p2[1] + center_y};+ }
+
+ SDL_RenderCopy(fx_renderer, texture_gradient, NULL, NULL);
+ SDL_RenderCopy(fx_renderer, texture_text, NULL, NULL);
+ SDL_SetRenderDrawColor(fx_renderer, line_color.r, line_color.g, line_color.b,
+ line_color.a);
+ SDL_RenderDrawLines(fx_renderer, points, 24);
+
+ SDL_SetRenderTarget(fx_renderer, og_texture);
+ SDL_RenderCopy(fx_renderer, texture_cube, NULL, NULL);
+}
--- /dev/null
+++ b/fx_cube.h
@@ -1,0 +1,8 @@
+#ifndef FX_CUBE_H_
+#define FX_CUBE_H_
+
+#include "SDL_render.h"
+void fx_cube_init(SDL_Renderer *target_renderer, SDL_Color foreground_color);
+void fx_cube_destroy();
+void fx_cube_update();
+#endif
\ No newline at end of file
--- a/input.c
+++ b/input.c
@@ -393,6 +393,7 @@
if (event.key.keysym.sym == SDLK_F4 &&
(event.key.keysym.mod & KMOD_ALT) > 0) { key = (input_msg_s){special, msg_quit};+ break;
}
// ESC = toggle keyjazz
--- a/main.c
+++ b/main.c
@@ -1,9 +1,6 @@
// 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>
@@ -10,6 +7,8 @@
#include <string.h>
#include <unistd.h>
+#include "SDL_log.h"
+#include "SDL_timer.h"
#include "command.h"
#include "config.h"
#include "input.h"
@@ -21,12 +20,20 @@
// maximum amount of bytes to read from the serial in one read()
#define serial_read_size 324
-uint8_t run = 1;
+enum state { QUIT, WAIT_FOR_DEVICE, RUN };+
+enum state run = WAIT_FOR_DEVICE;
uint8_t need_display_reset = 0;
// Handles CTRL+C / SIGINT
-void intHandler(int dummy) { run = 0; }+void intHandler(int dummy) { run = QUIT; }+void close_serial_port(struct sp_port *port) {+ disconnect(port);
+ sp_close(port);
+ sp_free_port(port);
+}
+
int main(int argc, char *argv[]) {// Initialize the config to defaults read in the params from the
// configfile if present
@@ -49,109 +56,174 @@
};
static slip_handler_s slip;
+ struct sp_port *port;
+ uint8_t prev_input = 0;
+ uint8_t prev_note = 0;
+ uint16_t zerobyte_packets = 0; // used to detect device disconnection
+
signal(SIGINT, intHandler);
signal(SIGTERM, intHandler);
slip_init(&slip, &slip_descriptor);
- struct sp_port *port;
+ // initialize all SDL systems
+ if (initialize_sdl(conf.init_fullscreen, conf.init_use_gpu) == -1)
+ run = QUIT;
- port = init_serial();
- if (port == NULL)
- return -1;
+/* Uncomment this line to enable debug messages or call make with `make
+ CFLAGS=-DDEBUG_MSG` #define DEBUG_MSG */
+#ifdef DEBUG_MSG
+ SDL_LogSetAllPriority(SDL_LOG_PRIORITY_DEBUG);
+#endif
- if (initialize_sdl(conf.init_fullscreen, conf.init_use_gpu) == -1)
- run = 0;
+ // main loop begin
+ do {+ port = init_serial(1);
+ if (port != NULL && enable_and_reset_display(port)) {+ run = RUN;
+ }
- if (enable_and_reset_display(port) == -1)
- run = 0;
+ // wait until device is connected
+ if (conf.wait_for_device) {+ static uint32_t ticks_poll_device = 0;
+ static uint32_t ticks_update_screen = 0;
- #ifdef DEBUG_MSG
- SDL_LogSetAllPriority(SDL_LOG_PRIORITY_DEBUG);
- #endif
+ if (port == NULL)
+ screensaver_init();
- uint8_t prev_input = 0;
- uint8_t prev_note = 0;
+ while (run == WAIT_FOR_DEVICE) {+ // get current inputs
+ input_msg_s input = get_input_msg(&conf);
+ if (input.type == special && input.value == msg_quit) {+ run = 0;
+ }
- // main loop
- while (run) {+ if (SDL_GetTicks() - ticks_update_screen > 16) {+ ticks_update_screen = SDL_GetTicks();
+ screensaver_draw();
+ render_screen();
+ }
- // get current inputs
- input_msg_s input = get_input_msg(&conf);
+ // Poll for M8 device every second
+ if (!port && SDL_GetTicks() - ticks_poll_device > 1000) {+ ticks_poll_device = SDL_GetTicks();
+ port = init_serial(0);
+ if (port != NULL) {+ // Device was found; enable display and proceed to the main loop
+ if (enable_and_reset_display(port)) {+ run = RUN;
+ screensaver_destroy();
+ } else {+ run = QUIT;
+ }
+ }
+ }
- switch (input.type) {- case normal:
- if (input.value != prev_input) {- prev_input = input.value;
- send_msg_controller(port, input.value);
+ SDL_Delay(conf.idle_ms);
}
- break;
- case keyjazz:
- if (input.value != 0) {- if (input.eventType == SDL_KEYDOWN && input.value != prev_input) {- send_msg_keyjazz(port, input.value, input.value2);
- prev_note = input.value;
- } else if (input.eventType == SDL_KEYUP && input.value == prev_note) {- send_msg_keyjazz(port, 0xFF, 0);
+
+ } else {+ // classic startup behaviour, exit if device is not found
+ if (port == NULL)
+ return -1;
+ }
+
+ // main loop
+ while (run == RUN) {+
+ // get current inputs
+ input_msg_s input = get_input_msg(&conf);
+
+ switch (input.type) {+ case normal:
+ if (input.value != prev_input) {+ prev_input = input.value;
+ send_msg_controller(port, input.value);
}
- }
- prev_input = input.value;
- break;
- case special:
- if (input.value != prev_input) {+ break;
+ case keyjazz:
+ if (input.value != 0) {+ if (input.eventType == SDL_KEYDOWN && input.value != prev_input) {+ send_msg_keyjazz(port, input.value, input.value2);
+ prev_note = input.value;
+ } else if (input.eventType == SDL_KEYUP && input.value == prev_note) {+ send_msg_keyjazz(port, 0xFF, 0);
+ }
+ }
prev_input = input.value;
- switch (input.value) {- case msg_quit:
- run = 0;
+ break;
+ case special:
+ if (input.value != prev_input) {+ prev_input = input.value;
+ switch (input.value) {+ case msg_quit:
+ run = 0;
+ break;
+ case msg_reset_display:
+ reset_display(port);
+ break;
+ default:
+ break;
+ }
break;
- case msg_reset_display:
- reset_display(port);
- break;
- default:
- break;
}
- break;
}
- }
- while (1) {- // read serial port
- int bytes_read = sp_nonblocking_read(port, serial_buf, serial_read_size);
- if (bytes_read < 0) {- SDL_LogCritical(SDL_LOG_CATEGORY_ERROR, "Error %d reading serial. \n",
- (int)bytes_read);
- run = 0;
- break;
- } else if (bytes_read > 0) {- 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, *(cur++));
- if (n != SLIP_NO_ERROR) {- if (n == SLIP_ERROR_INVALID_PACKET) {- reset_display(port);
+ while (1) {+ // read serial port
+ int bytes_read =
+ sp_nonblocking_read(port, serial_buf, serial_read_size);
+ if (bytes_read < 0) {+ SDL_LogCritical(SDL_LOG_CATEGORY_ERROR, "Error %d reading serial. \n",
+ (int)bytes_read);
+ run = QUIT;
+ break;
+ } else if (bytes_read > 0) {+ // input from device: reset the zero byte counter and create a
+ // pointer to the serial buffer
+ zerobyte_packets = 0;
+ 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, *(cur++));
+ if (n != SLIP_NO_ERROR) {+ if (n == SLIP_ERROR_INVALID_PACKET) {+ reset_display(port);
+ } else {+ SDL_LogError(SDL_LOG_CATEGORY_ERROR, "SLIP error %d\n", n);
+ }
+ }
+ }
+ } else {+ // zero byte packet, increment counter
+ zerobyte_packets++;
+ if (zerobyte_packets > 128) {+ // i guess it can be assumed that the device has been disconnected
+ if (conf.wait_for_device) {+ run = WAIT_FOR_DEVICE;
+ close_serial_port(port);
+ port = NULL;
+ break;
} else {- SDL_LogError(SDL_LOG_CATEGORY_ERROR, "SLIP error %d\n", n);
+ run = QUIT;
}
}
+ break;
}
- } else {- break;
}
+ render_screen();
+ SDL_Delay(conf.idle_ms);
}
- render_screen();
- SDL_Delay(conf.idle_ms);
- }
+ } while (run);
+ // main loop end
// exit, clean up
SDL_Log("Shutting down\n");close_game_controllers();
close_renderer();
- disconnect(port);
- sp_close(port);
- sp_free_port(port);
+ close_serial_port(port);
free(serial_buf);
SDL_Quit();
return 0;
--- a/render.c
+++ b/render.c
@@ -7,15 +7,17 @@
#include <stdio.h>
#include "SDL2_inprint.h"
+#include "SDL_log.h"
+#include "SDL_render.h"
#include "command.h"
+#include "fx_cube.h"
SDL_Window *win;
SDL_Renderer *rend;
SDL_Texture *maintexture;
SDL_Color background_color = (SDL_Color){0, 0, 0, 0};-static uint32_t ticks;
-
+static uint32_t ticks_screensaver;
static uint32_t ticks_fps;
static int fps;
uint8_t fullscreen = 0;
@@ -24,7 +26,7 @@
// Initializes SDL and creates a renderer and required surfaces
int initialize_sdl(int init_fullscreen, int init_use_gpu) {- ticks = SDL_GetTicks();
+ //ticks = SDL_GetTicks();
const int window_width = 640; // SDL window width
const int window_height = 480; // SDL window height
@@ -33,6 +35,8 @@
SDL_LogCritical(SDL_LOG_CATEGORY_ERROR, "SDL_Init: %s\n", SDL_GetError());
return -1;
}
+ // SDL documentation recommends this
+ atexit(SDL_Quit);
win = SDL_CreateWindow("m8c", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,window_width, window_height,
@@ -39,7 +43,8 @@
SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL |
SDL_WINDOW_RESIZABLE | init_fullscreen);
- rend = SDL_CreateRenderer(win, -1, init_use_gpu ? SDL_RENDERER_ACCELERATED : SDL_RENDERER_SOFTWARE);
+ rend = SDL_CreateRenderer(
+ win, -1, init_use_gpu ? SDL_RENDERER_ACCELERATED : SDL_RENDERER_SOFTWARE);
SDL_RenderSetLogicalSize(rend, 320, 240);
@@ -72,7 +77,8 @@
int fullscreen_state = SDL_GetWindowFlags(win) & SDL_WINDOW_FULLSCREEN;
- SDL_SetWindowFullscreen(win, fullscreen_state ? 0 : SDL_WINDOW_FULLSCREEN_DESKTOP);
+ SDL_SetWindowFullscreen(win,
+ fullscreen_state ? 0 : SDL_WINDOW_FULLSCREEN_DESKTOP);
SDL_ShowCursor(fullscreen_state);
dirty = 1;
@@ -128,23 +134,25 @@
static uint8_t wfm_cleared = 0;
- // If the waveform is not being displayed and it's already been cleared, skip rendering it
- if (! (wfm_cleared && command->waveform_size == 0)) {+ // If the waveform is not being displayed and it's already been cleared, skip
+ // rendering it
+ if (!(wfm_cleared && command->waveform_size == 0)) { const SDL_Rect wf_rect = {0, 0, 320, 21};SDL_SetRenderDrawColor(rend, background_color.r, background_color.g,
- background_color.b, background_color.a);
+ background_color.b, background_color.a);
SDL_RenderFillRect(rend, &wf_rect);
SDL_SetRenderDrawColor(rend, command->color.r, command->color.g,
- command->color.b, 255);
+ command->color.b, 255);
// 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
+ // Limit value because the oscilloscope commands seem to glitch
+ // occasionally
if (command->waveform[i] > 20)
command->waveform[i] = 20;
waveform_points[i].x = i;
@@ -156,8 +164,7 @@
// The packet we just drew was an empty waveform
if (command->waveform_size == 0) {wfm_cleared = 1;
- }
- else {+ } else {wfm_cleared = 0;
}
@@ -165,7 +172,8 @@
}
}
-void display_keyjazz_overlay(uint8_t show, uint8_t base_octave, uint8_t velocity) {+void display_keyjazz_overlay(uint8_t show, uint8_t base_octave,
+ uint8_t velocity) { if (show) {struct draw_rectangle_command drc;
@@ -189,7 +197,7 @@
char buf[8];
sprintf(buf, "%02X %u", velocity, base_octave);
- for (int i = 3; i >= 0; i--){+ for (int i = 3; i >= 0; i--) {dcc.c = buf[i];
draw_character(&dcc);
dcc.pos.x -= 8;
@@ -213,7 +221,7 @@
void render_screen() { if (dirty) {dirty = 0;
- ticks = SDL_GetTicks();
+ //ticks = SDL_GetTicks();
SDL_SetRenderTarget(rend, NULL);
SDL_SetRenderDrawColor(rend, 0, 0, 0, 0);
SDL_RenderClear(rend);
@@ -229,4 +237,19 @@
fps = 0;
}
}
+}
+
+void screensaver_init() {+ fx_cube_init(rend, (SDL_Color){255, 255, 255, 255});+ SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "Screensaver initialized");
+}
+
+void screensaver_draw() {+ fx_cube_update();
+ dirty = 1;
+}
+
+void screensaver_destroy() {+ fx_cube_destroy();
+ SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "Screensaver destroyed");
}
--- a/render.h
+++ b/render.h
@@ -18,4 +18,8 @@
void toggle_fullscreen();
void display_keyjazz_overlay(uint8_t show, uint8_t base_octave, uint8_t velocity);
+void screensaver_init();
+void screensaver_draw();
+void screensaver_destroy();
+
#endif
\ No newline at end of file
--- a/serial.c
+++ b/serial.c
@@ -30,13 +30,14 @@
return 0;
}
-struct sp_port *init_serial() {+struct sp_port *init_serial(int verbose) {/* A pointer to a null-terminated array of pointers to
* struct sp_port, which will contain the ports found.*/
struct sp_port *m8_port = NULL;
struct sp_port **port_list;
- SDL_Log("Looking for USB serial devices.\n");+ if (verbose)
+ SDL_Log("Looking for USB serial devices.\n");/* Call sp_list_ports() to get the ports. The port_list
* pointer will be updated to refer to the array created. */
@@ -61,29 +62,36 @@
sp_free_port_list(port_list);
if (m8_port != NULL) {- // Open the serial port and configure it
- SDL_Log("Opening port.\n");- enum sp_return result;
+ // Open the serial port and configure it
+ SDL_Log("Opening port.\n");+ enum sp_return result;
- result = sp_open(m8_port, SP_MODE_READ_WRITE);
- if (check(result) != SP_OK) return NULL;
-
- result = sp_set_baudrate(m8_port, 115200);
- if (check(result) != SP_OK) return NULL;
-
- result = sp_set_bits(m8_port, 8);
- if (check(result) != SP_OK) return NULL;
-
- result = sp_set_parity(m8_port, SP_PARITY_NONE);
- if (check(result) != SP_OK) return NULL;
-
- result = sp_set_stopbits(m8_port, 1);
- if (check(result) != SP_OK) return NULL;
-
- result = sp_set_flowcontrol(m8_port, SP_FLOWCONTROL_NONE);
- if (check(result) != SP_OK) return NULL;
+ result = sp_open(m8_port, SP_MODE_READ_WRITE);
+ if (check(result) != SP_OK)
+ return NULL;
+
+ result = sp_set_baudrate(m8_port, 115200);
+ if (check(result) != SP_OK)
+ return NULL;
+
+ result = sp_set_bits(m8_port, 8);
+ if (check(result) != SP_OK)
+ return NULL;
+
+ result = sp_set_parity(m8_port, SP_PARITY_NONE);
+ if (check(result) != SP_OK)
+ return NULL;
+
+ result = sp_set_stopbits(m8_port, 1);
+ if (check(result) != SP_OK)
+ return NULL;
+
+ result = sp_set_flowcontrol(m8_port, SP_FLOWCONTROL_NONE);
+ if (check(result) != SP_OK)
+ return NULL;
} else {- SDL_LogCritical(SDL_LOG_CATEGORY_SYSTEM, "Cannot find a M8.\n");
+ if (verbose)
+ SDL_LogCritical(SDL_LOG_CATEGORY_SYSTEM, "Cannot find a M8.\n");
}
return (m8_port);
@@ -100,7 +108,8 @@
break;
case SP_ERR_FAIL:
error_message = sp_last_error_message();
- SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Failed: %s\n", error_message);
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Failed: %s\n",
+ error_message);
sp_free_error_message(error_message);
break;
case SP_ERR_SUPP:
@@ -107,11 +116,12 @@
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Not supported.\n");
break;
case SP_ERR_MEM:
- SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Couldn't allocate memory.\n");
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "Error: Couldn't allocate memory.\n");
break;
case SP_OK:
default:
- break;
+ break;
}
return result;
}
--- a/serial.h
+++ b/serial.h
@@ -6,6 +6,6 @@
#include <libserialport.h>
-struct sp_port *init_serial();
+struct sp_port *init_serial(int verbose);
#endif
\ No newline at end of file
--- a/write.c
+++ b/write.c
@@ -7,6 +7,19 @@
#include <stdio.h>
#include <unistd.h>
+int send_msg_dummy(struct sp_port *port){+ SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "Sending dummy packet to M8");
+ uint8_t buf[1];
+ int result;
+ buf[0] = 0x00;
+ result = sp_blocking_write(port, buf, 2, 5);
+ if (result == 1){+ return 1;
+ } else {+ return 0;
+ }
+}
+
int reset_display(struct sp_port *port){ SDL_Log("Reset display\n");uint8_t buf[2];
--
⑨