diff options
author | Jörg Hohensohn <hohensoh@rockbox.org> | 2004-06-18 20:41:59 +0000 |
---|---|---|
committer | Jörg Hohensohn <hohensoh@rockbox.org> | 2004-06-18 20:41:59 +0000 |
commit | 44171b99b6f8aa258cc574bce3ece3dfcc67812b (patch) | |
tree | 834d25ef764d1585d771bac3a4b8df3cef21bf7d /apps/settings.c | |
parent | 87d064d9d1caaa7f29066eed043188dafa2ec171 (diff) | |
download | rockbox-44171b99b6f8aa258cc574bce3ece3dfcc67812b.tar.gz rockbox-44171b99b6f8aa258cc574bce3ece3dfcc67812b.zip |
New method of persisting the settings, using a central table. This saves lots of spaghetti code and saves ~6kB in .ajz size.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4772 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/settings.c')
-rw-r--r-- | apps/settings.c | 1792 |
1 files changed, 737 insertions, 1055 deletions
diff --git a/apps/settings.c b/apps/settings.c index c9e281dae0..abf152fdf2 100644 --- a/apps/settings.c +++ b/apps/settings.c | |||
@@ -18,6 +18,7 @@ | |||
18 | * | 18 | * |
19 | ****************************************************************************/ | 19 | ****************************************************************************/ |
20 | #include <stdio.h> | 20 | #include <stdio.h> |
21 | #include <stddef.h> | ||
21 | #include "config.h" | 22 | #include "config.h" |
22 | #include "kernel.h" | 23 | #include "kernel.h" |
23 | #include "thread.h" | 24 | #include "thread.h" |
@@ -61,6 +62,7 @@ | |||
61 | #include "sprintf.h" | 62 | #include "sprintf.h" |
62 | #include "keyboard.h" | 63 | #include "keyboard.h" |
63 | #include "version.h" | 64 | #include "version.h" |
65 | #include "rtc.h" | ||
64 | #ifdef HAVE_MAS3507D | 66 | #ifdef HAVE_MAS3507D |
65 | void dac_line_in(bool enable); | 67 | void dac_line_in(bool enable); |
66 | #endif | 68 | #endif |
@@ -69,9 +71,10 @@ char rockboxdir[] = ROCKBOX_DIR; /* config/font/data file directory */ | |||
69 | char rec_base_directory[] = REC_BASE_DIR; | 71 | char rec_base_directory[] = REC_BASE_DIR; |
70 | 72 | ||
71 | 73 | ||
72 | #define CONFIG_BLOCK_VERSION 10 | 74 | #define CONFIG_BLOCK_VERSION 11 |
73 | #define CONFIG_BLOCK_SIZE 512 | 75 | #define CONFIG_BLOCK_SIZE 512 |
74 | #define RTC_BLOCK_SIZE 44 | 76 | #define RTC_BLOCK_SIZE 44 |
77 | #define MARKER 0x7FFFFFFF /* FIXME: to be removed with val2phys/phys2val */ | ||
75 | 78 | ||
76 | #ifdef HAVE_LCD_BITMAP | 79 | #ifdef HAVE_LCD_BITMAP |
77 | #define MAX_LINES 10 | 80 | #define MAX_LINES 10 |
@@ -79,6 +82,28 @@ char rec_base_directory[] = REC_BASE_DIR; | |||
79 | #define MAX_LINES 2 | 82 | #define MAX_LINES 2 |
80 | #endif | 83 | #endif |
81 | 84 | ||
85 | long lasttime = 0; | ||
86 | static unsigned char config_block[CONFIG_BLOCK_SIZE]; | ||
87 | |||
88 | |||
89 | /* descriptor for a configuration value */ | ||
90 | /* (watch the struct packing and member sizes to keep this small) */ | ||
91 | struct bit_entry | ||
92 | { | ||
93 | /* how many bits within the bitfield (1-32), MSB set if value is signed */ | ||
94 | unsigned char bit_size; /* min 6+1 bit */ | ||
95 | /* how many bytes in the global_settings struct (1,2,4) */ | ||
96 | unsigned char byte_size; /* min 2 bits */ | ||
97 | /* store position in global_settings struct */ | ||
98 | short settings_offset; /* min 9 bit, better 10 */ | ||
99 | /* default value */ | ||
100 | int default_val; /* min 15 bit */ | ||
101 | /* variable name in a .cfg file, NULL if not to be saved */ | ||
102 | const char* cfg_name; | ||
103 | /* set of values, or NULL for a numerical value */ | ||
104 | const char* cfg_val; | ||
105 | }; | ||
106 | |||
82 | /******************************************** | 107 | /******************************************** |
83 | 108 | ||
84 | Config block as saved on the battery-packed RTC user RAM memory block | 109 | Config block as saved on the battery-packed RTC user RAM memory block |
@@ -87,89 +112,296 @@ of 44 bytes, starting at offset 0x14 of the RTC memory space. | |||
87 | offset abs | 112 | offset abs |
88 | 0x00 0x14 "Roc" header signature: 0x52 0x6f 0x63 | 113 | 0x00 0x14 "Roc" header signature: 0x52 0x6f 0x63 |
89 | 0x03 0x17 <version byte: 0x0> | 114 | 0x03 0x17 <version byte: 0x0> |
90 | 0x04 0x18 <volume byte> | 115 | 0x04 0x18 start of bit-table |
91 | 0x05 0x19 <balance byte> | 116 | ... |
92 | 0x06 0x1a <bass byte> | 117 | 0x28,0x29 unused, not reachable by set_bits() without disturbing the next 2 |
93 | 0x07 0x1b <treble byte> | 118 | 0x2A,0x2B <checksum 2 bytes: xor of 0x00-0x29> |
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> | ||
125 | |||
126 | 0x2a <checksum 2 bytes: xor of 0x0-0x29> | ||
127 | 119 | ||
128 | Config memory is reset to 0xff and initialized with 'factory defaults' if | 120 | 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 | 121 | 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 | 122 | increased when information is _relocated_ or space is _reused_ so that old |
131 | versions can read and modify configuration changed by new versions. New | 123 | versions can read and modify configuration changed by new versions. |
132 | versions should check for the value of '0xff' in each config memory | 124 | Memory locations not used by a given version should not be |
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. | 125 | modified unless the header & checksum test fails. |
136 | 126 | ||
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. | ||
140 | |||
141 | Rest of config block, only saved to disk: | 127 | Rest of config block, only saved to disk: |
142 | 0xA8 (char)jump scroll mode (only for player) | 128 | 0x2C start of 2nd bit-table |
143 | 0xA9 (char)jump scroll delay (only for player) | 129 | ... |
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 | 130 | 0xB8 (char[20]) WPS file |
163 | 0xCC (char[20]) Lang file | 131 | 0xCC (char[20]) Lang file |
164 | 0xE0 (char[20]) Font file | 132 | 0xE0 (char[20]) Font file |
165 | 0xF4 Prerecording time (bit 0-4), Recording directory option (bit 5-6) | 133 | 0xF4-0xFF <unused> |
166 | 0xF5-0xFF <unused> | ||
167 | 134 | ||
168 | *************************************/ | 135 | *************************************/ |
169 | 136 | ||
170 | #include "rtc.h" | 137 | /* The persistence of the global_settings members is now controlled by |
171 | long lasttime = 0; | 138 | the two tables below, rtc_bits and hd_bits. |
172 | static unsigned char config_block[CONFIG_BLOCK_SIZE]; | 139 | New values can just be added to the end, it will be backwards |
140 | compatible. If you however change order, bitsize, etc. of existing | ||
141 | entries, you need to bump CONFIG_BLOCK_VERSION to break compatibility. | ||
142 | */ | ||
143 | |||
144 | |||
145 | /* convenience macro for both size and offset of global_settings member */ | ||
146 | #define S_O(val) sizeof(global_settings.val), offsetof(struct user_settings, val) | ||
147 | #define SIGNED 0x80 /* for bitsize value with signed attribute */ | ||
148 | |||
149 | /* some sets of values which are used more than once, to save memory */ | ||
150 | static const char off_on[] = "off,on"; | ||
151 | static const char off_on_ask[] = "off,on,ask"; | ||
152 | static const char graphic_numeric[] = "graphic,numeric"; | ||
153 | |||
154 | /* the part of the settings which ends up in the RTC RAM, where available | ||
155 | (those we either need early, save frequently, or without spinup) */ | ||
156 | static struct bit_entry rtc_bits[] = | ||
157 | { | ||
158 | /* placeholder, containing the size information */ | ||
159 | {9, 0, 0, 0, NULL, NULL }, /* 9 bit to tell how far this is populated */ | ||
160 | |||
161 | /* # of bits, offset+size, default, .cfg name, .cfg values */ | ||
162 | /* sound */ | ||
163 | {7, S_O(volume), 70, "volume", NULL }, /* 0...100 */ | ||
164 | {7 | SIGNED, S_O(balance), 0, "balance", NULL }, /* -50...50 */ | ||
165 | {5, S_O(bass), 0, "bass", NULL }, /* 0...30 */ | ||
166 | {5, S_O(treble), 0, "treble", NULL }, /* 0...30 */ | ||
167 | #ifdef HAVE_MAS3587F | ||
168 | {5, S_O(loudness), 0, "loudness", NULL }, /* 0...17 */ | ||
169 | {4, S_O(bass_boost), 0, "bass boost", NULL }, /* 0...10 */ | ||
170 | {2, S_O(avc), 0, "auto volume", "off,2,4,8" }, | ||
171 | #endif | ||
172 | {3, S_O(channel_config), 6, "channels", | ||
173 | "stereo,stereo narrow,mono,mono left,mono right,karaoke,stereo wide" }, | ||
174 | /* playback */ | ||
175 | {2, S_O(resume), RESUME_ASK, "resume", "off,ask,ask once,on" }, | ||
176 | {1, S_O(playlist_shuffle), false, "shuffle", off_on }, | ||
177 | {16 | SIGNED, S_O(resume_index), -1, NULL, NULL }, | ||
178 | {16 | SIGNED, S_O(resume_first_index), 0, NULL, NULL }, | ||
179 | {32 | SIGNED, S_O(resume_offset), -1, NULL, NULL }, | ||
180 | {32 | SIGNED, S_O(resume_seed), -1, NULL, NULL }, | ||
181 | {2, S_O(repeat_mode), REPEAT_ALL, "repeat", "off,all,one" }, | ||
182 | /* LCD */ | ||
183 | {6, S_O(contrast), 40, "contrast", NULL }, | ||
184 | {1, S_O(backlight_on_when_charging), false, | ||
185 | "backlight when plugged", off_on }, | ||
186 | {5, S_O(backlight_timeout), 5, "backlight timeout", | ||
187 | "off,on,1,2,3,4,5,6,7,8,9,10,15,20,25,30,45,60,90" }, | ||
188 | #ifdef HAVE_LCD_BITMAP | ||
189 | {1, S_O(invert), false, "invert", off_on }, | ||
190 | {1, S_O(flip_display), false, "flip display", off_on }, | ||
191 | /* display */ | ||
192 | {1, S_O(invert_cursor), false, "invert cursor", off_on }, | ||
193 | {1, S_O(show_icons), true, "show icons", off_on }, | ||
194 | {1, S_O(statusbar), true, "statusbar", off_on }, | ||
195 | {1, S_O(scrollbar), true, "scrollbar", off_on }, | ||
196 | {1, S_O(buttonbar), true, "buttonbar", off_on }, | ||
197 | {1, S_O(volume_type), 0, "volume display", graphic_numeric }, | ||
198 | {1, S_O(battery_type), 0, "battery display", graphic_numeric }, | ||
199 | {1, S_O(timeformat), 0, "time format", "24hour,12hour" }, | ||
200 | #endif | ||
201 | /* system */ | ||
202 | {4, S_O(poweroff), 10, | ||
203 | "idle poweroff", "off,1,2,3,4,5,6,7,8,9,10,15,30,45,60" }, | ||
204 | {18, S_O(runtime), 0, NULL, NULL }, | ||
205 | {18, S_O(topruntime), 0, NULL, NULL }, | ||
206 | {15, S_O(max_files_in_playlist), 10000, | ||
207 | "max files in playlist", NULL }, /* 1000...20000 */ | ||
208 | {14, S_O(max_files_in_dir), 400, | ||
209 | "max files in dir", NULL }, /* 50...10000 */ | ||
210 | /* battery */ | ||
211 | #ifdef HAVE_CHARGE_CTRL | ||
212 | {1, S_O(discharge), 0, "deep discharge", off_on }, | ||
213 | {1, S_O(trickle_charge), true, "trickle charge", off_on }, | ||
214 | #endif | ||
215 | #ifdef HAVE_LIION | ||
216 | {12, S_O(battery_capacity), 2200, "battery capacity", NULL }, /* 1500...3200 */ | ||
217 | #else | ||
218 | {12, S_O(battery_capacity), 1500, "battery capacity", NULL }, /* 1500...3200 */ | ||
219 | #endif | ||
220 | {1, S_O(car_adapter_mode), false, "car adapter mode", off_on }, | ||
221 | |||
222 | /* new stuff to be added here */ | ||
223 | /* If values are just added to the end, no need to bump the version. */ | ||
224 | |||
225 | /* Current sum of bits: 254 (worst case) */ | ||
226 | /* Sum of all bit sizes must not grow beyond 288! */ | ||
227 | }; | ||
228 | |||
229 | |||
230 | /* the part of the settings which ends up in HD sector only */ | ||
231 | static struct bit_entry hd_bits[] = | ||
232 | { | ||
233 | /* This table starts after the 44 RTC bytes = 352 bits. */ | ||
234 | /* Here we need 11 bits to tell how far this is populated. */ | ||
235 | |||
236 | /* placeholder, containing the size information */ | ||
237 | {11, 0, 0, 0, NULL, NULL }, /* 11 bit to tell how far this is populated */ | ||
238 | |||
239 | /* # of bits, offset+size, default, .cfg name, .cfg values */ | ||
240 | /* more display */ | ||
241 | {1, S_O(caption_backlight), false, "caption backlight", off_on }, | ||
242 | {4, S_O(scroll_speed), 8, "scroll speed", NULL }, /* 1...10 */ | ||
243 | {7, S_O(scroll_step), 6, "scroll step", NULL }, /* 1...112 */ | ||
244 | {8, S_O(scroll_delay), 100, "scroll delay", NULL }, /* 0...250 */ | ||
245 | {8, S_O(bidir_limit), 50, "bidir limit", NULL }, /* 0...200 */ | ||
246 | #ifdef HAVE_LCD_CHARCELLS | ||
247 | {3, S_O(jump_scroll), 0, "jump scroll", NULL }, /* 0...5 */ | ||
248 | {8, S_O(jump_scroll_delay), 50, "jump scroll delay", NULL }, /* 0...250 */ | ||
249 | #endif | ||
250 | /* more playback */ | ||
251 | {1, S_O(play_selected), true, "play selected", off_on }, | ||
252 | {1, S_O(fade_on_stop), true, "volume fade", off_on }, | ||
253 | {4, S_O(ff_rewind_min_step), 1000, | ||
254 | "scan min step", "1,2,3,4,5,6,8,10,15,20,25,30,45,60" }, | ||
255 | {4, S_O(ff_rewind_accel), 3, "scan accel", NULL }, | ||
256 | {3, S_O(buffer_margin), 0, "antiskip", NULL }, | ||
257 | /* disk */ | ||
258 | #ifdef HAVE_ATA_POWER_OFF | ||
259 | {1, S_O(disk_poweroff), false, "disk poweroff", off_on }, | ||
260 | #endif | ||
261 | {8, S_O(disk_spindown), 5, "disk spindown", NULL }, | ||
262 | /* browser */ | ||
263 | {2, S_O(dirfilter), SHOW_MUSIC, | ||
264 | "show files", "all,supported,music,playlists" }, | ||
265 | {1, S_O(sort_case), false, "sort case", off_on }, | ||
266 | {1, S_O(browse_current), false, "follow playlist", off_on }, | ||
267 | /* playlist */ | ||
268 | {1, S_O(playlist_viewer_icons), true, "playlist viewer icons", off_on }, | ||
269 | {1, S_O(playlist_viewer_indices), true, | ||
270 | "playlist viewer indices", off_on }, | ||
271 | {1, S_O(playlist_viewer_track_display), 0, | ||
272 | "playlist viewer track display", "track name,full path" }, | ||
273 | {2, S_O(recursive_dir_insert), RECURSE_OFF, | ||
274 | "recursive directory insert", off_on_ask }, | ||
275 | /* bookmarks */ | ||
276 | {3, S_O(autocreatebookmark), BOOKMARK_NO, "autocreate bookmarks", | ||
277 | "off,on,ask,recent only - on,recent only - ask" }, | ||
278 | {2, S_O(autoloadbookmark), BOOKMARK_NO, | ||
279 | "autoload bookmarks", off_on_ask }, | ||
280 | {2, S_O(usemrb), BOOKMARK_NO, | ||
281 | "use most-recent-bookmarks", "off,on,unique only" }, | ||
282 | #ifdef HAVE_LCD_BITMAP | ||
283 | /* peak meter */ | ||
284 | {5, S_O(peak_meter_clip_hold), 16, "peak meter clip hold", /* 0...25 */ | ||
285 | "on,1,2,3,4,5,6,7,8,9,10,15,20,25,30,45,60,90,2min,3min,5min,10min,20min,45min,90min" }, | ||
286 | {1, S_O(peak_meter_performance), false, "peak meter busy", off_on }, | ||
287 | {5, S_O(peak_meter_hold), 3, "peak meter hold", | ||
288 | "off,200ms,300ms,500ms,1,2,3,4,5,6,7,8,9,10,15,20,30,1min" }, | ||
289 | {7, S_O(peak_meter_release), 8, "peak meter release", NULL }, /* 0...126 */ | ||
290 | {1, S_O(peak_meter_dbfs), true, "peak meter dbfs", NULL }, | ||
291 | {7, S_O(peak_meter_min), 60, "peak meter min", NULL }, /* 0...100 */ | ||
292 | {7, S_O(peak_meter_max), 0, "peak meter max", NULL }, /* 0...100 */ | ||
293 | #endif | ||
294 | #ifdef HAVE_MAS3587F | ||
295 | /* recording */ | ||
296 | {1, S_O(rec_editable), false, "editable recordings", off_on }, | ||
297 | {4, S_O(rec_timesplit), 0, "rec timesplit", /* 0...13 */ | ||
298 | "off,00:05,00:10,00:15,00:30,01:00,02:00,04:00,06:00,08:00,10:00,12:00,18:00,24:00" }, | ||
299 | {1, S_O(rec_channels), 0, "rec channels", "stereo,mono" }, | ||
300 | {4, S_O(rec_mic_gain), 8, "rec mic gain", NULL }, | ||
301 | {3, S_O(rec_quality), 5, "rec quality", NULL }, | ||
302 | {2, S_O(rec_source), 0, /* 0=mic */ | ||
303 | "rec source", "mic,line,spdif" }, | ||
304 | {3, S_O(rec_frequency), 0, /* 0=44.1kHz */ | ||
305 | "rec frequency", "44,48,32,22,24,16" }, | ||
306 | {4, S_O(rec_left_gain), 2, /* 0dB */ | ||
307 | "rec left gain", NULL }, /* 0...15 */ | ||
308 | {4, S_O(rec_right_gain), 2, /* 0dB */ | ||
309 | "rec right gain", NULL }, /* 0...15 */ | ||
310 | {1, S_O(rec_prerecord_time), 0, "prerecording time", NULL }, /* 0...30 */ | ||
311 | {1, S_O(rec_directory), 0, /* rec_base_directory */ | ||
312 | "rec directory", REC_BASE_DIR ",current" }, | ||
313 | #endif | ||
314 | #ifdef HAVE_MAS3507D | ||
315 | {1, S_O(line_in), false, "line in", off_on }, | ||
316 | #endif | ||
317 | /* voice */ | ||
318 | {2, S_O(talk_dir), 0, "talk dir", "off,number,spell,enter,hover" }, | ||
319 | {2, S_O(talk_file), 0, "talk file", "off,number,spell" }, | ||
320 | {1, S_O(talk_menu), true, "talk menu", off_on }, | ||
321 | |||
322 | /* new stuff to be added here */ | ||
323 | /* If values are just added to the end, no need to bump the version. */ | ||
324 | |||
325 | /* Sum of all bit sizes must not grow beyond 0xB8*8 = 1472 */ | ||
326 | }; | ||
327 | |||
328 | |||
329 | /* helper function to extract n (<=32) bits from an arbitrary position */ | ||
330 | static unsigned long get_bits( | ||
331 | unsigned long* p, /* the start of the bitfield array */ | ||
332 | unsigned int from, /* bit no. to start reading from */ | ||
333 | unsigned int size) /* how many bits to read */ | ||
334 | { | ||
335 | unsigned int bit_index; | ||
336 | unsigned int bits_to_use; | ||
337 | |||
338 | unsigned long mask; | ||
339 | unsigned long result; | ||
340 | |||
341 | if (size==1) | ||
342 | { /* short cut */ | ||
343 | return (p[from/32] & 1<<from%32) != 0; | ||
344 | } | ||
345 | |||
346 | result = 0; | ||
347 | while (size) | ||
348 | { | ||
349 | bit_index = from % 32; | ||
350 | bits_to_use = MIN(32 - bit_index, size); | ||
351 | mask = 0xFFFFFFFF >> (32 - bits_to_use); | ||
352 | mask <<= bit_index; | ||
353 | |||
354 | result <<= bits_to_use; /* from last round */ | ||
355 | result |= (p[from/32] & mask) >> bit_index; | ||
356 | |||
357 | from += bits_to_use; | ||
358 | size -= bits_to_use; | ||
359 | } | ||
360 | |||
361 | return result; | ||
362 | } | ||
363 | |||
364 | /* helper function to set n (<=32) bits to an arbitrary position */ | ||
365 | static void set_bits( | ||
366 | unsigned long* p, /* the start of the bitfield array */ | ||
367 | unsigned int from, /* bit no. to start writing into */ | ||
368 | unsigned int size, /* how many bits to change */ | ||
369 | unsigned long value) /* content (LSBs will be taken) */ | ||
370 | { | ||
371 | unsigned int end; | ||
372 | unsigned int word_index, bit_index; | ||
373 | unsigned int bits_to_use; | ||
374 | |||
375 | unsigned long mask; | ||
376 | |||
377 | if (size==1) | ||
378 | { /* short cut */ | ||
379 | if (value & 1) | ||
380 | p[from/32] |= 1<<from%32; | ||
381 | else | ||
382 | p[from/32] &= ~(1<<from%32); | ||
383 | return; | ||
384 | } | ||
385 | |||
386 | end = from + size - 1; | ||
387 | |||
388 | /* write back to front, least to most significant */ | ||
389 | while (size) | ||
390 | { | ||
391 | word_index = end / 32; | ||
392 | bit_index = (end % 32) + 1; | ||
393 | bits_to_use = MIN(bit_index, size); | ||
394 | bit_index -= bits_to_use; | ||
395 | mask = 0xFFFFFFFF >> (32 - bits_to_use); | ||
396 | mask <<= bit_index; | ||
397 | |||
398 | p[word_index] = (p[word_index] & ~mask) | (value<<bit_index & mask); | ||
399 | |||
400 | value >>= bits_to_use; | ||
401 | size -= bits_to_use; | ||
402 | end -= bits_to_use; | ||
403 | } | ||
404 | } | ||
173 | 405 | ||
174 | /* | 406 | /* |
175 | * Calculates the checksum for the config block and returns it | 407 | * Calculates the checksum for the config block and returns it |
@@ -313,91 +545,52 @@ static int load_config_buffer( void ) | |||
313 | return 0; | 545 | return 0; |
314 | } | 546 | } |
315 | 547 | ||
548 | |||
549 | /* helper to save content of global_settings into a bitfield, | ||
550 | as described per table */ | ||
551 | static void save_bit_table(const struct bit_entry* p_table, int count, int bitstart) | ||
552 | { | ||
553 | unsigned long* p_bitfield = (unsigned long*)config_block; /* 32 bit addr. */ | ||
554 | unsigned long value; /* 32 bit content */ | ||
555 | int i; | ||
556 | const struct bit_entry* p_run = p_table; /* start after the size info */ | ||
557 | int curr_bit = bitstart + p_table->bit_size; | ||
558 | count--; /* first is excluded from loop */ | ||
559 | |||
560 | for (i=0; i<count; i++) | ||
561 | { | ||
562 | p_run++; | ||
563 | /* could do a memcpy, but that would be endian-dependent */ | ||
564 | switch(p_run->byte_size) | ||
565 | { | ||
566 | case 1: | ||
567 | value = ((unsigned char*)&global_settings)[p_run->settings_offset]; | ||
568 | break; | ||
569 | case 2: | ||
570 | value = ((unsigned short*)&global_settings)[p_run->settings_offset/2]; | ||
571 | break; | ||
572 | case 4: | ||
573 | value = ((unsigned int*)&global_settings)[p_run->settings_offset/4]; | ||
574 | break; | ||
575 | default: | ||
576 | DEBUGF( "illegal size!" ); | ||
577 | continue; | ||
578 | } | ||
579 | set_bits(p_bitfield, curr_bit, p_run->bit_size & 0x3F, value); | ||
580 | curr_bit += p_run->bit_size & 0x3F; | ||
581 | } | ||
582 | set_bits(p_bitfield, bitstart, p_table->bit_size, /* write size */ | ||
583 | curr_bit); /* = position after last element */ | ||
584 | } | ||
585 | |||
586 | |||
316 | /* | 587 | /* |
317 | * persist all runtime user settings to disk or RTC RAM | 588 | * persist all runtime user settings to disk or RTC RAM |
318 | */ | 589 | */ |
319 | int settings_save( void ) | 590 | int settings_save( void ) |
320 | { | 591 | { |
592 | int restore[6]; /* recover, FIXME: get rid of this */ | ||
321 | DEBUGF( "settings_save()\n" ); | 593 | DEBUGF( "settings_save()\n" ); |
322 | |||
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; | ||
331 | |||
332 | config_block[0xa] = (unsigned char) | ||
333 | ((global_settings.contrast & 0x3f) | | ||
334 | (global_settings.invert ? 0x40 : 0) | | ||
335 | (global_settings.show_icons ? 0x80 : 0) ); | ||
336 | |||
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; | ||
343 | |||
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)); | ||
352 | |||
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)); | ||
358 | |||
359 | config_block[0x10] = (unsigned char) | ||
360 | ((global_settings.ff_rewind_min_step & 15) << 4 | | ||
361 | (global_settings.ff_rewind_accel & 15)); | ||
362 | |||
363 | config_block[0x11] = (unsigned char) | ||
364 | ((global_settings.avc & 0x03) | | ||
365 | ((global_settings.channel_config & 0x07) << 2)); | ||
366 | |||
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 ); | ||
373 | |||
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)); | ||
379 | |||
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); | ||
383 | |||
384 | memcpy(&config_block[0x1d], &global_settings.resume_seed, 4); | ||
385 | |||
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)); | ||
401 | 594 | ||
402 | { | 595 | { |
403 | int elapsed_secs; | 596 | int elapsed_secs; |
@@ -408,57 +601,45 @@ int settings_save( void ) | |||
408 | 601 | ||
409 | if ( global_settings.runtime > global_settings.topruntime ) | 602 | if ( global_settings.runtime > global_settings.topruntime ) |
410 | global_settings.topruntime = global_settings.runtime; | 603 | global_settings.topruntime = global_settings.runtime; |
411 | |||
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); | ||
416 | } | 604 | } |
417 | 605 | ||
418 | #ifdef HAVE_LCD_CHARCELLS | 606 | /* While the mpeg_val2phys business still exists: ( to be removed) */ |
419 | config_block[0xa8]=(unsigned char)global_settings.jump_scroll; | 607 | /* temporarily replace the hardware levels with the MMI values */ |
420 | config_block[0xa9]=(unsigned char)global_settings.jump_scroll_delay; | 608 | restore[SOUND_VOLUME] = global_settings.volume; |
609 | global_settings.volume = mpeg_val2phys(SOUND_VOLUME, global_settings.volume); | ||
610 | restore[SOUND_BASS] = global_settings.bass; | ||
611 | global_settings.bass = mpeg_val2phys(SOUND_BASS, global_settings.bass); | ||
612 | restore[SOUND_TREBLE] = global_settings.treble; | ||
613 | global_settings.treble = mpeg_val2phys(SOUND_TREBLE, global_settings.treble); | ||
614 | restore[SOUND_BALANCE] = global_settings.balance; | ||
615 | global_settings.balance = mpeg_val2phys(SOUND_BALANCE, global_settings.balance); | ||
616 | #ifdef HAVE_MAS3587F | ||
617 | restore[SOUND_LOUDNESS] = global_settings.loudness; | ||
618 | global_settings.loudness = mpeg_val2phys(SOUND_LOUDNESS, global_settings.loudness); | ||
619 | restore[SOUND_SUPERBASS] = global_settings.bass_boost; | ||
620 | global_settings.bass_boost = mpeg_val2phys(SOUND_SUPERBASS, global_settings.bass_boost); | ||
421 | #endif | 621 | #endif |
422 | config_block[0xaa] = (unsigned char) | 622 | |
423 | global_settings.max_files_in_playlist & 0xff; | 623 | |
424 | config_block[0xab] = (unsigned char) | 624 | /* serialize scalar values into RTC and HD sector, specified via table */ |
425 | (global_settings.max_files_in_playlist >> 8) & 0xff; | 625 | save_bit_table(rtc_bits, sizeof(rtc_bits)/sizeof(rtc_bits[0]), 4*8); |
426 | config_block[0xac] = (unsigned char) | 626 | save_bit_table(hd_bits, sizeof(hd_bits)/sizeof(hd_bits[0]), RTC_BLOCK_SIZE*8); |
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; | ||
447 | |||
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; | ||
452 | 627 | ||
453 | strncpy(&config_block[0xb8], global_settings.wps_file, MAX_FILENAME); | 628 | strncpy(&config_block[0xb8], global_settings.wps_file, MAX_FILENAME); |
454 | strncpy(&config_block[0xcc], global_settings.lang_file, MAX_FILENAME); | 629 | strncpy(&config_block[0xcc], global_settings.lang_file, MAX_FILENAME); |
455 | strncpy(&config_block[0xe0], global_settings.font_file, MAX_FILENAME); | 630 | strncpy(&config_block[0xe0], global_settings.font_file, MAX_FILENAME); |
456 | 631 | ||
457 | config_block[0xf4]=((unsigned char)global_settings.rec_prerecord_time | | 632 | |
458 | ((unsigned char)global_settings.rec_directory << 5)); | 633 | /* restore the original values; to be removed with mpeg_val2phys */ |
459 | config_block[0xf5] = (global_settings.talk_dir & 7) | | 634 | global_settings.volume = restore[SOUND_VOLUME]; |
460 | ((global_settings.talk_file & 3) << 3) | | 635 | global_settings.bass = restore[SOUND_BASS]; |
461 | ((global_settings.talk_menu & 1) << 5); | 636 | global_settings.treble = restore[SOUND_TREBLE]; |
637 | global_settings.balance = restore[SOUND_BALANCE]; | ||
638 | #ifdef HAVE_MAS3587F | ||
639 | global_settings.loudness = restore[SOUND_LOUDNESS]; | ||
640 | global_settings.bass_boost = restore[SOUND_SUPERBASS]; | ||
641 | #endif | ||
642 | |||
462 | 643 | ||
463 | if(save_config_buffer()) | 644 | if(save_config_buffer()) |
464 | { | 645 | { |
@@ -593,11 +774,66 @@ void settings_apply(void) | |||
593 | set_car_adapter_mode(global_settings.car_adapter_mode); | 774 | set_car_adapter_mode(global_settings.car_adapter_mode); |
594 | } | 775 | } |
595 | 776 | ||
777 | |||
778 | /* helper to load global_settings from a bitfield, as described per table */ | ||
779 | static void load_bit_table(const struct bit_entry* p_table, int count, int bitstart) | ||
780 | { | ||
781 | unsigned long* p_bitfield = (unsigned long*)config_block; /* 32 bit addr. */ | ||
782 | unsigned long value; /* 32 bit content */ | ||
783 | int i; | ||
784 | int maxbit; /* how many bits are valid in the saved part */ | ||
785 | const struct bit_entry* p_run = p_table; /* start after the size info */ | ||
786 | count--; /* first is excluded from loop */ | ||
787 | maxbit = get_bits(p_bitfield, bitstart, p_table->bit_size); | ||
788 | bitstart += p_table->bit_size; | ||
789 | |||
790 | for (i=0; i<count; i++) | ||
791 | { | ||
792 | int size; | ||
793 | p_run++; | ||
794 | |||
795 | size = p_run->bit_size & 0x3F; /* mask off abused bits */ | ||
796 | if (bitstart + size > maxbit) | ||
797 | break; /* exit if this is not valid any more in bitfield */ | ||
798 | |||
799 | value = get_bits(p_bitfield, bitstart, size); | ||
800 | bitstart += size; | ||
801 | if (p_run->bit_size & SIGNED) | ||
802 | { // sign extend the read value | ||
803 | unsigned long mask = 0xFFFFFFFF << (size - 1); | ||
804 | if (value & mask) /* true if MSB of value is set */ | ||
805 | value |= mask; | ||
806 | } | ||
807 | |||
808 | /* could do a memcpy, but that would be endian-dependent */ | ||
809 | switch(p_run->byte_size) | ||
810 | { | ||
811 | case 1: | ||
812 | ((unsigned char*)&global_settings)[p_run->settings_offset] = | ||
813 | (unsigned char)value; | ||
814 | break; | ||
815 | case 2: | ||
816 | ((unsigned short*)&global_settings)[p_run->settings_offset/2] = | ||
817 | (unsigned short)value; | ||
818 | break; | ||
819 | case 4: | ||
820 | ((unsigned int*)&global_settings)[p_run->settings_offset/4] = | ||
821 | (unsigned int)value; | ||
822 | break; | ||
823 | default: | ||
824 | DEBUGF( "illegal size!" ); | ||
825 | continue; | ||
826 | } | ||
827 | } | ||
828 | } | ||
829 | |||
830 | |||
596 | /* | 831 | /* |
597 | * load settings from disk or RTC RAM | 832 | * load settings from disk or RTC RAM |
598 | */ | 833 | */ |
599 | void settings_load(void) | 834 | void settings_load(void) |
600 | { | 835 | { |
836 | int restore[6]; /* recover, FIXME: get rid of this */ | ||
601 | 837 | ||
602 | DEBUGF( "reload_all_settings()\n" ); | 838 | DEBUGF( "reload_all_settings()\n" ); |
603 | 839 | ||
@@ -606,215 +842,53 @@ void settings_load(void) | |||
606 | 842 | ||
607 | /* load the buffer from the RTC (resets it to all-unused if the block | 843 | /* 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 */ | 844 | is invalid) and decode the settings which are set in the block */ |
609 | if (!load_config_buffer()) { | 845 | if (!load_config_buffer()) |
610 | if (config_block[0x4] != 0xFF) | 846 | { |
611 | global_settings.volume = config_block[0x4]; | 847 | /* While the mpeg_val2phys business still exists: ( FIXME: to be removed) */ |
612 | if (config_block[0x5] != 0xFF) | 848 | /* temporarily put markers into the values to detect if they got loaded */ |
613 | global_settings.balance = (char)config_block[0x5]; | 849 | restore[SOUND_VOLUME] = global_settings.volume; |
614 | if (config_block[0x6] != 0xFF) | 850 | global_settings.volume = MARKER; |
615 | global_settings.bass = config_block[0x6]; | 851 | restore[SOUND_BASS] = global_settings.bass; |
616 | if (config_block[0x7] != 0xFF) | 852 | global_settings.bass = MARKER; |
617 | global_settings.treble = config_block[0x7]; | 853 | restore[SOUND_TREBLE] = global_settings.treble; |
618 | if (config_block[0x8] != 0xFF) | 854 | global_settings.treble = MARKER; |
619 | global_settings.loudness = config_block[0x8]; | 855 | restore[SOUND_BALANCE] = global_settings.balance; |
620 | if (config_block[0x9] != 0xFF) | 856 | global_settings.balance = MARKER; |
621 | global_settings.bass_boost = config_block[0x9]; | 857 | #ifdef HAVE_MAS3587F |
622 | 858 | restore[SOUND_LOUDNESS] = global_settings.loudness; | |
623 | if (config_block[0xa] != 0xFF) { | 859 | global_settings.loudness = MARKER; |
624 | global_settings.contrast = config_block[0xa] & 0x3f; | 860 | restore[SOUND_SUPERBASS] = global_settings.bass_boost; |
625 | global_settings.invert = | 861 | global_settings.bass_boost = MARKER; |
626 | config_block[0xa] & 0x40 ? true : false; | 862 | #endif |
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; | ||
631 | } | ||
632 | |||
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; | ||
640 | } | ||
641 | |||
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 */ | ||
656 | } | ||
657 | 863 | ||
658 | if (config_block[0xf] != 0xFF) { | 864 | /* load scalar values from RTC and HD sector, specified via table */ |
659 | global_settings.volume_type = config_block[0xf] & 1; | 865 | load_bit_table(rtc_bits, sizeof(rtc_bits)/sizeof(rtc_bits[0]), 4*8); |
660 | global_settings.battery_type = (config_block[0xf] >> 1) & 1; | 866 | load_bit_table(hd_bits, sizeof(hd_bits)/sizeof(hd_bits[0]), RTC_BLOCK_SIZE*8); |
661 | global_settings.timeformat = (config_block[0xf] >> 2) & 1; | ||
662 | global_settings.scroll_speed = config_block[0xf] >> 3; | ||
663 | } | ||
664 | |||
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; | ||
668 | } | ||
669 | |||
670 | if (config_block[0x11] != 0xFF) | ||
671 | { | ||
672 | global_settings.avc = config_block[0x11] & 0x03; | ||
673 | global_settings.channel_config = (config_block[0x11] >> 2) & 0x07; | ||
674 | } | ||
675 | |||
676 | if (config_block[0x12] != 0xFF) | ||
677 | global_settings.resume_index = *((short*)(&config_block[0x12])); | ||
678 | |||
679 | if (config_block[0x14] != 0xFF) | ||
680 | global_settings.resume_first_index= *((short*)(&config_block[0x14])); | ||
681 | |||
682 | if (config_block[0x16] != 0xFF) | ||
683 | memcpy(&global_settings.resume_offset, &config_block[0x16], 4); | ||
684 | |||
685 | if (config_block[0x1a] != 0xFF) | ||
686 | global_settings.disk_spindown = config_block[0x1a]; | ||
687 | |||
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; | ||
693 | } | ||
694 | |||
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; | ||
701 | } | ||
702 | |||
703 | if (config_block[0x1d] != 0xFF) | ||
704 | memcpy(&global_settings.resume_seed, &config_block[0x1d], 4); | ||
705 | |||
706 | if (config_block[0x21] != 0xFF) | ||
707 | { | ||
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; | ||
711 | } | ||
712 | |||
713 | if (config_block[0x22] != 0xFF) | ||
714 | { | ||
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; | ||
718 | } | ||
719 | |||
720 | if (config_block[0x23] != 0xFF) | ||
721 | global_settings.rec_left_gain = config_block[0x23] & 0x0f; | ||
722 | |||
723 | if (config_block[0x24] != 0xFF) | ||
724 | global_settings.rec_right_gain = config_block[0x24] & 0x0f; | ||
725 | |||
726 | if (config_block[0x25] != 0xFF) | ||
727 | { | ||
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; | ||
732 | } | ||
733 | |||
734 | if (config_block[0x27] != 0xff) | ||
735 | global_settings.runtime = | ||
736 | config_block[0x26] | (config_block[0x27] << 8); | ||
737 | |||
738 | if (config_block[0x29] != 0xff) | ||
739 | global_settings.topruntime = | ||
740 | config_block[0x28] | (config_block[0x29] << 8); | ||
741 | |||
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; | ||
753 | } | ||
754 | |||
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; | ||
759 | } | ||
760 | |||
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; | ||
764 | } | ||
765 | |||
766 | if(config_block[0xb2] != 0xff) | ||
767 | global_settings.peak_meter_min = config_block[0xb2]; | ||
768 | 867 | ||
769 | if(config_block[0xb3] != 0xff) | 868 | /* FIXME, to be removed with mpeg_val2phys: */ |
770 | global_settings.peak_meter_max = config_block[0xb3]; | 869 | /* if a value got loaded, convert it, else restore it */ |
771 | 870 | global_settings.volume = (global_settings.volume == MARKER) ? | |
772 | if(config_block[0xb4] != 0xff) | 871 | restore[SOUND_VOLUME] : mpeg_phys2val(SOUND_VOLUME, global_settings.volume); |
773 | global_settings.battery_capacity = config_block[0xb4]*50 + 1000; | 872 | global_settings.bass = (global_settings.bass == MARKER) ? |
774 | 873 | restore[SOUND_BASS] : mpeg_phys2val(SOUND_BASS, global_settings.bass); | |
775 | if (config_block[0xb5] != 0xff) | 874 | global_settings.treble = (global_settings.treble == MARKER) ? |
776 | global_settings.scroll_step = config_block[0xb5]; | 875 | restore[SOUND_TREBLE] : mpeg_phys2val(SOUND_TREBLE, global_settings.treble); |
777 | 876 | global_settings.balance = (global_settings.balance == MARKER) ? | |
778 | if (config_block[0xb6] != 0xff) | 877 | restore[SOUND_BALANCE] : mpeg_phys2val(SOUND_BALANCE, global_settings.balance); |
779 | global_settings.scroll_delay = config_block[0xb6]; | 878 | #ifdef HAVE_MAS3587F |
780 | 879 | global_settings.loudness = (global_settings.loudness == MARKER) ? | |
781 | if (config_block[0xb7] != 0xff) | 880 | restore[SOUND_LOUDNESS] : mpeg_phys2val(SOUND_LOUDNESS, global_settings.loudness); |
782 | global_settings.bidir_limit = config_block[0xb7]; | 881 | global_settings.bass_boost = (global_settings.bass_boost == MARKER) ? |
783 | 882 | restore[SOUND_SUPERBASS] : mpeg_phys2val(SOUND_SUPERBASS, global_settings.bass_boost); | |
784 | if (config_block[0xac] != 0xff) | 883 | #endif |
785 | global_settings.max_files_in_dir = | ||
786 | config_block[0xac] | (config_block[0xad] << 8); | ||
787 | 884 | ||
788 | if (config_block[0xaa] != 0xff) | 885 | if ( global_settings.contrast < MIN_CONTRAST_SETTING ) |
789 | global_settings.max_files_in_playlist = | 886 | global_settings.contrast = lcd_default_contrast(); |
790 | config_block[0xaa] | (config_block[0xab] << 8); | ||
791 | 887 | ||
792 | strncpy(global_settings.wps_file, &config_block[0xb8], MAX_FILENAME); | 888 | strncpy(global_settings.wps_file, &config_block[0xb8], MAX_FILENAME); |
793 | strncpy(global_settings.lang_file, &config_block[0xcc], MAX_FILENAME); | 889 | strncpy(global_settings.lang_file, &config_block[0xcc], MAX_FILENAME); |
794 | strncpy(global_settings.font_file, &config_block[0xe0], MAX_FILENAME); | 890 | strncpy(global_settings.font_file, &config_block[0xe0], MAX_FILENAME); |
795 | 891 | } | |
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; | ||
799 | } | ||
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; | ||
804 | } | ||
805 | |||
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; | ||
816 | } | ||
817 | } | ||
818 | 892 | ||
819 | settings_apply(); | 893 | settings_apply(); |
820 | } | 894 | } |
@@ -882,94 +956,131 @@ void set_file(char* filename, char* setting, int maxlen) | |||
882 | settings_save(); | 956 | settings_save(); |
883 | } | 957 | } |
884 | 958 | ||
885 | static void set_sound(char* value, int type, int* setting) | 959 | /* helper to sort a .cfg file entry into a global_settings member, |
960 | as described per table. Returns the position if found, else 0. */ | ||
961 | static int load_cfg_table( | ||
962 | const struct bit_entry* p_table, /* the table which describes the entries */ | ||
963 | int count, /* number of entries in the table, including the first */ | ||
964 | char* name, /* the item to be searched */ | ||
965 | char* value, /* the value which got loaded for that item */ | ||
966 | int hint) /* position to start looking */ | ||
886 | { | 967 | { |
887 | int num = atoi(value); | 968 | int i = hint; |
888 | 969 | ||
889 | num = mpeg_phys2val(type, num); | 970 | do |
890 | |||
891 | if ((num > mpeg_sound_max(type)) || | ||
892 | (num < mpeg_sound_min(type))) | ||
893 | { | 971 | { |
894 | num = mpeg_sound_default(type); | 972 | if (p_table[i].cfg_name != NULL && !strcasecmp(name, p_table[i].cfg_name)) |
895 | } | 973 | { /* found */ |
896 | 974 | int val = 0; | |
897 | *setting = num; | 975 | if (p_table[i].cfg_val == NULL) |
898 | mpeg_sound_set(type, num); | 976 | { /* numerical value, just convert the string */ |
899 | 977 | val = atoi(value); | |
900 | #ifdef HAVE_MAS3507D | 978 | } |
901 | /* This is required to actually apply balance */ | 979 | else |
902 | if (SOUND_BALANCE == type) | 980 | { /* set of string values, find the index */ |
903 | mpeg_sound_set(SOUND_VOLUME, global_settings.volume); | 981 | const char* item; |
904 | #endif | 982 | const char* run; |
905 | } | 983 | int len = strlen(value); |
906 | 984 | ||
907 | static void set_cfg_bool(bool* variable, char* value) | 985 | item = run = p_table[i].cfg_val; |
908 | { | 986 | |
909 | /* look for the 'n' in 'on' */ | 987 | while(1) |
910 | if ((value[1] & 0xdf) == 'N') | 988 | { |
911 | *variable = true; | 989 | /* count the length of the field */ |
912 | else | 990 | while (*run != ',' && *run != '\0') |
913 | *variable = false; | 991 | run++; |
914 | } | 992 | |
993 | if (!strncasecmp(value, item, MAX(run-item, len))) | ||
994 | break; /* match, exit the search */ | ||
995 | |||
996 | if (*run == '\0') /* reached the end of the choices */ | ||
997 | return i; /* return the position, but don't update */ | ||
998 | |||
999 | val++; /* count the item up */ | ||
1000 | run++; /* behind the ',' */ | ||
1001 | item = run; | ||
1002 | } | ||
1003 | } | ||
1004 | |||
1005 | /* could do a memcpy, but that would be endian-dependent */ | ||
1006 | switch(p_table[i].byte_size) | ||
1007 | { | ||
1008 | case 1: | ||
1009 | ((unsigned char*)&global_settings)[p_table[i].settings_offset] = | ||
1010 | (unsigned char)val; | ||
1011 | break; | ||
1012 | case 2: | ||
1013 | ((unsigned short*)&global_settings)[p_table[i].settings_offset/2] = | ||
1014 | (unsigned short)val; | ||
1015 | break; | ||
1016 | case 4: | ||
1017 | ((unsigned int*)&global_settings)[p_table[i].settings_offset/4] = | ||
1018 | (unsigned int)val; | ||
1019 | break; | ||
1020 | default: | ||
1021 | DEBUGF( "illegal size!" ); | ||
1022 | continue; | ||
1023 | } | ||
915 | 1024 | ||
916 | static void set_cfg_int(int* variable, char* value, int min, int max ) | 1025 | return i; /* return the position */ |
917 | { | 1026 | } |
918 | *variable = atoi(value); | ||
919 | 1027 | ||
920 | if (*variable < min) | 1028 | i++; |
921 | *variable = min; | 1029 | if (i==count) |
922 | else | 1030 | i=1; /* wraparound */ |
923 | if (*variable > max) | 1031 | } while (i != hint); /* back where we started, all searched */ |
924 | *variable = max; | 1032 | |
1033 | return 0; /* indicate not found */ | ||
925 | } | 1034 | } |
926 | 1035 | ||
927 | static void set_cfg_option(int* variable, char* value, | ||
928 | char* options[], int numoptions ) | ||
929 | { | ||
930 | int i; | ||
931 | |||
932 | for (i=0; i<numoptions; i++) { | ||
933 | if (!strcasecmp(options[i], value)) { | ||
934 | *variable = i; | ||
935 | break; | ||
936 | } | ||
937 | } | ||
938 | } | ||
939 | 1036 | ||
940 | bool settings_load_config(char* file) | 1037 | bool settings_load_config(char* file) |
941 | { | 1038 | { |
942 | int fd; | 1039 | int fd; |
943 | char line[128]; | 1040 | char line[128]; |
1041 | int restore[6]; /* recover, FIXME: get rid of this */ | ||
944 | 1042 | ||
945 | fd = open(file, O_RDONLY); | 1043 | fd = open(file, O_RDONLY); |
946 | if (fd < 0) | 1044 | if (fd < 0) |
947 | return false; | 1045 | return false; |
948 | 1046 | ||
1047 | |||
1048 | /* While the mpeg_val2phys business still exists: ( to be removed) */ | ||
1049 | /* temporarily put markers into the values to detect if they got loaded */ | ||
1050 | restore[SOUND_VOLUME] = global_settings.volume; | ||
1051 | global_settings.volume = MARKER; | ||
1052 | restore[SOUND_BASS] = global_settings.bass; | ||
1053 | global_settings.bass = MARKER; | ||
1054 | restore[SOUND_TREBLE] = global_settings.treble; | ||
1055 | global_settings.treble = MARKER; | ||
1056 | restore[SOUND_BALANCE] = global_settings.balance; | ||
1057 | global_settings.balance = MARKER; | ||
1058 | #ifdef HAVE_MAS3587F | ||
1059 | restore[SOUND_LOUDNESS] = global_settings.loudness; | ||
1060 | global_settings.loudness = MARKER; | ||
1061 | restore[SOUND_SUPERBASS] = global_settings.bass_boost; | ||
1062 | global_settings.bass_boost = MARKER; | ||
1063 | #endif | ||
1064 | |||
1065 | |||
949 | while (read_line(fd, line, sizeof line) > 0) | 1066 | while (read_line(fd, line, sizeof line) > 0) |
950 | { | 1067 | { |
951 | char* name; | 1068 | char* name; |
952 | char* value; | 1069 | char* value; |
1070 | const struct bit_entry* table[2] = { rtc_bits, hd_bits }; | ||
1071 | const int ta_size[2] = { | ||
1072 | sizeof(rtc_bits)/sizeof(rtc_bits[0]), | ||
1073 | sizeof(hd_bits)/sizeof(hd_bits[0]) | ||
1074 | }; | ||
1075 | int last_table = 0; /* which table was used last round */ | ||
1076 | int last_pos = 1; /* at which position did we succeed */ | ||
1077 | int pos; /* currently returned position */ | ||
953 | 1078 | ||
954 | if (!settings_parseline(line, &name, &value)) | 1079 | if (!settings_parseline(line, &name, &value)) |
955 | continue; | 1080 | continue; |
956 | 1081 | ||
957 | if (!strcasecmp(name, "volume")) | 1082 | /* check for the string values */ |
958 | set_sound(value, SOUND_VOLUME, &global_settings.volume); | 1083 | if (!strcasecmp(name, "wps")) { |
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); | ||
971 | } | ||
972 | else if (!strcasecmp(name, "wps")) { | ||
973 | if (wps_load(value,false)) | 1084 | if (wps_load(value,false)) |
974 | set_file(value, global_settings.wps_file, MAX_FILENAME); | 1085 | set_file(value, global_settings.wps_file, MAX_FILENAME); |
975 | } | 1086 | } |
@@ -980,261 +1091,129 @@ bool settings_load_config(char* file) | |||
980 | talk_init(); /* use voice of same language */ | 1091 | talk_init(); /* use voice of same language */ |
981 | } | 1092 | } |
982 | } | 1093 | } |
983 | else if (!strcasecmp(name, "bidir limit")) | ||
984 | set_cfg_int(&global_settings.bidir_limit, value, 0, 200); | ||
985 | #ifdef HAVE_LCD_BITMAP | 1094 | #ifdef HAVE_LCD_BITMAP |
986 | else if (!strcasecmp(name, "font")) { | 1095 | else if (!strcasecmp(name, "font")) { |
987 | if (font_load(value)) | 1096 | if (font_load(value)) |
988 | set_file(value, global_settings.font_file, MAX_FILENAME); | 1097 | set_file(value, global_settings.font_file, MAX_FILENAME); |
989 | } | 1098 | } |
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); | ||
1005 | } | ||
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); | ||
1013 | } | ||
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); | ||
1025 | } | ||
1026 | else if (!strcasecmp(name, "battery display")) { | ||
1027 | static char* options[] = {"graphic", "numeric"}; | ||
1028 | set_cfg_option(&global_settings.battery_type, value, options, 2); | ||
1029 | } | ||
1030 | else if (!strcasecmp(name, "time format")) { | ||
1031 | static char* options[] = {"24hour", "12hour"}; | ||
1032 | set_cfg_option(&global_settings.timeformat, value, options, 2); | ||
1033 | } | ||
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); | ||
1052 | } | ||
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); | ||
1056 | } | ||
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); | ||
1062 | } | ||
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); | ||
1078 | } | ||
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); | ||
1089 | } | ||
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); | ||
1108 | } | ||
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); | ||
1124 | } | ||
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); | ||
1128 | } | ||
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); | ||
1132 | } | ||
1133 | else if (!strcasecmp(name, "rec channels")) { | ||
1134 | static char* options[] = {"stereo", "mono"}; | ||
1135 | set_cfg_option(&global_settings.rec_channels, value, options, 2); | ||
1136 | } | ||
1137 | else if (!strcasecmp(name, "editable recordings")) { | ||
1138 | set_cfg_bool(&global_settings.rec_editable, value); | ||
1139 | } | ||
1140 | else if (!strcasecmp(name, "prerecording time")) { | ||
1141 | set_cfg_int(&global_settings.rec_prerecord_time, value, 0, 30); | ||
1142 | } | ||
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); | ||
1146 | } | ||
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); | ||
1152 | } | ||
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); | ||
1157 | } | ||
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 | 1099 | #endif |
1168 | else if (!strcasecmp(name, "volume fade")) | 1100 | |
1169 | set_cfg_bool(&global_settings.fade_on_stop, value); | 1101 | /* check for scalar values, using the two tables */ |
1170 | else if (!strcasecmp(name, "max files in dir")) | 1102 | pos = load_cfg_table(table[last_table], ta_size[last_table], |
1171 | set_cfg_int(&global_settings.max_files_in_dir, value, | 1103 | name, value, last_pos); |
1172 | 50, 10000); | 1104 | if (pos) /* success */ |
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); | ||
1182 | } | ||
1183 | else if (!strcasecmp(name, "autoload bookmarks")) | ||
1184 | { | ||
1185 | static char* options[] = {"off", "on", "ask"}; | ||
1186 | set_cfg_option(&global_settings.autoloadbookmark, value, options, 3); | ||
1187 | } | ||
1188 | else if (!strcasecmp(name, "autocreate bookmarks")) | ||
1189 | { | ||
1190 | static char* options[] = {"off", "on", "ask","recent only - on", "recent only - ask"}; | ||
1191 | set_cfg_option(&global_settings.autocreatebookmark, value, options, 5); | ||
1192 | } | ||
1193 | else if (!strcasecmp(name, "use most-recent-bookmarks")) | ||
1194 | { | 1105 | { |
1195 | static char* options[] = {"off", "on", "unique only"}; | 1106 | last_pos = pos; /* remember as a position hint for next round */ |
1196 | set_cfg_option(&global_settings.usemrb, value, options, 3); | 1107 | continue; |
1197 | } | 1108 | } |
1198 | else if (!strcasecmp(name, "playlist viewer icons")) | 1109 | |
1199 | set_cfg_bool(&global_settings.playlist_viewer_icons, value); | 1110 | last_table = 1-last_table; /* try other table */ |
1200 | else if (!strcasecmp(name, "playlist viewer indices")) | 1111 | last_pos = 1; /* search from start */ |
1201 | set_cfg_bool(&global_settings.playlist_viewer_indices, value); | 1112 | pos = load_cfg_table(table[last_table], ta_size[last_table], |
1202 | else if (!strcasecmp(name, "playlist viewer track display")) | 1113 | name, value, last_pos); |
1114 | if (pos) /* success */ | ||
1203 | { | 1115 | { |
1204 | static char* options[] = {"track name", "full path"}; | 1116 | last_pos = pos; /* remember as a position hint for next round */ |
1205 | set_cfg_option(&global_settings.playlist_viewer_track_display, | 1117 | continue; |
1206 | value, options, 2); | ||
1207 | } | 1118 | } |
1208 | else if (!strcasecmp(name, "talk dir")) | 1119 | } |
1120 | |||
1121 | /* FIXME, to be removed with mpeg_val2phys: */ | ||
1122 | /* if a value got loaded, convert it, else restore it */ | ||
1123 | global_settings.volume = (global_settings.volume == MARKER) ? | ||
1124 | restore[SOUND_VOLUME] : mpeg_phys2val(SOUND_VOLUME, global_settings.volume); | ||
1125 | global_settings.bass = (global_settings.bass == MARKER) ? | ||
1126 | restore[SOUND_BASS] : mpeg_phys2val(SOUND_BASS, global_settings.bass); | ||
1127 | global_settings.treble = (global_settings.treble == MARKER) ? | ||
1128 | restore[SOUND_TREBLE] : mpeg_phys2val(SOUND_TREBLE, global_settings.treble); | ||
1129 | global_settings.balance = (global_settings.balance == MARKER) ? | ||
1130 | restore[SOUND_BALANCE] : mpeg_phys2val(SOUND_BALANCE, global_settings.balance); | ||
1131 | #ifdef HAVE_MAS3587F | ||
1132 | global_settings.loudness = (global_settings.loudness == MARKER) ? | ||
1133 | restore[SOUND_LOUDNESS] : mpeg_phys2val(SOUND_LOUDNESS, global_settings.loudness); | ||
1134 | global_settings.bass_boost = (global_settings.bass_boost == MARKER) ? | ||
1135 | restore[SOUND_SUPERBASS] : mpeg_phys2val(SOUND_SUPERBASS, global_settings.bass_boost); | ||
1136 | #endif | ||
1137 | |||
1138 | close(fd); | ||
1139 | settings_apply(); | ||
1140 | settings_save(); | ||
1141 | return true; | ||
1142 | } | ||
1143 | |||
1144 | |||
1145 | /* helper to save content of global_settings into a file, | ||
1146 | as described per table */ | ||
1147 | static void save_cfg_table(const struct bit_entry* p_table, int count, int fd) | ||
1148 | { | ||
1149 | long value; /* 32 bit content */ | ||
1150 | int i; | ||
1151 | const struct bit_entry* p_run = p_table; /* start after the size info */ | ||
1152 | count--; /* first is excluded from loop */ | ||
1153 | |||
1154 | for (i=0; i<count; i++) | ||
1155 | { | ||
1156 | p_run++; | ||
1157 | |||
1158 | if (p_run->cfg_name == NULL) | ||
1159 | continue; /* this value is not to be saved */ | ||
1160 | |||
1161 | /* could do a memcpy, but that would be endian-dependent */ | ||
1162 | switch(p_run->byte_size) | ||
1209 | { | 1163 | { |
1210 | static char* options[] = {"off", "number", "spell", "enter", "hover"}; | 1164 | case 1: |
1211 | set_cfg_option(&global_settings.talk_dir, value, options, 5); | 1165 | if (p_run->bit_size & SIGNED) /* signed? */ |
1166 | value = ((char*)&global_settings)[p_run->settings_offset]; | ||
1167 | else | ||
1168 | value = ((unsigned char*)&global_settings)[p_run->settings_offset]; | ||
1169 | break; | ||
1170 | case 2: | ||
1171 | if (p_run->bit_size & SIGNED) /* signed? */ | ||
1172 | value = ((short*)&global_settings)[p_run->settings_offset/2]; | ||
1173 | else | ||
1174 | value = ((unsigned short*)&global_settings)[p_run->settings_offset/2]; | ||
1175 | break; | ||
1176 | case 4: | ||
1177 | value = ((unsigned int*)&global_settings)[p_run->settings_offset/4]; | ||
1178 | break; | ||
1179 | default: | ||
1180 | DEBUGF( "illegal size!" ); | ||
1181 | continue; | ||
1212 | } | 1182 | } |
1213 | else if (!strcasecmp(name, "talk file")) | 1183 | |
1184 | if (p_run->cfg_val == NULL) /* write as number */ | ||
1214 | { | 1185 | { |
1215 | static char* options[] = {"off", "number", "spell"}; | 1186 | fprintf(fd, "%s: %d\r\n", p_run->cfg_name, value); |
1216 | set_cfg_option(&global_settings.talk_file, value, options, 3); | ||
1217 | } | 1187 | } |
1218 | else if (!strcasecmp(name, "talk menu")) | 1188 | else /* write as item */ |
1219 | { | 1189 | { |
1220 | set_cfg_bool(&global_settings.talk_menu, value); | 1190 | const char* p = p_run->cfg_val; |
1191 | |||
1192 | fprintf(fd, "%s: ", p_run->cfg_name); | ||
1193 | |||
1194 | while(value >= 0) | ||
1195 | { | ||
1196 | char c = *p++; /* currently processed char */ | ||
1197 | if (c == ',') /* separator */ | ||
1198 | value--; | ||
1199 | else if (c == '\0') /* end of string */ | ||
1200 | break; /* not found */ | ||
1201 | else if (value == 0) /* the right place */ | ||
1202 | write(fd, &c, 1); /* char by char, this is lame, OK */ | ||
1203 | } | ||
1204 | |||
1205 | fprintf(fd, "\r\n"); | ||
1221 | } | 1206 | } |
1222 | } | 1207 | } |
1223 | |||
1224 | close(fd); | ||
1225 | settings_apply(); | ||
1226 | settings_save(); | ||
1227 | return true; | ||
1228 | } | 1208 | } |
1229 | 1209 | ||
1230 | 1210 | ||
1231 | bool settings_save_config(void) | 1211 | bool settings_save_config(void) |
1232 | { | 1212 | { |
1233 | bool done = false; | 1213 | bool done = false; |
1234 | int fd, i, value; | 1214 | int fd, i; |
1235 | char filename[MAX_PATH]; | 1215 | char filename[MAX_PATH]; |
1236 | char* boolopt[] = {"off","on"}; | 1216 | int restore[6]; /* recover, FIXME: get rid of this */ |
1237 | char* triopt[] = {"off","on","ask"}; | ||
1238 | 1217 | ||
1239 | /* find unused filename */ | 1218 | /* find unused filename */ |
1240 | for (i=0; ; i++) { | 1219 | for (i=0; ; i++) { |
@@ -1248,6 +1227,9 @@ bool settings_save_config(void) | |||
1248 | /* allow user to modify filename */ | 1227 | /* allow user to modify filename */ |
1249 | while (!done) { | 1228 | while (!done) { |
1250 | if (!kbd_input(filename, sizeof filename)) { | 1229 | if (!kbd_input(filename, sizeof filename)) { |
1230 | #ifdef WIN32 /* test hack !!! */ | ||
1231 | strcpy(filename, "C:/test.cfg"); | ||
1232 | #endif | ||
1251 | fd = creat(filename,0); | 1233 | fd = creat(filename,0); |
1252 | if (fd < 0) { | 1234 | if (fd < 0) { |
1253 | lcd_clear_display(); | 1235 | lcd_clear_display(); |
@@ -1289,293 +1271,37 @@ bool settings_save_config(void) | |||
1289 | global_settings.font_file); | 1271 | global_settings.font_file); |
1290 | #endif | 1272 | #endif |
1291 | 1273 | ||
1292 | fprintf(fd, "#\r\n# Sound settings\r\n#\r\n"); | 1274 | /* FIXME: While the mpeg_val2phys business still exists: ( to be removed) */ |
1293 | 1275 | /* temporarily replace the hardware levels with the MMI values */ | |
1294 | value = mpeg_val2phys(SOUND_VOLUME, global_settings.volume); | 1276 | restore[SOUND_VOLUME] = global_settings.volume; |
1295 | fprintf(fd, "volume: %d\r\n", value); | 1277 | global_settings.volume = mpeg_val2phys(SOUND_VOLUME, global_settings.volume); |
1296 | 1278 | restore[SOUND_BASS] = global_settings.bass; | |
1297 | value = mpeg_val2phys(SOUND_BASS, global_settings.bass); | 1279 | global_settings.bass = mpeg_val2phys(SOUND_BASS, global_settings.bass); |
1298 | fprintf(fd, "bass: %d\r\n", value); | 1280 | restore[SOUND_TREBLE] = global_settings.treble; |
1299 | 1281 | global_settings.treble = mpeg_val2phys(SOUND_TREBLE, global_settings.treble); | |
1300 | value = mpeg_val2phys(SOUND_TREBLE, global_settings.treble); | 1282 | restore[SOUND_BALANCE] = global_settings.balance; |
1301 | fprintf(fd, "treble: %d\r\n", value); | 1283 | global_settings.balance = mpeg_val2phys(SOUND_BALANCE, global_settings.balance); |
1302 | |||
1303 | value = mpeg_val2phys(SOUND_BALANCE, global_settings.balance); | ||
1304 | fprintf(fd, "balance: %d\r\n", value); | ||
1305 | |||
1306 | { | ||
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]); | ||
1312 | } | ||
1313 | |||
1314 | #ifdef HAVE_MAS3587F | 1284 | #ifdef HAVE_MAS3587F |
1315 | value = mpeg_val2phys(SOUND_LOUDNESS, global_settings.loudness); | 1285 | restore[SOUND_LOUDNESS] = global_settings.loudness; |
1316 | fprintf(fd, "loudness: %d\r\n", value); | 1286 | global_settings.loudness = mpeg_val2phys(SOUND_LOUDNESS, global_settings.loudness); |
1317 | 1287 | restore[SOUND_SUPERBASS] = global_settings.bass_boost; | |
1318 | value = mpeg_val2phys(SOUND_SUPERBASS, global_settings.bass_boost); | 1288 | global_settings.bass_boost = mpeg_val2phys(SOUND_SUPERBASS, global_settings.bass_boost); |
1319 | fprintf(fd, "bass boost: %d\r\n", value); | ||
1320 | |||
1321 | { | ||
1322 | static char* options[] = {"off", "2", "4", "8" }; | ||
1323 | fprintf(fd, "auto volume: %s\r\n", options[global_settings.avc]); | ||
1324 | } | ||
1325 | #endif | 1289 | #endif |
1326 | |||
1327 | fprintf(fd, "#\r\n# Playback\r\n#\r\n"); | ||
1328 | fprintf(fd, "shuffle: %s\r\n", boolopt[global_settings.playlist_shuffle]); | ||
1329 | |||
1330 | { | ||
1331 | static char* options[] = {"off", "all", "one"}; | ||
1332 | fprintf(fd, "repeat: %s\r\n", options[global_settings.repeat_mode]); | ||
1333 | } | ||
1334 | |||
1335 | fprintf(fd, "play selected: %s\r\n", | ||
1336 | boolopt[global_settings.play_selected]); | ||
1337 | |||
1338 | { | ||
1339 | static char* options[] = {"off", "ask", "ask once", "on"}; | ||
1340 | fprintf(fd, "resume: %s\r\n", options[global_settings.resume]); | ||
1341 | } | ||
1342 | |||
1343 | { | ||
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]); | ||
1349 | } | ||
1350 | |||
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]); | ||
1357 | |||
1358 | { | ||
1359 | static char* options[] = {"all", "supported","music", "playlists"}; | ||
1360 | fprintf(fd, "show files: %s\r\n", options[global_settings.dirfilter]); | ||
1361 | } | ||
1362 | |||
1363 | fprintf(fd, "follow playlist: %s\r\n", | ||
1364 | boolopt[global_settings.browse_current]); | ||
1365 | |||
1366 | fprintf(fd, "#\r\n# Display\r\n#\r\n"); | ||
1367 | |||
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]); | ||
1373 | |||
1374 | { | ||
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]); | ||
1379 | } | ||
1380 | #endif | ||
1381 | |||
1382 | fprintf(fd, "scroll speed: %d\r\nscroll delay: %d\r\n", | ||
1383 | global_settings.scroll_speed, | ||
1384 | global_settings.scroll_delay); | ||
1385 | |||
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 | ||
1392 | |||
1393 | fprintf(fd, "bidir limit: %d\r\n", global_settings.bidir_limit); | ||
1394 | |||
1395 | { | ||
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]); | ||
1401 | } | ||
1402 | |||
1403 | fprintf(fd, "backlight when plugged: %s\r\n", | ||
1404 | boolopt[global_settings.backlight_on_when_charging]); | ||
1405 | |||
1406 | fprintf(fd, "caption backlight: %s\r\n", | ||
1407 | boolopt[global_settings.caption_backlight]); | ||
1408 | fprintf(fd, "contrast: %d\r\n", global_settings.contrast); | ||
1409 | |||
1410 | #ifdef HAVE_LCD_BITMAP | ||
1411 | fprintf(fd, "invert: %s\r\n", boolopt[global_settings.invert]); | ||
1412 | |||
1413 | fprintf(fd, "flip display: %s\r\n", boolopt[global_settings.flip_display]); | ||
1414 | |||
1415 | fprintf(fd, "invert cursor: %s\r\n", | ||
1416 | boolopt[global_settings.invert_cursor]); | ||
1417 | |||
1418 | fprintf(fd, "show icons: %s\r\n", | ||
1419 | boolopt[global_settings.show_icons]); | ||
1420 | |||
1421 | fprintf(fd, "peak meter release: %d\r\n", | ||
1422 | global_settings.peak_meter_release); | ||
1423 | |||
1424 | { | ||
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]); | ||
1430 | } | ||
1431 | |||
1432 | { | ||
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]); | ||
1438 | } | ||
1439 | |||
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]); | ||
1443 | |||
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 | ||
1448 | |||
1449 | fprintf(fd, "#\r\n# System\r\n#\r\ndisk spindown: %d\r\n", | ||
1450 | global_settings.disk_spindown); | ||
1451 | |||
1452 | #ifdef HAVE_ATA_POWER_OFF | ||
1453 | fprintf(fd, "disk poweroff: %s\r\n", | ||
1454 | boolopt[global_settings.disk_poweroff]); | ||
1455 | #endif | ||
1456 | |||
1457 | fprintf(fd, "battery capacity: %d\r\n", global_settings.battery_capacity); | ||
1458 | |||
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 | ||
1464 | |||
1465 | #ifdef HAVE_LCD_BITMAP | ||
1466 | { | ||
1467 | static char* options[] = {"24hour", "12hour"}; | ||
1468 | fprintf(fd, "time format: %s\r\n", | ||
1469 | options[global_settings.timeformat]); | ||
1470 | } | ||
1471 | #endif | ||
1472 | |||
1473 | { | ||
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]); | ||
1479 | } | ||
1480 | |||
1481 | fprintf(fd, "car adapter mode: %s\r\n", | ||
1482 | boolopt[global_settings.car_adapter_mode]); | ||
1483 | |||
1484 | #ifdef HAVE_MAS3507D | ||
1485 | fprintf(fd, "line in: %s\r\n", boolopt[global_settings.line_in]); | ||
1486 | #endif | ||
1487 | |||
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); | ||
1491 | 1290 | ||
1291 | /* here's the action: write values to file, specified via table */ | ||
1292 | save_cfg_table(rtc_bits, sizeof(rtc_bits)/sizeof(rtc_bits[0]), fd); | ||
1293 | save_cfg_table(hd_bits, sizeof(hd_bits)/sizeof(hd_bits[0]), fd); | ||
1294 | |||
1295 | /* FIXME to be removed with mpeg_val2phys: restore the original values */ | ||
1296 | global_settings.volume = restore[SOUND_VOLUME]; | ||
1297 | global_settings.bass = restore[SOUND_BASS]; | ||
1298 | global_settings.treble = restore[SOUND_TREBLE]; | ||
1299 | global_settings.balance = restore[SOUND_BALANCE]; | ||
1492 | #ifdef HAVE_MAS3587F | 1300 | #ifdef HAVE_MAS3587F |
1493 | fprintf(fd, "#\r\n# Recording\r\n#\r\n"); | 1301 | global_settings.loudness = restore[SOUND_LOUDNESS]; |
1494 | fprintf(fd, "rec quality: %d\r\n", global_settings.rec_quality); | 1302 | global_settings.bass_boost = restore[SOUND_SUPERBASS]; |
1495 | |||
1496 | { | ||
1497 | static char* options[] = {"44", "48", "32", "22", "24", "16"}; | ||
1498 | fprintf(fd, "rec frequency: %s\r\n", | ||
1499 | options[global_settings.rec_frequency]); | ||
1500 | } | ||
1501 | |||
1502 | { | ||
1503 | static char* options[] = {"mic", "line", "spdif"}; | ||
1504 | fprintf(fd, "rec source: %s\r\n", options[global_settings.rec_source]); | ||
1505 | } | ||
1506 | |||
1507 | { | ||
1508 | static char* options[] = {"stereo", "mono"}; | ||
1509 | fprintf(fd, "rec channels: %s\r\n", | ||
1510 | options[global_settings.rec_channels]); | ||
1511 | } | ||
1512 | |||
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); | ||
1518 | |||
1519 | fprintf(fd, "editable recordings: %s\r\n", | ||
1520 | boolopt[global_settings.rec_editable]); | ||
1521 | |||
1522 | fprintf(fd, "prerecording time: %d\r\n", | ||
1523 | global_settings.rec_prerecord_time); | ||
1524 | |||
1525 | { | ||
1526 | static char* options[] = {rec_base_directory, "current"}; | ||
1527 | fprintf(fd, "rec directory: %s\r\n", | ||
1528 | options[global_settings.rec_directory]); | ||
1529 | } | ||
1530 | |||
1531 | #endif | 1303 | #endif |
1532 | 1304 | ||
1533 | fprintf(fd, "#\r\n# Bookmarking\r\n#\r\n"); | ||
1534 | { | ||
1535 | fprintf(fd, "autoload bookmarks: %s\r\n", | ||
1536 | triopt[global_settings.autoloadbookmark]); | ||
1537 | } | ||
1538 | |||
1539 | { | ||
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]); | ||
1543 | } | ||
1544 | |||
1545 | { | ||
1546 | static char* options[] = {"off", "on", "unique only"}; | ||
1547 | fprintf(fd, "use most-recent-bookmarks: %s\r\n", options[global_settings.usemrb]); | ||
1548 | } | ||
1549 | |||
1550 | fprintf(fd, "#\r\n# Playlists\r\n#\r\n"); | ||
1551 | { | ||
1552 | fprintf(fd, "recursive directory insert: %s\r\n", | ||
1553 | triopt[global_settings.recursive_dir_insert]); | ||
1554 | } | ||
1555 | |||
1556 | fprintf(fd, "#\r\n# Playlist viewer\r\n#\r\n"); | ||
1557 | { | ||
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]); | ||
1562 | { | ||
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]); | ||
1566 | } | ||
1567 | } | ||
1568 | fprintf(fd, "#\r\n# Voice\r\n#\r\n"); | ||
1569 | { | ||
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]); | ||
1577 | } | ||
1578 | |||
1579 | close(fd); | 1305 | close(fd); |
1580 | 1306 | ||
1581 | lcd_clear_display(); | 1307 | lcd_clear_display(); |
@@ -1586,6 +1312,37 @@ bool settings_save_config(void) | |||
1586 | return true; | 1312 | return true; |
1587 | } | 1313 | } |
1588 | 1314 | ||
1315 | |||
1316 | /* helper to load defaults from table into global_settings members */ | ||
1317 | static void default_table(const struct bit_entry* p_table, int count) | ||
1318 | { | ||
1319 | int i; | ||
1320 | |||
1321 | for (i=1; i<count; i++) /* exclude the first, the size placeholder */ | ||
1322 | { | ||
1323 | /* could do a memcpy, but that would be endian-dependent */ | ||
1324 | switch(p_table[i].byte_size) | ||
1325 | { | ||
1326 | case 1: | ||
1327 | ((unsigned char*)&global_settings)[p_table[i].settings_offset] = | ||
1328 | (unsigned char)p_table[i].default_val; | ||
1329 | break; | ||
1330 | case 2: | ||
1331 | ((unsigned short*)&global_settings)[p_table[i].settings_offset/2] = | ||
1332 | (unsigned short)p_table[i].default_val; | ||
1333 | break; | ||
1334 | case 4: | ||
1335 | ((unsigned int*)&global_settings)[p_table[i].settings_offset/4] = | ||
1336 | (unsigned int)p_table[i].default_val; | ||
1337 | break; | ||
1338 | default: | ||
1339 | DEBUGF( "illegal size!" ); | ||
1340 | continue; | ||
1341 | } | ||
1342 | } | ||
1343 | } | ||
1344 | |||
1345 | |||
1589 | /* | 1346 | /* |
1590 | * reset all settings to their default value | 1347 | * reset all settings to their default value |
1591 | */ | 1348 | */ |
@@ -1593,6 +1350,11 @@ void settings_reset(void) { | |||
1593 | 1350 | ||
1594 | DEBUGF( "settings_reset()\n" ); | 1351 | DEBUGF( "settings_reset()\n" ); |
1595 | 1352 | ||
1353 | /* read defaults from table(s) into global_settings */ | ||
1354 | default_table(rtc_bits, sizeof(rtc_bits)/sizeof(rtc_bits[0])); | ||
1355 | default_table(hd_bits, sizeof(hd_bits)/sizeof(hd_bits[0])); | ||
1356 | |||
1357 | /* do some special cases not covered by table */ | ||
1596 | global_settings.volume = mpeg_sound_default(SOUND_VOLUME); | 1358 | global_settings.volume = mpeg_sound_default(SOUND_VOLUME); |
1597 | global_settings.balance = mpeg_sound_default(SOUND_BALANCE); | 1359 | global_settings.balance = mpeg_sound_default(SOUND_BALANCE); |
1598 | global_settings.bass = mpeg_sound_default(SOUND_BASS); | 1360 | global_settings.bass = mpeg_sound_default(SOUND_BASS); |
@@ -1601,91 +1363,11 @@ void settings_reset(void) { | |||
1601 | global_settings.bass_boost = mpeg_sound_default(SOUND_SUPERBASS); | 1363 | global_settings.bass_boost = mpeg_sound_default(SOUND_SUPERBASS); |
1602 | global_settings.avc = mpeg_sound_default(SOUND_AVC); | 1364 | global_settings.avc = mpeg_sound_default(SOUND_AVC); |
1603 | global_settings.channel_config = mpeg_sound_default(SOUND_CHANNELS); | 1365 | 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(); | 1366 | global_settings.contrast = lcd_default_contrast(); |
1616 | global_settings.invert = DEFAULT_INVERT_SETTING; | 1367 | global_settings.wps_file[0] = '\0'; |
1617 | global_settings.flip_display= false; | 1368 | global_settings.font_file[0] = '\0'; |
1618 | global_settings.poweroff = DEFAULT_POWEROFF_SETTING; | 1369 | global_settings.lang_file[0] = '\0'; |
1619 | global_settings.backlight_timeout = DEFAULT_BACKLIGHT_TIMEOUT_SETTING; | 1370 | |
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; | ||
1689 | } | 1371 | } |
1690 | 1372 | ||
1691 | bool set_bool(char* string, bool* variable ) | 1373 | bool set_bool(char* string, bool* variable ) |