ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/prefs.cpp
Revision: 1.1.1.1 (vendor branch)
Committed: 1999-10-03T14:16:25Z (25 years, 1 month ago) by cebix
Branch: cebix
CVS Tags: release-0_7-2, start
Changes since 1.1: +0 -0 lines
Log Message:
Imported sources

File Contents

# Content
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 }