]> bicyclesonthemoon.info Git - klavirko/ui/commitdiff
selected option is underlined, no separate states for options, use macros for buffer...
authorb <rowerynaksiezycu@gmail.com>
Wed, 1 Jan 2025 22:13:27 +0000 (23:13 +0100)
committerb <rowerynaksiezycu@gmail.com>
Wed, 1 Jan 2025 22:13:27 +0000 (23:13 +0100)
aix.c
ctrl.c
debug.c
gui.c
gui.h
klavirko-ui.h
lcd.c
lcd.h

diff --git a/aix.c b/aix.c
index c2e9542a1ea031c56c1af79d4a2a4446d20f4fb5..821e28507a159998a8d142b797834a5c055c5a77 100644 (file)
--- a/aix.c
+++ b/aix.c
@@ -1,6 +1,6 @@
 /* ANALOG INPUT EXPANDER */
 /*
-Copyright 2021 Balthasar Szczepański
+Copyright 2021, 2025 Balthasar Szczepański
 
 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 
@@ -50,16 +50,13 @@ inline void int_aix_rx (void) // received byte from AIX
        
        data = AIX_RX__SDR; // get byte
        
-       if((aix_buffer_w + 1 == aix_buffer_r) || (aix_buffer_w + 1 == aix_buffer_r + N_AIX_BUFFER)) // buffer overflow
+       if(FULL_BP(aix_buffer_w, aix_buffer_r, N_AIX_BUFFER)) // buffer overflow
                {}
        else
        {
                aix_buffer[aix_buffer_w] = data;
                // advance the pointer
-               if (aix_buffer_w >= N_AIX_BUFFER - 1)
-                       aix_buffer_w = 0;
-               else
-                       ++aix_buffer_w;
+               ADVANCE_BP(aix_buffer_w, N_AIX_BUFFER);
        }
 }
 
@@ -120,14 +117,11 @@ void handle_aix (void)
        uint8_t data;
        int16_t diff;
        
-       if (aix_buffer_r != aix_buffer_w) // data waiting in buffer
+       if (NOT_EMPTY_BP(aix_buffer_w, aix_buffer_r, N_AIX_BUFFER)) // data waiting in buffer
        {
                // get data; advance pointer
                data = aix_buffer[aix_buffer_r];
-               if(aix_buffer_r >= N_AIX_BUFFER - 1)
-                       aix_buffer_r = 0;
-               else
-                       ++aix_buffer_r;
+               ADVANCE_BP(aix_buffer_r, N_AIX_BUFFER);
                
                if (data == '\n') //end of frame
                {
diff --git a/ctrl.c b/ctrl.c
index 985191294080e86fc5aaf99940ad50040759a8fd..8b795dbfaeadb885de1be9740c241aa06e9feb3b 100644 (file)
--- a/ctrl.c
+++ b/ctrl.c
@@ -1,6 +1,6 @@
 /* COMMUNICATING WITH MAIN CONTROLLER */
 /*
-Copyright 2021, 2024 Balthasar Szczepański
+Copyright 2021, 2024, 2025 Balthasar Szczepański
 
 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 
@@ -58,16 +58,12 @@ inline void int_ctrl_rx(void) // received byte from CTRL
        
        data = CTRL_RX__SDR; // get byte
        
-       if((ctrl_rxbuffer_w + 1 == ctrl_rxbuffer_r) || (ctrl_rxbuffer_w + 1 == ctrl_rxbuffer_r + N_CTRL_RXBUFFER)) // buffer overflow
+       if (FULL_BP(ctrl_rxbuffer_w, ctrl_rxbuffer_r, N_CTRL_RXBUFFER)) // buffer overflow
                ctrl_error |= ERR_OVERFLOW;
        else
        {
                ctrl_rxbuffer[ctrl_rxbuffer_w] = data;
-               // advance the pointer
-               if (ctrl_rxbuffer_w >= N_CTRL_RXBUFFER - 1)
-                       ctrl_rxbuffer_w = 0;
-               else
-                       ++ctrl_rxbuffer_w;
+               ADVANCE_BP(ctrl_rxbuffer_w, N_CTRL_RXBUFFER);
        }
 }
 
@@ -243,7 +239,7 @@ void handle_ctrl (void)
        
        while (ctrl_state == CTRL_SEND) // send the command
        {
-               if((ctrl_txbuffer_w + 1 == ctrl_txbuffer_r) || (ctrl_txbuffer_w + 1 == ctrl_txbuffer_r + N_CTRL_TXBUFFER)) // no place in buffer
+               if (FULL_BP(ctrl_txbuffer_w, ctrl_txbuffer_r, N_CTRL_TXBUFFER)) // no place in buffer
                        break;
                
                if (ctrl_index < 0) // start of frame, command id
@@ -257,7 +253,7 @@ void handle_ctrl (void)
                {
                        io = '\n';
                        ctrl_state = CTRL_SWITCH; // GOTO next state
-                       ctrl_rxbuffer_r = ctrl_rxbuffer_w;
+                       CLEAR_BP(ctrl_rxbuffer_w, ctrl_rxbuffer_r, N_CTRL_RXBUFFER);
                }
                else // data byte
                {
@@ -285,24 +281,16 @@ void handle_ctrl (void)
                
                // put to buffer, adnvance the pointer
                ctrl_txbuffer[ctrl_txbuffer_w] = io;
-               if (ctrl_txbuffer_w >= N_CTRL_TXBUFFER - 1)
-                       ctrl_txbuffer_w = 0;
-               else
-                       ++ctrl_txbuffer_w;
+               ADVANCE_BP(ctrl_txbuffer_w, N_CTRL_TXBUFFER);
        }
        
-       if (ctrl_txbuffer_r != ctrl_txbuffer_w) // data in output buffer
+       if (NOT_EMPTY_BP(ctrl_txbuffer_w, ctrl_txbuffer_r, N_CTRL_TXBUFFER)) // data in output buffer
        {
                if(!(CTRL_TX__SSR & 0b01000000)) // uart is ready
                {
                        CTRL_TX__IF = 0;
                        CTRL_TX__SDR = ctrl_txbuffer[ctrl_txbuffer_r]; // send the byte
-                       
-                       // advance the pointer
-                       if (ctrl_txbuffer_r >= N_CTRL_RXBUFFER - 1)
-                               ctrl_txbuffer_r = 0;
-                       else
-                               ++ctrl_txbuffer_r;
+                       ADVANCE_BP(ctrl_txbuffer_r, N_CTRL_RXBUFFER); // advance the pointer
                }
        }
        
@@ -333,20 +321,17 @@ void handle_ctrl (void)
                ctrl_resp = CMD_NOP;
        }
        
-       while (ctrl_rxbuffer_r != ctrl_rxbuffer_w) // data in input buffer
+       while (NOT_EMPTY_BP(ctrl_rxbuffer_w, ctrl_rxbuffer_r, N_CTRL_RXBUFFER)) // data in input buffer
        {
                // get the byte, advance the pointer
                io = ctrl_rxbuffer[ctrl_rxbuffer_r];
-               if(ctrl_rxbuffer_r >= N_CTRL_RXBUFFER -1 )
-                       ctrl_rxbuffer_r = 0;
-               else
-                       ++ctrl_rxbuffer_r;
+               ADVANCE_BP(ctrl_rxbuffer_r, N_CTRL_RXBUFFER);
                
                if (io == CMD_ERR) // received a complain from CTRL
                {
                        // drop any action, immediately switch to listen
                        ctrl_state = CTRL_RECEIVE;
-                       ctrl_txbuffer_r = ctrl_txbuffer_w;
+                       CLEAR_BP(ctrl_txbuffer_w, ctrl_txbuffer_r, N_CTRL_TXBUFFER);
                }
                
                if (ctrl_state == CTRL_RECEIVE) // actually expecting to receive
diff --git a/debug.c b/debug.c
index 598271cc018165cd4c02310ea32a9740aa51edff..142c0c4712fde5dbbf04ea2b2767ee4eb8d49795 100644 (file)
--- a/debug.c
+++ b/debug.c
@@ -1,6 +1,6 @@
 /* DEBUG SERIAL OUTPUT */
 /*
-Copyright 2021 Balthasar Szczepański
+Copyright 2021, 2025 Balthasar Szczepański
 
 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 
@@ -24,7 +24,7 @@ void handle_debug(void)
 {
        uint8_t byte;
        
-       if(debug_buffer_r != debug_buffer_w) // data waiting in buffer
+       if (NOT_EMPTY_BP(debug_buffer_w, debug_buffer_r, N_DEBUG_BUFFER)) // data waiting in buffer
        {
                byte = debug_buffer[debug_buffer_r]; // get the byte
                
@@ -35,11 +35,7 @@ void handle_debug(void)
                }
                else
                        return;
-               // advance the pointer
-               if(debug_buffer_r >= N_DEBUG_BUFFER - 1)
-                       debug_buffer_r = 0;
-               else
-                       ++debug_buffer_r;
+               ADVANCE_BP(debug_buffer_r, N_DEBUG_BUFFER); // advance the pointer
        }
 }
 
@@ -48,7 +44,7 @@ void debug_byte ( // send a byte to debug output
        const uint8_t blocking
 )
 {
-       while((debug_buffer_w + 1 == debug_buffer_r) || (debug_buffer_w + 1 == debug_buffer_r + N_DEBUG_BUFFER))
+       while (FULL_BP(debug_buffer_w, debug_buffer_r, N_DEBUG_BUFFER))
        {
                if (blocking)
                        handle_debug();
@@ -56,10 +52,7 @@ void debug_byte ( // send a byte to debug output
                        return;
        }
        debug_buffer[debug_buffer_w] = value;
-       if(debug_buffer_w >= N_DEBUG_BUFFER - 1)
-               debug_buffer_w = 0;
-       else
-               ++debug_buffer_w;
+       ADVANCE_BP(debug_buffer_w, N_DEBUG_BUFFER);
 }
 
 void debug_string ( // send a string to debug output
diff --git a/gui.c b/gui.c
index a863a5ce246a2886cff9bd231a165a6dd3ad5725..51060844faf72e8b9f62942dcd1a60c4e0c2b2f7 100644 (file)
--- a/gui.c
+++ b/gui.c
@@ -1,6 +1,6 @@
 /* GUI */
 /*
-Copyright 2021, 2022, 2024 Balthasar Szczepański
+Copyright 2021, 2022, 2024, 2025 Balthasar Szczepański
 
 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 
@@ -49,6 +49,9 @@ volatile uint8_t  gui_event_w = 0;
          uint8_t  gui_return_state = GUI_WAVE;
          uint8_t  gui_errors = 0;
          uint8_t  gui_accepted_errors = GUI_ERRF_ALL;
+         int8_t   gui_choice = GUI_NOCHOICE;
+         int16_t  gui_used_voice_page = -1;
+         int16_t  gui_used_voice_id = -1;
 
          uint8_t  gui_page=0;
          uint8_t  gui_name[N_NAME+1] = {[0 ... (N_NAME)] = '\0'};
@@ -73,16 +76,13 @@ const    uint8_t  gui_list_123[N_123+1] = LIST_123;
 
 inline void add_gui_event(const uint16_t event)
 {
-       if((gui_event_w + 1 == gui_event_r) || (gui_event_w + 1 == gui_event_r + N_GUI_EVENT)) // event buffer is full
+       if (FULL_BP(gui_event_w, gui_event_r, N_GUI_EVENT)) // event buffer is full
                return;
        else
        {
                // add event, advance pointer
                gui_event[gui_event_w] = event;
-               if (gui_event_w >= N_GUI_EVENT - 1)
-                       gui_event_w = 0;
-               else
-                       ++gui_event_w;
+               ADVANCE_BP(gui_event_w, N_GUI_EVENT);
        }
 }
 
@@ -90,7 +90,7 @@ inline void reject_gui_events (void)
 {
        button_valid = 0; // reject any already pressed buttons
        button_hold_count = 0; // to not get a long hold in new state
-       gui_event_r = gui_event_w;
+       CLEAR_BP(gui_event_w, gui_event_r, N_GUI_EVENT);
 }
 
 inline void gui_trigger_error (const uint8_t error)
@@ -462,10 +462,14 @@ inline void gui_event_wave (const uint16_t event)
                else if (event & (BUTTON_A | BUTTON_B))
                {
                        gui_switch_wave();
+                       gui_used_voice_page = -1;
+                       gui_used_voice_id = -1;
                }
                else if (event & (BUTTON_C | BUTTON_D | BUTTON_E ))
                {
                        gui_switch_adsr();
+                       gui_used_voice_page = -1;
+                       gui_used_voice_id = -1;
                }
                else if (event & BUTTON_F)
                {
@@ -479,6 +483,8 @@ inline void gui_event_wave (const uint16_t event)
                                gui_lock_wave();
                                gui_lock_adsr();
                        }
+                       gui_used_voice_page = -1;
+                       gui_used_voice_id = -1;
                }
                break;
        }
@@ -503,6 +509,7 @@ inline void gui_exec_wave (void) // redraw if needed
 inline void gui_gotostate_select (void)
 {
        gui_state = GUI_SELECT;
+       // gui_choice = GUI_NOCHOICE;
        draw_select();
        reject_gui_events();
 }
@@ -535,11 +542,11 @@ inline void gui_event_select (const uint16_t event)
                                if (event & EVENT_LONG)
                                {
                                        fs_delete_voice(id);
-                                       lcd_update_button(id, "");
+                                       lcd_update_button(id, "", gui_choice == id);
                                        reject_gui_events();
                                }
                                else
-                                       lcd_update_button(id, GUI_BUTTONTEXT_CONFIRM_REMOVE);
+                                       lcd_update_button(id, GUI_BUTTONTEXT_CONFIRM_REMOVE, gui_choice == id);
                        }
                }
                else if (event & BUTTON_Y) // no need to check long hold
@@ -551,7 +558,7 @@ inline void gui_event_select (const uint16_t event)
                        if (fs_is_voice_stored(id))
                        {
                                if (event & EVENT_WAS_HOLD)
-                                       lcd_update_button(id, fs_page_names[id]);
+                                       lcd_update_button(id, fs_page_names[id], gui_choice == id);
                                else
                                {
                                        gui_lock_adsr();
@@ -569,11 +576,22 @@ inline void gui_event_select (const uint16_t event)
                                                ctrl_update_adsr();
                                                gui_update_adsr();
                                                gui_update_wave();
+                                               if (gui_choice != id)
+                                                       lcd_select_button(gui_choice, 0);
+                                               lcd_select_button(id, 1);
+                                               gui_used_voice_page = fs_page;
+                                               gui_used_voice_id = id;
+                                               gui_choice = id;
                                        }
                                        else
                                        {
                                                gui_unlock_adsr();
                                                gui_unlock_wave();
+                                               gui_used_voice_page = -1;
+                                               gui_used_voice_id = -1;
+                                               if ((gui_choice >= 0) && (gui_choice <= 5))
+                                                       lcd_select_button(gui_choice, 0);
+                                               gui_choice = GUI_NOCHOICE;
                                        }
                                }
                        }
@@ -581,6 +599,11 @@ inline void gui_event_select (const uint16_t event)
                        {
                                gui_unlock_adsr();
                                gui_unlock_wave();
+                               gui_used_voice_page = -1;
+                               gui_used_voice_id = -1;
+                               if ((gui_choice >= 0) && (gui_choice <= 5))
+                                       lcd_select_button(gui_choice, 0);
+                               gui_choice = GUI_NOCHOICE;
                        }
                }
                else if (event & BUTTON_X)
@@ -615,6 +638,7 @@ inline void gui_gotostate_name (const uint8_t new)
                gui_name_pos = 0;
        }
        gui_state = GUI_NAME;
+       gui_choice = 2;
        
        gui_name_list = gui_list_ABC;
        gui_name_maxcursor = N_ABC-1;
@@ -636,7 +660,8 @@ inline void gui_gotostate_name (const uint8_t new)
                GUI_BUTTONTEXT_ABC,
                GUI_BUTTONTEXT_abc,
                GUI_BUTTONTEXT_123,
-               GUI_BUTTONTEXT_OK
+               GUI_BUTTONTEXT_OK,
+               gui_choice
        );
        reject_gui_events();
        gui_ignore_event = new;
@@ -688,7 +713,7 @@ inline void gui_event_name (const uint16_t event)
                        }
                        else
                                gui_name[gui_name_pos] = '\0';
-                       lcd_update_button(-1,gui_name);
+                       lcd_update_button(-1, gui_name, 0);
                }
                else if (event & ( BUTTON_C | BUTTON_D | BUTTON_E ))
                {
@@ -696,16 +721,28 @@ inline void gui_event_name (const uint16_t event)
                        {
                                gui_name_list = gui_list_ABC;
                                gui_name_maxcursor = N_ABC-1;
+                               if (gui_choice != 2)
+                                       lcd_select_button(gui_choice, 0);
+                               gui_choice = 2;
+                               lcd_select_button(2, 1);
                        }
                        else if (event & BUTTON_D)
                        {
                                gui_name_list = gui_list_abc;
                                gui_name_maxcursor = N_abc-1;
+                               if (gui_choice != 3)
+                                       lcd_select_button(gui_choice, 0);
+                               gui_choice = 3;
+                               lcd_select_button(3, 1);
                        }
                        else if (event & BUTTON_E)
                        {
                                gui_name_list = gui_list_123;
                                gui_name_maxcursor = N_123-1;
+                               if (gui_choice != 4)
+                                       lcd_select_button(gui_choice, 0);
+                               gui_choice = 4;
+                               lcd_select_button(4, 1);
                        }
                        lcd_draw_name_list(gui_name_list);
                        if (gui_name_cursor > gui_name_maxcursor)
@@ -754,7 +791,7 @@ inline void gui_exec_name (void) // do cursor blinking
        if ((gui_name_pos < N_NAME) && (gui_name[gui_name_pos] != cursor))
        {
                gui_name[gui_name_pos] = cursor;
-               lcd_update_button(-1, gui_name);
+               lcd_update_button(-1, gui_name, 0);
        }
 }
 
@@ -764,6 +801,7 @@ inline void gui_gotostate_select_save (void)
 {
        // gui_return_state = gui_state;
        gui_state = GUI_SELECT_SAVE;
+       // gui_choice = GUI_NOCHOICE;
        draw_select_save();
        reject_gui_events();
 }
@@ -792,7 +830,7 @@ inline void gui_event_select_save (const uint16_t event)
                if (event & (BUTTON_ABCDEF))
                {
                        if (fs_is_voice_stored(id))
-                               lcd_update_button(id, GUI_BUTTONTEXT_CONFIRM_REPLACE);
+                               lcd_update_button(id, GUI_BUTTONTEXT_CONFIRM_REPLACE, gui_choice==id);
                }
                break;
        case EVENT_HOLD:
@@ -821,7 +859,7 @@ inline void gui_event_select_save (const uint16_t event)
                if (event & (BUTTON_ABCDEF))
                {
                        if (fs_is_voice_stored(id))
-                               lcd_update_button(id, fs_page_names[id]);
+                               lcd_update_button(id, fs_page_names[id], gui_choice==id);
                        else
                        {
                                fs_store_voice(
@@ -863,6 +901,12 @@ inline void gui_event_select_save (const uint16_t event)
 }
 
 // OPTIONS: menu with some settings
+//   TUNING:      change tuning of instrument
+//   TRANSPOSE:   shift by -12 to 12 semitones
+//   MIDI ID IN:  choose MIDI channel ID for input
+//   MIDI ID OUT: choose MIDI channel ID for output
+//   MIDI PEDAL:  allow / block MIDI pedal input
+//   TOTAL RESET  remove all stored voices from flash memory
 
 inline void gui_gotostate_options (void)
 {
@@ -872,6 +916,7 @@ inline void gui_gotostate_options (void)
        make_text_midi_out ();
        
        gui_state = GUI_OPTIONS;
+       gui_choice = GUI_NOCHOICE;
        lcd_draw_menu (6,
                GUI_TITLE_OPTIONS,"",
                text_tuning,
@@ -879,7 +924,8 @@ inline void gui_gotostate_options (void)
                text_midi_in,
                text_midi_out,
                midi_pedal_en ? GUI_BUTTONTEXT_MIDI_PEDAL : GUI_BUTTONTEXT_MIDI_NOPEDAL,
-               GUI_BUTTONTEXT_RESET
+               GUI_BUTTONTEXT_RESET,
+               gui_choice
        );
        reject_gui_events();
 }
@@ -889,22 +935,68 @@ inline void gui_event_options (const uint16_t event)
        switch (event & EVENT_BITS)
        {
        case EVENT_PRESS:
-               if (event & BUTTON_F)
-                       lcd_update_button(5, GUI_BUTTONTEXT_CONFIRM_RESET);
+               if (event & BUTTON_A)
+               {
+                       if (gui_choice != 0)
+                               lcd_select_button(gui_choice, 0);
+                       gui_choice = 0;
+                       lcd_select_button(0, 1);
+                       lcd_update_title(GUI_TITLE_OPTION_TUNING);
+               }
+               else if (event & BUTTON_B)
+               {
+                       if (gui_choice != 1)
+                               lcd_select_button(gui_choice, 0);
+                       gui_choice = 1;
+                       lcd_select_button(1, 1);
+                       lcd_update_title(GUI_TITLE_OPTION_TRANSPOSE);
+               }
+               else if (event & BUTTON_C)
+               {
+                       if (gui_choice != 2)
+                               lcd_select_button(gui_choice, 0);
+                       gui_choice = 2;
+                       lcd_select_button(2, 1);
+                       lcd_update_title(GUI_TITLE_OPTION_MIDI_ID);
+               }
+               else if (event & BUTTON_D)
+               {
+                       if (gui_choice != 3)
+                               lcd_select_button(gui_choice, 0);
+                       gui_choice = 3;
+                       lcd_select_button(3, 1);
+                       lcd_update_title(GUI_TITLE_OPTION_MIDI_OUT_ID);
+               }
+               else if (event & BUTTON_E)
+               {
+                       if (gui_choice != 4)
+                               lcd_select_button(gui_choice, 0);
+                       gui_choice = 4;
+                       lcd_select_button(4, 1);
+                       lcd_update_title(GUI_TITLE_OPTION_MIDI_PEDAL);
+               }
+               else if (event & BUTTON_F)
+               {
+                       if (gui_choice != 5)
+                               lcd_select_button(gui_choice, 0);
+                       gui_choice = 5;
+                       lcd_update_button(5, GUI_BUTTONTEXT_CONFIRM_RESET, 1);
+                       lcd_update_title(GUI_TITLE_OPTION_TRANSPOSE);
+               }
                break;
        case EVENT_HOLD:
                if (event & BUTTON_A)
                {
                        set_tuning(DEFAULT_TUNING);
                        make_text_tuning();
-                       lcd_update_button(0, text_tuning);
+                       lcd_update_button(0, text_tuning, 1);
                        reject_gui_events();
                }
                else if (event & BUTTON_B)
                {
                        set_transp(0);
                        make_text_transpose();
-                       lcd_update_button(1, text_transpose);
+                       lcd_update_button(1, text_transpose, 1);
                        reject_gui_events();
                }
                else if (event & BUTTON_C)
@@ -912,7 +1004,7 @@ inline void gui_event_options (const uint16_t event)
                        midi_id = N_MIDI_ID;
                        ctrl_update_midi();
                        make_text_midi_in();
-                       lcd_update_button(2, text_midi_in);
+                       lcd_update_button(2, text_midi_in, 1);
                        reject_gui_events();
                }
                else if (event & BUTTON_D)
@@ -920,7 +1012,7 @@ inline void gui_event_options (const uint16_t event)
                        midi_id_out = 0;
                        ctrl_update_midi();
                        make_text_midi_out();
-                       lcd_update_button(3, text_midi_out);
+                       lcd_update_button(3, text_midi_out, 1);
                        reject_gui_events();
                }
                // no long press on button E
@@ -935,237 +1027,92 @@ inline void gui_event_options (const uint16_t event)
                        gui_gotostate_wave();
                else if (event & BUTTON_Y)
                        gui_gotostate_select();
-               else if (event & BUTTON_A)
-                       gui_gotostate_tuning();
-               else if (event & BUTTON_B)
-                       gui_gotostate_transpose();
-               else if (event & BUTTON_C)
-                       gui_gotostate_midi_id();
-               else if (event & BUTTON_D)
-                       gui_gotostate_midi_id_out();
                else if (event & BUTTON_E)
                {
                        if (midi_pedal_en)
                        {
                                midi_pedal_en = 0;
-                               lcd_update_button(4, GUI_BUTTONTEXT_MIDI_NOPEDAL);
+                               lcd_update_button(4, GUI_BUTTONTEXT_MIDI_NOPEDAL, 1);
                        }
                        else
                        {
                                midi_pedal_en = 1;
-                               lcd_update_button(4, GUI_BUTTONTEXT_MIDI_PEDAL);
+                               lcd_update_button(4, GUI_BUTTONTEXT_MIDI_PEDAL, 1);
                        }
                        ctrl_update_midi();
                }
                else if (event & BUTTON_F)
-                               lcd_update_button(5, GUI_BUTTONTEXT_RESET);
-               break;
-       }
-}
-
-// TUNING: change tuning of instrument
-
-inline void gui_gotostate_tuning (void)
-{
-       make_text_tuning();
-       
-       gui_state = GUI_TUNING;
-       lcd_draw_menu (6,
-               GUI_TITLE_TUNING,"",
-               text_tuning, "", "", "", "", ""
-       );
-       reject_gui_events();
-}
-
-inline void gui_event_tuning (const uint16_t event)
-{
-       switch (event & EVENT_BITS)
-       {
-       case EVENT_HOLD:
-               if (event & BUTTON_A)
-               {
-                       set_tuning(DEFAULT_TUNING);
-                       make_text_tuning();
-                       lcd_update_button(0, text_tuning);
-                       reject_gui_events();
-               }
-               break;
-       case EVENT_RELEASE:
-               if (event & (BUTTON_A | BUTTON_X | BUTTON_Y))
-                       gui_gotostate_options();
+                       lcd_update_button(5, GUI_BUTTONTEXT_RESET, 1);
                break;
        case EVENT_JOG:
-               if ((event & JOG_BITS) == JOG_PLUS)
+               switch (gui_choice)
                {
-                       set_tuning(tuning + gui_jog_boost(event & JOG_TIME_BITS));
-               }
-               else
-               {
-                       set_tuning(tuning - gui_jog_boost(event & JOG_TIME_BITS));
-               }
-               
-               make_text_tuning();
-               lcd_update_button(0, text_tuning);
-               break;
-       }
-}
-
-// TRANSPOSE: shift by -12 to 12 semitones
-
-inline void gui_gotostate_transpose (void)
-{
-       make_text_transpose();
-       
-       gui_state = GUI_TRANSPOSE;
-       lcd_draw_menu (6,
-               GUI_TITLE_TRANSPOSE,"",
-               "",text_transpose, "", "", "", ""
-       );
-       reject_gui_events();
-}
-
-inline void gui_event_transpose (const uint16_t event)
-{
-       switch (event & EVENT_BITS)
-       {
-       case EVENT_HOLD:
-               if (event & BUTTON_B)
-               {
-                       set_transp(0);
+               case 0:
+                       if ((event & JOG_BITS) == JOG_PLUS)
+                       {
+                               set_tuning(tuning + gui_jog_boost(event & JOG_TIME_BITS));
+                       }
+                       else
+                       {
+                               set_tuning(tuning - gui_jog_boost(event & JOG_TIME_BITS));
+                       }
+                       make_text_tuning();
+                       lcd_update_button(0, text_tuning, 1);
+                       break;
+               case 1:
+                       if ((event & JOG_BITS) == JOG_PLUS)
+                       {
+                               if (transp<12)
+                                       set_transp(transp + 1);
+                       }
+                       else
+                       {
+                               if (transp>-12)
+                                       set_transp(transp - 1);
+                       }
                        make_text_transpose();
-                       lcd_update_button(1, text_transpose);
-                       reject_gui_events();
-               }
-               break;
-       case EVENT_RELEASE:
-               if (event & (BUTTON_B | BUTTON_X | BUTTON_Y))
-                       gui_gotostate_options();
-               break;
-       case EVENT_JOG:
-               if ((event & JOG_BITS) == JOG_PLUS)
-               {
-                       if (transp<12)
-                               set_transp(transp + 1);
-               }
-               else
-               {
-                       if (transp>-12)
-                               set_transp(transp - 1);
-               }
-               
-               make_text_transpose();
-               lcd_update_button(1, text_transpose);
-               break;
-       }
-}
-
-// MIDI_ID: choose MIDI channel ID for input
-
-inline void gui_gotostate_midi_id (void)
-{
-       make_text_midi_in();
-       
-       gui_state = GUI_MIDI_ID;
-       lcd_draw_menu (6,
-               GUI_TITLE_MIDI_ID,"",
-               "","",text_midi_in, "", "", ""
-       );
-       reject_gui_events();
-}
-
-inline void gui_event_midi_id (const uint16_t event)
-{
-       switch (event & EVENT_BITS)
-       {
-       case EVENT_HOLD:
-               if (event & BUTTON_C)
-               {
-                       midi_id = N_MIDI_ID;
+                       lcd_update_button(1, text_transpose, 1);
+                       break;
+               case 2:
+                       if ((event & JOG_BITS) == JOG_PLUS)
+                       {
+                               if (midi_id < N_MIDI_ID)
+                                       ++midi_id;
+                               else
+                                       midi_id = 0;
+                       }
+                       else
+                       {
+                               if (midi_id != 0)
+                                       --midi_id;
+                               else
+                                       midi_id = N_MIDI_ID;
+                       }
                        ctrl_update_midi();
                        make_text_midi_in();
-                       lcd_update_button(2, text_midi_in);
-                       reject_gui_events();
-               }
-               break;
-       case EVENT_RELEASE:
-               if (event & (BUTTON_C | BUTTON_X | BUTTON_Y))
-                       gui_gotostate_options();
-               break;
-       case EVENT_JOG:
-               if ((event & JOG_BITS) == JOG_PLUS)
-               {
-                       if (midi_id < N_MIDI_ID)
-                               ++midi_id;
-                       else
-                               midi_id = 0;
-               }
-               else
-               {
-                       if (midi_id != 0)
-                               --midi_id;
+                       lcd_update_button(2, text_midi_in, 1);
+                       break;
+               case 3:
+                       if ((event & JOG_BITS) == JOG_PLUS)
+                       {
+                               if (midi_id_out < N_MIDI_ID-1)
+                                       ++midi_id_out;
+                               else
+                                       midi_id_out = 0;
+                       }
                        else
-                               midi_id = N_MIDI_ID;
-               }
-               
-               ctrl_update_midi();
-               make_text_midi_in();
-               lcd_update_button(2, text_midi_in);
-               break;
-       }
-}
-
-// MIDI_ID_OUT: choose MIDI channel ID for output
-
-inline void gui_gotostate_midi_id_out (void)
-{
-       make_text_midi_out();
-       
-       gui_state = GUI_MIDI_ID_OUT;
-       lcd_draw_menu (6,
-               GUI_TITLE_MIDI_ID_OUT,"",
-               "","","",text_midi_out, "", ""
-       );
-       reject_gui_events();
-}
-
-inline void gui_event_midi_id_out (const uint16_t event)
-{
-       switch (event & EVENT_BITS)
-       {
-       case EVENT_HOLD:
-               if (event & BUTTON_D)
-               {
-                       midi_id_out = 0;
+                       {
+                               if (midi_id_out != 0)
+                                       --midi_id_out;
+                               else
+                                       midi_id_out = N_MIDI_ID-1;
+                       }
+                       
                        ctrl_update_midi();
                        make_text_midi_out();
-                       lcd_update_button(3, text_midi_out);
-                       reject_gui_events();
-               }
-               break;
-       case EVENT_RELEASE:
-               if (event & (BUTTON_D | BUTTON_X | BUTTON_Y))
-                       gui_gotostate_options();
-               break;
-       case EVENT_JOG:
-               if ((event & JOG_BITS) == JOG_PLUS)
-               {
-                       if (midi_id_out < N_MIDI_ID-1)
-                               ++midi_id_out;
-                       else
-                               midi_id_out = 0;
-               }
-               else
-               {
-                       if (midi_id_out != 0)
-                               --midi_id_out;
-                       else
-                               midi_id_out = N_MIDI_ID-1;
+                       lcd_update_button(3, text_midi_out, 1);
+                       break;
                }
-               
-               ctrl_update_midi();
-               make_text_midi_out();
-               lcd_update_button(3, text_midi_out);
-               break;
        }
 }
 
@@ -1176,7 +1123,8 @@ inline void gui_gotostate_err_aix (void)
        gui_state = GUI_ERR_AIX;
        lcd_draw_menu(1,
                GUI_TITLE_ERR_AIX,"",
-               "","","","","",GUI_BUTTONTEXT_IGNORE
+               "","","","","",GUI_BUTTONTEXT_IGNORE,
+               GUI_NOCHOICE
        );
        reject_gui_events();
 }
@@ -1200,7 +1148,8 @@ inline void gui_gotostate_err_ctrl (void)
        gui_state = GUI_ERR_CTRL;
        lcd_draw_menu(1,
                GUI_TITLE_ERR_CTRL,"",
-               "","","","","",GUI_BUTTONTEXT_IGNORE
+               "","","","","",GUI_BUTTONTEXT_IGNORE,
+               GUI_NOCHOICE
        );
        reject_gui_events();
 }
@@ -1227,7 +1176,8 @@ inline void gui_gotostate_err_fs (void)
                "","","",
                GUI_BUTTONTEXT_FORMAT,
                GUI_BUTTONTEXT_RECOVER,
-               GUI_BUTTONTEXT_IGNORE
+               GUI_BUTTONTEXT_IGNORE,
+               GUI_NOCHOICE
        );
        reject_gui_events();
 }
@@ -1259,7 +1209,8 @@ inline void gui_gotostate_total_reset (void)
        gui_state = GUI_TOTAL_RESET;
        lcd_draw_menu(0,
                GUI_TITLE_RESET,"",
-               "","","","","",""
+               "","","","","","",
+               GUI_NOCHOICE
        );
        fs_format();
        RESET_UI();
@@ -1270,14 +1221,11 @@ void handle_gui(void)
 {
                uint16_t event;
        
-       if (gui_event_r != gui_event_w) // event received
+       if (NOT_EMPTY_BP(gui_event_w, gui_event_r, N_GUI_EVENT)) // event received
        {
                // get event, advance pointer
                event = gui_event[gui_event_r];
-               if(gui_event_r >= N_GUI_EVENT - 1)
-                       gui_event_r = 0;
-               else
-                       ++gui_event_r;
+               ADVANCE_BP(gui_event_r, N_GUI_EVENT);
                
                // if ((event & EVENT_BITS) == EVENT_JOG)
                // {
@@ -1337,18 +1285,6 @@ void handle_gui(void)
                case GUI_OPTIONS:
                        gui_event_options(event);
                        break;
-               case GUI_TUNING:
-                       gui_event_tuning(event);
-                       break;
-               case GUI_TRANSPOSE:
-                       gui_event_transpose(event);
-                       break;
-               case GUI_MIDI_ID:
-                       gui_event_midi_id(event);
-                       break;
-               case GUI_MIDI_ID_OUT:
-                       gui_event_midi_id_out(event);
-                       break;
                case GUI_ERR_AIX:
                        gui_event_err_aix(event);
                        break;
@@ -1375,10 +1311,6 @@ void handle_gui(void)
        case GUI_SELECT:
        case GUI_SELECT_SAVE:
        case GUI_OPTIONS:
-       case GUI_TUNING:
-       case GUI_TRANSPOSE:
-       case GUI_MIDI_ID:
-       case GUI_MIDI_ID_OUT:
        case GUI_ERR_AIX:
        case GUI_ERR_CTRL:
        case GUI_ERR_FS:
@@ -1496,6 +1428,11 @@ void draw_adsr (void) // envelope display
 void draw_select (void) // voice settings selection
 {
        fs_load_page(gui_page);
+       if ((fs_page == gui_used_voice_page) && (gui_used_voice_id >= 0))
+               gui_choice = gui_used_voice_id;
+       else
+               gui_choice = GUI_NOCHOICE;
+       
        make_text_select();
        
        lcd_draw_menu(6,
@@ -1506,13 +1443,19 @@ void draw_select (void) // voice settings selection
                fs_page_names[2],
                fs_page_names[3],
                fs_page_names[4],
-               fs_page_names[5]
+               fs_page_names[5],
+               gui_choice
        );
 }
 
 void draw_select_save (void) // voice setting save location selection
 {
        fs_load_page(gui_page);
+       if ((fs_page == gui_used_voice_page) && (gui_used_voice_id >= 0))
+               gui_choice = gui_used_voice_id;
+       else
+               gui_choice = GUI_NOCHOICE;
+       
        make_text_save();
        
        lcd_draw_menu(7,
@@ -1523,7 +1466,8 @@ void draw_select_save (void) // voice setting save location selection
                fs_page_names[2],
                fs_page_names[3],
                fs_page_names[4],
-               fs_page_names[5]
+               fs_page_names[5],
+               gui_choice
        );
 }
 
diff --git a/gui.h b/gui.h
index 62c4abc29f2ef507801aac2f0dc7c826c2380ea6..78bfd27e13ff700c6302389192354047d2382262 100644 (file)
--- a/gui.h
+++ b/gui.h
@@ -1,6 +1,6 @@
 /* GUI */
 /*
-Copyright 2021, 2022, 2024 Balthasar Szczepański
+Copyright 2021, 2022, 2024, 2025 Balthasar Szczepański
 
 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 
@@ -79,16 +79,16 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 #define EVENT_WAS_HOLD 0x1000
 #define EVENT_LONG     0x0800
 
+
+#define GUI_NOCHOICE (-128)
+
+
 #define GUI_INIT        0x00
 #define GUI_WAVE        0x01
 #define GUI_SELECT      0x02
 #define GUI_SELECT_SAVE 0x03
 #define GUI_NAME        0x04
 #define GUI_OPTIONS     0x10
-#define GUI_TUNING      0x11
-#define GUI_TRANSPOSE   0x12
-#define GUI_MIDI_ID     0x13
-#define GUI_MIDI_ID_OUT 0x14
 
 #define GUI_ERROR       0x80
 #define GUI_ERR_AIX     0x81
@@ -110,16 +110,21 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 #define N_abc 35
 #define N_123 42
 
-#define GUI_TITLE_NAME        "Save as:"
-#define GUI_TITLE_OPTIONS     "Options:"
-#define GUI_TITLE_TUNING      "Tuning:"
-#define GUI_TITLE_TRANSPOSE   "Transpose:"
-#define GUI_TITLE_MIDI_ID     "MIDI in ID:"
-#define GUI_TITLE_MIDI_ID_OUT "MIDI out ID:"
-#define GUI_TITLE_ERR_AIX     "AIX communication fail!"
-#define GUI_TITLE_ERR_CTRL    "CTRL communication fail!"
-#define GUI_TITLE_ERR_FS      "File system unformatted or damaged!"
-#define GUI_TITLE_RESET       "TERAS BENDZIE INNY $WIAT"
+#define GUI_TITLE_NAME     "Save as:"
+#define GUI_TITLE_TUNING   "Tuning:"
+#define GUI_TITLE_ERR_AIX  "AIX communication fail!"
+#define GUI_TITLE_ERR_CTRL "CTRL communication fail!"
+#define GUI_TITLE_ERR_FS   "File system unformatted or damaged!"
+#define GUI_TITLE_RESET    "TERAS BENDZIE INNY $WIAT"
+
+#define GUI_TITLE_OPTIONS            "Options:           "
+#define GUI_TITLE_OPTION_TUNING      "Options:          (tuning)"
+#define GUI_TITLE_OPTION_TRANSPOSE   "Options:          (transpose)"
+#define GUI_TITLE_OPTION_MIDI_ID     "Options:          (MIDI in ID)"
+#define GUI_TITLE_OPTION_MIDI_OUT_ID "Options:          (MIDI out ID)"
+#define GUI_TITLE_OPTION_MIDI_PEDAL  "Options:          (MIDI pedal)"
+#define GUI_TITLE_OPTION_RESET       "Options:          (TOTAL RESET)"
+
 
 #define GUI_BUTTONTEXT_DEL             "  <xx"
 #define GUI_BUTTONTEXT_SPACE           ""
@@ -203,10 +208,6 @@ inline void gui_gotostate_select (void);
 inline void gui_gotostate_name (const uint8_t new);
 inline void gui_gotostate_select_save (void);
 inline void gui_gotostate_options (void);
-inline void gui_gotostate_tuning (void);
-inline void gui_gotostate_transpose (void);
-inline void gui_gotostate_midi_id (void);
-inline void gui_gotostate_midi_id_out (void);
 inline void gui_gotostate_err_aix (void);
 inline void gui_gotostate_err_ctrl (void);
 inline void gui_gotostate_err_fs (void);
@@ -217,10 +218,6 @@ inline void gui_event_select (const uint16_t event);
 inline void gui_event_name (const uint16_t event);
 inline void gui_event_select_save (const uint16_t event);
 inline void gui_event_options (const uint16_t event);
-inline void gui_event_tuning (const uint16_t event);
-inline void gui_event_transp (const uint16_t event);
-inline void gui_event_midi_id (const uint16_t event);
-inline void gui_event_midi_id_out (const uint16_t event);
 inline void gui_event_err_aix (const uint16_t event);
 inline void gui_event_err_ctrl (const uint16_t event);
 inline void gui_event_err_fs (const uint16_t event);
index 57016ec12a9dd428b61050564c26e0006f39c4f6..774eb457d144749b705df40e7b537c1fdc6a75ba 100644 (file)
@@ -1,5 +1,5 @@
 /*
-Copyright 2021 Balthasar Szczepański
+Copyright 2021, 2025 Balthasar Szczepański
 
 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 
@@ -263,5 +263,17 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
        asm("br !!0xEF00;"); \
 }
 
+// common actions on buffer pointers
+// W  write pointer
+// R  read pointer
+// P  any pointer
+// N  buffer size
+#define ADVANCE_BP(P, N)      ((P<(N-1)) ? (++P) : (P=0))
+#define DIFF_BP(W, R, N)      ((W<R) ? (N + W - R) : W - R)
+#define FULL_BP(W, R, N)      (DIFF_BP(W, R, N) == (N-1))
+#define NOT_FULL_BP(W, R, N)  (DIFF_BP(W, R, N) != (N-1))
+#define EMPTY_BP(W, R, N)     (R == W)
+#define NOT_EMPTY_BP(W, R, N) (R != W)
+#define CLEAR_BP(W, R, N)     (R = W)
 
 #endif
diff --git a/lcd.c b/lcd.c
index 299fdc9a6873624399ad6e891ff602c77537a7c7..8a9f84132c2cbc7b1bbbfadd450bb7e7a6ec2973 100644 (file)
--- a/lcd.c
+++ b/lcd.c
@@ -1,6 +1,6 @@
 /* LCD */
 /*
-Copyright 2021 Balthasar Szczepański
+Copyright 2021, 2025 Balthasar Szczepański
 
 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 
@@ -69,8 +69,6 @@ inline void lcd_contrast (const uint16_t value)
        lcd_write(LCD_MASTER, LCD_DATA, x >> LCD_Vop_HIGHSHIFT);
 }
 
-
-
 inline void setup_lcd (void)
 {
        PER1 |= 0b00000001; //enable timer RJ
@@ -598,13 +596,17 @@ void lcd_draw_adsr (const uint8_t * const data)
 void lcd_subdraw_button (
        uint16_t * const x,
        const uint8_t type,
-       const uint8_t * const text
+       const uint8_t * const text,
+       const uint8_t selected
 )
 {
        uint16_t line1, line2, line3, line4, margin_l, margin_r;
        uint16_t len, N;
        uint16_t i, i0, i1, i2, i3, j0, j1, j2, j3;
        uint8_t  chip = LCD_SLAVE;
+       uint8_t  underline;
+       
+       underline = selected ? 0x3C : 00;
        
        line1 = button_chars[type];
        margin_l = button_lmargin[type];
@@ -652,7 +654,7 @@ void lcd_subdraw_button (
                        lcd_write(chip, LCD_DATA, font16[j0]);
                        ++j0;
                        lcd_write(chip, LCD_DATA, 0x00);
-                       lcd_write(chip, LCD_DATA, 0x00);
+                       lcd_write(chip, LCD_DATA, underline);
                        ++(*x);
                }
        }
@@ -680,7 +682,7 @@ void lcd_subdraw_button (
                        ++j1;
                        lcd_write(chip, LCD_DATA, font16[j1]);
                        ++j1;
-                       lcd_write(chip, LCD_DATA, 0x00);
+                       lcd_write(chip, LCD_DATA, underline);
                        ++(*x);
                }
        }
@@ -709,7 +711,7 @@ void lcd_subdraw_button (
                        ++j1;
                        lcd_write(chip, LCD_DATA, font8[j2]);
                        ++j2;
-                       lcd_write(chip, LCD_DATA, 0x00);
+                       lcd_write(chip, LCD_DATA, underline);
                        ++(*x);
                }
        }
@@ -741,7 +743,7 @@ void lcd_subdraw_button (
                        ++j2;
                        lcd_write(chip, LCD_DATA, font8[j3]);
                        ++j3;
-                       lcd_write(chip, LCD_DATA, 0x00);
+                       lcd_write(chip, LCD_DATA, underline);
                        ++(*x);
                }
        }
@@ -753,7 +755,7 @@ void lcd_subdraw_button (
                lcd_write(chip, LCD_DATA, 0x00);
                lcd_write(chip, LCD_DATA, 0x00);
                lcd_write(chip, LCD_DATA, 0x00);
-               lcd_write(chip, LCD_DATA, 0x00);
+               lcd_write(chip, LCD_DATA, 0x80);
                ++(*x);
        }
 }
@@ -761,13 +763,17 @@ void lcd_subdraw_button (
 void lcd_subdraw_lowbutton8 (
        uint16_t * const x,
        const uint8_t type,
-       const uint8_t * const text
+       const uint8_t * const text,
+       const uint8_t selected
 )
 {
        uint16_t line1, margin_l, margin_r;
        uint16_t len, N;
        uint16_t i, i0, j0, j3;
        uint8_t  chip = LCD_SLAVE;
+       uint8_t  underline;
+       
+       underline = selected ? 0x3C : 00;
        
        line1 = button_chars[type];
        margin_l = button_lmargin[type];
@@ -802,7 +808,7 @@ void lcd_subdraw_lowbutton8 (
                }
                lcd_write(chip, LCD_DATA, font8[j0]);
                ++j0;
-               lcd_write(chip, LCD_DATA, 0x00);
+               lcd_write(chip, LCD_DATA, underline);
                ++(*x);
        }
 
@@ -913,45 +919,57 @@ void lcd_draw_menu (
        const uint8_t * const button_C,
        const uint8_t * const button_D,
        const uint8_t * const button_E,
-       const uint8_t * const button_F
+       const uint8_t * const button_F,
+       const int8_t          selected
 ){
        uint16_t x=0;
        
        lcd_setup_drawing(LCD_MONO, 0, 511, 0, 4);
        
-       lcd_subdraw_button (&x, FULLTEXT - buttons, title);
+       lcd_subdraw_button (&x, FULLTEXT - buttons, title, 0);
        switch (buttons)
        {
        case 7:
                lcd_subdraw_divider(&x);
-               lcd_subdraw_button (&x, BUTTON_1X, button_0);
+               lcd_subdraw_button (&x, BUTTON_1X, button_0, selected == -1);
        case 6:
                lcd_subdraw_divider(&x);
-               lcd_subdraw_button (&x, BUTTON_1X, button_A);
+               lcd_subdraw_button (&x, BUTTON_1X, button_A, selected == 0);
        case 5:
                lcd_subdraw_divider(&x);
-               lcd_subdraw_button (&x, BUTTON_1X, button_B);
+               lcd_subdraw_button (&x, BUTTON_1X, button_B, selected == 1);
        case 4:
                lcd_subdraw_divider(&x);
-               lcd_subdraw_button (&x, BUTTON_1X, button_C);
+               lcd_subdraw_button (&x, BUTTON_1X, button_C, selected == 2);
        case 3:
                lcd_subdraw_divider(&x);
-               lcd_subdraw_button (&x, BUTTON_1X, button_D);
+               lcd_subdraw_button (&x, BUTTON_1X, button_D, selected == 3);
        case 2:
                lcd_subdraw_divider(&x);
-               lcd_subdraw_button (&x, BUTTON_1X, button_E);
+               lcd_subdraw_button (&x, BUTTON_1X, button_E, selected == 4);
        case 1:
                lcd_subdraw_divider(&x);
-               lcd_subdraw_button (&x, BUTTON_1X, button_F);
+               lcd_subdraw_button (&x, BUTTON_1X, button_F, selected == 5);
        case 0:
        default:
                break;
        }
 }
 
+void lcd_update_title (const uint8_t * const text)
+{
+       uint16_t x = 0;
+       
+       lcd_setup_drawing(LCD_MONO, 0, TITLE_6B_PIXELS-1, 0, 4);
+       
+       lcd_subdraw_button (&x, TITLE_6B, text, 0);
+}
+
+
 void lcd_update_button (
        const int8_t id,
-       const uint8_t * const text
+       const uint8_t * const text,
+       const uint8_t selected
 )
 {
        uint16_t x;
@@ -960,7 +978,57 @@ void lcd_update_button (
        
        lcd_setup_drawing(LCD_MONO, x, x+BUTTON_1X_PIXELS-1, 0, 4);
        
-       lcd_subdraw_button (&x, 0, text);
+       lcd_subdraw_button (&x, BUTTON_1X, text, selected);
+}
+
+void lcd_select_button (
+       const int8_t id,
+       const uint8_t selected
+)
+{
+       uint16_t x;
+       uint16_t N;
+       uint16_t margin_l, margin_r;
+       uint16_t i;
+       uint8_t  chip = LCD_SLAVE;
+       uint8_t  underline;
+       
+       if ((id < -1) || (id > 5))
+               return;
+       
+       x = TITLE_6B_PIXELS + 1 + id * (BUTTON_1X_PIXELS + 1);
+       
+       lcd_setup_drawing(LCD_MONO, x, x+BUTTON_1X_PIXELS-1, 4, 4);
+       
+       underline = selected ? 0x3C : 00;
+
+       margin_l = button_lmargin[BUTTON_1X];
+       margin_r = button_rmargin[BUTTON_1X];
+       N = button_chars[BUTTON_1X] <<3;
+       
+       for(i=0; i<margin_l; ++i) // left margin
+       {
+               if (x >= 256)
+                       chip = LCD_MASTER;
+               lcd_write(chip, LCD_DATA, 0x00);
+               ++x;
+       }
+       
+       for (i=0; i<N; ++i) // underline
+       {
+               if (x >= 256)
+                       chip = LCD_MASTER;
+               lcd_write(chip, LCD_DATA, underline);
+               ++x;
+       }
+       
+       for(i=0; i<margin_r; ++i) // right margin
+       {
+               if (x >= 256)
+                       chip = LCD_MASTER;
+               lcd_write(chip, LCD_DATA, 0x00);
+               ++x;
+       }
 }
 
 void lcd_draw_name_cursor (const uint8_t pos)
@@ -1014,31 +1082,32 @@ void lcd_draw_name_menu (
        const uint8_t * const button_C,
        const uint8_t * const button_D,
        const uint8_t * const button_E,
-       const uint8_t * const button_F
+       const uint8_t * const button_F,
+       const int8_t          selected
 )
 {
        uint16_t x = 0;
        lcd_clear_screen(LCD_MONO);
        lcd_setup_drawing(LCD_MONO, 0, TITLE_6B_PIXELS, 0, 4);
        
-       lcd_subdraw_button (&x, TITLE_7B, title);
+       lcd_subdraw_button (&x, TITLE_7B, title, 0);
        lcd_subdraw_divider(&x);
-       lcd_subdraw_button (&x, BUTTON_1X, name);
+       lcd_subdraw_button (&x, BUTTON_1X, name, 0);
        lcd_subdraw_divider(&x);
        
        lcd_setup_drawing(LCD_MONO, x, 511, 3, 4);
        
-       lcd_subdraw_lowbutton8(&x, BUTTON_1X, button_A);
+       lcd_subdraw_lowbutton8(&x, BUTTON_1X, button_A, selected == 0);
        lcd_subdraw_lowdivider(&x);
-       lcd_subdraw_lowbutton8(&x, BUTTON_1X, button_B);
+       lcd_subdraw_lowbutton8(&x, BUTTON_1X, button_B, selected == 1);
        lcd_subdraw_lowdivider(&x);
-       lcd_subdraw_lowbutton8(&x, BUTTON_1X, button_C);
+       lcd_subdraw_lowbutton8(&x, BUTTON_1X, button_C, selected == 2);
        lcd_subdraw_lowdivider(&x);
-       lcd_subdraw_lowbutton8(&x, BUTTON_1X, button_D);
+       lcd_subdraw_lowbutton8(&x, BUTTON_1X, button_D, selected == 3);
        lcd_subdraw_lowdivider(&x);
-       lcd_subdraw_lowbutton8(&x, BUTTON_1X, button_E);
+       lcd_subdraw_lowbutton8(&x, BUTTON_1X, button_E, selected == 4);
        lcd_subdraw_lowdivider(&x);
-       lcd_subdraw_lowbutton8(&x, BUTTON_1X, button_F);
+       lcd_subdraw_lowbutton8(&x, BUTTON_1X, button_F, selected == 5);
        
        lcd_draw_name_list(list);
        
diff --git a/lcd.h b/lcd.h
index f136eadaf6ed7361f81d2a3a3b6cafb5f216165b..a62c36147a66cc1903a17a3f099d397c4610f3fd 100644 (file)
--- a/lcd.h
+++ b/lcd.h
@@ -1,6 +1,6 @@
 /* LCD */
 /*
-Copyright 2021 Balthasar Szczepański
+Copyright 2021, 2025 Balthasar Szczepański
 
 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 
@@ -428,12 +428,14 @@ void        lcd_draw_adsr (const uint8_t * const data);
 void        lcd_subdraw_button (
        uint16_t * const x,
        const uint8_t type,
-       const uint8_t * const text
+       const uint8_t * const text,
+       const uint8_t selected
 );
 void        lcd_subdraw_lowbutton8 (
        uint16_t * const x,
        const uint8_t type,
-       const uint8_t * const text
+       const uint8_t * const text,
+       const uint8_t selected
 );
 void        lcd_subdraw_lowbutton16 (
        uint16_t * const x,
@@ -450,11 +452,18 @@ void        lcd_draw_menu (
        const uint8_t * const button_C,
        const uint8_t * const button_D,
        const uint8_t * const button_E,
-       const uint8_t * const button_F
+       const uint8_t * const button_F,
+       const int8_t          selected
 );
+void        lcd_update_title (const uint8_t * const text);
 void        lcd_update_button (
        const int8_t id,
-       const uint8_t * const text
+       const uint8_t * const text,
+       const uint8_t selected
+);
+void        lcd_select_button (
+       const int8_t id,
+       const uint8_t selected
 );
 void lcd_draw_name_cursor(const uint8_t pos);
 void lcd_erase_name_cursor(const uint8_t pos);
@@ -469,5 +478,6 @@ void lcd_draw_name_menu (
        const uint8_t * const button_C,
        const uint8_t * const button_D,
        const uint8_t * const button_E,
-       const uint8_t * const button_F
+       const uint8_t * const button_F,
+       const int8_t          selected
 );