MixData* setDest(uint8_t dch, uint8_t src, bool clear=false) { uint8_t i = 0; MixData * mix; while (1) { mix = mixAddress(i); if (mix->srcRaw && mix->destCh <= dch) { if (clear && mix->destCh == dch) { deleteExpoMix(0, i); } else { if (++i==MAX_MIXERS) { // TODO should return null pointer but needs to be tested then mix = mixAddress(0); break; } } } else { break; } } memmove(mix+1, mix, (MAX_MIXERS-(i+1))*sizeof(MixData) ); memclear(mix, sizeof(MixData)); mix->destCh = dch; mix->srcRaw = src; mix->weight = 100; return mix; }
void onExpoMixMenu(const char *result) { bool expo = (g_menuStack[g_menuStackPtr] == menuModelExposAll); uint8_t chn = (expo ? expoAddress(s_currIdx)->chn+1 : mixAddress(s_currIdx)->destCh+1); if (result == STR_EDIT) { pushMenu(expo ? menuModelExpoOne : menuModelMixOne); } else if (result == STR_INSERT_BEFORE || result == STR_INSERT_AFTER) { if (!reachExpoMixCountLimit(expo)) { s_currCh = chn; if (result == STR_INSERT_AFTER) { s_currIdx++; m_posVert++; } insertExpoMix(expo, s_currIdx); pushMenu(expo ? menuModelExpoOne : menuModelMixOne); } } else if (result == STR_COPY || result == STR_MOVE) { s_copyMode = (result == STR_COPY ? COPY_MODE : MOVE_MODE); s_copySrcIdx = s_currIdx; s_copySrcCh = chn; s_copySrcRow = m_posVert; } else if (result == STR_DELETE) { deleteExpoMix(expo, s_currIdx); } }
void insertExpoMix(uint8_t expo, uint8_t idx) { pauseMixerCalculations(); if (expo) { ExpoData *expo = expoAddress(idx); memmove(expo+1, expo, (MAX_EXPOS-(idx+1))*sizeof(ExpoData)); memclear(expo, sizeof(ExpoData)); expo->srcRaw = (s_currCh > 4 ? MIXSRC_Rud - 1 + s_currCh : MIXSRC_Rud - 1 + channel_order(s_currCh)); expo->curve.type = CURVE_REF_EXPO; expo->mode = 3; // pos&neg expo->chn = s_currCh - 1; expo->weight = 100; } else { MixData *mix = mixAddress(idx); memmove(mix+1, mix, (MAX_MIXERS-(idx+1))*sizeof(MixData)); memclear(mix, sizeof(MixData)); mix->destCh = s_currCh-1; mix->srcRaw = s_currCh; if (!isSourceAvailable(mix->srcRaw)) { mix->srcRaw = (s_currCh > 4 ? MIXSRC_Rud - 1 + s_currCh : MIXSRC_Rud - 1 + channel_order(s_currCh)); while (!isSourceAvailable(mix->srcRaw)) { mix->srcRaw += 1; } } mix->weight = 100; } resumeMixerCalculations(); eeDirty(EE_MODEL); }
static int luaModelGetMix(lua_State *L) { unsigned int chn = luaL_checkunsigned(L, 1); unsigned int idx = luaL_checkunsigned(L, 2); unsigned int first = getFirstMix(chn); unsigned int count = getMixesCountFromFirst(chn, first); if (idx < count) { MixData * mix = mixAddress(first+idx); lua_newtable(L); lua_pushtablezstring(L, "name", mix->name); lua_pushtableinteger(L, "source", mix->srcRaw); lua_pushtableinteger(L, "weight", mix->weight); lua_pushtableinteger(L, "offset", mix->offset); lua_pushtableinteger(L, "switch", mix->swtch); lua_pushtableinteger(L, "curveType", mix->curve.type); lua_pushtableinteger(L, "curveValue", mix->curve.value); lua_pushtableinteger(L, "multiplex", mix->mltpx); lua_pushtableinteger(L, "flightModes", mix->flightModes); lua_pushtableboolean(L, "carryTrim", mix->carryTrim); lua_pushtableinteger(L, "mixWarn", mix->mixWarn); lua_pushtableinteger(L, "delayUp", mix->delayUp); lua_pushtableinteger(L, "delayDown", mix->delayDown); lua_pushtableinteger(L, "speedUp", mix->speedUp); lua_pushtableinteger(L, "speedDown", mix->speedDown); } else { lua_pushnil(L); } return 1; }
bool isThrottleOutput(uint8_t ch) { for (int i=0; i<MAX_MIXERS; i++) { MixData *mix = mixAddress(i); if (mix->destCh==ch && mix->srcRaw==MIXSRC_Thr) return true; } return false; }
static unsigned int getMixesCountFromFirst(unsigned int chn, unsigned int first) { unsigned int count = 0; for (unsigned int i=first; i<MAX_MIXERS; i++) { MixData * mix = mixAddress(i); if (!mix->srcRaw || mix->destCh!=chn) break; count++; } return count; }
static unsigned int getFirstMix(unsigned int chn) { for (unsigned int i=0; i<MAX_MIXERS; i++) { MixData * mix = mixAddress(i); if (!mix->srcRaw || mix->destCh>=chn) { return i; } } return 0; }
bool isSourceAvailable(int source) { #if defined(PCBTARANIS) if (source>=MIXSRC_FIRST_INPUT && source<=MIXSRC_LAST_INPUT) { return isInputAvailable(source - MIXSRC_FIRST_INPUT); } #endif #if defined(LUA_MODEL_SCRIPTS) if (source>=MIXSRC_FIRST_LUA && source<=MIXSRC_LAST_LUA) { div_t qr = div(source-MIXSRC_FIRST_LUA, MAX_SCRIPT_OUTPUTS); return (qr.rem<scriptInputsOutputs[qr.quot].outputsCount); } #elif defined(PCBTARANIS) if (source>=MIXSRC_FIRST_LUA && source<=MIXSRC_LAST_LUA) return false; #endif #if defined(PCBTARANIS) if (source>=MIXSRC_FIRST_POT && source<=MIXSRC_LAST_POT) { return IS_POT_AVAILABLE(POT1+source-MIXSRC_FIRST_POT); } #endif #if !defined(HELI) if (source>=MIXSRC_CYC1 && source<=MIXSRC_CYC3) return false; #endif if (source>=MIXSRC_CH1 && source<=MIXSRC_LAST_CH) { uint8_t destCh = source-MIXSRC_CH1; for (uint8_t i = 0; i < MAX_MIXERS; i++) { MixData *md = mixAddress(i); if (md->srcRaw == 0) return false; if (md->destCh==destCh) return true; } return false; } if (source>=MIXSRC_SW1 && source<=MIXSRC_LAST_LOGICAL_SWITCH) { LogicalSwitchData * cs = lswAddress(source-MIXSRC_SW1); return (cs->func != LS_FUNC_NONE); } #if !defined(GVARS) if (source>=MIXSRC_GVAR1 && source<=MIXSRC_LAST_GVAR) return false; #endif if (source>=MIXSRC_FIRST_TELEM && source<=MIXSRC_LAST_TELEM) return isTelemetrySourceAvailable(source-MIXSRC_FIRST_TELEM+1); return true; }
uint8_t getExpoMixCount(uint8_t expo) { uint8_t count = 0; uint8_t ch ; for (int i=(expo ? MAX_EXPOS-1 : MAX_MIXERS-1); i>=0; i--) { ch = (expo ? EXPO_VALID(expoAddress(i)) : mixAddress(i)->srcRaw); if (ch != 0) { count++; } } return count; }
void copyExpoMix(uint8_t expo, uint8_t idx) { pauseMixerCalculations(); if (expo) { ExpoData *expo = expoAddress(idx); memmove(expo+1, expo, (MAX_EXPOS-(idx+1))*sizeof(ExpoData)); } else { MixData *mix = mixAddress(idx); memmove(mix+1, mix, (MAX_MIXERS-(idx+1))*sizeof(MixData)); } resumeMixerCalculations(); eeDirty(EE_MODEL); }
void deleteExpoMix(uint8_t expo, uint8_t idx) { pauseMixerCalculations(); if (expo) { ExpoData *expo = expoAddress(idx); int input = expo->chn; memmove(expo, expo+1, (MAX_EXPOS-(idx+1))*sizeof(ExpoData)); memclear(&g_model.expoData[MAX_EXPOS-1], sizeof(ExpoData)); if (!isInputAvailable(input)) { memclear(&g_model.inputNames[input], LEN_INPUT_NAME); } } else { MixData *mix = mixAddress(idx); memmove(mix, mix+1, (MAX_MIXERS-(idx+1))*sizeof(MixData)); memclear(&g_model.mixData[MAX_MIXERS-1], sizeof(MixData)); } resumeMixerCalculations(); eeDirty(EE_MODEL); }
void menuModelExpoMix(uint8_t expo, uint8_t event) { uint8_t sub = m_posVert; if (s_editMode > 0) s_editMode = 0; uint8_t chn = (expo ? expoAddress(s_currIdx)->chn+1 : mixAddress(s_currIdx)->destCh+1); switch (event) { case EVT_ENTRY: case EVT_ENTRY_UP: s_copyMode = 0; s_copyTgtOfs = 0; break; case EVT_KEY_LONG(KEY_EXIT): if (s_copyMode && s_copyTgtOfs == 0) { deleteExpoMix(expo, s_currIdx); killEvents(event); event = 0; } // no break case EVT_KEY_BREAK(KEY_EXIT): if (s_copyMode) { if (s_copyTgtOfs) { // cancel the current copy / move operation if (s_copyMode == COPY_MODE) { deleteExpoMix(expo, s_currIdx); } else { do { swapExpoMix(expo, s_currIdx, s_copyTgtOfs > 0); s_copyTgtOfs += (s_copyTgtOfs < 0 ? +1 : -1); } while (s_copyTgtOfs != 0); eeDirty(EE_MODEL); } m_posVert = s_copySrcRow; s_copyTgtOfs = 0; } s_copyMode = 0; event = 0; } break; case EVT_KEY_BREAK(KEY_ENTER): if ((!s_currCh || (s_copyMode && !s_copyTgtOfs)) && !READ_ONLY()) { s_copyMode = (s_copyMode == COPY_MODE ? MOVE_MODE : COPY_MODE); s_copySrcIdx = s_currIdx; s_copySrcCh = chn; s_copySrcRow = sub; break; } // no break case EVT_KEY_LONG(KEY_ENTER): killEvents(event); if (s_copyTgtOfs) { s_copyMode = 0; s_copyTgtOfs = 0; } else { if (READ_ONLY()) { if (!s_currCh) { pushMenu(expo ? menuModelExpoOne : menuModelMixOne); } } else { if (s_copyMode) s_currCh = 0; if (s_currCh) { if (reachExpoMixCountLimit(expo)) break; insertExpoMix(expo, s_currIdx); pushMenu(expo ? menuModelExpoOne : menuModelMixOne); s_copyMode = 0; } else { event = 0; s_copyMode = 0; MENU_ADD_ITEM(STR_EDIT); MENU_ADD_ITEM(STR_INSERT_BEFORE); MENU_ADD_ITEM(STR_INSERT_AFTER); MENU_ADD_ITEM(STR_COPY); MENU_ADD_ITEM(STR_MOVE); MENU_ADD_ITEM(STR_DELETE); menuHandler = onExpoMixMenu; } } } break; case EVT_KEY_LONG(KEY_LEFT): case EVT_KEY_LONG(KEY_RIGHT): if (s_copyMode && !s_copyTgtOfs) { if (reachExpoMixCountLimit(expo)) break; s_currCh = chn; if (event == EVT_KEY_LONG(KEY_RIGHT)) { s_currIdx++; m_posVert++; } insertExpoMix(expo, s_currIdx); pushMenu(expo ? menuModelExpoOne : menuModelMixOne); s_copyMode = 0; killEvents(event); } break; case EVT_KEY_FIRST(KEY_MOVE_UP): case EVT_KEY_REPT(KEY_MOVE_UP): case EVT_KEY_FIRST(KEY_MOVE_DOWN): case EVT_KEY_REPT(KEY_MOVE_DOWN): if (s_copyMode) { uint8_t key = (event & 0x1f); uint8_t next_ofs = (key==KEY_MOVE_UP ? s_copyTgtOfs - 1 : s_copyTgtOfs + 1); if (s_copyTgtOfs==0 && s_copyMode==COPY_MODE) { // insert a mix on the same channel (just above / just below) if (reachExpoMixCountLimit(expo)) break; copyExpoMix(expo, s_currIdx); if (key==KEY_MOVE_DOWN) s_currIdx++; else if (sub-s_pgOfs >= 6) s_pgOfs++; } else if (next_ofs==0 && s_copyMode==COPY_MODE) { // delete the mix deleteExpoMix(expo, s_currIdx); if (key==KEY_MOVE_UP) s_currIdx--; } else { // only swap the mix with its neighbor if (!swapExpoMix(expo, s_currIdx, key==KEY_MOVE_UP)) break; eeDirty(EE_MODEL); } s_copyTgtOfs = next_ofs; } break; } if (expo) { lcd_outdezAtt(FW*sizeof(TR_MENUINPUTS)+FW+FW/2, 0, getExpoMixCount(true)); lcd_puts(FW*sizeof(TR_MENUINPUTS)+FW+FW/2, 0, STR_MAX(MAX_EXPOS)); // Value uint8_t index = expoAddress(s_currIdx)->chn; if (!s_currCh) { lcd_outdezAtt(127, 2, calcRESXto1000(anas[index]), PREC1|TINSIZE); } SIMPLE_MENU(STR_MENUINPUTS, menuTabModel, e_InputsAll, s_maxLines); // Gauge if (!s_currCh) { drawGauge(127, 1, 58, 6, anas[index], 1024); } } else { lcd_outdezAtt(FW*sizeof(TR_MIXER)+FW+FW/2, 0, getExpoMixCount(false)); lcd_puts(FW*sizeof(TR_MIXER)+FW+FW/2, 0, STR_MAX(MAX_MIXERS)); // Value uint8_t index = mixAddress(s_currIdx)->destCh; if (!s_currCh) { displayHeaderChannelName(index); lcd_outdezAtt(127, 2, calcRESXto1000(ex_chans[index]), PREC1|TINSIZE); } SIMPLE_MENU(STR_MIXER, menuTabModel, e_MixAll, s_maxLines); // Gauge if (!s_currCh) { drawGauge(127, 1, 58, 6, ex_chans[index], 1024); } } sub = m_posVert; s_currCh = 0; int cur = 0; int i = 0; for (int ch=1; ch<=(expo ? NUM_INPUTS : NUM_CHNOUT); ch++) { void *pointer = NULL; MixData * &md = (MixData * &)pointer; ExpoData * &ed = (ExpoData * &)pointer; coord_t y = MENU_HEADER_HEIGHT+1+(cur-s_pgOfs)*FH; if (expo ? (i<MAX_EXPOS && (ed=expoAddress(i))->chn+1 == ch && EXPO_VALID(ed)) : (i<MAX_MIXERS && (md=mixAddress(i))->srcRaw && md->destCh+1 == ch)) { if (cur-s_pgOfs >= 0 && cur-s_pgOfs < NUM_BODY_LINES) { if (expo) { putsMixerSource(0, y, ch, 0); } else { putsChn(0, y, ch, 0); // show CHx } } uint8_t mixCnt = 0; do { if (s_copyMode) { if (s_copyMode == MOVE_MODE && cur-s_pgOfs >= 0 && cur-s_pgOfs < NUM_BODY_LINES && s_copySrcCh == ch && s_copyTgtOfs != 0 && i == (s_copySrcIdx + (s_copyTgtOfs<0))) { lcd_rect(expo ? 18 : 22, y-1, expo ? LCD_W-18 : LCD_W-22, 9, DOTTED); cur++; y+=FH; } if (s_currIdx == i) { sub = m_posVert = cur; s_currCh = ch; } } else if (sub == cur) { s_currIdx = i; } if (cur-s_pgOfs >= 0 && cur-s_pgOfs < NUM_BODY_LINES) { uint8_t attr = ((s_copyMode || sub != cur) ? 0 : INVERS); if (expo) { GVAR_MENU_ITEM(EXPO_LINE_WEIGHT_POS, y, ed->weight, MIN_EXPO_WEIGHT, 100, attr | (isExpoActive(i) ? BOLD : 0), 0, 0); displayExpoLine(y, ed); if (ed->mode!=3) { lcd_putc(EXPO_LINE_SIDE_POS, y, ed->mode == 2 ? 126 : 127); } } else { if (mixCnt > 0) lcd_putsiAtt(FW, y, STR_VMLTPX2, md->mltpx, 0); putsMixerSource(MIX_LINE_SRC_POS, y, md->srcRaw, 0); gvarWeightItem(MIX_LINE_WEIGHT_POS, y, md, attr | (isMixActive(i) ? BOLD : 0), 0); displayMixLine(y, md); char cs = ' '; if (md->speedDown || md->speedUp) cs = 'S'; if (md->delayUp || md->delayDown) cs = (cs =='S' ? '*' : 'D'); lcd_putc(MIX_LINE_DELAY_POS, y, cs); } if (s_copyMode) { if ((s_copyMode==COPY_MODE || s_copyTgtOfs == 0) && s_copySrcCh == ch && i == (s_copySrcIdx + (s_copyTgtOfs<0))) { /* draw a border around the raw on selection mode (copy/move) */ lcd_rect(expo ? EXPO_LINE_SELECT_POS : 22, y-1, expo ? (LCD_W-EXPO_LINE_SELECT_POS) : (LCD_W-22), 9, s_copyMode == COPY_MODE ? SOLID : DOTTED); } if (cur == sub) { /* invert the raw when it's the current one */ drawFilledRect(expo ? EXPO_LINE_SELECT_POS+1 : 23, y, expo ? (LCD_W-EXPO_LINE_SELECT_POS-2) : (LCD_W-24), 7); } } } cur++; y+=FH; mixCnt++; i++; if (expo) ed++; else md++; } while (expo ? (i<MAX_EXPOS && ed->chn+1 == ch && EXPO_VALID(ed)) : (i<MAX_MIXERS && md->srcRaw && md->destCh+1 == ch)); if (s_copyMode == MOVE_MODE && cur-s_pgOfs >= 0 && cur-s_pgOfs < NUM_BODY_LINES && s_copySrcCh == ch && i == (s_copySrcIdx + (s_copyTgtOfs<0))) { lcd_rect(expo ? EXPO_LINE_SELECT_POS : 22, y-1, expo ? LCD_W-EXPO_LINE_SELECT_POS : LCD_W-22, 9, DOTTED); cur++; y+=FH; } } else { uint8_t attr = 0; if (sub == cur) { s_currIdx = i; s_currCh = ch; if (!s_copyMode) { attr = INVERS; } } if (cur-s_pgOfs >= 0 && cur-s_pgOfs < NUM_BODY_LINES) { if (expo) { putsMixerSource(0, y, ch, attr); } else { putsChn(0, y, ch, attr); // show CHx } if (s_copyMode == MOVE_MODE && s_copySrcCh == ch) { lcd_rect(expo ? EXPO_LINE_SELECT_POS : 22, y-1, expo ? (LCD_W-EXPO_LINE_SELECT_POS) : (LCD_W-22), 9, DOTTED); } } cur++; y+=FH; } } s_maxLines = cur; if (sub >= s_maxLines-1) m_posVert = s_maxLines-1; }
void menuModelMixOne(uint8_t event) { if (event == EVT_KEY_LONG(KEY_MENU)) { pushMenu(menuChannelsView); killEvents(event); } TITLE(s_currCh ? STR_INSERTMIX : STR_EDITMIX); MixData *md2 = mixAddress(s_currIdx) ; putsChn(lcdLastPos+1*FW, 0, md2->destCh+1,0); SUBMENU_NOTITLE(MIX_FIELD_COUNT, {0, 0, 0, 0, 0, CASE_CURVES(1) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0, 0 /*, ...*/}); #if MENU_COLUMNS > 1 lcd_vline(MENU_COLUMN2_X-4, FH+1, LCD_H-FH-1); SET_SCROLLBAR_X(0); #endif int8_t sub = m_posVert; int8_t editMode = s_editMode; for (int k=0; k<MENU_COLUMNS*(LCD_LINES-1); k++) { coord_t y; coord_t COLUMN_X; if (k >= LCD_LINES-1) { y = 1 + (k-LCD_LINES+2)*FH; COLUMN_X = MENU_COLUMN2_X; } else { y = 1 + (k+1)*FH; COLUMN_X = 0; } int8_t i = k; #if MENU_COLUMNS < 2 i = i + s_pgOfs; #endif LcdFlags attr = (sub==i ? (editMode>0 ? BLINK|INVERS : INVERS) : 0); switch(i) { case MIX_FIELD_NAME: editSingleName(COLUMN_X+MIXES_2ND_COLUMN, y, STR_MIXNAME, md2->name, sizeof(md2->name), event, attr); break; case MIX_FIELD_SOURCE: lcd_putsColumnLeft(COLUMN_X, y, NO_INDENT(STR_SOURCE)); putsMixerSource(COLUMN_X+MIXES_2ND_COLUMN, y, md2->srcRaw, STREXPANDED|attr); if (attr) CHECK_INCDEC_MODELSOURCE(event, md2->srcRaw, 1, MIXSRC_LAST); break; case MIX_FIELD_WEIGHT: lcd_putsColumnLeft(COLUMN_X, y, STR_WEIGHT); gvarWeightItem(COLUMN_X+MIXES_2ND_COLUMN, y, md2, attr|LEFT, event); break; case MIX_FIELD_OFFSET: { lcd_putsColumnLeft(COLUMN_X, y, NO_INDENT(STR_OFFSET)); u_int8int16_t offset; MD_OFFSET_TO_UNION(md2, offset); offset.word = GVAR_MENU_ITEM(COLUMN_X+MIXES_2ND_COLUMN, y, offset.word, GV_RANGELARGE_OFFSET_NEG, GV_RANGELARGE_OFFSET, attr|LEFT, 0, event); MD_UNION_TO_OFFSET(offset, md2); drawOffsetBar(COLUMN_X+MIXES_2ND_COLUMN+22, y, md2); break; } case MIX_FIELD_TRIM: lcd_putsColumnLeft(COLUMN_X, y, STR_TRIM); menu_lcd_onoff(COLUMN_X+MIXES_2ND_COLUMN, y, !md2->carryTrim, attr); if (attr) md2->carryTrim = !checkIncDecModel(event, !md2->carryTrim, 0, 1); break; #if defined(CURVES) case MIX_FIELD_CURVE: { lcd_putsColumnLeft(COLUMN_X, y, STR_CURVE); editCurveRef(COLUMN_X+MIXES_2ND_COLUMN, y, md2->curve, event, attr); break; } #endif #if defined(FLIGHT_MODES) case MIX_FIELD_FLIGHT_PHASE: md2->flightModes = editFlightModes(COLUMN_X+MIXES_2ND_COLUMN, y, event, md2->flightModes, attr); break; #endif case MIX_FIELD_SWITCH: md2->swtch = switchMenuItem(COLUMN_X+MIXES_2ND_COLUMN, y, md2->swtch, attr, event); break; case MIX_FIELD_WARNING: lcd_putsColumnLeft(COLUMN_X+MIXES_2ND_COLUMN, y, STR_MIXWARNING); if (md2->mixWarn) lcd_outdezAtt(COLUMN_X+MIXES_2ND_COLUMN, y, md2->mixWarn, attr|LEFT); else lcd_putsAtt(COLUMN_X+MIXES_2ND_COLUMN, y, STR_OFF, attr); if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, md2->mixWarn, 3); break; case MIX_FIELD_MLTPX: md2->mltpx = selectMenuItem(COLUMN_X+MIXES_2ND_COLUMN, y, STR_MULTPX, STR_VMLTPX, md2->mltpx, 0, 2, attr, event); break; case MIX_FIELD_DELAY_UP: md2->delayUp = EDIT_DELAY(COLUMN_X, y, event, attr, STR_DELAYUP, md2->delayUp); break; case MIX_FIELD_DELAY_DOWN: md2->delayDown = EDIT_DELAY(COLUMN_X, y, event, attr, STR_DELAYDOWN, md2->delayDown); break; case MIX_FIELD_SLOW_UP: md2->speedUp = EDIT_DELAY(COLUMN_X, y, event, attr, STR_SLOWUP, md2->speedUp); break; case MIX_FIELD_SLOW_DOWN: md2->speedDown = EDIT_DELAY(COLUMN_X, y, event, attr, STR_SLOWDOWN, md2->speedDown); break; } } }
bool swapExpoMix(uint8_t expo, uint8_t &idx, uint8_t up) { void *x, *y; uint8_t size; int8_t tgt_idx = (up ? idx-1 : idx+1); if (expo) { x = (ExpoData *)expoAddress(idx); if (tgt_idx < 0) { if (((ExpoData *)x)->chn == 0) return false; ((ExpoData *)x)->chn--; return true; } if (tgt_idx == MAX_EXPOS) { if (((ExpoData *)x)->chn == NUM_INPUTS-1) return false; ((ExpoData *)x)->chn++; return true; } y = (ExpoData *)expoAddress(tgt_idx); if(((ExpoData *)x)->chn != ((ExpoData *)y)->chn || !EXPO_VALID((ExpoData *)y)) { if (up) { if (((ExpoData *)x)->chn>0) ((ExpoData *)x)->chn--; else return false; } else { if (((ExpoData *)x)->chn<NUM_INPUTS-1) ((ExpoData *)x)->chn++; else return false; } return true; } size = sizeof(ExpoData); } else { x = (MixData *)mixAddress(idx); if (tgt_idx < 0) { if (((MixData *)x)->destCh == 0) return false; ((MixData *)x)->destCh--; return true; } if (tgt_idx == MAX_MIXERS) { if (((MixData *)x)->destCh == NUM_CHNOUT-1) return false; ((MixData *)x)->destCh++; return true; } y = (MixData *)mixAddress(tgt_idx); uint8_t destCh = ((MixData *)x)->destCh; if(!((MixData *)y)->srcRaw || destCh != ((MixData *)y)->destCh) { if (up) { if (destCh>0) ((MixData *)x)->destCh--; else return false; } else { if (destCh<NUM_CHNOUT-1) ((MixData *)x)->destCh++; else return false; } return true; } size = sizeof(MixData); } pauseMixerCalculations(); memswap(x, y, size); resumeMixerCalculations(); idx = tgt_idx; return true; }
static int luaModelInsertMix(lua_State *L) { unsigned int chn = luaL_checkunsigned(L, 1); unsigned int idx = luaL_checkunsigned(L, 2); unsigned int first = getFirstMix(chn); unsigned int count = getMixesCountFromFirst(chn, first); if (chn<NUM_CHNOUT && getExpoMixCount(0)<MAX_MIXERS && idx<=count) { idx += first; s_currCh = chn+1; insertExpoMix(0, idx); MixData *mix = mixAddress(idx); luaL_checktype(L, -1, LUA_TTABLE); for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) { luaL_checktype(L, -2, LUA_TSTRING); // key is string const char * key = luaL_checkstring(L, -2); if (!strcmp(key, "name")) { const char * name = luaL_checkstring(L, -1); str2zchar(mix->name, name, sizeof(mix->name)); } else if (!strcmp(key, "source")) { mix->srcRaw = luaL_checkinteger(L, -1); } else if (!strcmp(key, "weight")) { mix->weight = luaL_checkinteger(L, -1); } else if (!strcmp(key, "offset")) { mix->offset = luaL_checkinteger(L, -1); } else if (!strcmp(key, "switch")) { mix->swtch = luaL_checkinteger(L, -1); } else if (!strcmp(key, "curveType")) { mix->curve.type = luaL_checkinteger(L, -1); } else if (!strcmp(key, "curveValue")) { mix->curve.value = luaL_checkinteger(L, -1); } else if (!strcmp(key, "multiplex")) { mix->mltpx = luaL_checkinteger(L, -1); } else if (!strcmp(key, "flightModes")) { mix->flightModes = luaL_checkinteger(L, -1); } else if (!strcmp(key, "carryTrim")) { mix->carryTrim = lua_toboolean(L, -1); } else if (!strcmp(key, "mixWarn")) { mix->mixWarn = luaL_checkinteger(L, -1); } else if (!strcmp(key, "delayUp")) { mix->delayUp = luaL_checkinteger(L, -1); } else if (!strcmp(key, "delayDown")) { mix->delayDown = luaL_checkinteger(L, -1); } else if (!strcmp(key, "speedUp")) { mix->speedUp = luaL_checkinteger(L, -1); } else if (!strcmp(key, "speedDown")) { mix->speedDown = luaL_checkinteger(L, -1); } } } return 0; }