From dd93098f39649d883f5e24418f0ebb25c1175aaf Mon Sep 17 00:00:00 2001 From: Paul Dino Jones Date: Tue, 18 Aug 2026 16:39:24 -0400 Subject: [PATCH] added gui code --- .valgrindrc | 10 + CMakeLists.txt | 2 +- src/monocoque/devices/serialdevice.c | 17 +- src/monocoque/devices/sounddevice.c | 6 +- src/monocoque/gameloop/gameloop.c | 279 +++++++++++-- src/monocoque/gameloop/gameloop.h | 15 +- src/monocoque/gameloop/loopdata.h | 8 + src/monocoque/helper/confighelper.c | 561 ++++++++++++++++++++++++- src/monocoque/helper/confighelper.h | 71 ++-- src/monocoque/mgui/CMakeLists.txt | 12 +- src/monocoque/mgui/addeditaction.c | 604 +++++++++++++++++++++++++++ src/monocoque/mgui/addeditaction.h | 97 +++++ src/monocoque/mgui/mainwindow.h | 42 ++ src/monocoque/mgui/testaction.c | 188 +++++++++ src/monocoque/mgui/testaction.h | 44 ++ src/monocoque/mgui/uiconfighelper.c | 311 ++++++++++++++ src/monocoque/mgui/uiconfighelper.h | 14 + src/monocoque/monocoque-gui.c | 506 ++++++++++++++-------- 18 files changed, 2512 insertions(+), 275 deletions(-) create mode 100644 src/monocoque/mgui/addeditaction.c create mode 100644 src/monocoque/mgui/addeditaction.h create mode 100644 src/monocoque/mgui/mainwindow.h create mode 100644 src/monocoque/mgui/testaction.c create mode 100644 src/monocoque/mgui/testaction.h create mode 100644 src/monocoque/mgui/uiconfighelper.c create mode 100644 src/monocoque/mgui/uiconfighelper.h diff --git a/.valgrindrc b/.valgrindrc index 832b9fa..b23a2ac 100644 --- a/.valgrindrc +++ b/.valgrindrc @@ -120,3 +120,13 @@ ... obj:*/lib*/lib*.so.* } +{ + nappgui_gbind_uninitialized + Memcheck:Cond + fun:_gbind_update_control +} +{ + gtk_pango_uninitialized + Memcheck:Cond + fun:_pango_is_Vowel_Dependent +} diff --git a/CMakeLists.txt b/CMakeLists.txt index d44adcc..851a5b5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -186,7 +186,7 @@ else() # GCC/Clang warning option if(analyze) message("-- Analyzer is on") - target_compile_options(monocoque PRIVATE -fanalyzer -Wno-analyzer-possible-null-argument -Wno-analyzer-possible-null-dereference) + target_compile_options(monocoque PRIVATE -fanalyzer -Wno-analyzer-possible-null-argument -Wno-analyzer-possible-null-dereference -fsanitize=address -g -fno-omit-frame-pointer) endif() enable_cxx_compiler_flag_if_supported("-Wall") diff --git a/src/monocoque/devices/serialdevice.c b/src/monocoque/devices/serialdevice.c index 4731ecb..55f706b 100644 --- a/src/monocoque/devices/serialdevice.c +++ b/src/monocoque/devices/serialdevice.c @@ -61,7 +61,6 @@ int arduino_custom_updater(SimDevice* this, SimData* simdata) int arduino_customled_updater(SimDevice* this, SimData* simdata) { SerialDevice* serialdevice = (void *) this->derived; - arduino_customled_update(serialdevice, simdata); return 0; @@ -233,7 +232,7 @@ int serial_wheel_free(SimDevice* this) int serialdev_init(SerialDevice* serialdevice, DeviceSettings* ds, SimInfo* siminfo) { - slogi("initializing serial device on port %s to %i...", ds->serialdevsettings.portdev, ds->serialdevsettings.baud); + slogi("initializing serial device on port %s to %i...", ds->dev, ds->serialdevsettings.baud); int error = 0; @@ -246,17 +245,17 @@ int serialdev_init(SerialDevice* serialdevice, DeviceSettings* ds, SimInfo* simi // the wheel stuff assumed it was a usb //error = wheeldev_init(&serialdevice->u.wheeldevice, ds); // maybe this call a more generic serial wheel init first - error = moza_init(serialdevice, ds->serialdevsettings.portdev); + error = moza_init(serialdevice, ds->dev); break; case SERIALDEV__MOZA_NEW: - error = moza_new_init(serialdevice, ds->serialdevsettings.portdev); + error = moza_new_init(serialdevice, ds->dev); break; case SERIALDEV__MOZA_KS_PRO_WHEEL: - error = moza_ks_pro_wheel_init(serialdevice, ds->serialdevsettings.portdev); + error = moza_ks_pro_wheel_init(serialdevice, ds->dev); break; case ARDUINODEV__SIMLED__CUSTOM: serialdevice->m.device_specific_config_file = strdup(ds->specific_config_file); - error = arduino_custom_init(serialdevice, ds->serialdevsettings.portdev, serialdevice->m.device_specific_config_file, true); + error = arduino_custom_init(serialdevice, ds->dev, serialdevice->m.device_specific_config_file, true); if(error < 0) { free(serialdevice->m.device_specific_config_file); @@ -264,17 +263,17 @@ int serialdev_init(SerialDevice* serialdevice, DeviceSettings* ds, SimInfo* simi break; case ARDUINODEV__CUSTOM: serialdevice->m.device_specific_config_file = strdup(ds->specific_config_file); - error = arduino_custom_init(serialdevice, ds->serialdevsettings.portdev, serialdevice->m.device_specific_config_file, false); + error = arduino_custom_init(serialdevice, ds->dev, serialdevice->m.device_specific_config_file, false); if(error < 0) { free(serialdevice->m.device_specific_config_file); } break; case ARDUINODEV__SIMLED: - error = arduino_custom_init(serialdevice, ds->serialdevsettings.portdev, NULL, false); + error = arduino_custom_init(serialdevice, ds->dev, NULL, false); break; default: - error = arduino_init(serialdevice, ds->serialdevsettings.portdev); + error = arduino_init(serialdevice, ds->dev); break; } diff --git a/src/monocoque/devices/sounddevice.c b/src/monocoque/devices/sounddevice.c index 06872da..9210178 100644 --- a/src/monocoque/devices/sounddevice.c +++ b/src/monocoque/devices/sounddevice.c @@ -189,7 +189,7 @@ int sounddev_init(SoundDevice* sounddevice, const char* devname, SoundDeviceSett switch (sounddevice->m.hapticeffect.effecttype) { case (EFFECT_GEARSHIFT): sounddevice->sounddata.last_gear = 0; - sounddevice->sounddata.duration = sds.duration; + sounddevice->sounddata.duration = 0.125; streamname = "Gear"; break; case (EFFECT_TYRESLIP): @@ -283,8 +283,8 @@ SoundDevice* new_sound_device(DeviceSettings* ds, MonocoqueSettings* ms, SimInfo if(error == 0) { - slogt("Attempting to use sound device %s", ds->sounddevsettings.dev); - error = sounddev_init(this, ds->sounddevsettings.dev, ds->sounddevsettings); + slogt("Attempting to use sound device %s", ds->dev); + error = sounddev_init(this, ds->dev, ds->sounddevsettings); } if (error != 0) diff --git a/src/monocoque/gameloop/gameloop.c b/src/monocoque/gameloop/gameloop.c index 4cc046c..d3fb346 100644 --- a/src/monocoque/gameloop/gameloop.c +++ b/src/monocoque/gameloop/gameloop.c @@ -23,17 +23,24 @@ bool go = false; bool go2 = false; struct sigaction act; +static pthread_t loop_thread; +static uv_loop_t *loop = NULL; SimData* simdata; SimMap* simmap; loop_data* baton; +device_loop_data* test_baton; +SimDevice* test_simdevice; +SimInfo* test_siminfo; + uv_idle_t idler; uv_timer_t datachecktimer; uv_timer_t showstatstimer; uv_timer_t datamaptimer; uv_timer_t tyrediametertimer; +uv_timer_t testdevicetimer; uv_udp_t recv_socket; bool doui = false; @@ -358,7 +365,7 @@ void looprun(MonocoqueSettings* ms, loop_data* f, SimData* simdata) } - uv_timer_start(&showstatstimer, showstatscallback, 0, 100); + //uv_timer_start(&showstatstimer, showstatscallback, 0, 100); doui = false; } } @@ -632,18 +639,20 @@ void cb(uv_poll_t* handle, int status, int events) } -int monocoque_mainloop_start(MonocoqueSettings* ms) -{ +void* monocoque_mainloop_start(void* arg) +{ + MonocoqueSettings* ms = arg; simdata = malloc(sizeof(SimData)); simmap = simapi_simmap_create(); + slogd("setting initial app state"); + appstate = 1; - char ch; - struct pollfd mypoll = { STDIN_FILENO, POLLIN|POLLPRI }; - - uv_poll_t* poll = (uv_poll_t*) malloc(uv_handle_size(UV_POLL)); + //struct pollfd mypoll = { STDIN_FILENO, POLLIN|POLLPRI }; + //uv_poll_t* poll = (uv_poll_t*) malloc(uv_handle_size(UV_POLL)); baton = (loop_data*) malloc(sizeof(loop_data)); + baton->siminfo.mapapi = -1; baton->simmap = simmap; baton->simdata = simdata; baton->ms = ms; @@ -652,37 +661,109 @@ int monocoque_mainloop_start(MonocoqueSettings* ms) baton->use_udp = false; baton->req.data = (void*) baton; + simapi_set_log_info(simapilib_loginfo); simapi_set_log_debug(simapilib_logdebug); simapi_set_log_trace(simapilib_logtrace); - if (0 != uv_poll_init(uv_default_loop(), poll, 0)) - { - return 1; - }; - - uv_udp_init(uv_default_loop(), &recv_socket); - uv_timer_init(uv_default_loop(), &datachecktimer); - uv_timer_init(uv_default_loop(), &showstatstimer); - uv_timer_init(uv_default_loop(), &datamaptimer); - uv_timer_init(uv_default_loop(), &tyrediametertimer); - slogd("setting initial app state"); - appstate = 1; + //if (0 != uv_poll_init(uv_default_loop(), poll, 0)) + //{ + // return NULL; + //}; + + uv_udp_init(loop, &recv_socket); + uv_timer_init(loop, &datachecktimer); + uv_timer_init(loop, &datamaptimer); + uv_timer_init(loop, &tyrediametertimer); + + 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*) &showstatstimer, (void*) baton); + //uv_handle_set_data((uv_handle_t*) &showstatstimer, (void*) baton); uv_handle_set_data((uv_handle_t*) &recv_socket, (void*) baton); - uv_handle_set_data((uv_handle_t*) poll, (void*) baton); + //} + //uv_handle_set_data((uv_handle_t*) poll, (void*) baton); + + //if (0 != uv_poll_start(poll, UV_READABLE, cb)) + //{ + // return NULL; + //}; - if (0 != uv_poll_start(poll, UV_READABLE, cb)) - { - return 2; - }; uv_timer_start(&datachecktimer, datacheckcallback, 1000, 1000); - fprintf(stdout, "Searching for sim data... Press q to quit...\n"); - uv_run(uv_default_loop(), UV_RUN_NOWAIT); + //fprintf(stdout, "Searching for sim data... Press q to quit...\n"); + uv_run(loop, UV_RUN_DEFAULT); + + return NULL; +} + +SimData* get_test_simdata() +{ + if(test_baton == NULL) + { + return NULL; + } + return test_baton->simdata; +} + +void* monocoque_testloop_start(void* arg) +{ + test_loop_args* args = arg; + simmap = simapi_simmap_create(); + + + simapi_set_log_info(simapilib_loginfo); + simapi_set_log_debug(simapilib_logdebug); + simapi_set_log_trace(simapilib_logtrace); + + + DeviceSettings ds; + //int numdevices = getsingledevice(args->ms->config_str, args->confignum, args->devicenum, args->ms, &ds); + test_simdevice = malloc(1 * sizeof(SimDevice)); + test_siminfo = malloc(sizeof(SimInfo)); + simapi_set_faux_siminfo(test_siminfo); + int initdevices = devinit(test_simdevice, test_siminfo, 1, args->ds, args->ms); + //settingsfree(ds); + + + + test_baton->siminfo.mapapi = -1; + test_baton->simdevice = test_simdevice; + + test_baton->ms = args->ms; + test_baton->req.data = (void*) test_baton; + + + uv_timer_init(loop, &testdevicetimer); + uv_handle_set_data((uv_handle_t*) &testdevicetimer, (void*) test_baton); + uv_timer_start(&testdevicetimer, devicetimercallback, 1000, 16); + + uv_run(loop, UV_RUN_DEFAULT); + + + return NULL; +} + +int monocoque_testloop_stop() +{ + uv_timer_stop(&testdevicetimer); + + uv_stop(loop); + pthread_join(loop_thread, NULL); + + uv_run(loop, UV_RUN_NOWAIT); + uv_walk(loop, close_walk_cb, NULL); + uv_loop_close(loop); + uv_library_shutdown(); + + slogi("All threads stopped..."); + + test_simdevice->free(test_simdevice); + free(loop); + free(test_baton); + //free(simdata); + free(simmap); return 0; } @@ -690,20 +771,104 @@ int monocoque_mainloop_start(MonocoqueSettings* ms) int monocoque_mainloop_stop(MonocoqueSettings* ms) { - uv_stop(uv_default_loop()); - //uv_walk(uv_default_loop(), close_walk_cb, NULL); - uv_loop_close(uv_default_loop()); + uv_udp_recv_stop(&recv_socket); + uv_timer_stop(&datamaptimer); + uv_timer_stop(&datachecktimer); + + uv_stop(loop); + pthread_join(loop_thread, NULL); + + uv_run(loop, UV_RUN_NOWAIT); + uv_walk(loop, close_walk_cb, NULL); + uv_loop_close(loop); uv_library_shutdown(); + slogi("All threads stopped..."); - + free(loop); free(baton); free(simdata); free(simmap); + appstate = 0; return 0; } + +int start_loop(MonocoqueSettings* ms) +{ + loop = malloc(sizeof(uv_loop_t)); + + if (loop == NULL) + { + return -1; + } + + if (uv_loop_init(loop) != 0) + { + free(loop); + loop = NULL; + return -1; + } + return pthread_create(&loop_thread, NULL, monocoque_mainloop_start, ms); +} + +int start_test(test_loop_args* test_data) +{ + + test_baton = (device_loop_data*) malloc(sizeof(device_loop_data)); + test_baton->simdata = test_data->simdata; + + loop = malloc(sizeof(uv_loop_t)); + + if (loop == NULL) + { + return -1; + } + + if (uv_loop_init(loop) != 0) + { + free(loop); + loop = NULL; + return -1; + } + return pthread_create(&loop_thread, NULL, monocoque_testloop_start, test_data); +} + +const char* get_simexe_name(void) +{ + if(appstate <= 0) + { + return "None Detected"; + } + if(baton == NULL) + { + return "None Detected"; + } + if(baton->siminfo.simulatorexe <= 0) + { + return "None Detected"; + } + return simapi_gametofullstr(baton->siminfo.simulatorexe); +} + +const char* get_simd_onoff(void) +{ + if(appstate <= 0) + { + return "Not Detected"; + } + if(baton == NULL) + { + return "Not Detected"; + } + if(baton->siminfo.mapapi == 0) + { + return "Running"; + } + return "Not Detected"; +} + int monocoque_mainloop(MonocoqueSettings* ms) { @@ -781,6 +946,58 @@ int monocoque_mainloop(MonocoqueSettings* ms) return 0; } +void set_basic_simdata(SimData* simdata) +{ + simdata->car[0] = 'C'; + simdata->car[1] = 'A'; + simdata->car[2] = 'R'; + simdata->car[3] = '\0'; + simdata->gear = SIMAPI_GEAR_NEUTRAL; + simdata->gearc[0] = 0x4e; + simdata->gearc[1] = 0; + simdata->velocity = 160; + simdata->rpms = 7000; + simdata->maxrpm = 8000; + simdata->abs = 0; + simdata->tyrediameter[0] = -1; + simdata->tyrediameter[1] = -1; + simdata->tyrediameter[2] = -1; + simdata->tyrediameter[3] = -1; + simdata->tyreslipratio[0] = 0; + simdata->tyreslipratio[1] = 0; + simdata->tyreslipratio[2] = 0; + simdata->tyreslipratio[3] = 0; + simdata->Xvelocity = 0; + simdata->Yvelocity = 100; + simdata->Zvelocity = 0; +} + +void set_wheel_spin_simdata(SimData* simdata) +{ + simdata->velocity = 15; + simdata->tyreRPS[0] = 50; + simdata->tyreRPS[1] = 50; + simdata->tyreRPS[2] = 50; + simdata->tyreRPS[3] = 50; + simdata->tyrediameter[0] = 0.638636385206394; + simdata->tyrediameter[1] = 0.633384434597093; + simdata->tyrediameter[2] = 0.710475735564615; + simdata->tyrediameter[3] = 0.710475735564615; +} + +void set_wheel_lock_simdata(SimData* simdata) +{ + simdata->velocity = 150; + simdata->tyreRPS[0] = 25; + simdata->tyreRPS[1] = 25; + simdata->tyreRPS[2] = 25; + simdata->tyreRPS[3] = 25; + simdata->tyrediameter[0] = 0.638636385206394; + simdata->tyrediameter[1] = 0.633384434597093; + simdata->tyrediameter[2] = 0.710475735564615; + simdata->tyrediameter[3] = 0.710475735564615; +} + int tester(SimDevice* devices, int numdevices) { diff --git a/src/monocoque/gameloop/gameloop.h b/src/monocoque/gameloop/gameloop.h index 551520d..d5618f4 100644 --- a/src/monocoque/gameloop/gameloop.h +++ b/src/monocoque/gameloop/gameloop.h @@ -1,5 +1,6 @@ #include "../devices/simdevice.h" #include "../helper/parameters.h" +#include "loopdata.h" extern int appstate; @@ -7,5 +8,17 @@ int tester(SimDevice* devices, int numdevices); int looper(SimDevice* devices, int numdevices, Parameters* p); int monocoque_mainloop(MonocoqueSettings* ms); -int monocoque_mainloop_start(MonocoqueSettings* ms); + +int start_loop(MonocoqueSettings* ms); +int start_test(test_loop_args* test_loop_data); int monocoque_mainloop_stop(MonocoqueSettings* ms); +int monocoque_testloop_stop(); + +const char* get_simd_onoff(void); +const char* get_simexe_name(void); +SimData* get_test_simdata(); + + +void set_basic_simdata(SimData* simdata); +void set_wheel_spin_simdata(SimData* simdata); +void set_wheel_lock_simdata(SimData* simdata); diff --git a/src/monocoque/gameloop/loopdata.h b/src/monocoque/gameloop/loopdata.h index 801f2de..0a5f7bb 100644 --- a/src/monocoque/gameloop/loopdata.h +++ b/src/monocoque/gameloop/loopdata.h @@ -40,5 +40,13 @@ typedef struct loop_data } loop_data; +typedef struct test_loop_args +{ + MonocoqueSettings* ms; + DeviceSettings* ds; + SimData* simdata; + int devicenum; + int confignum; +} test_loop_args; #endif diff --git a/src/monocoque/helper/confighelper.c b/src/monocoque/helper/confighelper.c index f54eab1..97d3829 100644 --- a/src/monocoque/helper/confighelper.c +++ b/src/monocoque/helper/confighelper.c @@ -143,6 +143,11 @@ int strtodevsubsubtype(const char* device_subsubtype, DeviceSettings* ds) ds->dev_subsubtype = SIMDEVSUBTYPE_SIMAGICGTNEO; devfound = true; } + if (strcicmp(device_subsubtype, "REVBURNER") == 0) + { + ds->dev_subsubtype = SIMDEVSUBTYPE_REVBURNERTACHOMETER; + devfound = true; + } if(devfound == false) { @@ -679,6 +684,25 @@ int configcheck(const char* config_file_str, int confignum, int* devices) return 0; //return cfg; } +static int config_get_device(const config_setting_t *entry, DeviceSettings *ds) +{ + const char *value = NULL; + + if (config_setting_lookup_string(entry, "devid", &value)) + { + ds->dev = strdup(value); + return ds->dev != NULL; + } + + if (config_setting_lookup_string(entry, "devpath", &value)) + { + ds->dev = strdup(value); + return ds->dev != NULL; + } + + ds->dev = NULL; + return 0; +} int devsetup(const char* device_type, const char* device_subtype, const char* config_file, MonocoqueSettings* ms, DeviceSettings* ds, config_setting_t* device_settings) { @@ -705,6 +729,7 @@ int devsetup(const char* device_type, const char* device_subtype, const char* co ds->fps = 60; config_setting_lookup_int(device_settings, "fps", &ds->fps); + config_get_device(device_settings, ds); if (ds->dev_subtype == SIMDEVTYPE_TACHOMETER) { @@ -742,16 +767,13 @@ int devsetup(const char* device_type, const char* device_subtype, const char* co { if (device_settings != NULL) { - const char* temp; + const char* temp = NULL; int found = config_setting_lookup_string(device_settings, "subtype", &temp); if(temp != NULL && found > 0) { - strtodevsubsubtype(temp, ds); + strtodevsubsubtype(temp, ds); } - config_setting_lookup_string(device_settings, "devpath", &temp); - ds->serialdevsettings.portdev = strdup(temp); - int motorposition = 8; config_setting_lookup_int(device_settings, "motors", &motorposition); ds->serialdevsettings.motorsposition = motorposition; @@ -791,6 +813,7 @@ int devsetup(const char* device_type, const char* device_subtype, const char* co } + ds->has_haptic_effects = false; if (ds->dev_subtype == SIMDEVTYPE_USBHAPTIC || ds->dev_subtype == SIMDEVTYPE_USBWHEEL || ds->dev_type == SIMDEV_SOUND || ds->dev_subtype == SIMDEVTYPE_SERIALHAPTIC) { slogt("analysing haptic effect settings"); @@ -801,8 +824,8 @@ int devsetup(const char* device_type, const char* device_subtype, const char* co if (ds->hapticsettings.effect_type == EFFECT_TYRESLIP || ds->hapticsettings.effect_type == EFFECT_TYRELOCK || ds->hapticsettings.effect_type == EFFECT_ABSBRAKES || ds->hapticsettings.effect_type == EFFECT_SUSPENSION ) { gettyre(device_settings, ds); - ds->threshold = 0; - int found = config_setting_lookup_float(device_settings, "threshold", &ds->threshold); + ds->hapticsettings.threshold = 0; + int found = config_setting_lookup_float(device_settings, "threshold", &ds->hapticsettings.threshold); } slogi("reading configured haptic effect settings"); @@ -810,19 +833,16 @@ int devsetup(const char* device_type, const char* device_subtype, const char* co ds->hapticsettings.frequencyMax = 0; ds->hapticsettings.amplitude = 50; ds->hapticsettings.amplitudeMax = 50; - ds->hapticsettings.volume = 0; if (ds->hapticsettings.effect_type == EFFECT_GEARSHIFT) { ds->hapticsettings.duration = .125; } if (device_settings != NULL) { - - config_setting_lookup_int(device_settings, "volume", &ds->hapticsettings.volume); config_setting_lookup_int(device_settings, "frequency", &ds->hapticsettings.frequency); config_setting_lookup_int(device_settings, "frequencyMax", &ds->hapticsettings.frequencyMax); config_setting_lookup_int(device_settings, "amplitude", &ds->hapticsettings.amplitude); - config_setting_lookup_float(device_settings, "duration", &ds->sounddevsettings.duration); + config_setting_lookup_float(device_settings, "duration", &ds->hapticsettings.duration); config_setting_lookup_int(device_settings, "amplitudeMax", &ds->hapticsettings.amplitudeMax); const char* temp = NULL; @@ -876,7 +896,7 @@ int devsetup(const char* device_type, const char* device_subtype, const char* co ds->sounddevsettings.noise = 0; if (ds->hapticsettings.effect_type == EFFECT_GEARSHIFT) { - ds->sounddevsettings.duration = .125; + ds->hapticsettings.duration = .125; } if (device_settings != NULL) { @@ -891,13 +911,13 @@ int devsetup(const char* device_type, const char* device_subtype, const char* co found = config_setting_lookup_string(device_settings, "devid", &temp); if (found == CONFIG_FALSE) { - ds->sounddevsettings.dev = NULL; + ds->dev = NULL; } else { if(temp != NULL) { - ds->sounddevsettings.dev = strdup(temp); + ds->dev = strdup(temp); } } @@ -979,21 +999,516 @@ int uiloadconfig(const char* config_file_str, int confignum, int configureddevic return numdevices; } -int settingsfree(DeviceSettings ds) +int getsingledevice(const char* config_file_str, int confignum, int devicenum, MonocoqueSettings* ms, DeviceSettings* ds) { - if (ds.dev_type == SIMDEV_SERIAL) + int numdevices = 0; + config_t cfg; + config_init(&cfg); + if (!config_read_file(&cfg, config_file_str)) { - if (ds.serialdevsettings.portdev != NULL) + 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 num_devices = config_setting_length(config_devices); + + int i = 0; + + int error = MONOCOQUE_ERROR_NONE; + while (i= config_setting_length(devices)) + return -1; + + if (!config_setting_remove_elem(devices, devicenum)) + return -1; + + if (!config_write_file(cfg, configfile)) + return -1; + + return 0; +} + +static const char *device_type_to_string(DeviceType device_type) +{ + switch (device_type) + { + case SIMDEV_USB: + return "USB"; + case SIMDEV_SOUND: + return "Sound"; + case SIMDEV_SERIAL: + return "Serial"; + case SIMDEV_UNKNOWN: + return "Unknown"; + default: + return "Unknown"; + } +} + +static const char *device_subtype_to_string(DeviceSubType device_subtype) +{ + switch (device_subtype) + { + case SIMDEVTYPE_SOUNDHAPTIC: + return "SoundHaptic"; + case SIMDEVTYPE_TACHOMETER: + return "Tachometer"; + case SIMDEVTYPE_USBHAPTIC: + return "UsbHaptic"; + case SIMDEVTYPE_USBWHEEL: + return "UsbWheel"; + case SIMDEVTYPE_SHIFTLIGHTS: + return "ShiftLights"; + case SIMDEVTYPE_SIMWIND: + return "SimWind"; + case SIMDEVTYPE_SERIALHAPTIC: + return "SerialHaptic"; + case SIMDEVTYPE_SERIALWHEEL: + return "Wheel"; + case SIMDEVTYPE_SIMLED: + return "Simleds"; + case SIMDEVTYPE_ARDUINOCUSTOM: + return "ArduinoCustom"; + case SIMDEVTYPE_UNKNOWN: + default: + return "Unknown"; + } +} + +static const char *haptic_effect_to_string(VibrationEffectType effect) +{ + switch (effect) + { + case EFFECT_ENGINERPM: + return "Engine"; + case EFFECT_GEARSHIFT: + return "Gear"; + case EFFECT_ABSBRAKES: + return "ABS"; + case EFFECT_TYRESLIP: + return "TyreSlip"; + case EFFECT_TYRELOCK: + return "TyreLock"; + case EFFECT_SUSPENSION: + return "Suspension"; + default: + return "Unknown"; + } +} + +static const char *modulation_to_string(EffectModulationType modulation) +{ + switch (modulation) + { + case EFFECT_MODULATION_NONE: + return "None"; + case EFFECT_MODULATION_FREQUENCY: + return "Frequency"; + case EFFECT_MODULATION_AMPLIFY: + return "Amplitude"; + default: + return "Unknown"; + } +} + +static const char *tyre_to_string(MonocoqueTyreIdentifier tyre) +{ + switch (tyre) + { + case FRONTLEFT: + return "FrontLeft"; + case FRONTRIGHT: + return "FrontRight"; + case REARLEFT: + return "RearLeft"; + case REARRIGHT: + return "RearRight"; + case FRONTS: + return "Fronts"; + case REARS: + return "Rears"; + case ALLFOUR: + return "All"; + default: + return "Unknown"; + } +} + +int save_device_config(config_t *cfg, const char* configfile, int confignum, int devicenum, const DeviceSettings *ds) +{ + config_setting_t *configs; + config_setting_t *config_entry; + config_setting_t *devices; + config_setting_t *device_entry; + + if (cfg == NULL || ds == NULL) + return 0; + + slogd("Saving device with device num %i and confignum %i", devicenum, confignum); + configs = config_lookup(cfg, "configs"); + if (configs == NULL) + return 0; + + config_entry = config_setting_get_elem(configs, confignum); + if (config_entry == NULL) + return 0; + + devices = config_setting_lookup(config_entry, "devices"); + if (devices == NULL) + return 0; + + device_entry = config_setting_get_elem(devices, devicenum); + if (device_entry == NULL) + { + device_entry = config_setting_add(devices, NULL, CONFIG_TYPE_GROUP); + + if (device_entry == NULL) + return 0; + + if (config_setting_index(device_entry) != devicenum) + return 0; + } + if (device_entry == NULL) + return 0; + + set_string(device_entry, "device", device_type_to_string(ds->dev_type)); + + set_int(device_entry, "fps", ds->fps); + + if (ds->specific_config_file != NULL) + { + set_string(device_entry, "config", ds->specific_config_file); + } + if (ds->dev != NULL) + { + set_string(device_entry, "devid", ds->dev); + } + + switch (ds->dev_type) + { + + case SIMDEV_SERIAL: { - free(ds.sounddevsettings.dev); + set_string(device_entry, "type", device_subtype_to_string(ds->dev_type + SerialDevicesOffset)); + + const SerialDeviceSettings *ss = &ds->serialdevsettings; + + set_int(device_entry, "baud", ss->baud); + + set_float(device_entry, "ampfactor", ss->ampfactor); + + set_float(device_entry, "fanpower", ss->fanpower); + + break; } + + case SIMDEV_SOUND: + { + set_string(device_entry, "type", device_subtype_to_string(ds->dev_type)); + + const SoundDeviceSettings *ss = &ds->sounddevsettings; + + set_int(device_entry, "volume", ss->volume); + set_int(device_entry, "pan", ss->pan); + set_int(device_entry, "channels", ss->channels); + set_int(device_entry, "noise", ss->noise); + + break; + } + + case SIMDEV_USB: + { + set_string(device_entry, "type", device_subtype_to_string(ds->dev_type + USBDevicesOffset)); + + const USBDeviceSettings *us = &ds->usbdevsettings; + + break; + } + + default: + break; + } + + if(ds->has_haptic_effects == true) + { + slogt("Saving haptic effect settings"); + const HapticEffectSettings *hs = &ds->hapticsettings; + + set_int(device_entry, "frequency", hs->frequency); + + set_int(device_entry, "amplitude", hs->amplitude); + + set_int(device_entry, "frequencyMax", hs->frequencyMax); + + set_int(device_entry, "amplitudeMax", hs->amplitudeMax); + + set_float(device_entry, "threshold", hs->threshold); + + set_float(device_entry, "duration", hs->duration); + + set_string(device_entry, "effect", haptic_effect_to_string(hs->effect_type)); + + set_string(device_entry, "tyre", tyre_to_string(hs->tyre)); + + set_string(device_entry, "modulation", modulation_to_string(hs->modulation)); + } + + if(ds->has_led_effects == true) + { + slogt("Saving led effect settings"); + const SerialDeviceSettings *ss = &ds->serialdevsettings; + + set_int(device_entry, "numleds", ss->numleds); + set_int(device_entry, "startled", ss->startled); + set_int(device_entry, "endled", ss->endled); + } + + if(!config_write_file(cfg, configfile)) + { + return 1; + } + return 0; +} + +config_t *open_monocoque_config(const char *filename) +{ + config_t *cfg; + + if (filename == NULL) + return NULL; + + cfg = malloc(sizeof(*cfg)); + if (cfg == NULL) + return NULL; + + config_init(cfg); + + if (!config_read_file(cfg, filename)) + { + fprintf(stderr, + "Failed to read config file '%s' (line %d): %s\n", + filename, + config_error_line(cfg), + config_error_text(cfg)); + + config_destroy(cfg); + free(cfg); + + return NULL; + } + + return cfg; +} + +void close_monocoque_config(config_t* cfg) +{ + if (cfg == NULL) + return; + + config_destroy(cfg); +} + +int settingsfree(DeviceSettings ds) +{ + if (ds.dev != NULL) + { + free(ds.dev); } if(ds.has_config && ds.specific_config_file != NULL) @@ -1009,17 +1524,21 @@ int monocoquesettingsfree(MonocoqueSettings* ms) if(ms->tyre_diameter_config != NULL) { free(ms->tyre_diameter_config); + ms->tyre_diameter_config = NULL; } if(ms->config_str != NULL) { free(ms->config_str); + ms->config_str = NULL; } if(ms->log_filename_str != NULL) { free(ms->log_filename_str); + ms->log_filename_str = NULL; } if(ms->log_dirname_str != NULL) { free(ms->log_dirname_str); + ms->log_dirname_str = NULL; } } diff --git a/src/monocoque/helper/confighelper.h b/src/monocoque/helper/confighelper.h index 1496ab4..5d664c3 100644 --- a/src/monocoque/helper/confighelper.h +++ b/src/monocoque/helper/confighelper.h @@ -13,28 +13,32 @@ typedef enum { - SIMDEV_UNKNOWN = 0, - SIMDEV_USB = 1, - SIMDEV_SOUND = 2, - SIMDEV_SERIAL = 3 + SIMDEV_USB = 0, + SIMDEV_SOUND = 1, + SIMDEV_SERIAL = 2, + SIMDEV_UNKNOWN = 3, } DeviceType; typedef enum { SIMDEVTYPE_UNKNOWN = 0, - SIMDEVTYPE_TACHOMETER = 1, - SIMDEVTYPE_USBHAPTIC = 2, - SIMDEVTYPE_SHIFTLIGHTS = 3, - SIMDEVTYPE_SIMWIND = 4, - SIMDEVTYPE_SERIALHAPTIC = 5, - SIMDEVTYPE_USBWHEEL = 6, - SIMDEVTYPE_SERIALWHEEL = 7, - SIMDEVTYPE_SIMLED = 8, - SIMDEVTYPE_ARDUINOCUSTOM = 9 + SIMDEVTYPE_SOUNDHAPTIC = 1, + SIMDEVTYPE_TACHOMETER = 2, + SIMDEVTYPE_USBHAPTIC = 3, + SIMDEVTYPE_USBWHEEL = 4, + SIMDEVTYPE_SHIFTLIGHTS = 5, + SIMDEVTYPE_SIMWIND = 6, + SIMDEVTYPE_SERIALHAPTIC = 7, + SIMDEVTYPE_SERIALWHEEL = 8, + SIMDEVTYPE_SIMLED = 9, + SIMDEVTYPE_ARDUINOCUSTOM = 10, } DeviceSubType; +#define SerialDevicesOffset 5 +#define USBDevicesOffset 2 + typedef enum { SIMDEVSUBTYPE_UNKNOWN = 0, @@ -47,7 +51,8 @@ typedef enum SIMDEVSUBTYPE_MOZA_NEW = 7, SIMDEVSUBTYPE_LOGITECH_G29 = 8, SIMDEVSUBTYPE_MOZA_KS_PRO_WHEEL = 9, - SIMDEVSUBTYPE_SIMNETPEDALS = 10 + SIMDEVSUBTYPE_SIMNETPEDALS = 10, + SIMDEVSUBTYPE_REVBURNERTACHOMETER = 11 } DeviceSubSubType; @@ -155,6 +160,7 @@ typedef struct char* config_str; char* log_filename_str; char* log_dirname_str; + config_t* cfg; } MonocoqueSettings; @@ -170,27 +176,24 @@ TachometerSettings; typedef struct { - char* portdev; - MotorPosition motorsposition; - int numlights; - int numleds; - int startled; - int endled; + uint32_t numlights; + uint32_t numleds; + uint32_t startled; + uint32_t endled; float ampfactor; float fanpower; - int baud; + // baud is the only serial thing + uint32_t baud; } SerialDeviceSettings; typedef struct { uint32_t volume; - int pan; - int channels; - double duration; - char* dev; - int noise; + uint32_t pan; + uint32_t channels; + uint32_t noise; } SoundDeviceSettings; @@ -198,7 +201,6 @@ typedef struct { uint32_t frequency; uint32_t amplitude; - uint32_t volume; uint32_t frequencyMax; uint32_t amplitudeMax; @@ -221,17 +223,17 @@ USBDeviceSettings; typedef struct { bool is_valid; - int fps; + DeviceType dev_type; DeviceSubType dev_subtype; DeviceSubSubType dev_subsubtype; bool has_haptic_effects; - // to get really fancy move the effect information to it's own structure that would be a member of - // any device settings member structure that can carry an effect + bool has_led_effects; - double threshold; + char* dev; bool has_config; char* specific_config_file; + uint32_t fps; // union? HapticEffectSettings hapticsettings; TachometerSettings tachsettings; @@ -255,9 +257,16 @@ int getconfigtouse2(const char* config_file_str, char* car, int sim); int getconfigtouse1(const char* config_file_str, char* car, int sim); int getconfigtouse(const char* config_file_str, char* car, int sim); +config_t *open_monocoque_config(const char *filename); +void close_monocoque_config(config_t *cfg); + +int delete_device_config(config_t *cfg, const char *configfile, int confignum, int devicenum); +int save_device_config(config_t *cfg, const char* configfile, int confignum, int devicenum, const DeviceSettings *ds); 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); +int getsingledevice(const char* config_file_str, int confignum, int devicenum, MonocoqueSettings* ms, DeviceSettings* ds); + int getNumberOfConfigs(const char* config_file_str); #endif diff --git a/src/monocoque/mgui/CMakeLists.txt b/src/monocoque/mgui/CMakeLists.txt index 833d6ed..a0320ad 100644 --- a/src/monocoque/mgui/CMakeLists.txt +++ b/src/monocoque/mgui/CMakeLists.txt @@ -1,4 +1,12 @@ - +set(mgui_source_files + addeditaction.c + addeditaction.h + testaction.c + testaction.h + uiconfighelper.c + uiconfighelper.h + mainwindow.h +) set(NAPPGUI_DEMO NO CACHE BOOL "" FORCE) set(NAPPGUI_WEB False CACHE BOOL "Build NAppGUI WebView support.") @@ -8,7 +16,7 @@ add_subdirectory(nappgui_src) set(CMAKE_BUILD_TYPE ${_saved_build_type}) -add_library(mgui STATIC ${gui_source_files} ${NAppGUI_SOURCE_DIR}/src) +add_library(mgui STATIC ${mgui_source_files} ${NAppGUI_SOURCE_DIR}/src) set_property(TARGET mgui PROPERTY POSITION_INDEPENDENT_CODE ON) add_dependencies(mgui gui osapp osgui draw2d geom2d core osbs sewer encode) target_include_directories(mgui PUBLIC ${LIBXML_INCLUDE_DIR} ${NAppGUI_SOURCE_DIR}/src ${GTK3_INCLUDE_DIRS}) diff --git a/src/monocoque/mgui/addeditaction.c b/src/monocoque/mgui/addeditaction.c new file mode 100644 index 0000000..28884d2 --- /dev/null +++ b/src/monocoque/mgui/addeditaction.c @@ -0,0 +1,604 @@ +#include + +#include +#include + +#include "addeditaction.h" +#include "testaction.h" +#include "mainwindow.h" + +#include "uiconfighelper.h" +#include "../helper/confighelper.h" +#include "../gameloop/gameloop.h" +#include "../gameloop/loopdata.h" +#include "../slog/slog.h" + + +test_loop_args* test_loop_data; + +/*---------------------------------------------------------------------------*/ + +static Layout *i_modal_layout(AddDeviceData *data, App* app, MonocoqueSettings* ms, enum device_action dev_action, int confignum, int devicenum); + +/*---------------------------------------------------------------------------*/ + +static AddDeviceData *i_modal_data(Window *parent) +{ + AddDeviceData *data = heap_new0(AddDeviceData); + data->parent = parent; + data->type = UINT32_MAX; + return data; +} + +/*---------------------------------------------------------------------------*/ + +static void i_destroy_modal_data(AddDeviceData **data) +{ + AddDeviceData* d = *data; + DeviceSettings ds = *d->ds; + settingsfree(ds); + free(d->ds); + heap_delete(data, AddDeviceData); +} + + +/*---------------------------------------------------------------------------*/ + +static void i_OnTestClose(App *app, Event *e) +{ + +} + +static void update_device_data_from_controls(AddDeviceData* data) +{ + data->ds->dev_type = combo_get_selected(data->combo_select_device_class); + data->ds->dev_subtype = combo_get_selected(data->combo_select_device_subtype); + uint32_t device_selected = combo_get_selected(data->combo_select_device); + data->ds->dev = strdup(combo_get_text(data->combo_select_device, device_selected)); + if(data->ds->dev_type == SIMDEV_SERIAL) + { + data->ds->dev_subtype = combo_get_selected(data->combo_select_device_subtype) + SerialDevicesOffset; + } + if(data->ds->dev_type == SIMDEV_USB) + { + data->ds->dev_subtype = combo_get_selected(data->combo_select_device_subtype) + USBDevicesOffset; + } + data->ds->hapticsettings.tyre = combo_get_selected(data->combo_select_tyre); + data->ds->hapticsettings.effect_type = combo_get_selected(data->combo_select_effect); + data->ds->hapticsettings.modulation = combo_get_selected(data->combo_select_modulation); +} + + +static void i_OnTestDevice(AddDeviceData *data, Event *e) +{ + update_device_data_from_controls(data); + + Panel *panel = NULL; + + data->apppointer->window3 = window_create(ekWINDOW_STDRES); + + SimData* t_simdata = malloc(sizeof(SimData)); + + set_basic_simdata(t_simdata); + set_wheel_spin_simdata(t_simdata); + if(data->ds->has_haptic_effects == true) + { + if(data->ds->hapticsettings.effect_type == EFFECT_TYRELOCK) + { + set_wheel_lock_simdata(t_simdata); + } + } + + + test_loop_data = malloc(sizeof(test_loop_args)); + test_loop_data->ms = data->ms; + test_loop_data->confignum = data->confignum; + test_loop_data->devicenum = data->devicenum; + test_loop_data->ds = data->ds; + test_loop_data->simdata = t_simdata; + + start_test(test_loop_data); + panel = test_window(data->apppointer->window3, data->apppointer); + + window_panel(data->apppointer->window3, panel); + window_origin(data->apppointer->window3, v2df(800, 200)); + window_title(data->apppointer->window3, "monocoque"); + window_OnClose(data->apppointer->window3, listener(data->apppointer, i_OnTestClose, App)); + + window_modal(data->apppointer->window3, data->apppointer->window); + + window_destroy(&data->apppointer->window3); + + free(t_simdata); + free(test_loop_data); +} + +static void addHapticDeviceLayout(AddDeviceData* data) +{ + struct _add_device_t* subwindow = data; + subwindow->haptic_effect_sublayout = layout_create(8, 3); + + subwindow->label_select_effect = label_create(); + subwindow->combo_select_effect = combo_create(); + subwindow->label_select_modulation = label_create(); + subwindow->combo_select_modulation = combo_create(); + subwindow->label_select_tyre = label_create(); + subwindow->combo_select_tyre = combo_create(); + subwindow->label_motorposition = label_create(); + subwindow->edit_motorposition = edit_create(); + + subwindow->label_frequency = label_create(); + subwindow->edit_frequency = edit_create(); + subwindow->label_amplitude = label_create(); + subwindow->edit_amplitude = edit_create(); + + subwindow->label_frequencyMax = label_create(); + subwindow->edit_frequencyMax = edit_create(); + subwindow->label_amplitudeMax = label_create(); + subwindow->edit_amplitudeMax = edit_create(); + subwindow->label_threshold = label_create(); + subwindow->edit_threshold = edit_create(); + subwindow->label_duration = label_create(); + subwindow->edit_duration = edit_create(); + + label_text(subwindow->label_select_effect, "Effect:"); + label_text(subwindow->label_select_modulation, "Modulation:"); + label_text(subwindow->label_select_tyre, "Tyre:"); + label_text(subwindow->label_motorposition, "Motor Position:"); + label_text(subwindow->label_frequency, "Frequency:"); + label_text(subwindow->label_amplitude, "Amplitude:"); + label_text(subwindow->label_frequencyMax, "Max Frequency:"); + label_text(subwindow->label_amplitudeMax, "Max Amplitude:"); + label_text(subwindow->label_threshold, "Threshold:"); + label_text(subwindow->label_duration, "Duration:"); + + layout_label(subwindow->haptic_effect_sublayout, subwindow->label_select_effect, 0, 0); + layout_combo(subwindow->haptic_effect_sublayout, subwindow->combo_select_effect, 1, 0); + layout_label(subwindow->haptic_effect_sublayout, subwindow->label_select_modulation, 2, 0); + layout_combo(subwindow->haptic_effect_sublayout, subwindow->combo_select_modulation, 3, 0); + layout_label(subwindow->haptic_effect_sublayout, subwindow->label_select_tyre, 4, 0); + layout_combo(subwindow->haptic_effect_sublayout, subwindow->combo_select_tyre, 5, 0); + layout_label(subwindow->haptic_effect_sublayout, subwindow->label_motorposition, 6, 0); + layout_edit(subwindow->haptic_effect_sublayout, subwindow->edit_motorposition, 7, 0); + + combo_add_elem(subwindow->combo_select_effect, "Engine", NULL); + combo_add_elem(subwindow->combo_select_effect, "Gear", NULL); + combo_add_elem(subwindow->combo_select_effect, "ABS", NULL); + combo_add_elem(subwindow->combo_select_effect, "TyreSlip", NULL); + combo_add_elem(subwindow->combo_select_effect, "TyreLock", NULL); + combo_add_elem(subwindow->combo_select_effect, "Suspension", NULL); + + combo_add_elem(subwindow->combo_select_modulation, "None", NULL); + combo_add_elem(subwindow->combo_select_modulation, "Frequency", NULL); + combo_add_elem(subwindow->combo_select_modulation, "Amplitude", NULL); + + combo_add_elem(subwindow->combo_select_tyre, "FrontLeft", NULL); + combo_add_elem(subwindow->combo_select_tyre, "FrontRight", NULL); + combo_add_elem(subwindow->combo_select_tyre, "RearLeft", NULL); + combo_add_elem(subwindow->combo_select_tyre, "RearRight", NULL); + combo_add_elem(subwindow->combo_select_tyre, "Fronts", NULL); + combo_add_elem(subwindow->combo_select_tyre, "Rears", NULL); + combo_add_elem(subwindow->combo_select_tyre, "All", NULL); + + layout_label(subwindow->haptic_effect_sublayout, subwindow->label_frequency, 0, 1); + layout_edit(subwindow->haptic_effect_sublayout, subwindow->edit_frequency, 1, 1); + layout_label(subwindow->haptic_effect_sublayout, subwindow->label_amplitude, 2, 1); + layout_edit(subwindow->haptic_effect_sublayout, subwindow->edit_amplitude, 3, 1); + layout_label(subwindow->haptic_effect_sublayout, subwindow->label_frequencyMax, 6, 1); + layout_edit(subwindow->haptic_effect_sublayout, subwindow->edit_frequencyMax, 7, 1); + + layout_label(subwindow->haptic_effect_sublayout, subwindow->label_amplitudeMax, 0, 2); + layout_edit(subwindow->haptic_effect_sublayout, subwindow->edit_amplitudeMax, 1, 2); + layout_label(subwindow->haptic_effect_sublayout, subwindow->label_threshold, 2, 2); + layout_edit(subwindow->haptic_effect_sublayout, subwindow->edit_threshold, 3, 2); + layout_label(subwindow->haptic_effect_sublayout, subwindow->label_duration, 4, 2); + layout_edit(subwindow->haptic_effect_sublayout, subwindow->edit_duration, 5, 2); + + + + cell_dbind(layout_cell(subwindow->haptic_effect_sublayout, 1, 1), HapticEffectSettings, uint32_t, frequency); + cell_dbind(layout_cell(subwindow->haptic_effect_sublayout, 3, 1), HapticEffectSettings, uint32_t, amplitude); + cell_dbind(layout_cell(subwindow->haptic_effect_sublayout, 7, 1), HapticEffectSettings, uint32_t, frequencyMax); + cell_dbind(layout_cell(subwindow->haptic_effect_sublayout, 1, 2), HapticEffectSettings, uint32_t, amplitudeMax); + cell_dbind(layout_cell(subwindow->haptic_effect_sublayout, 7, 0), HapticEffectSettings, uint32_t, motorposition); + cell_dbind(layout_cell(subwindow->haptic_effect_sublayout, 3, 2), HapticEffectSettings, real64_t, threshold); + cell_dbind(layout_cell(subwindow->haptic_effect_sublayout, 5, 2), HapticEffectSettings, real64_t, duration); + + cell_dbind(layout_cell(subwindow->haptic_effect_sublayout, 3, 0), HapticEffectSettings, uint32_t, modulation); + cell_dbind(layout_cell(subwindow->haptic_effect_sublayout, 5, 0), HapticEffectSettings, uint32_t, tyre); + cell_dbind(layout_cell(subwindow->haptic_effect_sublayout, 1, 0), HapticEffectSettings, uint32_t, effect_type); + layout_dbind(subwindow->haptic_effect_sublayout, NULL, HapticEffectSettings); + layout_dbind_obj(subwindow->haptic_effect_sublayout, &data->ds->hapticsettings, HapticEffectSettings); + + // can i get this from the dbind + combo_selected(subwindow->combo_select_tyre, data->ds->hapticsettings.tyre); + combo_selected(subwindow->combo_select_effect, data->ds->hapticsettings.effect_type); + combo_selected(subwindow->combo_select_modulation, data->ds->hapticsettings.modulation); + + for (uint32_t row = 0; row < 3; row++) + { + for (uint32_t col = 1; col < 8; col += 2) + { + layout_halign(subwindow->haptic_effect_sublayout, col, row, ekJUSTIFY); + } + } + +} + +static void addSerialDeviceLayout(AddDeviceData* data) +{ + struct _add_device_t* subwindow = data; + subwindow->serial_device_sublayout = layout_create(4, 1); + subwindow->edit_baud = edit_create(); + subwindow->label_baud = label_create(); + label_text(subwindow->label_baud, "baud: "); + layout_label(subwindow->serial_device_sublayout, subwindow->label_baud, 0, 0); + layout_edit(subwindow->serial_device_sublayout, subwindow->edit_baud, 1, 0); + + cell_dbind(layout_cell(subwindow->serial_device_sublayout, 1, 0), SerialDeviceSettings, uint32_t, baud); + layout_dbind(subwindow->serial_device_sublayout, NULL, SerialDeviceSettings); + layout_dbind_obj(subwindow->serial_device_sublayout, &data->ds->serialdevsettings, SerialDeviceSettings); + + layout_update(subwindow->serial_device_sublayout); +} + +static void addSoundDeviceLayout(AddDeviceData* data) +{ + struct _add_device_t* subwindow = data; + + subwindow->sound_device_sublayout = layout_create(6, 1); + + subwindow->edit_channel = edit_create(); + subwindow->edit_channels = edit_create(); + subwindow->label_channel = label_create(); + subwindow->label_channels = label_create(); + subwindow->label_volume = label_create(); + subwindow->edit_volume = edit_create(); + + label_text(subwindow->label_channel, "Channel: "); + label_text(subwindow->label_channels, "Channels: "); + label_text(subwindow->label_volume, "Volume:"); + + layout_label(subwindow->sound_device_sublayout, subwindow->label_channel, 0, 0); + layout_label(subwindow->sound_device_sublayout, subwindow->label_channels, 2, 0); + layout_label(subwindow->sound_device_sublayout, subwindow->label_volume, 4, 0); + + layout_edit(subwindow->sound_device_sublayout, subwindow->edit_channel, 1, 0); + layout_edit(subwindow->sound_device_sublayout, subwindow->edit_channels, 3, 0); + layout_edit(subwindow->sound_device_sublayout, subwindow->edit_volume, 5, 0); + + + cell_dbind(layout_cell(subwindow->sound_device_sublayout, 1, 0), SoundDeviceSettings, uint32_t, pan); + cell_dbind(layout_cell(subwindow->sound_device_sublayout, 3, 0), SoundDeviceSettings, uint32_t, channels); + cell_dbind(layout_cell(subwindow->sound_device_sublayout, 5, 0), SoundDeviceSettings, uint32_t, volume); + layout_dbind(subwindow->sound_device_sublayout, NULL, SoundDeviceSettings); + layout_dbind_obj(subwindow->sound_device_sublayout, &data->ds->sounddevsettings, SoundDeviceSettings); + + + layout_update(subwindow->sound_device_sublayout); +} + +static void addLedDeviceLayout(AddDeviceData* data) +{ + struct _add_device_t* subwindow = data; + + subwindow->led_device_sublayout = layout_create(6,1); + + subwindow->edit_num_leds = edit_create(); + subwindow->edit_start_led = edit_create(); + subwindow->edit_end_led = edit_create(); + + subwindow->label_num_leds = label_create(); + subwindow->label_start_led = label_create(); + subwindow->label_end_led = label_create(); + + + label_text(subwindow->label_num_leds, "Leds: "); + label_text(subwindow->label_start_led, "Start Led: "); + label_text(subwindow->label_end_led, "End Led: "); + + layout_label(subwindow->led_device_sublayout, subwindow->label_num_leds, 0, 0); + layout_label(subwindow->led_device_sublayout, subwindow->label_start_led, 2, 0); + layout_label(subwindow->led_device_sublayout, subwindow->label_end_led, 4, 0); + + layout_edit(subwindow->led_device_sublayout, subwindow->edit_num_leds, 1, 0); + layout_edit(subwindow->led_device_sublayout, subwindow->edit_start_led, 3, 0); + layout_edit(subwindow->led_device_sublayout, subwindow->edit_end_led, 5, 0); + + + + + + cell_dbind(layout_cell(subwindow->led_device_sublayout, 1, 0), SerialDeviceSettings, uint32_t, numleds); + cell_dbind(layout_cell(subwindow->led_device_sublayout, 3, 0), SerialDeviceSettings, uint32_t, startled); + cell_dbind(layout_cell(subwindow->led_device_sublayout, 5, 0), SerialDeviceSettings, uint32_t, endled); + layout_dbind(subwindow->led_device_sublayout, NULL, SerialDeviceSettings); + layout_dbind_obj(subwindow->led_device_sublayout, &data->ds->serialdevsettings, SerialDeviceSettings); + + + layout_update(subwindow->led_device_sublayout); +} + +/*---------------------------------------------------------------------------*/ + +static void i_OnSaveDevice(AddDeviceData *data, Event *e) +{ + update_device_data_from_controls(data); + slogd("Attempting save of device class %i device type %i device %s", data->ds->dev_type, data->ds->dev_subtype, data->ds->dev); + save_device_config(data->ms->cfg, data->ms->config_str, data->confignum, data->devicenum, data->ds); +} + +static void i_OnDeviceSubtypeSelect(AddDeviceData *data, Event *e) +{ + const EvButton *p = event_params(e, EvButton); + cell_visible(data->cell_led_device_layout, false); + cell_visible(data->cell_haptic_effect_layout, false); + data->ds->has_led_effects = false; + data->ds->has_haptic_effects = false; + uint32_t selected = combo_get_selected(data->combo_select_device_subtype); + const char_t *text = combo_get_text(data->combo_select_device_subtype, selected); + + if (text != NULL && strcmp(text, "SIMLED") == 0) + { + cell_visible(data->cell_led_device_layout, true); + data->ds->has_led_effects = true; + } + if (text != NULL && strcmp(text, "SOUNDHAPTIC") == 0) + { + cell_visible(data->cell_haptic_effect_layout, true); + data->ds->has_haptic_effects = true; + } + panel_update(data->panel); +} + +static void populateSerialSubTypesCombo(Combo* combo) +{ + combo_add_elem(combo, "ShiftLights", NULL); + combo_add_elem(combo, "SimWind", NULL); + combo_add_elem(combo, "Haptic", NULL); + combo_add_elem(combo, "Wheel", NULL); + combo_add_elem(combo, "SimLed", NULL); + combo_add_elem(combo, "Custom", NULL); +} + + +static void i_OnDeviceClassSelect(AddDeviceData *data, Event *e) +{ + const EvButton *p = event_params(e, EvButton); + + panel_visible_layout(data->device_specific_panel, 0); + cell_visible(data->cell_led_device_layout, false); + cell_visible(data->cell_haptic_effect_layout, false); + panel_update(data->device_specific_panel); + combo_clear(data->combo_select_device); + combo_text(data->combo_select_device, ""); + combo_clear(data->combo_select_device_subtype); + combo_text(data->combo_select_device_subtype, ""); + uint32_t selected = combo_get_selected(data->combo_select_device_class); + const char_t *text = combo_get_text(data->combo_select_device_class, selected); + if (text != NULL && strcmp(text, "Serial") == 0) + { + add_serial_devices_to_combo(data->combo_select_device); + populateSerialSubTypesCombo(data->combo_select_device_subtype); + panel_visible_layout(data->device_specific_panel, 1); + // since SIMLED will be selected we will show led settings + cell_visible(data->cell_led_device_layout, true); + data->ds->has_led_effects = true; + } + if (text != NULL && strcmp(text, "Sound") == 0) + { + add_sound_devices_to_combo(data->combo_select_device); + combo_add_elem(data->combo_select_device_subtype, "Haptic", NULL); + panel_visible_layout(data->device_specific_panel, 2); + // since HAPTIC will be selected we will show haptic settings + cell_visible(data->cell_haptic_effect_layout, true); + data->ds->has_haptic_effects = true; + } + combo_selected(data->combo_select_device, 0); + combo_selected(data->combo_select_device_subtype, 0); + panel_update(data->device_specific_panel); + panel_update(data->panel); +} + +static Panel* device_specific_panel_create(AddDeviceData *data) +{ + Panel *panel = panel_create(); + data->empty_device_sublayout = layout_create(4, 1); + + addSerialDeviceLayout(data); + addSoundDeviceLayout(data); + + panel_layout(panel, data->empty_device_sublayout); + panel_layout(panel, data->serial_device_sublayout); + panel_layout(panel, data->sound_device_sublayout); + return panel; +} + + +static Layout *i_modal_layout(AddDeviceData *data, App* app, MonocoqueSettings* ms, enum device_action dev_action, int confignum, int devicenum) +{ + + struct _add_device_t* subwindow = data; + + subwindow->main_outer_layout = layout_create(1,11); + subwindow->top_selection_layout = layout_create(4,1); + subwindow->general_settings_layout = layout_create(4, 1); + + + // device class specific settings ( max 1 row so far ) + // possible led specific settings ( 1 row ) + // possible haptic specific settings ( 3 rows ) + + subwindow->add_save_test_layout = layout_create(2,1); + + subwindow->combo_select_device_class = combo_create(); + subwindow->combo_select_device_subtype = combo_create(); + subwindow->combo_select_device = combo_create(); + subwindow->label_select_device_class = label_create(); + subwindow->label_select_device_subtype = label_create(); + subwindow->label_select_device = label_create(); + label_text(subwindow->label_select_device_class, "Device Class: "); + label_text(subwindow->label_select_device_subtype, "Device SubType: "); + label_text(subwindow->label_select_device, "Device: "); + layout_label(subwindow->top_selection_layout, subwindow->label_select_device_class, 0, 0); + layout_combo(subwindow->top_selection_layout, subwindow->combo_select_device_class, 1, 0); + layout_label(subwindow->top_selection_layout, subwindow->label_select_device_subtype, 2, 0); + layout_combo(subwindow->top_selection_layout, subwindow->combo_select_device_subtype, 3, 0); + + + + layout_label(subwindow->general_settings_layout, subwindow->label_select_device, 2, 0); + layout_combo(subwindow->general_settings_layout, subwindow->combo_select_device, 3, 0); + subwindow->edit_fps = edit_create(); + subwindow->label_fps = label_create(); + label_text(subwindow->label_fps, "fps: "); + layout_label(subwindow->general_settings_layout, subwindow->label_fps, 0, 0); + layout_edit(subwindow->general_settings_layout, subwindow->edit_fps, 1, 0); + + + cell_dbind(layout_cell(subwindow->top_selection_layout, 1, 0), DeviceSettings, uint32_t, dev_type); + cell_dbind(layout_cell(subwindow->top_selection_layout, 3, 0), DeviceSettings, uint32_t, dev_subtype); + cell_dbind(layout_cell(subwindow->general_settings_layout, 1, 0), DeviceSettings, uint32_t, fps); + layout_dbind(subwindow->general_settings_layout, NULL, DeviceSettings); + layout_dbind(subwindow->top_selection_layout, NULL, DeviceSettings); + layout_dbind_obj(subwindow->general_settings_layout, data->ds, DeviceSettings); + + subwindow->device_specific_panel = device_specific_panel_create(data); + panel_visible_layout(data->device_specific_panel, 0); + + addLedDeviceLayout(data); + addHapticDeviceLayout(data); + + + subwindow->test_button = button_push(); + subwindow->save_button = button_push(); + button_text(subwindow->test_button, "Test"); + button_text(subwindow->save_button, "Save"); + layout_button(subwindow->add_save_test_layout, subwindow->test_button, 0, 0); + layout_button(subwindow->add_save_test_layout, subwindow->save_button, 1, 0); + button_OnClick(subwindow->test_button, listener(data, i_OnTestDevice, AddDeviceData)); + button_OnClick(subwindow->save_button, listener(data, i_OnSaveDevice, AddDeviceData)); + + + + layout_layout(subwindow->main_outer_layout, subwindow->top_selection_layout, 0, 0); + layout_layout(subwindow->main_outer_layout, subwindow->general_settings_layout, 0, 1); + layout_panel(subwindow->main_outer_layout, subwindow->device_specific_panel, 0, 2); + layout_layout(subwindow->main_outer_layout, subwindow->led_device_sublayout, 0, 3); + layout_layout(subwindow->main_outer_layout, subwindow->haptic_effect_sublayout, 0, 4); + layout_layout(subwindow->main_outer_layout, subwindow->add_save_test_layout, 0, 7); + + subwindow->cell_led_device_layout = layout_cell(subwindow->main_outer_layout, 0, 3); + subwindow->cell_haptic_effect_layout = layout_cell(subwindow->main_outer_layout, 0, 4); + cell_visible(subwindow->cell_led_device_layout, false); + cell_visible(subwindow->cell_haptic_effect_layout, false); + + + + + if(dev_action == DEVICE_ACTION_ADD) + { + combo_add_elem(subwindow->combo_select_device_class, "USB", NULL); + combo_add_elem(subwindow->combo_select_device_class, "Sound", NULL); + combo_add_elem(subwindow->combo_select_device_class, "Serial", NULL); + + + combo_OnSelect(subwindow->combo_select_device_class, listener(data, i_OnDeviceClassSelect, AddDeviceData)); + combo_OnSelect(subwindow->combo_select_device_subtype, listener(data, i_OnDeviceSubtypeSelect, AddDeviceData)); + + + return subwindow->main_outer_layout; + } + + char str0[255]; + sprintf(str0, "%s", data->ds->dev); + combo_add_elem(subwindow->combo_select_device, str0, NULL); + + + subwindow->cell_top_selection_layout = layout_cell(subwindow->main_outer_layout, 0, 0); + cell_enabled(subwindow->cell_top_selection_layout, false); + + if(data->ds->dev_type == SIMDEV_SERIAL) + { + combo_add_elem(subwindow->combo_select_device_class, "Serial", NULL); + add_serial_devices_to_combo(data->combo_select_device); + populateSerialSubTypesCombo(data->combo_select_device_subtype); + combo_selected(subwindow->combo_select_device_subtype, data->ds->dev_subtype - SerialDevicesOffset); + panel_visible_layout(data->device_specific_panel, 1); + } + if(data->ds->dev_type == SIMDEV_SOUND) + { + combo_add_elem(subwindow->combo_select_device_class, "Sound", NULL); + add_sound_devices_to_combo(data->combo_select_device); + combo_add_elem(data->combo_select_device_subtype, "Haptic", NULL); + combo_selected(subwindow->combo_select_device_subtype, data->ds->dev_subtype); + panel_visible_layout(data->device_specific_panel, 2); + cell_visible(data->cell_haptic_effect_layout, true); + } + if(data->ds->dev_type == SIMDEV_USB) + { + combo_selected(subwindow->combo_select_device_subtype, data->ds->dev_subtype - USBDevicesOffset); + panel_visible_layout(data->device_specific_panel, 2); + } + + if(data->ds->dev_subtype == SIMDEVTYPE_SIMLED) { + cell_visible(data->cell_led_device_layout, true); + } + + combo_selected(subwindow->combo_select_device_class, 0); + return subwindow->main_outer_layout; +} + +/*---------------------------------------------------------------------------*/ + +Panel *adddevice_window(Window *parent, App* app, MonocoqueSettings* ms, enum device_action dev_action, int confignum, int devicenum) +{ + Panel *panel = panel_create(); + AddDeviceData *data = i_modal_data(parent); + data->panel = panel; + + data->devicenum = devicenum; + data->confignum = confignum; + data->ds = malloc(sizeof(DeviceSettings)); + + // move this somewhere better or use dbind to set this stuff + data->ds->dev_type = 0; + data->ds->dev_subtype = 0; + data->ds->dev_subsubtype = 0; + data->ds->dev = NULL; + data->ds->fps = 60; + data->ds->specific_config_file = NULL; + data->ds->has_config = false; + data->ds->serialdevsettings.baud = 115200; + data->ds->serialdevsettings.startled = 0; + data->ds->serialdevsettings.endled = 0; + data->ds->serialdevsettings.numleds = 0; + data->ds->sounddevsettings.channels = 2; + data->ds->sounddevsettings.pan = 0; + data->ds->sounddevsettings.volume = 50; + data->ds->sounddevsettings.noise = 0; + data->ds->hapticsettings.frequency = 32; + data->ds->hapticsettings.amplitude = 50; + data->ds->hapticsettings.frequencyMax = 0; + data->ds->hapticsettings.amplitudeMax = 0; + data->ds->hapticsettings.motorposition = 0; + data->ds->hapticsettings.threshold = 0.0; + data->ds->hapticsettings.duration = 0.0; + data->ds->hapticsettings.modulation = 1; + data->ds->hapticsettings.tyre = 0; + data->ds->hapticsettings.effect_type = 0; + data->ds->has_led_effects = false; + data->ds->has_haptic_effects = false; + + data->ms = ms; + data->apppointer = app; + if(dev_action == DEVICE_ACTION_EDIT) + { + int numdevices = getsingledevice(ms->config_str, confignum, devicenum, ms, data->ds); + } + + Layout *layout = i_modal_layout(data, app, ms, dev_action, confignum, devicenum); + panel_layout(panel, layout); + panel_data(panel, &data, i_destroy_modal_data, AddDeviceData); + return panel; +} diff --git a/src/monocoque/mgui/addeditaction.h b/src/monocoque/mgui/addeditaction.h new file mode 100644 index 0000000..2dc3ada --- /dev/null +++ b/src/monocoque/mgui/addeditaction.h @@ -0,0 +1,97 @@ +#include +#include "mainwindow.h" + +Panel *adddevice_window(Window *parent, App* app, MonocoqueSettings* ms, enum device_action dev_action, int confignum, int devicenum); + +typedef struct _add_device_t AddDeviceData; + +struct _add_device_t +{ + Layout* main_outer_layout; + + Layout* top_selection_layout; + Label* label_select_device_class; + Label* label_select_device_subtype; + Label* label_select_device; + Combo* combo_select_device_class; + Combo* combo_select_device_subtype; + Combo* combo_select_device; + + Edit* edit_select_device; + + Layout* general_settings_layout; + Label* label_fps; + Edit* edit_fps; + Button* check_use_lua; + + Layout* empty_device_sublayout; + + Panel* device_specific_panel; + + // sound sublayout + Layout* sound_device_sublayout; + Label* label_channel; + Label* label_channels; + Label* label_volume; + Edit* edit_channel; + Edit* edit_channels; + Edit* edit_volume; + + // serial sublayout + Layout* serial_device_sublayout; + Label* label_baud; + Edit* edit_baud; + + // led sublayout + Layout* led_device_sublayout; + Label* label_num_leds; + Label* label_start_led; + Label* label_end_led; + Edit* edit_num_leds; + Edit* edit_start_led; + Edit* edit_end_led; + + Layout* haptic_effect_sublayout; + Label* label_select_effect; + Combo* combo_select_effect; + Label* label_select_modulation; + Combo* combo_select_modulation; + Label* label_select_tyre; + Combo* combo_select_tyre; + + Label* label_motorposition; + Edit* edit_motorposition; + Label* label_frequency; + Edit* edit_frequency; + Label* label_amplitude; + Edit* edit_amplitude; + + Label* label_frequencyMax; + Edit* edit_frequencyMax; + Label* label_amplitudeMax; + Edit* edit_amplitudeMax; + Label* label_threshold; + Edit* edit_threshold; + Label* label_duration; + Edit* edit_duration; + + + + Layout* add_save_test_layout; + Button* test_button; + Button* save_button; + + Cell* cell_top_selection_layout; + Cell* cell_led_device_layout; + Cell* cell_haptic_effect_layout; + + uint32_t type; + Label *label; + MonocoqueSettings* ms; + DeviceSettings* ds; + Panel* panel; + App* apppointer; + int confignum; + int devicenum; + Window *parent; +}; diff --git a/src/monocoque/mgui/mainwindow.h b/src/monocoque/mgui/mainwindow.h new file mode 100644 index 0000000..5cd138e --- /dev/null +++ b/src/monocoque/mgui/mainwindow.h @@ -0,0 +1,42 @@ +#include "../helper/confighelper.h" + +enum device_action { + DEVICE_ACTION_ADD, DEVICE_ACTION_EDIT, DEVICE_ACTION_DELETE +}; + +typedef struct _app_t App; +struct _app_t +{ + bool_t is_running; + + Panel *main_panel; + Panel *subpanel; + + + Layout *layout1; + Layout *layout2; + Layout *layout3; + Layout *layout4; + Layout *sub_layout; + + + Window *window; + Window *window2; + Window *window3; + Layout* layout; + + Combo* combo_configurations; + ListBox* listbox_devices; + + Button *button_startstop; + Button *button_add; + Button *button_edit; + Button *button_del; + Button *button_test; + + Label *label_configurations; + Label *label_game_status; + Label *label_simd_status; + + Cell* devices_subpanel; +}; diff --git a/src/monocoque/mgui/testaction.c b/src/monocoque/mgui/testaction.c new file mode 100644 index 0000000..7660c8b --- /dev/null +++ b/src/monocoque/mgui/testaction.c @@ -0,0 +1,188 @@ +/* Listboxes */ + +#include "testaction.h" +#include "../gameloop/gameloop.h" +#include "mainwindow.h" +#include + +typedef struct _modal_data_t gModalData; + +struct _modal_data_t +{ + uint32_t type; + Label *label; + Window *parent; +}; + + +/*---------------------------------------------------------------------------*/ + +static Layout *i_modal_layout(gModalData *data, Window *window, App *app); + +/*---------------------------------------------------------------------------*/ + +static gModalData *i_modal_data(Window *parent) +{ + gModalData *data = heap_new0(gModalData); + data->parent = parent; + data->type = UINT32_MAX; + return data; +} + +/*---------------------------------------------------------------------------*/ +static void i_OnTestDone(Window *window, Event *e) +{ + Button *button = event_sender(e, Button); + window_stop_modal(window, button_get_tag(button)); +} + +/*---------------------------------------------------------------------------*/ + +static void i_OnTestDataUpdate(Window* window, Event* e) +{ + Button *button = event_sender(e, Button); + //SimData* simdata = get_test_simdata(); +} + + +/*---------------------------------------------------------------------------*/ + +static void i_destroy_modal_data(gModalData **data) +{ + monocoque_testloop_stop(); + heap_delete(data, gModalData); +} + + +/*---------------------------------------------------------------------------*/ + +static Layout *i_modal_layout(gModalData *data, Window* window, App *app) +{ + struct _test_device_t subwindow; + subwindow.main_outer_layout = layout_create(1,7); + subwindow.data_edit_layout = layout_create(8,6); + subwindow.add_save_test_layout = layout_create(2,1); + + + subwindow.edit_gear = edit_create(); + subwindow.edit_velocity = edit_create(); + subwindow.edit_maxrpm = edit_create(); + subwindow.edit_rpm = edit_create(); + + subwindow.label_gear = label_create(); + subwindow.label_velocity = label_create(); + subwindow.label_maxrpm = label_create(); + subwindow.label_rpm = label_create(); + + + subwindow.label_tyre_diameter_1 = label_create(); + subwindow.label_tyre_diameter_2 = label_create(); + subwindow.label_tyre_diameter_3 = label_create(); + subwindow.label_tyre_diameter_4 = label_create(); + subwindow.label_tyre_rps_1 = label_create(); + subwindow.label_tyre_rps_2 = label_create(); + subwindow.label_tyre_rps_3 = label_create(); + subwindow.label_tyre_rps_4 = label_create(); + + subwindow.edit_tyre_diameter_1 = edit_create(); + subwindow.edit_tyre_diameter_2 = edit_create(); + subwindow.edit_tyre_diameter_3 = edit_create(); + subwindow.edit_tyre_diameter_4 = edit_create(); + subwindow.edit_tyre_rps_1 = edit_create(); + subwindow.edit_tyre_rps_2 = edit_create(); + subwindow.edit_tyre_rps_3 = edit_create(); + subwindow.edit_tyre_rps_4 = edit_create(); + + subwindow.update_button = button_push(); + subwindow.done_button = button_push(); + + label_text(subwindow.label_gear, "gear: "); + label_text(subwindow.label_velocity, "velocity: "); + label_text(subwindow.label_maxrpm, "max rpm: "); + label_text(subwindow.label_rpm, "rpm: "); + + + button_text(subwindow.update_button, "Update"); + button_text(subwindow.done_button, "Done"); + button_OnClick(subwindow.done_button, listener(window, i_OnTestDone, Window)); + button_OnClick(subwindow.update_button, listener(window, i_OnTestDataUpdate, Window)); + + layout_layout(subwindow.main_outer_layout, subwindow.data_edit_layout, 0, 2); + layout_layout(subwindow.main_outer_layout, subwindow.add_save_test_layout, 0, 5); + + layout_label(subwindow.data_edit_layout, subwindow.label_gear, 0, 0); + layout_label(subwindow.data_edit_layout, subwindow.label_velocity, 2, 0); + layout_label(subwindow.data_edit_layout, subwindow.label_maxrpm, 0, 1); + layout_label(subwindow.data_edit_layout, subwindow.label_rpm, 2, 1); + + layout_edit(subwindow.data_edit_layout, subwindow.edit_gear, 1, 0); + layout_edit(subwindow.data_edit_layout, subwindow.edit_velocity, 3, 0); + layout_edit(subwindow.data_edit_layout, subwindow.edit_maxrpm, 1, 1); + layout_edit(subwindow.data_edit_layout, subwindow.edit_rpm, 3, 1); + + layout_label(subwindow.data_edit_layout, subwindow.label_tyre_rps_1, 0, 2); + layout_label(subwindow.data_edit_layout, subwindow.label_tyre_rps_2, 2, 2); + layout_label(subwindow.data_edit_layout, subwindow.label_tyre_rps_3, 4, 2); + layout_label(subwindow.data_edit_layout, subwindow.label_tyre_rps_4, 6, 2); + layout_label(subwindow.data_edit_layout, subwindow.label_tyre_diameter_1, 0, 3); + layout_label(subwindow.data_edit_layout, subwindow.label_tyre_diameter_2, 2, 3); + layout_label(subwindow.data_edit_layout, subwindow.label_tyre_diameter_3, 4, 3); + layout_label(subwindow.data_edit_layout, subwindow.label_tyre_diameter_4, 6, 3); + label_text(subwindow.label_tyre_rps_1, "rps_lf"); + label_text(subwindow.label_tyre_rps_2, "rps_rf"); + label_text(subwindow.label_tyre_rps_3, "rps_lr"); + label_text(subwindow.label_tyre_rps_4, "rps_rr"); + label_text(subwindow.label_tyre_diameter_1, "diameter_lf"); + label_text(subwindow.label_tyre_diameter_2, "diameter_rf"); + label_text(subwindow.label_tyre_diameter_3, "diameter_lr"); + label_text(subwindow.label_tyre_diameter_4, "diameter_rr"); + + + layout_edit(subwindow.data_edit_layout, subwindow.edit_tyre_rps_1, 1, 2); + layout_edit(subwindow.data_edit_layout, subwindow.edit_tyre_rps_2, 3, 2); + layout_edit(subwindow.data_edit_layout, subwindow.edit_tyre_rps_3, 5, 2); + layout_edit(subwindow.data_edit_layout, subwindow.edit_tyre_rps_4, 7, 2); + layout_edit(subwindow.data_edit_layout, subwindow.edit_tyre_diameter_1, 1, 3); + layout_edit(subwindow.data_edit_layout, subwindow.edit_tyre_diameter_2, 3, 3); + layout_edit(subwindow.data_edit_layout, subwindow.edit_tyre_diameter_3, 5, 3); + layout_edit(subwindow.data_edit_layout, subwindow.edit_tyre_diameter_4, 7, 3); + + + + + cell_dbind(layout_cell(subwindow.data_edit_layout, 1, 0), SimData, uint32_t, gear); + cell_dbind(layout_cell(subwindow.data_edit_layout, 3, 0), SimData, uint32_t, velocity); + cell_dbind(layout_cell(subwindow.data_edit_layout, 1, 1), SimData, uint32_t, maxrpm); + cell_dbind(layout_cell(subwindow.data_edit_layout, 3, 1), SimData, uint32_t, rpms); + cell_dbind(layout_cell(subwindow.data_edit_layout, 1, 2), SimData, real64_t, tyreRPS[0]); + cell_dbind(layout_cell(subwindow.data_edit_layout, 3, 2), SimData, real64_t, tyreRPS[1]); + cell_dbind(layout_cell(subwindow.data_edit_layout, 5, 2), SimData, real64_t, tyreRPS[2]); + cell_dbind(layout_cell(subwindow.data_edit_layout, 7, 2), SimData, real64_t, tyreRPS[3]); + cell_dbind(layout_cell(subwindow.data_edit_layout, 1, 3), SimData, real64_t, tyrediameter[0]); + cell_dbind(layout_cell(subwindow.data_edit_layout, 3, 3), SimData, real64_t, tyrediameter[1]); + cell_dbind(layout_cell(subwindow.data_edit_layout, 5, 3), SimData, real64_t, tyrediameter[2]); + cell_dbind(layout_cell(subwindow.data_edit_layout, 7, 3), SimData, real64_t, tyrediameter[3]); + + + SimData* simdata = get_test_simdata(); + layout_dbind(subwindow.data_edit_layout, NULL, SimData); + layout_dbind_obj(subwindow.data_edit_layout, simdata, SimData); + + + layout_button(subwindow.add_save_test_layout, subwindow.update_button, 0, 0); + layout_button(subwindow.add_save_test_layout, subwindow.done_button, 1, 0); + + return subwindow.main_outer_layout; +} + +/*---------------------------------------------------------------------------*/ + +Panel *test_window(Window *parent, App* app) +{ + Panel *panel = panel_create(); + gModalData *data = i_modal_data(parent); + Layout *layout = i_modal_layout(data, parent, app); + panel_layout(panel, layout); + panel_data(panel, &data, i_destroy_modal_data, gModalData); + return panel; +} diff --git a/src/monocoque/mgui/testaction.h b/src/monocoque/mgui/testaction.h new file mode 100644 index 0000000..65f0707 --- /dev/null +++ b/src/monocoque/mgui/testaction.h @@ -0,0 +1,44 @@ +#include + +#include "mainwindow.h" + +Panel *test_window(Window *parent, App* app); + + +struct _test_device_t +{ + Layout* main_outer_layout; + + Layout* data_edit_layout; + Layout* add_save_test_layout; + + Label* label_gear; + Label* label_velocity; + Label* label_maxrpm; + Label* label_rpm; + Edit* edit_gear; + Edit* edit_velocity; + Edit* edit_maxrpm; + Edit* edit_rpm; + + Label* label_tyre_diameter_1; + Label* label_tyre_diameter_2; + Label* label_tyre_diameter_3; + Label* label_tyre_diameter_4; + Label* label_tyre_rps_1; + Label* label_tyre_rps_2; + Label* label_tyre_rps_3; + Label* label_tyre_rps_4; + + Edit* edit_tyre_diameter_1; + Edit* edit_tyre_diameter_2; + Edit* edit_tyre_diameter_3; + Edit* edit_tyre_diameter_4; + Edit* edit_tyre_rps_1; + Edit* edit_tyre_rps_2; + Edit* edit_tyre_rps_3; + Edit* edit_tyre_rps_4; + + Button* update_button; + Button* done_button; +}; diff --git a/src/monocoque/mgui/uiconfighelper.c b/src/monocoque/mgui/uiconfighelper.c new file mode 100644 index 0000000..b9481b8 --- /dev/null +++ b/src/monocoque/mgui/uiconfighelper.c @@ -0,0 +1,311 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "../helper/confighelper.h" + +typedef struct pa_devicelist { + uint8_t initialized; + char name[512]; + uint32_t index; + char description[256]; +} pa_devicelist_t; + +int find_default_config(config_setting_t *configs) +{ + int count = config_setting_length(configs); + + for (int i = 0; i < count; i++) + { + config_setting_t *entry = config_setting_get_elem(configs, i); + + const char *sim; + const char *api; + const char *car; + + if (!config_setting_lookup_string(entry, "sim", &sim)) + continue; + if (!config_setting_lookup_string(entry, "api", &api)) + continue; + if (!config_setting_lookup_string(entry, "car", &car)) + continue; + + if ((strcmp(sim, "default") == 0 || strcmp(sim, "all") == 0) && + (strcmp(api, "default") == 0 || strcmp(api, "all") == 0) && + (strcmp(car, "default") == 0 || strcmp(car, "all") == 0)) + { + return i; + } + } + + return -1; +} + +int add_serial_devices_to_combo(Combo *combo) +{ + // from libserialport examples + struct sp_port **port_list; + + enum sp_return result = sp_list_ports(&port_list); + + if (result != SP_OK) + { + return -1; + } + + int i; + for (i = 0; port_list[i] != NULL; i++) + { + struct sp_port *port = port_list[i]; + + char port_name[256]; + const char *name_ptr = sp_get_port_name(port); + + if (name_ptr != NULL) + { + snprintf(port_name, sizeof(port_name), "%s", name_ptr); + combo_add_elem(combo, port_name, NULL); + } + else + { + port_name[0] = '\0'; + } + } + + + sp_free_port_list(port_list); + + + return 0; +} + +void populate_combo_box(Combo* combo, config_t* cfg) +{ + config_setting_t *configs; + int count; + int i; + + configs = config_lookup(cfg, "configs"); + if (configs == NULL || !config_setting_is_list(configs)) + return; + + count = config_setting_length(configs); + + for (i = 0; i < count; i++) + { + config_setting_t *cfg_entry; + const char *sim = ""; + const char *car = ""; + const char *api = ""; + char text[256]; + + cfg_entry = config_setting_get_elem(configs, i); + + config_setting_lookup_string(cfg_entry, "sim", &sim); + config_setting_lookup_string(cfg_entry, "car", &car); + config_setting_lookup_string(cfg_entry, "api", &api); + + snprintf(text, sizeof(text), "%s / %s / %s", sim, car, api); + + combo_add_elem(combo, text, NULL); + } + +} + +void populate_device_list(ListBox *listbox, config_t* cfg) +{ + int count; + config_setting_t* devices; + devices = config_lookup(cfg, "configs"); + if (devices == NULL) + { + fprintf(stderr, "No configs section found\n"); + return; + } + + config_setting_t* config = NULL; + config = config_lookup(cfg, "configs"); + + int config_num = find_default_config(config); + + config_setting_t* selectedconfig = config_setting_get_elem(config, config_num); + config_setting_t* config_devices = NULL; + config_devices = config_setting_lookup(selectedconfig, "devices"); + + + count = config_setting_length(config_devices); + + for (int i = 0; i < count; i++) + { + config_setting_t *dev = config_setting_get_elem(config_devices, i); + + const char *device = ""; + const char *type = ""; + const char *subtype = ""; + const char *effect = ""; + const char *tyre = ""; + + config_setting_lookup_string(dev, "device", &device); + + char text[256]; + + if (strcasecmp(device, "sound") == 0) + { + config_setting_lookup_string(dev, "effect", &effect); + config_setting_lookup_string(dev, "tyre", &tyre); + + snprintf(text, sizeof(text), "%s - %s - %s", + device, effect, tyre); + } + else + { + config_setting_lookup_string(dev, "type", &type); + config_setting_lookup_string(dev, "subtype", &subtype); + + snprintf(text, sizeof(text), "%s - %s - %s", + device, type, subtype); + } + + listbox_add_elem(listbox, text, NULL); + } +} + + +void pa_sinklist_cb(pa_context *c, const pa_sink_info *l, int eol, void *userdata) { + pa_devicelist_t *pa_devicelist = userdata; + int ctr = 0; + + // If eol is set to a positive number, you're at the end of the list + if (eol > 0) { + return; + } + + // We know we've allocated 16 slots to hold devices. Loop through our + // structure and find the first one that's "uninitialized." Copy the + // contents into it and we're done. If we receive more than 16 devices, + // they're going to get dropped. You could make this dynamically allocate + // space for the device list, but this is a simple example. + for (ctr = 0; ctr < 16; ctr++) { + if (! pa_devicelist[ctr].initialized) { + strncpy(pa_devicelist[ctr].name, l->name, 511); + strncpy(pa_devicelist[ctr].description, l->description, 255); + pa_devicelist[ctr].index = l->index; + pa_devicelist[ctr].initialized = 1; + break; + } + } +} + + +int add_sound_devices_to_combo(Combo *combo) +{ + pa_mainloop *mainloop; + pa_context *context; + pa_operation *operation; + pa_context_state_t state; + pa_devicelist_t output[16] = {0}; + int retval; + //pa_devicelist_t* output = malloc(sizeof(pa_devicelist_t) * 16); + //memset(output, 0, sizeof(pa_devicelist_t) * 16); + mainloop = pa_mainloop_new(); + + if (mainloop == NULL) + return 0; + + context = pa_context_new( + pa_mainloop_get_api(mainloop), + "Monocoque"); + + if (context == NULL) + { + pa_mainloop_free(mainloop); + return 0; + } + + if (pa_context_connect(context, NULL, 0, NULL) < 0) + { + pa_context_unref(context); + pa_mainloop_free(mainloop); + return 0; + } + + /* + * Wait for PulseAudio to become ready. + */ + while (1) + { + if (pa_mainloop_iterate(mainloop, 1, &retval) < 0) + goto error; + + state = pa_context_get_state(context); + + if (state == PA_CONTEXT_READY) + break; + + if (!PA_CONTEXT_IS_GOOD(state)) + goto error; + } + + /* + * Enumerate all PulseAudio output devices (sinks). + */ + operation = pa_context_get_sink_info_list( + context, + pa_sinklist_cb, + &output); + + if (operation == NULL) + goto error; + + /* + * Run the mainloop until enumeration is complete. + */ + while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) + { + if (pa_mainloop_iterate(mainloop, 1, &retval) < 0) + { + pa_operation_unref(operation); + goto error; + } + } + + for (size_t i = 0; i < 16; i++) + { + if (!output[i].initialized) + { + continue; + } + + if (output[i].name[0] == '\0') + { + continue; + } + combo_add_elem(combo, output[i].name, NULL); + } + + pa_operation_unref(operation); + + pa_context_disconnect(context); + pa_context_unref(context); + pa_mainloop_free(mainloop); + + return 1; + +error: + + pa_context_disconnect(context); + pa_context_unref(context); + pa_mainloop_free(mainloop); + + return 0; +} diff --git a/src/monocoque/mgui/uiconfighelper.h b/src/monocoque/mgui/uiconfighelper.h new file mode 100644 index 0000000..04cf2e0 --- /dev/null +++ b/src/monocoque/mgui/uiconfighelper.h @@ -0,0 +1,14 @@ +#pragma once + +#include +#include + +#include + +#include "../helper/confighelper.h" + +int find_default_config(config_setting_t *configs); +void populate_combo_box(Combo* combo, config_t* cfg); +void populate_device_list(ListBox *listbox, config_t* cfg); +void add_serial_devices_to_combo(Combo *combo); +void add_sound_devices_to_combo(Combo *combo); diff --git a/src/monocoque/monocoque-gui.c b/src/monocoque/monocoque-gui.c index 4b386f4..b445a4c 100644 --- a/src/monocoque/monocoque-gui.c +++ b/src/monocoque/monocoque-gui.c @@ -5,6 +5,10 @@ #include #include +#include "mgui/uiconfighelper.h" +#include "mgui/addeditaction.h" +#include "mgui/mainwindow.h" + #include "gameloop/gameloop.h" #include "gameloop/loopdata.h" #include "gameloop/tachconfig.h" @@ -16,20 +20,19 @@ #include "simulatorapi/simapi/simapi/simdata.h" #include "slog/slog.h" +#include +#include +#include "./mgui/nappgui_src/build/demo/guihello/resgen/res_guihello.h" + + #define PROGRAM_NAME "monocoque" -MonocoqueSettings* ms; +MonocoqueSettings ms; +Parameters* p; +char **m_argv; +int m_argc; int appstate = 0; -void display_banner() -{ - printf("______ ______________ ___________________________________ ___________\n"); - printf("___ |/ /_ __ \\__ | / /_ __ \\_ ____/_ __ \\_ __ \\_ / / /__ ____/\n"); - printf("__ /|_/ /_ / / /_ |/ /_ / / / / _ / / / / / / / / /__ __/ \n"); - printf("_ / / / / /_/ /_ /| / / /_/ // /___ / /_/ // /_/ // /_/ / _ /___ \n"); - printf("/_/ /_/ \\____/ /_/ |_/ \\____/ \\____/ \\____/ \\___\\_\\\\____/ /_____/ \n"); -} - void SetSettingsFromParameters(Parameters* p, MonocoqueSettings* ms, char* configdir_str, char* cachedir_str) { @@ -76,18 +79,25 @@ void SetSettingsFromParameters(Parameters* p, MonocoqueSettings* ms, char* confi ms->force_udp_mode = false; ms->disable_audio = p->disable_audio; } +/*---------------------------------------------------------------------------*/ -int monocoque_main(int argc, char** argv) +int monocoque_initialize(int argc, char** argv) { + char* home_dir_str = gethome(); if(home_dir_str == NULL) { fprintf(stderr, "You need a home directory"); return 0; } - Parameters* p = NULL; + + p = NULL; p = malloc(sizeof(Parameters)); - ms = malloc(sizeof(MonocoqueSettings));; + p->config_dirpath = NULL; + p->config_filepath = NULL; + p->log_filename_str = NULL; + p->log_fullfilename_str = NULL; + p->log_dirname_str = NULL; ConfigError ppe = getParameters(argc, argv, p); if (ppe == E_SUCCESS_AND_EXIT || ppe == E_SOMETHING_BAD) @@ -102,7 +112,6 @@ int monocoque_main(int argc, char** argv) fprintf(stderr, "Function xdgInitHandle() failed, is $HOME unset?\n"); //goto cleanup_final; } - const char* config_home_str = xdgConfigHome(&xdg); const char* cache_home_str = xdgCacheHome(&xdg); @@ -120,27 +129,24 @@ int monocoque_main(int argc, char** argv) cachedir_str = create_user_dir(home_dir_str, ".cache", PROGRAM_NAME); } - fprintf(stderr, "applying settings\n"); - SetSettingsFromParameters(p, ms, configdir_str, cachedir_str); + SetSettingsFromParameters(p, &ms, configdir_str, cachedir_str); if(cachedir_str != NULL) { - free(cachedir_str); + free(cachedir_str); } if(configdir_str != NULL) { - free(configdir_str); + free(configdir_str); } - fprintf(stderr, "settings applied\n"); - slog_init("monocoque", SLOG_FLAGS_ALL, 1); slog_config_t slgCfg; slog_config_get(&slgCfg); slgCfg.eColorFormat = SLOG_COLORING_TAG; slgCfg.eDateControl = SLOG_TIME_ONLY; - strcpy(slgCfg.sFileName, ms->log_filename_str); - strcpy(slgCfg.sFilePath, ms->log_dirname_str); + strcpy(slgCfg.sFileName, ms.log_filename_str); + strcpy(slgCfg.sFilePath, ms.log_dirname_str); slgCfg.nTraceTid = 0; slgCfg.nToScreen = 1; slgCfg.nUseHeap = 0; @@ -148,203 +154,343 @@ int monocoque_main(int argc, char** argv) slgCfg.nFlush = 0; slgCfg.nFlags = SLOG_FLAGS_ALL; slog_config_set(&slgCfg); - if (ms->verbosity_count < 2) + if (ms.verbosity_count < 2) { slog_disable(SLOG_TRACE); } - if (ms->verbosity_count < 1) + if (ms.verbosity_count < 1) { slog_disable(SLOG_DEBUG); } xdgWipeHandle(&xdg); - slogi("checking for diameters config"); - char* diameters_file_str; - asprintf(&diameters_file_str, "%s/.config/monocoque/diameters.config", home_dir_str); - ms->tyre_diameter_config = strdup(diameters_file_str); - free(diameters_file_str); - - ms->useconfig = 0; - ms->configcheck = 0; - slogi("Testing monocoque config file: %s", ms->config_str); - slogd("using diameters file %s %i", ms->tyre_diameter_config, ms->configcheck); - config_t cfg; - config_init(&cfg); - config_setting_t* config_devices = NULL; - if (!config_read_file(&cfg, ms->config_str)) + + if(ms.disable_audio == false) { - sloge("Issue with monocoque config file: %s:%d - %s", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg)); - fprintf(stderr, "Issue with monocoque config file: %s:%d - %s\n", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg)); - config_destroy(&cfg); - slog_destroy(); - //goto cleanup_final; + setupsound(); } - else - { - slogi("Opened and validated monocoque configuration file"); - } - config_destroy(&cfg); - - - - int error = 0; - error = MONOCOQUE_ERROR_NONE; - //setupsound(); - bool pulseaudio = false; - - //if (ms->program_action == A_PLAY) - //{ - ms->useconfig = 1; - slogi("running monocoque in gameloop mode.."); -//#ifdef USE_PULSEAUDIO - //pa_threaded_mainloop_unlock(mainloop); - pulseaudio = true; -//#endif - - if(ms->disable_audio == false) - { - setupsound(); - } - //error = looper(devices, numdevices, p); - error = monocoque_mainloop_start(ms); - //if (error == MONOCOQUE_ERROR_NONE) - //{ - // slogi("Game loop exited succesfully with error code: %i", error); - //} - //else - //{ - // sloge("Game loop exited with error code: %i", error); - //} - //if(ms->disable_audio == false) - //{ - // freesound(); - //} - //} - - - } +/*---------------------------------------------------------------------------*/ - -#include - -#define NUM_BRICKS 40 - -Button *start_button; -Button *stop_button; - -Label *game_status; -Label *simd_status; - -typedef struct _app_t App; - - -struct _app_t +int monocoque_gameloop_start() { - bool_t is_running; - Cell *button; - Slider *slider; - View *view; - Window *window; -}; - - + start_loop(&ms); +} /*---------------------------------------------------------------------------*/ static void i_OnStart(App *app, Event *e) { - - appstate = 0; unref(e); app->is_running = TRUE; - cell_enabled(app->button, FALSE); - uint32_t i; - int argc = (int)osapp_argc(); - - char **argv = malloc(argc * sizeof(char *)); - - for (i = 0; i < (uint32_t)argc; ++i) + + int rc = 0; + if(appstate == 0) { - char buffer[128]; - - osapp_argv(i, buffer, sizeof(buffer)); - - argv[i] = strdup(buffer); /* allocate a copy */ + rc = monocoque_gameloop_start(); + } + else + { + monocoque_mainloop_stop(&ms); } - - int rc = monocoque_main(argc, argv); - fprintf(stderr, "monocoque mainloop started"); - /* cleanup */ - for (i = 0; i < (uint32_t)argc; ++i) - free(argv[i]); - - free(argv); } +/*---------------------------------------------------------------------------*/ static void i_OnStop(App *app, Event *e) { - monocoque_mainloop_stop(ms); -} - -/*---------------------------------------------------------------------------*/ - -static Panel *i_panel(App *app) -{ - Panel *panel = panel_create(); - Layout *layout = layout_create(1, 4); - View *view = view_create(); - Slider *slider = slider_create(); - game_status = label_create(); - start_button = button_push(); - stop_button = button_push(); - view_size(view, s2df(800, 600)); - //view_OnDraw(view, listener(app, i_OnDraw, App)); - //slider_OnMoved(slider, listener(app, i_OnSlider, App)); - label_text(game_status, "Game: None Detected Simd: Not Detected"); - button_text(start_button, "Start"); - button_text(stop_button, "Stop"); - button_OnClick(start_button, listener(app, i_OnStart, App)); - button_OnClick(stop_button, listener(app, i_OnStop, App)); - layout_view(layout, view, 0, 0); - //layout_slider(layout, slider, 0, 1); - layout_label(layout, game_status, 0, 3); - layout_button(layout, start_button, 0, 1); - layout_button(layout, stop_button, 0, 2); - layout_vexpand(layout, 0); - layout_vmargin(layout, 0, 10); - layout_vmargin(layout, 2, 10); - layout_margin(layout, 10); - panel_layout(panel, layout); - app->view = view; - app->slider = slider; - app->button = layout_cell(layout, 0, 3); - return panel; + monocoque_mainloop_stop(&ms); } /*---------------------------------------------------------------------------*/ static void i_OnClose(App *app, Event *e) { + close_monocoque_config(ms.cfg); + monocoquesettingsfree(&ms); + + freeparams(p); + free(p); + + for (int i = 0; i < (uint32_t)m_argc; ++i) + free(m_argv[i]); + free(m_argv); + osapp_finish(); unref(app); unref(e); } +/*---------------------------------------------------------------------------*/ + +static void i_OnAddClose(App *app, Event *e) +{ + + +} + +static void i_OnDelete(App* app, Event *e) +{ + int devicenum = listbox_get_selected(app->listbox_devices); + if(devicenum == UINT32_MAX) + { + return; + } + delete_device_config(ms.cfg, ms.config_str, 0, devicenum); + + listbox_clear(app->listbox_devices); + combo_clear(app->combo_configurations); + populate_device_list(app->listbox_devices, ms.cfg); + populate_combo_box(app->combo_configurations, ms.cfg); +} +/*---------------------------------------------------------------------------*/ + +static void i_OnAddEdit(App* app, Event *e, enum device_action device_action) +{ + Panel *panel = NULL; + + int devicenum = listbox_get_selected(app->listbox_devices); + if(devicenum == UINT32_MAX && device_action == DEVICE_ACTION_EDIT) + { + return; + } + if(device_action == DEVICE_ACTION_ADD) + { + devicenum = listbox_count(app->listbox_devices); + } + app->window2 = window_create(ekWINDOW_STDRES); + + panel = adddevice_window(app->window2, app, &ms, device_action, 0, devicenum); + + window_panel(app->window2, panel); + window_origin(app->window2, v2df(800, 200)); + window_title(app->window2, "monocoque"); + window_OnClose(app->window2, listener(app, i_OnAddClose, App)); + + window_modal(app->window2, app->window); + + window_destroy(&app->window2); + + listbox_clear(app->listbox_devices); + combo_clear(app->combo_configurations); + populate_device_list(app->listbox_devices, ms.cfg); + populate_combo_box(app->combo_configurations, ms.cfg); +} +/*---------------------------------------------------------------------------*/ + +static void i_OnAdd(App *app, Event *e) +{ + i_OnAddEdit(app, e, DEVICE_ACTION_ADD); +} +/*---------------------------------------------------------------------------*/ + +static void i_OnEdit(App *app, Event *e) +{ + i_OnAddEdit(app, e, DEVICE_ACTION_EDIT); +} /*---------------------------------------------------------------------------*/ + +static void set_bottom_label_status(Label* label) +{ + char status_string[256]; + snprintf(status_string, 256, "Game: %s Game Status: None Simd: %s", get_simexe_name(), get_simd_onoff()); + label_text(label, status_string); +} +/*---------------------------------------------------------------------------*/ + +static Panel *i_panel(App *app, MonocoqueSettings* ms) +{ + app->main_panel = panel_create(); + app->subpanel = panel_scroll(FALSE, TRUE); + + app->layout = layout_create(8,5); + + + app->listbox_devices = listbox_create(); + listbox_size(app->listbox_devices, s2df(50, 50)); + app->combo_configurations = combo_create(); + app->label_configurations = label_create(); + label_text(app->label_configurations, "Configuration: "); + app->label_game_status = label_create(); + + app->button_startstop = button_push(); + app->button_add = button_push(); + app->button_edit = button_push(); + app->button_del = button_push(); + + app->layout1 = layout_create(8,1); + app->layout2 = layout_create(8,1); + app->layout3 = layout_create(1,1); + app->layout4 = layout_create(1,2); + + layout_layout(app->layout, app->layout1, 0, 0); + layout_layout(app->layout, app->layout2, 0, 1); + layout_layout(app->layout, app->layout3, 0, 2); + layout_layout(app->layout, app->layout4, 0, 3); + + appstate = 0; + + set_bottom_label_status(app->label_game_status); + populate_device_list(app->listbox_devices, ms->cfg); + listbox_select(app->listbox_devices, 0, true); + populate_combo_box(app->combo_configurations, ms->cfg); + + + button_text(app->button_startstop, "Start"); + button_text(app->button_add, "Add Device"); + button_text(app->button_del, "Delete Device"); + button_text(app->button_edit, "Edit Device"); + button_OnClick(app->button_startstop, listener(app, i_OnStart, App)); + button_OnClick(app->button_add, listener(app, i_OnAdd, App)); + button_OnClick(app->button_edit, listener(app, i_OnEdit, App)); + button_OnClick(app->button_del, listener(app, i_OnDelete, App)); + + + layout_label(app->layout1, app->label_configurations, 0, 0); + layout_combo(app->layout1, app->combo_configurations, 1, 0); + + layout_button(app->layout2, app->button_add, 3, 0); + layout_button(app->layout2, app->button_edit, 4, 0); + layout_button(app->layout2, app->button_del, 5, 0); + + layout_listbox(app->layout3, app->listbox_devices, 0, 0); + + layout_button(app->layout4, app->button_startstop, 0, 0); + layout_label(app->layout4, app->label_game_status, 0, 1); + + panel_layout(app->subpanel, app->layout3); + layout_panel(app->layout, app->subpanel, 0, 2); + + panel_layout(app->main_panel, app->layout); + + + app->devices_subpanel = layout_cell(app->layout, 0, 2); + + // spacing + + layout_valign(app->layout4, 0, 0, ekBOTTOM); + layout_valign(app->layout4, 0, 1, ekBOTTOM); + + layout_halign(app->layout4, 0, 0, ekJUSTIFY); + layout_halign(app->layout4, 0, 1, ekJUSTIFY); + + layout_hexpand(app->layout, 0); + layout_hexpand(app->layout4, 0); + + layout_vexpand(app->layout, 0); + layout_vexpand(app->layout, 2); + layout_vexpand(app->layout4, 0); + + button_vpadding(app->button_startstop, 0); + button_hpadding(app->button_startstop, 0); + layout_hexpand(app->layout1, 1); + + return app->main_panel; +} + + static App *i_create(void) { + uint32_t i; + int old_argc = (int)osapp_argc(); + m_argc = old_argc + 1; + + m_argv = malloc((m_argc+1) * sizeof(char *)); + m_argv[m_argc] = NULL; + for (i = 0; i < (uint32_t)m_argc; ++i) + { + char buffer[128]; + m_argv[i] = NULL; + if (i == 1) + { + m_argv[i] = strdup("play"); + } + else + { + uint32_t old_i = (i > 1) ? i - 1 : i; + osapp_argv(old_i, buffer, sizeof(buffer)); + m_argv[i] = strdup(buffer); + } + } + + // do some monocoque things here + ms.tyre_diameter_config = NULL; + ms.config_str = NULL; + ms.log_filename_str = NULL; + ms.log_dirname_str = NULL; + + monocoque_initialize(m_argc, m_argv); + ms.cfg = open_monocoque_config(ms.config_str); + + // find a better spot for this + dbind(SimData, uint32_t, velocity); + dbind(SimData, uint32_t, rpms); + dbind(SimData, uint32_t, gear); + dbind(SimData, uint32_t, maxrpm); + dbind(SimData, real64_t, tyreRPS[0]); + dbind(SimData, real64_t, tyreRPS[1]); + dbind(SimData, real64_t, tyreRPS[2]); + dbind(SimData, real64_t, tyreRPS[3]); + dbind(SimData, real64_t, tyrediameter[0]); + dbind(SimData, real64_t, tyrediameter[1]); + dbind(SimData, real64_t, tyrediameter[2]); + dbind(SimData, real64_t, tyrediameter[3]); + + dbind(DeviceSettings, HapticEffectSettings, hapticsettings); + dbind(HapticEffectSettings, uint32_t, frequency); + dbind(HapticEffectSettings, uint32_t, frequencyMax); + dbind(HapticEffectSettings, uint32_t, amplitude); + dbind(HapticEffectSettings, uint32_t, amplitudeMax); + dbind(HapticEffectSettings, uint32_t, motorposition); + dbind(HapticEffectSettings, real64_t, threshold); + dbind(HapticEffectSettings, real64_t, duration); + dbind_enum(VibrationEffectType, EFFECT_ENGINERPM, "Engine RPM"); + dbind_enum(VibrationEffectType, EFFECT_GEARSHIFT, "Gear Shift"); + dbind_enum(VibrationEffectType, EFFECT_ABSBRAKES, "ABS Brakes"); + dbind_enum(VibrationEffectType, EFFECT_TYRESLIP, "Tyre Slip"); + dbind_enum(VibrationEffectType, EFFECT_TYRELOCK, "Tyre Lock"); + dbind_enum(VibrationEffectType, EFFECT_SUSPENSION, "Suspension"); + dbind_enum(EffectModulationType, EFFECT_MODULATION_NONE, "None"); + dbind_enum(EffectModulationType, EFFECT_MODULATION_FREQUENCY, "Frequency"); + dbind_enum(EffectModulationType, EFFECT_MODULATION_AMPLIFY, "Amplify"); + dbind_enum(MonocoqueTyreIdentifier, FRONTLEFT, "Front Left"); + dbind_enum(MonocoqueTyreIdentifier, FRONTRIGHT, "Front Right"); + dbind_enum(MonocoqueTyreIdentifier, REARLEFT, "Rear Left"); + dbind_enum(MonocoqueTyreIdentifier, REARRIGHT, "Rear Right"); + dbind_enum(MonocoqueTyreIdentifier, FRONTS, "Fronts"); + dbind_enum(MonocoqueTyreIdentifier, REARS, "Rears"); + dbind_enum(MonocoqueTyreIdentifier, ALLFOUR, "All Four"); + dbind(HapticEffectSettings, uint32_t, modulation); + dbind(HapticEffectSettings, uint32_t, tyre); + dbind(HapticEffectSettings, uint32_t, effect_type); + dbind(DeviceSettings, SerialDeviceSettings, serialdevsettings); + dbind(SerialDeviceSettings, uint32_t, baud); + dbind(SoundDeviceSettings, uint32_t, pan); + dbind(SoundDeviceSettings, uint32_t, channels); + dbind(SoundDeviceSettings, uint32_t, volume); + dbind(DeviceSettings, SerialDeviceSettings, serialdevsettings); + dbind(SerialDeviceSettings, uint32_t, startled); + dbind(SerialDeviceSettings, uint32_t, numleds); + dbind(SerialDeviceSettings, uint32_t, endled); + dbind_enum(DeviceType, SIMDEV_USB, "USB"); + dbind_enum(DeviceType, SIMDEV_SOUND, "Sound"); + dbind_enum(DeviceType, SIMDEV_SERIAL, "Serial"); + dbind(DeviceSettings, DeviceType, dev_type); + dbind(DeviceSettings, uint32_t, dev_subtype); + dbind(DeviceSettings, uint32_t, fps); + //gui stuff App *app = heap_new0(App); - Panel *panel = i_panel(app); + + Panel *panel = i_panel(app, &ms); app->window = window_create(ekWINDOW_STDRES); window_panel(app->window, panel); - window_origin(app->window, v2df(200, 200)); + window_origin(app->window, v2df(800, 200)); window_title(app->window, "monocoque"); window_OnClose(app->window, listener(app, i_OnClose, App)); window_show(app->window); + return app; } @@ -352,6 +498,10 @@ static App *i_create(void) static void i_destroy(App **app) { + //monocoquesettingsfree(&ms); + //freeparams(p); + //free(p); + osapp_finish(); window_destroy(&(*app)->window); heap_delete(app, App); } @@ -359,26 +509,30 @@ static void i_destroy(App **app) /*---------------------------------------------------------------------------*/ + + static void i_update(App *app, const real64_t prtime, const real64_t ctime) { if (app->is_running == TRUE) { if(appstate == 2) { - button_text(start_button, "Playing... Press to Stop"); + button_text(app->button_startstop, "Playing... Press to Stop"); + cell_enabled(app->devices_subpanel, false); } if(appstate == 1) { - button_text(start_button, "Searching for data... Press to Stop"); + button_text(app->button_startstop, "Searching for data... Press to Stop"); + cell_enabled(app->devices_subpanel, false); } - if(appstate == 0) + if(appstate <= 0) { - button_text(start_button, "Start"); + button_text(app->button_startstop, "Start"); + cell_enabled(app->devices_subpanel, true); } - label_text(game_status, "Game: (Searching) None Detected Simd: Not Detected"); + set_bottom_label_status(app->label_game_status); } - view_update(app->view); } /*---------------------------------------------------------------------------*/