* removed some more unused stuff in the simulator makefile
[kugel-rb.git] / apps / settings.c
blobc9e281dae01dcfb76401f04e603cc9b028e35f09
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 by wavey@wavey.org
11 * RTC config saving code (C) 2002 by hessu@hes.iki.fi
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
19 ****************************************************************************/
20 #include <stdio.h>
21 #include "config.h"
22 #include "kernel.h"
23 #include "thread.h"
24 #include "settings.h"
25 #include "disk.h"
26 #include "panic.h"
27 #include "debug.h"
28 #include "button.h"
29 #include "usb.h"
30 #include "backlight.h"
31 #include "lcd.h"
32 #include "mpeg.h"
33 #include "mp3_playback.h"
34 #include "talk.h"
35 #include "string.h"
36 #include "ata.h"
37 #include "fat.h"
38 #include "power.h"
39 #include "backlight.h"
40 #include "powermgmt.h"
41 #include "status.h"
42 #include "atoi.h"
43 #include "screens.h"
44 #include "ctype.h"
45 #include "file.h"
46 #include "errno.h"
47 #include "system.h"
48 #include "misc.h"
49 #include "timefuncs.h"
50 #ifdef HAVE_LCD_BITMAP
51 #include "icons.h"
52 #include "font.h"
53 #include "peakmeter.h"
54 #include "hwcompat.h"
55 #endif
56 #include "lang.h"
57 #include "language.h"
58 #include "wps-display.h"
59 #include "powermgmt.h"
60 #include "bookmark.h"
61 #include "sprintf.h"
62 #include "keyboard.h"
63 #include "version.h"
64 #ifdef HAVE_MAS3507D
65 void dac_line_in(bool enable);
66 #endif
67 struct user_settings global_settings;
68 char rockboxdir[] = ROCKBOX_DIR; /* config/font/data file directory */
69 char rec_base_directory[] = REC_BASE_DIR;
72 #define CONFIG_BLOCK_VERSION 10
73 #define CONFIG_BLOCK_SIZE 512
74 #define RTC_BLOCK_SIZE 44
76 #ifdef HAVE_LCD_BITMAP
77 #define MAX_LINES 10
78 #else
79 #define MAX_LINES 2
80 #endif
82 /********************************************
84 Config block as saved on the battery-packed RTC user RAM memory block
85 of 44 bytes, starting at offset 0x14 of the RTC memory space.
87 offset abs
88 0x00 0x14 "Roc" header signature: 0x52 0x6f 0x63
89 0x03 0x17 <version byte: 0x0>
90 0x04 0x18 <volume byte>
91 0x05 0x19 <balance byte>
92 0x06 0x1a <bass byte>
93 0x07 0x1b <treble byte>
94 0x08 0x1c <loudness byte>
95 0x09 0x1d <bass boost byte>
96 0x0a 0x1e <contrast (bit 0-5), invert bit (bit 6), show_icons (bit 7)>
97 0x0b 0x1f <backlight_on_when_charging, invert_cursor, backlight_timeout>
98 0x0c 0x20 <poweroff timer byte>
99 0x0d 0x21 <resume settings byte>
100 0x0e 0x22 <shuffle,dirfilter,sort_case,discharge,statusbar,show_hidden,
101 scroll bar>
102 0x0f 0x23 <volume type, battery type, timeformat, scroll speed>
103 0x10 0x24 <ff/rewind min step, acceleration rate>
104 0x11 0x25 <AVC, channel config>
105 0x12 0x26 <(short) Resume playlist index, or -1 if no playlist resume>
106 0x14 0x28 <(short) Resume playlist first index>
107 0x16 0x2a <(int) Byte offset into resume file>
108 0x1a 0x2e <time until disk spindown>
109 0x1b 0x2f <browse current, play selected, recursive dir insert>
110 0x1c 0x30 <peak meter hold timeout (bit 0-4),
111 flip_display (bit 6)
112 rec_editable (bit 7)>
113 0x1d 0x31 <(int) Resume shuffle seed, or -1 if no shuffle>
114 0x21 0x35 <repeat mode (bit 0-1), rec. channels (bit 2),
115 mic gain (bit 4-7)>
116 0x22 0x36 <rec. quality (bit 0-2), source (bit 3-4), frequency (bit 5-7)>
117 0x23 0x37 <rec. left gain (bit 0-3)>
118 0x24 0x38 <rec. right gain (bit 0-3)>
119 0x25 0x39 <disk poweroff flag (bit 0), MP3 buffer margin (bit 1-3),
120 Trickle charge flag (bit 4), buttonbar (bit 5)>
121 0x26 0x40 <runtime low byte>
122 0x27 0x41 <runtime high byte>
123 0x28 0x42 <topruntime low byte>
124 0x29 0x43 <topruntime high byte>
126 0x2a <checksum 2 bytes: xor of 0x0-0x29>
128 Config memory is reset to 0xff and initialized with 'factory defaults' if
129 a valid header & checksum is not found. Config version number is only
130 increased when information is _relocated_ or space is _reused_ so that old
131 versions can read and modify configuration changed by new versions. New
132 versions should check for the value of '0xff' in each config memory
133 location used, and reset the setting in question with a factory default if
134 needed. Memory locations not used by a given version should not be
135 modified unless the header & checksum test fails.
137 Because 0xff mean that the byte is unused, care must be taken so that
138 a used byte can't have the value 0xff. Either use only 7 bits, or make sure
139 that the value will never be 0xff.
141 Rest of config block, only saved to disk:
142 0xA8 (char)jump scroll mode (only for player)
143 0xA9 (char)jump scroll delay (only for player)
144 0xAA Max number of files in playlist (1000-20000)
145 0xAC Max number of files in dir (50-10000)
146 0xAE fade on pause/unpause/stop setting (bit 0)
147 caption backlight (bit 1)
148 car adapter mode (bit 2)
149 line_in (Player only) (bit 3)
150 playlist viewer icons (bit 4)
151 playlist viewer indices (bit 5)
152 playlist viewer track display (bit 6)
153 0xAF <most-recent-bookmarks, auto-bookmark, autoload>
154 0xB0 peak meter clip hold timeout (bit 0-4), peak meter performance (bit 7)
155 0xB1 peak meter release step size, peak_meter_dbfs (bit 7)
156 0xB2 peak meter min either in -db or in percent
157 0xB3 peak meter max either in -db or in percent
158 0xB4 battery capacity
159 0xB5 scroll step in pixels
160 0xB6 scroll start and endpoint delay
161 0xB7 bidir scroll setting (bidi if 0-200% longer than screen width)
162 0xB8 (char[20]) WPS file
163 0xCC (char[20]) Lang file
164 0xE0 (char[20]) Font file
165 0xF4 Prerecording time (bit 0-4), Recording directory option (bit 5-6)
166 0xF5-0xFF <unused>
168 *************************************/
170 #include "rtc.h"
171 long lasttime = 0;
172 static unsigned char config_block[CONFIG_BLOCK_SIZE];
175 * Calculates the checksum for the config block and returns it
178 static unsigned short calculate_config_checksum(unsigned char* buf)
180 unsigned int i;
181 unsigned char cksum[2];
182 cksum[0] = cksum[1] = 0;
184 for (i=0; i < RTC_BLOCK_SIZE - 2; i+=2 ) {
185 cksum[0] ^= buf[i];
186 cksum[1] ^= buf[i+1];
189 return (cksum[0] << 8) | cksum[1];
193 * initialize the config block buffer
195 static void init_config_buffer( void )
197 DEBUGF( "init_config_buffer()\n" );
199 /* reset to 0xff - all unused */
200 memset(config_block, 0xff, CONFIG_BLOCK_SIZE);
201 /* insert header */
202 config_block[0] = 'R';
203 config_block[1] = 'o';
204 config_block[2] = 'c';
205 config_block[3] = CONFIG_BLOCK_VERSION;
209 * save the config block buffer to disk or RTC RAM
211 static int save_config_buffer( void )
213 unsigned short chksum;
214 #ifdef HAVE_RTC
215 unsigned int i;
216 #endif
218 DEBUGF( "save_config_buffer()\n" );
220 /* update the checksum in the end of the block before saving */
221 chksum = calculate_config_checksum(config_block);
222 config_block[ RTC_BLOCK_SIZE - 2 ] = chksum >> 8;
223 config_block[ RTC_BLOCK_SIZE - 1 ] = chksum & 0xff;
225 #ifdef HAVE_RTC
226 /* FIXME: okay, it _would_ be cleaner and faster to implement rtc_write so
227 that it would write a number of bytes at a time since the RTC chip
228 supports that, but this will have to do for now 8-) */
229 for (i=0; i < RTC_BLOCK_SIZE; i++ ) {
230 int r = rtc_write(0x14+i, config_block[i]);
231 if (r) {
232 DEBUGF( "save_config_buffer: rtc_write failed at addr 0x%02x: %d\n",
233 14+i, r );
234 return r;
238 #endif
240 if (fat_startsector() != 0)
241 ata_delayed_write( 61, config_block);
242 else
243 return -1;
245 return 0;
249 * load the config block buffer from disk or RTC RAM
251 static int load_config_buffer( void )
253 unsigned short chksum;
254 bool correct = false;
256 #ifdef HAVE_RTC
257 unsigned int i;
258 unsigned char rtc_block[RTC_BLOCK_SIZE];
259 #endif
261 DEBUGF( "load_config_buffer()\n" );
263 if (fat_startsector() != 0) {
264 ata_read_sectors( 61, 1, config_block);
266 /* calculate the checksum, check it and the header */
267 chksum = calculate_config_checksum(config_block);
269 if (config_block[0] == 'R' &&
270 config_block[1] == 'o' &&
271 config_block[2] == 'c' &&
272 config_block[3] == CONFIG_BLOCK_VERSION &&
273 (chksum >> 8) == config_block[RTC_BLOCK_SIZE - 2] &&
274 (chksum & 0xff) == config_block[RTC_BLOCK_SIZE - 1])
276 DEBUGF( "load_config_buffer: header & checksum test ok\n" );
277 correct = true;
281 #ifdef HAVE_RTC
282 if(!correct)
284 /* If the disk sector was incorrect, reinit the buffer */
285 memset(config_block, 0xff, CONFIG_BLOCK_SIZE);
287 /* read rtc block */
288 for (i=0; i < RTC_BLOCK_SIZE; i++ )
289 rtc_block[i] = rtc_read(0x14+i);
291 chksum = calculate_config_checksum(rtc_block);
293 /* if rtc block is ok, use that */
294 if (rtc_block[0] == 'R' &&
295 rtc_block[1] == 'o' &&
296 rtc_block[2] == 'c' &&
297 rtc_block[3] == CONFIG_BLOCK_VERSION &&
298 (chksum >> 8) == rtc_block[RTC_BLOCK_SIZE - 2] &&
299 (chksum & 0xff) == rtc_block[RTC_BLOCK_SIZE - 1])
301 memcpy(config_block, rtc_block, RTC_BLOCK_SIZE);
302 correct = true;
304 #endif
306 if ( !correct ) {
307 /* if checksum is not valid, clear the config buffer */
308 DEBUGF( "load_config_buffer: header & checksum test failed\n" );
309 init_config_buffer();
310 return -1;
313 return 0;
317 * persist all runtime user settings to disk or RTC RAM
319 int settings_save( void )
321 DEBUGF( "settings_save()\n" );
323 /* update the config block buffer with current
324 settings and save the block in the RTC */
325 config_block[0x4] = (unsigned char)global_settings.volume;
326 config_block[0x5] = (char)global_settings.balance;
327 config_block[0x6] = (unsigned char)global_settings.bass;
328 config_block[0x7] = (unsigned char)global_settings.treble;
329 config_block[0x8] = (unsigned char)global_settings.loudness;
330 config_block[0x9] = (unsigned char)global_settings.bass_boost;
332 config_block[0xa] = (unsigned char)
333 ((global_settings.contrast & 0x3f) |
334 (global_settings.invert ? 0x40 : 0) |
335 (global_settings.show_icons ? 0x80 : 0) );
337 config_block[0xb] = (unsigned char)
338 ((global_settings.backlight_on_when_charging?0x40:0) |
339 (global_settings.invert_cursor ? 0x20 : 0) |
340 (global_settings.backlight_timeout & 0x1f));
341 config_block[0xc] = (unsigned char)global_settings.poweroff;
342 config_block[0xd] = (unsigned char)global_settings.resume;
344 config_block[0xe] = (unsigned char)
345 ((global_settings.playlist_shuffle & 1) |
346 ((global_settings.dirfilter & 1) << 1) |
347 ((global_settings.sort_case & 1) << 2) |
348 ((global_settings.discharge & 1) << 3) |
349 ((global_settings.statusbar & 1) << 4) |
350 ((global_settings.dirfilter & 2) << 4) |
351 ((global_settings.scrollbar & 1) << 6));
353 config_block[0xf] = (unsigned char)
354 ((global_settings.volume_type & 1) |
355 ((global_settings.battery_type & 1) << 1) |
356 ((global_settings.timeformat & 1) << 2) |
357 ( global_settings.scroll_speed << 3));
359 config_block[0x10] = (unsigned char)
360 ((global_settings.ff_rewind_min_step & 15) << 4 |
361 (global_settings.ff_rewind_accel & 15));
363 config_block[0x11] = (unsigned char)
364 ((global_settings.avc & 0x03) |
365 ((global_settings.channel_config & 0x07) << 2));
367 *((short*)(&config_block[0x12])) = global_settings.resume_index;
368 *((short*)(&config_block[0x14])) = global_settings.resume_first_index;
369 memcpy(&config_block[0x16], &global_settings.resume_offset, 4);
370 DEBUGF( "+Resume index %X offset %X\n",
371 global_settings.resume_index,
372 global_settings.resume_offset );
374 config_block[0x1a] = (unsigned char)global_settings.disk_spindown;
375 config_block[0x1b] = (unsigned char)
376 (((global_settings.browse_current & 1)) |
377 ((global_settings.play_selected & 1) << 1) |
378 ((global_settings.recursive_dir_insert & 3) << 2));
380 config_block[0x1c] = (unsigned char)global_settings.peak_meter_hold |
381 (global_settings.flip_display ? 0x40 : 0) |
382 (global_settings.rec_editable?0x80:0);
384 memcpy(&config_block[0x1d], &global_settings.resume_seed, 4);
386 config_block[0x21] = (unsigned char)
387 ((global_settings.repeat_mode & 3) |
388 ((global_settings.rec_channels & 1) << 2) |
389 ((global_settings.rec_mic_gain & 0x0f) << 4));
390 config_block[0x22] = (unsigned char)
391 ((global_settings.rec_quality & 7) |
392 ((global_settings.rec_source & 3) << 3) |
393 ((global_settings.rec_frequency & 7) << 5));
394 config_block[0x23] = (unsigned char)global_settings.rec_left_gain;
395 config_block[0x24] = (unsigned char)global_settings.rec_right_gain;
396 config_block[0x25] = (unsigned char)
397 ((global_settings.disk_poweroff & 1) |
398 ((global_settings.buffer_margin & 7) << 1) |
399 ((global_settings.trickle_charge & 1) << 4) |
400 ((global_settings.buttonbar & 1) << 5));
403 int elapsed_secs;
405 elapsed_secs = (current_tick - lasttime) / HZ;
406 global_settings.runtime += elapsed_secs;
407 lasttime += (elapsed_secs * HZ);
409 if ( global_settings.runtime > global_settings.topruntime )
410 global_settings.topruntime = global_settings.runtime;
412 config_block[0x26]=(unsigned char)(global_settings.runtime & 0xff);
413 config_block[0x27]=(unsigned char)(global_settings.runtime >> 8);
414 config_block[0x28]=(unsigned char)(global_settings.topruntime & 0xff);
415 config_block[0x29]=(unsigned char)(global_settings.topruntime >> 8);
418 #ifdef HAVE_LCD_CHARCELLS
419 config_block[0xa8]=(unsigned char)global_settings.jump_scroll;
420 config_block[0xa9]=(unsigned char)global_settings.jump_scroll_delay;
421 #endif
422 config_block[0xaa] = (unsigned char)
423 global_settings.max_files_in_playlist & 0xff;
424 config_block[0xab] = (unsigned char)
425 (global_settings.max_files_in_playlist >> 8) & 0xff;
426 config_block[0xac] = (unsigned char)
427 global_settings.max_files_in_dir & 0xff;
428 config_block[0xad] = (unsigned char)
429 (global_settings.max_files_in_dir >> 8) & 0xff;
430 config_block[0xae] = (unsigned char)
431 ((global_settings.fade_on_stop & 1) |
432 ((global_settings.caption_backlight & 1) << 1) |
433 ((global_settings.car_adapter_mode & 1) << 2) |
434 ((global_settings.line_in & 1) << 3) |
435 ((global_settings.playlist_viewer_icons & 1) << 4) |
436 ((global_settings.playlist_viewer_indices & 1) << 5) |
437 ((global_settings.playlist_viewer_track_display & 1) << 6));
438 config_block[0xaf] = ((global_settings.usemrb << 5) |
439 (global_settings.autocreatebookmark << 2) |
440 (global_settings.autoloadbookmark));
441 config_block[0xb0] = (unsigned char)global_settings.peak_meter_clip_hold |
442 (global_settings.peak_meter_performance ? 0x80 : 0);
443 config_block[0xb1] = global_settings.peak_meter_release |
444 (global_settings.peak_meter_dbfs ? 0x80 : 0);
445 config_block[0xb2] = (unsigned char)global_settings.peak_meter_min;
446 config_block[0xb3] = (unsigned char)global_settings.peak_meter_max;
448 config_block[0xb4]=(global_settings.battery_capacity - 1000) / 50;
449 config_block[0xb5]=(unsigned char)global_settings.scroll_step;
450 config_block[0xb6]=(unsigned char)global_settings.scroll_delay;
451 config_block[0xb7]=(unsigned char)global_settings.bidir_limit;
453 strncpy(&config_block[0xb8], global_settings.wps_file, MAX_FILENAME);
454 strncpy(&config_block[0xcc], global_settings.lang_file, MAX_FILENAME);
455 strncpy(&config_block[0xe0], global_settings.font_file, MAX_FILENAME);
457 config_block[0xf4]=((unsigned char)global_settings.rec_prerecord_time |
458 ((unsigned char)global_settings.rec_directory << 5));
459 config_block[0xf5] = (global_settings.talk_dir & 7) |
460 ((global_settings.talk_file & 3) << 3) |
461 ((global_settings.talk_menu & 1) << 5);
463 if(save_config_buffer())
465 lcd_clear_display();
466 #ifdef HAVE_LCD_CHARCELLS
467 lcd_puts(0, 0, str(LANG_SETTINGS_SAVE_PLAYER));
468 lcd_puts(0, 1, str(LANG_SETTINGS_BATTERY_PLAYER));
469 #else
470 lcd_puts(4, 2, str(LANG_SETTINGS_SAVE_RECORDER));
471 lcd_puts(2, 4, str(LANG_SETTINGS_BATTERY_RECORDER));
472 lcd_update();
473 #endif
474 sleep(HZ*2);
475 return -1;
477 return 0;
480 #ifdef HAVE_LCD_BITMAP
482 * Applies the range infos stored in global_settings to
483 * the peak meter.
485 void settings_apply_pm_range(void)
487 int pm_min, pm_max;
489 /* depending on the scale mode (dBfs or percent) the values
490 of global_settings.peak_meter_dbfs have different meanings */
491 if (global_settings.peak_meter_dbfs)
493 /* convert to dBfs * 100 */
494 pm_min = -(((int)global_settings.peak_meter_min) * 100);
495 pm_max = -(((int)global_settings.peak_meter_max) * 100);
497 else
499 /* percent is stored directly -> no conversion */
500 pm_min = global_settings.peak_meter_min;
501 pm_max = global_settings.peak_meter_max;
504 /* apply the range */
505 peak_meter_init_range(global_settings.peak_meter_dbfs, pm_min, pm_max);
507 #endif /* HAVE_LCD_BITMAP */
509 void settings_apply(void)
511 char buf[64];
513 mpeg_sound_set(SOUND_BASS, global_settings.bass);
514 mpeg_sound_set(SOUND_TREBLE, global_settings.treble);
515 mpeg_sound_set(SOUND_BALANCE, global_settings.balance);
516 mpeg_sound_set(SOUND_VOLUME, global_settings.volume);
517 mpeg_sound_set(SOUND_CHANNELS, global_settings.channel_config);
518 #ifdef HAVE_MAS3587F
519 mpeg_sound_set(SOUND_LOUDNESS, global_settings.loudness);
520 mpeg_sound_set(SOUND_SUPERBASS, global_settings.bass_boost);
521 mpeg_sound_set(SOUND_AVC, global_settings.avc);
522 #endif
524 mpeg_set_buffer_margin(global_settings.buffer_margin);
526 lcd_set_contrast(global_settings.contrast);
527 lcd_scroll_speed(global_settings.scroll_speed);
528 backlight_set_timeout(global_settings.backlight_timeout);
529 backlight_set_on_when_charging(global_settings.backlight_on_when_charging);
530 ata_spindown(global_settings.disk_spindown);
531 #ifdef HAVE_MAS3507D
532 dac_line_in(global_settings.line_in);
533 #endif
534 #ifdef HAVE_ATA_POWER_OFF
535 ata_poweroff(global_settings.disk_poweroff);
536 #endif
538 set_poweroff_timeout(global_settings.poweroff);
539 #ifdef HAVE_CHARGE_CTRL
540 charge_restart_level = global_settings.discharge ?
541 CHARGE_RESTART_LO : CHARGE_RESTART_HI;
542 enable_trickle_charge(global_settings.trickle_charge);
543 #endif
545 set_battery_capacity(global_settings.battery_capacity);
547 #ifdef HAVE_LCD_BITMAP
548 lcd_set_invert_display(global_settings.invert);
549 lcd_set_flip(global_settings.flip_display);
550 button_set_flip(global_settings.flip_display);
551 lcd_update(); /* refresh after flipping the screen */
552 settings_apply_pm_range();
553 peak_meter_init_times(
554 global_settings.peak_meter_release, global_settings.peak_meter_hold,
555 global_settings.peak_meter_clip_hold);
556 #endif
558 if ( global_settings.wps_file[0] &&
559 global_settings.wps_file[0] != 0xff ) {
560 snprintf(buf, sizeof buf, ROCKBOX_DIR "/%s.wps",
561 global_settings.wps_file);
562 wps_load(buf, false);
564 else
565 wps_reset();
567 #ifdef HAVE_LCD_BITMAP
568 if ( global_settings.font_file[0] &&
569 global_settings.font_file[0] != 0xff ) {
570 snprintf(buf, sizeof buf, ROCKBOX_DIR FONT_DIR "/%s.fnt",
571 global_settings.font_file);
572 font_load(buf);
574 else
575 font_reset();
577 lcd_scroll_step(global_settings.scroll_step);
578 #else
579 lcd_jump_scroll(global_settings.jump_scroll);
580 lcd_jump_scroll_delay(global_settings.jump_scroll_delay * (HZ/10));
581 #endif
582 lcd_bidir_scroll(global_settings.bidir_limit);
583 lcd_scroll_delay(global_settings.scroll_delay * (HZ/10));
585 if ( global_settings.lang_file[0] &&
586 global_settings.lang_file[0] != 0xff ) {
587 snprintf(buf, sizeof buf, ROCKBOX_DIR LANG_DIR "/%s.lng",
588 global_settings.lang_file);
589 lang_load(buf);
590 talk_init(); /* use voice of same language */
593 set_car_adapter_mode(global_settings.car_adapter_mode);
597 * load settings from disk or RTC RAM
599 void settings_load(void)
602 DEBUGF( "reload_all_settings()\n" );
604 /* populate settings with default values */
605 settings_reset();
607 /* load the buffer from the RTC (resets it to all-unused if the block
608 is invalid) and decode the settings which are set in the block */
609 if (!load_config_buffer()) {
610 if (config_block[0x4] != 0xFF)
611 global_settings.volume = config_block[0x4];
612 if (config_block[0x5] != 0xFF)
613 global_settings.balance = (char)config_block[0x5];
614 if (config_block[0x6] != 0xFF)
615 global_settings.bass = config_block[0x6];
616 if (config_block[0x7] != 0xFF)
617 global_settings.treble = config_block[0x7];
618 if (config_block[0x8] != 0xFF)
619 global_settings.loudness = config_block[0x8];
620 if (config_block[0x9] != 0xFF)
621 global_settings.bass_boost = config_block[0x9];
623 if (config_block[0xa] != 0xFF) {
624 global_settings.contrast = config_block[0xa] & 0x3f;
625 global_settings.invert =
626 config_block[0xa] & 0x40 ? true : false;
627 if ( global_settings.contrast < MIN_CONTRAST_SETTING )
628 global_settings.contrast = lcd_default_contrast();
629 global_settings.show_icons =
630 config_block[0xa] & 0x80 ? true : false;
633 if (config_block[0xb] != 0xFF) {
634 /* Bit 7 is unused to be able to detect uninitialized entry */
635 global_settings.backlight_timeout = config_block[0xb] & 0x1f;
636 global_settings.invert_cursor =
637 config_block[0xb] & 0x20 ? true : false;
638 global_settings.backlight_on_when_charging =
639 config_block[0xb] & 0x40 ? true : false;
642 if (config_block[0xc] != 0xFF)
643 global_settings.poweroff = config_block[0xc];
644 if (config_block[0xd] != 0xFF)
645 global_settings.resume = config_block[0xd];
646 if (config_block[0xe] != 0xFF) {
647 global_settings.playlist_shuffle = config_block[0xe] & 1;
648 global_settings.dirfilter = (config_block[0xe] >> 1) & 1;
649 global_settings.sort_case = (config_block[0xe] >> 2) & 1;
650 global_settings.discharge = (config_block[0xe] >> 3) & 1;
651 global_settings.statusbar = (config_block[0xe] >> 4) & 1;
652 global_settings.dirfilter |= ((config_block[0xe] >> 5) & 1) << 1;
653 global_settings.scrollbar = (config_block[0xe] >> 6) & 1;
654 /* Don't use the last bit, it must be unused to detect
655 an uninitialized entry */
658 if (config_block[0xf] != 0xFF) {
659 global_settings.volume_type = config_block[0xf] & 1;
660 global_settings.battery_type = (config_block[0xf] >> 1) & 1;
661 global_settings.timeformat = (config_block[0xf] >> 2) & 1;
662 global_settings.scroll_speed = config_block[0xf] >> 3;
665 if (config_block[0x10] != 0xFF) {
666 global_settings.ff_rewind_min_step = (config_block[0x10] >> 4) & 15;
667 global_settings.ff_rewind_accel = config_block[0x10] & 15;
670 if (config_block[0x11] != 0xFF)
672 global_settings.avc = config_block[0x11] & 0x03;
673 global_settings.channel_config = (config_block[0x11] >> 2) & 0x07;
676 if (config_block[0x12] != 0xFF)
677 global_settings.resume_index = *((short*)(&config_block[0x12]));
679 if (config_block[0x14] != 0xFF)
680 global_settings.resume_first_index= *((short*)(&config_block[0x14]));
682 if (config_block[0x16] != 0xFF)
683 memcpy(&global_settings.resume_offset, &config_block[0x16], 4);
685 if (config_block[0x1a] != 0xFF)
686 global_settings.disk_spindown = config_block[0x1a];
688 if (config_block[0x1b] != 0xFF) {
689 global_settings.browse_current = (config_block[0x1b]) & 1;
690 global_settings.play_selected = (config_block[0x1b] >> 1) & 1;
691 global_settings.recursive_dir_insert =
692 (config_block[0x1b] >> 2) & 3;
695 if (config_block[0x1c] != 0xFF) {
696 global_settings.peak_meter_hold = (config_block[0x1c]) & 0x1f;
697 global_settings.flip_display =
698 (config_block[0x1c] & 0x40)?true:false;
699 global_settings.rec_editable =
700 (config_block[0x1c] & 0x80)?true:false;
703 if (config_block[0x1d] != 0xFF)
704 memcpy(&global_settings.resume_seed, &config_block[0x1d], 4);
706 if (config_block[0x21] != 0xFF)
708 global_settings.repeat_mode = config_block[0x21] & 3;
709 global_settings.rec_channels = (config_block[0x21] >> 2) & 1;
710 global_settings.rec_mic_gain = (config_block[0x21] >> 4) & 0x0f;
713 if (config_block[0x22] != 0xFF)
715 global_settings.rec_quality = config_block[0x22] & 7;
716 global_settings.rec_source = (config_block[0x22] >> 3) & 3;
717 global_settings.rec_frequency = (config_block[0x22] >> 5) & 7;
720 if (config_block[0x23] != 0xFF)
721 global_settings.rec_left_gain = config_block[0x23] & 0x0f;
723 if (config_block[0x24] != 0xFF)
724 global_settings.rec_right_gain = config_block[0x24] & 0x0f;
726 if (config_block[0x25] != 0xFF)
728 global_settings.disk_poweroff = config_block[0x25] & 1;
729 global_settings.buffer_margin = (config_block[0x25] >> 1) & 7;
730 global_settings.trickle_charge = (config_block[0x25] >> 4) & 1;
731 global_settings.buttonbar = (config_block[0x25] >> 5) & 1;
734 if (config_block[0x27] != 0xff)
735 global_settings.runtime =
736 config_block[0x26] | (config_block[0x27] << 8);
738 if (config_block[0x29] != 0xff)
739 global_settings.topruntime =
740 config_block[0x28] | (config_block[0x29] << 8);
742 if (config_block[0xae] != 0xff) {
743 global_settings.fade_on_stop = config_block[0xae] & 1;
744 global_settings.caption_backlight = (config_block[0xae] >> 1) & 1;
745 global_settings.car_adapter_mode = (config_block[0xae] >> 2) & 1;
746 global_settings.line_in = (config_block[0xae] >> 3) & 1;
747 global_settings.playlist_viewer_icons =
748 (config_block[0xae] >> 4) & 1;
749 global_settings.playlist_viewer_indices =
750 (config_block[0xae] >> 5) & 1;
751 global_settings.playlist_viewer_track_display =
752 (config_block[0xae] >> 6) & 1;
755 if(config_block[0xb0] != 0xff) {
756 global_settings.peak_meter_clip_hold = (config_block[0xb0]) & 0x1f;
757 global_settings.peak_meter_performance =
758 (config_block[0xb0] & 0x80) != 0;
761 if(config_block[0xb1] != 0xff) {
762 global_settings.peak_meter_release = config_block[0xb1] & 0x7f;
763 global_settings.peak_meter_dbfs = (config_block[0xb1] & 0x80) != 0;
766 if(config_block[0xb2] != 0xff)
767 global_settings.peak_meter_min = config_block[0xb2];
769 if(config_block[0xb3] != 0xff)
770 global_settings.peak_meter_max = config_block[0xb3];
772 if(config_block[0xb4] != 0xff)
773 global_settings.battery_capacity = config_block[0xb4]*50 + 1000;
775 if (config_block[0xb5] != 0xff)
776 global_settings.scroll_step = config_block[0xb5];
778 if (config_block[0xb6] != 0xff)
779 global_settings.scroll_delay = config_block[0xb6];
781 if (config_block[0xb7] != 0xff)
782 global_settings.bidir_limit = config_block[0xb7];
784 if (config_block[0xac] != 0xff)
785 global_settings.max_files_in_dir =
786 config_block[0xac] | (config_block[0xad] << 8);
788 if (config_block[0xaa] != 0xff)
789 global_settings.max_files_in_playlist =
790 config_block[0xaa] | (config_block[0xab] << 8);
792 strncpy(global_settings.wps_file, &config_block[0xb8], MAX_FILENAME);
793 strncpy(global_settings.lang_file, &config_block[0xcc], MAX_FILENAME);
794 strncpy(global_settings.font_file, &config_block[0xe0], MAX_FILENAME);
796 if (config_block[0xf4] != 0xff) {
797 global_settings.rec_prerecord_time = config_block[0xf4] & 0x1f;
798 global_settings.rec_directory = (config_block[0xf4] >> 5) & 3;
800 if (config_block[0xf5] != 0xff) {
801 global_settings.talk_dir = config_block[0xf5] & 7;
802 global_settings.talk_file = (config_block[0xf5] >> 3) & 3;
803 global_settings.talk_menu = (config_block[0xf5] >> 5) & 1;
806 #ifdef HAVE_LCD_CHARCELLS
807 if (config_block[0xa8] != 0xff)
808 global_settings.jump_scroll = config_block[0xa8];
809 if (config_block[0xa9] != 0xff)
810 global_settings.jump_scroll_delay = config_block[0xa9];
811 #endif
812 if(config_block[0xaf] != 0xff) {
813 global_settings.usemrb = (config_block[0xaf] >> 5) & 3;
814 global_settings.autocreatebookmark = (config_block[0xaf] >> 2) & 7;
815 global_settings.autoloadbookmark = (config_block[0xaf]) & 3;
819 settings_apply();
822 /* parse a line from a configuration file. the line format is:
824 setting name: setting value
826 Any whitespace before setting name or value (after ':') is ignored.
827 A # as first non-whitespace character discards the whole line.
828 Function sets pointers to null-terminated setting name and value.
829 Returns false if no valid config entry was found.
832 static bool settings_parseline(char* line, char** name, char** value)
834 char* ptr;
836 while ( isspace(*line) )
837 line++;
839 if ( *line == '#' )
840 return false;
842 ptr = strchr(line, ':');
843 if ( !ptr )
844 return false;
846 *name = line;
847 *ptr = 0;
848 ptr++;
849 while (isspace(*ptr))
850 ptr++;
851 *value = ptr;
852 return true;
855 void set_file(char* filename, char* setting, int maxlen)
857 char* fptr = strrchr(filename,'/');
858 int len;
859 int extlen = 0;
860 char* ptr;
862 if (!fptr)
863 return;
865 *fptr = 0;
866 fptr++;
868 len = strlen(fptr);
869 ptr = fptr + len;
870 while (*ptr != '.') {
871 extlen++;
872 ptr--;
875 if (strncmp(ROCKBOX_DIR, filename ,strlen(ROCKBOX_DIR)) ||
876 (len-extlen > maxlen))
877 return;
879 strncpy(setting, fptr, len-extlen);
880 setting[len-extlen]=0;
882 settings_save();
885 static void set_sound(char* value, int type, int* setting)
887 int num = atoi(value);
889 num = mpeg_phys2val(type, num);
891 if ((num > mpeg_sound_max(type)) ||
892 (num < mpeg_sound_min(type)))
894 num = mpeg_sound_default(type);
897 *setting = num;
898 mpeg_sound_set(type, num);
900 #ifdef HAVE_MAS3507D
901 /* This is required to actually apply balance */
902 if (SOUND_BALANCE == type)
903 mpeg_sound_set(SOUND_VOLUME, global_settings.volume);
904 #endif
907 static void set_cfg_bool(bool* variable, char* value)
909 /* look for the 'n' in 'on' */
910 if ((value[1] & 0xdf) == 'N')
911 *variable = true;
912 else
913 *variable = false;
916 static void set_cfg_int(int* variable, char* value, int min, int max )
918 *variable = atoi(value);
920 if (*variable < min)
921 *variable = min;
922 else
923 if (*variable > max)
924 *variable = max;
927 static void set_cfg_option(int* variable, char* value,
928 char* options[], int numoptions )
930 int i;
932 for (i=0; i<numoptions; i++) {
933 if (!strcasecmp(options[i], value)) {
934 *variable = i;
935 break;
940 bool settings_load_config(char* file)
942 int fd;
943 char line[128];
945 fd = open(file, O_RDONLY);
946 if (fd < 0)
947 return false;
949 while (read_line(fd, line, sizeof line) > 0)
951 char* name;
952 char* value;
954 if (!settings_parseline(line, &name, &value))
955 continue;
957 if (!strcasecmp(name, "volume"))
958 set_sound(value, SOUND_VOLUME, &global_settings.volume);
959 else if (!strcasecmp(name, "bass"))
960 set_sound(value, SOUND_BASS, &global_settings.bass);
961 else if (!strcasecmp(name, "treble"))
962 set_sound(value, SOUND_TREBLE, &global_settings.treble);
963 else if (!strcasecmp(name, "balance"))
964 set_sound(value, SOUND_BALANCE, &global_settings.balance);
965 else if (!strcasecmp(name, "channels")) {
966 static char* options[] = {
967 "stereo","stereo narrow","mono","mono left",
968 "mono right","karaoke","stereo wide"};
969 set_cfg_option(&global_settings.channel_config, value,
970 options, 7);
972 else if (!strcasecmp(name, "wps")) {
973 if (wps_load(value,false))
974 set_file(value, global_settings.wps_file, MAX_FILENAME);
976 else if (!strcasecmp(name, "lang")) {
977 if (!lang_load(value))
979 set_file(value, global_settings.lang_file, MAX_FILENAME);
980 talk_init(); /* use voice of same language */
983 else if (!strcasecmp(name, "bidir limit"))
984 set_cfg_int(&global_settings.bidir_limit, value, 0, 200);
985 #ifdef HAVE_LCD_BITMAP
986 else if (!strcasecmp(name, "font")) {
987 if (font_load(value))
988 set_file(value, global_settings.font_file, MAX_FILENAME);
990 else if (!strcasecmp(name, "scroll step"))
991 set_cfg_int(&global_settings.scroll_step, value, 1, LCD_WIDTH);
992 else if (!strcasecmp(name, "statusbar"))
993 set_cfg_bool(&global_settings.statusbar, value);
994 else if (!strcasecmp(name, "buttonbar"))
995 set_cfg_bool(&global_settings.buttonbar, value);
996 else if (!strcasecmp(name, "peak meter release"))
997 set_cfg_int(&global_settings.peak_meter_release, value, 1, 0x7e);
998 else if (!strcasecmp(name, "peak meter hold")) {
999 static char* options[] = {
1000 "off","200ms","300ms","500ms",
1001 "1","2","3","4","5","6","7","8","9","10",
1002 "15","20","30","1min"};
1003 set_cfg_option(&global_settings.peak_meter_hold, value,
1004 options, 18);
1006 else if (!strcasecmp(name, "peak meter clip hold")) {
1007 static char* options[] = {
1008 "on","1","2","3","4","5","6","7","8","9","10",
1009 "15","20","25","30","45","60","90",
1010 "2min","3min","5min","10min","20min","45min","90min"};
1011 set_cfg_option(&global_settings.peak_meter_clip_hold, value,
1012 options, 25);
1014 else if (!strcasecmp(name, "peak meter dbfs"))
1015 set_cfg_bool(&global_settings.peak_meter_dbfs, value);
1016 else if (!strcasecmp(name, "peak meter min"))
1017 set_cfg_int(&global_settings.peak_meter_min, value, 0, 100);
1018 else if (!strcasecmp(name, "peak meter max"))
1019 set_cfg_int(&global_settings.peak_meter_max, value, 0, 100);
1020 else if (!strcasecmp(name, "peak meter busy"))
1021 set_cfg_bool(&global_settings.peak_meter_performance, value);
1022 else if (!strcasecmp(name, "volume display")) {
1023 static char* options[] = {"graphic", "numeric"};
1024 set_cfg_option(&global_settings.volume_type, value, options, 2);
1026 else if (!strcasecmp(name, "battery display")) {
1027 static char* options[] = {"graphic", "numeric"};
1028 set_cfg_option(&global_settings.battery_type, value, options, 2);
1030 else if (!strcasecmp(name, "time format")) {
1031 static char* options[] = {"24hour", "12hour"};
1032 set_cfg_option(&global_settings.timeformat, value, options, 2);
1034 else if (!strcasecmp(name, "scrollbar"))
1035 set_cfg_bool(&global_settings.scrollbar, value);
1036 else if (!strcasecmp(name, "invert"))
1037 set_cfg_bool(&global_settings.invert, value);
1038 else if (!strcasecmp(name, "flip display"))
1039 set_cfg_bool(&global_settings.flip_display, value);
1040 else if (!strcasecmp(name, "invert cursor"))
1041 set_cfg_bool(&global_settings.invert_cursor, value);
1042 else if (!strcasecmp(name, "show icons"))
1043 set_cfg_bool(&global_settings.show_icons, value);
1044 #endif
1045 else if (!strcasecmp(name, "caption backlight"))
1046 set_cfg_bool(&global_settings.caption_backlight, value);
1047 else if (!strcasecmp(name, "shuffle"))
1048 set_cfg_bool(&global_settings.playlist_shuffle, value);
1049 else if (!strcasecmp(name, "repeat")) {
1050 static char* options[] = {"off", "all", "one"};
1051 set_cfg_option(&global_settings.repeat_mode, value, options, 3);
1053 else if (!strcasecmp(name, "resume")) {
1054 static char* options[] = {"off", "ask", "ask once", "on"};
1055 set_cfg_option(&global_settings.resume, value, options, 4);
1057 else if (!strcasecmp(name, "sort case"))
1058 set_cfg_bool(&global_settings.sort_case, value);
1059 else if (!strcasecmp(name, "show files")) {
1060 static char* options[] = {"all", "supported","music", "playlists"};
1061 set_cfg_option(&global_settings.dirfilter, value, options, 4);
1063 else if (!strcasecmp(name, "follow playlist"))
1064 set_cfg_bool(&global_settings.browse_current, value);
1065 else if (!strcasecmp(name, "play selected"))
1066 set_cfg_bool(&global_settings.play_selected, value);
1067 else if (!strcasecmp(name, "contrast"))
1068 set_cfg_int(&global_settings.contrast, value,
1069 MIN_CONTRAST_SETTING, MAX_CONTRAST_SETTING);
1070 else if (!strcasecmp(name, "scroll speed"))
1071 set_cfg_int(&global_settings.scroll_speed, value, 1, 10);
1072 else if (!strcasecmp(name, "scan min step")) {
1073 static char* options[] =
1074 {"1","2","3","4","5","6","8","10",
1075 "15","20","25","30","45","60"};
1076 set_cfg_option(&global_settings.ff_rewind_min_step, value,
1077 options, 14);
1079 else if (!strcasecmp(name, "scan accel"))
1080 set_cfg_int(&global_settings.ff_rewind_accel, value, 0, 15);
1081 else if (!strcasecmp(name, "scroll delay"))
1082 set_cfg_int(&global_settings.scroll_delay, value, 0, 250);
1083 else if (!strcasecmp(name, "backlight timeout")) {
1084 static char* options[] = {
1085 "off","on","1","2","3","4","5","6","7","8","9",
1086 "10","15","20","25","30","45","60","90"};
1087 set_cfg_option(&global_settings.backlight_timeout, value,
1088 options, 19);
1090 else if (!strcasecmp(name, "backlight when plugged"))
1091 set_cfg_bool(&global_settings.backlight_on_when_charging, value);
1092 else if (!strcasecmp(name, "antiskip"))
1093 set_cfg_int(&global_settings.buffer_margin, value, 0, 7);
1094 else if (!strcasecmp(name, "disk spindown"))
1095 set_cfg_int(&global_settings.disk_spindown, value, 3, 254);
1096 #ifdef HAVE_ATA_POWER_OFF
1097 else if (!strcasecmp(name, "disk poweroff"))
1098 set_cfg_bool(&global_settings.disk_poweroff, value);
1099 #endif
1100 #ifdef HAVE_MAS3587F
1101 else if (!strcasecmp(name, "loudness"))
1102 set_sound(value, SOUND_LOUDNESS, &global_settings.loudness);
1103 else if (!strcasecmp(name, "bass boost"))
1104 set_sound(value, SOUND_SUPERBASS, &global_settings.bass_boost);
1105 else if (!strcasecmp(name, "auto volume")) {
1106 static char* options[] = {"off", "2", "4", "8" };
1107 set_cfg_option(&global_settings.avc, value, options, 4);
1109 else if (!strcasecmp(name, "rec mic gain"))
1110 set_sound(value, SOUND_MIC_GAIN, &global_settings.rec_mic_gain);
1111 else if (!strcasecmp(name, "rec left gain"))
1112 set_sound(value, SOUND_LEFT_GAIN, &global_settings.rec_left_gain);
1113 else if (!strcasecmp(name, "rec right gain"))
1114 set_sound(value, SOUND_RIGHT_GAIN, &global_settings.rec_right_gain);
1115 else if (!strcasecmp(name, "rec quality"))
1116 set_cfg_int(&global_settings.rec_quality, value, 0, 7);
1117 else if (!strcasecmp(name, "rec timesplit")){
1118 static char* options[] = {"off", "00:05","00:10","00:15",
1119 "00:30","01:00","02:00","04:00",
1120 "06:00","08:00","10:00","12:00",
1121 "18:00","24:00"};
1122 set_cfg_option(&global_settings.rec_timesplit, value,
1123 options, 14);
1125 else if (!strcasecmp(name, "rec source")) {
1126 static char* options[] = {"mic", "line", "spdif"};
1127 set_cfg_option(&global_settings.rec_source, value, options, 3);
1129 else if (!strcasecmp(name, "rec frequency")) {
1130 static char* options[] = {"44", "48", "32", "22", "24", "16"};
1131 set_cfg_option(&global_settings.rec_frequency, value, options, 6);
1133 else if (!strcasecmp(name, "rec channels")) {
1134 static char* options[] = {"stereo", "mono"};
1135 set_cfg_option(&global_settings.rec_channels, value, options, 2);
1137 else if (!strcasecmp(name, "editable recordings")) {
1138 set_cfg_bool(&global_settings.rec_editable, value);
1140 else if (!strcasecmp(name, "prerecording time")) {
1141 set_cfg_int(&global_settings.rec_prerecord_time, value, 0, 30);
1143 else if (!strcasecmp(name, "rec directory")) {
1144 static char* options[] = {rec_base_directory, "current"};
1145 set_cfg_option(&global_settings.rec_directory, value, options, 2);
1147 #endif
1148 else if (!strcasecmp(name, "idle poweroff")) {
1149 static char* options[] = {"off","1","2","3","4","5","6","7","8",
1150 "9","10","15","30","45","60"};
1151 set_cfg_option(&global_settings.poweroff, value, options, 15);
1153 #ifdef HAVE_MAS3507D
1154 else if (!strcasecmp(name, "line in")){
1155 set_cfg_bool(&global_settings.line_in, value);
1156 dac_line_in(global_settings.line_in);
1158 #endif
1159 else if (!strcasecmp(name, "battery capacity"))
1160 set_cfg_int(&global_settings.battery_capacity, value,
1161 1500, BATTERY_CAPACITY_MAX);
1162 #ifdef HAVE_CHARGE_CTRL
1163 else if (!strcasecmp(name, "deep discharge"))
1164 set_cfg_bool(&global_settings.discharge, value);
1165 else if (!strcasecmp(name, "trickle charge"))
1166 set_cfg_bool(&global_settings.trickle_charge, value);
1167 #endif
1168 else if (!strcasecmp(name, "volume fade"))
1169 set_cfg_bool(&global_settings.fade_on_stop, value);
1170 else if (!strcasecmp(name, "max files in dir"))
1171 set_cfg_int(&global_settings.max_files_in_dir, value,
1172 50, 10000);
1173 else if (!strcasecmp(name, "max files in playlist"))
1174 set_cfg_int(&global_settings.max_files_in_playlist, value,
1175 1000, 20000);
1176 else if (!strcasecmp(name, "car adapter mode"))
1177 set_cfg_bool(&global_settings.car_adapter_mode, value);
1178 else if (!strcasecmp(name, "recursive directory insert")) {
1179 static char* options[] = {"off", "on", "ask"};
1180 set_cfg_option(&global_settings.recursive_dir_insert, value,
1181 options, 3);
1183 else if (!strcasecmp(name, "autoload bookmarks"))
1185 static char* options[] = {"off", "on", "ask"};
1186 set_cfg_option(&global_settings.autoloadbookmark, value, options, 3);
1188 else if (!strcasecmp(name, "autocreate bookmarks"))
1190 static char* options[] = {"off", "on", "ask","recent only - on", "recent only - ask"};
1191 set_cfg_option(&global_settings.autocreatebookmark, value, options, 5);
1193 else if (!strcasecmp(name, "use most-recent-bookmarks"))
1195 static char* options[] = {"off", "on", "unique only"};
1196 set_cfg_option(&global_settings.usemrb, value, options, 3);
1198 else if (!strcasecmp(name, "playlist viewer icons"))
1199 set_cfg_bool(&global_settings.playlist_viewer_icons, value);
1200 else if (!strcasecmp(name, "playlist viewer indices"))
1201 set_cfg_bool(&global_settings.playlist_viewer_indices, value);
1202 else if (!strcasecmp(name, "playlist viewer track display"))
1204 static char* options[] = {"track name", "full path"};
1205 set_cfg_option(&global_settings.playlist_viewer_track_display,
1206 value, options, 2);
1208 else if (!strcasecmp(name, "talk dir"))
1210 static char* options[] = {"off", "number", "spell", "enter", "hover"};
1211 set_cfg_option(&global_settings.talk_dir, value, options, 5);
1213 else if (!strcasecmp(name, "talk file"))
1215 static char* options[] = {"off", "number", "spell"};
1216 set_cfg_option(&global_settings.talk_file, value, options, 3);
1218 else if (!strcasecmp(name, "talk menu"))
1220 set_cfg_bool(&global_settings.talk_menu, value);
1224 close(fd);
1225 settings_apply();
1226 settings_save();
1227 return true;
1231 bool settings_save_config(void)
1233 bool done = false;
1234 int fd, i, value;
1235 char filename[MAX_PATH];
1236 char* boolopt[] = {"off","on"};
1237 char* triopt[] = {"off","on","ask"};
1239 /* find unused filename */
1240 for (i=0; ; i++) {
1241 snprintf(filename, sizeof filename, ROCKBOX_DIR "/config%02d.cfg", i);
1242 fd = open(filename, O_RDONLY);
1243 if (fd < 0)
1244 break;
1245 close(fd);
1248 /* allow user to modify filename */
1249 while (!done) {
1250 if (!kbd_input(filename, sizeof filename)) {
1251 fd = creat(filename,0);
1252 if (fd < 0) {
1253 lcd_clear_display();
1254 lcd_puts(0,0,str(LANG_FAILED));
1255 lcd_update();
1256 sleep(HZ);
1258 else
1259 done = true;
1261 else
1262 break;
1265 /* abort if file couldn't be created */
1266 if (!done) {
1267 lcd_clear_display();
1268 lcd_puts(0,0,str(LANG_RESET_DONE_CANCEL));
1269 lcd_update();
1270 sleep(HZ);
1271 return false;
1274 fprintf(fd, "# >>> .cfg file created by rockbox %s <<<\r\n", appsversion);
1275 fprintf(fd, "# >>> http://rockbox.haxx.se <<<\r\n#\r\n");
1276 fprintf(fd, "#\r\n# wps / language / font \r\n#\r\n");
1278 if (global_settings.wps_file[0] != 0)
1279 fprintf(fd, "wps: %s/%s.wps\r\n", ROCKBOX_DIR,
1280 global_settings.wps_file);
1282 if (global_settings.lang_file[0] != 0)
1283 fprintf(fd, "lang: %s/%s.lng\r\n", ROCKBOX_DIR LANG_DIR,
1284 global_settings.lang_file);
1286 #ifdef HAVE_LCD_BITMAP
1287 if (global_settings.font_file[0] != 0)
1288 fprintf(fd, "font: %s/%s.fnt\r\n", ROCKBOX_DIR FONT_DIR,
1289 global_settings.font_file);
1290 #endif
1292 fprintf(fd, "#\r\n# Sound settings\r\n#\r\n");
1294 value = mpeg_val2phys(SOUND_VOLUME, global_settings.volume);
1295 fprintf(fd, "volume: %d\r\n", value);
1297 value = mpeg_val2phys(SOUND_BASS, global_settings.bass);
1298 fprintf(fd, "bass: %d\r\n", value);
1300 value = mpeg_val2phys(SOUND_TREBLE, global_settings.treble);
1301 fprintf(fd, "treble: %d\r\n", value);
1303 value = mpeg_val2phys(SOUND_BALANCE, global_settings.balance);
1304 fprintf(fd, "balance: %d\r\n", value);
1307 static char* options[] =
1308 {"stereo","stereo narrow","mono","mono left",
1309 "mono right","karaoke","stereo wide"};
1310 fprintf(fd, "channels: %s\r\n",
1311 options[global_settings.channel_config]);
1314 #ifdef HAVE_MAS3587F
1315 value = mpeg_val2phys(SOUND_LOUDNESS, global_settings.loudness);
1316 fprintf(fd, "loudness: %d\r\n", value);
1318 value = mpeg_val2phys(SOUND_SUPERBASS, global_settings.bass_boost);
1319 fprintf(fd, "bass boost: %d\r\n", value);
1322 static char* options[] = {"off", "2", "4", "8" };
1323 fprintf(fd, "auto volume: %s\r\n", options[global_settings.avc]);
1325 #endif
1327 fprintf(fd, "#\r\n# Playback\r\n#\r\n");
1328 fprintf(fd, "shuffle: %s\r\n", boolopt[global_settings.playlist_shuffle]);
1331 static char* options[] = {"off", "all", "one"};
1332 fprintf(fd, "repeat: %s\r\n", options[global_settings.repeat_mode]);
1335 fprintf(fd, "play selected: %s\r\n",
1336 boolopt[global_settings.play_selected]);
1339 static char* options[] = {"off", "ask", "ask once", "on"};
1340 fprintf(fd, "resume: %s\r\n", options[global_settings.resume]);
1344 static char* options[] =
1345 {"1","2","3","4","5","6","8","10",
1346 "15","20","25","30","45","60"};
1347 fprintf(fd, "scan min step: %s\r\n",
1348 options[global_settings.ff_rewind_min_step]);
1351 fprintf(fd, "scan accel: %d\r\nantiskip: %d\r\n",
1352 global_settings.ff_rewind_accel,
1353 global_settings.buffer_margin);
1354 fprintf(fd, "volume fade: %s\r\n", boolopt[global_settings.fade_on_stop]);
1355 fprintf(fd, "#\r\n# File View\r\n#\r\n");
1356 fprintf(fd, "sort case: %s\r\n", boolopt[global_settings.sort_case]);
1359 static char* options[] = {"all", "supported","music", "playlists"};
1360 fprintf(fd, "show files: %s\r\n", options[global_settings.dirfilter]);
1363 fprintf(fd, "follow playlist: %s\r\n",
1364 boolopt[global_settings.browse_current]);
1366 fprintf(fd, "#\r\n# Display\r\n#\r\n");
1368 #ifdef HAVE_LCD_BITMAP
1369 fprintf(fd, "statusbar: %s\r\nbuttonbar: %s\r\nscrollbar: %s\r\n",
1370 boolopt[global_settings.statusbar],
1371 boolopt[global_settings.buttonbar],
1372 boolopt[global_settings.scrollbar]);
1375 static char* options[] = {"graphic", "numeric"};
1376 fprintf(fd, "volume display: %s\r\nbattery display: %s\r\n",
1377 options[global_settings.volume_type],
1378 options[global_settings.battery_type]);
1380 #endif
1382 fprintf(fd, "scroll speed: %d\r\nscroll delay: %d\r\n",
1383 global_settings.scroll_speed,
1384 global_settings.scroll_delay);
1386 #ifdef HAVE_LCD_BITMAP
1387 fprintf(fd, "scroll step: %d\r\n", global_settings.scroll_step);
1388 #else
1389 fprintf(fd, "jump scroll: %d\r\n", global_settings.jump_scroll);
1390 fprintf(fd, "jump scroll delay: %d\r\n", global_settings.jump_scroll_delay);
1391 #endif
1393 fprintf(fd, "bidir limit: %d\r\n", global_settings.bidir_limit);
1396 static char* options[] =
1397 {"off","on","1","2","3","4","5","6","7","8","9",
1398 "10","15","20","25","30","45","60","90"};
1399 fprintf(fd, "backlight timeout: %s\r\n",
1400 options[global_settings.backlight_timeout]);
1403 fprintf(fd, "backlight when plugged: %s\r\n",
1404 boolopt[global_settings.backlight_on_when_charging]);
1406 fprintf(fd, "caption backlight: %s\r\n",
1407 boolopt[global_settings.caption_backlight]);
1408 fprintf(fd, "contrast: %d\r\n", global_settings.contrast);
1410 #ifdef HAVE_LCD_BITMAP
1411 fprintf(fd, "invert: %s\r\n", boolopt[global_settings.invert]);
1413 fprintf(fd, "flip display: %s\r\n", boolopt[global_settings.flip_display]);
1415 fprintf(fd, "invert cursor: %s\r\n",
1416 boolopt[global_settings.invert_cursor]);
1418 fprintf(fd, "show icons: %s\r\n",
1419 boolopt[global_settings.show_icons]);
1421 fprintf(fd, "peak meter release: %d\r\n",
1422 global_settings.peak_meter_release);
1425 static char* options[] =
1426 {"off","200ms","300ms","500ms","1","2","3","4","5",
1427 "6","7","8","9","10","15","20","30","1min"};
1428 fprintf(fd, "peak meter hold: %s\r\n",
1429 options[global_settings.peak_meter_hold]);
1433 static char* options[] =
1434 {"on","1","2","3","4","5","6","7","8","9","10","15","20","25","30",
1435 "45","60","90","2min","3min","5min","10min","20min","45min","90min"};
1436 fprintf(fd, "peak meter clip hold: %s\r\n",
1437 options[global_settings.peak_meter_clip_hold]);
1440 fprintf(fd, "peak meter busy: %s\r\npeak meter dbfs: %s\r\n",
1441 boolopt[global_settings.peak_meter_performance],
1442 boolopt[global_settings.peak_meter_dbfs]);
1444 fprintf(fd, "peak meter min: %d\r\npeak meter max: %d\r\n",
1445 global_settings.peak_meter_min,
1446 global_settings.peak_meter_max);
1447 #endif
1449 fprintf(fd, "#\r\n# System\r\n#\r\ndisk spindown: %d\r\n",
1450 global_settings.disk_spindown);
1452 #ifdef HAVE_ATA_POWER_OFF
1453 fprintf(fd, "disk poweroff: %s\r\n",
1454 boolopt[global_settings.disk_poweroff]);
1455 #endif
1457 fprintf(fd, "battery capacity: %d\r\n", global_settings.battery_capacity);
1459 #ifdef HAVE_CHARGE_CTRL
1460 fprintf(fd, "deep discharge: %s\r\ntrickle charge: %s\r\n",
1461 boolopt[global_settings.discharge],
1462 boolopt[global_settings.trickle_charge]);
1463 #endif
1465 #ifdef HAVE_LCD_BITMAP
1467 static char* options[] = {"24hour", "12hour"};
1468 fprintf(fd, "time format: %s\r\n",
1469 options[global_settings.timeformat]);
1471 #endif
1474 static char* options[] =
1475 {"off","1","2","3","4","5","6","7","8",
1476 "9","10","15","30","45","60"};
1477 fprintf(fd, "idle poweroff: %s\r\n",
1478 options[global_settings.poweroff]);
1481 fprintf(fd, "car adapter mode: %s\r\n",
1482 boolopt[global_settings.car_adapter_mode]);
1484 #ifdef HAVE_MAS3507D
1485 fprintf(fd, "line in: %s\r\n", boolopt[global_settings.line_in]);
1486 #endif
1488 fprintf(fd, "max files in dir: %d\r\n", global_settings.max_files_in_dir);
1489 fprintf(fd, "max files in playlist: %d\r\n",
1490 global_settings.max_files_in_playlist);
1492 #ifdef HAVE_MAS3587F
1493 fprintf(fd, "#\r\n# Recording\r\n#\r\n");
1494 fprintf(fd, "rec quality: %d\r\n", global_settings.rec_quality);
1497 static char* options[] = {"44", "48", "32", "22", "24", "16"};
1498 fprintf(fd, "rec frequency: %s\r\n",
1499 options[global_settings.rec_frequency]);
1503 static char* options[] = {"mic", "line", "spdif"};
1504 fprintf(fd, "rec source: %s\r\n", options[global_settings.rec_source]);
1508 static char* options[] = {"stereo", "mono"};
1509 fprintf(fd, "rec channels: %s\r\n",
1510 options[global_settings.rec_channels]);
1513 fprintf(fd,
1514 "rec mic gain: %d\r\nrec left gain: %d\r\nrec right gain: %d\r\n",
1515 global_settings.rec_mic_gain,
1516 global_settings.rec_left_gain,
1517 global_settings.rec_right_gain);
1519 fprintf(fd, "editable recordings: %s\r\n",
1520 boolopt[global_settings.rec_editable]);
1522 fprintf(fd, "prerecording time: %d\r\n",
1523 global_settings.rec_prerecord_time);
1526 static char* options[] = {rec_base_directory, "current"};
1527 fprintf(fd, "rec directory: %s\r\n",
1528 options[global_settings.rec_directory]);
1531 #endif
1533 fprintf(fd, "#\r\n# Bookmarking\r\n#\r\n");
1535 fprintf(fd, "autoload bookmarks: %s\r\n",
1536 triopt[global_settings.autoloadbookmark]);
1540 static char* options[] = {"off", "on", "ask","recent only - on", "recent only - ask"};
1541 fprintf(fd, "autocreate bookmarks: %s\r\n",
1542 options[global_settings.autocreatebookmark]);
1546 static char* options[] = {"off", "on", "unique only"};
1547 fprintf(fd, "use most-recent-bookmarks: %s\r\n", options[global_settings.usemrb]);
1550 fprintf(fd, "#\r\n# Playlists\r\n#\r\n");
1552 fprintf(fd, "recursive directory insert: %s\r\n",
1553 triopt[global_settings.recursive_dir_insert]);
1556 fprintf(fd, "#\r\n# Playlist viewer\r\n#\r\n");
1558 fprintf(fd, "playlist viewer icons: %s\r\n",
1559 boolopt[global_settings.playlist_viewer_icons]);
1560 fprintf(fd, "playlist viewer indices: %s\r\n",
1561 boolopt[global_settings.playlist_viewer_indices]);
1563 static char* options[] = {"track name", "full path"};
1564 fprintf(fd, "playlist viewer track display: %s\r\n",
1565 options[global_settings.playlist_viewer_track_display]);
1568 fprintf(fd, "#\r\n# Voice\r\n#\r\n");
1570 static char* options[] = {"off", "number", "spell", "enter", "hover"};
1571 fprintf(fd, "talk dir: %s\r\n",
1572 options[global_settings.talk_dir]);
1573 fprintf(fd, "talk file: %s\r\n", /* recycle the options, */
1574 options[global_settings.talk_file]); /* first 3 are alike */
1575 fprintf(fd, "talk menu: %s\r\n",
1576 boolopt[global_settings.talk_menu]);
1579 close(fd);
1581 lcd_clear_display();
1582 lcd_puts(0,0,str(LANG_SETTINGS_SAVED1));
1583 lcd_puts(0,1,str(LANG_SETTINGS_SAVED2));
1584 lcd_update();
1585 sleep(HZ);
1586 return true;
1590 * reset all settings to their default value
1592 void settings_reset(void) {
1594 DEBUGF( "settings_reset()\n" );
1596 global_settings.volume = mpeg_sound_default(SOUND_VOLUME);
1597 global_settings.balance = mpeg_sound_default(SOUND_BALANCE);
1598 global_settings.bass = mpeg_sound_default(SOUND_BASS);
1599 global_settings.treble = mpeg_sound_default(SOUND_TREBLE);
1600 global_settings.loudness = mpeg_sound_default(SOUND_LOUDNESS);
1601 global_settings.bass_boost = mpeg_sound_default(SOUND_SUPERBASS);
1602 global_settings.avc = mpeg_sound_default(SOUND_AVC);
1603 global_settings.channel_config = mpeg_sound_default(SOUND_CHANNELS);
1604 global_settings.rec_quality = 5;
1605 global_settings.rec_source = 0; /* 0=mic */
1606 global_settings.rec_frequency = 0; /* 0=44.1kHz */
1607 global_settings.rec_channels = 0; /* 0=Stereo */
1608 global_settings.rec_mic_gain = 8;
1609 global_settings.rec_left_gain = 2; /* 0dB */
1610 global_settings.rec_right_gain = 2; /* 0dB */
1611 global_settings.rec_editable = false;
1612 global_settings.rec_prerecord_time = 0;
1613 global_settings.rec_directory = 0; /* rec_base_directory */
1614 global_settings.resume = RESUME_ASK;
1615 global_settings.contrast = lcd_default_contrast();
1616 global_settings.invert = DEFAULT_INVERT_SETTING;
1617 global_settings.flip_display= false;
1618 global_settings.poweroff = DEFAULT_POWEROFF_SETTING;
1619 global_settings.backlight_timeout = DEFAULT_BACKLIGHT_TIMEOUT_SETTING;
1620 global_settings.invert_cursor = DEFAULT_INVERT_CURSOR_SETTING;
1621 global_settings.backlight_on_when_charging =
1622 DEFAULT_BACKLIGHT_ON_WHEN_CHARGING_SETTING;
1623 #ifdef HAVE_LIION
1624 global_settings.battery_capacity = 2200; /* mAh */
1625 #else
1626 global_settings.battery_capacity = 1500; /* mAh */
1627 #endif
1628 global_settings.trickle_charge = true;
1629 global_settings.dirfilter = SHOW_MUSIC;
1630 global_settings.sort_case = false;
1631 global_settings.statusbar = true;
1632 global_settings.buttonbar = true;
1633 global_settings.scrollbar = true;
1634 global_settings.repeat_mode = REPEAT_ALL;
1635 global_settings.playlist_shuffle = false;
1636 global_settings.discharge = 0;
1637 global_settings.timeformat = 0;
1638 global_settings.volume_type = 0;
1639 global_settings.battery_type = 0;
1640 global_settings.scroll_speed = 8;
1641 global_settings.bidir_limit = 50;
1642 #ifdef HAVE_LCD_CHARCELLS
1643 global_settings.jump_scroll = 0;
1644 global_settings.jump_scroll_delay = 50;
1645 #endif
1646 global_settings.scroll_delay = 100;
1647 global_settings.scroll_step = 6;
1648 global_settings.ff_rewind_min_step = DEFAULT_FF_REWIND_MIN_STEP;
1649 global_settings.ff_rewind_accel = DEFAULT_FF_REWIND_ACCEL_SETTING;
1650 global_settings.resume_index = -1;
1651 global_settings.resume_first_index = 0;
1652 global_settings.resume_offset = -1;
1653 global_settings.resume_seed = -1;
1654 global_settings.disk_spindown = 5;
1655 global_settings.disk_poweroff = false;
1656 global_settings.buffer_margin = 0;
1657 global_settings.browse_current = false;
1658 global_settings.play_selected = true;
1659 global_settings.peak_meter_release = 8;
1660 global_settings.peak_meter_hold = 3;
1661 global_settings.peak_meter_clip_hold = 16;
1662 global_settings.peak_meter_dbfs = true;
1663 global_settings.peak_meter_min = 60;
1664 global_settings.peak_meter_max = 0;
1665 global_settings.peak_meter_performance = false;
1666 global_settings.wps_file[0] = 0;
1667 global_settings.font_file[0] = 0;
1668 global_settings.lang_file[0] = 0;
1669 global_settings.runtime = 0;
1670 global_settings.topruntime = 0;
1671 global_settings.autocreatebookmark = BOOKMARK_NO;
1672 global_settings.autoloadbookmark = BOOKMARK_NO;
1673 global_settings.usemrb = BOOKMARK_NO;
1674 global_settings.fade_on_stop = true;
1675 global_settings.caption_backlight = false;
1676 global_settings.car_adapter_mode = false;
1677 global_settings.max_files_in_dir = 400;
1678 global_settings.max_files_in_playlist = 10000;
1679 global_settings.show_icons = true;
1680 global_settings.recursive_dir_insert = RECURSE_OFF;
1681 global_settings.line_in = false;
1682 global_settings.playlist_viewer_icons = true;
1683 global_settings.playlist_viewer_indices = true;
1684 global_settings.playlist_viewer_track_display = 0;
1685 /* talking menu on by default, to help the blind (if voice file present) */
1686 global_settings.talk_menu = 1;
1687 global_settings.talk_dir = 0;
1688 global_settings.talk_file = 0;
1691 bool set_bool(char* string, bool* variable )
1693 return set_bool_options(string, variable,
1694 STR(LANG_SET_BOOL_YES),
1695 STR(LANG_SET_BOOL_NO),
1696 NULL);
1699 /* wrapper to convert from int param to bool param in set_option */
1700 static void (*boolfunction)(bool);
1701 void bool_funcwrapper(int value)
1703 if (value)
1704 boolfunction(true);
1705 else
1706 boolfunction(false);
1709 bool set_bool_options(char* string, bool* variable,
1710 char* yes_str, int yes_voice,
1711 char* no_str, int no_voice,
1712 void (*function)(bool))
1714 struct opt_items names[] = { {no_str, no_voice}, {yes_str, yes_voice} };
1715 bool result;
1717 boolfunction = function;
1718 result = set_option(string, variable, BOOL, names, 2,
1719 function ? bool_funcwrapper : NULL);
1720 return result;
1723 bool set_int(char* string,
1724 char* unit,
1725 int voice_unit,
1726 int* variable,
1727 void (*function)(int),
1728 int step,
1729 int min,
1730 int max )
1732 bool done = false;
1733 int button;
1734 int org_value=*variable;
1735 int last_value = 0x7FFFFFFF; /* out of range init */
1737 #ifdef HAVE_LCD_BITMAP
1738 if(global_settings.statusbar)
1739 lcd_setmargins(0, STATUSBAR_HEIGHT);
1740 else
1741 lcd_setmargins(0, 0);
1742 #endif
1744 lcd_clear_display();
1745 lcd_puts_scroll(0, 0, string);
1747 while (!done) {
1748 char str[32];
1749 snprintf(str,sizeof str,"%d %s ", *variable, unit);
1750 lcd_puts(0, 1, str);
1751 #ifdef HAVE_LCD_BITMAP
1752 status_draw(true);
1753 #endif
1754 lcd_update();
1756 if (global_settings.talk_menu && *variable != last_value)
1758 if (voice_unit < UNIT_LAST)
1759 { /* use the available unit definition */
1760 talk_value(*variable, voice_unit, false);
1762 else
1763 { /* say the number, followed by an arbitrary voice ID */
1764 talk_number(*variable, false);
1765 talk_id(voice_unit, true);
1767 last_value = *variable;
1770 button = button_get_w_tmo(HZ/2);
1771 switch(button) {
1772 #ifdef HAVE_RECORDER_KEYPAD
1773 case BUTTON_UP:
1774 case BUTTON_UP | BUTTON_REPEAT:
1775 #else
1776 case BUTTON_RIGHT:
1777 case BUTTON_RIGHT | BUTTON_REPEAT:
1778 #endif
1779 *variable += step;
1780 break;
1782 #ifdef HAVE_RECORDER_KEYPAD
1783 case BUTTON_DOWN:
1784 case BUTTON_DOWN | BUTTON_REPEAT:
1785 #else
1786 case BUTTON_LEFT:
1787 case BUTTON_LEFT | BUTTON_REPEAT:
1788 #endif
1789 *variable -= step;
1790 break;
1792 #ifdef HAVE_RECORDER_KEYPAD
1793 case BUTTON_LEFT:
1794 case BUTTON_PLAY:
1795 #else
1796 case BUTTON_PLAY:
1797 #endif
1798 done = true;
1799 break;
1801 #ifdef HAVE_RECORDER_KEYPAD
1802 case BUTTON_OFF:
1803 #else
1804 case BUTTON_STOP:
1805 case BUTTON_MENU:
1806 #endif
1807 if (*variable != org_value) {
1808 *variable=org_value;
1809 lcd_stop_scroll();
1810 lcd_puts(0, 0, str(LANG_MENU_SETTING_CANCEL));
1811 lcd_update();
1812 sleep(HZ/2);
1814 done = true;
1815 break;
1817 case SYS_USB_CONNECTED:
1818 usb_screen();
1819 return true;
1822 if(*variable > max )
1823 *variable = max;
1825 if(*variable < min )
1826 *variable = min;
1828 if ( function && button != BUTTON_NONE)
1829 function(*variable);
1831 lcd_stop_scroll();
1833 return false;
1836 /* NOTE: the 'type' parameter specifies the actual type of the variable
1837 that 'variable' points to. not the value within. Only variables with
1838 type 'bool' should use parameter BOOL.
1840 The type separation is necessary since int and bool are fundamentally
1841 different and bit-incompatible types and can not share the same access
1842 code. */
1844 bool set_option(char* string, void* variable, enum optiontype type,
1845 struct opt_items* options, int numoptions, void (*function)(int))
1847 bool done = false;
1848 int button;
1849 int* intvar = (int*)variable;
1850 bool* boolvar = (bool*)variable;
1851 int oldval = 0;
1852 int index, oldindex = -1; /* remember what we said */
1854 if (type==INT)
1855 oldval=*intvar;
1856 else
1857 oldval=*boolvar;
1859 #ifdef HAVE_LCD_BITMAP
1860 if(global_settings.statusbar)
1861 lcd_setmargins(0, STATUSBAR_HEIGHT);
1862 else
1863 lcd_setmargins(0, 0);
1864 #endif
1866 lcd_clear_display();
1867 lcd_puts_scroll(0, 0, string);
1869 while ( !done ) {
1870 index = type==INT ? *intvar : (int)*boolvar;
1871 lcd_puts(0, 1, options[index].string);
1872 if (global_settings.talk_menu && index != oldindex)
1874 talk_id(options[index].voice_id, false);
1875 oldindex = index;
1877 #ifdef HAVE_LCD_BITMAP
1878 status_draw(true);
1879 #endif
1880 lcd_update();
1882 button = button_get_w_tmo(HZ/2);
1883 switch (button) {
1884 #ifdef HAVE_RECORDER_KEYPAD
1885 case BUTTON_UP:
1886 case BUTTON_UP | BUTTON_REPEAT:
1887 #else
1888 case BUTTON_RIGHT:
1889 case BUTTON_RIGHT | BUTTON_REPEAT:
1890 #endif
1891 if (type == INT) {
1892 if ( *intvar < (numoptions-1) )
1893 (*intvar)++;
1894 else
1895 (*intvar) -= (numoptions-1);
1897 else
1898 *boolvar = !*boolvar;
1899 break;
1901 #ifdef HAVE_RECORDER_KEYPAD
1902 case BUTTON_DOWN:
1903 case BUTTON_DOWN | BUTTON_REPEAT:
1904 #else
1905 case BUTTON_LEFT:
1906 case BUTTON_LEFT | BUTTON_REPEAT:
1907 #endif
1908 if (type == INT) {
1909 if ( *intvar > 0 )
1910 (*intvar)--;
1911 else
1912 (*intvar) += (numoptions-1);
1914 else
1915 *boolvar = !*boolvar;
1916 break;
1918 #ifdef HAVE_RECORDER_KEYPAD
1919 case BUTTON_LEFT:
1920 case BUTTON_PLAY:
1921 #else
1922 case BUTTON_PLAY:
1923 #endif
1924 done = true;
1925 break;
1927 #ifdef HAVE_RECORDER_KEYPAD
1928 case BUTTON_OFF:
1929 #else
1930 case BUTTON_STOP:
1931 case BUTTON_MENU:
1932 #endif
1933 if (((type==INT) && (*intvar != oldval)) ||
1934 ((type==BOOL) && (*boolvar != (bool)oldval))) {
1935 if (type==INT)
1936 *intvar=oldval;
1937 else
1938 *boolvar=oldval;
1939 lcd_stop_scroll();
1940 lcd_puts(0, 0, str(LANG_MENU_SETTING_CANCEL));
1941 lcd_update();
1942 sleep(HZ/2);
1944 done = true;
1945 break;
1947 case SYS_USB_CONNECTED:
1948 usb_screen();
1949 return true;
1952 if ( function && button != BUTTON_NONE) {
1953 if (type == INT)
1954 function(*intvar);
1955 else
1956 function(*boolvar);
1959 lcd_stop_scroll();
1960 return false;
1963 #ifdef HAVE_MAS3587F
1964 /* This array holds the record timer interval lengths, in seconds */
1965 static unsigned long rec_timer_seconds[] =
1967 24*60*60, /* OFF really means 24 hours, to avoid >2Gbyte files */
1968 5*60, /* 00:05 */
1969 10*60, /* 00:10 */
1970 15*60, /* 00:15 */
1971 30*60, /* 00:30 */
1972 60*60, /* 01:00 */
1973 2*60*60, /* 02:00 */
1974 4*60*60, /* 04:00 */
1975 6*60*60, /* 06:00 */
1976 8*60*60, /* 08:00 */
1977 10*60*60, /* 10:00 */
1978 12*60*60, /* 12:00 */
1979 18*60*60, /* 18:00 */
1980 24*60*60 /* 24:00 */
1983 unsigned int rec_timesplit_seconds(void)
1985 return rec_timer_seconds[global_settings.rec_timesplit];
1987 #endif