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 (23 years, 9 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     * 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     }