/* * Authors (alphabetical order) * - Andre Bernet * - Andreas Weitl * - Bertrand Songis * - Bryan J. Rentoul (Gruvin) * - Cameron Weeks * - Erez Raviv * - Gabriel Birkus * - Jean-Pierre Parisy * - Karl Szmutny * - Michael Blandford * - Michal Hlavinka * - Pat Mackenzie * - Philip Moss * - Rob Thomson * - Romolo Manfredini * - Thomas Husterer * * opentx is based on code named * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/, * er9x by Erez Raviv: http://code.google.com/p/er9x/, * and the original (and ongoing) project by * Thomas Husterer, th9x: http://code.google.com/p/th9x/ * * 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 "../../opentx.h" #define TRIM_LH_X 90 #define TRIM_LV_X 24 #define TRIM_RV_X (LCD_W-35) #define TRIM_RH_X (LCD_W-95) #define TRIM_V_Y 135 #define TRIM_H_Y 235 #define TRIM_LEN 80 void drawTrimSquare(coord_t x, coord_t y) { lcdDrawSolidFilledRect(x-2, y, 15, 15, TITLE_BGCOLOR); lcdDrawBitmapPattern(x-2, y, LBM_TRIM_SHADOW, TEXT_COLOR); } void drawHorizontalTrimPosition(coord_t x, coord_t y, int16_t dir) { drawTrimSquare(x, y); if (dir >= 0) { lcdDrawSolidVerticalLine(x+8, y+3, 9, TEXT_INVERTED_COLOR); } if (dir <= 0) { lcdDrawSolidVerticalLine(x+2, y+3, 9, TEXT_INVERTED_COLOR); } // if (exttrim) { // lcdDrawSolidVerticalLine(xm, ym, 9, TEXT_INVERTED_COLOR); // } } void drawVerticalTrimPosition(coord_t x, coord_t y, int16_t dir) { drawTrimSquare(x, y); if (dir >= 0) { lcdDrawSolidHorizontalLine(x+1, y+4, 9, TEXT_INVERTED_COLOR); } if (dir <= 0) { lcdDrawSolidHorizontalLine(x+1, y+10, 9, TEXT_INVERTED_COLOR); } // if (exttrim) { // lcdDrawSolidHorizontalLine(xm-1, ym, 3, TEXT_INVERTED_COLOR); // } } void drawHorizontalStick(coord_t x, int val) { for (int i=0; i<=160; i+=4) { if (i==0 || i==80 || i==160) lcdDrawSolidVerticalLine(x+i, 250, 13, TEXT_COLOR); else lcdDrawSolidVerticalLine(x+i, 252, 9, TEXT_COLOR); } drawHorizontalTrimPosition(x+TRIM_LEN+val*TRIM_LEN/RESX-5, TRIM_H_Y+16, val); } void drawVerticalStick(coord_t x, int val) { for (int i=0; i<=160; i+=4) { if (i==0 || i==80 || i==160) lcdDrawSolidHorizontalLine(x, 56+i, 13, TEXT_COLOR); else lcdDrawSolidHorizontalLine(x+2, 56+i, 9, TEXT_COLOR); } drawVerticalTrimPosition(x, TRIM_V_Y+val*TRIM_LEN/RESX-6, val); } void drawSticks() { drawVerticalStick(6, calibratedStick[1]); drawHorizontalStick(TRIM_LH_X-TRIM_LEN+1, calibratedStick[0]); drawVerticalStick(LCD_W-18, calibratedStick[2]); drawHorizontalStick(TRIM_RH_X-TRIM_LEN+1, calibratedStick[3]); } void drawTrims(uint8_t flightMode) { g_model.displayTrims = DISPLAY_TRIMS_ALWAYS; for (uint8_t i=0; i<4; i++) { static coord_t x[4] = {TRIM_LH_X, TRIM_LV_X, TRIM_RV_X, TRIM_RH_X}; static uint8_t vert[4] = {0, 1, 1, 0}; unsigned int stickIndex = CONVERT_MODE(i); coord_t xm = x[stickIndex]; int32_t trim = getTrimValue(flightMode, i); int32_t val = trim * TRIM_LEN / 125; bool exttrim = false; if (val < -(TRIM_LEN+1)) { val = -(TRIM_LEN+1); exttrim = true; } else if (val > (TRIM_LEN+1)) { val = TRIM_LEN+1; exttrim = true; } if (vert[i]) { coord_t ym = TRIM_V_Y; lcdDrawBitmapPattern(xm, ym-TRIM_LEN, LBM_VTRIM_FRAME, TEXT_COLOR); if (i!=2 || !g_model.thrTrim) { // TODO } ym -= val; drawVerticalTrimPosition(xm-1, ym-6, val); if (g_model.displayTrims != DISPLAY_TRIMS_NEVER && trim != 0) { if (g_model.displayTrims == DISPLAY_TRIMS_ALWAYS || (trimsDisplayTimer > 0 && (trimsDisplayMask & (1<0 ? 100 : 200, xm-2, trim, TINSIZE|VERTICAL); } } } else { coord_t ym = TRIM_H_Y; lcdDrawBitmapPattern(xm-TRIM_LEN, ym, LBM_HTRIM_FRAME, TEXT_COLOR); xm += val; drawHorizontalTrimPosition(xm-3, ym-2, val); if (g_model.displayTrims != DISPLAY_TRIMS_NEVER && trim != 0) { if (g_model.displayTrims == DISPLAY_TRIMS_ALWAYS || (trimsDisplayTimer > 0 && (trimsDisplayMask & (1<0 ? -20 : 50), ym+2, trim, TINSIZE); } } } } } void drawTimer(coord_t x, coord_t y, int index) { TimerData & timerData = g_model.timers[index]; TimerState & timerState = timersStates[index]; lcdDrawBitmapPattern(x, y, LBM_TIMER_BACKGROUND, TEXT_BGCOLOR); if (timerData.start) { lcdDrawBitmapPatternPie(x+2, y+3, LBM_RSCALE, TITLE_BGCOLOR, 0, timerState.val <= 0 ? 360 : 360*(timerData.start-timerState.val)/timerData.start); } putsTimer(x+74, y+31, abs(timerState.val), TEXT_COLOR|DBLSIZE|LEFT); if (ZLEN(timerData.name) > 0) { lcd_putsnAtt(x+74, y+20, timerData.name, LEN_TIMER_NAME, ZCHAR|SMLSIZE|TEXT_COLOR); } putsStrIdx(x+137, y+17, "TMR", 1, SMLSIZE|TEXT_COLOR); } void displayMainTelemetryFields() { const int ALTITUDE_Y = 16; const int VOLTS_Y = 16+16+30; const int ALTITUDE_W = 56; const int ALTITUDE_X = LCD_W-ALTITUDE_Y-ALTITUDE_W; const int ALTITUDE_H = 30; const int PADDING = 4; if (g_model.frsky.voltsSource) { TelemetryItem & item = telemetryItems[g_model.frsky.voltsSource-1]; if (item.isAvailable()) { int32_t value = item.value; TelemetrySensor & sensor = g_model.telemetrySensors[g_model.frsky.altitudeSource-1]; LcdFlags att = 0; if (sensor.prec == 2) { att |= PREC1; value /= 10; } else if (sensor.prec == 1) { att |= PREC1; } att |= (item.isOld() ? ALARM_COLOR : TEXT_COLOR); lcdDrawSolidFilledRect(ALTITUDE_X, VOLTS_Y, ALTITUDE_W, ALTITUDE_H, TEXT_BGCOLOR); lcd_putsAtt(ALTITUDE_X+PADDING, VOLTS_Y+2, "Voltage", att); putsValueWithUnit(ALTITUDE_X+PADDING, VOLTS_Y+12, value, UNIT_VOLTS, DBLSIZE|LEFT|att); } } if (g_model.frsky.altitudeSource) { TelemetryItem & item = telemetryItems[g_model.frsky.altitudeSource-1]; if (item.isAvailable()) { int32_t value = item.value; TelemetrySensor & sensor = g_model.telemetrySensors[g_model.frsky.altitudeSource-1]; if (sensor.prec) value /= sensor.prec == 2 ? 100 : 10; LcdFlags att = (item.isOld() ? ALARM_COLOR : TEXT_COLOR); lcdDrawSolidFilledRect(ALTITUDE_X, ALTITUDE_Y, ALTITUDE_W, ALTITUDE_H, TEXT_BGCOLOR); lcd_putsAtt(ALTITUDE_X+PADDING, ALTITUDE_Y+2, "Alt", att); putsValueWithUnit(ALTITUDE_X+PADDING, ALTITUDE_Y+12, value, UNIT_METERS, DBLSIZE|LEFT|att); } } } bool isViewAvailable(int index) { if (index <= VIEW_CHANNELS) return true; else return TELEMETRY_SCREEN_TYPE(index-VIEW_TELEM1) != TELEMETRY_SCREEN_TYPE_NONE; } void displayMainViewIndex() { int x = LCD_W - 14; for (int i=VIEW_COUNT; i>=0; --i) { if (isViewAvailable(i)) { if (g_eeGeneral.view == i) { lcdDrawSolidFilledRect(x, MENU_FOOTER_TOP+17, 9, 9, TEXT_INVERTED_BGCOLOR); } else { lcdDrawSolidRect(x+1, MENU_FOOTER_TOP+18, 7, 7, TEXT_COLOR); } x -= 11; } } } void onMainViewMenu(const char *result) { if (result == STR_RESET_TIMER1) { timerReset(0); } else if (result == STR_RESET_TIMER2) { timerReset(1); } #if defined(CPUARM) else if (result == STR_RESET_TIMER3) { timerReset(2); } else if (result == STR_VIEW_NOTES) { pushModelNotes(); } else if (result == STR_RESET_SUBMENU) { MENU_ADD_ITEM(STR_RESET_FLIGHT); MENU_ADD_ITEM(STR_RESET_TIMER1); MENU_ADD_ITEM(STR_RESET_TIMER2); MENU_ADD_ITEM(STR_RESET_TIMER3); #if defined(FRSKY) MENU_ADD_ITEM(STR_RESET_TELEMETRY); #endif } #endif #if defined(FRSKY) else if (result == STR_RESET_TELEMETRY) { telemetryReset(); } #endif else if (result == STR_RESET_FLIGHT) { flightReset(); } else if (result == STR_STATISTICS) { chainMenu(menuStatisticsView); } #if defined(CPUARM) else if (result == STR_ABOUT_US) { chainMenu(menuAboutView); } #endif } const uint16_t LBM_MAINVIEW_FLAT[] = { #include "../../bitmaps/Horus/mainview_flat.lbm" }; const uint16_t LBM_CORSAIR[] = { #include "../../bitmaps/Horus/corsair.lbm" }; void menuMainView(evt_t event) { // clear the screen lcdDrawSolidFilledRect(0, 0, LCD_W, LCD_H, TEXT_BGCOLOR); switch (event) { case EVT_ENTRY: killEvents(KEY_EXIT); killEvents(KEY_UP); killEvents(KEY_DOWN); break; case EVT_KEY_LONG(KEY_ENTER): killEvents(event); if (modelHasNotes()) { MENU_ADD_ITEM(STR_VIEW_NOTES); } MENU_ADD_ITEM(STR_RESET_SUBMENU); MENU_ADD_ITEM(STR_STATISTICS); MENU_ADD_ITEM(STR_ABOUT_US); menuHandler = onMainViewMenu; break; case EVT_KEY_BREAK(KEY_MENU): pushMenu(menuModelSetup); break; case EVT_KEY_LONG(KEY_MENU): killEvents(event); pushMenu(menuGeneralSetup); break; case EVT_KEY_BREAK(KEY_DOWN): storageDirty(EE_GENERAL); g_eeGeneral.view = circularIncDec(g_eeGeneral.view, +1, 0, VIEW_COUNT-1, isViewAvailable); break; case EVT_KEY_BREAK(KEY_UP): killEvents(event); storageDirty(EE_GENERAL); g_eeGeneral.view = circularIncDec(g_eeGeneral.view, -1, 0, VIEW_COUNT-1, isViewAvailable); break; case EVT_KEY_FIRST(KEY_EXIT): #if defined(GVARS) if (s_gvar_timer > 0) { s_gvar_timer = 0; } #endif AUDIO_KEYPAD_UP(); break; } lcdDrawBitmap(0, 0, LBM_MAINVIEW_BACKGROUND); // lcdDrawBitmap(0, 0, LBM_MAINVIEW_FLAT); // Header lcdDrawSolidFilledRect(0, 0, LCD_W, MENU_HEADER_HEIGHT, HEADER_BGCOLOR); lcdDrawBitmapPattern(0, 0, LBM_TOPMENU_POLYGON, TITLE_BGCOLOR); lcdDrawBitmapPattern(4, 10, LBM_TOPMENU_OPENTX, MENU_TITLE_COLOR); lcdDrawTopmenuDatetime(); if (1 || usbPlugged()) { lcdDrawBitmapPattern(378, 8, LBM_TOPMENU_USB, MENU_TITLE_COLOR); } const uint8_t rssiBarsValue[] = { 30, 40, 50, 60, 80 }; const uint8_t rssiBarsHeight[] = { 5, 10, 15, 21, 31 }; for (unsigned int i=0; i= rssiBarsValue[i] ? MENU_TITLE_COLOR : MENU_TITLE_DISABLE_COLOR); } // Flight Mode Name int mode = mixerCurrentFlightMode; for (int i=0; i 0) { s_gvar_timer--; displayMessageBox(); putsStrIdx(WARNING_LINE_X, WARNING_LINE_Y, STR_GV, s_gvar_last+1, DBLSIZE|YELLOW); lcd_putsnAtt(WARNING_LINE_X+45, WARNING_LINE_Y, g_model.gvars[s_gvar_last].name, LEN_GVAR_NAME, DBLSIZE|YELLOW|ZCHAR); lcd_outdezAtt(WARNING_LINE_X, WARNING_INFOLINE_Y, GVAR_VALUE(s_gvar_last, getGVarFlightPhase(mixerCurrentFlightMode, s_gvar_last)), DBLSIZE|LEFT); } #endif } void menuMainViewChannelsMonitor(evt_t event) { switch(event) { case EVT_KEY_BREAK(KEY_EXIT): chainMenu(menuMainView); event = 0; break; } return menuChannelsView(event); }