/* * Copyright (C) EdgeTX * * Based on code named * opentx - https://github.com/opentx/opentx * th9x - http://code.google.com/p/th9x * er9x - http://code.google.com/p/er9x * gruvin9x - http://code.google.com/p/gruvin9x * * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #include #include #include #include "definitions.h" #include "datastructs_220.h" #include "sdcard.h" #include using namespace bin_storage_220; #include // see "yaml/yaml_datastructs.h" namespace yaml_conv_220 { const YamlNode* get_radiodata_nodes(); const YamlNode* get_modeldata_nodes(); const YamlNode* get_partialmodel_nodes(); }; #if defined(STORAGE_MODELSLIST) void patchFilenameToYaml(char* str); static const char* convertData_220_to_221( const char* path, unsigned size, const YamlNode* root_node, void (*patchBinary)(uint8_t*) = nullptr) { auto data = reinterpret_cast(malloc(size)); memset(data, 0, size); uint8_t version; const char* error = loadFileBin(path, data, size, &version); if (!error) { if (patchBinary) patchBinary(data); char output_fname[FF_MAX_LFN+1]; strncpy(output_fname, path, FF_MAX_LFN); output_fname[FF_MAX_LFN] = '\0'; patchFilenameToYaml(output_fname); error = writeFileYaml(output_fname, root_node, data); } free(data); return error; } #if defined(COLORLCD) void patchWidgetOptions(ZonePersistentData* zones, unsigned n_zones) { for (unsigned i = 0; i < n_zones; i++) { auto& zone = zones[i]; auto name_len = strnlen(zone.widgetName, sizeof(zone.widgetName)); std::string widgetName(zone.widgetName, name_len); if (widgetName.empty()) continue; if (widgetName == "Value") { zone.widgetData.options[0].type = ZOV_Source; zone.widgetData.options[1].type = ZOV_Color; } else if (widgetName == "Gauge") { zone.widgetData.options[0].type = ZOV_Source; zone.widgetData.options[3].type = ZOV_Color; } else if (widgetName == "Outputs") { zone.widgetData.options[2].type = ZOV_Color; zone.widgetData.options[3].type = ZOV_Color; zone.widgetData.options[4].type = ZOV_Color; } else if (widgetName == "Text") { zone.widgetData.options[1].type = ZOV_Color; } } } static void patchModelData(uint8_t* data) { auto md = reinterpret_cast(data); for (auto& screen : md->screenData) { if (!strnlen(screen.LayoutId, sizeof(screen.LayoutId))) break; patchWidgetOptions(screen.layoutData.zones, MAX_LAYOUT_ZONES); } patchWidgetOptions(md->topbarData.zones, MAX_TOPBAR_ZONES); } #else #define patchModelData nullptr #endif const char* convertModelData_220_to_221(const char* path) { constexpr unsigned md_size = sizeof(bin_storage_220::ModelData); return convertData_220_to_221(path, md_size, yaml_conv_220::get_modeldata_nodes(), patchModelData); } static void patchRadioData(uint8_t* data) { auto rd = reinterpret_cast(data); rd->version = 221; patchFilenameToYaml(rd->currModelFilename); } const char* convertRadioData_220_to_221(const char* path) { constexpr unsigned rd_size = sizeof(bin_storage_220::RadioData); return convertData_220_to_221(path, rd_size, yaml_conv_220::get_radiodata_nodes(), patchRadioData); } #else #include constexpr uint8_t MODELIDX_STRLEN = sizeof(MODEL_FILENAME_PREFIX "00"); static void getModelNumberStr(uint8_t idx, char* model_idx) { memcpy(model_idx, MODEL_FILENAME_PREFIX, sizeof(MODEL_FILENAME_PREFIX)); model_idx[sizeof(MODEL_FILENAME_PREFIX)-1] = '0' + idx / 10; model_idx[sizeof(MODEL_FILENAME_PREFIX)] = '0' + idx % 10; model_idx[sizeof(MODEL_FILENAME_PREFIX)+1] = '\0'; } const char* convertModelData_220_to_221(uint8_t id) { constexpr unsigned size = sizeof(bin_storage_220::ModelData); auto data = reinterpret_cast(malloc(size)); memset(data, 0, size); const char* error = nullptr; uint16_t read = eeLoadModelData(id, data, size); if (read == size) { char model_idx[MODELIDX_STRLEN + sizeof(YAML_EXT)]; getModelNumberStr(id, model_idx); GET_FILENAME(path, MODELS_PATH, model_idx, YAML_EXT); error = writeFileYaml(path, yaml_conv_220::get_modeldata_nodes(), data); } else { // ERROR: size mismatch !!! } free(data); return error; } const char* convertRadioData_220_to_221() { constexpr unsigned size = sizeof(bin_storage_220::RadioData); auto data = reinterpret_cast(malloc(size)); memset(data, 0, size); const char* error = nullptr; uint16_t read = eeLoadGeneralSettingsData(data, size); if (read == size) { error = writeFileYaml(RADIO_SETTINGS_YAML_PATH, yaml_conv_220::get_radiodata_nodes(), data); } else { // ERROR: size mismatch !!! } free(data); return error; } #endif