ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/prefs.cpp
Revision: 1.1
Committed: 1999-10-03T14:16:25Z (25 years, 2 months ago) by cebix
Branch: MAIN
Branch point for: cebix
Log Message:
Initial revision

File Contents

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