From f36d01d560840fa5cb6e1eba338d4bd6300cfe95 Mon Sep 17 00:00:00 2001 From: Damjan Adamic Date: Tue, 21 Feb 2017 10:59:47 +0100 Subject: [PATCH] Fixes #4438: wrong cast used when setting Lua mixer script input source (#4470) * Fixes #4438: wrong cast used when setting Lua mixer script input source Improved parsing of Lua mixer script inputs * Additional type check * ScriptDataInput union introduced. Fixed: when using SOURCE input, do not use default value Fixed: when using SOURCE input, min-max range is fixed --- radio/src/datastructs.h | 11 ++++-- radio/src/gui/128x64/model_custom_scripts.cpp | 14 ++++---- radio/src/gui/212x64/model_custom_scripts.cpp | 14 ++++---- .../src/gui/480x272/model_custom_scripts.cpp | 14 ++++---- radio/src/lua/api_general.cpp | 4 +-- radio/src/lua/interface.cpp | 36 ++++++++++++------- radio/src/lua/lua_api.h | 7 ++++ 7 files changed, 65 insertions(+), 35 deletions(-) diff --git a/radio/src/datastructs.h b/radio/src/datastructs.h index 870ed1f17..3f6436560 100644 --- a/radio/src/datastructs.h +++ b/radio/src/datastructs.h @@ -453,10 +453,15 @@ PACK(struct SwashRingData { #endif #if MAX_SCRIPTS > 0 +union ScriptDataInput { + int16_t value; + source_t source; +}; + PACK(struct ScriptData { - char file[LEN_SCRIPT_FILENAME]; - char name[LEN_SCRIPT_NAME]; - int16_t inputs[MAX_SCRIPT_INPUTS]; + char file[LEN_SCRIPT_FILENAME]; + char name[LEN_SCRIPT_NAME]; + ScriptDataInput inputs[MAX_SCRIPT_INPUTS]; }); #endif diff --git a/radio/src/gui/128x64/model_custom_scripts.cpp b/radio/src/gui/128x64/model_custom_scripts.cpp index 19afd5ea4..75a1d5e5a 100644 --- a/radio/src/gui/128x64/model_custom_scripts.cpp +++ b/radio/src/gui/128x64/model_custom_scripts.cpp @@ -96,17 +96,19 @@ void menuModelCustomScriptOne(event_t event) else if (i <= ITEM_MODEL_CUSTOMSCRIPT_PARAMS_LABEL+scriptInputsOutputs[s_currIdx].inputsCount) { int inputIdx = i-ITEM_MODEL_CUSTOMSCRIPT_PARAMS_LABEL-1; lcdDrawSizedText(INDENT_WIDTH, y, scriptInputsOutputs[s_currIdx].inputs[inputIdx].name, 10, 0); - if (scriptInputsOutputs[s_currIdx].inputs[inputIdx].type == 0) { - lcdDrawNumber(SCRIPT_ONE_2ND_COLUMN_POS, y, g_model.scriptsData[s_currIdx].inputs[inputIdx]+scriptInputsOutputs[s_currIdx].inputs[inputIdx].def, attr|LEFT); + if (scriptInputsOutputs[s_currIdx].inputs[inputIdx].type == INPUT_TYPE_VALUE) { + lcdDrawNumber(SCRIPT_ONE_2ND_COLUMN_POS, y, g_model.scriptsData[s_currIdx].inputs[inputIdx].value+ \ + scriptInputsOutputs[s_currIdx].inputs[inputIdx].def, attr|LEFT); if (attr) { - CHECK_INCDEC_MODELVAR(event, g_model.scriptsData[s_currIdx].inputs[inputIdx], scriptInputsOutputs[s_currIdx].inputs[inputIdx].min-scriptInputsOutputs[s_currIdx].inputs[inputIdx].def, scriptInputsOutputs[s_currIdx].inputs[inputIdx].max-scriptInputsOutputs[s_currIdx].inputs[inputIdx].def); + CHECK_INCDEC_MODELVAR(event, g_model.scriptsData[s_currIdx].inputs[inputIdx].value, \ + scriptInputsOutputs[s_currIdx].inputs[inputIdx].min-scriptInputsOutputs[s_currIdx].inputs[inputIdx].def, \ + scriptInputsOutputs[s_currIdx].inputs[inputIdx].max-scriptInputsOutputs[s_currIdx].inputs[inputIdx].def); } } else { - uint8_t *source = (uint8_t *)&g_model.scriptsData[s_currIdx].inputs[inputIdx]; - drawSource(SCRIPT_ONE_2ND_COLUMN_POS, y, *source + scriptInputsOutputs[s_currIdx].inputs[inputIdx].def, attr); + drawSource(SCRIPT_ONE_2ND_COLUMN_POS, y, g_model.scriptsData[s_currIdx].inputs[inputIdx].source , attr); if (attr) { - CHECK_INCDEC_MODELSOURCE(event, *source, scriptInputsOutputs[s_currIdx].inputs[inputIdx].min-scriptInputsOutputs[s_currIdx].inputs[inputIdx].def, scriptInputsOutputs[s_currIdx].inputs[inputIdx].max-scriptInputsOutputs[s_currIdx].inputs[inputIdx].def); + CHECK_INCDEC_MODELSOURCE(event, g_model.scriptsData[s_currIdx].inputs[inputIdx].source, 0, MIXSRC_LAST_TELEM); } } } diff --git a/radio/src/gui/212x64/model_custom_scripts.cpp b/radio/src/gui/212x64/model_custom_scripts.cpp index a67364314..e0f052de5 100644 --- a/radio/src/gui/212x64/model_custom_scripts.cpp +++ b/radio/src/gui/212x64/model_custom_scripts.cpp @@ -89,17 +89,19 @@ void menuModelCustomScriptOne(event_t event) else if (i <= ITEM_MODEL_CUSTOMSCRIPT_PARAMS_LABEL+scriptInputsOutputs[s_currIdx].inputsCount) { int inputIdx = i-ITEM_MODEL_CUSTOMSCRIPT_PARAMS_LABEL-1; lcdDrawSizedText(INDENT_WIDTH, y, scriptInputsOutputs[s_currIdx].inputs[inputIdx].name, 10, 0); - if (scriptInputsOutputs[s_currIdx].inputs[inputIdx].type == 0) { - lcdDrawNumber(SCRIPT_ONE_2ND_COLUMN_POS, y, g_model.scriptsData[s_currIdx].inputs[inputIdx]+scriptInputsOutputs[s_currIdx].inputs[inputIdx].def, attr|LEFT); + if (scriptInputsOutputs[s_currIdx].inputs[inputIdx].type == INPUT_TYPE_VALUE) { + lcdDrawNumber(SCRIPT_ONE_2ND_COLUMN_POS, y, g_model.scriptsData[s_currIdx].inputs[inputIdx].value+ \ + scriptInputsOutputs[s_currIdx].inputs[inputIdx].def, attr|LEFT); if (attr) { - CHECK_INCDEC_MODELVAR(event, g_model.scriptsData[s_currIdx].inputs[inputIdx], scriptInputsOutputs[s_currIdx].inputs[inputIdx].min-scriptInputsOutputs[s_currIdx].inputs[inputIdx].def, scriptInputsOutputs[s_currIdx].inputs[inputIdx].max-scriptInputsOutputs[s_currIdx].inputs[inputIdx].def); + CHECK_INCDEC_MODELVAR(event, g_model.scriptsData[s_currIdx].inputs[inputIdx].value, \ + scriptInputsOutputs[s_currIdx].inputs[inputIdx].min-scriptInputsOutputs[s_currIdx].inputs[inputIdx].def, \ + scriptInputsOutputs[s_currIdx].inputs[inputIdx].max-scriptInputsOutputs[s_currIdx].inputs[inputIdx].def); } } else { - uint8_t *source = (uint8_t *)&g_model.scriptsData[s_currIdx].inputs[inputIdx]; - drawSource(SCRIPT_ONE_2ND_COLUMN_POS, y, *source + scriptInputsOutputs[s_currIdx].inputs[inputIdx].def, attr); + drawSource(SCRIPT_ONE_2ND_COLUMN_POS, y, g_model.scriptsData[s_currIdx].inputs[inputIdx].source, attr); if (attr) { - CHECK_INCDEC_MODELSOURCE(event, *source, scriptInputsOutputs[s_currIdx].inputs[inputIdx].min-scriptInputsOutputs[s_currIdx].inputs[inputIdx].def, scriptInputsOutputs[s_currIdx].inputs[inputIdx].max-scriptInputsOutputs[s_currIdx].inputs[inputIdx].def); + CHECK_INCDEC_MODELSOURCE(event, g_model.scriptsData[s_currIdx].inputs[inputIdx].source, 0, MIXSRC_LAST_TELEM); } } } diff --git a/radio/src/gui/480x272/model_custom_scripts.cpp b/radio/src/gui/480x272/model_custom_scripts.cpp index d9b9bc9ed..7134a1133 100644 --- a/radio/src/gui/480x272/model_custom_scripts.cpp +++ b/radio/src/gui/480x272/model_custom_scripts.cpp @@ -89,17 +89,19 @@ bool menuModelCustomScriptOne(event_t event) else if (i <= ITEM_MODEL_CUSTOMSCRIPT_PARAMS_LABEL+scriptInputsOutputs[s_currIdx].inputsCount) { int inputIdx = i-ITEM_MODEL_CUSTOMSCRIPT_PARAMS_LABEL-1; lcdDrawSizedText(INDENT_WIDTH, y, scriptInputsOutputs[s_currIdx].inputs[inputIdx].name, 10, 0); - if (scriptInputsOutputs[s_currIdx].inputs[inputIdx].type == 0) { - lcdDrawNumber(SCRIPT_ONE_2ND_COLUMN_POS, y, g_model.scriptsData[s_currIdx].inputs[inputIdx]+scriptInputsOutputs[s_currIdx].inputs[inputIdx].def, attr|LEFT); + if (scriptInputsOutputs[s_currIdx].inputs[inputIdx].type == INPUT_TYPE_VALUE) { + lcdDrawNumber(SCRIPT_ONE_2ND_COLUMN_POS, y, g_model.scriptsData[s_currIdx].inputs[inputIdx].value+ \ + scriptInputsOutputs[s_currIdx].inputs[inputIdx].def, attr|LEFT); if (attr) { - CHECK_INCDEC_MODELVAR(event, g_model.scriptsData[s_currIdx].inputs[inputIdx], scriptInputsOutputs[s_currIdx].inputs[inputIdx].min-scriptInputsOutputs[s_currIdx].inputs[inputIdx].def, scriptInputsOutputs[s_currIdx].inputs[inputIdx].max-scriptInputsOutputs[s_currIdx].inputs[inputIdx].def); + CHECK_INCDEC_MODELVAR(event, g_model.scriptsData[s_currIdx].inputs[inputIdx].value, \ + scriptInputsOutputs[s_currIdx].inputs[inputIdx].min-scriptInputsOutputs[s_currIdx].inputs[inputIdx].def, \ + scriptInputsOutputs[s_currIdx].inputs[inputIdx].max-scriptInputsOutputs[s_currIdx].inputs[inputIdx].def); } } else { - uint8_t *source = (uint8_t *)&g_model.scriptsData[s_currIdx].inputs[inputIdx]; - drawSource(SCRIPT_ONE_2ND_COLUMN_POS, y, *source + scriptInputsOutputs[s_currIdx].inputs[inputIdx].def, attr); + drawSource(SCRIPT_ONE_2ND_COLUMN_POS, y, g_model.scriptsData[s_currIdx].inputs[inputIdx].source, attr); if (attr) { - CHECK_INCDEC_MODELSOURCE(event, *source, scriptInputsOutputs[s_currIdx].inputs[inputIdx].min-scriptInputsOutputs[s_currIdx].inputs[inputIdx].def, scriptInputsOutputs[s_currIdx].inputs[inputIdx].max-scriptInputsOutputs[s_currIdx].inputs[inputIdx].def); + CHECK_INCDEC_MODELSOURCE(event, g_model.scriptsData[s_currIdx].inputs[inputIdx].source, 0, MIXSRC_LAST_TELEM); } } } diff --git a/radio/src/lua/api_general.cpp b/radio/src/lua/api_general.cpp index 18902946b..4d51ed1a4 100644 --- a/radio/src/lua/api_general.cpp +++ b/radio/src/lua/api_general.cpp @@ -1230,8 +1230,8 @@ const luaR_value_entry opentxConstants[] = { { "LEFT", LEFT }, { "PREC1", PREC1 }, { "PREC2", PREC2 }, - { "VALUE", 0 }, // TODO reuse ZoneOption::Integer - { "SOURCE", 1 }, // TODO reuse ZoneOption::Source + { "VALUE", INPUT_TYPE_VALUE }, + { "SOURCE", INPUT_TYPE_SOURCE }, { "REPLACE", MLTPX_REP }, { "MIXSRC_FIRST_INPUT", MIXSRC_FIRST_INPUT }, { "MIXSRC_Rud", MIXSRC_Rud }, diff --git a/radio/src/lua/interface.cpp b/radio/src/lua/interface.cpp index 654716e55..2404ae3c7 100644 --- a/radio/src/lua/interface.cpp +++ b/radio/src/lua/interface.cpp @@ -84,45 +84,57 @@ int luaGetInputs(lua_State * L, ScriptInputsOutputs & sid) if (!lua_istable(L, -1)) return -1; + memclear(sid.inputs, sizeof(sid.inputs)); sid.inputsCount = 0; for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) { luaL_checktype(L, -2, LUA_TNUMBER); // key is number luaL_checktype(L, -1, LUA_TTABLE); // value is table if (sid.inputsCountname = lua_tostring(L, -1); break; case 1: luaL_checktype(L, -2, LUA_TNUMBER); // key is number luaL_checktype(L, -1, LUA_TNUMBER); // value is number - sid.inputs[sid.inputsCount].type = lua_tointeger(L, -1); - if (sid.inputs[sid.inputsCount].type == 0) { - sid.inputs[sid.inputsCount].min = -100; - sid.inputs[sid.inputsCount].max = 100; + type = lua_tointeger(L, -1); + if (type >= INPUT_TYPE_FIRST && type <= INPUT_TYPE_LAST) { + si->type = type; + } + if (si->type == INPUT_TYPE_VALUE) { + si->min = -100; + si->max = 100; } else { - sid.inputs[sid.inputsCount].max = MIXSRC_LAST_TELEM; + si->max = MIXSRC_LAST_TELEM; } break; case 2: luaL_checktype(L, -2, LUA_TNUMBER); // key is number luaL_checktype(L, -1, LUA_TNUMBER); // value is number - sid.inputs[sid.inputsCount].min = lua_tointeger(L, -1); + if (si->type == INPUT_TYPE_VALUE) { + si->min = lua_tointeger(L, -1); + } break; case 3: luaL_checktype(L, -2, LUA_TNUMBER); // key is number luaL_checktype(L, -1, LUA_TNUMBER); // value is number - sid.inputs[sid.inputsCount].max = lua_tointeger(L, -1); + if (si->type == INPUT_TYPE_VALUE) { + si->max = lua_tointeger(L, -1); + } break; case 4: luaL_checktype(L, -2, LUA_TNUMBER); // key is number luaL_checktype(L, -1, LUA_TNUMBER); // value is number - sid.inputs[sid.inputsCount].def = lua_tointeger(L, -1); + if (si->type == INPUT_TYPE_VALUE) { + si->def = lua_tointeger(L, -1); + } break; } } @@ -830,10 +842,10 @@ bool luaDoOneRunPermanentScript(event_t evt, int i, uint32_t scriptType) #endif lua_rawgeti(lsScripts, LUA_REGISTRYINDEX, sid.run); for (int j=0; jinputsCount; j++) { - if (sio->inputs[j].type == 1) - luaGetValueAndPush(lsScripts, (uint8_t)sd.inputs[j]); + if (sio->inputs[j].type == INPUT_TYPE_SOURCE) + luaGetValueAndPush(lsScripts, sd.inputs[j].source); else - lua_pushinteger(lsScripts, sd.inputs[j] + sio->inputs[j].def); + lua_pushinteger(lsScripts, sd.inputs[j].value + sio->inputs[j].def); } } else if ((scriptType & RUN_FUNC_SCRIPT) && (sid.reference >= SCRIPT_FUNC_FIRST && sid.reference <= SCRIPT_FUNC_LAST)) { diff --git a/radio/src/lua/lua_api.h b/radio/src/lua/lua_api.h index af69f6583..613ab235e 100644 --- a/radio/src/lua/lua_api.h +++ b/radio/src/lua/lua_api.h @@ -69,6 +69,13 @@ void luaInitThemesAndWidgets(); #define RUN_TELEM_FG_SCRIPT (1 << 3) #define RUN_STNDAL_SCRIPT (1 << 4) +enum luaScriptInputType { + INPUT_TYPE_FIRST = 0, + INPUT_TYPE_VALUE = INPUT_TYPE_FIRST, + INPUT_TYPE_SOURCE, + INPUT_TYPE_LAST = INPUT_TYPE_SOURCE +}; + struct ScriptInput { const char *name; uint8_t type;