Major overhault to add libuv event loop. Enhancements to config file to support profiles.
This commit is contained in:
parent
607a7ad7c3
commit
40726c06c8
|
|
@ -37,10 +37,10 @@ add_executable(monocoque src/monocoque/monocoque.c)
|
||||||
if(USE_PULSEAUDIO)
|
if(USE_PULSEAUDIO)
|
||||||
message("Using pulseaudio backend...")
|
message("Using pulseaudio backend...")
|
||||||
add_compile_definitions(USE_PULSEAUDIO=true)
|
add_compile_definitions(USE_PULSEAUDIO=true)
|
||||||
target_link_libraries(monocoque m hidapi-hidraw pulse serialport xml2 argtable2 config gameloop helper devices slog simulatorapi)
|
target_link_libraries(monocoque m hidapi-hidraw pulse serialport xml2 argtable2 config gameloop helper devices slog simulatorapi uv xdg-basedir)
|
||||||
else()
|
else()
|
||||||
message("Using portaudio backend...")
|
message("Using portaudio backend...")
|
||||||
target_link_libraries(monocoque m hidapi-hidraw portaudio serialport xml2 argtable2 config gameloop helper devices slog simulatorapi)
|
target_link_libraries(monocoque m hidapi-hidraw portaudio serialport xml2 argtable2 config gameloop helper devices slog simulatorapi uv xdg-basedir)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_include_directories(monocoque PUBLIC config ${LIBXML_INCLUDE_DIR})
|
target_include_directories(monocoque PUBLIC config ${LIBXML_INCLUDE_DIR})
|
||||||
|
|
|
||||||
|
|
@ -78,15 +78,12 @@ void stream_state_cb(pa_stream *s, void *mainloop) {
|
||||||
int usb_generic_shaker_free(SoundDevice* sounddevice)
|
int usb_generic_shaker_free(SoundDevice* sounddevice)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
//err = Pa_CloseStream( sounddevice->stream );
|
|
||||||
//if( err != paNoError )
|
|
||||||
//{
|
|
||||||
// err = Pa_Terminate();
|
|
||||||
//}
|
|
||||||
if (sounddevice->stream)
|
if (sounddevice->stream)
|
||||||
{
|
{
|
||||||
|
pa_stream_disconnect(sounddevice->stream);
|
||||||
pa_stream_unref(sounddevice->stream);
|
pa_stream_unref(sounddevice->stream);
|
||||||
pa_xfree(sounddevice->stream);
|
// why is this wrong
|
||||||
|
//pa_xfree(sounddevice->stream);
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -104,8 +104,7 @@ int sounddev_free(SimDevice* this)
|
||||||
{
|
{
|
||||||
SoundDevice* sounddevice = (void *) this->derived;
|
SoundDevice* sounddevice = (void *) this->derived;
|
||||||
|
|
||||||
//figure out why this is causing problems
|
usb_generic_shaker_free(sounddevice);
|
||||||
//usb_generic_shaker_free(sounddevice);
|
|
||||||
|
|
||||||
free(sounddevice);
|
free(sounddevice);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ set(gameloop_source_files
|
||||||
gameloop.h
|
gameloop.h
|
||||||
tachconfig.c
|
tachconfig.c
|
||||||
tachconfig.h
|
tachconfig.h
|
||||||
|
loopdata.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(LIBXML_INCLUDE_DIR /usr/include/libxml2)
|
set(LIBXML_INCLUDE_DIR /usr/include/libxml2)
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,11 @@
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <uv.h>
|
||||||
|
|
||||||
#include "gameloop.h"
|
#include "gameloop.h"
|
||||||
|
#include "loopdata.h"
|
||||||
|
|
||||||
#include "../helper/parameters.h"
|
#include "../helper/parameters.h"
|
||||||
#include "../helper/confighelper.h"
|
#include "../helper/confighelper.h"
|
||||||
#include "../devices/simdevice.h"
|
#include "../devices/simdevice.h"
|
||||||
|
|
@ -22,15 +25,17 @@ bool go = false;
|
||||||
bool go2 = false;
|
bool go2 = false;
|
||||||
struct sigaction act;
|
struct sigaction act;
|
||||||
|
|
||||||
void sighandler(int signum, siginfo_t* info, void* ptr)
|
|
||||||
{
|
uv_idle_t idler;
|
||||||
sloge("caught signal");
|
uv_timer_t datachecktimer;
|
||||||
go = false;
|
uv_timer_t datamaptimer;
|
||||||
go2 = false;
|
|
||||||
//gfx_clear(pixels, pixels_len);
|
bool doui = false;
|
||||||
//gfx_swapbuffers();
|
int appstate = 0;
|
||||||
//gfx_close();
|
|
||||||
}
|
void shmdatamapcallback(uv_timer_t* handle);
|
||||||
|
void datacheckcallback(uv_timer_t* handle);
|
||||||
|
void startdatalogger(MonocoqueSettings* ms, loop_data* l);
|
||||||
|
|
||||||
int showstats(SimData* simdata)
|
int showstats(SimData* simdata)
|
||||||
{
|
{
|
||||||
|
|
@ -181,26 +186,61 @@ int showstats(SimData* simdata)
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void shmdatamapcallback(uv_timer_t* handle)
|
||||||
|
{
|
||||||
|
|
||||||
int clilooper(SimDevice* devices, int numdevices, Parameters* p, SimData* simdata, SimMap* simmap)
|
void* b = uv_handle_get_data((uv_handle_t*) handle);
|
||||||
|
loop_data* f = (loop_data*) b;
|
||||||
|
SimData* simdata = f->simdata;
|
||||||
|
SimMap* simmap = f->simmap;
|
||||||
|
MonocoqueSettings* ms = f->ms;
|
||||||
|
//appstate = 2;
|
||||||
|
if (appstate == 2)
|
||||||
{
|
{
|
||||||
struct pollfd mypoll = { STDIN_FILENO, POLLIN|POLLPRI };
|
simdatamap(simdata, simmap, f->sim);
|
||||||
double update_rate = DEFAULT_UPDATE_RATE;
|
|
||||||
char ch;
|
if (doui == true)
|
||||||
int t=0;
|
|
||||||
int s=0;
|
|
||||||
go2 = true;
|
|
||||||
slogd("game data found, starting game loop");
|
|
||||||
while (go2 == true && simdata->simstatus > 1)
|
|
||||||
{
|
{
|
||||||
simdatamap(simdata, simmap, p->sim);
|
slogi("looking for ui config %s", ms->config_str);
|
||||||
showstats(simdata);
|
int confignum = getconfigtouse(ms->config_str, simdata->car, f->sim);
|
||||||
t++;
|
int configureddevices;
|
||||||
s++;
|
configcheck(ms->config_str, confignum, &configureddevices);
|
||||||
if(simdata->rpms<100)
|
|
||||||
|
DeviceSettings* ds = malloc(configureddevices * sizeof(DeviceSettings));
|
||||||
|
slogd("loading confignum %i, with %i devices.", confignum, configureddevices);
|
||||||
|
|
||||||
|
f->numdevices = uiloadconfig(ms->config_str, confignum, configureddevices, ms, ds);
|
||||||
|
|
||||||
|
f->simdevices = malloc(f->numdevices * sizeof(SimDevice));
|
||||||
|
int initdevices = devinit(f->simdevices, configureddevices, ds, ms);
|
||||||
|
int i = 0;
|
||||||
|
for( i = 0; i < configureddevices; i++)
|
||||||
{
|
{
|
||||||
simdata->rpms=100;
|
settingsfree(ds[i]);
|
||||||
}
|
}
|
||||||
|
free(ds);
|
||||||
|
doui = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
showstats(simdata);
|
||||||
|
SimDevice* devices = f->simdevices;
|
||||||
|
int numdevices = f->numdevices;
|
||||||
|
for (int x = 0; x < numdevices; x++)
|
||||||
|
{
|
||||||
|
if (devices[x].initialized == true)
|
||||||
|
{
|
||||||
|
devices[x].update(&devices[x], simdata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f->simstate == false || simdata->simstatus <= 1 || appstate <= 1)
|
||||||
|
{
|
||||||
|
f->uion = false;
|
||||||
|
SimDevice* devices = f->simdevices;
|
||||||
|
int numdevices = f->numdevices;
|
||||||
|
|
||||||
for (int x = 0; x < numdevices; x++)
|
for (int x = 0; x < numdevices; x++)
|
||||||
{
|
{
|
||||||
|
|
@ -209,51 +249,82 @@ int clilooper(SimDevice* devices, int numdevices, Parameters* p, SimData* simdat
|
||||||
devices[x].update(&devices[x], simdata);
|
devices[x].update(&devices[x], simdata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (int x = 0; x < numdevices; x++)
|
||||||
if( poll(&mypoll, 1, 1000.0/update_rate) )
|
|
||||||
{
|
{
|
||||||
|
if (devices[x].initialized == true)
|
||||||
|
{
|
||||||
|
devices[x].free(&devices[x]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(devices);
|
||||||
|
int r = simfree(simdata, simmap, f->sim);
|
||||||
|
slogd("simfree returned %i", r);
|
||||||
|
f->numdevices = 0;
|
||||||
|
slogi("stopped mapping data, press q again to quit");
|
||||||
|
//stopui(ms->ui_type, f);
|
||||||
|
// free loop data
|
||||||
|
uv_timer_stop(handle);
|
||||||
|
uv_timer_start(&datachecktimer, datacheckcallback, 3000, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void datacheckcallback(uv_timer_t* handle)
|
||||||
|
{
|
||||||
|
|
||||||
|
void* b = uv_handle_get_data((uv_handle_t*) handle);
|
||||||
|
loop_data* f = (loop_data*) b;
|
||||||
|
SimData* simdata = f->simdata;
|
||||||
|
SimMap* simmap = f->simmap;
|
||||||
|
|
||||||
|
if ( appstate == 1 )
|
||||||
|
{
|
||||||
|
getSim(simdata, simmap, &f->simstate, &f->sim);
|
||||||
|
}
|
||||||
|
if (f->simstate == true)
|
||||||
|
{
|
||||||
|
if ( appstate == 1 )
|
||||||
|
{
|
||||||
|
appstate++;
|
||||||
|
doui = true;
|
||||||
|
uv_timer_start(&datamaptimer, shmdatamapcallback, 2000, 16);
|
||||||
|
uv_timer_stop(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (appstate == 0)
|
||||||
|
{
|
||||||
|
slogi("stopping checking for data");
|
||||||
|
uv_timer_stop(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cb(uv_poll_t* handle, int status, int events)
|
||||||
|
{
|
||||||
|
char ch;
|
||||||
scanf("%c", &ch);
|
scanf("%c", &ch);
|
||||||
if (ch == 'q')
|
if (ch == 'q')
|
||||||
{
|
{
|
||||||
slogd("User gameloop exit requested.");
|
appstate--;
|
||||||
go2 = false;
|
slogi("User requested stop appstate is now %i", appstate);
|
||||||
}
|
fprintf(stdout, "User requested stop appstate is now %i\n", appstate);
|
||||||
}
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
simdata->velocity = 0;
|
if (appstate == 0)
|
||||||
simdata->rpms = 100;
|
|
||||||
simdata->gear = MONOCOQUE_GEAR_NEUTRAL;
|
|
||||||
for (int x = 0; x < numdevices; x++)
|
|
||||||
{
|
{
|
||||||
if (devices[x].initialized == true)
|
slogi("Monocoque is exiting...");
|
||||||
|
uv_timer_stop(&datachecktimer);
|
||||||
|
uv_poll_stop(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int monocoque_mainloop(MonocoqueSettings* ms)
|
||||||
{
|
{
|
||||||
devices[x].update(&devices[x], simdata);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stdout, "\n");
|
|
||||||
int r = simfree(simdata, simmap, p->sim);
|
|
||||||
slogd("simfree returned %i", r);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int looper(SimDevice* devices, int numdevices, Parameters* p)
|
|
||||||
{
|
|
||||||
memset(&act, 0, sizeof(act));
|
|
||||||
act.sa_sigaction = sighandler;
|
|
||||||
act.sa_flags = SA_SIGINFO;
|
|
||||||
sigaction(SIGTERM, &act, NULL);
|
|
||||||
sigaction(SIGINT, &act, NULL);
|
|
||||||
sigaction(SIGTSTP, &act, NULL);
|
|
||||||
|
|
||||||
SimData* simdata = malloc(sizeof(SimData));
|
SimData* simdata = malloc(sizeof(SimData));
|
||||||
SimMap* simmap = malloc(sizeof(SimMap));
|
SimMap* simmap = malloc(sizeof(SimMap));
|
||||||
simdata->tyrediameter[0] = -1;
|
|
||||||
simdata->tyrediameter[1] = -1;
|
|
||||||
simdata->tyrediameter[2] = -1;
|
|
||||||
simdata->tyrediameter[3] = -1;
|
|
||||||
|
|
||||||
struct termios newsettings, canonicalmode;
|
struct termios newsettings, canonicalmode;
|
||||||
tcgetattr(0, &canonicalmode);
|
tcgetattr(0, &canonicalmode);
|
||||||
|
|
@ -265,64 +336,190 @@ int looper(SimDevice* devices, int numdevices, Parameters* p)
|
||||||
char ch;
|
char ch;
|
||||||
struct pollfd mypoll = { STDIN_FILENO, POLLIN|POLLPRI };
|
struct pollfd mypoll = { STDIN_FILENO, POLLIN|POLLPRI };
|
||||||
|
|
||||||
|
uv_poll_t* poll = (uv_poll_t*) malloc(uv_handle_size(UV_POLL));
|
||||||
|
|
||||||
|
loop_data* baton = (loop_data*) malloc(sizeof(loop_data));
|
||||||
|
baton->simmap = simmap;
|
||||||
|
baton->simdata = simdata;
|
||||||
|
baton->ms = ms;
|
||||||
|
baton->simstate = false;
|
||||||
|
baton->uion = false;
|
||||||
|
baton->sim = 0;
|
||||||
|
baton->req.data = (void*) baton;
|
||||||
|
uv_handle_set_data((uv_handle_t*) &datachecktimer, (void*) baton);
|
||||||
|
uv_handle_set_data((uv_handle_t*) &datamaptimer, (void*) baton);
|
||||||
|
uv_handle_set_data((uv_handle_t*) poll, (void*) baton);
|
||||||
|
appstate = 1;
|
||||||
|
slogd("setting initial app state");
|
||||||
|
uv_timer_init(uv_default_loop(), &datachecktimer);
|
||||||
fprintf(stdout, "Searching for sim data... Press q to quit...\n");
|
fprintf(stdout, "Searching for sim data... Press q to quit...\n");
|
||||||
p->simon = false;
|
uv_timer_start(&datachecktimer, datacheckcallback, 1000, 1000);
|
||||||
double update_rate = SIM_CHECK_RATE;
|
|
||||||
go = true;
|
|
||||||
while (go == true)
|
|
||||||
{
|
|
||||||
p->simon = false;
|
|
||||||
getSim(simdata, simmap, &p->simon, &p->sim);
|
|
||||||
|
|
||||||
if (p->simon == true && simdata->simstatus > 1)
|
|
||||||
{
|
|
||||||
slogi("preparing game loop with %i devices...", numdevices);
|
|
||||||
|
|
||||||
|
|
||||||
slogi("sending initial data to devices");
|
if (0 != uv_poll_init(uv_default_loop(), poll, 0))
|
||||||
simdata->velocity = 16;
|
|
||||||
simdata->rpms = 100;
|
|
||||||
for (int x = 0; x < numdevices; x++)
|
|
||||||
{
|
{
|
||||||
devices[x].update(&devices[x], simdata);
|
return 1;
|
||||||
}
|
};
|
||||||
sleep(3);
|
if (0 != uv_poll_start(poll, UV_READABLE, cb))
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
};
|
||||||
|
|
||||||
clilooper(devices, numdevices, p, simdata, simmap);
|
|
||||||
}
|
|
||||||
if (p->simon == true)
|
|
||||||
{
|
|
||||||
p->simon = false;
|
|
||||||
fprintf(stdout, "Searching for sim data... Press q again to quit...\n");
|
|
||||||
sleep(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (poll(&mypoll, 1, 1000.0/update_rate) )
|
uv_timer_init(uv_default_loop(), &datamaptimer);
|
||||||
{
|
|
||||||
if (go != false )
|
|
||||||
{
|
|
||||||
scanf("%c", &ch);
|
|
||||||
if(ch == 'q')
|
|
||||||
{
|
|
||||||
slogd("User application exit requested.");
|
|
||||||
go = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||||
fprintf(stdout, "\n");
|
fprintf(stdout, "\n");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
tcsetattr(0, TCSANOW, &canonicalmode);
|
tcsetattr(0, TCSANOW, &canonicalmode);
|
||||||
|
|
||||||
int r = simfree(simdata, simmap, p->sim);
|
|
||||||
slogd("simfree returned %i", r);
|
|
||||||
free(simdata);
|
free(simdata);
|
||||||
free(simmap);
|
free(simmap);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//int clilooper(SimDevice* devices, int numdevices, Parameters* p, SimData* simdata, SimMap* simmap)
|
||||||
|
//{
|
||||||
|
// struct pollfd mypoll = { STDIN_FILENO, POLLIN|POLLPRI };
|
||||||
|
// double update_rate = DEFAULT_UPDATE_RATE;
|
||||||
|
// char ch;
|
||||||
|
// int t=0;
|
||||||
|
// int s=0;
|
||||||
|
// go2 = true;
|
||||||
|
// slogd("game data found, starting game loop");
|
||||||
|
// while (go2 == true && simdata->simstatus > 1)
|
||||||
|
// {
|
||||||
|
// simdatamap(simdata, simmap, p->sim);
|
||||||
|
// showstats(simdata);
|
||||||
|
// t++;
|
||||||
|
// s++;
|
||||||
|
// if(simdata->rpms<100)
|
||||||
|
// {
|
||||||
|
// simdata->rpms=100;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// for (int x = 0; x < numdevices; x++)
|
||||||
|
// {
|
||||||
|
// if (devices[x].initialized == true)
|
||||||
|
// {
|
||||||
|
// devices[x].update(&devices[x], simdata);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if( poll(&mypoll, 1, 1000.0/update_rate) )
|
||||||
|
// {
|
||||||
|
// scanf("%c", &ch);
|
||||||
|
// if(ch == 'q')
|
||||||
|
// {
|
||||||
|
// slogd("User gameloop exit requested.");
|
||||||
|
// go2 = false;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// simdata->velocity = 0;
|
||||||
|
// simdata->rpms = 100;
|
||||||
|
// simdata->gear = MONOCOQUE_GEAR_NEUTRAL;
|
||||||
|
// for (int x = 0; x < numdevices; x++)
|
||||||
|
// {
|
||||||
|
// if (devices[x].initialized == true)
|
||||||
|
// {
|
||||||
|
// devices[x].update(&devices[x], simdata);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fprintf(stdout, "\n");
|
||||||
|
// int r = simfree(simdata, simmap, p->sim);
|
||||||
|
// slogd("simfree returned %i", r);
|
||||||
|
//
|
||||||
|
// return 0;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//int looper(SimDevice* devices, int numdevices, Parameters* p)
|
||||||
|
//{
|
||||||
|
// memset(&act, 0, sizeof(act));
|
||||||
|
// act.sa_sigaction = sighandler;
|
||||||
|
// act.sa_flags = SA_SIGINFO;
|
||||||
|
// sigaction(SIGTERM, &act, NULL);
|
||||||
|
// sigaction(SIGINT, &act, NULL);
|
||||||
|
// sigaction(SIGTSTP, &act, NULL);
|
||||||
|
//
|
||||||
|
// SimData* simdata = malloc(sizeof(SimData));
|
||||||
|
// SimMap* simmap = malloc(sizeof(SimMap));
|
||||||
|
// simdata->tyrediameter[0] = -1;
|
||||||
|
// simdata->tyrediameter[1] = -1;
|
||||||
|
// simdata->tyrediameter[2] = -1;
|
||||||
|
// simdata->tyrediameter[3] = -1;
|
||||||
|
//
|
||||||
|
// struct termios newsettings, canonicalmode;
|
||||||
|
// tcgetattr(0, &canonicalmode);
|
||||||
|
// newsettings = canonicalmode;
|
||||||
|
// newsettings.c_lflag &= (~ICANON & ~ECHO);
|
||||||
|
// newsettings.c_cc[VMIN] = 1;
|
||||||
|
// newsettings.c_cc[VTIME] = 0;
|
||||||
|
// tcsetattr(0, TCSANOW, &newsettings);
|
||||||
|
// char ch;
|
||||||
|
// struct pollfd mypoll = { STDIN_FILENO, POLLIN|POLLPRI };
|
||||||
|
//
|
||||||
|
// fprintf(stdout, "Searching for sim data... Press q to quit...\n");
|
||||||
|
// p->simon = false;
|
||||||
|
// double update_rate = SIM_CHECK_RATE;
|
||||||
|
// go = true;
|
||||||
|
// while (go == true)
|
||||||
|
// {
|
||||||
|
// p->simon = false;
|
||||||
|
// getSim(simdata, simmap, &p->simon, &p->sim);
|
||||||
|
//
|
||||||
|
// if (p->simon == true && simdata->simstatus > 1)
|
||||||
|
// {
|
||||||
|
// slogi("preparing game loop with %i devices...", numdevices);
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// slogi("sending initial data to devices");
|
||||||
|
// simdata->velocity = 16;
|
||||||
|
// simdata->rpms = 100;
|
||||||
|
// for (int x = 0; x < numdevices; x++)
|
||||||
|
// {
|
||||||
|
// devices[x].update(&devices[x], simdata);
|
||||||
|
// }
|
||||||
|
// sleep(3);
|
||||||
|
//
|
||||||
|
// clilooper(devices, numdevices, p, simdata, simmap);
|
||||||
|
// }
|
||||||
|
// if (p->simon == true)
|
||||||
|
// {
|
||||||
|
// p->simon = false;
|
||||||
|
// fprintf(stdout, "Searching for sim data... Press q again to quit...\n");
|
||||||
|
// sleep(2);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (poll(&mypoll, 1, 1000.0/update_rate) )
|
||||||
|
// {
|
||||||
|
// if (go != false )
|
||||||
|
// {
|
||||||
|
// scanf("%c", &ch);
|
||||||
|
// if(ch == 'q')
|
||||||
|
// {
|
||||||
|
// slogd("User application exit requested.");
|
||||||
|
// go = false;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fprintf(stdout, "\n");
|
||||||
|
// fflush(stdout);
|
||||||
|
// tcsetattr(0, TCSANOW, &canonicalmode);
|
||||||
|
//
|
||||||
|
// int r = simfree(simdata, simmap, p->sim);
|
||||||
|
// slogd("simfree returned %i", r);
|
||||||
|
// free(simdata);
|
||||||
|
// free(simmap);
|
||||||
|
//
|
||||||
|
// return 0;
|
||||||
|
//}
|
||||||
|
|
||||||
int tester(SimDevice* devices, int numdevices)
|
int tester(SimDevice* devices, int numdevices)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,3 +3,5 @@
|
||||||
|
|
||||||
int tester(SimDevice* devices, int numdevices);
|
int tester(SimDevice* devices, int numdevices);
|
||||||
int looper(SimDevice* devices, int numdevices, Parameters* p);
|
int looper(SimDevice* devices, int numdevices, Parameters* p);
|
||||||
|
|
||||||
|
int monocoque_mainloop(MonocoqueSettings* ms);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef _LOOPDATA_H
|
||||||
|
#define _LOOPDATA_H
|
||||||
|
|
||||||
|
#include <uv.h>
|
||||||
|
#include "../helper/parameters.h"
|
||||||
|
#include "../helper/confighelper.h"
|
||||||
|
#include "../devices/simdevice.h"
|
||||||
|
#include "../simulatorapi/simapi/simapi/simdata.h"
|
||||||
|
#include "../simulatorapi/simapi/simapi/simmapper.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct loop_data
|
||||||
|
{
|
||||||
|
uv_work_t req;
|
||||||
|
Simulator sim;
|
||||||
|
bool simstate;
|
||||||
|
bool uion;
|
||||||
|
int numdevices;
|
||||||
|
MonocoqueSettings* ms;
|
||||||
|
SimData* simdata;
|
||||||
|
SimMap* simmap;
|
||||||
|
SimDevice* simdevices;
|
||||||
|
} loop_data;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -176,6 +176,55 @@ int strtodev(const char* device_type, const char* device_subtype, DeviceSettings
|
||||||
return MONOCOQUE_ERROR_NONE;
|
return MONOCOQUE_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getconfigtouse(const char* config_file_str, char* car, int sim)
|
||||||
|
{
|
||||||
|
config_t cfg;
|
||||||
|
config_init(&cfg);
|
||||||
|
if (!config_read_file(&cfg, config_file_str))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s:%d - %s\n", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
config_setting_t* config = NULL;
|
||||||
|
config_setting_t* config_widgets = NULL;
|
||||||
|
config = config_lookup(&cfg, "configs");
|
||||||
|
int configs = config_setting_length(config);
|
||||||
|
|
||||||
|
const char* temp;
|
||||||
|
config_setting_t* config_config = NULL;
|
||||||
|
int j = 0;
|
||||||
|
if ( configs == 1 )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int confignum = 0;
|
||||||
|
for (j = 0; j < configs; j++)
|
||||||
|
{
|
||||||
|
config_config = config_setting_get_elem(config, j);
|
||||||
|
|
||||||
|
int found = 0;
|
||||||
|
int csim = 0;
|
||||||
|
config_setting_lookup_int(config_config, "sim", &csim);
|
||||||
|
if (csim != sim && csim != 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
found = config_setting_lookup_string(config_config, "car", &temp);
|
||||||
|
if(strcicmp("default", car) == 0)
|
||||||
|
{
|
||||||
|
confignum = j;
|
||||||
|
}
|
||||||
|
if(strcicmp(temp, car) != 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
confignum = j;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return confignum;
|
||||||
|
}
|
||||||
|
|
||||||
int loadtachconfig(const char* config_file, DeviceSettings* ds)
|
int loadtachconfig(const char* config_file, DeviceSettings* ds)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -312,6 +361,28 @@ int loadconfig(const char* config_file, DeviceSettings* ds)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int configcheck(const char* config_file_str, int confignum, int* devices)
|
||||||
|
{
|
||||||
|
slogt("ui config check");
|
||||||
|
config_t cfg;
|
||||||
|
config_init(&cfg);
|
||||||
|
if (!config_read_file(&cfg, config_file_str))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s:%d - %s\n", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg));
|
||||||
|
}
|
||||||
|
|
||||||
|
config_setting_t* config = NULL;
|
||||||
|
config = config_lookup(&cfg, "configs");
|
||||||
|
config_setting_t* selectedconfig = config_setting_get_elem(config, confignum);
|
||||||
|
slogt("selected num %i", confignum);
|
||||||
|
config_setting_t* config_devices = NULL;
|
||||||
|
config_devices = config_setting_lookup(selectedconfig, "devices");
|
||||||
|
*devices = config_setting_length(config_devices);
|
||||||
|
config_destroy(&cfg);
|
||||||
|
return 0;
|
||||||
|
//return cfg;
|
||||||
|
}
|
||||||
|
|
||||||
int devsetup(const char* device_type, const char* device_subtype, const char* config_file, MonocoqueSettings* ms, DeviceSettings* ds, config_setting_t* device_settings)
|
int devsetup(const char* device_type, const char* device_subtype, const char* config_file, MonocoqueSettings* ms, DeviceSettings* ds, config_setting_t* device_settings)
|
||||||
{
|
{
|
||||||
int error = MONOCOQUE_ERROR_NONE;
|
int error = MONOCOQUE_ERROR_NONE;
|
||||||
|
|
@ -442,6 +513,69 @@ int devsetup(const char* device_type, const char* device_subtype, const char* co
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int uiloadconfig(const char* config_file_str, int confignum, int configureddevices, MonocoqueSettings* ms, DeviceSettings* ds)
|
||||||
|
{
|
||||||
|
int numdevices = 0;
|
||||||
|
config_t cfg;
|
||||||
|
config_init(&cfg);
|
||||||
|
if (!config_read_file(&cfg, config_file_str))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s:%d - %s\n", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
slogi("Parsing config file");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
config_setting_t* config = NULL;
|
||||||
|
config = config_lookup(&cfg, "configs");
|
||||||
|
config_setting_t* selectedconfig = config_setting_get_elem(config, confignum);
|
||||||
|
config_setting_t* config_devices = NULL;
|
||||||
|
config_devices = config_setting_lookup(selectedconfig, "devices");
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
int error = MONOCOQUE_ERROR_NONE;
|
||||||
|
while (i<configureddevices)
|
||||||
|
{
|
||||||
|
error = MONOCOQUE_ERROR_NONE;
|
||||||
|
DeviceSettings settings;
|
||||||
|
|
||||||
|
config_setting_t* config_device = config_setting_get_elem(config_devices, i);
|
||||||
|
const char* device_type;
|
||||||
|
const char* device_subtype;
|
||||||
|
const char* device_config_file;
|
||||||
|
config_setting_lookup_string(config_device, "device", &device_type);
|
||||||
|
config_setting_lookup_string(config_device, "type", &device_subtype);
|
||||||
|
config_setting_lookup_string(config_device, "config", &device_config_file);
|
||||||
|
|
||||||
|
//slogt("device type: %s", device_type);
|
||||||
|
//slogt("device sub type: %s", device_subtype);
|
||||||
|
//slogt("device config file: %s", device_config_file);
|
||||||
|
if (error == MONOCOQUE_ERROR_NONE)
|
||||||
|
{
|
||||||
|
error = devsetup(device_type, device_subtype, device_config_file, ms, &settings, config_device);
|
||||||
|
}
|
||||||
|
if (error == MONOCOQUE_ERROR_NONE)
|
||||||
|
{
|
||||||
|
numdevices++;
|
||||||
|
}
|
||||||
|
ds[i] = settings;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
config_destroy(&cfg);
|
||||||
|
|
||||||
|
return numdevices;
|
||||||
|
}
|
||||||
|
|
||||||
int settingsfree(DeviceSettings ds)
|
int settingsfree(DeviceSettings ds)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,9 @@ typedef struct
|
||||||
int configcheck;
|
int configcheck;
|
||||||
int useconfig;
|
int useconfig;
|
||||||
char* tyre_diameter_config;
|
char* tyre_diameter_config;
|
||||||
|
char* config_str;
|
||||||
|
char* log_filename_str;
|
||||||
|
char* log_dirname_str;
|
||||||
}
|
}
|
||||||
MonocoqueSettings;
|
MonocoqueSettings;
|
||||||
|
|
||||||
|
|
@ -186,4 +189,10 @@ int settingsfree(DeviceSettings ds);
|
||||||
|
|
||||||
int strcicmp(char const *a, char const *b);
|
int strcicmp(char const *a, char const *b);
|
||||||
|
|
||||||
|
int getconfigtouse(const char* config_file_str, char* car, int sim);
|
||||||
|
|
||||||
|
int configcheck(const char* config_file_str, int confignum, int* devices);
|
||||||
|
|
||||||
|
int uiloadconfig(const char* config_file_str, int confignum, int configureddevices, MonocoqueSettings* ms, DeviceSettings* ds);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,36 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
void create_dir(char* dir)
|
||||||
|
{
|
||||||
|
struct stat st = {0};
|
||||||
|
if (stat(dir, &st) == -1)
|
||||||
|
{
|
||||||
|
mkdir(dir, 0700);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void create_xdg_dir(const char* dir)
|
||||||
|
{
|
||||||
|
struct stat st = {0};
|
||||||
|
if (stat(dir, &st) == -1)
|
||||||
|
{
|
||||||
|
mkdir(dir, 0700);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char* create_user_dir(char* home_dir_str, const char* dirtype, const char* programname)
|
||||||
|
{
|
||||||
|
// +3 for slashes
|
||||||
|
size_t ss = (4 + strlen(home_dir_str) + strlen(dirtype) + strlen(programname));
|
||||||
|
char* config_dir_str = malloc(ss);
|
||||||
|
|
||||||
|
snprintf (config_dir_str, ss, "%s/%s/%s/", home_dir_str, dirtype, programname);
|
||||||
|
|
||||||
|
create_dir(config_dir_str);
|
||||||
|
return config_dir_str;
|
||||||
|
}
|
||||||
|
|
||||||
char* gethome()
|
char* gethome()
|
||||||
{
|
{
|
||||||
char* homedir = getenv("HOME");
|
char* homedir = getenv("HOME");
|
||||||
|
|
@ -175,28 +205,67 @@ void restrict_folders_to_cache(char* path, int cachesize)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool does_directory_exist(char* path, char* dirname)
|
bool does_directory_exist(char* path)
|
||||||
{
|
{
|
||||||
struct dirent* de;
|
DIR* dir = opendir(path);
|
||||||
DIR* dr = opendir(path);
|
if (dir)
|
||||||
|
|
||||||
if (dr == NULL)
|
|
||||||
{
|
{
|
||||||
printf("Could not open current directory");
|
// Directory exists
|
||||||
|
closedir(dir);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Directory does not exist or cannot be opened
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Refer http://pubs.opengroup.org/onlinepubs/7990989775/xsh/readdir.html
|
bool does_file_exist(const char* file)
|
||||||
bool answer = false;
|
|
||||||
while ((de = readdir(dr)) != NULL)
|
|
||||||
{
|
{
|
||||||
if (strcmp(dirname,de->d_name) == 0)
|
if (file == NULL)
|
||||||
{
|
{
|
||||||
answer = true;
|
return false;
|
||||||
}
|
}
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
#if defined(WIN_API)
|
||||||
|
// if you want the WinAPI, versus CRT
|
||||||
|
if (strnlen(file, MAX_PATH+1) > MAX_PATH)
|
||||||
|
{
|
||||||
|
// ... throw error here or ...
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
DWORD res = GetFileAttributesA(file);
|
||||||
closedir(dr);
|
return (res != INVALID_FILE_ATTRIBUTES &&
|
||||||
return answer;
|
!(res& FILE_ATTRIBUTE_DIRECTORY));
|
||||||
|
#else
|
||||||
|
// Use Win CRT
|
||||||
|
struct stat fi;
|
||||||
|
if (_stat(file, &fi) == 0)
|
||||||
|
{
|
||||||
|
#if defined(S_ISSOCK)
|
||||||
|
// sockets come back as a 'file' on some systems
|
||||||
|
// so make sure it's not a socket or directory
|
||||||
|
// (in other words, make sure it's an actual file)
|
||||||
|
return !(S_ISDIR(fi.st_mode)) &&
|
||||||
|
!(S_ISSOCK(fi.st_mode));
|
||||||
|
#else
|
||||||
|
return !(S_ISDIR(fi.st_mode));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
struct stat fi;
|
||||||
|
if (stat(file, &fi) == 0)
|
||||||
|
{
|
||||||
|
#if defined(S_ISSOCK)
|
||||||
|
return !(S_ISDIR(fi.st_mode)) &&
|
||||||
|
!(S_ISSOCK(fi.st_mode));
|
||||||
|
#else
|
||||||
|
return !(S_ISDIR(fi.st_mode));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,14 @@
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
void create_dir(char* dir);
|
||||||
|
void create_xdg_dir(const char* dir);
|
||||||
|
char* create_user_dir(char* home_dir_str, const char* dirtype, const char* programpath);
|
||||||
char* gethome();
|
char* gethome();
|
||||||
char* str2md5(const char* str, int length);
|
char* str2md5(const char* str, int length);
|
||||||
bool does_directory_exist(char* path, char* dirname);
|
bool does_directory_exist(char* path);
|
||||||
void restrict_folders_to_cache(char* path, int cachesize);
|
void restrict_folders_to_cache(char* path, int cachesize);
|
||||||
void delete_dir(char* path);
|
void delete_dir(char* path);
|
||||||
|
bool does_file_exist(const char* file);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,39 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <libgen.h>
|
||||||
|
|
||||||
#include <libconfig.h>
|
#include <libconfig.h>
|
||||||
|
|
||||||
#include <argtable2.h>
|
#include <argtable2.h>
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
|
|
||||||
|
int freeparams(Parameters* p)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(p->config_dirpath != NULL)
|
||||||
|
{
|
||||||
|
free(p->config_dirpath);
|
||||||
|
}
|
||||||
|
if(p->config_filepath != NULL)
|
||||||
|
{
|
||||||
|
free(p->config_filepath);
|
||||||
|
}
|
||||||
|
if(p->log_filename_str != NULL)
|
||||||
|
{
|
||||||
|
free(p->log_filename_str);
|
||||||
|
}
|
||||||
|
if(p->log_fullfilename_str != NULL)
|
||||||
|
{
|
||||||
|
free(p->log_fullfilename_str);
|
||||||
|
}
|
||||||
|
if(p->log_dirname_str != NULL)
|
||||||
|
{
|
||||||
|
free(p->log_dirname_str);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
ConfigError getParameters(int argc, char** argv, Parameters* p)
|
ConfigError getParameters(int argc, char** argv, Parameters* p)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -18,6 +45,10 @@ ConfigError getParameters(int argc, char** argv, Parameters* p)
|
||||||
p->max_revs = 0;
|
p->max_revs = 0;
|
||||||
p->verbosity_count = 0;
|
p->verbosity_count = 0;
|
||||||
|
|
||||||
|
p->user_specified_config_file = false;
|
||||||
|
p->user_specified_log_file = false;
|
||||||
|
p->user_specified_config_dir = false;
|
||||||
|
|
||||||
// setup argument handling structures
|
// setup argument handling structures
|
||||||
const char* progname = "monocoque";
|
const char* progname = "monocoque";
|
||||||
|
|
||||||
|
|
@ -26,11 +57,13 @@ ConfigError getParameters(int argc, char** argv, Parameters* p)
|
||||||
struct arg_lit* arg_verbosity3 = arg_litn("v","verbose", 0, 2, "increase logging verbosity");
|
struct arg_lit* arg_verbosity3 = arg_litn("v","verbose", 0, 2, "increase logging verbosity");
|
||||||
|
|
||||||
struct arg_rex* cmd1 = arg_rex1(NULL, NULL, "play", NULL, REG_ICASE, NULL);
|
struct arg_rex* cmd1 = arg_rex1(NULL, NULL, "play", NULL, REG_ICASE, NULL);
|
||||||
struct arg_str* arg_sim = arg_strn("s", "sim", "<gamename>", 0, 1, NULL);
|
struct arg_file* arg_conf = arg_filen(NULL, "uiconf", "<config_file>", 0, 1, NULL);
|
||||||
|
struct arg_file* arg_log = arg_filen("l", "log", "<log_file>", 0, 1, NULL);
|
||||||
|
struct arg_str* arg_confdir = arg_strn(NULL, "configdir", "config_dir>", 0, 1, NULL);
|
||||||
struct arg_lit* help = arg_litn(NULL,"help", 0, 1, "print this help and exit");
|
struct arg_lit* help = arg_litn(NULL,"help", 0, 1, "print this help and exit");
|
||||||
struct arg_lit* vers = arg_litn(NULL,"version", 0, 1, "print version information and exit");
|
struct arg_lit* vers = arg_litn(NULL,"version", 0, 1, "print version information and exit");
|
||||||
struct arg_end* end1 = arg_end(20);
|
struct arg_end* end1 = arg_end(20);
|
||||||
void* argtable1[] = {cmd1,arg_sim,arg_verbosity1,help,vers,end1};
|
void* argtable1[] = {cmd1,arg_log,arg_conf,arg_verbosity1,help,vers,end1};
|
||||||
int nerrors1;
|
int nerrors1;
|
||||||
|
|
||||||
struct arg_rex* cmd2a = arg_rex1(NULL, NULL, "config", NULL, REG_ICASE, NULL);
|
struct arg_rex* cmd2a = arg_rex1(NULL, NULL, "config", NULL, REG_ICASE, NULL);
|
||||||
|
|
@ -83,8 +116,24 @@ ConfigError getParameters(int argc, char** argv, Parameters* p)
|
||||||
if (nerrors1==0)
|
if (nerrors1==0)
|
||||||
{
|
{
|
||||||
p->program_action = A_PLAY;
|
p->program_action = A_PLAY;
|
||||||
p->sim_string = arg_sim->sval[0];
|
|
||||||
p->verbosity_count = arg_verbosity1->count;
|
p->verbosity_count = arg_verbosity1->count;
|
||||||
|
|
||||||
|
if(arg_conf->count > 0)
|
||||||
|
{
|
||||||
|
p->config_filepath = strdup(arg_conf->filename[0]);
|
||||||
|
p->user_specified_config_file = true;
|
||||||
|
}
|
||||||
|
if(arg_log->count > 0)
|
||||||
|
{
|
||||||
|
char* filename = strdup(arg_log->filename[0]);
|
||||||
|
p->log_fullfilename_str = strdup(arg_log->filename[0]);
|
||||||
|
p->log_filename_str = strdup(arg_log->basename[0]);
|
||||||
|
char* dname;
|
||||||
|
dname = dirname(filename);
|
||||||
|
p->log_dirname_str = strdup(dname);
|
||||||
|
p->user_specified_log_file = true;
|
||||||
|
free(filename);
|
||||||
|
}
|
||||||
exitcode = E_SUCCESS_AND_DO;
|
exitcode = E_SUCCESS_AND_DO;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,16 @@ typedef struct
|
||||||
|
|
||||||
Simulator sim;
|
Simulator sim;
|
||||||
bool simon;
|
bool simon;
|
||||||
|
|
||||||
|
char* config_filepath;
|
||||||
|
char* config_dirpath;
|
||||||
|
bool user_specified_config_file;
|
||||||
|
bool user_specified_config_dir;
|
||||||
|
bool user_specified_log_file;
|
||||||
|
|
||||||
|
char* log_filename_str;
|
||||||
|
char* log_fullfilename_str;
|
||||||
|
char* log_dirname_str;
|
||||||
}
|
}
|
||||||
Parameters;
|
Parameters;
|
||||||
|
|
||||||
|
|
@ -35,6 +45,7 @@ typedef enum
|
||||||
}
|
}
|
||||||
ConfigError;
|
ConfigError;
|
||||||
|
|
||||||
|
int freeparams(Parameters* p);
|
||||||
ConfigError getParameters(int argc, char** argv, Parameters* p);
|
ConfigError getParameters(int argc, char** argv, Parameters* p);
|
||||||
|
|
||||||
struct _errordesc
|
struct _errordesc
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,9 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <basedir_fs.h>
|
||||||
#include <libconfig.h>
|
#include <libconfig.h>
|
||||||
|
|
||||||
#include "gameloop/gameloop.h"
|
#include "gameloop/gameloop.h"
|
||||||
#include "gameloop/tachconfig.h"
|
#include "gameloop/tachconfig.h"
|
||||||
#include "devices/simdevice.h"
|
#include "devices/simdevice.h"
|
||||||
|
|
@ -14,27 +15,7 @@
|
||||||
#include "simulatorapi/simapi/simapi/simdata.h"
|
#include "simulatorapi/simapi/simapi/simdata.h"
|
||||||
#include "slog/slog.h"
|
#include "slog/slog.h"
|
||||||
|
|
||||||
|
#define PROGRAM_NAME "monocoque"
|
||||||
int create_dir(char* dir)
|
|
||||||
{
|
|
||||||
struct stat st = {0};
|
|
||||||
if (stat(dir, &st) == -1)
|
|
||||||
{
|
|
||||||
mkdir(dir, 0700);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char* create_user_dir(char* dirtype)
|
|
||||||
{
|
|
||||||
char* home_dir_str = gethome();
|
|
||||||
char* config_dir_str = ( char* ) malloc(1 + strlen(home_dir_str) + strlen(dirtype) + strlen("monocoque/"));
|
|
||||||
strcpy(config_dir_str, home_dir_str);
|
|
||||||
strcat(config_dir_str, dirtype);
|
|
||||||
strcat(config_dir_str, "monocoque");
|
|
||||||
|
|
||||||
create_dir(config_dir_str);
|
|
||||||
free(config_dir_str);
|
|
||||||
}
|
|
||||||
|
|
||||||
void display_banner()
|
void display_banner()
|
||||||
{
|
{
|
||||||
|
|
@ -45,10 +26,57 @@ void display_banner()
|
||||||
printf("/_/ /_/ \\____/ /_/ |_/ \\____/ \\____/ \\____/ \\___\\_\\\\____/ /_____/ \n");
|
printf("/_/ /_/ \\____/ /_/ |_/ \\____/ \\____/ \\____/ \\___\\_\\\\____/ /_____/ \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetSettingsFromParameters(Parameters* p, MonocoqueSettings* ms, char* configdir_str, char* cachedir_str)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(p->user_specified_config_file == true && does_file_exist(p->config_filepath))
|
||||||
|
{
|
||||||
|
ms->config_str = strdup(p->config_filepath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(p->user_specified_config_dir == true && does_directory_exist(p->config_dirpath))
|
||||||
|
{
|
||||||
|
asprintf(&ms->config_str, "%s/%s", p->config_dirpath, "monocoque.config");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
asprintf(&ms->config_str, "%s%s", configdir_str, "monocoque.config");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(p->user_specified_log_file == true && does_file_exist(p->log_fullfilename_str))
|
||||||
|
{
|
||||||
|
ms->log_dirname_str = strdup(p->log_dirname_str);
|
||||||
|
ms->log_filename_str = strdup(p->log_filename_str);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ms->log_dirname_str = strdup(cachedir_str);
|
||||||
|
ms->log_filename_str = strdup("monocoque.log");
|
||||||
|
}
|
||||||
|
|
||||||
|
ms->program_action = A_TEST;
|
||||||
|
if (p->program_action == A_PLAY)
|
||||||
|
{
|
||||||
|
ms->program_action = A_PLAY;
|
||||||
|
}
|
||||||
|
if (p->program_action == A_CONFIG_TACH)
|
||||||
|
{
|
||||||
|
ms->program_action = A_CONFIG_TACH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
display_banner();
|
display_banner();
|
||||||
|
|
||||||
|
char* home_dir_str = gethome();
|
||||||
|
if(home_dir_str == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "You need a home directory");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Parameters* p = malloc(sizeof(Parameters));
|
Parameters* p = malloc(sizeof(Parameters));
|
||||||
MonocoqueSettings* ms = malloc(sizeof(MonocoqueSettings));;
|
MonocoqueSettings* ms = malloc(sizeof(MonocoqueSettings));;
|
||||||
|
|
||||||
|
|
@ -57,33 +85,47 @@ int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
goto cleanup_final;
|
goto cleanup_final;
|
||||||
}
|
}
|
||||||
ms->program_action = p->program_action;
|
|
||||||
|
|
||||||
char* home_dir_str = gethome();
|
xdgHandle xdg;
|
||||||
create_user_dir("/.config/");
|
if(!xdgInitHandle(&xdg))
|
||||||
create_user_dir("/.cache/");
|
{
|
||||||
char* config_file_str = ( char* ) malloc(1 + strlen(home_dir_str) + strlen("/.config/") + strlen("monocoque/monocoque.config"));
|
fprintf(stderr, "Function xdgInitHandle() failed, is $HOME unset?");
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* config_home_str = xdgConfigHome(&xdg);
|
||||||
|
const char* cache_home_str = xdgCacheHome(&xdg);
|
||||||
|
|
||||||
|
char* cachedir_str = NULL;
|
||||||
|
char* configdir_str = NULL;
|
||||||
|
|
||||||
|
if(p->user_specified_config_file == false && p->user_specified_config_dir == false)
|
||||||
|
{
|
||||||
|
create_xdg_dir(config_home_str);
|
||||||
|
configdir_str = create_user_dir(home_dir_str, ".config", PROGRAM_NAME);
|
||||||
|
}
|
||||||
|
if(p->user_specified_log_file == false)
|
||||||
|
{
|
||||||
|
create_xdg_dir(cache_home_str);
|
||||||
|
cachedir_str = create_user_dir(home_dir_str, ".cache", PROGRAM_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetSettingsFromParameters(p, ms, configdir_str, cachedir_str);
|
||||||
|
freeparams(p);
|
||||||
|
free(p);
|
||||||
|
|
||||||
|
//char* config_file_str = ( char* ) malloc(1 + strlen(home_dir_str) + strlen("/.config/") + strlen("monocoque/monocoque.config"));
|
||||||
|
|
||||||
size_t diameters_file_sz = snprintf(NULL, 0, "%s/.config/monocoque/diameters.config", home_dir_str);
|
size_t diameters_file_sz = snprintf(NULL, 0, "%s/.config/monocoque/diameters.config", home_dir_str);
|
||||||
diameters_file_sz += 1;
|
diameters_file_sz += 1;
|
||||||
char* diameters_file_str = ( char* ) malloc(diameters_file_sz);
|
char* diameters_file_str = ( char* ) malloc(diameters_file_sz);
|
||||||
snprintf(diameters_file_str, diameters_file_sz, "%s/.config/monocoque/diameters.config", home_dir_str);
|
snprintf(diameters_file_str, diameters_file_sz, "%s/.config/monocoque/diameters.config", home_dir_str);
|
||||||
|
|
||||||
|
|
||||||
char* cache_dir_str = ( char* ) malloc(1 + strlen(home_dir_str) + strlen("/.cache/monocoque/"));
|
|
||||||
strcpy(config_file_str, home_dir_str);
|
|
||||||
strcat(config_file_str, "/.config/");
|
|
||||||
strcpy(cache_dir_str, home_dir_str);
|
|
||||||
strcat(cache_dir_str, "/.cache/monocoque/");
|
|
||||||
strcat(config_file_str, "monocoque/monocoque.config");
|
|
||||||
|
|
||||||
|
|
||||||
slog_config_t slgCfg;
|
slog_config_t slgCfg;
|
||||||
slog_config_get(&slgCfg);
|
slog_config_get(&slgCfg);
|
||||||
slgCfg.eColorFormat = SLOG_COLORING_TAG;
|
slgCfg.eColorFormat = SLOG_COLORING_TAG;
|
||||||
slgCfg.eDateControl = SLOG_TIME_ONLY;
|
slgCfg.eDateControl = SLOG_TIME_ONLY;
|
||||||
strcpy(slgCfg.sFileName, "monocoque.log");
|
strcpy(slgCfg.sFileName, ms->log_filename_str);
|
||||||
strcpy(slgCfg.sFilePath, cache_dir_str);
|
strcpy(slgCfg.sFilePath, ms->log_dirname_str);
|
||||||
slgCfg.nTraceTid = 0;
|
slgCfg.nTraceTid = 0;
|
||||||
slgCfg.nToScreen = 1;
|
slgCfg.nToScreen = 1;
|
||||||
slgCfg.nUseHeap = 0;
|
slgCfg.nUseHeap = 0;
|
||||||
|
|
@ -105,24 +147,22 @@ int main(int argc, char** argv)
|
||||||
ms->configcheck = 0;
|
ms->configcheck = 0;
|
||||||
free(diameters_file_str);
|
free(diameters_file_str);
|
||||||
|
|
||||||
slogi("Loading configuration file: %s", config_file_str);
|
slogi("Loading configuration file: %s", ms->config_str);
|
||||||
slogd("using diameters file %s %i", ms->tyre_diameter_config, ms->configcheck);
|
slogd("using diameters file %s %i", ms->tyre_diameter_config, ms->configcheck);
|
||||||
config_t cfg;
|
config_t cfg;
|
||||||
config_init(&cfg);
|
config_init(&cfg);
|
||||||
config_setting_t* config_devices = NULL;
|
config_setting_t* config_devices = NULL;
|
||||||
if (!config_read_file(&cfg, config_file_str))
|
if (!config_read_file(&cfg, ms->config_str))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s:%d - %s\n", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg));
|
fprintf(stderr, "%s:%d - %s\n", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg));
|
||||||
|
goto cleanup_final;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
slogi("Openend monocoque configuration file");
|
slogi("Openend monocoque configuration file");
|
||||||
config_devices = config_lookup(&cfg, "devices");
|
|
||||||
}
|
}
|
||||||
free(config_file_str);
|
|
||||||
free(cache_dir_str);
|
|
||||||
|
|
||||||
if (p->program_action == A_CONFIG_TACH)
|
if (ms->program_action == A_CONFIG_TACH)
|
||||||
{
|
{
|
||||||
int error = 0;
|
int error = 0;
|
||||||
SimDevice* tachdev = malloc(sizeof(SimDevice));
|
SimDevice* tachdev = malloc(sizeof(SimDevice));
|
||||||
|
|
@ -169,70 +209,25 @@ int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
int configureddevices = config_setting_length(config_devices);
|
|
||||||
int numdevices = 0;
|
|
||||||
DeviceSettings ds[configureddevices];
|
|
||||||
slogi("found %i devices in configuration", configureddevices);
|
|
||||||
int i = 0;
|
|
||||||
error = MONOCOQUE_ERROR_NONE;
|
error = MONOCOQUE_ERROR_NONE;
|
||||||
while (i<configureddevices)
|
|
||||||
{
|
|
||||||
DeviceSettings settings;
|
|
||||||
|
|
||||||
config_setting_t* config_device = config_setting_get_elem(config_devices, i);
|
|
||||||
const char* device_type;
|
|
||||||
const char* device_subtype;
|
|
||||||
const char* device_config_file;
|
|
||||||
config_setting_lookup_string(config_device, "device", &device_type);
|
|
||||||
config_setting_lookup_string(config_device, "type", &device_subtype);
|
|
||||||
config_setting_lookup_string(config_device, "config", &device_config_file);
|
|
||||||
|
|
||||||
//slogt("device type: %s", device_type);
|
|
||||||
//slogt("device sub type: %s", device_subtype);
|
|
||||||
//slogt("device config file: %s", device_config_file);
|
|
||||||
if (error == MONOCOQUE_ERROR_NONE)
|
|
||||||
{
|
|
||||||
error = devsetup(device_type, device_subtype, device_config_file, ms, &settings, config_device);
|
|
||||||
}
|
|
||||||
if (error == MONOCOQUE_ERROR_NONE)
|
|
||||||
{
|
|
||||||
numdevices++;
|
|
||||||
}
|
|
||||||
ds[i] = settings;
|
|
||||||
|
|
||||||
i++;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
int j = 0;
|
|
||||||
error = MONOCOQUE_ERROR_NONE;
|
|
||||||
|
|
||||||
setupsound();
|
setupsound();
|
||||||
|
|
||||||
if (p->program_action == A_PLAY)
|
if (ms->program_action == A_PLAY)
|
||||||
{
|
{
|
||||||
ms->useconfig = 1;
|
ms->useconfig = 1;
|
||||||
}
|
}
|
||||||
SimDevice* devices = malloc(numdevices * sizeof(SimDevice));
|
|
||||||
int initdevices = devinit(devices, configureddevices, ds, ms);
|
|
||||||
bool pulseaudio = false;
|
|
||||||
|
|
||||||
if (p->program_action == A_PLAY)
|
bool pulseaudio = false;
|
||||||
|
if (ms->program_action == A_PLAY)
|
||||||
{
|
{
|
||||||
slogi("running monocoque in gameloop mode..");
|
slogi("running monocoque in gameloop mode..");
|
||||||
//error = strtogame(p->sim_string, ms);
|
|
||||||
//if (error != MONOCOQUE_ERROR_NONE)
|
|
||||||
//{
|
|
||||||
// goto cleanup_final;
|
|
||||||
//}
|
|
||||||
#ifdef USE_PULSEAUDIO
|
#ifdef USE_PULSEAUDIO
|
||||||
pa_threaded_mainloop_unlock(mainloop);
|
pa_threaded_mainloop_unlock(mainloop);
|
||||||
pulseaudio = true;
|
pulseaudio = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
error = looper(devices, numdevices, p);
|
//error = looper(devices, numdevices, p);
|
||||||
|
error = monocoque_mainloop(ms);
|
||||||
if (error == MONOCOQUE_ERROR_NONE)
|
if (error == MONOCOQUE_ERROR_NONE)
|
||||||
{
|
{
|
||||||
slogi("Game loop exited succesfully with error code: %i", error);
|
slogi("Game loop exited succesfully with error code: %i", error);
|
||||||
|
|
@ -252,7 +247,23 @@ int main(int argc, char** argv)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ms->useconfig = 0;
|
ms->useconfig = 0;
|
||||||
error = tester(devices, numdevices);
|
|
||||||
|
int confignum = getconfigtouse(ms->config_str, "default", 0);
|
||||||
|
int configureddevices;
|
||||||
|
configcheck(ms->config_str, confignum, &configureddevices);
|
||||||
|
|
||||||
|
DeviceSettings* ds = malloc(configureddevices * sizeof(DeviceSettings));
|
||||||
|
slogd("loading confignum %i, with %i devices.", confignum, configureddevices);
|
||||||
|
|
||||||
|
int numdevices = uiloadconfig(ms->config_str, confignum, configureddevices, ms, ds);
|
||||||
|
SimDevice* simdevices = malloc(numdevices * sizeof(SimDevice));
|
||||||
|
int initdevices = devinit(simdevices, configureddevices, ds, ms);
|
||||||
|
for( int i = 0; i < configureddevices; i++)
|
||||||
|
{
|
||||||
|
settingsfree(ds[i]);
|
||||||
|
}
|
||||||
|
free(ds);
|
||||||
|
error = tester(simdevices, numdevices);
|
||||||
if (error == MONOCOQUE_ERROR_NONE)
|
if (error == MONOCOQUE_ERROR_NONE)
|
||||||
{
|
{
|
||||||
slogi("Test exited succesfully with error code: %i", error);
|
slogi("Test exited succesfully with error code: %i", error);
|
||||||
|
|
@ -261,35 +272,22 @@ int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
sloge("Test exited with error code: %i", error);
|
sloge("Test exited with error code: %i", error);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
for (int x = 0; x < numdevices; x++)
|
for (int x = 0; x < numdevices; x++)
|
||||||
{
|
{
|
||||||
if (devices[x].initialized == true)
|
if (simdevices[x].initialized == true)
|
||||||
{
|
{
|
||||||
devices[x].free(&devices[x]);
|
simdevices[x].free(&simdevices[x]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(pulseaudio == true)
|
if(pulseaudio == true)
|
||||||
{
|
{
|
||||||
freesound();
|
freesound();
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 0;
|
|
||||||
// improve the api around the config helper
|
|
||||||
// i don't like that i stack allocated but hid a malloc inside
|
|
||||||
for( i = 0; i < configureddevices; i++)
|
|
||||||
{
|
|
||||||
settingsfree(ds[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
configcleanup:
|
|
||||||
config_destroy(&cfg);
|
|
||||||
|
|
||||||
cleanup_final:
|
cleanup_final:
|
||||||
|
|
||||||
if(ms->tyre_diameter_config != NULL)
|
if(ms->tyre_diameter_config != NULL)
|
||||||
|
|
@ -297,7 +295,6 @@ cleanup_final:
|
||||||
free(ms->tyre_diameter_config);
|
free(ms->tyre_diameter_config);
|
||||||
}
|
}
|
||||||
free(ms);
|
free(ms);
|
||||||
free(p);
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue