676 lines
23 KiB
C
676 lines
23 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <ncurses.h>
|
|
#include <signal.h>
|
|
#include <time.h>
|
|
#include <MQTTClient.h>
|
|
|
|
#include "gameloop.h"
|
|
#include "../helper/parameters.h"
|
|
#include "../helper/confighelper.h"
|
|
#include "../simulatorapi/simapi/simapi/simdata.h"
|
|
#include "../simulatorapi/simapi/simapi/simmapper.h"
|
|
#include "../slog/slog.h"
|
|
|
|
#include <json-c/json.h>
|
|
|
|
#define DEFAULT_UPDATE_RATE 100
|
|
|
|
#define ADDRESS "tcp://mqtt.brak:1883"
|
|
#define CLIENTID "gilles"
|
|
#define TOPIC "telemetry"
|
|
//#define PAYLOAD "Hello, MQTT!"
|
|
#define QOS 0
|
|
#define TIMEOUT 10000L
|
|
|
|
char datestring[30];
|
|
|
|
WINDOW* win1;
|
|
WINDOW* win2;
|
|
WINDOW* win3;
|
|
WINDOW* win4;
|
|
|
|
int winx, winy;
|
|
|
|
int win23y, win23x;
|
|
|
|
|
|
|
|
void handle_winch(int sig)
|
|
{
|
|
endwin();
|
|
|
|
refresh();
|
|
clear();
|
|
getmaxyx(stdscr, winx, winy);
|
|
win23y = winy/3;
|
|
win23x = winx/3;
|
|
win1 = newwin(winx,winy,0,0);
|
|
win2 = newwin(win23x,win23y,1,win23y-1);
|
|
win3 = newwin(win23x,win23y,1,win23y*2-1);
|
|
win4 = newwin(winx-win23x-2,winy-win23y,win23x+1,win23y-1);
|
|
refresh();
|
|
}
|
|
|
|
void rectangle(int y1, int x1, int y2, int x2)
|
|
{
|
|
mvhline(y1, x1, 0, x2-x1);
|
|
mvhline(y2, x1, 0, x2-x1);
|
|
mvvline(y1, x1, 0, y2-y1);
|
|
mvvline(y1, x2, 0, y2-y1);
|
|
mvaddch(y1, x1, ACS_ULCORNER);
|
|
mvaddch(y2, x1, ACS_LLCORNER);
|
|
mvaddch(y1, x2, ACS_URCORNER);
|
|
mvaddch(y2, x2, ACS_LRCORNER);
|
|
}
|
|
|
|
int curses_init()
|
|
{
|
|
initscr();
|
|
start_color();
|
|
|
|
init_pair(1,COLOR_GREEN,0);
|
|
init_pair(2,COLOR_YELLOW,0);
|
|
init_pair(3,COLOR_MAGENTA,0);
|
|
init_pair(4,COLOR_WHITE,0);
|
|
|
|
getmaxyx(stdscr, winx, winy);
|
|
win1 = newwin(winx,winy,0,0);
|
|
win23y = winy/3;
|
|
win23x = winx/3;
|
|
win2 = newwin(win23x,win23y,1,win23y-1);
|
|
win3 = newwin(win23x,win23y,1,win23y*2-1);
|
|
win4 = newwin(winx-win23x-2,winy-win23y,win23x+1,win23y-1);
|
|
|
|
wbkgd(win1,COLOR_PAIR(1));
|
|
wbkgd(win2,COLOR_PAIR(1));
|
|
wbkgd(win3,COLOR_PAIR(1));
|
|
wbkgd(win4,COLOR_PAIR(1));
|
|
|
|
signal(SIGWINCH, handle_winch);
|
|
cbreak();
|
|
noecho();
|
|
|
|
box(win1, 0, 0);
|
|
box(win2, 0, 0);
|
|
box(win3, 0, 0);
|
|
box(win4, 0, 0);
|
|
}
|
|
|
|
char * removeSpacesFromStr(char *string)
|
|
{
|
|
int non_space_count = 0;
|
|
|
|
for (int i = 0; string[i] != '\0'; i++)
|
|
{
|
|
if (string[i] != ' ')
|
|
{
|
|
string[non_space_count] = string[i];
|
|
non_space_count++;
|
|
}
|
|
}
|
|
|
|
string[non_space_count] = '\0';
|
|
return string;
|
|
}
|
|
|
|
void update_date()
|
|
{
|
|
time_t rawtime;
|
|
struct tm * timeinfo;
|
|
time ( &rawtime );
|
|
timeinfo = localtime ( &rawtime );
|
|
sprintf(datestring, "%.24s", asctime (timeinfo));
|
|
}
|
|
|
|
int looper(Simulator simulator, Parameters* p)
|
|
{
|
|
|
|
SimData* simdata = malloc(sizeof(SimData));
|
|
SimMap* simmap = malloc(sizeof(SimMap));
|
|
|
|
int error = siminit(simdata, simmap, simulator);
|
|
if (error != GILLES_ERROR_NONE)
|
|
{
|
|
slogf("Fatal error getting simulator data");
|
|
return error;
|
|
}
|
|
|
|
curses_init();
|
|
|
|
timeout(DEFAULT_UPDATE_RATE);
|
|
|
|
bool mqtt = p->mqtt;
|
|
bool mqtt_connected = false;
|
|
|
|
MQTTClient client;
|
|
MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
|
|
MQTTClient_message pubmsg = MQTTClient_message_initializer;
|
|
MQTTClient_deliveryToken token;
|
|
int rc;
|
|
|
|
// Create a new MQTT client
|
|
MQTTClient_create(&client, ADDRESS, CLIENTID,
|
|
MQTTCLIENT_PERSISTENCE_NONE, NULL);
|
|
|
|
// Connect to the MQTT server
|
|
if (mqtt == true)
|
|
{
|
|
conn_opts.keepAliveInterval = 20;
|
|
conn_opts.cleansession = 1;
|
|
if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) {
|
|
MQTTClient_disconnect(client, 10000);
|
|
sloge("Failed to connect, return code %d", rc);
|
|
//exit(-1);
|
|
}
|
|
mqtt_connected = true;
|
|
}
|
|
|
|
int go = true;
|
|
char lastsimstatus = false;
|
|
while (go == true)
|
|
{
|
|
simdatamap(simdata, simmap, simulator);
|
|
|
|
char* newdatestring;
|
|
char simstatus = (simdata->simstatus > 0) ? true : false;
|
|
if (simdata->simstatus > 0 && simstatus != lastsimstatus)
|
|
{
|
|
update_date();
|
|
newdatestring = removeSpacesFromStr(datestring);
|
|
}
|
|
lastsimstatus = simstatus;
|
|
|
|
if (mqtt_connected == true && simdata->simstatus > 0)
|
|
{
|
|
char payloads[16][10];
|
|
|
|
//sprintf(payloads[0], "telemetry,lap=%i,session=%s gas=%04f", simdata->lap, newdatestring, simdata->gas);
|
|
//sprintf(payloads[1], "telemetry,lap=%i,session=%s brake=%04f", simdata->lap, newdatestring, simdata->brake);
|
|
//sprintf(payloads[2], "telemetry,lap=%i,session=%s steer=%04f", simdata->lap, newdatestring, simdata->brake);
|
|
//sprintf(payloads[3], "telemetry,lap=%i,session=%s gear=%04i", simdata->lap, newdatestring, simdata->gear);
|
|
//sprintf(payloads[4], "telemetry,lap=%i,session=%s speed=%04i", simdata->lap, newdatestring, simdata->velocity);
|
|
|
|
sprintf(payloads[0], "%04f", simdata->clutch);
|
|
sprintf(payloads[1], "%04f", simdata->brake);
|
|
sprintf(payloads[2], "%04f", simdata->gas);
|
|
sprintf(payloads[3], "%04f", simdata->handbrake);
|
|
sprintf(payloads[4], "%04f", simdata->steer);
|
|
sprintf(payloads[5], "%i", simdata->rpms);
|
|
sprintf(payloads[6], "%i", simdata->gear);
|
|
sprintf(payloads[7], "%04f", simdata->velocity * 0.2777778);
|
|
sprintf(payloads[8], "%08f", simdata->trackdistancearound);
|
|
sprintf(payloads[9], "%08f", simdata->worldposx);
|
|
sprintf(payloads[10], "%08f", simdata->worldposy);
|
|
sprintf(payloads[11], "%08f", simdata->worldposz);
|
|
sprintf(payloads[12], "%i", simdata->playerlaps);
|
|
sprintf(payloads[13], "%i", simdata->currentlapinseconds);
|
|
sprintf(payloads[14], "%i", simdata->lastlapinseconds);
|
|
sprintf(payloads[15], "%i", simdata->lapisvalid);
|
|
|
|
json_object *root = json_object_new_object();
|
|
if (!root)
|
|
return 1;
|
|
// {"module":"log"}
|
|
|
|
json_object *child = json_object_new_object();
|
|
json_object_object_add(root, "time", json_object_new_string("1669657644794")); //unix time milliseconds
|
|
|
|
/* these get placed into the topic path
|
|
json_object_object_add(root, "CarModel", json_object_new_string(simdata->car));
|
|
json_object_object_add(root, "GameName", json_object_new_string("Assetto Corsa (64 bit")));
|
|
json_object_object_add(root, "SessionId", json_object_new_string("1669233672"));
|
|
json_object_object_add(root, "SessionTypeName", json_object_new_string("Practice"));
|
|
json_object_object_add(root, "TrackCode", json_object_new_string(simdata->track));
|
|
*/
|
|
|
|
json_object_object_add(child, "Clutch", json_object_new_string(payloads[1]));
|
|
json_object_object_add(child, "Brake", json_object_new_string(payloads[1]));
|
|
json_object_object_add(child, "Throtte", json_object_new_string(payloads[2]));
|
|
json_object_object_add(child, "HandBrake", json_object_new_string(payloads[3]));
|
|
json_object_object_add(child, "SteeringAngle", json_object_new_string(payloads[4]));
|
|
json_object_object_add(child, "Rpms", json_object_new_string(payloads[5]));
|
|
json_object_object_add(child, "Gear", json_object_new_string(payloads[6]));
|
|
json_object_object_add(child, "SpeedMs", json_object_new_string(payloads[7]));
|
|
json_object_object_add(child, "DistanceRoundTrack", json_object_new_string(payloads[8]));
|
|
json_object_object_add(child, "WorldPosition_x", json_object_new_string(payloads[9]));
|
|
json_object_object_add(child, "WorldPosition_y", json_object_new_string(payloads[10]));
|
|
json_object_object_add(child, "WorldPosition_z", json_object_new_string(payloads[11]));
|
|
json_object_object_add(child, "CurrentLap", json_object_new_string(payloads[12]));
|
|
json_object_object_add(child, "CurrentLapTime", json_object_new_string(payloads[13]));
|
|
json_object_object_add(child, "LapTimePrevious", json_object_new_string(payloads[14]));
|
|
json_object_object_add(child, "CurrentLapIsValid", json_object_new_string(payloads[15]));
|
|
json_object_object_add(child, "PreviousLapWasValid", json_object_new_string("1"));
|
|
|
|
json_object_object_add(root, "telemetry", child);
|
|
|
|
slogi(json_object_to_json_string_ext(root, JSON_C_TO_STRING_PRETTY));
|
|
|
|
for (int k =0; k < 5; k++)
|
|
{
|
|
pubmsg.payload = payloads[k];
|
|
pubmsg.payloadlen = strlen(payloads[k]);
|
|
pubmsg.qos = QOS;
|
|
pubmsg.retained = 0;
|
|
MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token);
|
|
}
|
|
}
|
|
|
|
wclear(win1);
|
|
wclear(win2);
|
|
wclear(win3);
|
|
wclear(win4);
|
|
|
|
{ // window 1 car diagnostics
|
|
|
|
char spacer[14];
|
|
sprintf(spacer, "\n");
|
|
waddstr(win1, spacer);
|
|
|
|
sprintf(spacer, "\n");
|
|
waddstr(win1, spacer);
|
|
|
|
char speed[14];
|
|
wbkgd(win1,COLOR_PAIR(1));
|
|
wattrset(win1, COLOR_PAIR(1));
|
|
wprintw(win1, " Speed: ");
|
|
sprintf(speed, "%i\n", simdata->velocity);
|
|
wattrset(win1, COLOR_PAIR(2));
|
|
waddstr(win1, speed);
|
|
|
|
char rpm[14];
|
|
wattrset(win1, COLOR_PAIR(1));
|
|
wprintw(win1, " RPM: ");
|
|
sprintf(rpm, "%i\n", simdata->rpms);
|
|
wattrset(win1, COLOR_PAIR(2));
|
|
waddstr(win1, rpm);
|
|
|
|
char gear[14];
|
|
wattrset(win1, COLOR_PAIR(1));
|
|
wprintw(win1, " Gear: ");
|
|
sprintf(gear, "%i\n", simdata->gear);
|
|
wattrset(win1, COLOR_PAIR(2));
|
|
waddstr(win1, gear);
|
|
|
|
char gas[14];
|
|
wattrset(win1, COLOR_PAIR(1));
|
|
wprintw(win1, " Gas: ");
|
|
sprintf(gas, "%f\n", simdata->gas);
|
|
wattrset(win1, COLOR_PAIR(2));
|
|
waddstr(win1, gas);
|
|
|
|
char brake[14];
|
|
wattrset(win1, COLOR_PAIR(1));
|
|
wprintw(win1, " Brake: ");
|
|
sprintf(brake, "%f\n", simdata->brake);
|
|
wattrset(win1, COLOR_PAIR(2));
|
|
waddstr(win1, brake);
|
|
|
|
char fuel[14];
|
|
wattrset(win1, COLOR_PAIR(1));
|
|
wprintw(win1, " Fuel: ");
|
|
sprintf(fuel, "%f\n", simdata->fuel);
|
|
wattrset(win1, COLOR_PAIR(2));
|
|
waddstr(win1, fuel);
|
|
|
|
sprintf(spacer, "\n");
|
|
waddstr(win1, spacer);
|
|
|
|
sprintf(spacer, "\n");
|
|
waddstr(win1, spacer);
|
|
|
|
sprintf(spacer, "\n");
|
|
waddstr(win1, spacer);
|
|
|
|
wattrset(win1, COLOR_PAIR(1));
|
|
wprintw(win1, " braketemp ");
|
|
wattrset(win1, COLOR_PAIR(2));
|
|
wprintw(win1, "%.0f", simdata->braketemp[0]);
|
|
wattrset(win1, COLOR_PAIR(1));
|
|
wprintw(win1, " braketemp ");
|
|
wattrset(win1, COLOR_PAIR(2));
|
|
wprintw(win1, "%.0f\n", simdata->braketemp[1]);
|
|
|
|
sprintf(spacer, "\n");
|
|
waddstr(win1, spacer);
|
|
|
|
wattrset(win1, COLOR_PAIR(1));
|
|
wprintw(win1, " temp ");
|
|
wattrset(win1, COLOR_PAIR(2));
|
|
wprintw(win1, "%.0f", simdata->tyretemp[0]);
|
|
wattrset(win1, COLOR_PAIR(1));
|
|
wprintw(win1, " temp ");
|
|
wattrset(win1, COLOR_PAIR(2));
|
|
wprintw(win1, "%.0f\n", simdata->tyretemp[1]);
|
|
|
|
wattrset(win1, COLOR_PAIR(1));
|
|
wprintw(win1, " pres ");
|
|
wattrset(win1, COLOR_PAIR(2));
|
|
wprintw(win1, "%.0f", simdata->tyrepressure[0]);
|
|
wattrset(win1, COLOR_PAIR(1));
|
|
wprintw(win1, " pres ");
|
|
wattrset(win1, COLOR_PAIR(2));
|
|
wprintw(win1, "%.0f\n", simdata->tyrepressure[1]);
|
|
|
|
wattrset(win1, COLOR_PAIR(1));
|
|
wprintw(win1, " wear ");
|
|
wattrset(win1, COLOR_PAIR(2));
|
|
wprintw(win1, "%.0f", simdata->tyrewear[0]);
|
|
wattrset(win1, COLOR_PAIR(1));
|
|
wprintw(win1, " wear ");
|
|
wattrset(win1, COLOR_PAIR(2));
|
|
wprintw(win1, "%.0f\n", simdata->tyrewear[1]);
|
|
|
|
sprintf(spacer, "\n");
|
|
waddstr(win1, spacer);
|
|
|
|
sprintf(spacer, "\n");
|
|
waddstr(win1, spacer);
|
|
|
|
sprintf(spacer, "\n");
|
|
waddstr(win1, spacer);
|
|
|
|
wattrset(win1, COLOR_PAIR(1));
|
|
wprintw(win1, " temp ");
|
|
wattrset(win1, COLOR_PAIR(2));
|
|
wprintw(win1, "%.0f", simdata->tyretemp[2]);
|
|
wattrset(win1, COLOR_PAIR(1));
|
|
wprintw(win1, " temp ");
|
|
wattrset(win1, COLOR_PAIR(2));
|
|
wprintw(win1, "%.0f\n", simdata->tyretemp[3]);
|
|
|
|
wattrset(win1, COLOR_PAIR(1));
|
|
wprintw(win1, " pres ");
|
|
wattrset(win1, COLOR_PAIR(2));
|
|
wprintw(win1, "%.0f", simdata->tyrepressure[2]);
|
|
wattrset(win1, COLOR_PAIR(1));
|
|
wprintw(win1, " pres ");
|
|
wattrset(win1, COLOR_PAIR(2));
|
|
wprintw(win1, "%.0f\n", simdata->tyrepressure[3]);
|
|
|
|
wattrset(win1, COLOR_PAIR(1));
|
|
wprintw(win1, " wear ");
|
|
wattrset(win1, COLOR_PAIR(2));
|
|
wprintw(win1, "%.0f", simdata->tyrewear[2]);
|
|
wattrset(win1, COLOR_PAIR(1));
|
|
wprintw(win1, " wear ");
|
|
wattrset(win1, COLOR_PAIR(2));
|
|
wprintw(win1, "%.0f\n", simdata->tyrewear[3]);
|
|
|
|
sprintf(spacer, "\n");
|
|
waddstr(win1, spacer);
|
|
|
|
wattrset(win1, COLOR_PAIR(1));
|
|
wprintw(win1, " braketemp ");
|
|
wattrset(win1, COLOR_PAIR(2));
|
|
wprintw(win1, "%.0f", simdata->braketemp[0]);
|
|
wattrset(win1, COLOR_PAIR(1));
|
|
wprintw(win1, " braketemp ");
|
|
wattrset(win1, COLOR_PAIR(2));
|
|
wprintw(win1, "%.0f\n", simdata->braketemp[1]);
|
|
|
|
wattrset(win1, COLOR_PAIR(1));
|
|
rectangle(12, 12, 16, 16); // left front
|
|
rectangle(12, 18, 16, 22); // right front
|
|
rectangle(18, 12, 22, 16); // left rear
|
|
rectangle(18, 18, 22, 22); // right rear
|
|
}
|
|
|
|
{ // window 2 session info
|
|
|
|
char spacer[14];
|
|
sprintf(spacer, "\n");
|
|
waddstr(win2, spacer);
|
|
|
|
char airtemp[14];
|
|
wbkgd(win2,COLOR_PAIR(1));
|
|
wattrset(win2, COLOR_PAIR(1));
|
|
wprintw(win2, " Air Temp: ");
|
|
sprintf(airtemp, "%.0f\n", simdata->airtemp);
|
|
wattrset(win2, COLOR_PAIR(2));
|
|
waddstr(win2, airtemp);
|
|
|
|
char airdensity[14];
|
|
wattrset(win2, COLOR_PAIR(1));
|
|
wprintw(win2, " Humidity: ");
|
|
sprintf(airdensity, "%.0f\n", simdata->airdensity);
|
|
wattrset(win2, COLOR_PAIR(2));
|
|
waddstr(win2, airdensity);
|
|
|
|
char tracktemp[14];
|
|
wattrset(win2, COLOR_PAIR(1));
|
|
wprintw(win2, " Track Temp: ");
|
|
sprintf(tracktemp, "%.0f\n", simdata->tracktemp);
|
|
wattrset(win2, COLOR_PAIR(2));
|
|
waddstr(win2, tracktemp);
|
|
|
|
char numlaps[14];
|
|
wbkgd(win2,COLOR_PAIR(1));
|
|
wattrset(win2, COLOR_PAIR(1));
|
|
wprintw(win2, " Num Laps: ");
|
|
sprintf(numlaps, "%i\n", simdata->numlaps);
|
|
wattrset(win2, COLOR_PAIR(2));
|
|
waddstr(win2, numlaps);
|
|
|
|
char timeleft[14];
|
|
int hours = simdata->timeleft/6000;
|
|
int minutes = simdata->timeleft/60 - (hours*6000);
|
|
int seconds = simdata->timeleft-((minutes*60)+(hours*6000));
|
|
//int fraction = simdata->timeleft-(minutes*60000)-(seconds*1000);
|
|
wbkgd(win2, COLOR_PAIR(1));
|
|
wattrset(win2, COLOR_PAIR(1));
|
|
wprintw(win2, " Time Left: ");
|
|
sprintf(timeleft, "%02d:%02d:%02d\n", hours, minutes, seconds);
|
|
wattrset(win2, COLOR_PAIR(2));
|
|
waddstr(win2, timeleft);
|
|
|
|
char currenttime[14];
|
|
hours = simdata->time/6000;
|
|
minutes = simdata->time/60 - (hours*6000);
|
|
seconds = simdata->time-((minutes*60)+(hours*6000));
|
|
//fraction = simdata->time-(minutes*60000)-(seconds*1000);
|
|
wbkgd(win2, COLOR_PAIR(1));
|
|
wattrset(win2, COLOR_PAIR(1));
|
|
wprintw(win2, " Current Time: ");
|
|
sprintf(currenttime, "%02d:%02d:%02d\n", hours, minutes, seconds);
|
|
wattrset(win2, COLOR_PAIR(2));
|
|
waddstr(win2, currenttime);
|
|
|
|
wattrset(win2, COLOR_PAIR(1));
|
|
}
|
|
|
|
{ // window 3 basic timing and scoring
|
|
|
|
char spacer[14];
|
|
sprintf(spacer, "\n");
|
|
waddstr(win3, spacer);
|
|
|
|
char car[14];
|
|
wattrset(win3, COLOR_PAIR(1));
|
|
wprintw(win3, " Car: ");
|
|
sprintf(car, "%s\n", simdata->car);
|
|
wattrset(win3, COLOR_PAIR(2));
|
|
waddstr(win3, car);
|
|
|
|
char track[14];
|
|
wattrset(win3, COLOR_PAIR(1));
|
|
wprintw(win3, " Track: ");
|
|
sprintf(track, "%s\n", simdata->track);
|
|
wattrset(win3, COLOR_PAIR(2));
|
|
waddstr(win3, track);
|
|
|
|
char driver[14];
|
|
wattrset(win3, COLOR_PAIR(1));
|
|
wprintw(win3, " Driver: ");
|
|
sprintf(driver, "%s\n", simdata->driver);
|
|
wattrset(win3, COLOR_PAIR(2));
|
|
waddstr(win3, driver);
|
|
|
|
char lap[14];
|
|
wbkgd(win3,COLOR_PAIR(1));
|
|
wattrset(win3, COLOR_PAIR(1));
|
|
wprintw(win3, " Lap: ");
|
|
sprintf(lap, "%i\n", simdata->lap);
|
|
wattrset(win3, COLOR_PAIR(2));
|
|
waddstr(win3, lap);
|
|
|
|
char position[14];
|
|
wattrset(win3, COLOR_PAIR(1));
|
|
wprintw(win3, " Position: ");
|
|
sprintf(position, "%i\n", simdata->position);
|
|
wattrset(win3, COLOR_PAIR(2));
|
|
waddstr(win3, position);
|
|
|
|
char lastlap[14];
|
|
int minutes = simdata->lastlap/60000;
|
|
int seconds = simdata->lastlap/1000-(minutes*60);
|
|
int fraction = simdata->lastlap-(minutes*60000)-(seconds*1000);
|
|
wattrset(win3, COLOR_PAIR(1));
|
|
wprintw(win3, " Last Lap: ");
|
|
sprintf(lastlap, "%d:%02d:%02d\n", minutes, seconds, fraction);
|
|
wattrset(win3, COLOR_PAIR(2));
|
|
waddstr(win3, lastlap);
|
|
|
|
char bestlap[14];
|
|
minutes = simdata->bestlap/60000;
|
|
seconds = simdata->bestlap/1000-(minutes*60);
|
|
fraction = simdata->bestlap-(minutes*60000)-(seconds*1000);
|
|
wattrset(win3, COLOR_PAIR(1));
|
|
wprintw(win3, " Best Lap: ");
|
|
sprintf(bestlap, "%d:%02d:%02d\n", minutes, seconds, fraction);
|
|
wattrset(win3, COLOR_PAIR(2));
|
|
waddstr(win3, bestlap);
|
|
|
|
wattrset(win3, COLOR_PAIR(1));
|
|
}
|
|
|
|
{ // window 4 live standings timing and scoring
|
|
char spacer[14];
|
|
sprintf(spacer, "\n");
|
|
waddstr(win4, spacer);
|
|
|
|
wattrset(win4, COLOR_PAIR(4));
|
|
wprintw(win4, " P ");
|
|
wprintw(win4, " Driver ");
|
|
wprintw(win4, " Car ");
|
|
wprintw(win4, " Laps ");
|
|
wprintw(win4, " Last ");
|
|
wprintw(win4, " Best ");
|
|
wprintw(win4, " Pit ");
|
|
wprintw(win4, "\n");
|
|
|
|
// figuring out how many and which entrants to display while respecting term size
|
|
// this will take some work and testing
|
|
int thisx, thisy;
|
|
getmaxyx(win4, thisx, thisy);
|
|
int maxdispcars = thisy/5;
|
|
int displaycars = maxdispcars;
|
|
if (displaycars > MAXCARS)
|
|
{
|
|
displaycars = MAXCARS;
|
|
}
|
|
if (simdata->numcars < displaycars)
|
|
{
|
|
displaycars = simdata->numcars;
|
|
}
|
|
for(int i=0; i<displaycars; i++)
|
|
{
|
|
int ihold = i;
|
|
for(i=0; i<displaycars; i++)
|
|
{
|
|
if((ihold+1)==simdata->cars[i].pos)
|
|
break;
|
|
}
|
|
|
|
wattrset(win4, COLOR_PAIR(2));
|
|
int maxstrlen = 20;
|
|
wprintw(win4, " %02d ", simdata->cars[i].pos);
|
|
wprintw(win4, " %-*.*s ", maxstrlen, maxstrlen, simdata->cars[i].driver);
|
|
wprintw(win4, " %-*.*s ", maxstrlen, maxstrlen, simdata->cars[i].car);
|
|
wprintw(win4, " %d ", simdata->cars[i].lap);
|
|
|
|
char clastlap[14];
|
|
int lastlap = simdata->cars[i].lastlap;
|
|
int minutes = lastlap/60000;
|
|
int seconds = lastlap/1000-(minutes*60);
|
|
int fraction = lastlap-(minutes*60000)-(seconds*1000);
|
|
sprintf(clastlap, "%02d:%02d:%03d", minutes, seconds, fraction);
|
|
waddstr(win4, clastlap);
|
|
|
|
wprintw(win4, " ");
|
|
|
|
char cbestlap[14];
|
|
int bestlap = simdata->cars[i].bestlap;
|
|
minutes = bestlap/60000;
|
|
seconds = bestlap/1000-(minutes*60);
|
|
fraction = bestlap-(minutes*60000)-(seconds*1000);
|
|
sprintf(cbestlap, "%02d:%02d:%03d", minutes, seconds, fraction);
|
|
waddstr(win4, cbestlap);
|
|
|
|
if(simdata->cars[i].inpitlane == 0 && simdata->cars[i].inpit == 0)
|
|
{
|
|
wattrset(win4, COLOR_PAIR(1));
|
|
wprintw(win4, " ontrack ");
|
|
}
|
|
else
|
|
{
|
|
if(simdata->cars[i].inpit > 0)
|
|
{
|
|
wprintw(win4, " pit ");
|
|
}
|
|
else
|
|
{
|
|
wprintw(win4, " pitlane ");
|
|
}
|
|
}
|
|
i = ihold;
|
|
wprintw(win4, "\n");
|
|
}
|
|
wattrset(win4, COLOR_PAIR(1));
|
|
}
|
|
|
|
box(win1, 0, 0);
|
|
box(win2, 0, 0);
|
|
box(win3, 0, 0);
|
|
box(win4, 0, 0);
|
|
|
|
wrefresh(win1);
|
|
wrefresh(win2);
|
|
wrefresh(win3);
|
|
wrefresh(win4);
|
|
|
|
if (getch() == 'q')
|
|
{
|
|
go = false;
|
|
}
|
|
}
|
|
|
|
wrefresh(win4);
|
|
delwin(win4);
|
|
endwin();
|
|
|
|
wrefresh(win3);
|
|
delwin(win3);
|
|
endwin();
|
|
|
|
wrefresh(win2);
|
|
delwin(win2);
|
|
endwin();
|
|
|
|
wrefresh(win1);
|
|
delwin(win1);
|
|
endwin();
|
|
|
|
if (mqtt_connected == true)
|
|
{
|
|
MQTTClient_disconnect(client, 10000);
|
|
}
|
|
MQTTClient_destroy(&client);
|
|
|
|
free(simdata);
|
|
free(simmap);
|
|
|
|
return 0;
|
|
}
|