ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SIDPlayer/src/prefs.cpp
Revision: 1.1
Committed: 2000-07-28T12:42:30Z (24 years, 3 months ago) by cebix
Branch: MAIN
Branch point for: cebix
Log Message:
Initial revision

File Contents

# Content
1 /*
2 * prefs.cpp - Preferences handling
3 *
4 * SIDPlayer (C) Copyright 1996-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 "sys.h"
22
23 #include <string.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <ctype.h>
27
28 #include "prefs.h"
29
30
31 // List of preferences items
32 prefs_desc prefs_items[] = {
33 {"victype", TYPE_STRING, false}, // Type number of VIC-II to emulate ("6569", "6567" or "6567R5")
34 {"sidtype", TYPE_STRING, false}, // Type number of SID to emulate ("6581" or "8580")
35 {"samplerate", TYPE_INT32, false}, // Audio sample rate in Hz
36 {"audio16bit", TYPE_BOOLEAN, false}, // 16-bit audio output?
37 {"stereo", TYPE_BOOLEAN, false}, // Stereo audio output?
38 {"filters", TYPE_BOOLEAN, false}, // Emulate SID filters?
39 {"dualsid", TYPE_BOOLEAN, false}, // Emulate 2 SID chips?
40 {"audioeffect", TYPE_INT32, false}, // Audio effect type (0 = none, 1 = reverb, 2 = spatial)
41 {"revdelay", TYPE_INT32, false}, // Reverb delay in ms
42 {"revfeedback", TYPE_INT32, false}, // Reverb feedback (0..0x100 = 0..100%)
43 {"volume", TYPE_INT32, false}, // Master volume (0..0x100 = 0..100%)
44 {"v1volume", TYPE_INT32, false}, // Volume voice 1 (0..0x100 = 0..100%)
45 {"v2volume", TYPE_INT32, false}, // Volume voice 2 (0..0x100 = 0..100%)
46 {"v3volume", TYPE_INT32, false}, // Volume voice 3 (0..0x100 = 0..100%)
47 {"v4volume", TYPE_INT32, false}, // Volume sampled voice (0..0x100 = 0..100%)
48 {"v1pan", TYPE_INT32, false}, // Panning voice 1 (-0x100..0x100 = left..right)
49 {"v2pan", TYPE_INT32, false}, // Panning voice 2 (-0x100..0x100 = left..right)
50 {"v3pan", TYPE_INT32, false}, // Panning voice 3 (-0x100..0x100 = left..right)
51 {"v4pan", TYPE_INT32, false}, // Panning sampled voice (-0x100..0x100 = left..right)
52 {"dualsep", TYPE_INT32, false}, // Dual-SID stereo separation (0..0x100 = 0..100%)
53 {"replayfreq", TYPE_INT32, false}, // Frequency at which 6510 replay routine is called in Hz
54 {NULL, TYPE_END, false} // End of list
55 };
56
57
58 // Prefs item are stored in a linked list of these nodes
59 struct prefs_node {
60 prefs_node *next;
61 const char *name;
62 prefs_type type;
63 void *data;
64 prefs_desc *desc;
65 };
66
67 // List of prefs nodes
68 static prefs_node *the_prefs;
69
70
71 /*
72 * Initialize preferences
73 */
74
75 void PrefsInit(int argc, char **argv)
76 {
77 // Start with empty list
78 the_prefs = NULL;
79
80 // Set defaults
81 PrefsAddString("victype", "6569");
82 PrefsAddString("sidtype", "6581");
83 PrefsAddInt32("samplerate", 44100);
84 PrefsAddBool("audio16bit", true);
85 PrefsAddBool("stereo", true);
86 PrefsAddBool("filters", true);
87 PrefsAddBool("dualsid", false);
88 PrefsAddInt32("audioeffect", 2);
89 PrefsAddInt32("revdelay", 125);
90 PrefsAddInt32("revfeedback", 0x50);
91 PrefsAddInt32("volume", 0x100);
92 PrefsAddInt32("v1volume", 0x100);
93 PrefsAddInt32("v1pan", -0x40);
94 PrefsAddInt32("v2volume", 0x100);
95 PrefsAddInt32("v2pan", 0);
96 PrefsAddInt32("v3volume", 0x100);
97 PrefsAddInt32("v3pan", 0x40);
98 PrefsAddInt32("v4volume", 0x100);
99 PrefsAddInt32("v4pan", 0);
100 PrefsAddInt32("dualsep", 0x80);
101 PrefsAddInt32("replayfreq", 50);
102 }
103
104
105 /*
106 * Deinitialize preferences
107 */
108
109 void PrefsExit(void)
110 {
111 // Free prefs list
112 prefs_node *p = the_prefs, *next;
113 while (p) {
114 next = p->next;
115 free((void *)p->name);
116 free(p->data);
117 delete p;
118 p = next;
119 }
120 }
121
122
123 /*
124 * Find preferences descriptor by keyword
125 */
126
127 static prefs_desc *find_prefs_desc(const char *name, prefs_desc *list)
128 {
129 while (list->type != TYPE_ANY) {
130 if (strcmp(list->name, name) == 0)
131 return list;
132 list++;
133 }
134 return NULL;
135 }
136
137
138 /*
139 * Set prefs items
140 */
141
142 static void add_data(const char *name, prefs_type type, void *data, int size)
143 {
144 void *d = malloc(size);
145 if (d == NULL)
146 return;
147 memcpy(d, data, size);
148 prefs_node *p = new prefs_node;
149 p->next = 0;
150 p->name = strdup(name);
151 p->type = type;
152 p->data = d;
153 p->desc = find_prefs_desc(p->name, prefs_items);
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 PrefsAddInt32(const char *name, int32 val)
174 {
175 add_data(name, TYPE_INT32, &val, sizeof(int32));
176 }
177
178
179 /*
180 * Replace prefs items
181 */
182
183 static prefs_node *find_node(const char *name, prefs_type type, int index = 0)
184 {
185 prefs_node *p = the_prefs;
186 int i = 0;
187 while (p) {
188 if ((type == TYPE_ANY || p->type == type) && !strcmp(p->name, name)) {
189 if (i == index)
190 return p;
191 else
192 i++;
193 }
194 p = p->next;
195 }
196 return NULL;
197 }
198
199 void PrefsReplaceString(const char *name, const char *s, int index)
200 {
201 prefs_node *p = find_node(name, TYPE_STRING, index);
202 if (p) {
203 if (p->desc && p->desc->func)
204 ((prefs_func_string)(p->desc->func))(name, (const char *)p->data, s);
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 if (p->desc && p->desc->func)
216 ((prefs_func_bool)(p->desc->func))(name, *(bool *)(p->data), b);
217 *(bool *)(p->data) = b;
218 } else
219 add_data(name, TYPE_BOOLEAN, &b, sizeof(bool));
220 }
221
222 void PrefsReplaceInt32(const char *name, int32 val)
223 {
224 prefs_node *p = find_node(name, TYPE_INT32);
225 if (p) {
226 if (p->desc && p->desc->func)
227 ((prefs_func_int32)(p->desc->func))(name, *(int32 *)(p->data), val);
228 *(int32 *)(p->data) = val;
229 } else
230 add_data(name, TYPE_INT32, &val, sizeof(int32));
231 }
232
233
234 /*
235 * Get prefs items
236 */
237
238 const char *PrefsFindString(const char *name, int index)
239 {
240 prefs_node *p = find_node(name, TYPE_STRING, index);
241 if (p)
242 return (char *)(p->data);
243 else
244 return NULL;
245 }
246
247 bool PrefsFindBool(const char *name)
248 {
249 prefs_node *p = find_node(name, TYPE_BOOLEAN, 0);
250 if (p)
251 return *(bool *)(p->data);
252 else
253 return false;
254 }
255
256 int32 PrefsFindInt32(const char *name)
257 {
258 prefs_node *p = find_node(name, TYPE_INT32, 0);
259 if (p)
260 return *(int32 *)(p->data);
261 else
262 return 0;
263 }
264
265
266 /*
267 * Remove prefs items
268 */
269
270 void PrefsRemoveItem(const char *name, int index)
271 {
272 prefs_node *p = find_node(name, TYPE_ANY, index);
273 if (p) {
274 free((void *)p->name);
275 free(p->data);
276 prefs_node *q = the_prefs;
277 if (q == p) {
278 the_prefs = NULL;
279 delete p;
280 return;
281 }
282 while (q) {
283 if (q->next == p) {
284 q->next = p->next;
285 delete p;
286 return;
287 }
288 q = q->next;
289 }
290 }
291 }
292
293
294 /*
295 * Set prefs change callback function
296 */
297
298 static void set_callback(const char *name, prefs_func f)
299 {
300 prefs_desc *d = find_prefs_desc(name, prefs_items);
301 if (d == NULL)
302 return;
303 d->func = f;
304 }
305
306 void PrefsSetCallback(const char *name, prefs_func_string f)
307 {
308 set_callback(name, (prefs_func)f);
309 }
310
311 void PrefsSetCallback(const char *name, prefs_func_bool f)
312 {
313 set_callback(name, (prefs_func)f);
314 }
315
316 void PrefsSetCallback(const char *name, prefs_func_int32 f)
317 {
318 set_callback(name, (prefs_func)f);
319 }