ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/prefs.cpp
Revision: 1.7
Committed: 2000-07-22T16:07:17Z (24 years, 4 months ago) by cebix
Branch: MAIN
Changes since 1.6: +1 -1 lines
Log Message:
- new FOURCC() macro in macos_util.h

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