|  |  | @ -3,6 +3,7 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  |  */ |  |  |  |  */ | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | #include <stdbool.h> |  |  |  | #include <stdbool.h> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #include <string.h> | 
			
		
	
		
		
			
				
					
					|  |  |  | #include "app_gui.h" |  |  |  | #include "app_gui.h" | 
			
		
	
		
		
			
				
					
					|  |  |  | #include "app_heater.h" |  |  |  | #include "app_heater.h" | 
			
		
	
		
		
			
				
					
					|  |  |  | #include "app_buzzer.h" |  |  |  | #include "app_buzzer.h" | 
			
		
	
	
		
		
			
				
					|  |  | @ -35,15 +36,19 @@ typedef void (*menu_callback_t)(int choice); | 
			
		
	
		
		
			
				
					
					|  |  |  |  */ |  |  |  |  */ | 
			
		
	
		
		
			
				
					
					|  |  |  | static void screen_menu(GuiEvent event, const char **options, menu_callback_t cb); |  |  |  | static void screen_menu(GuiEvent event, const char **options, menu_callback_t cb); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static struct State { |  |  |  | static struct State { | 
			
		
	
		
		
			
				
					
					|  |  |  |   float oven_temp; |  |  |  |   float oven_temp; | 
			
		
	
		
		
			
				
					
					|  |  |  |   //float soc_temp;
 |  |  |  |   //float soc_temp;
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   // manual mode controls
 |  |  |  |   // manual mode controls
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   int set_temp; |  |  |  |   int set_temp; | 
			
		
	
		
		
			
				
					
					|  |  |  |   int set_temp_wheel; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   bool heater_enabled; |  |  |  |   bool heater_enabled; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   bool down_prescaller; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   bool up_prescaller; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   bool pushed; |  |  |  |   bool pushed; | 
			
		
	
		
		
			
				
					
					|  |  |  |   bool paint_needed; |  |  |  |   bool paint_needed; | 
			
		
	
		
		
			
				
					
					|  |  |  |   uint32_t last_tick_event; |  |  |  |   uint32_t last_tick_event; | 
			
		
	
	
		
		
			
				
					|  |  | @ -53,8 +58,17 @@ static struct State { | 
			
		
	
		
		
			
				
					
					|  |  |  |   bool initial_pushed; |  |  |  |   bool initial_pushed; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   screen_t screen; |  |  |  |   screen_t screen; | 
			
		
	
		
		
			
				
					
					|  |  |  |   int menu_pos; |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   int menu_len; |  |  |  |   union { | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       struct menu_state { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           int pos; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           int len; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           uint32_t change_time; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           uint32_t slide_end_time; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           uint16_t text_slide; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           uint8_t tick_counter; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       } menu; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   } page; | 
			
		
	
		
		
			
				
					
					|  |  |  | } s_app = {}; |  |  |  | } s_app = {}; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | /** Get push time (while held) */ |  |  |  | /** Get push time (while held) */ | 
			
		
	
	
		
		
			
				
					|  |  | @ -111,11 +125,33 @@ void app_task_gui(void *argument) | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |         osMessageQueueGet(guiEventQueHandle, &message, NULL, ticks_remain); |  |  |  |         osMessageQueueGet(guiEventQueHandle, &message, NULL, ticks_remain); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if (message == GUI_EVENT_KNOB_PLUS) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             if (s_app.up_prescaller) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 s_app.up_prescaller = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 // let this through
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 // consume this
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 s_app.down_prescaller = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 s_app.up_prescaller = 1; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 message = GUI_EVENT_NONE; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } else if (message == GUI_EVENT_KNOB_MINUS) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             if (s_app.down_prescaller) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 s_app.down_prescaller = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 // let this through
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 // consume this
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 s_app.up_prescaller = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 s_app.down_prescaller = 1; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 message = GUI_EVENT_NONE; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         uint32_t tickNow = xTaskGetTickCount(); |  |  |  |         uint32_t tickNow = xTaskGetTickCount(); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         // 10ms tick event
 |  |  |  |         // 10ms tick event
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (tickNow - s_app.last_tick_event > pdMS_TO_TICKS(10)) { |  |  |  |         if (tickNow - s_app.last_tick_event > pdMS_TO_TICKS(10)) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             s_app.screen(GUI_EVENT_TICK); |  |  |  |             s_app.screen(GUI_EVENT_SCREEN_TICK); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             s_app.last_tick_event = tickNow; |  |  |  |             s_app.last_tick_event = tickNow; | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -161,6 +197,8 @@ void app_task_gui(void *argument) | 
			
		
	
		
		
			
				
					
					|  |  |  | static void switch_screen(screen_t pScreen, bool init) { |  |  |  | static void switch_screen(screen_t pScreen, bool init) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     s_app.initial_pushed = s_app.pushed; |  |  |  |     s_app.initial_pushed = s_app.pushed; | 
			
		
	
		
		
			
				
					
					|  |  |  |     s_app.screen = pScreen; |  |  |  |     s_app.screen = pScreen; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     // clear the union field
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     memset(&s_app.page, 0, sizeof(s_app.page)); | 
			
		
	
		
		
			
				
					
					|  |  |  |     request_paint(); |  |  |  |     request_paint(); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (init) { |  |  |  |     if (init) { | 
			
		
	
	
		
		
			
				
					|  |  | @ -190,6 +228,8 @@ static void input_sound_effect() | 
			
		
	
		
		
			
				
					
					|  |  |  | static const char* main_menu_opts[] = { |  |  |  | static const char* main_menu_opts[] = { | 
			
		
	
		
		
			
				
					
					|  |  |  |     "Manual mode", |  |  |  |     "Manual mode", | 
			
		
	
		
		
			
				
					
					|  |  |  |     "Calibration", |  |  |  |     "Calibration", | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     "Moderately long text", | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     "Very very long text that slides", | 
			
		
	
		
		
			
				
					
					|  |  |  |     NULL |  |  |  |     NULL | 
			
		
	
		
		
			
				
					
					|  |  |  | }; |  |  |  | }; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -215,23 +255,9 @@ static void screen_home(GuiEvent event) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | // --------- manual mode screen ---------------
 |  |  |  | // --------- manual mode screen ---------------
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | /** Calc set temperature from the current knob position */ |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | static void manual_calc_set_temp() |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     int clamped = s_app.set_temp_wheel; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (clamped < 0) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         clamped = 0; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     s_app.set_temp = (clamped / 2) * 5; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (s_app.set_temp > MAX_TEMP) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         s_app.set_temp = MAX_TEMP; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     app_heater_set_target((float) s_app.set_temp); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | static void screen_manual(GuiEvent event) |  |  |  | static void screen_manual(GuiEvent event) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     bool temp_changed = false; | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (event == GUI_EVENT_SCREEN_INIT) { |  |  |  |     if (event == GUI_EVENT_SCREEN_INIT) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         return; |  |  |  |         return; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
	
		
		
			
				
					|  |  | @ -258,23 +284,25 @@ static void screen_manual(GuiEvent event) | 
			
		
	
		
		
			
				
					
					|  |  |  |             break; |  |  |  |             break; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         case GUI_EVENT_KNOB_PLUS: |  |  |  |         case GUI_EVENT_KNOB_PLUS: | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (s_app.set_temp < MAX_TEMP) { |  |  |  |             if (s_app.set_temp <= MAX_TEMP - 5) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 input_sound_effect(); |  |  |  |                 s_app.set_temp += 5; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 s_app.set_temp_wheel++; |  |  |  |                 temp_changed = true; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 manual_calc_set_temp(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 request_paint(); |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |             break; |  |  |  |             break; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         case GUI_EVENT_KNOB_MINUS: |  |  |  |         case GUI_EVENT_KNOB_MINUS: | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (s_app.set_temp > 0) { |  |  |  |             if (s_app.set_temp >= 5) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 input_sound_effect(); |  |  |  |                 s_app.set_temp -= 5; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 s_app.set_temp_wheel--; |  |  |  |                 temp_changed = true; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 manual_calc_set_temp(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 request_paint(); |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |             break; |  |  |  |             break; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if (temp_changed) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         input_sound_effect(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         app_heater_set_target((float) s_app.set_temp); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         request_paint(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | // ---------------------------
 |  |  |  | // ---------------------------
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -308,48 +336,83 @@ static void screen_manual_menu(GuiEvent event) | 
			
		
	
		
		
			
				
					
					|  |  |  | // ------------------------
 |  |  |  | // ------------------------
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static void screen_menu(GuiEvent event, const char **options, menu_callback_t cb) { |  |  |  | static void screen_menu(GuiEvent event, const char **options, menu_callback_t cb) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     bool menu_changed = false; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     uint32_t tickNow = xTaskGetTickCount(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     struct menu_state *menu = &s_app.page.menu; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     switch (event) { |  |  |  |     switch (event) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         case GUI_EVENT_SCREEN_INIT: |  |  |  |         case GUI_EVENT_SCREEN_INIT: | 
			
		
	
		
		
			
				
					
					|  |  |  |             s_app.menu_pos = 0; |  |  |  |             menu->pos = 0; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             s_app.menu_len = 0; |  |  |  |             menu->len = 0; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             menu->change_time = tickNow; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             menu->text_slide = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |             const char **opt = options; |  |  |  |             const char **opt = options; | 
			
		
	
		
		
			
				
					
					|  |  |  |             while (*opt) { |  |  |  |             while (*opt) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                 s_app.menu_len++; |  |  |  |                 menu->len++; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                 opt++; |  |  |  |                 opt++; | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             menu->pos = menu->len - 1; // FIXME temporary, for debug
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             break; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         case GUI_EVENT_SCREEN_TICK: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             if (tickNow - menu->change_time >= pdMS_TO_TICKS(500)) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 uint32_t textlen = strlen(options[menu->pos]) * 6; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 if (textlen >= FBW - 2) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     if (textlen - menu->text_slide > FBW - 2) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         menu->text_slide += 1; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         if (textlen - menu->text_slide > FBW - 2) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             menu->slide_end_time = tickNow; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     } else if (tickNow - menu->slide_end_time >= pdMS_TO_TICKS(500)) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         menu->change_time = tickNow; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         menu->slide_end_time = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         menu->text_slide = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     request_paint(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |             break; |  |  |  |             break; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         case GUI_EVENT_PAINT: |  |  |  |         case GUI_EVENT_PAINT: | 
			
		
	
		
		
			
				
					
					|  |  |  |             for (int i = 0; i < s_app.menu_len; i++) { |  |  |  |             for (int i = 0; i < menu->len; i++) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 fbcolor_t color = s_app.menu_pos != i; |  |  |  |                 bool current = menu->pos == i; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 fbcolor_t color = !current; | 
			
		
	
		
		
			
				
					
					|  |  |  |                 fbpos_t y = 27 + i * 10; |  |  |  |                 fbpos_t y = 27 + i * 10; | 
			
		
	
		
		
			
				
					
					|  |  |  |                 fb_rect(0, y, 64, 10, !color); |  |  |  |                 fb_rect(0, y, FBW, 10, !color); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 fb_text(1, y + 1, options[i], FONT_5X7, color); |  |  |  |                 fb_text(1 - (current ? menu->text_slide : 0), y + 1, options[i], FONT_5X7, color); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                 // ensure the text doesnt escape the screen
 |  |  |  |                 // ensure the text doesnt escape the screen
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 fb_vline(63, y, 10, !color); |  |  |  |                 fb_vline(FBW - 1, y, 10, !color); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 fb_vline(0, y, 10, !color); | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |             break; |  |  |  |             break; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         // the button is held! release is what activates the button
 |  |  |  |         // the button is held! release is what activates the button
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         case GUI_EVENT_KNOB_RELEASE: |  |  |  |         case GUI_EVENT_KNOB_RELEASE: | 
			
		
	
		
		
			
				
					
					|  |  |  |             input_sound_effect(); |  |  |  |             input_sound_effect(); | 
			
		
	
		
		
			
				
					
					|  |  |  |             cb(s_app.menu_pos); |  |  |  |             cb(menu->pos); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             break; |  |  |  |             break; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         case GUI_EVENT_KNOB_PLUS: |  |  |  |         case GUI_EVENT_KNOB_PLUS: | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (s_app.menu_pos < s_app.menu_len - 1) { |  |  |  |             if (menu->pos < menu->len - 1) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 s_app.menu_pos++; |  |  |  |                 menu->pos++; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 input_sound_effect(); |  |  |  |                 menu_changed = true; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 request_paint(); |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |             break; |  |  |  |             break; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         case GUI_EVENT_KNOB_MINUS: |  |  |  |         case GUI_EVENT_KNOB_MINUS: | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (s_app.menu_pos > 0) { |  |  |  |             if (menu->pos > 0) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 s_app.menu_pos--; |  |  |  |                 menu->pos--; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 input_sound_effect(); |  |  |  |                 menu_changed = true; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 request_paint(); |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |             break; |  |  |  |             break; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if (menu_changed) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         menu->change_time = tickNow; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         menu->text_slide = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         menu->slide_end_time = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         input_sound_effect(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         request_paint(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
	
		
		
			
				
					|  |  | 
 |