Index: /trunk/core/gui_space.c
===================================================================
--- /trunk/core/gui_space.c	(revision 1298)
+++ /trunk/core/gui_space.c	(revision 1299)
@@ -18,108 +18,73 @@
 }
 
+// Local variables used by various space display functions, setup in space_color
+static color cl;
+static coord xx, yy;
+static int perc, width, height;
+
+// Set up color and percent free variables for free space OSD
+static void space_color()
+{
+    perc = get_space_perc();
+    cl = conf.space_color;
+    if (((conf.space_warn_type == 0) && (perc <= conf.space_perc_warn)) ||
+        ((conf.space_warn_type == 1) && (GetFreeCardSpaceKb() <= conf.space_mb_warn*1024)))
+    {
+        cl = conf.osd_color_warn;
+    }
+}
+
+// Setup position and size variables then draw free space bar, outer shape
+static void spacebar_outer(OSD_pos pos, int w, int h)
+{
+    // Get color and percent free
+    space_color();
+
+    // space icon / bar position
+    xx = pos.x;
+    yy = pos.y;
+
+    // space icon / bar size
+    width = w;
+    height = h;
+
+    // Clamp co-ordinates to keep bar on screen
+    if (xx > (screen_width-width-4)) {
+        xx = screen_width-width-4;
+    }
+    if (yy > (screen_height-height-4)) {
+        yy = screen_height-height-4;
+    }
+
+    draw_rect(xx, yy, xx+width+3, yy+height+3, COLOR_BLACK);     // Outer black rectangle
+    draw_rect(xx+1, yy+1, xx+width+2, yy+height+2, cl);          // Inner white/red rectangle
+}
+
 static void gui_space_draw_spacebar_horizontal() {
     coord x;
-    register coord xx, yy;
 
-    xx = conf.space_hor_pos.x;
-    yy = conf.space_hor_pos.y;
-
-    color cl = conf.space_color;
-    int perc = get_space_perc(),height = 2;
-    int size = 0;
-    if (conf.space_warn_type == 0) {
-        cl = (perc<=conf.space_perc_warn)?conf.osd_color_warn:(conf.space_color);
-    } else if (conf.space_warn_type == 1) {
-        cl = (GetFreeCardSpaceKb()/1024<=conf.space_mb_warn)?conf.osd_color_warn:(conf.space_color);
-    } else if (conf.space_warn_type == 2) {
-        cl = conf.space_color;
-    }
-    // space icon / bar
-    height = conf.space_bar_width+1;
-    if (conf.space_bar_size == 0) {
-        size = screen_width/4-4;
-        if (xx>(screen_width-size)) {
-            xx = screen_width-size;
-        }
-    } else if (conf.space_bar_size == 1) {
-        size = screen_width/2-4;
-        if (xx>(screen_width-size)) {
-            xx = screen_width-size;
-        }
-    } else if (conf.space_bar_size == 2) {
-        size = screen_width-4;
-        if (xx>(screen_width-size)) {
-            xx = 0;
-        }
-    }
-    if (yy > (screen_height-height-3)) {
-        yy = screen_height-height-3;
-    }
-    draw_rect(xx+1,    yy+1,     xx+1+size+2, yy+1+height+1,  cl);
-    draw_vline(xx+1-1,    yy+1-1, 1+height+2, COLOR_BLACK);  // l
-    draw_hline(xx+1-1,    yy+1-1,   1+size+3, COLOR_BLACK);  // t
-    draw_hline(xx+1-1,    yy+1+height+2,  1+size+3, COLOR_BLACK);  // b
-    draw_vline(xx+1+size+3, yy+1-1,  1+height+2,  COLOR_BLACK);  // r
+    // Setup and draw outer shape
+    spacebar_outer(conf.space_hor_pos, (screen_width / (4 >> conf.space_bar_size)) - 4, conf.space_bar_width);
 
     // space bar fill
-
-    x = xx + size - ((perc*size)/100);
-    if (x<=xx+1) x=xx+1;
-    if (x>xx+size) x=xx+size;
-    draw_filled_rect(xx+1+1, yy+1+1, x-1, yy+1+height, MAKE_COLOR(COLOR_TRANSPARENT, COLOR_BLACK));
-    draw_filled_rect(x, yy+1+1, xx+1+size+2, yy+1+height, MAKE_COLOR(cl, cl));
+    x = width - ((perc*width)/100);
+    if (x < 1) x = 1;
+    if (x >= width) x = width;
+    else draw_filled_rect(xx+x+2, yy+2, xx+width+1, yy+height+1, MAKE_COLOR(cl, cl));               // If not empty fill 'free' space area
+    draw_filled_rect(xx+2, yy+2, xx+x+1, yy+height+1, MAKE_COLOR(COLOR_TRANSPARENT, COLOR_BLACK));  // fill 'used' space area
 }
 
 static void gui_space_draw_spacebar_vertical() {
     coord y;
-    register coord xx, yy;
 
-    xx = conf.space_ver_pos.x;
-    yy = conf.space_ver_pos.y;
-
-    color cl = conf.space_color;
-    int perc = get_space_perc(), width = 2;
-    int size = 0;
-    if (conf.space_warn_type == 0) {
-        cl = (perc<=conf.space_perc_warn)?conf.osd_color_warn:(conf.space_color);
-    } else if (conf.space_warn_type == 1) {
-        cl = (GetFreeCardSpaceKb()/1024<=conf.space_mb_warn)?conf.osd_color_warn:(conf.space_color);
-    } else if (conf.space_warn_type == 2) {
-        cl = conf.space_color;
-    }
-
-    // space icon / bar
-    width = conf.space_bar_width+1;
-    if (conf.space_bar_size == 0) {
-        size = screen_height/4-4;
-        if (yy>(screen_height-size)) {
-            yy = screen_height-size;
-        }
-    } else if (conf.space_bar_size == 1) {
-        size = screen_height/2-4;
-        if (yy>(screen_height-size)) {
-            yy = screen_height-size;
-        }
-    } else if (conf.space_bar_size == 2) {
-        size = screen_height-4;
-        if (yy>(screen_height-size)) {
-            yy = 0;
-        }
-    }
-    if (xx > (screen_width-width-3)) {
-        xx = screen_width-width-3;
-    }
-    draw_rect(xx+1,    yy+1,     xx+1+width+1, yy+1+size+2,  cl);
-    draw_vline(xx+1-1,    yy+1-1, 1+5, COLOR_BLACK);   // l
-    draw_hline(xx+1-1,    yy+1-1, 1+width+2, COLOR_BLACK);   // t
-    draw_hline(xx+1-1,    yy+1+size+3, 1+width+2, COLOR_BLACK);   // b
-    draw_vline(xx+1+width+2, yy+1-1,   1+size+3,  COLOR_BLACK);   // r
+    // Setup and draw outer shape
+    spacebar_outer(conf.space_ver_pos, conf.space_bar_width, (screen_height / (4 >> conf.space_bar_size)) - 4);
 
     // space bar fill
-    y = yy + size - ((perc*size)/100);
-    if (y<=yy+1) y=yy+1;
-    if (y>yy+size) y=yy+size;
-    draw_filled_rect(xx+1+1, yy+1+1, xx+1+width, y-1, MAKE_COLOR(COLOR_TRANSPARENT, COLOR_BLACK));
-    draw_filled_rect(xx+1+1, y, xx+1+width, yy+1+size+2, MAKE_COLOR(cl, cl));
+    y = height - ((perc*height)/100);
+    if (y < 1) y = 1;
+    if (y >= height) y = height;
+    else draw_filled_rect(xx+2, yy+y+2, xx+width+1, yy+height+1, MAKE_COLOR(cl, cl));               // If not empty fill 'free' space area
+    draw_filled_rect(xx+2, yy+2, xx+width+1, yy+y+1, MAKE_COLOR(COLOR_TRANSPARENT, COLOR_BLACK));   // fill 'used' space area
 }
 
@@ -127,34 +92,25 @@
     coord x;
     register coord xx, yy;
+    int i;
 
     xx = conf.space_icon_pos.x;
     yy = conf.space_icon_pos.y;
 
-    color cl = conf.space_color;
-    int perc = get_space_perc();
-    if (conf.space_warn_type == 0) {
-        cl = (perc<=conf.space_perc_warn)?conf.osd_color_warn:(conf.space_color);
-    } else if (conf.space_warn_type == 1) {
-        cl = (GetFreeCardSpaceKb()/1024<=conf.space_mb_warn)?conf.osd_color_warn:(conf.space_color);
-    } else if (conf.space_warn_type == 2) {
-        cl = conf.space_color;
-    }
-    int i;
+    space_color();
+
 #define LE  23
 #define WI  15
-//    int le = 23;    // length
-//    int wi = 15;    // width
 
-    draw_hline(xx+5,      yy,      LE-5,     COLOR_BLACK);          // outer top
-    draw_hline(xx+6,      yy+1,    LE-7,     MAKE_COLOR(cl, cl));   // inner top
-    draw_vline(xx,        yy+5,    WI-5,     COLOR_BLACK);          // outer left
-    draw_vline(xx+1,      yy+6,    WI-7,     MAKE_COLOR(cl, cl));   // inner left
-    draw_hline(xx,        yy+WI,   LE,       COLOR_BLACK);          // outer bottom
-    draw_hline(xx+1,      yy+WI-1, LE-2,     MAKE_COLOR(cl, cl));   // inner bottom
-    draw_vline(xx+LE,     yy,      WI,       COLOR_BLACK);          // outer right
-    draw_vline(xx+LE-1,   yy+1,    WI-2,     MAKE_COLOR(cl, cl));   // inner right
-    draw_line(xx+5,      yy,       xx,        yy+5,     COLOR_BLACK);          // edge
-    draw_line(xx+5,      yy+1,     xx+1,      yy+5,     MAKE_COLOR(cl, cl));   // edge
-    draw_line(xx+6,      yy+1,     xx+1,      yy+6,     MAKE_COLOR(cl, cl));   // edge
+    draw_hline(xx+5,     yy,      LE-5,     COLOR_BLACK);          // outer top
+    draw_hline(xx+6,     yy+1,    LE-7,     MAKE_COLOR(cl, cl));   // inner top
+    draw_vline(xx,       yy+5,    WI-5,     COLOR_BLACK);          // outer left
+    draw_vline(xx+1,     yy+6,    WI-7,     MAKE_COLOR(cl, cl));   // inner left
+    draw_hline(xx,       yy+WI,   LE,       COLOR_BLACK);          // outer bottom
+    draw_hline(xx+1,     yy+WI-1, LE-2,     MAKE_COLOR(cl, cl));   // inner bottom
+    draw_vline(xx+LE,    yy,      WI,       COLOR_BLACK);          // outer right
+    draw_vline(xx+LE-1,  yy+1,    WI-2,     MAKE_COLOR(cl, cl));   // inner right
+    draw_line(xx+5,      yy,      xx,       yy+5,     COLOR_BLACK);          // edge
+    draw_line(xx+5,      yy+1,    xx+1,     yy+5,     MAKE_COLOR(cl, cl));   // edge
+    draw_line(xx+6,      yy+1,    xx+1,     yy+6,     MAKE_COLOR(cl, cl));   // edge
 
     // memory fill
@@ -163,13 +119,13 @@
     if (x>2) draw_hline(xx+x+1,    yy+2,     LE-x-3,  MAKE_COLOR(cl, cl));
     else     draw_hline(xx+4,      yy+2,     LE-6,    MAKE_COLOR(cl, cl));
-    for(i=3; i<7; i++) {                                                                                                     //          /--------------|
+    for(i=3; i<7; i++) {                                                               //          /--------------|
         if (x>7-i) draw_pixel(xx+8-i,     yy+i,     COLOR_BLACK);                      //        /  1st for loop  |
         if (x>7-i) draw_pixel(xx+x,       yy+i,     COLOR_BLACK);                      //      /__________________|
-        draw_hline(xx+x+1,                 yy+i,     LE-x-3,    MAKE_COLOR(cl, cl));   //     |                   |
-    }                                                                                                                        //     |     2nd for loop  |
-    for(i=7; i<WI-2; i++) {                                                                                                  //     |                   |
+        draw_hline(xx+x+1, yy+i, LE-x-3, MAKE_COLOR(cl, cl));                          //     |                   |
+    }                                                                                  //     |     2nd for loop  |
+    for(i=7; i<WI-2; i++) {                                                            //     |                   |
         if (x>1) draw_pixel(xx+2,         yy+i,     COLOR_BLACK);                      //     |-------------------|
         if (x>1) draw_pixel(xx+x,         yy+i,     COLOR_BLACK);
-        draw_hline(xx+x+1,                 yy+i,     LE-x-3,    MAKE_COLOR(cl, cl));
+        draw_hline(xx+x+1, yy+i, LE-x-3, MAKE_COLOR(cl, cl));
     }
     if (x>1) draw_hline(xx+2,      yy+WI-2,    x-2,     COLOR_BLACK);
@@ -179,14 +135,6 @@
 //-------------------------------------------------------------------
 static void gui_space_draw_percent() {
-    int perc = get_space_perc();
-    color cl = conf.space_color;
-    if (conf.space_warn_type == 0) {
-        cl = (perc<=conf.space_perc_warn)?conf.osd_color_warn:(conf.space_color);
-    } else if (conf.space_warn_type == 1) {
-        cl = (GetFreeCardSpaceKb()/1024<=conf.space_mb_warn)?conf.osd_color_warn:(conf.space_color);
-    } else if (conf.space_warn_type == 2) {
-        cl = conf.space_color;
-    }
-    sprintf(osd_buf, "%3d%%", get_space_perc());
+    space_color();
+    sprintf(osd_buf, "%3d%%", perc);
     osd_buf[5]=0;
     draw_string(conf.space_txt_pos.x, conf.space_txt_pos.y, osd_buf, cl);
@@ -195,13 +143,5 @@
 //-------------------------------------------------------------------
 static void gui_space_draw_mb() {
-    int perc = get_space_perc();
-    color cl = conf.space_color;
-    if (conf.space_warn_type == 0) {
-        cl = (perc<=conf.space_perc_warn)?conf.osd_color_warn:(conf.space_color);
-    } else if (conf.space_warn_type == 1) {
-        cl = (GetFreeCardSpaceKb()/1024<=conf.space_mb_warn)?conf.osd_color_warn:(conf.space_color);
-    } else if (conf.space_warn_type == 2) {
-        cl = conf.space_color;
-    }
+    space_color();
     unsigned int freemb=GetFreeCardSpaceKb()/1024;
     if (freemb < 10000) sprintf(osd_buf, "%3d%M",freemb);
Index: /trunk/core/gui_draw.c
===================================================================
--- /trunk/core/gui_draw.c	(revision 1298)
+++ /trunk/core/gui_draw.c	(revision 1299)
@@ -254,4 +254,5 @@
 //-------------------------------------------------------------------
 
+// Local variables set up by draw_rectangle, and used in fill_rect
 static unsigned int xMin, yMin, xMax, yMax;
 
Index: /trunk/core/gui_menu.c
===================================================================
--- /trunk/core/gui_menu.c	(revision 1298)
+++ /trunk/core/gui_menu.c	(revision 1299)
@@ -35,5 +35,4 @@
 static int          len_bool, len_int, len_enum, len_space, len_br1, len_br2, cl_rect;
 static int          int_incr, incr_modified;
-static int          c, j;
 static unsigned char *item_color;
 
@@ -49,10 +48,10 @@
     if (menu_ptr) {
         if (conf.menu_select_first_entry)
-        gui_menu_set_curr_menu(menu_ptr, 0, 0);
+            gui_menu_set_curr_menu(menu_ptr, 0, 0);
         else 
-        gui_menu_set_curr_menu(menu_ptr, 0, -1);
+            gui_menu_set_curr_menu(menu_ptr, 0, -1);
         gui_menu_stack_ptr = 0;
     }
-    
+
     num_lines = screen_height/rbf_font_height()-1;
     x = CAM_MENU_BORDERWIDTH;
@@ -66,21 +65,32 @@
     cl_rect = rbf_font_height() - 4;
     int_incr = 1;
-    
+
     gui_menu_redraw=2;
 }
 
 //-------------------------------------------------------------------
+int gui_menu_rows()
+{
+    int n;
+    // Count the numer of rows in current menu
+    for(n = 0; curr_menu->menu[n].text; n++);
+    return n;
+}
+
+//-------------------------------------------------------------------
+// Called from other gui functions to force redraw of menu
 void gui_menu_force_redraw()
 {
     if (gui_get_mode() == GUI_MODE_MENU)
     {
-        gui_menu_redraw=2;
-    }
-}
-
-//-------------------------------------------------------------------
-static void gui_menu_color_selected(color clr) {
-    *item_color = (unsigned char)(clr&0xFF);
-    gui_menu_redraw=2;
+        gui_menu_redraw = 2;
+    }
+}
+
+//-------------------------------------------------------------------
+// Full screen erase and redraw of menu
+static void gui_menu_erase_and_redraw()
+{
+    gui_menu_redraw = 2;
     draw_restore();
     gui_force_restore();
@@ -88,17 +98,263 @@
 
 //-------------------------------------------------------------------
+// Function passed to gui_palette_init
+// This is called when a new color is selected to update the menu / config value
+static void gui_menu_color_selected(color clr)
+{
+    *item_color = (unsigned char)(clr&0xFF);
+    gui_menu_erase_and_redraw();
+}
+
+//-------------------------------------------------------------------
+// Return to previous menu on stack
 static void gui_menu_back() {
-    if (gui_menu_stack_ptr > 0){
+    if (gui_menu_stack_ptr > 0)
+    {
         gui_menu_stack_ptr--;
         gui_menu_set_curr_menu(gui_menu_stack[gui_menu_stack_ptr].menu, gui_menu_stack[gui_menu_stack_ptr].toppos, gui_menu_stack[gui_menu_stack_ptr].curpos);
-        gui_menu_redraw=2;
-        draw_restore();
-        gui_force_restore();
-    }
-}
-
-//-------------------------------------------------------------------
+        gui_menu_erase_and_redraw();
+    }
+}
+
+//-------------------------------------------------------------------
+// Helper functions for gui_menu_kbd_process
+//  common code blocks extracted to try and make it easier to understand
+
+// If updating an 'int' value check if other buttons are also pressed, and set increment accordingly
+// E.G. if ZOOM_OUT is held then RIGHT pressed the 'int' value will be incremented by 10, ZOOM_IN + RIGHT increment by 100
+static void get_int_incr_from_button()
+{
+    if (kbd_is_key_pressed(KEY_ZOOM_OUT))
+    {
+        int_incr=10;
+        incr_modified=1;
+    }
+    if (kbd_is_key_pressed(KEY_ZOOM_IN))
+    {
+        int_incr=100;
+        incr_modified=1;
+    }
+    if (kbd_is_key_pressed(KEY_SHOOT_HALF))
+    {
+        int_incr=1000;
+        incr_modified=1;
+    }
+}
+
+// After updating a value check for callback and on_change functions and call if necessary
+static void do_callback()
+{
+    if ((curr_menu->menu[gui_menu_curr_item].type & MENUITEM_ARG_MASK) == MENUITEM_ARG_CALLBACK && curr_menu->menu[gui_menu_curr_item].arg)
+    {
+        ((void (*)())(curr_menu->menu[gui_menu_curr_item].arg))();
+    }
+
+    if (curr_menu->on_change)
+    {
+        curr_menu->on_change(gui_menu_curr_item);
+    }
+}
+
+// Update an 'int' value, direction = 1 for increment, -1 for decrement
+static void update_int_value(int direction)
+{
+    // set amount to increment by (int_incr) if other buttons pressed
+    get_int_incr_from_button();
+
+    // do update based on 'int' sub-type
+    switch (curr_menu->menu[gui_menu_curr_item].type & MENUITEM_ARG_MASK)
+    {
+        case MENUITEM_ARG_INC:
+            *(curr_menu->menu[gui_menu_curr_item].value) += curr_menu->menu[gui_menu_curr_item].arg * direction;
+            break;
+        case MENUITEM_ARG_ADDR_INC:
+            *(curr_menu->menu[gui_menu_curr_item].value) += *(int *)(curr_menu->menu[gui_menu_curr_item].arg) * direction;
+            break;
+        default:
+            *(curr_menu->menu[gui_menu_curr_item].value) += int_incr * direction;
+            break;
+    }
+
+    // Limit new value to defined bounds
+    if ( curr_menu->menu[gui_menu_curr_item].type & MENUITEM_F_UNSIGNED)
+    {
+        if (*(curr_menu->menu[gui_menu_curr_item].value) < 0) 
+            *(curr_menu->menu[gui_menu_curr_item].value) = 0;
+
+        if ( curr_menu->menu[gui_menu_curr_item].type & MENUITEM_F_MIN)
+        {
+            if (*(curr_menu->menu[gui_menu_curr_item].value) < (unsigned short)(curr_menu->menu[gui_menu_curr_item].arg & 0xFFFF)) 
+                *(curr_menu->menu[gui_menu_curr_item].value) = (unsigned short)(curr_menu->menu[gui_menu_curr_item].arg & 0xFFFF);
+        }
+    }
+    else
+    {
+        if (*(curr_menu->menu[gui_menu_curr_item].value) < -9999) 
+            *(curr_menu->menu[gui_menu_curr_item].value) = -9999;
+
+        if ( curr_menu->menu[gui_menu_curr_item].type & MENUITEM_F_MIN)
+        {
+            if (*(curr_menu->menu[gui_menu_curr_item].value) < (short)(curr_menu->menu[gui_menu_curr_item].arg & 0xFFFF)) 
+                *(curr_menu->menu[gui_menu_curr_item].value) = (short)(curr_menu->menu[gui_menu_curr_item].arg & 0xFFFF);
+        }
+    }
+
+    if (*(curr_menu->menu[gui_menu_curr_item].value) > 99999) 
+        *(curr_menu->menu[gui_menu_curr_item].value) = 99999;
+
+    if ( curr_menu->menu[gui_menu_curr_item].type & MENUITEM_F_UNSIGNED)
+    {
+        if ( curr_menu->menu[gui_menu_curr_item].type & MENUITEM_F_MAX)
+        {
+            if (*(curr_menu->menu[gui_menu_curr_item].value) > (unsigned short)((curr_menu->menu[gui_menu_curr_item].arg>>16) & 0xFFFF)) 
+                *(curr_menu->menu[gui_menu_curr_item].value) = (unsigned short)((curr_menu->menu[gui_menu_curr_item].arg>>16) & 0xFFFF);
+        }
+    }
+    else
+    {
+        if ( curr_menu->menu[gui_menu_curr_item].type & MENUITEM_F_MAX)
+        {
+            if (*(curr_menu->menu[gui_menu_curr_item].value) > (short)((curr_menu->menu[gui_menu_curr_item].arg>>16) & 0xFFFF)) 
+                *(curr_menu->menu[gui_menu_curr_item].value) = (short)((curr_menu->menu[gui_menu_curr_item].arg>>16) & 0xFFFF);
+        }
+    }
+
+    // execute custom callback and on_change functions
+    do_callback();
+
+    // reset int_incr if necessary
+    if (incr_modified)
+    {
+        int_incr=1;
+        incr_modified=0;
+        draw_string(FONT_WIDTH*2,0,"    ", MAKE_COLOR(COLOR_TRANSPARENT, COLOR_TRANSPARENT));
+    }
+
+    // force menu redraw
+    gui_menu_redraw=1;
+}
+
+// Update a 'bool' value
+static void update_bool_value()
+{
+    // update value
+    *(curr_menu->menu[gui_menu_curr_item].value) = !(*(curr_menu->menu[gui_menu_curr_item].value));
+
+    // execute custom callback and on_change functions
+    do_callback();
+
+    // force menu redraw
+    gui_menu_redraw=1;
+}
+
+// Update an 'enum' value, direction = 1 for increment, -1 for decrement
+static void update_enum_value(int direction)
+{
+    // update value
+    if (curr_menu->menu[gui_menu_curr_item].value)
+    {
+        int c;
+        if (kbd_is_key_pressed(KEY_SHOOT_HALF)) c=3;
+        else if (kbd_is_key_pressed(KEY_ZOOM_IN)) c=6;
+        else if (kbd_is_key_pressed(KEY_ZOOM_OUT)) c=3;
+        else c=1;
+        ((const char* (*)(int change, int arg))(curr_menu->menu[gui_menu_curr_item].value))(c*direction, curr_menu->menu[gui_menu_curr_item].arg);
+    }
+
+    // force menu redraw
+    gui_menu_redraw=1;
+}
+
+// Open a sub-menu
+static void select_sub_menu()
+{
+    // push current menu on stack
+    gui_menu_stack[gui_menu_stack_ptr].menu = curr_menu;
+    gui_menu_stack[gui_menu_stack_ptr].curpos = gui_menu_curr_item;
+    gui_menu_stack[gui_menu_stack_ptr].toppos = gui_menu_top_item;
+
+    // Select first item in menu, (or none)
+    if (conf.menu_select_first_entry)
+    {
+        gui_menu_set_curr_menu((CMenu*)(curr_menu->menu[gui_menu_curr_item].value), 0, 0);
+        if ((curr_menu->menu[gui_menu_curr_item].type & MENUITEM_MASK)==MENUITEM_TEXT || (curr_menu->menu[gui_menu_curr_item].type & MENUITEM_MASK)==MENUITEM_SEPARATOR)
+        {
+            //++gui_menu_top_item;
+            ++gui_menu_curr_item;
+        }
+    }
+    else 
+        gui_menu_set_curr_menu((CMenu*)(curr_menu->menu[gui_menu_curr_item].value), 0, -1);
+
+    gui_menu_stack_ptr++;
+
+    // FIXME check on stack overrun;
+    if (gui_menu_stack_ptr > MENUSTACK_MAXDEPTH)
+    {
+        draw_txt_string(0, 0, "E1", MAKE_COLOR(COLOR_RED, COLOR_YELLOW));
+        gui_menu_stack_ptr = 0;
+    }
+
+    // Force full redraw
+    gui_menu_erase_and_redraw();
+}
+
+// Move up / down in menu, adjusting scroll position if needed
+//   increment = -1 to move up, 1 to move down
+static void gui_menu_updown(int increment)
+{
+    int c, j;
+
+    // Determine number of rows to move (1 or 4)
+    if (kbd_is_key_pressed(KEY_SHOOT_HALF) || kbd_is_key_pressed(KEY_ZOOM_IN) || kbd_is_key_pressed(KEY_ZOOM_OUT)) c=4; else c=1;
+
+    for (j = 0; j < c; ++j)
+    {
+        do
+        {
+            // Move to next or previous row
+            gui_menu_curr_item += increment;
+
+            if (gui_menu_curr_item < 0)                                     // Off top, move to bottom
+            {
+                gui_menu_curr_item = gui_menu_rows() - 1;
+                gui_menu_top_item = gui_menu_curr_item - num_lines + 1;
+            }
+            else if (gui_menu_curr_item >= gui_menu_rows())                 // Off bottom, move to top
+            {
+                gui_menu_curr_item = gui_menu_top_item = 0;
+            }
+            else if (increment == 1)                                        // Still in menu, if moving down adjust scroll if needed
+            {
+                if (gui_menu_curr_item - gui_menu_top_item >= num_lines - 1)
+                {
+                    gui_menu_top_item = gui_menu_curr_item - num_lines + 2;
+                    if (gui_menu_top_item + num_lines > gui_menu_rows()) gui_menu_top_item = gui_menu_rows() - num_lines;
+                }
+            }
+            else                                                            // Still in menu, and moving up, adjust scroll
+            {
+                if (gui_menu_curr_item == gui_menu_top_item) 
+                    --gui_menu_top_item;
+            }
+
+            // Check in case scroll moved off top of menu
+            if (gui_menu_top_item < 0) gui_menu_top_item = 0;
+        } while ((curr_menu->menu[gui_menu_curr_item].type & MENUITEM_MASK)==MENUITEM_TEXT || 
+                 (curr_menu->menu[gui_menu_curr_item].type & MENUITEM_MASK)==MENUITEM_SEPARATOR);
+
+        // Reset amount to increment integer values by
+        int_incr = 1;
+
+        // Redraw menu if needed
+        if (gui_menu_redraw == 0) gui_menu_redraw=1;
+    }
+}
+
+//-------------------------------------------------------------------
+// Process button presses when in GUI_MODE_MENU mode
 void gui_menu_kbd_process() {
-static char sbuf[7];
+    static char sbuf[7];
+
     switch (kbd_get_autoclicked_key() | get_jogdial_direction()) {
 #if CAM_HAS_ERASE_BUTTON
@@ -107,173 +363,64 @@
         case KEY_SHOOT_HALF:
 #endif
-		if (conf.user_menu_enable == 3) {
-			if (curr_menu->title != LANG_MENU_USER_MENU) {
-				/*
-				 * Add new entry
-				 * user menu is currently not visible so no redraw necessary
-				 */
-				mod_user_menu(curr_menu->menu[gui_menu_curr_item],&gui_menu_curr_item, 1);
-			}
-			else {
-				int x;
-				/*
-				 * Remove entry from menu
-				 */
-				mod_user_menu(curr_menu->menu[gui_menu_curr_item],&gui_menu_curr_item, 0);
-
-
-				/*
-				 * Check to see if the last visible entry was deleted and we need need
-				 * to move up our top menu item.
-				 */
-				if(gui_menu_top_item)
-					if(!curr_menu->menu[gui_menu_top_item + num_lines-1].text)
-						gui_menu_top_item--;
-
-				/*
-				 * menu list is smaller so have to redraw everything to get
-				 * things like scroll bar correct.
-				 */
-	            		gui_menu_redraw=2;
-
-				/*
-				 * Count the numer of menu entries
-				 */
-				for(x = 0; curr_menu->menu[x].text; x++)
-						;
-
-				/*
-				 * if the new menu is smaller than visible menu lines on screen
-				 * you have to restore full screen before menu redraw.
-				 * If you don't do this, then a new smaller menu will be drawn
-				 * on top of the older larger menu
-				 *
-				 */
-				if(x < num_lines)
-					draw_restore();
-			}
-		}
-		break;
+            if (conf.user_menu_enable == 3) {
+                if (curr_menu->title != LANG_MENU_USER_MENU) {
+                    /*
+                    * Add new entry
+                    * user menu is currently not visible so no redraw necessary
+                    */
+                    mod_user_menu(curr_menu->menu[gui_menu_curr_item],&gui_menu_curr_item, 1);
+                }
+                else {
+                    /*
+                    * Remove entry from menu
+                    */
+                    mod_user_menu(curr_menu->menu[gui_menu_curr_item],&gui_menu_curr_item, 0);
+
+                    /*
+                    * Check to see if the last visible entry was deleted and we need need
+                    * to move up our top menu item.
+                    */
+                    if(gui_menu_top_item)
+                        if(!curr_menu->menu[gui_menu_top_item + num_lines-1].text)
+                            gui_menu_top_item--;
+
+                    /*
+                    * menu list is smaller so have to redraw everything to get
+                    * things like scroll bar correct.
+                    */
+                    gui_menu_redraw=2;
+
+                    /*
+                    * if the new menu is smaller than visible menu lines on screen
+                    * you have to restore full screen before menu redraw.
+                    * If you don't do this, then a new smaller menu will be drawn
+                    * on top of the older larger menu
+                    *
+                    */
+                    if(gui_menu_rows() < num_lines)
+                        draw_restore();
+                }
+            }
+            break;
         case JOGDIAL_LEFT:
         case KEY_UP:
-			if (kbd_is_key_pressed(KEY_SHOOT_HALF) || kbd_is_key_pressed(KEY_ZOOM_IN) || kbd_is_key_pressed(KEY_ZOOM_OUT)) c=4; else c=1;
-            for (j=0;j<c;++j){
-            do {
-                if (gui_menu_curr_item>0) {
-                    if (gui_menu_curr_item-1==gui_menu_top_item && gui_menu_top_item>0) 
-                        --gui_menu_top_item;
-                    --gui_menu_curr_item;
-                } else {
-                    int i;
-                    while (curr_menu->menu[gui_menu_curr_item+1].text)
-                        ++gui_menu_curr_item;
-                    gui_menu_top_item = gui_menu_curr_item - num_lines +1;
-                    if (gui_menu_top_item<0) gui_menu_top_item=0;
-                }
-            } while ((curr_menu->menu[gui_menu_curr_item].type & MENUITEM_MASK)==MENUITEM_TEXT || 
-                     (curr_menu->menu[gui_menu_curr_item].type & MENUITEM_MASK)==MENUITEM_SEPARATOR);
-            int_incr = 1;
-            if (gui_menu_redraw == 0) gui_menu_redraw=1;
-			}
+            gui_menu_updown(-1);
             break;
         case JOGDIAL_RIGHT:
         case KEY_DOWN: 
-			if (kbd_is_key_pressed(KEY_SHOOT_HALF) || kbd_is_key_pressed(KEY_ZOOM_IN) || kbd_is_key_pressed(KEY_ZOOM_OUT)) c=4; else c=1;
-            for (j=0;j<c;++j){
-            do {
-                if (curr_menu->menu[gui_menu_curr_item+1].text) {
-                    int i;
-                    for (i=0; i<num_lines-1 && curr_menu->menu[gui_menu_top_item+i].text; ++i);
-                    if (i==num_lines-1 && curr_menu->menu[gui_menu_top_item+i].text 
-                        && gui_menu_top_item+i-1==gui_menu_curr_item && curr_menu->menu[gui_menu_top_item+i+1].text)
-                        ++gui_menu_top_item;
-                    ++gui_menu_curr_item;
-                } else {
-                    gui_menu_curr_item = gui_menu_top_item = 0;
-                }
-            } while ((curr_menu->menu[gui_menu_curr_item].type & MENUITEM_MASK)==MENUITEM_TEXT || 
-                     (curr_menu->menu[gui_menu_curr_item].type & MENUITEM_MASK)==MENUITEM_SEPARATOR);
-            int_incr = 1;
-            if (gui_menu_redraw == 0) gui_menu_redraw=1;
-			}
+            gui_menu_updown(1);
             break;
         case FRONTDIAL_LEFT:
         case KEY_LEFT:
-            if (gui_menu_curr_item>=0) {
+            if (gui_menu_curr_item >= 0) {
                 switch (curr_menu->menu[gui_menu_curr_item].type & MENUITEM_MASK) {
                     case MENUITEM_INT:
-						{
-						if (kbd_is_key_pressed(KEY_ZOOM_OUT)) {
-						int_incr=10;
-						incr_modified=1;
-						}
-						if (kbd_is_key_pressed(KEY_ZOOM_IN)) {
-						int_incr=100;
-						incr_modified=1;
-						}
-						if (kbd_is_key_pressed(KEY_SHOOT_HALF)) {
-						int_incr=1000;
-						incr_modified=1;
-						}
-						}
-                        switch (curr_menu->menu[gui_menu_curr_item].type & MENUITEM_ARG_MASK) {
-                            case MENUITEM_ARG_INC:
-                                *(curr_menu->menu[gui_menu_curr_item].value) -= curr_menu->menu[gui_menu_curr_item].arg;
-                                break;
-                            case MENUITEM_ARG_ADDR_INC:
-                                *(curr_menu->menu[gui_menu_curr_item].value) -= *(int *)(curr_menu->menu[gui_menu_curr_item].arg);
-                                break;
-                            default:
-                                *(curr_menu->menu[gui_menu_curr_item].value) -= int_incr;
-                                break;
-                        }
-                        if (*(curr_menu->menu[gui_menu_curr_item].value) < -9999) 
-                            *(curr_menu->menu[gui_menu_curr_item].value) = -9999;
-                        if ( curr_menu->menu[gui_menu_curr_item].type & MENUITEM_F_UNSIGNED) {
-                            if (*(curr_menu->menu[gui_menu_curr_item].value) < 0) 
-                                *(curr_menu->menu[gui_menu_curr_item].value) = 0;
-                            if ( curr_menu->menu[gui_menu_curr_item].type & MENUITEM_F_MIN) {
-                                if (*(curr_menu->menu[gui_menu_curr_item].value) < (unsigned short)(curr_menu->menu[gui_menu_curr_item].arg & 0xFFFF)) 
-                                    *(curr_menu->menu[gui_menu_curr_item].value) = (unsigned short)(curr_menu->menu[gui_menu_curr_item].arg & 0xFFFF);
-                            }
-                        } else {
-                            if ( curr_menu->menu[gui_menu_curr_item].type & MENUITEM_F_MIN) {
-                                if (*(curr_menu->menu[gui_menu_curr_item].value) < (short)(curr_menu->menu[gui_menu_curr_item].arg & 0xFFFF)) 
-                                    *(curr_menu->menu[gui_menu_curr_item].value) = (short)(curr_menu->menu[gui_menu_curr_item].arg & 0xFFFF);
-                            }
-                        }
-                        if ((curr_menu->menu[gui_menu_curr_item].type & MENUITEM_ARG_MASK) == MENUITEM_ARG_CALLBACK && curr_menu->menu[gui_menu_curr_item].arg) {
-                            ((void (*)())(curr_menu->menu[gui_menu_curr_item].arg))();
-                        }
-                        if (curr_menu->on_change) {
-                            curr_menu->on_change(gui_menu_curr_item);
-                        }
-                        if (incr_modified) {
-						int_incr=1;
-						incr_modified=0;
-						draw_string(FONT_WIDTH*2,0,"    ", MAKE_COLOR(COLOR_TRANSPARENT, COLOR_TRANSPARENT));
-						}
-                        gui_menu_redraw=1;
+                        update_int_value(-1);
                         break;
                     case MENUITEM_BOOL:
-                        *(curr_menu->menu[gui_menu_curr_item].value) = !(*(curr_menu->menu[gui_menu_curr_item].value));
-                        if ((curr_menu->menu[gui_menu_curr_item].type & MENUITEM_ARG_MASK) == MENUITEM_ARG_CALLBACK && curr_menu->menu[gui_menu_curr_item].arg) {
-                            ((void (*)())(curr_menu->menu[gui_menu_curr_item].arg))();
-                        }
-                        if (curr_menu->on_change) {
-                            curr_menu->on_change(gui_menu_curr_item);
-                        }
-                        gui_menu_redraw=1;
+                        update_bool_value();
                         break;
                     case MENUITEM_ENUM:
-                        if (curr_menu->menu[gui_menu_curr_item].value) {
-							int c;
-							if (kbd_is_key_pressed(KEY_SHOOT_HALF)) c=3;
-							else if (kbd_is_key_pressed(KEY_ZOOM_IN)) c=6;
-							else if (kbd_is_key_pressed(KEY_ZOOM_OUT)) c=3;
-							else c=1;
-							((const char* (*)(int change, int arg))(curr_menu->menu[gui_menu_curr_item].value))(-c, curr_menu->menu[gui_menu_curr_item].arg);
-                        }
-                        gui_menu_redraw=1;
+                        update_enum_value(-1);
                         break;
                     case MENUITEM_UP:
@@ -287,101 +434,17 @@
         case FRONTDIAL_RIGHT:
         case KEY_RIGHT:
-            if (gui_menu_curr_item>=0) {
+            if (gui_menu_curr_item >= 0) {
                 switch (curr_menu->menu[gui_menu_curr_item].type & MENUITEM_MASK){
                     case MENUITEM_INT:
-						{
-						if (kbd_is_key_pressed(KEY_ZOOM_OUT)) {
-						int_incr=10;
-						incr_modified=1;
-						}
-						if (kbd_is_key_pressed(KEY_ZOOM_IN)) {
-						int_incr=100;
-						incr_modified=1;
-						}
-						if (kbd_is_key_pressed(KEY_SHOOT_HALF)) {
-						int_incr=1000;
-						incr_modified=1;
-						}
-						}
-                        switch (curr_menu->menu[gui_menu_curr_item].type & MENUITEM_ARG_MASK) {
-                            case MENUITEM_ARG_INC:
-                                *(curr_menu->menu[gui_menu_curr_item].value) += curr_menu->menu[gui_menu_curr_item].arg;
-                                break;
-                            case MENUITEM_ARG_ADDR_INC:
-                                *(curr_menu->menu[gui_menu_curr_item].value) += *(int *)(curr_menu->menu[gui_menu_curr_item].arg);
-                                break;
-                            default:
-                                *(curr_menu->menu[gui_menu_curr_item].value) += int_incr;
-                                break;
-                        }
-                        if (*(curr_menu->menu[gui_menu_curr_item].value) > 99999) 
-                            *(curr_menu->menu[gui_menu_curr_item].value) = 99999;
-                        if ( curr_menu->menu[gui_menu_curr_item].type & MENUITEM_F_UNSIGNED) {
-                            if ( curr_menu->menu[gui_menu_curr_item].type & MENUITEM_F_MAX) {
-                                if (*(curr_menu->menu[gui_menu_curr_item].value) > (unsigned short)((curr_menu->menu[gui_menu_curr_item].arg>>16) & 0xFFFF)) 
-                                    *(curr_menu->menu[gui_menu_curr_item].value) = (unsigned short)((curr_menu->menu[gui_menu_curr_item].arg>>16) & 0xFFFF);
-                            }
-                        } else {
-                            if ( curr_menu->menu[gui_menu_curr_item].type & MENUITEM_F_MAX) {
-                                if (*(curr_menu->menu[gui_menu_curr_item].value) > (short)((curr_menu->menu[gui_menu_curr_item].arg>>16) & 0xFFFF)) 
-                                    *(curr_menu->menu[gui_menu_curr_item].value) = (short)((curr_menu->menu[gui_menu_curr_item].arg>>16) & 0xFFFF);
-                            }
-                        }
-                        if ((curr_menu->menu[gui_menu_curr_item].type & MENUITEM_ARG_MASK) == MENUITEM_ARG_CALLBACK && curr_menu->menu[gui_menu_curr_item].arg) {
-                            ((void (*)())(curr_menu->menu[gui_menu_curr_item].arg))();
-                        }
-                        if (curr_menu->on_change) {
-                            curr_menu->on_change(gui_menu_curr_item);
-                        }
-                        if (incr_modified) {
-						int_incr=1;
-						incr_modified=0;
-						draw_string(FONT_WIDTH*2,0,"    ", MAKE_COLOR(COLOR_TRANSPARENT, COLOR_TRANSPARENT));
-						}
-                        gui_menu_redraw=1;
+                        update_int_value(1);
                         break;
                     case MENUITEM_BOOL:
-                        *(curr_menu->menu[gui_menu_curr_item].value) = !(*(curr_menu->menu[gui_menu_curr_item].value));
-                        if ((curr_menu->menu[gui_menu_curr_item].type & MENUITEM_ARG_MASK) == MENUITEM_ARG_CALLBACK && curr_menu->menu[gui_menu_curr_item].arg) {
-                            ((void (*)())(curr_menu->menu[gui_menu_curr_item].arg))();
-                        }
-                        if (curr_menu->on_change) {
-                            curr_menu->on_change(gui_menu_curr_item);
-                        }
-                        gui_menu_redraw=1;
+                        update_bool_value();
                         break;
                     case MENUITEM_ENUM:
-                        if (curr_menu->menu[gui_menu_curr_item].value) {
-							int c;
-							if (kbd_is_key_pressed(KEY_SHOOT_HALF)) c=3;
-							else if (kbd_is_key_pressed(KEY_ZOOM_IN)) c=6;
-							else if (kbd_is_key_pressed(KEY_ZOOM_OUT)) c=3;
-							else c=1;
-							((const char* (*)(int change, int arg))(curr_menu->menu[gui_menu_curr_item].value))(+c, curr_menu->menu[gui_menu_curr_item].arg);
-                        }
-                        gui_menu_redraw=1;
+                        update_enum_value(1);
                         break;
                     case MENUITEM_SUBMENU:
-                        gui_menu_stack[gui_menu_stack_ptr].menu = curr_menu;
-                        gui_menu_stack[gui_menu_stack_ptr].curpos = gui_menu_curr_item;
-                        gui_menu_stack[gui_menu_stack_ptr].toppos = gui_menu_top_item;
-                        if (conf.menu_select_first_entry) {
-                            gui_menu_set_curr_menu((CMenu*)(curr_menu->menu[gui_menu_curr_item].value), 0, 0);
-                            if ((curr_menu->menu[gui_menu_curr_item].type & MENUITEM_MASK)==MENUITEM_TEXT || (curr_menu->menu[gui_menu_curr_item].type & MENUITEM_MASK)==MENUITEM_SEPARATOR) {
-//                                ++gui_menu_top_item;
-                                ++gui_menu_curr_item;
-                            }
-                        }
-                        else 
-                            gui_menu_set_curr_menu((CMenu*)(curr_menu->menu[gui_menu_curr_item].value), 0, -1);
-                        gui_menu_stack_ptr++;
-                        // FIXME check on stack overrun;
-                        if (gui_menu_stack_ptr > MENUSTACK_MAXDEPTH){
-                            draw_txt_string(0, 0, "E1", MAKE_COLOR(COLOR_RED, COLOR_YELLOW));
-                            gui_menu_stack_ptr = 0;
-                        }
-                        gui_menu_redraw=2;
-                        draw_restore();
-                        gui_force_restore();
+                        select_sub_menu();
                         break;
                 }
@@ -389,28 +452,22 @@
             break;
         case KEY_SET:
-            if (gui_menu_curr_item>=0) {
+            if (gui_menu_curr_item >= 0) {
                 switch (curr_menu->menu[gui_menu_curr_item].type & MENUITEM_MASK){
                     case MENUITEM_INT:
-                        switch (curr_menu->menu[gui_menu_curr_item].type & MENUITEM_ARG_MASK) {
-							default:
-                                if (kbd_is_key_pressed(KEY_SHOOT_HALF)) *(curr_menu->menu[gui_menu_curr_item].value) = 0;
-								break;
-						}
-						gui_menu_redraw=1;
-						break;
+                        if (kbd_is_key_pressed(KEY_SHOOT_HALF))
+                        {
+                            *(curr_menu->menu[gui_menu_curr_item].value) = 0;
+                            gui_menu_redraw=1;
+                        }
+                        break;
                     case MENUITEM_BOOL:
-                        *(curr_menu->menu[gui_menu_curr_item].value) = !(*(curr_menu->menu[gui_menu_curr_item].value));
-                        if ((curr_menu->menu[gui_menu_curr_item].type & MENUITEM_ARG_MASK) == MENUITEM_ARG_CALLBACK && curr_menu->menu[gui_menu_curr_item].arg) {
-                            ((void (*)())(curr_menu->menu[gui_menu_curr_item].arg))();
-                        }
-                        if (curr_menu->on_change) {
-                            curr_menu->on_change(gui_menu_curr_item);
-                        }
-                        gui_menu_redraw=1;
+                        update_bool_value();
                         break;
                     case MENUITEM_PROC:
-                    	if (curr_menu->menu[gui_menu_curr_item].value) {
+                        if (curr_menu->menu[gui_menu_curr_item].value)
+                        {
                             ((void (*)(int arg))(curr_menu->menu[gui_menu_curr_item].value))(curr_menu->menu[gui_menu_curr_item].arg);
-                            if (curr_menu->on_change) {
+                            if (curr_menu->on_change)
+                            {
                                 curr_menu->on_change(gui_menu_curr_item);
                             }
@@ -420,25 +477,5 @@
                         break;
                     case MENUITEM_SUBMENU:
-                        gui_menu_stack[gui_menu_stack_ptr].menu = curr_menu;
-                        gui_menu_stack[gui_menu_stack_ptr].curpos = gui_menu_curr_item;
-                        gui_menu_stack[gui_menu_stack_ptr].toppos = gui_menu_top_item;
-                        if (conf.menu_select_first_entry) {
-                            gui_menu_set_curr_menu((CMenu*)(curr_menu->menu[gui_menu_curr_item].value), 0, 0);
-                            if ((curr_menu->menu[gui_menu_curr_item].type & MENUITEM_MASK)==MENUITEM_TEXT || (curr_menu->menu[gui_menu_curr_item].type & MENUITEM_MASK)==MENUITEM_SEPARATOR) {
-//                                ++gui_menu_top_item;
-                                ++gui_menu_curr_item;
-                            }
-                        }
-                        else 
-                            gui_menu_set_curr_menu((CMenu*)(curr_menu->menu[gui_menu_curr_item].value), 0, -1);
-                        gui_menu_stack_ptr++;
-                        // FIXME check on stack overrun;
-                        if (gui_menu_stack_ptr > MENUSTACK_MAXDEPTH){
-                            draw_txt_string(0, 0, "E1", MAKE_COLOR(COLOR_RED, COLOR_YELLOW));
-                            gui_menu_stack_ptr = 0;
-                        }
-                        gui_menu_redraw=2;
-                        draw_restore();
-                        gui_force_restore();
+                        select_sub_menu();
                         break;
                     case MENUITEM_UP:
@@ -454,7 +491,5 @@
                         break;
                     case MENUITEM_ENUM:
-                        if (curr_menu->menu[gui_menu_curr_item].value) {
-                            ((const char* (*)(int change, int arg))(curr_menu->menu[gui_menu_curr_item].value))(+1, curr_menu->menu[gui_menu_curr_item].arg);
-                        }
+                        update_enum_value(1);
                         gui_menu_redraw=1;
                         break;
@@ -465,82 +500,71 @@
 #if CAM_HAS_ZOOM_LEVER
         case KEY_ZOOM_IN:
-		/*
-		 * Move current entry up in menu
-		 * if in user menu edit mode and viewing user menu
-		 */
-		if( (conf.user_menu_enable == 3)  && (curr_menu->title == LANG_MENU_USER_MENU)) {
-			mod_user_menu(curr_menu->menu[gui_menu_curr_item],&gui_menu_curr_item, 2);
-			if(gui_menu_curr_item < gui_menu_top_item+1) {
-				if(gui_menu_curr_item)
-					gui_menu_top_item = gui_menu_curr_item-1;
-			}
-			
-			gui_menu_redraw=1;
-		}
-		else {
-		    if (int_incr >= 10){
-			int_incr /= 10;
-		    }
-		    sprintf(sbuf, "±%d",int_incr);
-		    draw_string(FONT_WIDTH*2,0,"    ", MAKE_COLOR(COLOR_TRANSPARENT, COLOR_TRANSPARENT));
-		    draw_string(0,0,sbuf,MAKE_COLOR(COLOR_SELECTED_BG, COLOR_SELECTED_FG));
-		}
-		break;
+            /*
+            * Move current entry up in menu
+            * if in user menu edit mode and viewing user menu
+            */
+            if( (conf.user_menu_enable == 3)  && (curr_menu->title == LANG_MENU_USER_MENU)) {
+                mod_user_menu(curr_menu->menu[gui_menu_curr_item],&gui_menu_curr_item, 2);
+                if(gui_menu_curr_item < gui_menu_top_item+1) {
+                    if(gui_menu_curr_item)
+                        gui_menu_top_item = gui_menu_curr_item-1;
+                }
+
+                gui_menu_redraw=1;
+            }
+            else {
+                if (int_incr >= 10){
+                    int_incr /= 10;
+                }
+                sprintf(sbuf, "±%d",int_incr);
+                draw_string(FONT_WIDTH*2,0,"    ", MAKE_COLOR(COLOR_TRANSPARENT, COLOR_TRANSPARENT));
+                draw_string(0,0,sbuf,MAKE_COLOR(COLOR_SELECTED_BG, COLOR_SELECTED_FG));
+            }
+            break;
 
         case KEY_ZOOM_OUT:
-		/*
-		 * Move current entry down in menu
-		 * if in user menu edit mode and viewing user menu
-		 */
-		if( (conf.user_menu_enable == 3)  && (curr_menu->title == LANG_MENU_USER_MENU)) {
-			mod_user_menu(curr_menu->menu[gui_menu_curr_item],&gui_menu_curr_item, 3);
-			gui_menu_redraw=1;
-			if(gui_menu_curr_item > gui_menu_top_item + num_lines -2) {
-				if((gui_menu_curr_item < USER_MENU_ITEMS) && curr_menu->menu[gui_menu_curr_item +1].text)
-					gui_menu_top_item++;
-			}
-		}
-		else {
-		    if (int_incr <= 1000){
-			int_incr *= 10;
-		    }
-		    sprintf(sbuf, "±%d",int_incr);
-		    draw_string(0,0,sbuf,MAKE_COLOR(COLOR_SELECTED_BG, COLOR_SELECTED_FG));
-		}
-		break;
+            /*
+            * Move current entry down in menu
+            * if in user menu edit mode and viewing user menu
+            */
+            if( (conf.user_menu_enable == 3)  && (curr_menu->title == LANG_MENU_USER_MENU)) {
+                mod_user_menu(curr_menu->menu[gui_menu_curr_item],&gui_menu_curr_item, 3);
+                if(gui_menu_curr_item > gui_menu_top_item + num_lines -2) {
+                    if((gui_menu_curr_item < USER_MENU_ITEMS) && curr_menu->menu[gui_menu_curr_item +1].text)
+                        gui_menu_top_item++;
+                }
+
+                gui_menu_redraw=1;
+            }
+            else {
+                if (int_incr <= 1000){
+                    int_incr *= 10;
+                }
+                sprintf(sbuf, "±%d",int_incr);
+                draw_string(0,0,sbuf,MAKE_COLOR(COLOR_SELECTED_BG, COLOR_SELECTED_FG));
+            }
+            break;
 
         case KEY_DISPLAY:
-            if (gui_menu_stack_ptr > 0){
-                gui_menu_stack_ptr--;
-                gui_menu_set_curr_menu(gui_menu_stack[gui_menu_stack_ptr].menu, gui_menu_stack[gui_menu_stack_ptr].toppos, gui_menu_stack[gui_menu_stack_ptr].curpos);
-                gui_menu_redraw=2;
-                draw_restore();
-                gui_force_restore();
-            }
+            gui_menu_back();
             break;
 #else
         case KEY_DISPLAY:
             if (conf.user_menu_enable == 3 && curr_menu->title == LANG_MENU_USER_MENU) {
-               if (gui_menu_stack_ptr > 0){
-                  gui_menu_stack_ptr--;
-                  gui_menu_set_curr_menu(gui_menu_stack[gui_menu_stack_ptr].menu, gui_menu_stack[gui_menu_stack_ptr].toppos, gui_menu_stack[gui_menu_stack_ptr].curpos);
-                  gui_menu_redraw=2;
-                  draw_restore();
-                  gui_force_restore();
-               }
+                gui_menu_back();
             }
             else {
-               if (int_incr <= 1000){
-                  int_incr *= 10;
-               }
-               else {
-                  int_incr = 1;
-               }
-               sprintf(sbuf, "±%d",int_incr);
-               if (int_incr == 1) {
-                  draw_string(FONT_WIDTH*2,0,"    ", MAKE_COLOR(COLOR_TRANSPARENT, COLOR_TRANSPARENT));
-               }
-               draw_string(0,0,sbuf,MAKE_COLOR(COLOR_SELECTED_BG, COLOR_SELECTED_FG));
-               break;
+                if (int_incr <= 1000){
+                    int_incr *= 10;
+                }
+                else {
+                    int_incr = 1;
+                }
+                sprintf(sbuf, "±%d",int_incr);
+                if (int_incr == 1) {
+                    draw_string(FONT_WIDTH*2,0,"    ", MAKE_COLOR(COLOR_TRANSPARENT, COLOR_TRANSPARENT));
+                }
+                draw_string(0,0,sbuf,MAKE_COLOR(COLOR_SELECTED_BG, COLOR_SELECTED_FG));
+                break;
             }
 #endif
@@ -549,36 +573,84 @@
 
 //-------------------------------------------------------------------
+// Draw menu scroll bar if needed, and title bar
 void gui_menu_draw_initial() { 
     color cl=conf.menu_title_color>>8; 
     unsigned char wplus=0; 
 
-    for (count=0; curr_menu->menu[count].text; ++count); 
-    if (count>num_lines) {
-      y = ((screen_height-(num_lines-1)*rbf_font_height())>>1);
-      wplus=8; 
-      // scrollbar background 
-      draw_filled_rect((x+w), y, (x+w)+wplus, y+num_lines*rbf_font_height()-1, MAKE_COLOR((conf.menu_color>>8)&0xFF, (conf.menu_color>>8)&0xFF)); 
-    } else {
-      if (conf.menu_center) {
-        y = (screen_height-(count-1)*rbf_font_height())>>1; 
-      } else {
-        y = ((screen_height-(num_lines-1)*rbf_font_height())>>1);  
-      }
-    }
+    count = gui_menu_rows();
+
+    if (count > num_lines)
+    {
+        y = ((screen_height-(num_lines-1)*rbf_font_height())>>1);
+        wplus=8; 
+        // scrollbar background 
+        draw_filled_rect((x+w), y, (x+w)+wplus, y+num_lines*rbf_font_height()-1, MAKE_COLOR((conf.menu_color>>8)&0xFF, (conf.menu_color>>8)&0xFF)); 
+    }
+    else
+    {
+        if (conf.menu_center)
+        {
+            y = (screen_height-(count-1)*rbf_font_height())>>1; 
+        }
+        else
+        {
+            y = ((screen_height-(num_lines-1)*rbf_font_height())>>1);  
+        }
+    }
+
+    rbf_draw_string_center_len(x, y-rbf_font_height(), w+wplus, (conf.menu_symbol_enable)?curr_menu->symbol:0, lang_str(curr_menu->title), conf.menu_title_color);
+}
+
+//-------------------------------------------------------------------
+
+// Local variables used by menu draw functions
+static int imenu, yy, xx, symbol_width;
+static color cl, cl_symbol;
+
+// Common code extracted from gui_menu_draw for displaying the symbol on the left
+static void gui_menu_draw_symbol(int num_symbols)
+{
     if (conf.menu_symbol_enable)
-      rbf_draw_string_center_len(x, y-rbf_font_height(), w+wplus, curr_menu->symbol, lang_str(curr_menu->title), conf.menu_title_color);
+    {
+        xx += rbf_draw_char(xx, yy, ' ', cl_symbol);
+        xx += symbol_width = rbf_draw_symbol(xx, yy, curr_menu->menu[imenu].symbol, cl_symbol);
+        symbol_width = (symbol_width * num_symbols) + len_space;
+    }
     else
-      rbf_draw_string_center_len(x, y-rbf_font_height(), w+wplus, 0x0, lang_str(curr_menu->title), conf.menu_title_color);    
-//    if (cl!=COLOR_FG) 
-//      draw_line(x,y-1,x+w-1+wplus,y-1,COLOR_FG); 
-}
+    {
+        symbol_width = 0;
+    }
+
+    xx += rbf_draw_char(xx, yy, ' ', cl);
+}
+
+// Common code extracted from gui_menu_draw for displaying an int, enum or bool value on the right
+static void gui_menu_draw_value(const char *str, int len_str)
+{
+    gui_menu_draw_symbol(1);
+    xx += rbf_draw_string_len(xx, yy, w-len_space-len_space-len_br1-len_str-len_br2-len_space-symbol_width, lang_str(curr_menu->menu[imenu].text), cl);
+    xx += rbf_draw_string(xx, yy, " [", cl);
+    xx += rbf_draw_string_right_len(xx, yy, len_str, str, cl);
+    rbf_draw_string(xx, yy, "] ", cl);
+}
+
+// Common code extracted from gui_menu_draw for displaying a text menu string
+static void gui_menu_draw_text(char *str, int num_symbols)
+{
+    gui_menu_draw_symbol(num_symbols);
+    xx += rbf_draw_string_len(xx, yy, w-len_space-len_space-symbol_width, str, cl);
+    if ((num_symbols == 2) && conf.menu_symbol_enable)
+        xx += rbf_draw_symbol(xx, yy, 0x52, cl_symbol);
+    rbf_draw_char(xx, yy, ' ', cl);
+}
+
 //-------------------------------------------------------------------
 void gui_menu_draw() {
     static char tbuf[64];
-    int imenu, i, j, yy, xx, symbol_width;
-    color cl, cl_symbol;
+    int i, j;
     const char *ch = "";
 
-    if (gui_menu_redraw) {
+    if (gui_menu_redraw)
+    {
         if (gui_menu_redraw==2)
             gui_menu_draw_initial();
@@ -586,174 +658,90 @@
         gui_menu_redraw=0;
 
-        for (imenu=gui_menu_top_item, i=0, yy=y; curr_menu->menu[imenu].text && i<num_lines; ++imenu, ++i, yy+=rbf_font_height()){
+        for (imenu=gui_menu_top_item, i=0, yy=y; curr_menu->menu[imenu].text && i<num_lines; ++imenu, ++i, yy+=rbf_font_height())
+        {
             cl = (gui_menu_curr_item==imenu)?conf.menu_cursor_color:conf.menu_color;
             /*
-             * When cursor is over a symbol, force symbol background color to be the menu cursor color but
-             * keep the symbol color user defined.
-             * old method was to set the symbol color to the symbol background color when the cursor highlighted it.
-             * This method allows the user to have any symbol color and background color they want with the restriction
-             * that the symbol background color will match the rest of the line when the cursor highlights it.
-             * It creates a nice consistent look expecially when the symbol color matches the menu text color.
-             * without this mod, there is no way to ever make the symbol color match the color of the rest of text menu line
-             * when the cursor highlights a line.
-             */
-            cl_symbol=(gui_menu_curr_item==imenu)?MAKE_COLOR((cl>>8)&0xFF,(conf.menu_symbol_color)&0xFF):conf.menu_symbol_color; //color 8Bit=Hintergrund 8Bit=Vordergrund
+            * When cursor is over a symbol, force symbol background color to be the menu cursor color but
+            * keep the symbol color user defined.
+            * old method was to set the symbol color to the symbol background color when the cursor highlighted it.
+            * This method allows the user to have any symbol color and background color they want with the restriction
+            * that the symbol background color will match the rest of the line when the cursor highlights it.
+            * It creates a nice consistent look expecially when the symbol color matches the menu text color.
+            * without this mod, there is no way to ever make the symbol color match the color of the rest of text menu line
+            * when the cursor highlights a line.
+            */
+            cl_symbol = (gui_menu_curr_item==imenu)?MAKE_COLOR((cl>>8)&0xFF,(conf.menu_symbol_color)&0xFF):conf.menu_symbol_color; //color 8Bit=Hintergrund 8Bit=Vordergrund
 
             xx = x;
 
-            switch (curr_menu->menu[imenu].type & MENUITEM_MASK) {
+            switch (curr_menu->menu[imenu].type & MENUITEM_MASK)
+            {
             case MENUITEM_BOOL:
-                if (conf.menu_symbol_enable) {
-                  xx+=rbf_draw_char(xx, yy, ' ', cl_symbol);
-                  xx+=symbol_width=rbf_draw_symbol(xx, yy, curr_menu->menu[imenu].symbol, cl_symbol);
-                  symbol_width+=len_space;
-                } else {
-                  symbol_width=0;
-                }
-                xx+=rbf_draw_char(xx, yy, ' ', cl);
-                xx+=rbf_draw_string_len(xx, yy, w-len_space-len_space-len_br1-len_bool-len_br2-len_space-symbol_width, lang_str(curr_menu->menu[imenu].text), cl);
-                xx+=rbf_draw_string(xx, yy, " [", cl);
-                xx+=rbf_draw_string_len(xx, yy, len_bool, (*(curr_menu->menu[imenu].value))?"\x95":"", cl);
-                rbf_draw_string(xx, yy, "] ", cl);
+                gui_menu_draw_value((*(curr_menu->menu[imenu].value))?"\x95":"", len_bool);
                 break;
             case MENUITEM_INT:
-                if (conf.menu_symbol_enable) {
-                  xx+=rbf_draw_char(xx, yy, ' ', cl_symbol);
-                  xx+=symbol_width=rbf_draw_symbol(xx, yy, curr_menu->menu[imenu].symbol, cl_symbol);
-                  symbol_width+=len_space;
-                } else {
-                  symbol_width=0;
-                }
-                xx+=rbf_draw_char(xx, yy, ' ', cl);
-                xx+=rbf_draw_string_len(xx, yy, w-len_space-len_space-len_br1-len_int-len_br2-len_space-symbol_width, lang_str(curr_menu->menu[imenu].text), cl);
-                xx+=rbf_draw_string(xx, yy, " [", cl);
                 sprintf(tbuf, "%d", *(curr_menu->menu[imenu].value));
-                xx+=rbf_draw_string_right_len(xx, yy, len_int, tbuf, cl);
-                rbf_draw_string(xx, yy, "] ", cl);
+                gui_menu_draw_value(tbuf, len_int);
                 break;
             case MENUITEM_SUBMENU:
-                if (conf.menu_symbol_enable) {
-                  xx+=rbf_draw_char(xx, yy, ' ', cl_symbol);
-                  xx+=symbol_width=rbf_draw_symbol(xx, yy, curr_menu->menu[imenu].symbol, cl_symbol);
-                  symbol_width+=len_space+symbol_width;
-                  sprintf(tbuf, "%s", lang_str(curr_menu->menu[imenu].text));
-                } else {
-                  sprintf(tbuf, "%s ->", lang_str(curr_menu->menu[imenu].text));
-                  symbol_width=0;
-                }
-                xx+=rbf_draw_char(xx, yy, ' ', cl);
-                xx+=rbf_draw_string_len(xx, yy, w-len_space-len_space-symbol_width, tbuf, cl);
-                if (conf.menu_symbol_enable) {
-                  xx+=rbf_draw_symbol(xx, yy, 0x52, cl_symbol);
-                  rbf_draw_char(xx, yy, ' ', cl_symbol);
-                } else rbf_draw_char(xx, yy, ' ', cl);
+                sprintf(tbuf, "%s%s", lang_str(curr_menu->menu[imenu].text),(conf.menu_symbol_enable)?"":" ->");
+                gui_menu_draw_text(tbuf,2);
                 break;
             case MENUITEM_UP:
-                if (conf.menu_symbol_enable) {
-                  xx+=rbf_draw_char(xx, yy, ' ', cl_symbol);
-                  xx+=symbol_width=rbf_draw_symbol(xx, yy, curr_menu->menu[imenu].symbol, cl_symbol);
-                  symbol_width+=len_space;
-                  sprintf(tbuf, "%s", lang_str(curr_menu->menu[imenu].text));
-                } else {
-                  symbol_width=0;
-                  sprintf(tbuf, "<- %s", lang_str(curr_menu->menu[imenu].text));
-                }
-                xx+=rbf_draw_char(xx, yy, ' ', cl);
-                xx+=rbf_draw_string_len(xx, yy, w-len_space-len_space-symbol_width, tbuf, cl);
-                rbf_draw_char(xx, yy, ' ', cl);
+                sprintf(tbuf, "%s%s", (conf.menu_symbol_enable)?"":"<- ", lang_str(curr_menu->menu[imenu].text));
+                gui_menu_draw_text(tbuf,1);
                 break;
             case MENUITEM_PROC:
             case MENUITEM_TEXT:
-                if (conf.menu_symbol_enable) {
-                  xx+=rbf_draw_char(xx, yy, ' ', cl_symbol);
-                  xx+=symbol_width=rbf_draw_symbol(xx, yy, curr_menu->menu[imenu].symbol, cl_symbol);
-                  symbol_width+=len_space;
-                } else {
-                  symbol_width=0;
-                }
-                xx+=rbf_draw_char(xx, yy, ' ', cl);
-                xx+=rbf_draw_string_len(xx, yy, w-len_space-len_space-symbol_width, lang_str(curr_menu->menu[imenu].text), cl);
-                rbf_draw_char(xx, yy, ' ', cl);
+                gui_menu_draw_text(lang_str(curr_menu->menu[imenu].text),1);
                 break;
             case MENUITEM_SEPARATOR:
-                if (lang_str(curr_menu->menu[imenu].text)[0]) {
-                    j = rbf_str_width(lang_str(curr_menu->menu[imenu].text));
-#if defined (CAMERA_g11) || defined (CAMERA_s90) || defined (CAMERA_sx130is)
-		xx+=((int)w-j-len_space*2)>>1;
-#else
-		xx+=(w-j-len_space*2)>>1;
-#endif
-                    (conf.menu_symbol_enable)?rbf_draw_char(x, yy, ' ', cl_symbol):rbf_draw_char(x, yy, ' ', cl);
-                    draw_filled_rect(x+len_space, yy, xx-1, yy+rbf_font_height()/2-1, MAKE_COLOR(cl>>8, cl>>8));
-                    draw_line(x+len_space, yy+rbf_font_height()/2, xx-1, yy+rbf_font_height()/2, cl);
-                    draw_filled_rect(x+len_space, yy+rbf_font_height()/2+1, xx-1, yy+rbf_font_height()-1, MAKE_COLOR(cl>>8, cl>>8));
-
-                    xx+=rbf_draw_char(xx, yy, ' ', cl);
-                    xx+=rbf_draw_string(xx, yy, lang_str(curr_menu->menu[imenu].text), cl);
-                    xx+=rbf_draw_char(xx, yy, ' ', cl);
-                    
-                    draw_filled_rect(xx, yy, x+w-len_space-1, yy+rbf_font_height()/2-1, MAKE_COLOR(cl>>8, cl>>8));
-                    draw_line(xx, yy+rbf_font_height()/2, x+w-1-len_space, yy+rbf_font_height()/2, cl);
-                    draw_filled_rect(xx, yy+rbf_font_height()/2+1, x+w-len_space-1, yy+rbf_font_height()-1, MAKE_COLOR(cl>>8, cl>>8));
-                    rbf_draw_char(x+w-len_space, yy, ' ', cl);
-                } else {
-                    rbf_draw_char(x, yy, ' ', cl);
-                    draw_filled_rect(x+len_space, yy, x+w-len_space-1, yy+rbf_font_height()/2-1, MAKE_COLOR(cl>>8, cl>>8));
-                    draw_line(x+len_space, yy+rbf_font_height()/2, x+w-1-len_space, yy+rbf_font_height()/2, cl);
-                    draw_filled_rect(x+len_space, yy+rbf_font_height()/2+1, x+w-len_space-1, yy+rbf_font_height()-1, MAKE_COLOR(cl>>8, cl>>8));
-                    rbf_draw_char(x+w-len_space, yy, ' ', cl);
-                }
+                rbf_draw_char(x, yy, ' ', cl);
+
+                if (lang_str(curr_menu->menu[imenu].text)[0])
+                    sprintf(tbuf," %s ",lang_str(curr_menu->menu[imenu].text));
+
+                j = rbf_str_width(lang_str(curr_menu->menu[imenu].text));
+                xx += ((int)w - j - len_space*2) >> 1;
+
+                draw_filled_rect(x+len_space, yy, xx-1, yy+rbf_font_height()/2-1, MAKE_COLOR(cl>>8, cl>>8));
+                draw_line(x+len_space, yy+rbf_font_height()/2, xx-1, yy+rbf_font_height()/2, cl);
+                draw_filled_rect(x+len_space, yy+rbf_font_height()/2+1, xx-1, yy+rbf_font_height()-1, MAKE_COLOR(cl>>8, cl>>8));
+
+                if (j) xx += rbf_draw_string(xx, yy, tbuf, cl);
+
+                draw_filled_rect(xx, yy, x+w-len_space-1, yy+rbf_font_height()/2-1, MAKE_COLOR(cl>>8, cl>>8));
+                draw_line(xx, yy+rbf_font_height()/2, x+w-1-len_space, yy+rbf_font_height()/2, cl);
+                draw_filled_rect(xx, yy+rbf_font_height()/2+1, x+w-len_space-1, yy+rbf_font_height()-1, MAKE_COLOR(cl>>8, cl>>8));
+
+                rbf_draw_char(x+w-len_space, yy, ' ', cl);
                 break;
             case MENUITEM_COLOR_FG:
             case MENUITEM_COLOR_BG:
-                if (conf.menu_symbol_enable) {
-                  xx+=rbf_draw_char(xx, yy, ' ', cl_symbol);
-                  xx+=symbol_width=rbf_draw_symbol(xx, yy, curr_menu->menu[imenu].symbol, cl_symbol);
-                  symbol_width+=len_space;
-                } else {
-                  symbol_width=0;
-                }
-                xx+=rbf_draw_char(xx, yy, ' ', cl);
+                gui_menu_draw_symbol(1);
                 xx+=rbf_draw_string_len(xx, yy, w-len_space-symbol_width, lang_str(curr_menu->menu[imenu].text), cl);
                 draw_filled_round_rect(x+w-1-cl_rect-2-len_space, yy+2, x+w-1-2-len_space, yy+rbf_font_height()-1-2, 
-                                 MAKE_COLOR(((*(curr_menu->menu[imenu].value))>>(((curr_menu->menu[imenu].type & MENUITEM_MASK)==MENUITEM_COLOR_BG)?8:0))&0xFF, 
-                                            ((*(curr_menu->menu[imenu].value))>>(((curr_menu->menu[imenu].type & MENUITEM_MASK)==MENUITEM_COLOR_BG)?8:0))&0xFF));
+                    MAKE_COLOR(((*(curr_menu->menu[imenu].value))>>(((curr_menu->menu[imenu].type & MENUITEM_MASK)==MENUITEM_COLOR_BG)?8:0))&0xFF, 
+                               ((*(curr_menu->menu[imenu].value))>>(((curr_menu->menu[imenu].type & MENUITEM_MASK)==MENUITEM_COLOR_BG)?8:0))&0xFF));
                 break;
             case MENUITEM_ENUM:
-                if (curr_menu->menu[imenu].value) {
-                    ch=((const char* (*)(int change, int arg))(curr_menu->menu[imenu].value))(0, curr_menu->menu[imenu].arg);
-                }
-                if (conf.menu_symbol_enable) {
-                  xx+=rbf_draw_char(xx, yy, ' ', cl_symbol);
-                  xx+=symbol_width=rbf_draw_symbol(xx, yy, curr_menu->menu[imenu].symbol, cl_symbol);
-                  symbol_width+=len_space;
-                } else {
-                  symbol_width=0;
-                }
-                xx+=rbf_draw_char(xx, yy, ' ', cl);
-                xx+=rbf_draw_string_len(xx, yy, w-len_space-len_space-len_br1-len_enum-len_br2-len_space-symbol_width, lang_str(curr_menu->menu[imenu].text), cl);
-                xx+=rbf_draw_string(xx, yy, " [", cl);
-                xx+=rbf_draw_string_right_len(xx, yy, len_enum, ch, cl);
-                rbf_draw_string(xx, yy, "] ", cl);
-                break;
-            }
-        }
-        
+                if (curr_menu->menu[imenu].value)
+                    ch = ((const char* (*)(int change, int arg))(curr_menu->menu[imenu].value))(0, curr_menu->menu[imenu].arg);
+                gui_menu_draw_value(ch, len_enum);
+                break;
+            }
+        }
+
         // scrollbar
-        if (count>num_lines) {
-            i=num_lines*rbf_font_height()-1 -1;           // full height
-            j=i*num_lines/count;                    // bar height
+        if (count > num_lines)
+        {
+            i = num_lines*rbf_font_height()-1 -1;           // full height
+            j = i*num_lines/count;                          // bar height
             if (j<20) j=20;
-            i=(i-j)*((gui_menu_curr_item<0)?0:gui_menu_curr_item)/(count-1);   // top pos
-            draw_filled_round_rect((x+w)+2, y+1, 
-                             (x+w)+6, y+1+i, MAKE_COLOR(COLOR_BLACK, COLOR_BLACK));
-            draw_filled_round_rect((x+w)+2, y+i+j, 
-                             (x+w)+6, y+num_lines*rbf_font_height()-1-1, MAKE_COLOR(COLOR_BLACK, COLOR_BLACK));
-            draw_filled_round_rect((x+w)+2, y+1+i, 
-                             (x+w)+6, y+i+j, MAKE_COLOR(COLOR_WHITE, COLOR_WHITE));
-//        } else {
-//            draw_filled_rect((x+w)*FONT_WIDTH+2, y*FONT_HEIGHT+1, 
-//                             (x+w)*FONT_WIDTH+6, (y+count)*FONT_HEIGHT-1-1, MAKE_COLOR(COLOR_BLACK, COLOR_BLACK));
-        }
-    }
-}
+            i = (i-j)*((gui_menu_curr_item<0)?0:gui_menu_curr_item)/(count-1);   // top pos
+            draw_filled_round_rect((x+w)+2, y+1,   (x+w)+6, y+1+i,                             MAKE_COLOR(COLOR_BLACK, COLOR_BLACK));
+            draw_filled_round_rect((x+w)+2, y+i+j, (x+w)+6, y+num_lines*rbf_font_height()-1-1, MAKE_COLOR(COLOR_BLACK, COLOR_BLACK));
+            draw_filled_round_rect((x+w)+2, y+1+i, (x+w)+6, y+i+j,                             MAKE_COLOR(COLOR_WHITE, COLOR_WHITE));
+        }
+    }
+}
