forked from laamaa/m8c
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.c
161 lines (134 loc) · 3.94 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
// Copyright 2021 Jonne Kokkonen
// Released under the MIT licence, https://opensource.org/licenses/MIT
#include <SDL2/SDL.h>
#include <libserialport.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include "command.h"
#include "ini.h"
#include "input.h"
#include "render.h"
#include "serial.h"
#include "slip.h"
#include "write.h"
// maximum amount of bytes to read from the serial in one read()
#define serial_read_size 1024
uint8_t run = 1;
uint8_t need_display_reset = 0;
// Handles CTRL+C / SIGINT
void intHandler(int dummy) { run = 0; }
// Config variables
int init_fullscreen = 0;
// Read config
void read_config() {
// Load the config and read the fullscreen setting from the graphics section
ini_t *config = ini_load("config.ini");
const char *setting_fullscren = ini_get(config, "graphics", "fullscreen");
// Other settings could be read here, too.
// This obviously requires the parameter to be a lowercase true to enable fullscreen
if ( strcmp(setting_fullscren, "true") == 0 ) {
init_fullscreen = 1;
}
// Frees the mem used for the config
ini_free(config);
}
int main(int argc, char *argv[]) {
read_config();
// allocate memory for serial buffer
uint8_t *serial_buf = malloc(serial_read_size);
static uint8_t slip_buffer[serial_read_size]; // SLIP command buffer
// settings for the slip packet handler
static const slip_descriptor_s slip_descriptor = {
.buf = slip_buffer,
.buf_size = sizeof(slip_buffer),
.recv_message = process_command, // the function where complete slip
// packets are processed further
};
static slip_handler_s slip;
signal(SIGINT, intHandler);
signal(SIGTERM, intHandler);
slip_init(&slip, &slip_descriptor);
struct sp_port *port;
port = init_serial();
if (port == NULL)
return -1;
if (enable_and_reset_display(port) == -1)
run = 0;
if (initialize_sdl(init_fullscreen) == -1)
run = 0;
uint8_t prev_input = 0;
// main loop
while (run) {
// get current inputs
input_msg_s input = get_input_msg();
switch (input.type) {
case normal:
if (input.value != prev_input) {
prev_input = input.value;
send_msg_controller(port, input.value);
}
break;
case keyjazz:
if (input.value != prev_input) {
prev_input = input.value;
if (input.value != 0) {
send_msg_keyjazz(port, input.value, 0xFF);
} else {
send_msg_keyjazz(port, 0, 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;
}
}
// read serial port
size_t 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;
}
if (bytes_read > 0) {
for (int i = 0; i < bytes_read; i++) {
uint8_t rx = serial_buf[i];
// process the incoming bytes into commands and draw them
int n = slip_read_byte(&slip, rx);
if (n != SLIP_NO_ERROR) {
if (n == SLIP_ERROR_INVALID_PACKET) {
// Reset display on invalid packets. On current firmwares this can cause a softlock in effect list so this is commented out for now.
//reset_display(port);
} else {
SDL_LogError(SDL_LOG_CATEGORY_ERROR, "SLIP error %d\n", n);
}
}
}
usleep(10);
} else {
render_screen();
usleep(100);
}
}
// exit, clean up
SDL_Log("Shutting down\n");
close_game_controllers();
close_renderer();
disconnect(port);
sp_close(port);
sp_free_port(port);
free(serial_buf);
return 0;
}