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 (23 years, 9 months ago) by cebix
Branch: MAIN
Changes since 1.6: +1 -1 lines
Log Message:
- new FOURCC() macro in macos_util.h

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 {"noclipconversion", TYPE_BOOLEAN, false}, // Don't convert clipboard contents (clip_*.cpp)
62 {"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 PrefsAddInt32("cpu", 3); // 68030
96 PrefsAddBool("fpu", false);
97 PrefsAddBool("nocdrom", false);
98 PrefsAddBool("nosound", false);
99 PrefsAddBool("noclipconversion", false);
100 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 fprintf(f, "%s %d\n", list->name, PrefsFindInt32(list->name));
398 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 }