ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/prefs.cpp
Revision: 1.5
Committed: 2000-04-14T19:03:48Z (24 years, 7 months ago) by cebix
Branch: MAIN
Changes since 1.4: +0 -2 lines
Log Message:
- empty values in prefs file are now possible

File Contents

# Content
1 /*
2 * prefs.cpp - Preferences handling
3 *
4 * Basilisk II (C) 1997-2000 Christian Bauer
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include <string.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <ctype.h>
25
26 #include "sysdeps.h"
27 #include "sys.h"
28 #include "prefs.h"
29
30
31 // Common preferences items (those which exist on all platforms)
32 // Except for "disk", "floppy", "cdrom", "scsiX", "screen", "rom" and "ether",
33 // these are guaranteed to be in the prefs; "disk", "floppy" and "cdrom" can
34 // occur multiple times
35 prefs_desc common_prefs_items[] = {
36 {"disk", TYPE_STRING, true}, // Device/file names of Mac volumes (disk.cpp)
37 {"floppy", TYPE_STRING, true}, // Device/file names of Mac floppy drives (sony.cpp)
38 {"cdrom", TYPE_STRING, true}, // Device/file names of Mac CD-ROM drives (cdrom.cpp)
39 {"extfs", TYPE_STRING, false}, // Root path of ExtFS (extfs.cpp)
40 {"scsi0", TYPE_STRING, false}, // SCSI targets for Mac SCSI ID 0..6 (scsi_*.cpp)
41 {"scsi1", TYPE_STRING, false},
42 {"scsi2", TYPE_STRING, false},
43 {"scsi3", TYPE_STRING, false},
44 {"scsi4", TYPE_STRING, false},
45 {"scsi5", TYPE_STRING, false},
46 {"scsi6", TYPE_STRING, false},
47 {"screen", TYPE_STRING, false}, // Video mode (video.cpp)
48 {"seriala", TYPE_STRING, false}, // Device name of Mac serial port A (serial_*.cpp)
49 {"serialb", TYPE_STRING, false}, // Device name of Mac serial port B (serial_*.cpp)
50 {"ether", TYPE_STRING, false}, // Device name of Mac ethernet adapter (ether_*.cpp)
51 {"rom", TYPE_STRING, false}, // Path of ROM file (main_*.cpp)
52 {"bootdrive", TYPE_INT16, false}, // Boot drive number (main.cpp)
53 {"bootdriver", TYPE_INT16, false}, // Boot driver number (main.cpp)
54 {"ramsize", TYPE_INT32, false}, // Size of Mac RAM in bytes (main_*.cpp)
55 {"frameskip", TYPE_INT32, false}, // Number of frames to skip in refreshed video modes (video_*.cpp)
56 {"modelid", TYPE_INT32, false}, // Mac Model ID (Gestalt Model ID minus 6) (rom_patches.cpp)
57 {"cpu", TYPE_INT32, false}, // CPU type (0 = 68000, 1 = 68010 etc.) (main.cpp)
58 {"fpu", TYPE_BOOLEAN, false}, // Enable FPU emulation (main.cpp)
59 {"nocdrom", TYPE_BOOLEAN, false}, // Don't install CD-ROM driver (cdrom.cpp/rom_patches.cpp)
60 {"nosound", TYPE_BOOLEAN, false}, // Don't enable sound output (audio_*.cpp)
61 {"nogui", TYPE_BOOLEAN, false}, // Disable GUI (main_*.cpp)
62 {NULL, TYPE_END, false} // End of list
63 };
64
65
66 // Prefs item are stored in a linked list of these nodes
67 struct prefs_node {
68 prefs_node *next;
69 const char *name;
70 prefs_type type;
71 void *data;
72 };
73
74 // List of prefs nodes
75 static prefs_node *the_prefs;
76
77
78 /*
79 * Initialize preferences
80 */
81
82 void PrefsInit(void)
83 {
84 // Start with empty list
85 the_prefs = NULL;
86
87 // Set defaults
88 SysAddSerialPrefs();
89 PrefsAddInt16("bootdriver", 0);
90 PrefsAddInt16("bootdrive", 0);
91 PrefsAddInt32("ramsize", 8 * 1024 * 1024);
92 PrefsAddInt32("frameskip", 6);
93 PrefsAddInt32("modelid", 5); // Mac IIci
94 PrefsAddInt32("cpu", 3); // 68030
95 PrefsAddBool("fpu", false);
96 PrefsAddBool("nocdrom", false);
97 PrefsAddBool("nosound", false);
98 PrefsAddBool("nogui", false);
99 AddPlatformPrefsDefaults();
100
101 // Load preferences from settings file
102 LoadPrefs();
103 }
104
105
106 /*
107 * Deinitialize preferences
108 */
109
110 void PrefsExit(void)
111 {
112 // Free prefs list
113 prefs_node *p = the_prefs, *next;
114 while (p) {
115 next = p->next;
116 free((void *)p->name);
117 free(p->data);
118 delete p;
119 p = next;
120 }
121 }
122
123
124 /*
125 * Find preferences descriptor by keyword
126 */
127
128 static const prefs_desc *find_prefs_desc(const char *name, const prefs_desc *list)
129 {
130 while (list->type != TYPE_ANY) {
131 if (strcmp(list->name, name) == 0)
132 return list;
133 list++;
134 }
135 return NULL;
136 }
137
138
139 /*
140 * Set prefs items
141 */
142
143 static void add_data(const char *name, prefs_type type, void *data, int size)
144 {
145 void *d = malloc(size);
146 if (d == NULL)
147 return;
148 memcpy(d, data, size);
149 prefs_node *p = new prefs_node;
150 p->next = 0;
151 p->name = strdup(name);
152 p->type = type;
153 p->data = d;
154 if (the_prefs) {
155 prefs_node *prev = the_prefs;
156 while (prev->next)
157 prev = prev->next;
158 prev->next = p;
159 } else
160 the_prefs = p;
161 }
162
163 void PrefsAddString(const char *name, const char *s)
164 {
165 add_data(name, TYPE_STRING, (void *)s, strlen(s) + 1);
166 }
167
168 void PrefsAddBool(const char *name, bool b)
169 {
170 add_data(name, TYPE_BOOLEAN, &b, sizeof(bool));
171 }
172
173 void PrefsAddInt16(const char *name, int16 val)
174 {
175 add_data(name, TYPE_INT16, &val, sizeof(int16));
176 }
177
178 void PrefsAddInt32(const char *name, int32 val)
179 {
180 add_data(name, TYPE_INT32, &val, sizeof(int32));
181 }
182
183
184 /*
185 * Replace prefs items
186 */
187
188 static prefs_node *find_node(const char *name, prefs_type type, int index = 0)
189 {
190 prefs_node *p = the_prefs;
191 int i = 0;
192 while (p) {
193 if ((type == TYPE_ANY || p->type == type) && !strcmp(p->name, name)) {
194 if (i == index)
195 return p;
196 else
197 i++;
198 }
199 p = p->next;
200 }
201 return NULL;
202 }
203
204 void PrefsReplaceString(const char *name, const char *s, int index)
205 {
206 prefs_node *p = find_node(name, TYPE_STRING, index);
207 if (p) {
208 free(p->data);
209 p->data = strdup(s);
210 } else
211 add_data(name, TYPE_STRING, (void *)s, strlen(s) + 1);
212 }
213
214 void PrefsReplaceBool(const char *name, bool b)
215 {
216 prefs_node *p = find_node(name, TYPE_BOOLEAN);
217 if (p)
218 *(bool *)(p->data) = b;
219 else
220 add_data(name, TYPE_BOOLEAN, &b, sizeof(bool));
221 }
222
223 void PrefsReplaceInt16(const char *name, int16 val)
224 {
225 prefs_node *p = find_node(name, TYPE_INT16);
226 if (p)
227 *(int16 *)(p->data) = val;
228 else
229 add_data(name, TYPE_INT16, &val, sizeof(int16));
230 }
231
232 void PrefsReplaceInt32(const char *name, int32 val)
233 {
234 prefs_node *p = find_node(name, TYPE_INT32);
235 if (p)
236 *(int32 *)(p->data) = val;
237 else
238 add_data(name, TYPE_INT32, &val, sizeof(int32));
239 }
240
241
242 /*
243 * Get prefs items
244 */
245
246 const char *PrefsFindString(const char *name, int index)
247 {
248 prefs_node *p = find_node(name, TYPE_STRING, index);
249 if (p)
250 return (char *)(p->data);
251 else
252 return NULL;
253 }
254
255 bool PrefsFindBool(const char *name)
256 {
257 prefs_node *p = find_node(name, TYPE_BOOLEAN, 0);
258 if (p)
259 return *(bool *)(p->data);
260 else
261 return false;
262 }
263
264 int16 PrefsFindInt16(const char *name)
265 {
266 prefs_node *p = find_node(name, TYPE_INT16, 0);
267 if (p)
268 return *(int16 *)(p->data);
269 else
270 return 0;
271 }
272
273 int32 PrefsFindInt32(const char *name)
274 {
275 prefs_node *p = find_node(name, TYPE_INT32, 0);
276 if (p)
277 return *(int32 *)(p->data);
278 else
279 return 0;
280 }
281
282
283 /*
284 * Remove prefs items
285 */
286
287 void PrefsRemoveItem(const char *name, int index)
288 {
289 prefs_node *p = find_node(name, TYPE_ANY, index);
290 if (p) {
291 free((void *)p->name);
292 free(p->data);
293 prefs_node *q = the_prefs;
294 if (q == p) {
295 the_prefs = NULL;
296 delete p;
297 return;
298 }
299 while (q) {
300 if (q->next == p) {
301 q->next = p->next;
302 delete p;
303 return;
304 }
305 q = q->next;
306 }
307 }
308 }
309
310
311 /*
312 * Load prefs from stream (utility function for LoadPrefs() implementation)
313 */
314
315 void LoadPrefsFromStream(FILE *f)
316 {
317 char line[256];
318 while(fgets(line, 255, f)) {
319 // Read line
320 int len = strlen(line);
321 if (len == 0)
322 continue;
323 line[len-1] = 0;
324
325 // Comments begin with "#" or ";"
326 if (line[0] == '#' || line[0] == ';')
327 continue;
328
329 // Terminate string after keyword
330 char *p = line;
331 while (!isspace(*p)) p++;
332 *p++ = 0;
333
334 // Skip whitespace until value
335 while (isspace(*p)) p++;
336 char *keyword = line;
337 char *value = p;
338 int32 i = atol(value);
339
340 // Look for keyword first in common item list, then in platform specific list
341 const prefs_desc *desc = find_prefs_desc(keyword, common_prefs_items);
342 if (desc == NULL)
343 desc = find_prefs_desc(keyword, platform_prefs_items);
344 if (desc == NULL) {
345 printf("WARNING: Unknown preferences keyword '%s'\n", keyword);
346 continue;
347 }
348
349 // Add item to prefs
350 switch (desc->type) {
351 case TYPE_STRING:
352 if (desc->multiple)
353 PrefsAddString(keyword, value);
354 else
355 PrefsReplaceString(keyword, value);
356 break;
357 case TYPE_BOOLEAN:
358 PrefsReplaceBool(keyword, !strcmp(value, "true"));
359 break;
360 case TYPE_INT16:
361 PrefsReplaceInt16(keyword, i);
362 break;
363 case TYPE_INT32:
364 PrefsReplaceInt32(keyword, i);
365 break;
366 default:
367 break;
368 }
369 }
370 }
371
372
373 /*
374 * Save settings to stream (utility function for SavePrefs() implementation)
375 */
376
377 static void write_prefs(FILE *f, const prefs_desc *list)
378 {
379 while (list->type != TYPE_ANY) {
380 switch (list->type) {
381 case TYPE_STRING: {
382 int index = 0;
383 const char *str;
384 while ((str = PrefsFindString(list->name, index++)) != NULL)
385 fprintf(f, "%s %s\n", list->name, str);
386 break;
387 }
388 case TYPE_BOOLEAN:
389 fprintf(f, "%s %s\n", list->name, PrefsFindBool(list->name) ? "true" : "false");
390 break;
391 case TYPE_INT16:
392 fprintf(f, "%s %d\n", list->name, PrefsFindInt16(list->name));
393 break;
394 case TYPE_INT32:
395 fprintf(f, "%s %ld\n", list->name, PrefsFindInt32(list->name));
396 break;
397 default:
398 break;
399 }
400 list++;
401 }
402 }
403
404 void SavePrefsToStream(FILE *f)
405 {
406 write_prefs(f, common_prefs_items);
407 write_prefs(f, platform_prefs_items);
408 }