source: trunk/core/gui.c @ 1414

Revision 1414, 119.8 KB checked in by philmoz, 20 months ago (diff)

Add ALPHA version for SX40HS, firmware 1.00f and 1.00g (thx ERR99).

  • Property svn:eol-style set to native
Line 
1#include "stdlib.h"
2#include "platform.h"
3#include "core.h"
4#include "keyboard.h"
5#include "conf.h"
6#include "camera.h"
7#include "font.h"
8#include "lang.h"
9#include "gui.h"
10#include "gui_lang.h"
11#include "gui_draw.h"
12#include "gui_menu.h"
13#include "gui_palette.h"
14#include "gui_mbox.h"
15#include "gui_mpopup.h"
16#ifdef OPT_GAME_REVERSI
17#include "gui_reversi.h"
18#endif
19#ifdef OPT_GAME_SOKOBAN
20#include "gui_sokoban.h"
21#endif
22#ifdef OPT_GAME_CONNECT4
23#include "gui_4wins.h"
24#endif
25#ifdef OPT_GAME_MASTERMIND
26#include "gui_mastermind.h"
27#endif
28#include "console.h"
29#ifdef OPT_DEBUGGING
30#include "gui_debug.h"
31#endif
32#include "gui_fselect.h"
33#include "gui_batt.h"
34#include "gui_usb.h"
35#include "gui_space.h"
36#include "gui_osd.h"
37#ifdef OPT_TEXTREADER
38        #include "gui_read.h"
39#endif
40#ifdef OPT_CALENDAR
41        #include "gui_calendar.h"
42#endif
43#ifdef OPT_DEBUGGING
44#include "gui_bench.h"
45#endif
46#include "gui_grid.h"
47#include "histogram.h"
48#include "motion_detector.h"
49#include "raw.h"
50#ifdef OPT_CURVES
51        #include "curves.h"
52#endif
53#ifdef OPT_EDGEOVERLAY
54        #include "edgeoverlay.h"
55#endif
56#ifdef OPT_SCRIPTING
57    #include "script.h"
58    int script_params_has_changed=0;
59#endif
60//-------------------------------------------------------------------
61
62#define OPTIONS_AUTOSAVE
63#define SPLASH_TIME               20
64
65//shortcuts
66//------------------------------------------------------------------
67// #define KEY_NONE (KEY_DUMMY+1)
68
69#if defined(CAMERA_a580) // Cam has not erase button AND Half press shoot button + Left sets AFL, + Up sets AEL!
70    //Alt mode
71    #define SHORTCUT_TOGGLE_RAW          KEY_DISPLAY
72    #define SHORTCUT_MF_TOGGLE           KEY_UP
73    //Half press shoot button
74    #define SHORTCUT_TOGGLE_HISTO        KEY_DOWN
75    #define SHORTCUT_TOGGLE_ZEBRA        KEY_MENU
76    #define SHORTCUT_TOGGLE_OSD          KEY_RIGHT
77    #define SHORTCUT_DISABLE_OVERRIDES   KEY_DISPLAY
78    //Alt mode & Manual mode   
79    #define SHORTCUT_SET_INFINITY        KEY_DISPLAY
80    #define SHORTCUT_SET_HYPERFOCAL      KEY_DOWN
81    // For models without ZOOM_LEVER  (#if !CAM_HAS_ZOOM_LEVER)
82    // SHORTCUT_SET_INFINITY is not used
83    // KEY_DISPLAY is used for gui_subj_dist_override_koef_enum;
84    // KEY_LEFT/KEY_RIGHT is used for gui_subj_dist_override_value_enum (because of no separate ZOOM_IN/OUT)
85
86#elif !CAM_HAS_ERASE_BUTTON
87//Alt mode
88 #define SHORTCUT_TOGGLE_RAW          KEY_DISPLAY
89 #define SHORTCUT_MF_TOGGLE           KEY_UP
90//Half press shoot button
91 #define SHORTCUT_TOGGLE_HISTO        KEY_DOWN
92 #define SHORTCUT_TOGGLE_ZEBRA        KEY_MENU
93 #define SHORTCUT_TOGGLE_OSD          KEY_RIGHT
94 #define SHORTCUT_DISABLE_OVERRIDES   KEY_LEFT
95//Alt mode & Manual mode
96 #define SHORTCUT_SET_INFINITY        KEY_DISPLAY
97 #define SHORTCUT_SET_HYPERFOCAL      KEY_DOWN
98 // For models without ZOOM_LEVER  (#if !CAM_HAS_ZOOM_LEVER)
99 // SHORTCUT_SET_INFINITY is not used
100 // KEY_DISPLAY is used for gui_subj_dist_override_koef_enum;
101 // KEY_LEFT/KEY_RIGHT is used for gui_subj_dist_override_value_enum (because of no separate ZOOM_IN/OUT)
102
103#elif defined(CAMERA_g7) || defined(CAMERA_sx10) || defined(CAMERA_sx1) || defined(CAMERA_sx20) || defined(CAMERA_sx30) || defined(CAMERA_sx40hs)
104//Alt mode
105 #define SHORTCUT_TOGGLE_RAW          KEY_ERASE
106//Half press shoot button
107 #define SHORTCUT_TOGGLE_HISTO        KEY_DOWN
108 #define SHORTCUT_TOGGLE_ZEBRA        KEY_LEFT
109 #define SHORTCUT_TOGGLE_OSD          KEY_RIGHT
110 #define SHORTCUT_DISABLE_OVERRIDES   KEY_UP
111//Alt mode & Manual mode
112 #define SHORTCUT_SET_INFINITY        KEY_UP
113 #define SHORTCUT_SET_HYPERFOCAL      KEY_DOWN
114
115#elif defined(CAMERA_sx100is) ||defined(CAMERA_sx110is)
116//Alt mode
117 #define SHORTCUT_TOGGLE_RAW          KEY_ERASE
118//Half press shoot button
119 #define SHORTCUT_TOGGLE_HISTO        KEY_UP
120 #define SHORTCUT_TOGGLE_ZEBRA        KEY_DOWN
121 #define SHORTCUT_TOGGLE_OSD          KEY_RIGHT
122 #define SHORTCUT_DISABLE_OVERRIDES   KEY_LEFT
123//Alt mode & Manual mode
124 #define SHORTCUT_SET_INFINITY        KEY_UP
125 #define SHORTCUT_SET_HYPERFOCAL      KEY_DOWN
126
127 #else
128
129//Alt mode
130 #define SHORTCUT_TOGGLE_RAW          KEY_ERASE
131//Half press shoot button
132 #define SHORTCUT_TOGGLE_HISTO        KEY_UP
133 #define SHORTCUT_TOGGLE_ZEBRA        KEY_LEFT
134 #define SHORTCUT_TOGGLE_OSD          KEY_RIGHT
135 #define SHORTCUT_DISABLE_OVERRIDES   KEY_DOWN
136//Alt mode & Manual mode
137 #define SHORTCUT_SET_INFINITY        KEY_UP
138 #define SHORTCUT_SET_HYPERFOCAL      KEY_DOWN
139 #ifndef CAM_HAS_MANUAL_FOCUS
140 #define SHORTCUT_MF_TOGGLE           KEY_DISPLAY
141 #endif
142#endif
143
144
145// forward declarations
146//-------------------------------------------------------------------
147extern void dump_memory();
148// both from platform/generic/shooting.c
149extern const char* tv_override[];
150extern const int tv_override_amount;
151extern const int tv_override_zero_shift;
152
153static void gui_draw_osd();
154
155static void gui_draw_splash(char* logo, int logo_size);
156
157void user_menu_save();
158void user_menu_restore();
159// Menu procs
160//-------------------------------------------------------------------
161static void gui_show_build_info(int arg);
162static void gui_show_memory_info(int arg);
163static void gui_draw_palette(int arg);
164static void gui_draw_reversi(int arg);
165static void gui_draw_sokoban(int arg);
166static void gui_draw_4wins(int arg);
167static void gui_draw_mastermind(int arg);
168#ifdef OPT_DEBUGGING
169        static void gui_draw_debug(int arg);
170        static void gui_draw_bench(int arg);
171#endif
172static void gui_draw_fselect(int arg);
173static void gui_draw_osd_le(int arg);
174#ifdef OPT_TEXTREADER
175static void gui_draw_read(int arg);
176static void gui_draw_read_last(int arg);
177#endif
178static void gui_draw_load_menu_rbf(int arg);
179static void gui_draw_load_symbol_rbf(int arg);          //AKA
180#ifdef OPT_TEXTREADER
181        static void gui_draw_load_rbf(int arg);
182#endif
183#ifdef OPT_CALENDAR
184static void gui_draw_calendar(int arg);
185#endif
186static void gui_draw_load_lang(int arg);
187static void gui_menuproc_mkbootdisk(int arg);
188#ifdef OPT_DEBUGGING
189void gui_compare_props(int arg);
190#endif
191#ifndef OPTIONS_AUTOSAVE
192static void gui_menuproc_save(int arg);
193#endif
194static void gui_menuproc_reset(int arg);
195static void gui_grid_lines_load(int arg);
196static void gui_raw_develop(int arg);
197#ifdef OPT_DEBUGGING
198static void gui_menuproc_break_card(int arg);
199#endif
200static void gui_menuproc_swap_partitions(int arg);
201static void gui_menuproc_reset_files(int arg);
202#ifdef OPT_CURVES
203        static void gui_load_curve_selected(const char *fn);
204        static void gui_load_curve(int arg);
205#endif
206static const char* gui_histo_mode_enum(int change, int arg);
207static const char* gui_histo_layout_enum(int change, int arg);
208static const char* gui_font_enum(int change, int arg);
209
210#if CAM_ADJUSTABLE_ALT_BUTTON
211static const char* gui_alt_mode_button_enum(int change, int arg);
212#endif
213static const char* gui_alt_power_enum(int change, int arg);
214static const char* gui_video_bitrate_enum(int change, int arg);
215static const char* gui_av_override_enum(int change, int arg);
216#if ZOOM_OVERRIDE
217static const char* gui_zoom_override_enum(int change, int arg);
218#endif
219static const char* gui_tv_override_koef_enum(int change, int arg);
220static const char* gui_tv_override_value_enum(int change, int arg);
221static const char* gui_tv_enum_type_enum(int change, int arg);
222static const char* gui_subj_dist_override_value_enum(int change, int arg);
223static const char* gui_subj_dist_override_koef_enum(int change, int arg);
224/*
225static const char* gui_tv_exposure_order_enum(int change, int arg);
226static const char* gui_av_exposure_order_enum(int change, int arg);
227static const char* gui_iso_exposure_order_enum(int change, int arg);
228*/
229const char* gui_user_menu_show_enum(int change, int arg);
230static const char* gui_bad_pixel_enum(int change, int arg);
231static const char* gui_video_af_key_enum(int change, int arg);
232#ifdef OPT_CURVES
233        static const char* gui_conf_curve_enum(int change, int arg);
234#endif
235#ifdef OPT_DEBUGGING
236        static void gui_debug_shortcut(void);
237#endif
238
239#ifdef OPT_EDGEOVERLAY
240static void gui_menuproc_edge_save(int arg);
241static void gui_menuproc_edge_load(int arg);
242#endif
243
244#ifdef OPT_SCRIPTING
245static void gui_load_script(int arg);
246static void gui_load_script_default(int arg);
247static const char* gui_script_param_set_enum(int change, int arg);
248#endif
249
250void rinit();
251
252// Menu callbacks
253//-------------------------------------------------------------------
254static void cb_step_25();
255static void cb_perc();
256static void cb_volts();
257static void cb_space_perc();
258static void cb_space_mb();
259static void cb_battery_menu_change(unsigned int item);
260static void cb_zebra_restore_screen();
261static void cb_zebra_restore_osd();
262#if DNG_SUPPORT
263static void cb_change_dng();
264void gui_menuproc_badpixel_create(int arg);
265#endif
266#if defined (DNG_EXT_FROM)
267static void cb_change_dng_usb_ext();
268#endif
269
270// for memory info, duplicated from lowlevel
271extern const char _start,_end;
272
273#ifdef OPT_DEBUGGING
274static int debug_tasklist_start;
275static int debug_display_direction=1;
276#endif
277// Menu definition
278//-------------------------------------------------------------------
279static CMenuItem remote_submenu_items[] = {
280    MENU_ITEM(0x71,LANG_MENU_REMOTE_ENABLE,            MENUITEM_BOOL,                    &conf.remote_enable, 0),
281    MENU_ITEM(0x0,LANG_MENU_SYNCHABLE_REMOTE,          MENUITEM_SEPARATOR, 0, 0 ),
282    MENU_ITEM(0x71,LANG_MENU_SYNCHABLE_REMOTE_ENABLE,  MENUITEM_BOOL,                    &conf.ricoh_ca1_mode, 0),
283    MENU_ITEM(0x5c,LANG_MENU_SYNCH_ENABLE,             MENUITEM_BOOL,                    &conf.synch_enable, 0),
284    MENU_ITEM(0x5c,LANG_MENU_SYNCH_DELAY_ENABLE,       MENUITEM_BOOL,                    &conf.synch_delay_enable, 0),
285    MENU_ITEM(0x5c,LANG_MENU_SYNCH_DELAY_VALUE,        MENUITEM_INT|MENUITEM_F_UNSIGNED, &conf.synch_delay_value, 0),
286    MENU_ITEM(0x5c,LANG_MENU_SYNCH_DELAY_COARSE_VALUE, MENUITEM_INT|MENUITEM_F_UNSIGNED, &conf.synch_delay_coarse_value, 0),
287    MENU_ITEM(0x5c,LANG_MENU_REMOTE_ZOOM_ENABLE,       MENUITEM_BOOL,                    &conf.remote_zoom_enable, 0),
288    MENU_ITEM(0x5f,LANG_MENU_REMOTE_ZOOM_TIMEOUT,      MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.zoom_timeout, MENU_MINMAX(2,10)),
289    MENU_ITEM(0x51,LANG_MENU_BACK,                     MENUITEM_UP, 0, 0),
290    {0}
291};
292static CMenu remote_submenu = {0x86,LANG_MENU_REMOTE_PARAM_TITLE, NULL, remote_submenu_items };
293
294
295#ifdef OPT_SCRIPTING
296static const char* gui_script_autostart_modes[]={ "Off", "On", "Once"};
297static CMenuItem script_submenu_items_top[] = {
298    MENU_ITEM(0x35,LANG_MENU_SCRIPT_LOAD,             MENUITEM_PROC,                      gui_load_script, 0 ),
299    MENU_ITEM(0x5f,LANG_MENU_SCRIPT_DELAY,            MENUITEM_INT|MENUITEM_F_UNSIGNED,   &conf.script_shoot_delay, 0 ),
300        // remote autostart
301        MENU_ENUM2(0x5f,LANG_MENU_SCRIPT_AUTOSTART,               &conf.script_startup, gui_script_autostart_modes ),
302
303#if CAM_REMOTE
304    MENU_ITEM(0x86,LANG_MENU_REMOTE_PARAM,            MENUITEM_SUBMENU,   &remote_submenu, 0 ),
305        //MENU_ITEM(0x71,LANG_MENU_SCRIPT_REMOTE_ENABLE,        MENUITEM_BOOL,                                          &conf.remote_enable, 0),
306#endif
307    MENU_ITEM(0x5d,LANG_MENU_SCRIPT_DEFAULT_VAL,     MENUITEM_PROC,                      gui_load_script_default, 0 ),
308    MENU_ITEM(0x5e,LANG_MENU_SCRIPT_PARAM_SET,     MENUITEM_ENUM,                         gui_script_param_set_enum, 0 ),
309    MENU_ITEM(0x5c,LANG_MENU_SCRIPT_PARAM_SAVE,             MENUITEM_BOOL,                    &conf.script_param_save, 0 ),
310    MENU_ITEM(0x0,(int)script_title,                 MENUITEM_SEPARATOR, 0, 0 ),
311//    MENU_ITEM(0x0,LANG_MENU_SCRIPT_CURRENT,          MENUITEM_SEPARATOR, 0, 0 ),
312//    MENU_ITEM(0x0,(int)script_title,                 MENUITEM_TEXT, 0, 0 ),
313//    MENU_ITEM(0x0,LANG_MENU_SCRIPT_PARAMS,           MENUITEM_SEPARATOR, 0, 0)
314};
315
316static CMenuItem script_submenu_items_bottom[] = {
317    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
318    {0}
319};
320
321static CMenuItem script_submenu_items[sizeof(script_submenu_items_top)/sizeof(script_submenu_items_top[0])+SCRIPT_NUM_PARAMS+
322                               sizeof(script_submenu_items_bottom)/sizeof(script_submenu_items_bottom[0])];
323static CMenu script_submenu = {0x27,LANG_MENU_SCRIPT_TITLE, NULL, script_submenu_items };
324#endif
325
326static CMenuItem games_submenu_items[] = {
327#ifdef OPT_GAME_REVERSI
328    MENU_ITEM(0x38,LANG_MENU_GAMES_REVERSI,           MENUITEM_PROC,  gui_draw_reversi, 0 ),
329#endif
330#ifdef OPT_GAME_SOKOBAN
331    MENU_ITEM(0x38,LANG_MENU_GAMES_SOKOBAN,           MENUITEM_PROC,  gui_draw_sokoban, 0 ),
332#endif
333#ifdef OPT_GAME_CONNECT4
334    MENU_ITEM(0x38,LANG_MENU_GAMES_CONNECT4,             MENUITEM_PROC,  gui_draw_4wins, 0 ),
335#endif
336#ifdef OPT_GAME_MASTERMIND
337    MENU_ITEM(0x38,LANG_MENU_GAMES_MASTERMIND,           MENUITEM_PROC,  gui_draw_mastermind, 0 ),
338#endif
339    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
340    {0}
341};
342static CMenu games_submenu = {0x38,LANG_MENU_GAMES_TITLE, NULL, games_submenu_items };
343
344static const char* gui_autoiso_shutter_modes[] = { "Auto", "1/8s", "1/15s", "1/30s", "1/60s", "1/125s", "1/250s", "1/500s", "1/1000s"};
345static CMenuItem autoiso_submenu_items[] = {
346    MENU_ITEM(0x5c,LANG_MENU_AUTOISO_ENABLED,          MENUITEM_BOOL,   &conf.autoiso_enable, 0),
347    MENU_ENUM2(0x5f,LANG_MENU_AUTOISO_MIN_SHUTTER,  &conf.autoiso_shutter, gui_autoiso_shutter_modes ),
348    MENU_ITEM(0x5f,LANG_MENU_AUTOISO_USER_FACTOR,   MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.autoiso_user_factor, MENU_MINMAX(1, 8) ),
349#if CAM_HAS_IS
350    MENU_ITEM(0x5f,LANG_MENU_AUTOISO_IS_FACTOR,       MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.autoiso_is_factor, MENU_MINMAX(1, 8) ),
351#endif
352    MENU_ITEM(0x5f,LANG_MENU_AUTOISO_MAX_ISO_HI,      MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.autoiso_max_iso_hi, MENU_MINMAX(20, 160) ),
353    MENU_ITEM(0x5f,LANG_MENU_AUTOISO_MAX_ISO_AUTO, MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.autoiso_max_iso_auto, MENU_MINMAX(10, 80) ),
354    MENU_ITEM(0x5f,LANG_MENU_AUTOISO_MIN_ISO,           MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.autoiso_min_iso, MENU_MINMAX(1, 20) ),
355    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
356    {0}
357};
358static CMenu autoiso_submenu = {0x2d,LANG_MENU_AUTOISO_TITLE, NULL, autoiso_submenu_items };
359
360
361#ifdef OPT_TEXTREADER
362static const char* gui_reader_codepage_cps[] = { "Win1251", "DOS"};
363static CMenuItem reader_submenu_items[] = {
364    MENU_ITEM(0x35,LANG_MENU_READ_OPEN_NEW,           MENUITEM_PROC,    gui_draw_read, 0 ),
365    MENU_ITEM(0x35,LANG_MENU_READ_OPEN_LAST,          MENUITEM_PROC,    gui_draw_read_last, 0 ),
366    MENU_ITEM(0x35,LANG_MENU_READ_SELECT_FONT,        MENUITEM_PROC,    gui_draw_load_rbf, 0 ),
367    MENU_ENUM2(0x5f,LANG_MENU_READ_CODEPAGE,          &conf.reader_codepage, gui_reader_codepage_cps ),
368    MENU_ITEM(0x5c,LANG_MENU_READ_WORD_WRAP,          MENUITEM_BOOL,    &conf.reader_wrap_by_words, 0 ),
369    MENU_ITEM(0x5c,LANG_MENU_READ_AUTOSCROLL,         MENUITEM_BOOL,    &conf.reader_autoscroll, 0 ),
370    MENU_ITEM(0x5f,LANG_MENU_READ_AUTOSCROLL_DELAY,   MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.reader_autoscroll_delay, MENU_MINMAX(0, 60) ),
371    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
372    {0}
373};
374static CMenu reader_submenu = {0x37,LANG_MENU_READ_TITLE, NULL, reader_submenu_items };
375#endif
376
377#ifdef OPT_DEBUGGING
378static const char* gui_debug_shortcut_modes[] = { "None", "DmpRAM", "Page", "CmpProps"};
379static const char* gui_debug_display_modes[] = { "None", "Props", "Params", "Tasks"};
380static CMenuItem debug_submenu_items[] = {
381    MENU_ENUM2(0x5c,LANG_MENU_DEBUG_DISPLAY,          &conf.debug_display, gui_debug_display_modes ),
382    MENU_ITEM(0x2a,LANG_MENU_DEBUG_PROPCASE_PAGE,     MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,   &conf.debug_propcase_page, MENU_MINMAX(0, 128) ),
383    MENU_ITEM(0x2a,LANG_MENU_DEBUG_TASKLIST_START,    MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,   &debug_tasklist_start, MENU_MINMAX(0, 63) ),
384    MENU_ITEM(0x5c,LANG_MENU_DEBUG_SHOW_MISC_VALS,    MENUITEM_BOOL,          &conf.debug_misc_vals_show, 0 ),
385    MENU_ITEM(0x2a,LANG_MENU_DEBUG_MEMORY_BROWSER,    MENUITEM_PROC,          gui_draw_debug, 0 ),
386    MENU_ITEM(0x2a,LANG_MENU_DEBUG_BENCHMARK,         MENUITEM_PROC,          gui_draw_bench, 0 ),
387    MENU_ENUM2(0x5c,LANG_MENU_DEBUG_SHORTCUT_ACTION,  &conf.debug_shortcut_action, gui_debug_shortcut_modes ),
388    MENU_ITEM(0x5c,LANG_MENU_RAW_TIMER,               MENUITEM_BOOL,          &conf.raw_timer, 0 ),
389#ifdef OPT_LUA
390    MENU_ITEM(0x5c,LANG_MENU_LUA_RESTART,             MENUITEM_BOOL,          &conf.debug_lua_restart_on_error, 0 ),
391#endif
392#if CAM_MULTIPART
393    MENU_ITEM(0x33,LANG_MENU_DEBUG_CREATE_MULTIPART , MENUITEM_PROC,            gui_menuproc_break_card, 0 ),
394#endif
395    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
396    {0}
397};
398static CMenu debug_submenu = {0x2a,LANG_MENU_DEBUG_TITLE, NULL, debug_submenu_items };
399#endif
400
401
402static CMenuItem misc_submenu_items[] = {
403    MENU_ITEM(0x35,LANG_MENU_MISC_FILE_BROWSER,       MENUITEM_PROC,    gui_draw_fselect, 0 ),
404#ifdef OPT_CALENDAR
405    MENU_ITEM(0x36,LANG_MENU_MISC_CALENDAR,           MENUITEM_PROC,    gui_draw_calendar, 0 ),
406#endif
407#ifdef OPT_TEXTREADER
408    MENU_ITEM(0x37,LANG_MENU_MISC_TEXT_READER,        MENUITEM_SUBMENU, &reader_submenu, 0 ),
409#endif
410#if defined (OPT_GAME_REVERSI) || (OPT_GAME_SOKOBAN || (OPT_GAME_CONNECT4) || OPT_GAME_MASTERMIND)
411    MENU_ITEM(0x38,LANG_MENU_MISC_GAMES,              MENUITEM_SUBMENU, &games_submenu, 0 ),
412#endif
413#if CAM_SWIVEL_SCREEN
414    MENU_ITEM(0x28,LANG_MENU_MISC_FLASHLIGHT,         MENUITEM_BOOL,    &conf.flashlight, 0 ),
415#endif
416    MENU_ITEM(0x5c,LANG_MENU_MISC_SHOW_SPLASH,        MENUITEM_BOOL,    &conf.splash_show, 0 ),
417    MENU_ITEM(0x5c,LANG_MENU_MISC_START_SOUND,        MENUITEM_BOOL,    &conf.start_sound, 0 ),
418#if CAM_USE_ZOOM_FOR_MF
419    MENU_ITEM(0x59,LANG_MENU_MISC_ZOOM_FOR_MF,        MENUITEM_BOOL,    &conf.use_zoom_mf, 0 ),
420#endif
421#if CAM_ADJUSTABLE_ALT_BUTTON
422    MENU_ITEM(0x22,LANG_MENU_MISC_ALT_BUTTON,         MENUITEM_ENUM,    gui_alt_mode_button_enum, 0 ),
423#endif
424    MENU_ITEM(0x5d,LANG_MENU_MISC_DISABLE_LCD_OFF,    MENUITEM_ENUM,    gui_alt_power_enum, 0 ),
425    MENU_ITEM(0x65,LANG_MENU_MISC_PALETTE,            MENUITEM_PROC,    gui_draw_palette, 0 ),
426    MENU_ITEM(0x80,LANG_MENU_MISC_BUILD_INFO,         MENUITEM_PROC,    gui_show_build_info, 0 ),
427    MENU_ITEM(0x80,LANG_MENU_MISC_MEMORY_INFO,        MENUITEM_PROC,    gui_show_memory_info, 0 ),
428    MENU_ITEM(0x33,LANG_MENU_DEBUG_MAKE_BOOTABLE,     MENUITEM_PROC,    gui_menuproc_mkbootdisk, 0 ),
429#if CAM_MULTIPART
430    MENU_ITEM(0x33,LANG_MENU_DEBUG_SWAP_PART,         MENUITEM_PROC,            gui_menuproc_swap_partitions, 0 ),
431#endif
432    MENU_ITEM(0x2b,LANG_MENU_MAIN_RESET_OPTIONS,      MENUITEM_PROC,      gui_menuproc_reset, 0 ),
433#ifdef OPT_DEBUGGING
434    MENU_ITEM(0x2a,LANG_MENU_MAIN_DEBUG,              MENUITEM_SUBMENU,   &debug_submenu, 0 ),
435#endif
436    MENU_ITEM(0x86,LANG_MENU_REMOTE_PARAM,            MENUITEM_SUBMENU,   &remote_submenu, 0 ),
437#if defined (DNG_EXT_FROM)
438    MENU_ITEM(0x71,LANG_MENU_DNG_VIA_USB,             MENUITEM_BOOL | MENUITEM_ARG_CALLBACK, &conf.dng_usb_ext , (int)cb_change_dng_usb_ext ),
439#endif
440    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
441    {0},
442};
443static CMenu misc_submenu = {0x29,LANG_MENU_MISC_TITLE, NULL, misc_submenu_items };
444
445static int voltage_step;
446static CMenuItem battery_submenu_items[] = {
447    MENU_ITEM(0x66,LANG_MENU_BATT_VOLT_MAX,           MENUITEM_INT|MENUITEM_ARG_ADDR_INC,     &conf.batt_volts_max,   (int)&voltage_step ),
448    MENU_ITEM(0x67,LANG_MENU_BATT_VOLT_MIN,           MENUITEM_INT|MENUITEM_ARG_ADDR_INC,     &conf.batt_volts_min,   (int)&voltage_step ),
449    MENU_ITEM(0x68,LANG_MENU_BATT_STEP_25,            MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,    &conf.batt_step_25,     (int)cb_step_25 ),
450    MENU_ITEM(0x0,(int)"",                            MENUITEM_SEPARATOR, 0, 0 ),
451    MENU_ITEM(0x73,LANG_MENU_BATT_SHOW_PERCENT,       MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,    &conf.batt_perc_show,   (int)cb_perc ),
452    MENU_ITEM(0x73,LANG_MENU_BATT_SHOW_VOLTS,         MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,    &conf.batt_volts_show,  (int)cb_volts ),
453    MENU_ITEM(0x32,LANG_MENU_BATT_SHOW_ICON,          MENUITEM_BOOL,                          &conf.batt_icon_show, 0 ),
454    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
455    {0}
456};
457static CMenu battery_submenu = {0x32,LANG_MENU_BATT_TITLE, cb_battery_menu_change, battery_submenu_items };
458
459static const char* gui_space_bar_modes[] = { "Don't", "Horizontal", "Vertical"};
460static const char* gui_space_bar_size_modes[] = { "1/4", "1/2", "1"};
461static const char* gui_space_bar_width_modes[] = { "1", "2", "3","4","5","6","7","8","9","10"};
462static const char* gui_space_warn_type_modes[] = { "Percent", "MB", "Don't"};
463static CMenuItem space_submenu_items[] = {
464    MENU_ITEM(0x5c,LANG_MENU_SPACE_SHOW_ICON,         MENUITEM_BOOL,                          &conf.space_icon_show, 0 ),
465    MENU_ENUM2(0x69,LANG_MENU_SPACE_SHOW_BAR,     &conf.space_bar_show, gui_space_bar_modes ),
466    MENU_ENUM2(0x6a,LANG_MENU_SPACE_BAR_SIZE,     &conf.space_bar_size, gui_space_bar_size_modes ),
467    MENU_ENUM2(0x6b,LANG_MENU_SPACE_BAR_WIDTH,    &conf.space_bar_width, gui_space_bar_width_modes ),
468    MENU_ITEM(0x5c,LANG_MENU_SPACE_SHOW_PERCENT,      MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,    &conf.space_perc_show,   (int)cb_space_perc ),
469    MENU_ITEM(0x5c,LANG_MENU_SPACE_SHOW_MB,           MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,    &conf.space_mb_show,  (int)cb_space_mb ),
470    MENU_ENUM2(0x5f,LANG_MENU_SPACE_WARN_TYPE,    &conf.space_warn_type, gui_space_warn_type_modes ),
471    MENU_ITEM(0x58,LANG_MENU_SPACE_WARN_PERCENT,     MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,   &conf.space_perc_warn, MENU_MINMAX(1, 99) ),
472    MENU_ITEM(0x58,LANG_MENU_SPACE_WARN_MB,     MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,   &conf.space_mb_warn, MENU_MINMAX(1, 4000) ),
473    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
474    {0}
475};
476static CMenu space_submenu = {0x33,LANG_MENU_OSD_SPACE_PARAMS_TITLE, NULL, space_submenu_items};
477
478static const char* gui_dof_show_value_modes[] = { "Don't", "Separate", "In Misc" };
479static CMenuItem dof_submenu_items[] = {
480          MENU_ENUM2(0x5f,LANG_MENU_OSD_SHOW_DOF_CALC,           &conf.show_dof, gui_dof_show_value_modes ),
481          MENU_ITEM(0x5c,LANG_MENU_DOF_SUBJ_DIST_AS_NEAR_LIMIT,  MENUITEM_BOOL,      &conf.dof_subj_dist_as_near_limit, 0),
482          MENU_ITEM(0x5c,LANG_MENU_DOF_USE_EXIF_SUBJ_DIST,       MENUITEM_BOOL,      &conf.dof_use_exif_subj_dist, 0),
483          MENU_ITEM(0x5c,LANG_MENU_DOF_SUBJ_DIST_IN_MISC,        MENUITEM_BOOL,      &conf.dof_subj_dist_in_misc, 0),
484          MENU_ITEM(0x5c,LANG_MENU_DOF_NEAR_LIMIT_IN_MISC,       MENUITEM_BOOL,      &conf.dof_near_limit_in_misc, 0),
485      MENU_ITEM(0x5c,LANG_MENU_DOF_FAR_LIMIT_IN_MISC,        MENUITEM_BOOL,                      &conf.dof_far_limit_in_misc, 0),
486      MENU_ITEM(0x5c,LANG_MENU_DOF_HYPERFOCAL_IN_MISC,       MENUITEM_BOOL,      &conf.dof_hyperfocal_in_misc, 0),
487      MENU_ITEM(0x5c,LANG_MENU_DOF_DEPTH_LIMIT_IN_MISC,      MENUITEM_BOOL,      &conf.dof_depth_in_misc, 0),
488#if !CAM_DRYOS
489      MENU_ITEM(0x5c,LANG_MENU_DOF_DIST_FROM_LENS,           MENUITEM_BOOL,      &conf.dof_dist_from_lens, 0),
490#endif
491          MENU_ITEM(0x51,LANG_MENU_BACK,                           MENUITEM_UP, 0, 0 ),
492    {0}
493};
494static CMenu dof_submenu = {0x31,LANG_MENU_DOF_TITLE, /*cb_dof_menu_change*/ NULL, dof_submenu_items };
495
496static const char* gui_zoom_value_modes[] = { "X", "FL", "EFL" };
497static const char* gui_show_values_modes[] = { "Don't", "Always", "Shoot" };
498static CMenuItem values_submenu_items[] = {
499          MENU_ENUM2(0x5f,LANG_MENU_OSD_SHOW_MISC_VALUES,          &conf.show_values, gui_show_values_modes ),
500         // MENU_ITEM(0x43,LANG_MENU_VALUES_SHOW_IN_REVIEW,   MENUITEM_BOOL,      &conf.values_show_in_review, 0 ),
501          MENU_ITEM(0x5c,LANG_MENU_SHOW_VALUES_IN_VIDEO,           MENUITEM_BOOL,      &conf.show_values_in_video, 0 ),
502          MENU_ITEM(0x5c,LANG_MENU_VALUES_SHOW_ZOOM,               MENUITEM_BOOL,      &conf.values_show_zoom, 0 ),
503          MENU_ENUM2(0x5f,LANG_MENU_OSD_ZOOM_VALUE,                &conf.zoom_value, gui_zoom_value_modes ),
504          MENU_ITEM(0x60,LANG_MENU_OSD_ZOOM_SCALE,                 MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.zoom_scale,   MENU_MINMAX(0, 1000) ),
505      MENU_ITEM(0x62,LANG_MENU_VALUES_SHOW_REAL_APERTURE,      MENUITEM_BOOL,      &conf.values_show_real_aperture, 0 ),
506      MENU_ITEM(0x74,LANG_MENU_VALUES_SHOW_REAL_ISO,           MENUITEM_BOOL,      &conf.values_show_real_iso, 0 ),
507      MENU_ITEM(0x74,LANG_MENU_VALUES_SHOW_MARKET_ISO,         MENUITEM_BOOL,      &conf.values_show_market_iso, 0 ),
508          MENU_ITEM(0x2d,LANG_MENU_SHOW_ISO_ONLY_IN_AUTOISO_MODE,  MENUITEM_BOOL,            &conf.values_show_iso_only_in_autoiso_mode, 0 ),
509      MENU_ITEM(0x5c,LANG_MENU_VALUES_SHOW_EV_SETED,                     MENUITEM_BOOL,      &conf.values_show_ev_seted, 0 ),
510      MENU_ITEM(0x5c,LANG_MENU_VALUES_SHOW_EV_MEASURED,        MENUITEM_BOOL,            &conf.values_show_ev_measured, 0 ),
511      MENU_ITEM(0x5c,LANG_MENU_VALUES_SHOW_BV_SETED,                     MENUITEM_BOOL,      &conf.values_show_bv_seted, 0 ),
512      MENU_ITEM(0x5c,LANG_MENU_VALUES_SHOW_BV_MEASURED,          MENUITEM_BOOL,      &conf.values_show_bv_measured, 0 ),
513      MENU_ITEM(0x5c,LANG_MENU_VALUES_SHOW_OVEREXPOSURE,             MENUITEM_BOOL,      &conf.values_show_overexposure, 0 ),
514      MENU_ITEM(0x5c,LANG_MENU_SHOW_CANON_OVEREXPOSURE,      MENUITEM_BOOL,      &conf.values_show_canon_overexposure, 0 ),
515      MENU_ITEM(0x5c,LANG_MENU_VALUES_SHOW_LUMINANCE,        MENUITEM_BOOL,      &conf.values_show_luminance, 0 ),
516          MENU_ITEM(0x51,LANG_MENU_BACK,                           MENUITEM_UP, 0, 0 ),
517    {0}
518};
519static CMenu values_submenu = {0x28,LANG_MENU_OSD_VALUES_TITLE, /*cb_values_menu_change*/ NULL, values_submenu_items };
520
521static const char* gui_show_clock_modes[]={ "Don't", "Normal", "Seconds"};
522static const char* gui_clock_format_modes[] = { "24h", "12h"};
523static const char* gui_clock_indicator_modes[] = { "PM", "P", "."};
524static const char* gui_clock_halfpress_modes[] = { "Full", "Seconds", "Don't"};
525static CMenuItem clock_submenu_items[] = {
526    MENU_ENUM2(0x5f,LANG_MENU_OSD_SHOW_CLOCK,           &conf.show_clock, gui_show_clock_modes ),
527    MENU_ENUM2(0x6d,LANG_MENU_OSD_CLOCK_FORMAT,         &conf.clock_format, gui_clock_format_modes ),
528    MENU_ENUM2(0x6c,LANG_MENU_OSD_CLOCK_INDICATOR,      &conf.clock_indicator, gui_clock_indicator_modes ),
529    MENU_ENUM2(0x6e,LANG_MENU_OSD_CLOCK_HALFPRESS,      &conf.clock_halfpress, gui_clock_halfpress_modes ),
530    MENU_ITEM(0x51,LANG_MENU_BACK, MENUITEM_UP, 0, 0 ),
531    {0}
532};
533static CMenu clock_submenu = {0x34,LANG_MENU_OSD_CLOCK_PARAMS_TITLE, NULL, clock_submenu_items };
534
535
536static const char* gui_show_movie_time_modes[] = { "Don't", "hh:mm:ss", "KB/s","both"};
537#if !CAM_VIDEO_QUALITY_ONLY
538    static const char* gui_video_mode_modes[] = { "Bitrate", "Quality"};
539#else
540    static const char* gui_video_mode_modes[] = { "Default", "Quality"};
541#endif
542static CMenuItem video_submenu_items[] = {
543#if CAM_CHDK_HAS_EXT_VIDEO_MENU
544        MENU_ENUM2(0x23,LANG_MENU_VIDEO_MODE,             &conf.video_mode, gui_video_mode_modes ),
545#if !CAM_VIDEO_QUALITY_ONLY
546      MENU_ITEM(0x5e,LANG_MENU_VIDEO_BITRATE,           MENUITEM_ENUM,    gui_video_bitrate_enum, 0 ),
547#endif
548    MENU_ITEM(0x60,LANG_MENU_VIDEO_QUALITY,           MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.video_quality, MENU_MINMAX(1, 99) ),
549    MENU_ITEM(0x5c,LANG_MENU_CLEAR_VIDEO_VALUES,    MENUITEM_BOOL,    &conf.clear_video, 0 ),
550#endif
551#if CAM_VIDEO_CONTROL
552    MENU_ITEM(0x5c,LANG_MENU_FAST_SWITCH_VIDEO,   MENUITEM_BOOL,  &conf.fast_movie_control, 0 ),
553#endif
554#if CAM_CHDK_HAS_EXT_VIDEO_MENU
555    MENU_ITEM(0x5c,LANG_MENU_FAST_SWITCH_QUALITY_VIDEO,   MENUITEM_BOOL,  &conf.fast_movie_quality_control, 0 ),
556#endif
557#if CAM_CAN_UNLOCK_OPTICAL_ZOOM_IN_VIDEO
558    MENU_ITEM(0x5c,LANG_MENU_OPTICAL_ZOOM_IN_VIDEO,   MENUITEM_BOOL,  &conf.unlock_optical_zoom_for_video, 0 ),
559#endif
560#if CAM_CAN_MUTE_MICROPHONE
561    MENU_ITEM(0x83,LANG_MENU_MUTE_ON_ZOOM,   MENUITEM_BOOL,  &conf.mute_on_zoom, 0 ),
562#endif
563#if CAM_AF_SCAN_DURING_VIDEO_RECORD
564    MENU_ITEM(0x82,LANG_MENU_VIDEO_AF_KEY,   MENUITEM_ENUM,    gui_video_af_key_enum, 0 ),
565#endif
566    MENU_ENUM2(0x5c,LANG_MENU_OSD_SHOW_VIDEO_TIME,         &conf.show_movie_time, gui_show_movie_time_modes ),
567    MENU_ITEM(0x60,LANG_MENU_OSD_SHOW_VIDEO_REFRESH,             MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.show_movie_refresh,   MENU_MINMAX(1, 20) ),
568    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
569    {0}
570};
571static CMenu video_submenu = {0x23,LANG_MENU_VIDEO_PARAM_TITLE, NULL, video_submenu_items };
572
573static const char* gui_bracket_values_modes[] = { "Off", "1/3 Ev","2/3 Ev", "1 Ev", "1 1/3Ev", "1 2/3Ev", "2 Ev", "2 1/3Ev", "2 2/3Ev", "3 Ev", "3 1/3Ev", "3 2/3Ev", "4 Ev"};
574static const char* gui_override_koef_modes[] = { "Off", "1", "10", "100", "1000" };
575static const char* gui_bracket_type_modes[] = { "+/-", "-","+"};
576static CMenuItem bracketing_in_continuous_submenu_items[] = {
577          MENU_ENUM2(0x63,LANG_MENU_TV_BRACKET_VALUE,            &conf.tv_bracket_value, gui_bracket_values_modes ),
578#if CAM_HAS_IRIS_DIAPHRAGM
579          MENU_ENUM2(0x62,LANG_MENU_AV_BRACKET_VALUE,            &conf.av_bracket_value, gui_bracket_values_modes ),
580#endif
581#if CAM_CAN_SD_OVERRIDE
582          MENU_ITEM(0x5e,LANG_MENU_SUBJ_DIST_BRACKET_VALUE,      MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.subj_dist_bracket_value, MENU_MINMAX(0, 100) ),
583          MENU_ENUM2(0x5f,LANG_MENU_SUBJ_DIST_BRACKET_KOEF,      &conf.subj_dist_bracket_koef, gui_override_koef_modes ),
584#endif
585          MENU_ITEM(0x74,LANG_MENU_ISO_BRACKET_VALUE,            MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.iso_bracket_value, MENU_MINMAX(0, 100) ),
586          MENU_ENUM2a(0x5f,LANG_MENU_ISO_BRACKET_KOEF,           &conf.iso_bracket_koef, gui_override_koef_modes, 4 ),
587          MENU_ENUM2(0x60,LANG_MENU_BRACKET_TYPE,                &conf.bracket_type, gui_bracket_type_modes ),
588          MENU_ITEM(0x5b,LANG_MENU_CLEAR_BRACKET_VALUES,        MENUITEM_BOOL,        &conf.clear_bracket, 0 ),
589     MENU_ITEM(0x5c,LANG_MENU_BRACKETING_ADD_RAW_SUFFIX,                MENUITEM_BOOL,      &conf.bracketing_add_raw_suffix, 0 ),
590      MENU_ITEM(0x51,LANG_MENU_BACK,                         MENUITEM_UP, 0, 0 ),
591      {0}
592};
593static CMenu bracketing_in_continuous_submenu = {0x2c,LANG_MENU_BRACKET_IN_CONTINUOUS_TITLE, NULL, bracketing_in_continuous_submenu_items };
594
595
596/*
597static CMenuItem exposure_submenu_items[] = {
598          MENU_ITEM(0x59,LANG_MENU_RECALC_EXPOSURE,         MENUITEM_BOOL,    &conf.recalc_exposure, 0),
599          MENU_ITEM(0x63,LANG_MENU_TV_EXPOSURE_ORDER,       MENUITEM_ENUM,    gui_tv_exposure_order_enum, 0),
600          MENU_ITEM(0x62,LANG_MENU_AV_EXPOSURE_ORDER,       MENUITEM_ENUM,    gui_av_exposure_order_enum, 0),
601          MENU_ITEM(0x74,LANG_MENU_ISO_EXPOSURE_ORDER,     MENUITEM_ENUM,    gui_iso_exposure_order_enum, 0),
602          MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
603      {0}
604};
605static CMenu exposure_submenu = {0x2a,LANG_MENU_EXPOSURE_TITLE, NULL, exposure_submenu_items };
606*/
607
608// "Extra Photo Operations" Menu
609static const char* gui_override_disable_modes[] = { "Off", "On", "Disabled"};
610static const char* gui_nd_filter_state_modes[] = { "Off", "In", "Out" };
611static const char* gui_fast_ev_step_modes[] = {"1/6 Ev","1/3 Ev","1/2 Ev", "2/3 Ev","5/6 Ev","1 Ev","1 1/6 Ev","1 1/3 Ev","1 1/2 Ev", "1 2/3 Ev","1 5/6 Ev","2 Ev","2 1/6 Ev","2 1/3 Ev","2 1/2 Ev", "2 2/3 Ev","2 5/6 Ev","3 Ev","3 1/6 Ev","3 1/3 Ev","3 1/2 Ev", "3 2/3 Ev","3 5/6 Ev","4 Ev"};
612static const char* gui_fast_image_quality_modes[] = { "sup.fine", "fine", "normal", "off" };
613static CMenuItem operation_submenu_items[] = {
614      MENU_ENUM2(0x5f,LANG_MENU_OVERRIDE_DISABLE,    &conf.override_disable, gui_override_disable_modes ),
615      MENU_ITEM(0x5c,LANG_MENU_OVERRIDE_DISABLE_ALL,     MENUITEM_BOOL,    &conf.override_disable_all, 0 ),
616          MENU_ITEM(0x61,LANG_MENU_OVERRIDE_TV_VALUE,        MENUITEM_ENUM,    gui_tv_override_value_enum, 0 ),
617          MENU_ITEM(0x5f,LANG_MENU_OVERRIDE_TV_KOEF,         MENUITEM_ENUM,    gui_tv_override_koef_enum, 0 ),
618          MENU_ITEM(0x59,LANG_MENU_TV_ENUM_TYPE,             MENUITEM_ENUM,    gui_tv_enum_type_enum, 0 ),
619#if CAM_HAS_IRIS_DIAPHRAGM
620          MENU_ITEM(0x62,LANG_MENU_OVERRIDE_AV_VALUE,        MENUITEM_ENUM,    gui_av_override_enum, 0 ),
621#endif
622#if CAM_HAS_ND_FILTER
623      MENU_ENUM2(0x5f,LANG_MENU_OVERRIDE_ND_FILTER,      &conf.nd_filter_state, gui_nd_filter_state_modes ),
624#endif
625#if CAM_CAN_SD_OVERRIDE
626      MENU_ITEM(0x5e,LANG_MENU_OVERRIDE_SUBJ_DIST_VALUE, MENUITEM_ENUM,    gui_subj_dist_override_value_enum, 0 ),
627          MENU_ITEM(0x5f,LANG_MENU_OVERRIDE_SUBJ_DIST_KOEF,  MENUITEM_ENUM,    gui_subj_dist_override_koef_enum, 0 ),
628#endif
629          MENU_ITEM(0x74,LANG_MENU_OVERRIDE_ISO_VALUE,     MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.iso_override_value, MENU_MINMAX(0, 800) ),
630          MENU_ENUM2a(0x5f,LANG_MENU_OVERRIDE_ISO_KOEF,       &conf.iso_override_koef, gui_override_koef_modes, 4 ),
631#if ZOOM_OVERRIDE
632    MENU_ITEM(0x5c,LANG_MENU_OVERRIDE_ZOOM,         MENUITEM_BOOL,    &conf.zoom_override, 0 ),
633    MENU_ITEM(0x5f,LANG_MENU_OVERRIDE_ZOOM_VALUE,         MENUITEM_ENUM,    gui_zoom_override_enum, 0 ),
634
635          MENU_ITEM(0x5c,LANG_MENU_CLEAR_ZOOM_OVERRIDE_VALUES,    MENUITEM_BOOL,    &conf.clear_zoom_override, 0 ),
636#endif
637          MENU_ITEM(0x2c,LANG_MENU_BRACKET_IN_CONTINUOUS,          MENUITEM_SUBMENU, &bracketing_in_continuous_submenu, 0 ),
638          MENU_ITEM(0x2d,LANG_MENU_AUTOISO,                  MENUITEM_SUBMENU, &autoiso_submenu, 0 ),
639      //{LANG_MENU_EXPOSURE,               MENUITEM_SUBMENU, &exposure_submenu, 0 ),
640          MENU_ITEM(0x5b,LANG_MENU_CLEAR_OVERRIDE_VALUES,    MENUITEM_BOOL,    &conf.clear_override, 0 ),
641
642      MENU_ITEM(0x5c,LANG_MENU_MISC_FAST_EV,         MENUITEM_BOOL,    &conf.fast_ev, 0 ),
643      MENU_ENUM2(0x5f,LANG_MENU_MISC_FAST_EV_STEP,   &conf.fast_ev_step, gui_fast_ev_step_modes ),
644#if CAM_REAR_CURTAIN
645      MENU_ITEM(0x5c, LANG_MENU_REAR_CURTAIN, MENUITEM_BOOL, &conf.flash_sync_curtain, 0 ),
646#endif
647          MENU_ITEM(0x5c, LANG_MENU_FLASH_MANUAL_OVERRIDE, MENUITEM_BOOL,   &conf.flash_manual_override, 0 ),
648    MENU_ITEM(0x5f, LANG_MENU_FLASH_VIDEO_OVERRIDE_POWER,      MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.flash_video_override_power, MENU_MINMAX(0, 2) ),
649#if CAM_HAS_VIDEO_BUTTON
650    MENU_ITEM(0x5c, LANG_MENU_FLASH_VIDEO_OVERRIDE, MENUITEM_BOOL,   &conf.flash_video_override, 0 ),
651#endif
652#if CAM_QUALITY_OVERRIDE
653    MENU_ENUM2(0x5c,LANG_MENU_MISC_IMAGE_QUALITY,   &conf.fast_image_quality, gui_fast_image_quality_modes ),
654#endif
655    MENU_ITEM(0x51,LANG_MENU_BACK,                     MENUITEM_UP, 0, 0 ),
656    {0}
657};
658static CMenu operation_submenu = {0x21,LANG_MENU_OPERATION_PARAM_TITLE, NULL, operation_submenu_items };
659
660#ifdef OPT_EDGEOVERLAY
661static const char* gui_edge_pano_modes[] = { "Off", "Right", "Down", "Left", "Up", "Free"};
662static CMenuItem edge_overlay_submenu_items[] = {
663    MENU_ITEM(0x5c,LANG_MENU_EDGE_OVERLAY_ENABLE,     MENUITEM_BOOL,          &conf.edge_overlay_enable, 0 ),
664    MENU_ITEM(0x5c,LANG_MENU_EDGE_FILTER,     MENUITEM_BOOL,          &conf.edge_overlay_filter, 0 ),
665    MENU_ENUM2(0x5f,LANG_MENU_EDGE_PANO,    &conf.edge_overlay_pano, gui_edge_pano_modes ),
666    MENU_ITEM(0x5e,LANG_MENU_EDGE_PANO_OVERLAP,   MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.edge_overlay_pano_overlap, MENU_MINMAX(0, 100) ),
667    MENU_ITEM(0x5c,LANG_MENU_EDGE_SHOW,     MENUITEM_BOOL,          &conf.edge_overlay_show, 0 ),
668    MENU_ITEM(0x5e,LANG_MENU_EDGE_OVERLAY_TRESH,      MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.edge_overlay_thresh, MENU_MINMAX(0, 255) ),
669    MENU_ITEM(0x65,LANG_MENU_EDGE_OVERLAY_COLOR,      MENUITEM_COLOR_FG,      &conf.edge_overlay_color, 0 ),
670    MENU_ITEM(0x5c,LANG_MENU_EDGE_PLAY,                 MENUITEM_BOOL,          &conf.edge_overlay_play, 0 ), //does not work on cams like s-series, which dont have a real "hardware" play/rec switch, need a workaround, probably another button
671    MENU_ITEM(0x33,LANG_MENU_EDGE_SAVE,                 MENUITEM_PROC,          gui_menuproc_edge_save, 0 ),
672    MENU_ITEM(0x5c,LANG_MENU_EDGE_ZOOM,     MENUITEM_BOOL,          &conf.edge_overlay_zoom, 0 ),
673    MENU_ITEM(0x33,LANG_MENU_EDGE_LOAD,                 MENUITEM_PROC,          gui_menuproc_edge_load, 0 ),
674    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
675    {0}
676};
677static CMenu edge_overlay_submenu = {0x7f,LANG_MENU_EDGE_OVERLAY_TITLE, NULL, edge_overlay_submenu_items };
678#endif
679
680static CMenuItem grid_submenu_items[] = {
681    MENU_ITEM(0x2f,LANG_MENU_SHOW_GRID,               MENUITEM_BOOL,            &conf.show_grid_lines, 0 ),
682    MENU_ITEM(0x35,LANG_MENU_GRID_LOAD,               MENUITEM_PROC,            gui_grid_lines_load, 0 ),
683    MENU_ITEM(0x0,LANG_MENU_GRID_CURRENT,            MENUITEM_SEPARATOR, 0, 0 ),
684    MENU_ITEM(0x0,(int)grid_title,                   MENUITEM_TEXT, 0, 0 ),
685    MENU_ITEM(0x0,(int)"",                           MENUITEM_SEPARATOR, 0, 0 ),
686    MENU_ITEM(0x5c,LANG_MENU_GRID_FORCE_COLOR,        MENUITEM_BOOL,          &conf.grid_force_color, 0 ),
687    MENU_ITEM(0x65,LANG_MENU_GRID_COLOR_LINE,         MENUITEM_COLOR_FG,      &conf.grid_color, 0 ),
688    MENU_ITEM(0x65,LANG_MENU_GRID_COLOR_FILL,         MENUITEM_COLOR_BG,      &conf.grid_color, 0 ),
689    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
690    {0}
691};
692static CMenu grid_submenu = {0x2f,LANG_MENU_GRID_TITLE, NULL, grid_submenu_items };
693
694static CMenuItem visual_submenu_items[] = {
695    MENU_ITEM(0x35,LANG_MENU_VIS_LANG,                MENUITEM_PROC,      gui_draw_load_lang, 0 ),
696    MENU_ITEM(0x5f,LANG_MENU_VIS_OSD_FONT,            MENUITEM_ENUM,      gui_font_enum, 0 ),
697    MENU_ITEM(0x35,LANG_MENU_VIS_MENU_FONT,           MENUITEM_PROC,      gui_draw_load_menu_rbf, 0 ),
698    MENU_ITEM(0x35,LANG_MENU_VIS_MENU_SYMBOL_FONT,    MENUITEM_PROC,      gui_draw_load_symbol_rbf, 0 ),
699    MENU_ITEM(0x80,LANG_MENU_RESET_FILES                 ,         MENUITEM_PROC,          gui_menuproc_reset_files, 0 ),
700    MENU_ITEM(0x0,LANG_MENU_VIS_COLORS,              MENUITEM_SEPARATOR, 0, 0 ),
701    MENU_ITEM(0x65,LANG_MENU_VIS_OSD_TEXT,            MENUITEM_COLOR_FG,  &conf.osd_color, 0 ),
702    MENU_ITEM(0x65,LANG_MENU_VIS_OSD_BKG,             MENUITEM_COLOR_BG,  &conf.osd_color, 0 ),
703    MENU_ITEM(0x65,LANG_MENU_VIS_OSD_WARNING,         MENUITEM_COLOR_FG,  &conf.osd_color_warn, 0 ),
704    MENU_ITEM(0x65,LANG_MENU_VIS_OSD_WARNING_BKG,     MENUITEM_COLOR_BG,  &conf.osd_color_warn, 0 ),
705    MENU_ITEM(0x65,LANG_MENU_VIS_HISTO,               MENUITEM_COLOR_FG,  &conf.histo_color, 0 ),
706    MENU_ITEM(0x65,LANG_MENU_VIS_HISTO_BKG,           MENUITEM_COLOR_BG,  &conf.histo_color, 0 ),
707    MENU_ITEM(0x65,LANG_MENU_VIS_HISTO_BORDER,        MENUITEM_COLOR_FG,  &conf.histo_color2, 0 ),
708    MENU_ITEM(0x65,LANG_MENU_VIS_HISTO_MARKERS,       MENUITEM_COLOR_BG,  &conf.histo_color2, 0 ),
709    MENU_ITEM(0x65,LANG_MENU_VIS_ZEBRA_UNDER,         MENUITEM_COLOR_BG,  &conf.zebra_color, 0 ),
710    MENU_ITEM(0x65,LANG_MENU_VIS_ZEBRA_OVER,          MENUITEM_COLOR_FG,  &conf.zebra_color, 0 ),
711    MENU_ITEM(0x65,LANG_MENU_VIS_BATT_ICON,           MENUITEM_COLOR_FG,  &conf.batt_icon_color, 0 ),
712    MENU_ITEM(0x65,LANG_MENU_VIS_SPACE_ICON,          MENUITEM_COLOR_FG,  &conf.space_color, 0 ),
713    MENU_ITEM(0x65,LANG_MENU_VIS_SPACE_ICON_BKG,      MENUITEM_COLOR_BG,  &conf.space_color, 0 ),
714    MENU_ITEM(0x65,LANG_MENU_VIS_MENU_TEXT,           MENUITEM_COLOR_FG,  &conf.menu_color, 0 ),
715    MENU_ITEM(0x65,LANG_MENU_VIS_MENU_BKG,            MENUITEM_COLOR_BG,  &conf.menu_color, 0 ),
716    MENU_ITEM(0x65,LANG_MENU_VIS_MENU_TITLE_TEXT,     MENUITEM_COLOR_FG,  &conf.menu_title_color, 0 ),
717    MENU_ITEM(0x65,LANG_MENU_VIS_MENU_TITLE_BKG,      MENUITEM_COLOR_BG,  &conf.menu_title_color, 0 ),
718    MENU_ITEM(0x65,LANG_MENU_VIS_MENU_CURSOR_TEXT,    MENUITEM_COLOR_FG,  &conf.menu_cursor_color, 0 ),
719    MENU_ITEM(0x65,LANG_MENU_VIS_MENU_CURSOR_BKG,     MENUITEM_COLOR_BG,  &conf.menu_cursor_color, 0 ),
720    MENU_ITEM(0x65,LANG_MENU_VIS_MENU_SYMBOL_TEXT,    MENUITEM_COLOR_FG,  &conf.menu_symbol_color, 0 ),
721    MENU_ITEM(0x65,LANG_MENU_VIS_MENU_SYMBOL_BKG,     MENUITEM_COLOR_BG,  &conf.menu_symbol_color, 0 ),
722    MENU_ITEM(0x65,LANG_MENU_VIS_READER_TEXT,         MENUITEM_COLOR_FG,  &conf.reader_color, 0 ),
723    MENU_ITEM(0x65,LANG_MENU_VIS_READER_BKG,          MENUITEM_COLOR_BG,  &conf.reader_color, 0 ),
724    MENU_ITEM(0x65,LANG_MENU_VIS_OSD_OVERRIDE,         MENUITEM_COLOR_FG,  &conf.osd_color_override, 0 ),
725    MENU_ITEM(0x65,LANG_MENU_VIS_OSD_OVERRIDE_BKG,     MENUITEM_COLOR_BG,  &conf.osd_color_override, 0 ),
726    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
727    {0}
728};
729static CMenu visual_submenu = {0x28,LANG_MENU_VIS_TITLE, NULL, visual_submenu_items };
730
731/*
732 * 1 extra entry for the "Main menu" and 1 for null when the menu is full with user selections
733 * Compiler will zero init remaining portion of array so no there is no hidden relationship between
734 * this structure and the value of USER_MENU_ITEMS. The value of USER_MENU_ITEMS can be anything you
735 * wish and everything automagically works.
736*/
737
738static CMenuItem user_submenu_items[USER_MENU_ITEMS + 2] = {
739        MENU_ITEM(0x20,LANG_MENU_MAIN_TITLE,     MENUITEM_PROC,  rinit, 0 )
740};
741
742static CMenu user_submenu = {0x2e,LANG_MENU_USER_MENU, NULL, user_submenu_items };
743
744static CMenuItem raw_state_submenu_items[] = {
745    MENU_ITEM(0x5c,LANG_MENU_OSD_SHOW_RAW_STATE,      MENUITEM_BOOL,      &conf.show_raw_state, 0 ),
746    MENU_ITEM(0x5c,LANG_MENU_OSD_SHOW_REMAINING_RAW,  MENUITEM_BOOL,      &conf.show_remaining_raw, 0 ),
747    MENU_ITEM(0x60,LANG_MENU_OSD_RAW_TRESHOLD,        MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.remaining_raw_treshold,   MENU_MINMAX(0, 200) ),
748    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
749    {0}
750};
751
752static CMenu raw_state_submenu = {0x24,LANG_MENU_OSD_RAW_STATE_PARAMS_TITLE, NULL, raw_state_submenu_items };
753
754#ifdef  CAM_TOUCHSCREEN_UI
755static const char* gui_touchscreen_disable_modes[]={ "Enable", "Disable" };
756static CMenuItem touchscreen_submenu_items[] = {
757    MENU_ENUM2(0x5f,LANG_MENU_TS_VIDEO_AE_DISABLE,      &conf.touchscreen_disable_video_controls,    gui_touchscreen_disable_modes ),
758    MENU_ENUM2(0x5f,LANG_MENU_TS_ALT_SHORTCUTS_DISABLE, &conf.touchscreen_disable_shortcut_controls, gui_touchscreen_disable_modes ),
759    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
760    {0}
761};
762static CMenu touchscreen_submenu = {0x28,LANG_MENU_TOUCHSCREEN_VALUES, /*cb_values_menu_change*/ NULL, touchscreen_submenu_items };
763#endif
764
765static const char* gui_temp_mode_modes[] = { "Off", "Optical", "CCD", "Battery", "all" };
766static const char* gui_hide_osd_modes[] = { "Don't", "In Playback", "On Disp Press", "Both"};
767static const char* gui_show_usb_info_modes[] = { "Off", "Icon", "Text"};
768static CMenuItem osd_submenu_items[] = {
769    MENU_ITEM(0x5c,LANG_MENU_OSD_SHOW,                MENUITEM_BOOL,      &conf.show_osd, 0 ),
770    MENU_ENUM2(0x5c,LANG_MENU_OSD_HIDE_PLAYBACK,      &conf.hide_osd, gui_hide_osd_modes ),
771    MENU_ITEM(0x81,LANG_MENU_VIS_MENU_CENTER,         MENUITEM_BOOL,        &conf.menu_center, 0 ),
772    MENU_ITEM(0x81,LANG_MENU_SELECT_FIRST_ENTRY,         MENUITEM_BOOL,     &conf.menu_select_first_entry, 0 ),
773    MENU_ITEM(0x64,LANG_MENU_VIS_SYMBOL,             MENUITEM_BOOL,         &conf.menu_symbol_enable, 0 ),
774    MENU_ITEM(0x2e,LANG_MENU_USER_MENU,                         MENUITEM_SUBMENU,   &user_submenu, 0 ),
775    MENU_ITEM(0x5f,LANG_MENU_USER_MENU_ENABLE,          MENUITEM_ENUM,      gui_user_menu_show_enum, 0 ),
776    MENU_ITEM(0x5c,LANG_MENU_USER_MENU_AS_ROOT,       MENUITEM_BOOL,      &conf.user_menu_as_root, 0 ),
777    MENU_ITEM(0x5f,LANG_MENU_OSD_SHOW_STATES,         MENUITEM_BOOL,      &conf.show_state, 0 ),
778    MENU_ENUM2(0x5f,LANG_MENU_OSD_SHOW_TEMP,         &conf.show_temp, gui_temp_mode_modes ),
779    MENU_ITEM(0x59,LANG_MENU_OSD_TEMP_FAHRENHEIT,      MENUITEM_BOOL,      &conf.temperature_unit, 0 ),
780    MENU_ENUM2(0x71,LANG_MENU_USB_SHOW_INFO,         &conf.usb_info_enable, gui_show_usb_info_modes ),
781    MENU_ITEM(0x72,LANG_MENU_OSD_LAYOUT_EDITOR,       MENUITEM_PROC,      gui_draw_osd_le, 0 ),
782    MENU_ITEM(0x2f,LANG_MENU_OSD_GRID_PARAMS,         MENUITEM_SUBMENU,   &grid_submenu, 0 ),
783    MENU_ITEM(0x22,LANG_MENU_OSD_VALUES,                MENUITEM_SUBMENU,   &values_submenu, 0 ),
784    MENU_ITEM(0x31,LANG_MENU_OSD_DOF_CALC,            MENUITEM_SUBMENU,   &dof_submenu, 0 ),
785    MENU_ITEM(0x24,LANG_MENU_OSD_RAW_STATE_PARAMS,    MENUITEM_SUBMENU,   &raw_state_submenu, 0 ),
786    MENU_ITEM(0x32,LANG_MENU_OSD_BATT_PARAMS,         MENUITEM_SUBMENU,   &battery_submenu, 0 ),
787    MENU_ITEM(0x33,LANG_MENU_OSD_SPACE_PARAMS,        MENUITEM_SUBMENU,   &space_submenu, 0 ),
788    MENU_ITEM(0x34,LANG_MENU_OSD_CLOCK_PARAMS,          MENUITEM_SUBMENU,   &clock_submenu, 0 ),
789    MENU_ITEM(0x59,LANG_MENU_OSD_SHOW_IN_REVIEW,      MENUITEM_BOOL,      &conf.show_osd_in_review, 0 ),
790#ifndef OPTIONS_AUTOSAVE
791    MENU_ITEM(0x5c,LANG_MENU_MAIN_SAVE_OPTIONS,       MENUITEM_PROC,      gui_menuproc_save, 0 ),
792#endif
793#ifdef  CAM_TOUCHSCREEN_UI
794    MENU_ITEM(0x22,LANG_MENU_TOUCHSCREEN_VALUES,         MENUITEM_SUBMENU,   &touchscreen_submenu, 0 ),
795#endif
796    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
797    {0}
798};
799
800static CMenu osd_submenu = {0x22,LANG_MENU_OSD_TITLE, NULL, osd_submenu_items };
801
802static const char* gui_histo_show_modes[] = { "Don't", "Always", "Shoot" };
803static CMenuItem histo_submenu_items[] = {
804    MENU_ENUM2(0x5f,LANG_MENU_HISTO_SHOW,             &conf.show_histo, gui_histo_show_modes ),
805    MENU_ITEM(0x6f,LANG_MENU_HISTO_LAYOUT,            MENUITEM_ENUM,      gui_histo_layout_enum, 0 ),
806    MENU_ITEM(0x5f,LANG_MENU_HISTO_MODE,              MENUITEM_ENUM,      gui_histo_mode_enum, 0 ),
807    MENU_ITEM(0x5c,LANG_MENU_HISTO_EXP,               MENUITEM_BOOL,       &conf.show_overexp, 0 ),
808    MENU_ITEM(0x70,LANG_MENU_HISTO_IGNORE_PEAKS,      MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.histo_ignore_boundary,   MENU_MINMAX(0, 32) ),
809    MENU_ITEM(0x5c,LANG_MENU_HISTO_MAGNIFY,           MENUITEM_BOOL,       &conf.histo_auto_ajust, 0 ),
810    MENU_ITEM(0x5c,LANG_MENU_HISTO_SHOW_EV_GRID,      MENUITEM_BOOL,       &conf.histo_show_ev_grid, 0 ),
811    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
812    {0}
813};
814static CMenu histo_submenu = {0x25,LANG_MENU_HISTO_TITLE, NULL, histo_submenu_items };
815
816static CMenuItem raw_exceptions_submenu_items[] = {
817    #if defined CAM_HAS_VIDEO_BUTTON
818     MENU_ITEM(0x5c,LANG_MENU_RAW_SAVE_IN_VIDEO,                MENUITEM_BOOL,      &conf.save_raw_in_video, 0 ),
819    #endif
820    #if defined(CAMERA_s3is)
821        MENU_ITEM(0x5c,LANG_MENU_RAW_SAVE_IN_SPORTS,                MENUITEM_BOOL,      &conf.save_raw_in_sports, 0 ),
822    #endif
823    MENU_ITEM(0x5c,LANG_MENU_RAW_SAVE_IN_BURST,                MENUITEM_BOOL,      &conf.save_raw_in_burst, 0 ),
824    MENU_ITEM(0x5c,LANG_MENU_RAW_SAVE_IN_TIMER,                MENUITEM_BOOL,      &conf.save_raw_in_timer, 0 ),
825    MENU_ITEM(0x5c,LANG_MENU_RAW_SAVE_IN_EDGEOVERLAY,          MENUITEM_BOOL,      &conf.save_raw_in_edgeoverlay, 0 ),
826    MENU_ITEM(0x5c,LANG_MENU_RAW_SAVE_IN_AUTO,                 MENUITEM_BOOL,      &conf.save_raw_in_auto, 0 ),
827                #if CAM_BRACKETING
828        MENU_ITEM(0x5c,LANG_MENU_RAW_SAVE_IN_EV_BRACKETING,                MENUITEM_BOOL,      &conf.save_raw_in_ev_bracketing, 0 ),
829                #endif
830    MENU_ITEM(0x5c,LANG_MENU_RAW_WARN,                MENUITEM_BOOL,      &conf.raw_exceptions_warn, 0 ),
831    MENU_ITEM(0x51,LANG_MENU_BACK,                           MENUITEM_UP, 0, 0 ),
832    {0}
833};
834static CMenu raw_exceptions_submenu = {0x59,LANG_MENU_OSD_RAW_EXCEPTIONS_PARAMS_TITLE, NULL, raw_exceptions_submenu_items };
835
836
837static const char* gui_raw_nr_modes[] = { "Auto", "Off", "On"};
838static CMenuItem raw_submenu_items[] = {
839    MENU_ITEM(0x5c,LANG_MENU_RAW_SAVE,                MENUITEM_BOOL,      &conf.save_raw, 0 ),
840    MENU_ITEM(0x59,LANG_MENU_OSD_RAW_EXCEPTIONS_PARAMS,         MENUITEM_SUBMENU,   &raw_exceptions_submenu, 0 ),
841    MENU_ENUM2(0x5f,LANG_MENU_RAW_NOISE_REDUCTION,    &conf.raw_nr, gui_raw_nr_modes ),
842    MENU_ITEM(0x5c,LANG_MENU_RAW_FIRST_ONLY,          MENUITEM_BOOL,      &conf.raw_save_first_only, 0 ),
843    MENU_ITEM(0x5c,LANG_MENU_RAW_SAVE_IN_DIR,         MENUITEM_BOOL,      &conf.raw_in_dir, 0 ),
844    MENU_ENUM2a(0x5f,LANG_MENU_RAW_PREFIX,            &conf.raw_prefix, img_prefixes, NUM_IMG_PREFIXES ),
845    MENU_ENUM2a(0x5f,LANG_MENU_RAW_EXTENSION,         &conf.raw_ext, img_exts, NUM_IMG_EXTS ),
846    MENU_ENUM2a(0x5f,LANG_MENU_SUB_PREFIX,            &conf.sub_batch_prefix, img_prefixes, NUM_IMG_PREFIXES ),
847    MENU_ENUM2a(0x5f,LANG_MENU_SUB_EXTENSION,         &conf.sub_batch_ext, img_exts, NUM_IMG_EXTS ),
848//  MENU_ITEM(0x60,LANG_MENU_SUB_IN_DARK_VALUE,       MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.sub_in_dark_value, MENU_MINMAX(0, 1023) ),
849//  MENU_ITEM(0x60,LANG_MENU_SUB_OUT_DARK_VALUE,      MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.sub_out_dark_value, MENU_MINMAX(0, 1023) ),
850    MENU_ITEM(0x2a,LANG_MENU_RAW_DEVELOP,             MENUITEM_PROC,      gui_raw_develop, 0 ),
851    MENU_ITEM(0x5c,LANG_MENU_BAD_PIXEL_REMOVAL,       MENUITEM_ENUM,      gui_bad_pixel_enum, 0 ),
852#if DNG_SUPPORT
853    MENU_ITEM(0x5c,LANG_MENU_DNG_FORMAT,              MENUITEM_BOOL | MENUITEM_ARG_CALLBACK, &conf.dng_raw , (int)cb_change_dng ),
854    MENU_ITEM(0x5c,LANG_MENU_RAW_DNG_EXT,             MENUITEM_BOOL,      &conf.raw_dng_ext, 0 ),
855    MENU_ITEM(0x2a,LANG_MENU_BADPIXEL_CREATE,         MENUITEM_PROC,      gui_menuproc_badpixel_create, 0 ),
856#endif
857    MENU_ITEM(0x5c,LANG_MENU_RAW_CACHED,              MENUITEM_BOOL,      &conf.raw_cache, 0 ),
858    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
859    {0}
860};
861static CMenu raw_submenu = {0x24,LANG_MENU_RAW_TITLE, NULL, raw_submenu_items };
862
863
864static const char* gui_zebra_mode_modes[] = { "Blink 1", "Blink 2", "Blink 3", "Solid", "Zebra 1", "Zebra 2" };
865static const char* gui_zebra_draw_osd_modes[] = { "Nothing", "Histo", "OSD" };
866static CMenuItem zebra_submenu_items[] = {
867    MENU_ITEM(0x5c,LANG_MENU_ZEBRA_DRAW,              MENUITEM_BOOL,                            &conf.zebra_draw, 0 ),
868    MENU_ENUM2(0x5f,LANG_MENU_ZEBRA_MODE,             &conf.zebra_mode, gui_zebra_mode_modes ),
869    MENU_ITEM(0x58,LANG_MENU_ZEBRA_UNDER,             MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.zebra_under,   MENU_MINMAX(0, 32) ),
870    MENU_ITEM(0x57,LANG_MENU_ZEBRA_OVER,              MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.zebra_over,    MENU_MINMAX(0, 32) ),
871    MENU_ITEM(0x28,LANG_MENU_ZEBRA_RESTORE_SCREEN,    MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,      &conf.zebra_restore_screen,     (int)cb_zebra_restore_screen ),
872    MENU_ITEM(0x5c,LANG_MENU_ZEBRA_RESTORE_OSD,       MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,      &conf.zebra_restore_osd,        (int)cb_zebra_restore_osd ),
873    MENU_ENUM2(0x5f,LANG_MENU_ZEBRA_DRAW_OVER,        &conf.zebra_draw_osd, gui_zebra_draw_osd_modes ),
874    MENU_ITEM(0x5c,LANG_MENU_ZEBRA_MULTICHANNEL,      MENUITEM_BOOL,                            &conf.zebra_multichannel, 0 ),
875    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
876    {0}
877};
878static CMenu zebra_submenu = {0x26,LANG_MENU_ZEBRA_TITLE, NULL, zebra_submenu_items };
879
880#ifdef OPT_CURVES
881static CMenuItem curve_submenu_items[] = {
882    MENU_ITEM(0x5f,LANG_MENU_CURVE_ENABLE,        MENUITEM_ENUM,      gui_conf_curve_enum, 0 ),
883    MENU_ITEM(0x35,LANG_MENU_CURVE_LOAD,          MENUITEM_PROC,      gui_load_curve, 0 ),
884    MENU_ITEM(0x51,LANG_MENU_BACK,                MENUITEM_UP, 0, 0 ),
885    {0}
886};
887static CMenu curve_submenu = {0x85,LANG_MENU_CURVE_PARAM_TITLE, NULL, curve_submenu_items };
888#endif
889
890static CMenuItem root_menu_items[] = {
891    MENU_ITEM(0x21,LANG_MENU_OPERATION_PARAM,         MENUITEM_SUBMENU,   &operation_submenu, 0 ),
892    MENU_ITEM(0x23,LANG_MENU_VIDEO_PARAM,             MENUITEM_SUBMENU,   &video_submenu, 0 ),
893    MENU_ITEM(0x24,LANG_MENU_MAIN_RAW_PARAM,          MENUITEM_SUBMENU,   &raw_submenu, 0 ),
894#ifdef OPT_EDGEOVERLAY
895    MENU_ITEM(0x7f,LANG_MENU_EDGE_OVERLAY,         MENUITEM_SUBMENU,   &edge_overlay_submenu, 0 ),
896#endif
897#ifdef OPT_CURVES
898    MENU_ITEM(0x85,LANG_MENU_CURVE_PARAM,             MENUITEM_SUBMENU,   &curve_submenu, 0 ),
899#endif
900    MENU_ITEM(0x25,LANG_MENU_MAIN_HISTO_PARAM,        MENUITEM_SUBMENU,   &histo_submenu, 0 ),
901    MENU_ITEM(0x26,LANG_MENU_MAIN_ZEBRA_PARAM,        MENUITEM_SUBMENU,   &zebra_submenu, 0 ),
902    MENU_ITEM(0x22,LANG_MENU_MAIN_OSD_PARAM,          MENUITEM_SUBMENU,   &osd_submenu, 0 ),
903    MENU_ITEM(0x28,LANG_MENU_MAIN_VISUAL_PARAM,       MENUITEM_SUBMENU,   &visual_submenu, 0 ),
904#ifdef OPT_SCRIPTING
905    MENU_ITEM(0x27,LANG_MENU_MAIN_SCRIPT_PARAM,       MENUITEM_SUBMENU,   &script_submenu, 0 ),
906#endif
907    MENU_ITEM(0x29,LANG_MENU_MAIN_MISC,               MENUITEM_SUBMENU,   &misc_submenu, 0 ),
908#ifndef OPTIONS_AUTOSAVE
909    MENU_ITEM(0x33,LANG_MENU_MAIN_SAVE_OPTIONS,       MENUITEM_PROC,      gui_menuproc_save, 0 ),
910#endif
911    {0}
912};
913
914static CMenu root_menu = {0x20,LANG_MENU_MAIN_TITLE, NULL, root_menu_items };
915
916static int gui_user_menu_flag;
917
918void rinit(){
919        // Erase screen if switching from user menu to main menu
920        // in case the user menu is larger than the main menu
921        // otherwise it leaves remnants of the user menu above and below
922        // the main menu.
923    draw_restore();
924        gui_menu_init(&root_menu);
925}
926
927//-------------------------------------------------------------------
928void
929mod_user_menu(CMenuItem curr_menu_item, int* cur_memnu_item_indx, int mod) {
930int i;
931CMenuItem tmp_menu_item;
932        switch(mod) {
933
934                case 0:
935                        /*
936                         * Delete user menu entry by sliding all the lower valid/existing entries up.
937                         */
938
939                        if (*cur_memnu_item_indx == 0) /* don't allow deleting "user menu" */
940                                break;
941                        for(i = *cur_memnu_item_indx; user_submenu_items[i].text; i++) {
942                                user_submenu_items[i] = user_submenu_items[i+1];
943                        }
944
945                        /*
946                         * there were no valid entries below this one, so
947                         * the index pointer must be decremented.
948                         */
949                        if(!user_submenu_items[*cur_memnu_item_indx].text)
950                                *cur_memnu_item_indx -= 1;
951
952                        break;
953
954                case 1:
955                        /*
956                         * Insert new Item at end of existing entries
957                         */
958                        for(i = 1; i < USER_MENU_ITEMS + 1; i++) {
959                                if(!user_submenu_items[i].text) {
960                                        user_submenu_items[i] = curr_menu_item;
961                                        break;
962                                }
963                        }
964                        break;
965
966                case 2:
967                        /*
968                         * Move entry up
969                         */
970
971                        if((*cur_memnu_item_indx > 1)) {
972                                tmp_menu_item = user_submenu_items[*cur_memnu_item_indx -1];
973                                user_submenu_items[*cur_memnu_item_indx -1] = user_submenu_items[*cur_memnu_item_indx];
974                                user_submenu_items[*cur_memnu_item_indx] = tmp_menu_item;
975                                *cur_memnu_item_indx -=1;
976                        }
977                        break;
978
979                case 3:
980                        /*
981                         * Move entry down below next entry if next entry is not empty
982                         */
983                        if (*cur_memnu_item_indx == 0) /* don't allow moving "user menu" */
984                                break;
985                        if((*cur_memnu_item_indx < (USER_MENU_ITEMS)) && (user_submenu_items[*cur_memnu_item_indx +1].text)) {
986                                tmp_menu_item = user_submenu_items[*cur_memnu_item_indx +1];
987                                user_submenu_items[*cur_memnu_item_indx + 1] = user_submenu_items[*cur_memnu_item_indx];
988                                user_submenu_items[*cur_memnu_item_indx] = tmp_menu_item;
989                                *cur_memnu_item_indx +=1;
990                        }
991                        break;
992
993        }
994}
995
996//-------------------------------------------------------------------
997void cb_step_25() {
998    voltage_step = (conf.batt_step_25)?25:1;
999}
1000
1001void cb_perc() {
1002    conf.batt_volts_show=0;
1003}
1004
1005void cb_volts() {
1006    conf.batt_perc_show=0;
1007}
1008
1009void cb_space_perc() {
1010    conf.space_mb_show=0;
1011}
1012
1013void cb_space_mb() {
1014    conf.space_perc_show=0;
1015}
1016
1017void cb_battery_menu_change(unsigned int item) {
1018    switch (item) {
1019        case 0: //Voltage MAX
1020            if (conf.batt_volts_max<conf.batt_volts_min+25) {
1021                conf.batt_volts_min = conf.batt_volts_max-25;
1022            }
1023            break;
1024        case 1: //Voltage MIN
1025            if (conf.batt_volts_min>conf.batt_volts_max-25) {
1026                conf.batt_volts_max = conf.batt_volts_min+25;
1027            }
1028            break;
1029        default:
1030            break;
1031    }
1032}
1033
1034void cb_zebra_restore_screen() {
1035    if (!conf.zebra_restore_screen)
1036        conf.zebra_restore_osd = 0;
1037}
1038
1039void cb_zebra_restore_osd() {
1040    if (conf.zebra_restore_osd)
1041        conf.zebra_restore_screen = 1;
1042}
1043
1044#if DNG_SUPPORT
1045void cb_change_dng(){
1046 int old=conf.dng_raw;
1047 conf_change_dng();
1048 if ((old==1) && (conf.dng_raw==0)) gui_mbox_init(LANG_ERROR, LANG_CANNOT_OPEN_BADPIXEL_FILE, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
1049}
1050
1051void gui_menuproc_badpixel_create(int arg) {
1052    create_badpixel_bin();
1053}
1054#endif
1055
1056#if defined (DNG_EXT_FROM)
1057void cb_change_dng_usb_ext(){
1058 if (conf.dng_usb_ext) change_ext_to_dng(); else change_ext_to_default();
1059}
1060#endif
1061
1062/*
1063common code for "enum" menu items that just take a list of string values and don't require any special setters
1064would be better to have another menu item type that does this by default
1065save memory by eliminating dupe code
1066*/
1067static void gui_enum_value_change(int *value, int change, unsigned num_items) {
1068    *value+=change;
1069    if (*value<0)
1070        *value = num_items-1;
1071    else if (*value>=num_items)
1072        *value = 0;
1073}
1074static const char* gui_change_simple_enum(int* value, int change, const char** items, unsigned num_items) {
1075        gui_enum_value_change(value, change, num_items);
1076    return items[*value];
1077}
1078const char* gui_change_enum2(const CMenuItem *menu_item, int change)
1079{
1080    const char** items = (const char**)menu_item->arg;
1081        gui_enum_value_change(menu_item->value, change, menu_item->opt_len);
1082    return items[*menu_item->value];
1083}
1084
1085//-------------------------------------------------------------------
1086#ifdef OPT_CURVES
1087const char* gui_conf_curve_enum(int change, int arg) {
1088    static const char* modes[]={ "None", "Custom", "+1EV", "+2EV", "Auto DR" };
1089
1090    gui_enum_value_change(&conf.curve_enable,change,sizeof(modes)/sizeof(modes[0]));
1091
1092        if(change)
1093                curve_init_mode();
1094    return modes[conf.curve_enable];
1095}
1096#endif
1097
1098#ifdef OPT_SCRIPTING
1099//-------------------------------------------------------------------
1100const char* gui_script_param_set_enum(int change, int arg) {
1101    static const char* modes[]={ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
1102
1103    if (change != 0) {
1104        if (conf.script_param_save) {
1105            save_params_values(0);
1106        }
1107                gui_enum_value_change(&conf.script_param_set,change,sizeof(modes)/sizeof(modes[0]));
1108
1109        if (!load_params_values(conf.script_file, 1, 0))
1110            script_load(conf.script_file, 0);
1111        gui_update_script_submenu();
1112    }
1113
1114    return modes[conf.script_param_set];
1115}
1116
1117//-------------------------------------------------------------------
1118void gui_update_script_submenu() {
1119    register int p=0, i;
1120
1121    for (i=0; i<sizeof(script_submenu_items_top)/sizeof(script_submenu_items_top[0]); ++p, ++i) {
1122        script_submenu_items[p]=script_submenu_items_top[i];
1123    }
1124    for (i=0; i<SCRIPT_NUM_PARAMS; ++i) {
1125        if (script_param_order[i]) {
1126            script_submenu_items[p].symbol=0x0;
1127            script_submenu_items[p].text=(int)script_params[script_param_order[i]-1];
1128            script_submenu_items[p].type=MENUITEM_INT;
1129            script_submenu_items[p].value=&conf.ubasic_vars[script_param_order[i]-1];
1130            ++p;
1131        }
1132    }
1133    for (i=0; i<sizeof(script_submenu_items_bottom)/sizeof(script_submenu_items_bottom[0]); ++p, ++i) {
1134        script_submenu_items[p]=script_submenu_items_bottom[i];
1135    }
1136}
1137
1138//-------------------------------------------------------------------
1139static void gui_load_script_selected(const char *fn) {
1140    if (fn)
1141        script_load(fn, 1);
1142}
1143
1144void gui_load_script(int arg) {
1145    DIR   *d;
1146    char  *path="A/CHDK/SCRIPTS";
1147
1148    // if exists "A/CHDK/SCRIPTS" go into
1149    d=opendir(path);
1150    if (d) {
1151        closedir(d);
1152    } else {
1153        path="A";
1154    }
1155
1156    gui_fselect_init(LANG_STR_SELECT_SCRIPT_FILE, path, gui_load_script_selected);
1157}
1158
1159void gui_load_script_default(int arg) {
1160    script_load(conf.script_file, 0);
1161    if (conf.script_param_save) {
1162        save_params_values(1);
1163    }
1164}
1165#endif
1166
1167//-------------------------------------------------------------------
1168const char* gui_override_disable_enum(int change, int arg) {
1169        return gui_change_simple_enum(&conf.override_disable,change,gui_override_disable_modes,sizeof(gui_override_disable_modes)/sizeof(gui_override_disable_modes[0]));
1170}
1171
1172//-------------------------------------------------------------------
1173const char* gui_histo_mode_enum(int change, int arg) {
1174    static const char* modes[]={ "Linear", "Log" };
1175
1176        gui_enum_value_change(&conf.histo_mode,change,sizeof(modes)/sizeof(modes[0]));
1177
1178    histogram_set_mode(conf.histo_mode);
1179
1180    return modes[conf.histo_mode];
1181}
1182
1183//-------------------------------------------------------------------
1184const char* gui_histo_layout_enum(int change, int arg) {
1185    static const char* modes[]={ "RGB", "Y", "RGB Y",  "R G B", "RGB all", "Y all", "Blend", "Blend Y"};
1186
1187        gui_enum_value_change(&conf.histo_layout,change,sizeof(modes)/sizeof(modes[0]));
1188
1189    if (conf.histo_layout==OSD_HISTO_LAYOUT_Y || conf.histo_layout==OSD_HISTO_LAYOUT_Y_argb) {
1190        histogram_set_main(HISTO_Y);
1191    } else {
1192        histogram_set_main(HISTO_RGB);
1193    }
1194
1195    return modes[conf.histo_layout];
1196}
1197
1198//-------------------------------------------------------------------
1199const char* gui_font_enum(int change, int arg) {
1200    static const char* fonts[]={ "Win1250", "Win1251", "Win1252", "Win1253", "Win1254", "Win1257"};
1201
1202        gui_enum_value_change(&conf.font_cp,change,sizeof(fonts)/sizeof(fonts[0]));
1203
1204    if (change != 0) {
1205        font_set(conf.font_cp);
1206        if (!rbf_load(conf.menu_rbf_file))
1207            rbf_load_from_8x16(current_font);
1208        rbf_set_codepage(FONT_CP_WIN);
1209        gui_menu_init(NULL);
1210    }
1211
1212    return fonts[conf.font_cp];
1213}
1214
1215//-------------------------------------------------------------------
1216#ifdef  CAM_TOUCHSCREEN_UI
1217
1218const char* gui_on_off_enum(int change, int *conf_val)
1219{
1220    static const char* modes[]={ "Off", "On"};
1221        return gui_change_simple_enum(conf_val,change,modes,sizeof(modes)/sizeof(modes[0]));
1222}
1223
1224#endif
1225
1226//-------------------------------------------------------------------
1227const char* gui_nd_filter_state_enum(int change, int arg) {
1228        return gui_change_simple_enum(&conf.nd_filter_state,change,gui_nd_filter_state_modes,sizeof(gui_nd_filter_state_modes)/sizeof(gui_nd_filter_state_modes[0]));
1229}
1230
1231const char* gui_histo_show_enum(int change, int arg) {
1232        return gui_change_simple_enum(&conf.show_histo,change,gui_histo_show_modes,sizeof(gui_histo_show_modes)/sizeof(gui_histo_show_modes[0]));
1233}
1234
1235//-------------------------------------------------------------------
1236#if CAM_ADJUSTABLE_ALT_BUTTON
1237const char* gui_alt_mode_button_enum(int change, int arg) {
1238#if defined(CAMERA_s2is) || defined(CAMERA_s3is) || defined(CAMERA_s5is)
1239    static const char* names[]={ "Shrtcut", "Flash", "Timer", "ISO", "Video" };
1240    static const int keys[]={ KEY_PRINT, KEY_FLASH, KEY_TIMER, KEY_ISO, KEY_VIDEO };
1241#elif defined(CAMERA_g7) || defined(CAMERA_g9)
1242    static const char* names[]={ "Print", "FE"};
1243    static const int keys[]={ KEY_PRINT, KEY_MICROPHONE };
1244#elif defined(CAMERA_g10) || defined(CAMERA_g12) 
1245    static const char* names[]={ "Print", "Disp",  "AE Lock", "Jump" };
1246    static const int keys[]={ KEY_PRINT, KEY_DISPLAY, KEY_AE_LOCK, KEY_METERING};
1247#elif defined(CAMERA_g11)
1248    static const char* names[]={ "Print", "Disp",  "AE Lock", "Jump" };
1249    static const int keys[]={ KEY_PRINT, KEY_DISPLAY, KEY_MICROPHONE, KEY_METERING};   
1250#elif defined(CAMERA_ixus65_sd630)
1251    static const char* names[]={ "Print", "Disp"};
1252    static const int keys[]={ KEY_PRINT, KEY_DISPLAY };
1253#elif defined(CAMERA_a650)
1254    static const char* names[]={ "Print", "ISO"};
1255    static const int keys[]={ KEY_PRINT, KEY_ISO };
1256#elif defined(CAMERA_sx100is) || defined(CAMERA_sx110is)
1257    static const char* names[]={ "Print", "Face"};
1258    static const int keys[]={ KEY_PRINT, KEY_FACE };
1259#elif defined(CAMERA_sx10) || defined(CAMERA_sx1) || defined(CAMERA_sx20) || defined(CAMERA_sx30) || defined(CAMERA_sx40hs)
1260    static const char* names[]={ "Shrtcut", "Flash", "Video"};
1261    static const int keys[]={ KEY_PRINT, KEY_FLASH, KEY_VIDEO };
1262#elif defined(CAMERA_a570) || defined(CAMERA_a580) || defined(CAMERA_a590) || defined(CAMERA_a720)
1263    static const char* names[]={ "Print", "Display"};
1264    static const int keys[] = {KEY_PRINT, KEY_DISPLAY};
1265#elif defined(CAMERA_sx220hs) || defined(CAMERA_sx230hs)
1266    static const char* names[]={ "Disp+Set", "Display", "Playback", "Video"};
1267    static const int keys[] = {KEY_PRINT, KEY_DISPLAY, KEY_PLAYBACK, KEY_VIDEO};
1268#else
1269    #error camera alt-buttons not defined
1270#endif
1271    int i;
1272
1273    for (i=0; i<sizeof(names)/sizeof(names[0]); ++i) {
1274        if (conf.alt_mode_button==keys[i]) {
1275            break;
1276        }
1277    }
1278
1279    i+=change;
1280    if (i<0)
1281        i=(sizeof(names)/sizeof(names[0]))-1;
1282    else if (i>=(sizeof(names)/sizeof(names[0])))
1283        i=0;
1284
1285    conf.alt_mode_button = keys[i];
1286    kbd_set_alt_mode_key_mask(conf.alt_mode_button);
1287    return names[i];
1288}
1289#endif
1290
1291//-------------------------------------------------------------------
1292const char* gui_alt_power_enum(int change, int arg) {
1293// Script option is retained even if scripting is disabled, otherwise conf values will change
1294// Equivalent to ALT
1295    static const char* modes[]={ "Never", "Alt", "Script", "Always" };
1296        gui_enum_value_change(&conf.alt_prevent_shutdown,change,sizeof(modes)/sizeof(modes[0]));
1297
1298        conf_update_prevent_shutdown();
1299
1300    return modes[conf.alt_prevent_shutdown];
1301}
1302
1303//-------------------------------------------------------------------
1304const char* gui_video_bitrate_enum(int change, int arg) {
1305        gui_enum_value_change(&conf.video_bitrate,change,VIDEO_BITRATE_STEPS);
1306
1307    shooting_video_bitrate_change(conf.video_bitrate);
1308
1309    return video_bitrate_strings[conf.video_bitrate];
1310}
1311
1312
1313//-------------------------------------------------------------------
1314const char* gui_tv_override_koef_enum(int change, int arg) {
1315    static const char* modes[]={"Off", "1/100K", "1/10000", "1/1000","1/100","1/10", "1","10","100"};
1316
1317    conf.tv_override_koef+=change;
1318   if (conf.tv_enum_type) {
1319     if (conf.tv_override_koef<0)  conf.tv_override_koef=6;
1320     else if (conf.tv_override_koef>6) conf.tv_override_koef=0;
1321     else if (conf.tv_override_koef==1)  conf.tv_override_koef=6;
1322     else if (conf.tv_override_koef==5)  conf.tv_override_koef=0;
1323     else if (conf.tv_override_koef!=0 && conf.tv_override_koef!=6) conf.tv_override_koef=6;
1324     }
1325   else {
1326    if (conf.tv_override_koef<0)
1327        conf.tv_override_koef=sizeof(modes)/sizeof(modes[0])-1;
1328    else if (conf.tv_override_koef>=(sizeof(modes)/sizeof(modes[0])))
1329        conf.tv_override_koef=0;
1330    }
1331
1332    return modes[conf.tv_override_koef];
1333}
1334
1335const char* gui_tv_override_value_enum(int change, int arg) {
1336        /*
1337    static const char* modes[]={
1338    // add very long time exposures as approximately powers of 2, adding 15 exposures
1339    "2048","1625","1290","1024","812","645","512","406","322","256","203","161","128","101","80",
1340                "64","50.8", "40.3", "32", "25.4","20","16", "12.7", "10","8", "6.3","5","4","3.2", "2.5","2", "1.6", "1.3", "1", "0.8", "0.6", "0.5", "0.4", "0.3", "1/4", "1/5", "1/6", "1/8", "1/10", "1/13", "1/15", "1/20", "1/25", "1/30", "1/40", "1/50", "1/60", "1/80", "1/100", "1/125", "1/160", "1/200", "1/250", "1/320", "1/400", "1/500", "1/640","1/800", "1/1000", "1/1250", "1/1600","1/2000","1/2500","1/3200","1/4000", "1/5000", "1/6400", "1/8000", "1/10000", "1/12500", "1/16000", "1/20000", "1/25000", "1/32000", "1/40000", "1/50000", "1/64000","1/80000", "1/100k"};
1341                */
1342    static char *buf;
1343
1344        // XXX This array above is redundant with platform/generic/shooting.c, this should be avoided!
1345    conf.tv_override_value+=change;
1346    if (conf.tv_enum_type) {
1347       if (conf.tv_override_value<0) {
1348          conf.tv_override_value=tv_override_amount-1;
1349        }
1350       else if ((unsigned)conf.tv_override_value>=(tv_override_amount))
1351         conf.tv_override_value=0;
1352       return tv_override[conf.tv_override_value];
1353     }
1354     else
1355      {
1356       if (conf.tv_override_value<0) {
1357          conf.tv_override_value=100;
1358        }
1359       else if (conf.tv_override_value>100)  conf.tv_override_value=0;
1360       if(!buf) buf=malloc(4);
1361       if(!buf) return "";
1362       sprintf(buf, "%d",  conf.tv_override_value);
1363       return buf;
1364      }
1365}
1366
1367const char* gui_tv_enum_type_enum(int change, int arg) {
1368    static const char* modes[]={"Factor", "Ev Step"};
1369
1370    gui_enum_value_change(&conf.tv_enum_type,change,sizeof(modes)/sizeof(modes[0]));
1371    if (change) {
1372        conf.tv_override_koef=6;
1373        if (conf.tv_enum_type)
1374            conf.tv_override_value=tv_override_zero_shift;
1375        else conf.tv_override_value=1;
1376    }
1377    return modes[conf.tv_enum_type];
1378}
1379
1380const char* gui_subj_dist_override_value_enum(int change, int arg) {
1381        static const int koef[] = {0, 1,10,100,1000};
1382    static char buf[8];
1383    conf.subj_dist_override_value+=(change*koef[conf.subj_dist_override_koef]);
1384    if (conf.subj_dist_override_value<0)
1385        conf.subj_dist_override_value=MAX_DIST;
1386    else if (conf.subj_dist_override_value>MAX_DIST)
1387        conf.subj_dist_override_value=0;
1388    sprintf(buf, "%d", (int)conf.subj_dist_override_value);
1389    return buf;
1390}
1391
1392
1393const char* gui_subj_dist_override_koef_enum(int change, int arg) {
1394        return gui_change_simple_enum(&conf.subj_dist_override_koef,change,gui_override_koef_modes,sizeof(gui_override_koef_modes)/sizeof(gui_override_koef_modes[0]));
1395}
1396
1397/*
1398const char* gui_tv_exposure_order_enum(int change, int arg) {
1399    static const char* modes[]={ "Off", "1","2", "3"};
1400
1401    conf.tv_exposure_order+=change;
1402    if (conf.tv_exposure_order<0)
1403        conf.tv_exposure_order=0;
1404    else if (conf.tv_exposure_order>=(sizeof(modes)/sizeof(modes[0])))
1405        conf.tv_exposure_order=sizeof(modes)/sizeof(modes[0])-1;
1406    if((conf.tv_exposure_order>0) && (conf.av_exposure_order==conf.tv_exposure_order))
1407     {
1408       conf.av_exposure_order=0;
1409     }
1410    if((conf.tv_exposure_order>0) && (conf.iso_exposure_order==conf.tv_exposure_order))
1411     {
1412       conf.iso_exposure_order=0;
1413     }
1414
1415    return modes[conf.tv_exposure_order];
1416}
1417
1418const char* gui_av_exposure_order_enum(int change, int arg) {
1419    static const char* modes[]={ "Off", "1","2", "3"};
1420
1421    conf.av_exposure_order+=change;
1422    if (conf.av_exposure_order<0)
1423        conf.av_exposure_order=0;
1424    else if (conf.av_exposure_order>=(sizeof(modes)/sizeof(modes[0])))
1425        conf.av_exposure_order=sizeof(modes)/sizeof(modes[0])-1;
1426    if((conf.av_exposure_order>0) && (conf.tv_exposure_order==conf.av_exposure_order))
1427     {
1428       conf.tv_exposure_order=0;
1429     }
1430    if((conf.av_exposure_order>0) && (conf.iso_exposure_order==conf.av_exposure_order))
1431     {
1432       conf.iso_exposure_order=0;
1433     }
1434    return modes[conf.av_exposure_order];
1435}
1436
1437const char* gui_iso_exposure_order_enum(int change, int arg) {
1438    static const char* modes[]={ "Off", "1","2", "3"};
1439
1440    conf.iso_exposure_order+=change;
1441    if (conf.iso_exposure_order<0)
1442        conf.iso_exposure_order=0;
1443    else if (conf.iso_exposure_order>=(sizeof(modes)/sizeof(modes[0])))
1444        conf.iso_exposure_order=sizeof(modes)/sizeof(modes[0])-1;
1445    if((conf.iso_exposure_order>0) && (conf.tv_exposure_order==conf.iso_exposure_order))
1446     {
1447       conf.tv_exposure_order=0;
1448     }
1449    if((conf.iso_exposure_order>0) && (conf.av_exposure_order==conf.iso_exposure_order))
1450     {
1451       conf.av_exposure_order=0;
1452     }
1453
1454    return modes[conf.iso_exposure_order];
1455}
1456*/
1457const char* gui_av_override_enum(int change, int arg) {
1458    static char buf[8];
1459    short prop_id;
1460    conf.av_override_value+=change;
1461    if (conf.av_override_value<0) conf.av_override_value=shooting_get_aperture_sizes_table_size()+6;
1462    else if (conf.av_override_value>shooting_get_aperture_sizes_table_size()+6) conf.av_override_value=0;
1463    if (conf.av_override_value == 0)  return "Off";
1464    else {
1465     short prop_id=shooting_get_aperture_from_av96(shooting_get_av96_override_value());
1466         sprintf(buf, "%d.%02d", (int)prop_id/100, (int)prop_id%100 );
1467         return buf;
1468        }
1469}
1470
1471#if ZOOM_OVERRIDE
1472const char* gui_zoom_override_enum(int change, int arg) {
1473    static char buf[3];
1474    conf.zoom_override_value+=change;
1475    if (conf.zoom_override_value<0) conf.zoom_override_value=zoom_points-1;
1476    else if (conf.zoom_override_value>zoom_points-1) conf.zoom_override_value=0;
1477                sprintf(buf,"%i",conf.zoom_override_value);
1478                return buf;
1479}
1480#endif
1481
1482const char* gui_user_menu_show_enum(int change, int arg) {
1483    static const char* modes[]={ "Off", "On","On Direct", "Edit" };
1484
1485        if (conf.user_menu_enable == 3) user_menu_save();
1486        return gui_change_simple_enum(&conf.user_menu_enable,change,modes,sizeof(modes)/sizeof(modes[0]));
1487}
1488
1489const char* gui_video_af_key_enum(int change, int arg){
1490#if CAMERA_g12
1491    static const char* names[]={ "", "Shutter", "Set", "AE Lock"};
1492    static const int keys[]={0, KEY_SHOOT_HALF, KEY_SET, KEY_AE_LOCK };
1493#else
1494    static const char* names[]={ "", "Shutter", "Set"};
1495    static const int keys[]={0, KEY_SHOOT_HALF, KEY_SET };
1496#endif
1497    int i;
1498
1499    for (i=0; i<sizeof(names)/sizeof(names[0]); ++i) {
1500        if (conf.video_af_key==keys[i]) {
1501            break;
1502        }
1503    }
1504
1505    i+=change;
1506    if (i<0)
1507        i=(sizeof(names)/sizeof(names[0]))-1;
1508    else if (i>=(sizeof(names)/sizeof(names[0])))
1509        i=0;
1510
1511    conf.video_af_key = keys[i];
1512    return names[i];
1513}
1514
1515const char* gui_bad_pixel_enum(int change, int arg) {
1516    int modes[]={LANG_MENU_BAD_PIXEL_OFF, LANG_MENU_BAD_PIXEL_INTERPOLATION, LANG_MENU_BAD_PIXEL_RAW_CONVERTER};
1517        return lang_str((int)gui_change_simple_enum(&conf.bad_pixel_removal,change,(const char **)modes,sizeof(modes)/sizeof(modes[0])));
1518}
1519
1520//-------------------------------------------------------------------
1521
1522void raw_fselect_cb(const char * filename){
1523 struct stat st;
1524 if (!filename) return;
1525 stat((char*)filename,&st);
1526 if (st.st_size!=hook_raw_size()) return;
1527 gui_mbox_init((int)"", LANG_RAW_DEVELOP_MESSAGE, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
1528 raw_prepare_develop((char*)filename);
1529}
1530
1531//-------------------------------------------------------------------
1532void gui_raw_develop(int arg){
1533 int m=mode_get();
1534 gui_fselect_init(LANG_RAW_DEVELOP_SELECT_FILE, "A/DCIM", raw_fselect_cb);
1535}
1536
1537//-------------------------------------------------------------------
1538
1539static void gui_menuproc_reset_files(int arg){
1540conf.lang_file[0] = 0;
1541conf.menu_symbol_rbf_file[0] = 0;
1542conf.menu_rbf_file[0] = 0;
1543conf_save();
1544gui_mbox_init(LANG_INFORMATION, LANG_MENU_RESTART_CAMERA, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
1545
1546}
1547
1548//-------------------------------------------------------------------
1549#ifdef OPT_DEBUGGING
1550#define TASKLIST_MAX_LINES 12 // probably as much as will fit on screen
1551#define TASKLIST_NUM_TASKS 64 // should be enough ?
1552static void gui_debug_draw_tasklist(void) {
1553#ifndef CAM_DRYOS
1554    int tasklist[TASKLIST_NUM_TASKS]; // max number of tasks we will look at
1555    char buf[40]; // a single line of the list
1556    int n_tasks,n_show_tasks,show_start;
1557    const char *name;
1558    int i;
1559    n_tasks = task_id_list_get(tasklist,sizeof(tasklist)/sizeof(tasklist[0]));
1560    show_start = debug_tasklist_start;
1561    n_show_tasks = n_tasks - show_start;
1562    // auto adjust to show the last N tasks
1563    if(n_show_tasks < TASKLIST_MAX_LINES) {
1564        show_start = n_tasks - TASKLIST_MAX_LINES;
1565        if(show_start<0)
1566            show_start = 0;
1567         n_show_tasks = n_tasks - show_start;
1568    }
1569    else if( n_show_tasks > TASKLIST_MAX_LINES ) {
1570        n_show_tasks = TASKLIST_MAX_LINES;
1571    }
1572    sprintf(buf,"%d-%d of %d tasks %c",show_start,show_start+n_show_tasks,n_tasks,debug_display_direction > 0?'+':'-');
1573    draw_string(64,0,buf, conf.osd_color);
1574    for( i = 0;  i < n_show_tasks; i++ ) {
1575        // TODO get full task info
1576        name = task_name(tasklist[show_start+i]);
1577        if ( !name || !*name ) {
1578            name = "(unknown)";
1579        }
1580        sprintf(buf,"%10s %8X",name,tasklist[show_start+i]);
1581        draw_string(64,16+16*i,buf, conf.osd_color);
1582    }
1583#endif //CAM_DRYOS
1584}
1585
1586#define DEBUG_DISPLAY_NONE 0
1587#define DEBUG_DISPLAY_PROPS 1
1588#define DEBUG_DISPLAY_PARAMS 2
1589#define DEBUG_DISPLAY_TASKS 3
1590
1591static void gui_debug_shortcut(void) {
1592    static int lastcall = -1;
1593    int t=get_tick_count();
1594    if ( lastcall != -1) {
1595        if (t-lastcall <= 400)
1596            debug_display_direction = -debug_display_direction;
1597    }
1598    lastcall=t;
1599    switch(conf.debug_shortcut_action) {
1600        case 1:
1601            dump_memory();
1602        break;
1603        case 2:
1604            if(conf.debug_display == DEBUG_DISPLAY_TASKS) {
1605                debug_tasklist_start += debug_display_direction*(TASKLIST_MAX_LINES-2); // a little intentional overlap
1606                if(debug_tasklist_start >= TASKLIST_NUM_TASKS || debug_tasklist_start < 0)
1607                    debug_tasklist_start = 0;
1608            }
1609            else if (conf.debug_display == DEBUG_DISPLAY_PROPS || conf.debug_display == DEBUG_DISPLAY_PARAMS) {
1610                conf.debug_propcase_page += debug_display_direction*1;
1611                if(conf.debug_propcase_page > 128 || conf.debug_propcase_page < 0)
1612                    conf.debug_propcase_page = 0;
1613            }
1614        break;
1615        case 3:
1616            gui_compare_props(1);
1617        break;
1618    }
1619}
1620
1621//-------------------------------------------------------------------
1622#endif
1623
1624#if CAM_MULTIPART
1625void card_break_proc(unsigned int btn){
1626 if (btn==MBOX_BTN_YES) create_partitions();
1627}
1628
1629
1630#ifdef OPT_DEBUGGING
1631static void gui_menuproc_break_card(int arg){
1632 gui_mbox_init(LANG_WARNING, LANG_PARTITIONS_CREATE_WARNING, MBOX_BTN_YES_NO|MBOX_DEF_BTN2|MBOX_TEXT_CENTER, card_break_proc);
1633}
1634#endif
1635
1636static void gui_menuproc_swap_partitions(int arg){
1637 if (get_part_count()<2) gui_mbox_init(LANG_ERROR, LANG_ONLY_ONE_PARTITION, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
1638 else
1639        {
1640                swap_partitions();
1641                gui_mbox_init(LANG_INFORMATION, LANG_SOKOBAN_MSG_FINISH_TITLE, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
1642        }
1643}
1644#endif
1645
1646//-------------------------------------------------------------------
1647static volatile enum Gui_Mode gui_mode;
1648static volatile int gui_restore;
1649static volatile int gui_in_redraw;
1650static int gui_splash, gui_splash_mode;
1651static char osd_buf[32];
1652#ifdef OPTIONS_AUTOSAVE
1653static Conf old_conf;
1654#endif
1655
1656//-------------------------------------------------------------------
1657void gui_init()
1658{
1659    gui_set_mode(GUI_MODE_NONE);
1660    gui_restore = 0;
1661    gui_in_redraw = 0;
1662    if (conf.start_sound>0)
1663    {
1664        play_sound(4);
1665    }
1666    gui_splash = (conf.splash_show)?SPLASH_TIME:0;
1667    user_menu_restore();
1668    gui_lang_init();
1669    draw_init();
1670
1671    exposition_thresh = screen_size/500;
1672    voltage_step = (conf.batt_step_25)?25:1;
1673    load_bad_pixels_list("A/CHDK/badpixel");
1674    load_bad_pixels_list("A/CHDK/badpixel.txt");
1675#ifdef OPT_CURVES
1676        // initialize curves, loading files if required by current mode
1677        curve_init_mode();
1678#endif
1679#if ZOOM_OVERRIDE
1680// reyalp - need to do this in capt_seq
1681//              if (conf.zoom_override) shooting_set_zoom(conf.zoom_override_value);
1682#endif
1683}
1684
1685//-------------------------------------------------------------------
1686#ifdef OPT_CURVES
1687static void gui_load_curve_selected(const char *fn) {
1688        if (fn) {
1689                // TODO we could sanity check here, but curve_set_type should fail gracefullish
1690                strcpy(conf.curve_file,fn);
1691                if(conf.curve_enable == 1)
1692                        curve_init_mode();
1693        }
1694}
1695
1696//-------------------------------------------------------------------
1697void gui_load_curve(int arg) {
1698    DIR   *d;
1699    char  *path = CURVE_DIR;
1700
1701    // if exists CURVE_DIR go into
1702    d=opendir(path);
1703    if (d) {
1704        closedir(d);
1705    } else {
1706        path="A";
1707    }
1708
1709    gui_fselect_init(LANG_STR_SELECT_CURVE_FILE, path, gui_load_curve_selected);
1710}
1711
1712#endif
1713//-------------------------------------------------------------------
1714enum Gui_Mode gui_get_mode() {
1715    return gui_mode;
1716}
1717
1718//-------------------------------------------------------------------
1719void gui_set_mode(enum Gui_Mode mode) {
1720#ifdef CAM_TOUCHSCREEN_UI
1721    if (((gui_mode == 0) != (mode == 0)) ||                         // Change from GUI_MODE_NONE to any other or vice-versa
1722        ((gui_mode > GUI_MODE_MENU) != (mode > GUI_MODE_MENU)))     // Switch in & out of menu mode
1723        redraw_buttons = 1;
1724#endif
1725    gui_mode = mode;
1726}
1727
1728//-------------------------------------------------------------------
1729void gui_force_restore() {
1730    gui_restore = gui_in_redraw;
1731}
1732
1733static void gui_handle_splash(void) {
1734        static char *logo = NULL;
1735    static int logo_size;
1736    if (gui_splash) {
1737                static int need_logo=1; // don't use logo ptr, since we don't want to keep re-trying
1738                if(need_logo) {
1739                const char *logo_name="A/CHDK/DATA/logo.dat";
1740            FILE *fd;
1741            struct stat st;
1742                        need_logo=0;
1743            if (stat(logo_name,&st) == 0) {
1744                                logo_size=st.st_size;
1745                                logo=malloc(logo_size);
1746                                if(logo) {
1747                                        fd = fopen(logo_name, "rb");
1748                                        if(fd){
1749                                                fread(logo,1,logo_size,fd);
1750                                                fclose(fd);
1751                                        }
1752                                        else {
1753                                                free(logo);
1754                                                logo=NULL;
1755                                        }
1756                }
1757                        }
1758                }
1759        if (gui_splash>(SPLASH_TIME-4)) {
1760            gui_draw_splash(logo,logo_size);
1761           //   conf.show_osd = 0;
1762        } else if (gui_splash==1 && (mode_get()&MODE_MASK) == gui_splash_mode && (gui_mode==GUI_MODE_NONE || gui_mode==GUI_MODE_ALT)) {
1763            draw_restore();
1764           // conf.show_osd = 1; //had to uncomment in order to fix a bug with disappearing osd...
1765        }
1766        --gui_splash;
1767                if(!gui_splash) {
1768                        free(logo);
1769                }
1770    }
1771}
1772
1773//-------------------------------------------------------------------
1774#ifdef OPTIONS_AUTOSAVE
1775
1776static void conf_store_old_settings() {
1777    old_conf=conf;
1778}
1779
1780static int conf_save_new_settings_if_changed() {
1781    if (memcmp(&old_conf, &conf, sizeof(Conf)) != 0) {
1782                user_menu_save();
1783        conf_save();
1784        conf_store_old_settings();
1785        return 1;
1786    }
1787    return 0;
1788}
1789
1790#endif
1791
1792//-------------------------------------------------------------------
1793void gui_chdk_draw()
1794{
1795    static int show_md_grid=0;
1796
1797    gui_draw_osd();
1798
1799#ifdef CAM_DISP_ALT_TEXT
1800    draw_txt_string(20, 14, "<ALT>", MAKE_COLOR(COLOR_ALT_BG, COLOR_FG));
1801#endif
1802
1803#ifdef OPT_SCRIPTING
1804    if ((mode_get()&MODE_MASK) == MODE_REC)
1805    {
1806        draw_txt_string(0, 14, script_title, MAKE_COLOR(COLOR_ALT_BG, COLOR_FG));
1807        if (state_kbd_script_run) show_md_grid=5;
1808        if (show_md_grid)
1809        {
1810            --show_md_grid;
1811            md_draw_grid();
1812        }
1813    }
1814#endif
1815
1816    console_draw();
1817}
1818
1819//-------------------------------------------------------------------
1820// Handler for Menu button press default - enter Menu mode
1821void gui_default_kbd_process_menu_btn()
1822{
1823    gui_set_mode(GUI_MODE_MENU);
1824    draw_restore();
1825}
1826
1827// Change SD override factor, direction = 1 to increase, -1 to decrease
1828// Only applies if camera has a Zoom lever
1829#if CAM_HAS_ZOOM_LEVER
1830static void sd_override_koef(int direction)
1831{
1832    gui_subj_dist_override_koef_enum(direction,0);
1833#if !CAM_HAS_MANUAL_FOCUS
1834    if (conf.subj_dist_override_koef==0) conf.subj_dist_override_koef=1;
1835#endif
1836    shooting_set_focus(shooting_get_subject_distance_override_value(), SET_NOW);
1837}
1838#endif
1839
1840// Change SD override by factor amount, direction = 1 to increase (zoom in), -1 to decrease (zoom out)
1841static void sd_override(int direction)
1842{
1843    gui_subj_dist_override_value_enum(direction,0);
1844    shooting_set_focus(shooting_get_subject_distance_override_value(),SET_NOW);
1845}
1846
1847// Main button processing for CHDK Alt mode (not in MENU mode)
1848// This needs to be cleaned up, re-organised and commented !!!!
1849void gui_chdk_kbd_process()
1850{
1851#if !CAM_HAS_ERASE_BUTTON && CAM_CAN_SD_OVERRIDE        // ALT RAW toggle kbd processing if camera has SD override but no erase button
1852    if (kbd_is_key_clicked(SHORTCUT_TOGGLE_RAW))
1853    {
1854        if (conf.debug_shortcut_action > 0)
1855        {
1856#ifdef OPT_DEBUGGING
1857            gui_debug_shortcut();
1858#endif
1859        }
1860        // Check in manual focus mode
1861        else if (!shooting_get_common_focus_mode())
1862        {
1863            // Not manual focus mode so just update RAW save setting
1864            conf.save_raw = !conf.save_raw;
1865            draw_restore();
1866        }
1867        else
1868        {
1869            // In manual focus mode so update shooting distance
1870#if CAM_HAS_ZOOM_LEVER
1871            conf.subj_dist_override_value=MAX_DIST;
1872            shooting_set_focus(shooting_get_subject_distance_override_value(), SET_NOW);
1873#else
1874            if (conf.subj_dist_override_koef==4)
1875                gui_subj_dist_override_koef_enum(-3,0);
1876            else
1877                gui_subj_dist_override_koef_enum(1,0);
1878#endif
1879        }
1880    }
1881#else                                                   // ALT RAW toggle kbd processing if can't SD override or has erase button
1882    if (kbd_is_key_clicked(SHORTCUT_TOGGLE_RAW))
1883    {
1884        if (conf.debug_shortcut_action > 0)
1885        {
1886#ifdef OPT_DEBUGGING
1887            gui_debug_shortcut();
1888#endif
1889        }
1890        else
1891        {
1892            // Change RAW save state
1893            conf.save_raw = !conf.save_raw;
1894            draw_restore();
1895        }
1896    }
1897#endif
1898#ifdef OPT_SCRIPTING                                    // ALT Set button processing if scripting enabled - open script menu
1899    else if (kbd_is_key_clicked(KEY_SET))
1900    {
1901        gui_menu_init(&script_submenu);
1902        gui_default_kbd_process_menu_btn();
1903    }
1904#endif
1905#if CAM_CAN_SD_OVERRIDE                                 // ALT button processing if camera has SD override
1906    else
1907    {
1908#if !CAM_HAS_MANUAL_FOCUS
1909        if (kbd_is_key_clicked(SHORTCUT_MF_TOGGLE))     // Camera does not have manual focus
1910        {
1911            if (conf.subj_dist_override_koef>0)
1912                conf.subj_dist_override_koef=0;
1913            else conf.subj_dist_override_koef=1;
1914            draw_restore();
1915        }
1916        else
1917#endif
1918        if (shooting_get_common_focus_mode())           // Check in manual focus mode
1919        {
1920#if CAM_HAS_ZOOM_LEVER                                  // Camera has zoom lever, use left & right to change factor,up to set infinity
1921            if (kbd_is_key_clicked(KEY_RIGHT))
1922            {
1923                sd_override_koef(1);
1924            }
1925            else if (kbd_is_key_clicked(KEY_LEFT))
1926            {
1927                sd_override_koef(-1);
1928            }
1929            else if (kbd_is_key_clicked(SHORTCUT_SET_INFINITY))
1930            {
1931                conf.subj_dist_override_value=MAX_DIST;
1932                shooting_set_focus(shooting_get_subject_distance_override_value(), SET_NOW);
1933            }
1934            else
1935#endif
1936            if (kbd_is_key_clicked(SHORTCUT_SET_HYPERFOCAL))    // Set hyperfocal distance if down pressed
1937            {
1938                int m=mode_get()&MODE_SHOOTING_MASK;
1939                if ((m==MODE_M) || (m==MODE_AV))
1940                     conf.subj_dist_override_value=(int)shooting_get_hyperfocal_distance_f(shooting_get_aperture_from_av96(shooting_get_user_av96()),get_focal_length(lens_get_zoom_point()));
1941                else conf.subj_dist_override_value=(int)shooting_get_hyperfocal_distance();
1942                shooting_set_focus(shooting_get_subject_distance_override_value(), SET_NOW);
1943            }
1944            else
1945            {
1946                switch (kbd_get_autoclicked_key())
1947                {
1948#if CAM_HAS_ZOOM_LEVER
1949                case KEY_ZOOM_IN:
1950#else
1951                case KEY_RIGHT:
1952#endif
1953                    sd_override(1);
1954                    break;
1955#if CAM_HAS_ZOOM_LEVER
1956                case KEY_ZOOM_OUT:
1957#else
1958                case KEY_LEFT:
1959#endif
1960                    sd_override(-1);
1961                    break;
1962                }
1963            }
1964        }
1965    }
1966#endif
1967}
1968
1969//-------------------------------------------------------------------
1970// Handler for Menu button press in CHDK Alt mode (not in Menu mode)
1971// Enter main menu or user menu based on configuration
1972void gui_chdk_kbd_process_menu_btn()
1973{
1974    if (conf.user_menu_as_root && (conf.user_menu_enable != 0)) {
1975        if (kbd_is_key_pressed(KEY_SHOOT_HALF))
1976            gui_menu_init(&root_menu);
1977        else
1978            gui_menu_init(&user_submenu);
1979    }
1980    else {
1981        if ((conf.user_menu_enable != 0) && kbd_is_key_pressed(KEY_SHOOT_HALF))
1982            gui_menu_init(&user_submenu);
1983        else
1984            gui_menu_init(&root_menu);
1985    }
1986    gui_default_kbd_process_menu_btn();
1987}
1988
1989// Menu button handled for text reader
1990#ifdef OPT_TEXTREADER
1991void gui_read_kbd_process_menu_btn()
1992{
1993    gui_read_kbd_process();
1994    gui_default_kbd_process_menu_btn();
1995}
1996#endif
1997
1998// Menu button handled for Menu mode
1999void gui_menu_kbd_process_menu_btn()
2000{
2001#ifdef OPTIONS_AUTOSAVE
2002    conf_save_new_settings_if_changed();
2003#endif
2004    if (gui_user_menu_flag)
2005    {
2006        gui_set_mode(GUI_MODE_MENU);
2007        gui_user_menu_flag = 0;
2008        gui_menu_init(&root_menu);
2009    }
2010    else
2011        gui_set_mode(GUI_MODE_ALT);
2012    draw_restore();
2013}
2014
2015//-------------------------------------------------------------------
2016// Structure to store gui redraw and kbd process handlers for each mode
2017typedef struct
2018{
2019    void (*redraw)(void);                   // Called to redraw screen
2020    void (*kbd_process)(void);              // Main button handler for mode
2021    void (*kbd_process_menu_btn)(void);     // Menu button handler for mode
2022} gui_handler;
2023
2024// GUI handler table (entries must be in the same order and have the same number of entries as Gui_Mode enum)
2025gui_handler guiHandlers[] =
2026{
2027    /*GUI_MODE_NONE*/           { gui_draw_osd,         0,                          0 },
2028    /*GUI_MODE_ALT*/            { gui_chdk_draw,        gui_chdk_kbd_process,       gui_chdk_kbd_process_menu_btn },
2029    /*GUI_MODE_MENU*/           { gui_menu_draw,        gui_menu_kbd_process,       gui_menu_kbd_process_menu_btn },
2030    /*GUI_MODE_PALETTE*/        { gui_palette_draw,     gui_palette_kbd_process,    gui_default_kbd_process_menu_btn },
2031    /*GUI_MODE_MBOX*/           { gui_mbox_draw,        gui_mbox_kbd_process,       0 },
2032#ifdef OPT_GAME_REVERSI
2033    /*GUI_MODE_REVERSI*/        { gui_reversi_draw,     gui_reversi_kbd_process,    gui_default_kbd_process_menu_btn },
2034#else
2035                                { 0, 0, 0 },
2036#endif
2037#ifdef OPT_GAME_SOKOBAN
2038    /*GUI_MODE_SOKOBAN*/        { gui_sokoban_draw,     gui_sokoban_kbd_process,    gui_default_kbd_process_menu_btn },
2039#else
2040                                { 0, 0, 0 },
2041#endif
2042#ifdef OPT_DEBUGGING
2043    /*GUI_MODE_DEBUG*/          { gui_debug_draw,       gui_debug_kbd_process,      gui_default_kbd_process_menu_btn },
2044#else
2045                                { 0, 0, 0 },
2046#endif
2047    /*GUI_MODE_FSELECT*/        { gui_fselect_draw,     gui_fselect_kbd_process,    gui_fselect_kbd_process },
2048#ifdef OPT_TEXTREADER
2049    /*GUI_MODE_READ*/           { gui_read_draw,        gui_read_kbd_process,       gui_read_kbd_process_menu_btn },
2050#else
2051                                { 0, 0, 0 },
2052#endif
2053    /*GUI_MODE_OSD*/            { gui_osd_draw,         gui_osd_kbd_process,        gui_default_kbd_process_menu_btn },
2054#ifdef OPT_CALENDAR
2055    /*GUI_MODE_CALENDAR*/       { gui_calendar_draw,    gui_calendar_kbd_process,   gui_default_kbd_process_menu_btn },
2056#else
2057                                { 0, 0, 0 },
2058#endif
2059#ifdef OPT_DEBUGGING
2060    /*GUI_MODE_BENCH*/          { gui_bench_draw,       gui_bench_kbd_process,      gui_default_kbd_process_menu_btn },
2061#else
2062                                { 0, 0, 0 },
2063#endif
2064    /*GUI_MODE_MPOPUP*/         { gui_mpopup_draw,      gui_mpopup_kbd_process,     0 },
2065#ifdef OPT_GAME_CONNECT4
2066    /*GUI_MODE_4WINS*/          { gui_4wins_draw,       gui_4wins_kbd_process,      gui_default_kbd_process_menu_btn },
2067#else
2068                                { 0, 0, 0 },
2069#endif
2070#ifdef OPT_GAME_MASTERMIND
2071    /*GUI_MODE_MASTERMIND*/     { gui_mastermind_draw,  gui_mastermind_kbd_process, gui_default_kbd_process_menu_btn },
2072#else
2073                                { 0, 0, 0 },
2074#endif
2075};
2076
2077//-------------------------------------------------------------------
2078// Main GUI redraw function, perform common initialisation then calls the redraw handler for the mode
2079void gui_redraw()
2080{
2081    enum Gui_Mode gui_mode_old;
2082
2083#ifdef CAM_DETECT_SCREEN_ERASE
2084    if (!draw_test_guard() && gui_mode)     // Attempt to detect screen erase in <Alt> mode, redraw if needed
2085    {
2086        draw_set_guard();
2087        gui_menu_force_redraw();
2088        gui_fselect_force_redraw();
2089#ifdef CAM_TOUCHSCREEN_UI
2090        extern int redraw_buttons;
2091        redraw_buttons = 1;
2092#endif
2093    }
2094#endif
2095
2096        gui_handle_splash();
2097
2098    gui_in_redraw = 1;
2099    gui_mode_old = gui_mode;
2100
2101#ifdef CAM_TOUCHSCREEN_UI
2102    extern void virtual_buttons();
2103    virtual_buttons();
2104#endif
2105
2106    // Call redraw handler
2107    if (guiHandlers[gui_mode].redraw) guiHandlers[gui_mode].redraw();
2108
2109    // Forced redraw if needed
2110    gui_in_redraw = 0;
2111    if ((gui_mode_old != gui_mode && (gui_mode_old != GUI_MODE_NONE && gui_mode_old != GUI_MODE_ALT) && (gui_mode != GUI_MODE_MBOX && gui_mode != GUI_MODE_MPOPUP)) || gui_restore) {
2112        if (gui_restore) gui_menu_force_redraw();
2113        gui_restore = 0;
2114        if (gui_mode != GUI_MODE_REVERSI && gui_mode != GUI_MODE_SOKOBAN && gui_mode != GUI_MODE_4WINS && gui_mode != GUI_MODE_MASTERMIND)
2115            draw_restore();
2116    }
2117}
2118
2119//-------------------------------------------------------------------
2120// Main kbd processing for GUI modes
2121void gui_kbd_process()
2122{
2123    // Call menu button handler if menu button pressed
2124    if (kbd_is_key_clicked(KEY_MENU))
2125    {
2126        if (guiHandlers[gui_mode].kbd_process_menu_btn) guiHandlers[gui_mode].kbd_process_menu_btn();
2127        return;
2128    }
2129
2130    // Call mode handler for other buttons
2131    if (guiHandlers[gui_mode].kbd_process) guiHandlers[gui_mode].kbd_process();
2132}
2133
2134//-------------------------------------------------------------------
2135void gui_kbd_enter()
2136{
2137    // XXX set custom palette
2138#ifdef OPTIONS_AUTOSAVE
2139    conf_store_old_settings();
2140#endif
2141    gui_set_mode(GUI_MODE_ALT);
2142
2143        conf_update_prevent_shutdown();
2144
2145    vid_turn_off_updates();
2146
2147        gui_user_menu_flag = 0;
2148        if (conf.user_menu_enable == 2) {
2149                gui_menu_init(&user_submenu);
2150                gui_set_mode(GUI_MODE_MENU);
2151                draw_restore();
2152                gui_user_menu_flag = 1;
2153        }
2154
2155}
2156
2157//-------------------------------------------------------------------
2158void gui_kbd_leave()
2159{
2160    // XXX restore palette
2161#ifdef OPTIONS_AUTOSAVE
2162    conf_save_new_settings_if_changed();
2163#endif
2164#ifdef OPT_UBASIC
2165    ubasic_error = UBASIC_E_NONE;
2166#endif
2167    draw_restore();
2168    if (gui_mode == GUI_MODE_READ && !rbf_load(conf.menu_rbf_file))
2169        rbf_load_from_8x16(current_font);
2170    rbf_set_codepage(FONT_CP_WIN);
2171    vid_turn_on_updates();
2172    gui_set_mode(GUI_MODE_NONE);
2173
2174        conf_update_prevent_shutdown();
2175}
2176//-------------------------------------------------------------------
2177
2178void other_kbd_process(){
2179 int key;
2180#if CAM_AF_SCAN_DURING_VIDEO_RECORD
2181
2182 if (movie_status==VIDEO_RECORD_IN_PROGRESS) {
2183  if (kbd_is_key_clicked(conf.video_af_key)) MakeAFScan();
2184 }
2185
2186#endif
2187
2188#if CAM_CAN_UNLOCK_OPTICAL_ZOOM_IN_VIDEO
2189 // return from digital to optical zoom in video
2190#if CAM_HAS_ZOOM_LEVER
2191   key=KEY_ZOOM_OUT;
2192#else
2193   key=KEY_DOWN;
2194#endif
2195    if (conf.unlock_optical_zoom_for_video && (movie_status==VIDEO_RECORD_IN_PROGRESS) &&  kbd_is_key_clicked(key)){
2196     short x;
2197     get_property_case(PROPCASE_DIGITAL_ZOOM_STATE, &x, sizeof(x));
2198     if (x) {
2199      get_property_case(PROPCASE_DIGITAL_ZOOM_POSITION, &x, sizeof(x));
2200#if defined (CAMERA_s90) || defined (CAMERA_s95) || defined (CAMERA_g12) || defined (CAMERA_a3000)
2201          if (x==0) zoom_status=ZOOM_OPTICAL_MAX; //ERR99: No zoom back from digital to optical zoom possible if set to medium
2202#else
2203          if (x==0) zoom_status=ZOOM_OPTICAL_MEDIUM;
2204#endif
2205
2206     }
2207    }
2208#endif
2209
2210#if CAM_EV_IN_VIDEO
2211    if ((movie_status==VIDEO_RECORD_IN_PROGRESS) && !kbd_is_key_pressed(KEY_SHOOT_HALF)){
2212#if CAM_HAS_ERASE_BUTTON
2213        if (kbd_is_key_clicked(KEY_ERASE)){
2214#else
2215#if !defined (CAMERA_a480)
2216        if (kbd_is_key_clicked(KEY_DISPLAY)){
2217#else
2218        if (kbd_is_key_clicked(KEY_MENU)){
2219#endif
2220#endif
2221            set_ev_video_avail(!get_ev_video_avail());
2222#ifdef CAM_TOUCHSCREEN_UI
2223            redraw_buttons = 1;
2224#endif
2225        }
2226        if (get_ev_video_avail()) {
2227            if (kbd_is_key_clicked(KEY_LEFT)) {
2228                set_ev_video(get_ev_video()-1);
2229            }
2230            if (kbd_is_key_clicked(KEY_RIGHT)){
2231                set_ev_video(get_ev_video()+1);
2232            }
2233        }
2234    }
2235#endif
2236}
2237
2238void gui_draw_debug_vals_osd() {
2239#ifdef OPT_DEBUGGING
2240
2241#if defined(OPT_EXMEM_TESTING)
2242    // Only do memory corruption testing if not recording video
2243    if (!MODE_IS_VIDEO(mode_get()))
2244    {
2245            // If defined the exmem memory is allocated; but not used for CHDK.
2246            // It is filled with a guard value (see wrappers.c) which is checked here
2247        // Any corruption is reported, otherwise 'OK' is displayed on screen (along with the exmem memory start address).
2248            extern void *exmem_start, *exmem_end;
2249            // check exmem allocated memory for corruption
2250            unsigned long* p = (unsigned long*)exmem_start;
2251            unsigned long *f = 0, *l = 0;
2252            long cnt = 0;
2253            while (p < (unsigned long*)exmem_end)
2254            {
2255                    if (p[0] != 0xDEADBEEF)
2256                    {
2257                            l = p;
2258                            if (f == 0) f = p;
2259                            cnt++;
2260                    }
2261                    p++;
2262            }
2263            if (cnt != 0)
2264            {
2265                    sprintf(osd_buf, "s:%8x e:%8x", exmem_start, exmem_end);
2266                    draw_txt_string(2, 12, osd_buf, conf.osd_color);
2267                    sprintf(osd_buf, "f:%8x l:%8x c:%d", f, l, cnt);
2268            }
2269            else
2270            {
2271                    sprintf(osd_buf, "OK 0x%x", exmem_start);
2272            }
2273            draw_txt_string(2, 13, osd_buf, conf.osd_color);
2274            // end of check     
2275    }
2276#endif
2277
2278    // DEBUG: "Show misc. values"
2279    // change ROW to fit values on screen in draw_txt_string(COLUMN, ROW, ...)
2280    // uncomment gui_draw_debug_vals_osd() below if you want debug values always on top
2281    if (conf.debug_misc_vals_show) {
2282        // show value of Memory Address selected with Memory Browser
2283        sprintf(osd_buf, "MEM: %#8x", (void*) (*(int*)conf.mem_view_addr_init));    // show value in Hexadecimal integer
2284        //sprintf(osd_buf, "MEM: %8u", (void*) (*(int*)conf.mem_view_addr_init));    // show value in Decimal integer
2285        draw_txt_string(28,  9, osd_buf, conf.osd_color);
2286
2287        // show Autofocus status (if AF is working)
2288        extern volatile long focus_busy;
2289        sprintf(osd_buf, "FB:  %8u", focus_busy);
2290        draw_txt_string(28, 10, osd_buf, conf.osd_color);
2291
2292        // show Zoom status (if Lens is moving)
2293        extern volatile long zoom_busy;
2294        sprintf(osd_buf, "ZB:  %8u", zoom_busy);
2295        draw_txt_string(28, 11, osd_buf, conf.osd_color);
2296
2297        // show USB-Power status to debug remote / sync
2298        sprintf(osd_buf, "USB: %8u", get_usb_power(1));
2299        draw_txt_string(28, 12, osd_buf, conf.osd_color);
2300
2301        /*
2302        // some cameras missing zoom_status
2303        sprintf(osd_buf, "ZS:  %#8x", zoom_status);
2304        draw_txt_string(28, 13, osd_buf, conf.osd_color);
2305        */
2306
2307        /*
2308        sprintf(osd_buf, "VP:  %#8x", vid_get_viewport_fb_d());
2309        draw_txt_string(28, 14, osd_buf, conf.osd_color);
2310        */
2311
2312        /*
2313        // debug keymap, KEYS_MASKx, SD_READONLY_FLAG, USB_MASK
2314        extern long physw_status[3];
2315        sprintf(osd_buf, "PS1: %#8x", physw_status[0]);
2316        draw_txt_string(28, 10, osd_buf, conf.osd_color);
2317
2318        sprintf(osd_buf, "PS2: %#8x", physw_status[1]);
2319        draw_txt_string(28, 11, osd_buf, conf.osd_color);
2320
2321        sprintf(osd_buf, "PS3: %#8x", physw_status[2]);
2322        draw_txt_string(28, 12, osd_buf, conf.osd_color);
2323        */
2324
2325        /*
2326        long v=get_file_counter();
2327        sprintf(osd_buf, "1:%03d-%04d", (v>>18)&0x3FF, (v>>4)&0x3FFF);
2328        sprintf(osd_buf, "1:%d, %08X", xxxx, eeee);
2329        */
2330    }
2331    {
2332        static char sbuf[100];
2333        int r,i, p, len;
2334        if (conf.debug_display == DEBUG_DISPLAY_PROPS){
2335
2336            for (i=0;i<10;i++){
2337                r = 0;
2338                p = conf.debug_propcase_page*10+i;
2339                get_property_case(p, &r, 4);
2340                sprintf(sbuf, "%3d: %d              ", p, r);
2341                sbuf[20]=0;
2342                draw_string(64,16+16*i,sbuf, conf.osd_color);
2343            }
2344        }
2345
2346        if (conf.debug_display == DEBUG_DISPLAY_PARAMS){
2347            extern long* FlashParamsTable[];
2348            char s[30];
2349            int count;
2350
2351            for (i=0;i<10;i++){
2352                r = 0;
2353                p = conf.debug_propcase_page*10+i;
2354                if (p>=get_flash_params_count()) {
2355                    sprintf(sbuf, "%3d: This parameter does not exists", p);
2356                } else  {
2357                    len=FlashParamsTable[p][1]>>16;
2358                    if ((len==1)||(len==2)||(len==4)){
2359                        get_parameter_data(p, &r, len);
2360                        sprintf(sbuf, "%3d: %30d :%2d ", p, r,len);
2361                    }
2362                    else {
2363                        if (len>=sizeof(s)) count=sizeof(s)-1; else count=len;
2364                        get_parameter_data(p, &s, count);
2365                        s[count]=0;
2366                        sprintf(sbuf, "%3d: %30s :%2d ", p, s,len);
2367                    }
2368                }
2369                draw_string(16,16+16*i,sbuf, conf.osd_color);
2370            }
2371        }
2372    }
2373
2374    if(conf.debug_display == DEBUG_DISPLAY_TASKS) {
2375            gui_debug_draw_tasklist();
2376    }
2377#endif
2378}
2379//-------------------------------------------------------------------
2380//extern int xxxx, eeee;
2381//-------------------------------------------------------------------
2382void gui_draw_osd() {
2383    unsigned int m, /*n = 0,*/ mode_photo, mode_video;
2384    coord x;
2385#if CAM_SWIVEL_SCREEN
2386    static int flashlight = 0;
2387#endif
2388    static int pressed = 0;
2389    static int half_disp_press_old=0;
2390    int half_disp_press;
2391    int need_restore = 0;
2392    m = mode_get();
2393
2394// DEBUG: uncomment if you want debug values always on top
2395//gui_draw_debug_vals_osd();
2396
2397#if CAM_SWIVEL_SCREEN
2398    if (conf.flashlight && (m&MODE_SCREEN_OPENED) && (m&MODE_SCREEN_ROTATED) && (gui_mode==GUI_MODE_NONE /* || gui_mode==GUI_MODE_ALT */)) {
2399        draw_filled_rect(0, 0, screen_width-1, screen_height-1, MAKE_COLOR(COLOR_WHITE, COLOR_WHITE));
2400        flashlight = 1;
2401    }
2402    if (flashlight) {
2403        if ((!((m&MODE_SCREEN_OPENED) && (m&MODE_SCREEN_ROTATED))) || (gui_mode!=GUI_MODE_NONE /* && gui_mode!=GUI_MODE_ALT */)) {
2404            flashlight = 0;
2405                        need_restore = 1;
2406        } else {
2407                        return;
2408                }
2409    }
2410#endif
2411
2412    if (kbd_is_key_pressed(KEY_SHOOT_HALF)) {
2413        if (kbd_is_key_pressed(SHORTCUT_TOGGLE_ZEBRA)) {
2414            if (!pressed) {
2415                conf.zebra_draw = !conf.zebra_draw;
2416                if (!conf.zebra_draw) {
2417                                        need_restore = 1;
2418                }
2419                pressed = 1;
2420            }
2421        } else if (kbd_is_key_pressed(SHORTCUT_TOGGLE_HISTO)) {
2422            if (!pressed) {
2423                if (++conf.show_histo>SHOW_HALF) conf.show_histo=0;
2424                if (!conf.show_histo) {
2425                                        need_restore = 1;
2426                }
2427                pressed = 1;
2428            }
2429        } else if (kbd_is_key_pressed(SHORTCUT_TOGGLE_OSD)) {
2430            if (!pressed) {
2431                conf.show_osd = !conf.show_osd;
2432                if (!conf.show_osd) {
2433                                        need_restore = 1;
2434                }
2435                pressed = 1;
2436            }
2437        } else if (kbd_is_key_pressed(SHORTCUT_DISABLE_OVERRIDES)) {
2438             if (!pressed) {
2439                 if (conf.override_disable < 2) conf.override_disable = !conf.override_disable;
2440                 if (!conf.show_osd) {
2441                                        need_restore = 1;
2442                 }
2443                 pressed = 1;
2444             }
2445        } else {
2446            pressed = 0;
2447        }
2448    } else {
2449        pressed = 0;
2450    }
2451
2452        // TODO some of the ifs below should probably use this
2453        mode_video = MODE_IS_VIDEO(m);
2454
2455    mode_photo = (m&MODE_MASK) == MODE_PLAY ||
2456                 !( mode_video ||
2457                                 (m&MODE_SHOOTING_MASK)==MODE_STITCH);
2458
2459    half_disp_press=mode_photo && kbd_is_key_pressed(KEY_SHOOT_HALF) && kbd_is_key_pressed(KEY_DISPLAY);
2460    if (half_disp_press && ! half_disp_press_old)
2461                need_restore = 1;
2462    half_disp_press_old=half_disp_press;
2463
2464        if (need_restore)
2465                draw_restore();
2466
2467    if (half_disp_press)
2468                return;
2469
2470        if (gui_osd_draw_zebra(conf.zebra_draw && gui_mode==GUI_MODE_NONE &&
2471                                                        kbd_is_key_pressed(KEY_SHOOT_HALF) && mode_photo &&
2472                                                        !state_kbd_script_run)) {// no zebra when script running, to save mem
2473                return; // if zebra drawn, we're done
2474        }
2475#if !CAM_SHOW_OSD_IN_SHOOT_MENU
2476      if (!(conf.show_osd && (canon_menu_active==(int)&canon_menu_active-4) && (canon_shoot_menu_active==0)))  return;
2477#else
2478      if (!(conf.show_osd && (canon_menu_active==(int)&canon_menu_active-4) /*&& (canon_shoot_menu_active==0)*/ ))  return;
2479#endif
2480
2481
2482    if ((gui_mode==GUI_MODE_NONE || gui_mode==GUI_MODE_ALT) && (
2483     (kbd_is_key_pressed(KEY_SHOOT_HALF) && ((conf.show_histo==SHOW_HALF)/* || (m&MODE_MASK) == MODE_PLAY*/)) ||
2484     ((conf.show_histo==SHOW_ALWAYS)  &&  !((m&MODE_MASK) == MODE_PLAY) && (recreview_hold==0))
2485    ) &&
2486    (mode_photo || (m&MODE_SHOOTING_MASK)==MODE_STITCH)) {
2487        gui_osd_draw_histo();
2488    }
2489
2490    if ((m&MODE_MASK) == MODE_REC && (recreview_hold==0 || conf.show_osd_in_review) ) {
2491        if (conf.show_grid_lines) {
2492            gui_grid_draw_osd(1);
2493        }
2494        if ((gui_mode==GUI_MODE_NONE || gui_mode==GUI_MODE_ALT) && (((kbd_is_key_pressed(KEY_SHOOT_HALF) || (state_kbd_script_run) || (shooting_get_common_focus_mode())) && (mode_photo || (m&MODE_SHOOTING_MASK)==MODE_STITCH )) || ((mode_video || movie_status > 1) && conf.show_values_in_video) )) {
2495
2496           if (conf.show_dof!=DOF_DONT_SHOW) gui_osd_calc_dof();
2497
2498           if (conf.show_dof==DOF_SHOW_IN_DOF) gui_osd_draw_dof();
2499
2500           if (conf.values_show_real_iso || conf.values_show_market_iso || conf.values_show_ev_seted || conf.values_show_ev_measured || conf.values_show_bv_measured || conf.values_show_bv_seted || conf.values_show_overexposure || conf.values_show_canon_overexposure || conf.values_show_luminance) gui_osd_calc_expo_param();
2501        }
2502        if (conf.show_state) gui_osd_draw_state();
2503        if (conf.save_raw && conf.show_raw_state && !mode_video && (!kbd_is_key_pressed(KEY_SHOOT_HALF))) gui_osd_draw_raw_info();
2504
2505            if ((conf.show_values==SHOW_ALWAYS && mode_photo) || ((mode_video || movie_status > 1)&& conf.show_values_in_video) || ((kbd_is_key_pressed(KEY_SHOOT_HALF) || (recreview_hold==1)) && (conf.show_values==SHOW_HALF)))
2506                   gui_osd_draw_values(1);
2507        else if  (shooting_get_common_focus_mode() && mode_photo && conf.show_values && !(conf.show_dof==DOF_SHOW_IN_DOF) )
2508           gui_osd_draw_values(2);
2509            else if  (conf.show_values==SHOW_HALF)
2510                   gui_osd_draw_values(0);
2511    }
2512
2513
2514    if ((recreview_hold==0) &&  (!kbd_is_key_pressed(KEY_SHOOT_HALF) &&  (  ((m&MODE_MASK) == MODE_REC) || (!((m&MODE_MASK) == MODE_REC) &&  !((conf.hide_osd == 1) || (conf.hide_osd == 3)) )) && !(((conf.hide_osd == 2) || (conf.hide_osd == 3))&& (shooting_get_prop(PROPCASE_DISPLAY_MODE) == 1))))   {
2515        gui_batt_draw_osd();
2516        gui_space_draw_osd();
2517        gui_usb_draw_osd();
2518        if (conf.fast_ev && !mode_video && (m&MODE_MASK) == MODE_REC ) gui_osd_draw_ev();
2519    }
2520
2521    if ((conf.show_clock) && (recreview_hold==0) &&  ((!kbd_is_key_pressed(KEY_SHOOT_HALF) &&  (  ((m&MODE_MASK) == MODE_REC) || (!((m&MODE_MASK) == MODE_REC) &&  !((conf.hide_osd == 1) || (conf.hide_osd == 3)) )) && !(((conf.hide_osd == 2) || (conf.hide_osd == 3))&& (shooting_get_prop(PROPCASE_DISPLAY_MODE) == 1)))|| (conf.clock_halfpress==0) )) {
2522        gui_osd_draw_clock(0,0,0);
2523    }
2524    else if ((conf.show_clock) && (recreview_hold==0) &&  kbd_is_key_pressed(KEY_SHOOT_HALF) && conf.clock_halfpress==1) {
2525        gui_osd_draw_seconds();
2526    }
2527
2528    if ((conf.show_temp>0) && (recreview_hold==0) &&  ((!kbd_is_key_pressed(KEY_SHOOT_HALF) &&  (  ((m&MODE_MASK) == MODE_REC) || (!((m&MODE_MASK) == MODE_REC) &&  !((conf.hide_osd == 1) || (conf.hide_osd == 3)) )) && !(((conf.hide_osd == 2) || (conf.hide_osd == 3))&& (shooting_get_prop(PROPCASE_DISPLAY_MODE) == 1)) )|| (conf.clock_halfpress==0) )) {
2529        gui_osd_draw_temp();
2530    }
2531    if (conf.show_movie_time > 0 && (mode_video || movie_status > 1)) {
2532        gui_osd_draw_movie_time_left();
2533    }
2534
2535#if CAM_DRAW_EXPOSITION
2536    if (gui_mode==GUI_MODE_NONE && kbd_is_key_pressed(KEY_SHOOT_HALF) && ((m&MODE_MASK)==MODE_REC) && ((m&MODE_SHOOTING_MASK))!=MODE_VIDEO_STD && (m&MODE_SHOOTING_MASK)!=MODE_VIDEO_COMPACT) {
2537     strcpy(osd_buf,shooting_get_tv_str());
2538     strcat(osd_buf,"\"  F");
2539     strcat(osd_buf,shooting_get_av_str());
2540     draw_txt_string(22-strlen(osd_buf)/2, 14, osd_buf, conf.osd_color);
2541    }
2542#endif
2543
2544#if CAM_EV_IN_VIDEO
2545    if (movie_status==VIDEO_RECORD_IN_PROGRESS) gui_osd_draw_ev_video(get_ev_video_avail());
2546#endif
2547
2548        gui_draw_debug_vals_osd();
2549
2550#ifdef OPT_UBASIC
2551    if (ubasic_error){
2552        const char *msg;
2553        if (ubasic_error >= UBASIC_E_ENDMARK) {
2554            msg = ubasic_errstrings[UBASIC_E_UNKNOWN_ERROR];
2555        } else {
2556            msg = ubasic_errstrings[ubasic_error];
2557        }
2558        sprintf(osd_buf, "uBASIC:%d %s ", ubasic_linenumber(), msg);
2559        draw_txt_string(0, 0, osd_buf, MAKE_COLOR(COLOR_RED, COLOR_YELLOW));
2560    }
2561#endif
2562}
2563
2564#ifndef OPTIONS_AUTOSAVE
2565//-------------------------------------------------------------------
2566void gui_menuproc_save(int arg)
2567{
2568    conf_save();
2569}
2570#endif
2571
2572//-------------------------------------------------------------------
2573static void gui_menuproc_reset_selected(unsigned int btn) {
2574    if (btn==MBOX_BTN_YES)
2575        conf_load_defaults();
2576}
2577
2578void gui_menuproc_reset(int arg)
2579{
2580    gui_mbox_init(LANG_MSG_RESET_OPTIONS_TITLE,
2581                  LANG_MSG_RESET_OPTIONS_TEXT,
2582                  MBOX_FUNC_RESTORE|MBOX_TEXT_CENTER|MBOX_BTN_YES_NO|MBOX_DEF_BTN2, gui_menuproc_reset_selected);
2583}
2584
2585//-------------------------------------------------------------------
2586void gui_draw_palette(int arg) {
2587    draw_restore();
2588    gui_palette_init(PALETTE_MODE_DEFAULT, 0x00, NULL);
2589    gui_set_mode(GUI_MODE_PALETTE);
2590}
2591
2592//-------------------------------------------------------------------
2593void gui_show_build_info(int arg) {
2594    static char buf[192];
2595    static char comp[64];
2596
2597#ifdef __GNUC__
2598# ifndef __GNUC_PATCHLEVEL__
2599# define __GNUC_PATCHLEVEL 0
2600# endif
2601    sprintf(comp, "GCC %d.%d.%d", __GNUC__ ,__GNUC_MINOR__,__GNUC_PATCHLEVEL__ );
2602#else
2603    sprintf(comp, "UNKNOWN" );
2604#endif
2605    sprintf(buf, lang_str(LANG_MSG_BUILD_INFO_TEXT), HDK_VERSION, BUILD_NUMBER, __DATE__, __TIME__, PLATFORM, PLATFORMSUB, comp);
2606gui_mbox_init(LANG_MSG_BUILD_INFO_TITLE, (int)buf, MBOX_FUNC_RESTORE|MBOX_TEXT_LEFT, NULL);
2607}
2608
2609//-------------------------------------------------------------------
2610void gui_show_memory_info(int arg) {
2611    static char buf[96];    // buffer size was 64, size increased for none english language
2612
2613    sprintf(buf, lang_str(LANG_MSG_MEMORY_INFO_TEXT), core_get_free_memory(), MEMISOSIZE, &_start, &_end);
2614    gui_mbox_init(LANG_MSG_MEMORY_INFO_TITLE, (int)buf, MBOX_FUNC_RESTORE|MBOX_TEXT_CENTER, NULL);
2615}
2616
2617//-------------------------------------------------------------------
2618#ifdef OPT_GAME_REVERSI
2619void gui_draw_reversi(int arg) {
2620    if ((mode_get()&MODE_MASK) != MODE_PLAY) {
2621        gui_mbox_init(LANG_MSG_INFO_TITLE, LANG_MSG_SWITCH_TO_PLAY_MODE,
2622                      MBOX_FUNC_RESTORE|MBOX_TEXT_CENTER, NULL);
2623        return;
2624    }
2625
2626    gui_set_mode(GUI_MODE_REVERSI);
2627    gui_reversi_init();
2628}
2629#endif
2630
2631//-------------------------------------------------------------------
2632#ifdef OPT_GAME_SOKOBAN
2633void gui_draw_sokoban(int arg) {
2634    if ((mode_get()&MODE_MASK) != MODE_PLAY) {
2635        gui_mbox_init(LANG_MSG_INFO_TITLE, LANG_MSG_SWITCH_TO_PLAY_MODE,
2636                      MBOX_FUNC_RESTORE|MBOX_TEXT_CENTER, NULL);
2637        return;
2638    }
2639    if ( gui_sokoban_init() )
2640        gui_set_mode(GUI_MODE_SOKOBAN);
2641}
2642#endif
2643//-------------------------------------------------------------------
2644#ifdef OPT_GAME_CONNECT4
2645void gui_draw_4wins(int arg) {
2646    if ((mode_get()&MODE_MASK) != MODE_PLAY) {
2647        gui_mbox_init(LANG_MSG_INFO_TITLE, LANG_MSG_SWITCH_TO_PLAY_MODE,
2648                      MBOX_FUNC_RESTORE|MBOX_TEXT_CENTER, NULL);
2649        return;
2650    }
2651    if ( gui_4wins_init() )
2652        gui_set_mode(GUI_MODE_4WINS);
2653}
2654#endif
2655//-------------------------------------------------------------------
2656#ifdef OPT_GAME_MASTERMIND
2657void gui_draw_mastermind(int arg) {
2658    if ((mode_get()&MODE_MASK) != MODE_PLAY) {
2659        gui_mbox_init(LANG_MSG_INFO_TITLE, LANG_MSG_SWITCH_TO_PLAY_MODE,
2660                      MBOX_FUNC_RESTORE|MBOX_TEXT_CENTER, NULL);
2661        return;
2662    }
2663    if ( gui_mastermind_init() )
2664        gui_set_mode(GUI_MODE_MASTERMIND);
2665}
2666#endif
2667//-------------------------------------------------------------------
2668#ifdef OPT_DEBUGGING
2669void gui_draw_debug(int arg) {
2670//    gui_debug_init(0x2510);
2671//    gui_debug_init(0x127E0);
2672//    gui_debug_init(0x7F5B8);
2673//    gui_debug_init(malloc(16));
2674    gui_debug_init((void*)conf.mem_view_addr_init);
2675}
2676#endif
2677//-------------------------------------------------------------------
2678#ifdef OPT_DEBUGGING
2679void gui_draw_bench(int arg) {
2680    gui_set_mode(GUI_MODE_BENCH);
2681    gui_bench_init();
2682}
2683#endif
2684//-------------------------------------------------------------------
2685
2686void gui_draw_splash(char* logo, int logo_size) {
2687    coord w, h, x, y;
2688    static const char *text[] = {
2689        "CHDK Firmware '" HDK_VERSION " " BUILD_NUMBER "'" ,
2690        "Build: " __DATE__ " " __TIME__ ,
2691        "Camera: " PLATFORM " - " PLATFORMSUB };
2692    int i, l;
2693    color cl = MAKE_COLOR(COLOR_RED, COLOR_WHITE);
2694
2695    gui_splash_mode = (mode_get()&MODE_MASK);
2696
2697    h=sizeof(text)/sizeof(text[0])*FONT_HEIGHT+8;
2698    w=0;
2699    for (i=0; i<sizeof(text)/sizeof(text[0]); ++i) {
2700        l=strlen(text[i]);
2701        if (l>w) w=l;
2702    }
2703    w=w*FONT_WIDTH+10;
2704
2705    x = (screen_width-w)>>1; y = ((screen_height-h)>>1) + 20;
2706    draw_filled_round_rect(x, y, x+w, y+h, MAKE_COLOR(COLOR_RED, COLOR_RED));
2707    for (i=0; i<sizeof(text)/sizeof(text[0]); ++i) {
2708        draw_string(x+((w-strlen(text[i])*FONT_WIDTH)>>1), y+i*FONT_HEIGHT+4, text[i], cl);
2709    }
2710    if(logo){
2711      int pos;
2712      int mx=0;
2713      int my=0;
2714      int offset_x = (screen_width-150)>>1;
2715      int offset_y = ((screen_height-84)>>1) - 42;
2716      const color color_lookup[8] = {COLOR_BLACK,
2717                                                                        COLOR_SPLASH_RED/*0x2E redish*/,
2718                                                                        COLOR_RED,
2719                                                                        COLOR_GREY /*0x3D*/,
2720                                                                        COLOR_SPLASH_GREY /*0x1F*/,
2721                                                                        COLOR_SPLASH_PINK /*0x21 pinkish*/,
2722                                                                        COLOR_TRANSPARENT /*0x00*/,
2723                                                                        COLOR_WHITE /*0x11*/};
2724      for(pos=0; pos<logo_size; pos++){
2725          char data = logo[pos];
2726          color c = color_lookup[(data>>5) & 0x07];
2727          for(i=0; i<(data&0x1F)+1; i++){
2728              if (c!=0x00){
2729                  draw_pixel(offset_x+mx,offset_y+my,c);
2730              }
2731              if (mx==149){
2732                  mx=0;
2733                  my++;
2734              }else{
2735                  mx++;
2736              }
2737          }
2738      }
2739    }
2740}
2741
2742//-------------------------------------------------------------------
2743void gui_draw_fselect(int arg) {
2744    gui_fselect_init(LANG_STR_FILE_BROWSER, "A", NULL);
2745}
2746
2747//-------------------------------------------------------------------
2748static void gui_grid_lines_load_selected(const char *fn) {
2749    if (fn)
2750        grid_lines_load(fn);
2751}
2752void gui_grid_lines_load(int arg) {
2753    DIR   *d;
2754    char  *path="A/CHDK/GRIDS";
2755
2756    // if exists "A/CHDK/GRIDS" go into
2757    d=opendir(path);
2758    if (d) {
2759        closedir(d);
2760    } else {
2761        path="A";
2762    }
2763
2764    gui_fselect_init(LANG_STR_SELECT_GRID_FILE, path, gui_grid_lines_load_selected);
2765}
2766
2767//-------------------------------------------------------------------
2768void gui_draw_osd_le(int arg) {
2769    gui_set_mode(GUI_MODE_OSD);
2770    gui_osd_init();
2771}
2772
2773//-------------------------------------------------------------------
2774#ifdef OPT_TEXTREADER
2775static void gui_draw_read_selected(const char *fn) {
2776    if (fn) {
2777        if (!rbf_load(conf.reader_rbf_file))
2778            rbf_load_from_8x16(current_font);
2779        rbf_set_codepage(conf.reader_codepage);
2780        gui_set_mode(GUI_MODE_READ);
2781        gui_read_init(fn);
2782    }
2783}
2784void gui_draw_read(int arg) {
2785    DIR   *d;
2786    char  *path="A/CHDK/BOOKS";
2787
2788    // if exists "A/CHDK/BOOKS" go into
2789    d=opendir(path);
2790    if (d) {
2791        closedir(d);
2792    } else {
2793        path="A";
2794    }
2795    gui_fselect_init(LANG_STR_SELECT_TEXT_FILE, path, gui_draw_read_selected);
2796    void gui_fselect_set_key_redraw(int n);
2797    gui_fselect_set_key_redraw(1);
2798}
2799
2800//-------------------------------------------------------------------
2801void gui_draw_read_last(int arg) {
2802    int fd;
2803
2804    fd = open(conf.reader_file, O_RDONLY, 0777);
2805    if (fd >= 0) {
2806        close(fd);
2807        gui_draw_read_selected(conf.reader_file);
2808    } else {
2809        gui_draw_read(arg);
2810    }
2811}
2812#endif
2813
2814//-------------------------------------------------------------------
2815void gui_menuproc_mkbootdisk(int arg) {
2816    mark_filesystem_bootable();
2817    gui_mbox_init(LANG_INFORMATION, LANG_CONSOLE_TEXT_FINISHED, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
2818}
2819
2820#ifdef OPT_EDGEOVERLAY
2821static void gui_load_edge_selected( const char* fn ) {
2822    if( fn )
2823        load_edge_overlay(fn);
2824}
2825
2826void gui_menuproc_edge_save(int arg) {
2827    save_edge_overlay();
2828}
2829
2830void gui_menuproc_edge_load(int arg) {
2831    DIR   *d;
2832    char  *path = EDGE_SAVE_DIR;
2833    const char* fn;
2834
2835    // if exists, go into
2836    d=opendir(path);
2837    if (d) {
2838        closedir(d);
2839    } else {
2840        path="A";
2841    }
2842
2843    gui_fselect_init(LANG_MENU_EDGE_LOAD, path, gui_load_edge_selected);
2844}
2845#endif
2846
2847//-------------------------------------------------------------------
2848#ifdef OPT_CALENDAR
2849void gui_draw_calendar(int arg) {
2850    gui_set_mode(GUI_MODE_CALENDAR);
2851    gui_calendar_init();
2852}
2853#endif
2854//-------------------------------------------------------------------
2855#ifdef OPT_TEXTREADER
2856static void gui_draw_rbf_selected(const char *fn) {
2857    if (fn) {
2858        strcpy(conf.reader_rbf_file, fn);
2859    }
2860}
2861void gui_draw_load_rbf(int arg) {
2862    DIR   *d;
2863    char  *path="A/CHDK/FONTS";
2864
2865    // if exists "A/CHDK/FONTS" go into
2866    d=opendir(path);
2867    if (d) {
2868        closedir(d);
2869    } else {
2870        path="A";
2871    }
2872
2873    gui_fselect_init(LANG_STR_SELECT_FONT_FILE, path, gui_draw_rbf_selected);
2874}
2875#endif
2876//-------------------------------------------------------------------
2877static void gui_draw_menu_rbf_selected(const char *fn) {
2878    if (fn) {
2879        strcpy(conf.menu_rbf_file, fn);
2880        if (!rbf_load(conf.menu_rbf_file))
2881            rbf_load_from_8x16(current_font);
2882        rbf_set_codepage(FONT_CP_WIN);
2883        gui_menu_init(NULL);
2884    }
2885}
2886void gui_draw_load_menu_rbf(int arg) {
2887    DIR   *d;
2888    char  *path="A/CHDK/FONTS";
2889
2890    // if exists "A/CHDK/FONTS" go into
2891    d=opendir(path);
2892    if (d) {
2893        closedir(d);
2894    } else {
2895        path="A";
2896    }
2897
2898    gui_fselect_init(LANG_STR_SELECT_FONT_FILE, path, gui_draw_menu_rbf_selected);
2899}
2900
2901//-------------------------------------------------------------------
2902static void gui_draw_symbol_rbf_selected(const char *fn) {
2903    if (fn) {
2904        strcpy(conf.menu_symbol_rbf_file, fn);
2905        if(!rbf_load_symbol(conf.menu_symbol_rbf_file)) conf.menu_symbol_enable=0;              //AKA
2906        gui_menu_init(NULL);
2907    }
2908}
2909void gui_draw_load_symbol_rbf(int arg) {
2910    DIR   *d;
2911    char  *path="A/CHDK/SYMBOLS";
2912
2913    // if exists "A/CHDK/FONTS" go into
2914    d=opendir(path);
2915    if (d) {
2916        closedir(d);
2917    } else {
2918        path="A";
2919    }
2920
2921    gui_fselect_init(LANG_STR_SELECT_SYMBOL_FILE, path, gui_draw_symbol_rbf_selected);
2922}
2923
2924//-------------------------------------------------------------------
2925static void gui_draw_lang_selected(const char *fn) {
2926    if (fn) {
2927        strcpy(conf.lang_file, fn);
2928        lang_load_from_file(conf.lang_file);
2929        gui_menu_init(NULL);
2930    }
2931}
2932void gui_draw_load_lang(int arg) {
2933    DIR   *d;
2934    char  *path="A/CHDK/LANG";
2935
2936    // if exists "A/CHDK/LANG" go into
2937    d=opendir(path);
2938    if (d) {
2939        closedir(d);
2940    } else {
2941        path="A";
2942    }
2943
2944    gui_fselect_init(LANG_STR_SELECT_LANG_FILE, path, gui_draw_lang_selected);
2945}
2946
2947int find_mnu(CMenu *curr_menu, int mnu, int count)
2948{
2949        int gui_menu_curr_item;
2950
2951        gui_menu_curr_item = 0;
2952        while(curr_menu->menu[gui_menu_curr_item].text) {
2953                if (curr_menu->menu[gui_menu_curr_item].text == mnu){
2954                        user_submenu_items[count] = curr_menu->menu[gui_menu_curr_item];
2955                        return 1;
2956                }
2957                if ((curr_menu->menu[gui_menu_curr_item].type & MENUITEM_MASK) == MENUITEM_SUBMENU)
2958                        if (curr_menu->menu[gui_menu_curr_item].text != LANG_MENU_USER_MENU)
2959                                if (find_mnu((CMenu*)(curr_menu->menu[gui_menu_curr_item].value), mnu, count)) return 1;
2960                gui_menu_curr_item++;
2961        }
2962        return 0;
2963}
2964
2965void user_menu_save() {
2966    int x;
2967        for (x=0; x<USER_MENU_ITEMS; x++) {
2968                /*
2969                 * First entry in user_submenu_items is reserved for the "Main Menu"
2970                 * conf.user_menu_vars only traks/saves the real user entries.
2971                 */
2972                conf.user_menu_vars[x] = user_submenu_items[x+1].text;
2973        }
2974}
2975
2976void user_menu_restore() {
2977     int x;
2978        for (x=0; x<USER_MENU_ITEMS; x++) {
2979                /*
2980                 * First entry in user_submenu_items is reserved for the "Main Menu"
2981                 * conf.user_menu_vars only traks/saves the real user entries.
2982                 */
2983                find_mnu(&root_menu, conf.user_menu_vars[x], x+1);
2984        }
2985}
2986
2987#ifdef OPT_DEBUGGING
2988
2989void gui_compare_props(int arg)
2990{
2991        #define NUM_PROPS 512
2992        // never freed, but not allocated unless prop compare is used once
2993        static int *props = NULL;
2994        char buf[64];
2995        int i;
2996        int p;
2997        int c;
2998
2999        if( props )
3000        { // we have previous data set! do a comparison
3001                c = 0;
3002                for( i = 0; i < NUM_PROPS; ++i )
3003                {
3004                        p = shooting_get_prop(i);
3005                        if( props[i] != p )
3006                        {
3007                                ++c;
3008                                sprintf(buf,"%4d is %8d was %8d",i,p,props[i]);
3009                                draw_string(16,16*c,buf,MAKE_COLOR(COLOR_BLACK,COLOR_YELLOW));
3010                        }
3011                        props[i] = p;
3012                        if( c == 12 )
3013                        {
3014                                ++c;
3015                                sprintf(buf,"%s","Waiting 15 Seconds");
3016                                draw_string(16,16*c,buf,MAKE_COLOR(COLOR_BLACK,COLOR_YELLOW));
3017                                msleep(15000);
3018                                c = 0;
3019                        }
3020                }
3021                ++c;
3022                sprintf(buf,"%s","Press <ALT> to leave");
3023                draw_string(16,16*c,buf,MAKE_COLOR(COLOR_BLACK,COLOR_YELLOW));
3024        }
3025        else
3026        {
3027        // no previous data was set so we save the data initially
3028                props = (int *)malloc(NUM_PROPS*sizeof(int));
3029                if(props) {
3030                        for( i = 0; i < NUM_PROPS; ++i )
3031                        {
3032                                props[i] = shooting_get_prop(i);
3033                        }
3034                }
3035        }
3036}
3037
3038#endif
Note: See TracBrowser for help on using the repository browser.