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

# User Rev Content
1 cebix 1.1 /*
2     * prefs.cpp - Preferences handling
3     *
4 cebix 1.4 * Basilisk II (C) 1997-2000 Christian Bauer
5 cebix 1.1 *
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 cebix 1.2 {"extfs", TYPE_STRING, false}, // Root path of ExtFS (extfs.cpp)
40 cebix 1.1 {"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 cebix 1.3 {"bootdrive", TYPE_INT16, false}, // Boot drive number (main.cpp)
53     {"bootdriver", TYPE_INT16, false}, // Boot driver number (main.cpp)
54 cebix 1.1 {"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 cebix 1.3 {"cpu", TYPE_INT32, false}, // CPU type (0 = 68000, 1 = 68010 etc.) (main.cpp)
58     {"fpu", TYPE_BOOLEAN, false}, // Enable FPU emulation (main.cpp)
59 cebix 1.1 {"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 cebix 1.3 PrefsAddInt32("cpu", 3); // 68030
95 cebix 1.1 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     }