1 /* $Id: options.c,v 1.4 2006/09/15 13:34:06 toad32767 Exp $ */
2 /**
3 ** 2005, 2006 by Marco Trillo
4 ** This file is part of UModPlayer, and is released by
5 ** its autors to the Public Domain.
6 ** In case it's not legally possible, its autors grant
7 ** anyone the right to use, redistribute and modify
8 ** this software for any purpose, without any conditions,
9 ** unless such conditions are required by law.
10 **
11 ** THIS FILE COMES WITHOUT ANY WARRANTY. THE AUTHORS
12 ** SHALL NOT BE LIABLE FOR ANY DAMAGE RESULTING BY THE
13 ** USE OR MISUSE OF THIS SOFTWARE.
14 **/
15
16 /*
17 * =====================
18 * OPTIONS-RELATED STUFF
19 * =====================
20 */
21
22 #include <umodplayer.h>
23 #include <text.h>
24 #include <messages.h>
25 #include <file_read.h>
26
27 /*
28 * Try to detect the local endianness
29 */
30 LOCAL Endian
DetectEndian()31 DetectEndian()
32 {
33 union cio {
34 uint16_t w;
35 uint8_t b[2];
36 } d;
37
38 d.w = 0xCAFE;
39
40 if (d.b[0] == 0xCA && d.b[1] == 0xFE) {
41 return BIG_ENDIAN;
42 } else if (d.b[0] == 0xFE && d.b[1] == 0xCA) {
43 return LTE_ENDIAN;
44 } else {
45 fputs(">>> WARNING: CAN'T detect local endianness!\n", stderr);
46 fputs(">>> Please set it manually with the `setadvanced' command\n", stderr);
47 return UNKNOWN_ENDIAN;
48 }
49
50 /* NOTREACHED */
51 return UNKNOWN_ENDIAN;
52 }
53
54 EXPORT void
DefaultOptions(struct oFlags * ops)55 DefaultOptions(struct oFlags * ops)
56 {
57 ops->samplerate = DEFAULT_SAMPLERATE;
58 ops->flags = MODPLUG_ENABLE_OVERSAMPLING;
59 ops->resampling = MODPLUG_RESAMPLE_SPLINE;
60 ops->vol = 128;
61 ops->channels = 2;
62 ops->reverbDepth = 20;
63 ops->reverbDelay = 60;
64 ops->bassAmount = 40;
65 ops->bassRange = 50;
66 ops->surroundDepth = 50;
67 ops->surroundDelay = 20;
68 ops->appareance = TABLE_THEME_CLASSIC;
69 ops->endianness = DetectEndian();
70 ops->verbosity = 1;
71 return;
72 }
73
74 EXPORT void
InitOptions(struct oFlags * ops)75 InitOptions(struct oFlags * ops)
76 {
77 char *path, *home;
78 int fd, bytes_in, dodefaults = 1;
79
80 home = getenv("HOME");
81 if (home != NULL) {
82 path = (char *) malloc(strlen(home) + strlen(PREFS_FILE) + 2);
83 if (path == NULL) {
84 error("%s", MESSAGE_NO_MEMORY);
85 UFreeFile();
86 exit(UM_ERR_MEMORY);
87 }
88 strcpy(path, home);
89 strcat(path, "/");
90 strcat(path, PREFS_FILE);
91
92 fd = open(path, O_RDONLY);
93 if (fd != -1) {
94 bytes_in = read(fd, ops, sizeof(struct oFlags));
95 if (bytes_in == sizeof(struct oFlags))
96 dodefaults = 0;
97 close(fd);
98 }
99 free(path);
100 }
101 if (dodefaults == 1) {
102 DefaultOptions(ops);
103 }
104 return;
105 }
106
107 EXPORT void
SaveOptions(struct oFlags * ops)108 SaveOptions(struct oFlags * ops)
109 {
110 char *path, *home;
111 int fd;
112
113 home = getenv("HOME");
114 if (home != NULL) {
115 path = (char *) malloc(strlen(home) + strlen(PREFS_FILE) + 2);
116 if (path == NULL) {
117 error("%s", MESSAGE_NO_MEMORY);
118 UFreeFile();
119 exit(UM_ERR_MEMORY);
120 }
121 strcpy(path, home);
122 strcat(path, "/");
123 strcat(path, PREFS_FILE);
124
125 fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, 0600);
126 if (fd != -1) {
127 (void) write(fd, ops, sizeof(struct oFlags));
128 close(fd);
129 }
130 free(path);
131 }
132 return;
133 }
134
135 EXPORT void
AdvancedConfig()136 AdvancedConfig()
137 {
138 static char vbuf[4];
139 WTable table;
140 int i;
141
142 rr = (char **) malloc(9 * sizeof(char *));
143 rr[0] = (char *) malloc(8);
144 sprintf(rr[0], "%d", sets.reverbDepth);
145 rr[1] = (char *) malloc(8);
146 sprintf(rr[1], "%d ms", sets.reverbDelay);
147 rr[2] = (char *) malloc(8);
148 sprintf(rr[2], "%d", sets.bassAmount);
149 rr[3] = (char *) malloc(8);
150 sprintf(rr[3], "%d Hz", sets.bassRange);
151 rr[4] = (char *) malloc(8);
152 sprintf(rr[4], "%d", sets.surroundDepth);
153 rr[5] = (char *) malloc(16);
154 sprintf(rr[5], "%d ms", sets.surroundDelay);
155
156 if (sets.endianness == BIG_ENDIAN) {
157 rr[6] = "big-endian";
158 } else if (sets.endianness == LTE_ENDIAN) {
159 rr[6] = "little-endian";
160 } else {
161 rr[6] = "unknown!";
162 }
163
164 if (sets.appareance == TABLE_THEME_CLASSIC) {
165 rr[7] = "classic";
166 } else if (sets.appareance == TABLE_THEME_STRONG) {
167 rr[7] = "strong";
168 } else {
169 rr[7] = "boxed";
170 }
171
172 snprintf(vbuf, 4, "%d", sets.verbosity);
173 rr[8] = vbuf;
174
175 TableSetOptions(&table, 2, 9, 2, 16, 0, TABLE_LEFT_ALIGN);
176 TableInitCallback(&table, MyTextCallback);
177 TableUseTheme(&table, sets.appareance);
178 DrawTable(table);
179
180 for (i = 0; i < 6; ++i)
181 free(rr[i]);
182 free(rr);
183
184 return;
185 }
186
187 LOCAL void
AskUserForData(const char * str,int minvalue,int maxvalue,int * putdata)188 AskUserForData(const char *str, int minvalue, int maxvalue, int *putdata)
189 {
190 char *e;
191 int k;
192
193 for (;;) {
194 fputs(str, stdout);
195 fflush(stdout);
196 e = ReadString();
197 if (e == NULL) {
198 error("%s", MESSAGE_NO_MEMORY);
199 return;
200 }
201 TrimString(e);
202 if (*e == 0)
203 return;
204 k = atoi(e);
205 free(e);
206 if (k < minvalue || k > maxvalue) {
207 continue;
208 }
209 *putdata = k;
210 break;
211 }
212
213 return;
214 }
215
216 EXPORT void
SetAdvancedConfig()217 SetAdvancedConfig()
218 {
219 char *response;
220
221 AskUserForData("Reverb Depth [0-100]? ", 0, 100, &(sets.reverbDepth));
222 AskUserForData("Reverb Delay in ms. [40-200]? ", 40, 200, &(sets.reverbDelay));
223 AskUserForData("Bass Amount [0-100]? ", 0, 100, &(sets.bassAmount));
224 AskUserForData("Bass Range in Hz. [10-100]? ", 10, 100, &(sets.bassRange));
225 AskUserForData("Surround Depth [0-100]? ", 0, 100, &(sets.surroundDepth));
226 AskUserForData("Surround Delay in ms. [5-40]? ", 5, 40, &(sets.surroundDelay));
227
228 endian1:
229 fputs("local endianness [little-endian, big-endian]? ", stdout);
230 fflush(stdout);
231 response = ReadString();
232 if (response == NULL) {
233 error("%s", MESSAGE_NO_MEMORY);
234 } else if (*response == '\0') {
235 /*
236 * skip to the next question
237 */
238 free(response);
239 goto appareance1;
240 } else {
241 /*
242 * Use memcmp() instead of strcmp()
243 * to match only the beginning of the string.
244 *
245 * I.e., any string starting with "little" will match
246 * little-endian, no matter if its "little-endian", "littleendian",
247 * "little", or whatever.
248 */
249 if (memcmp(response, "little", 6) == 0) {
250 sets.endianness = LTE_ENDIAN;
251 } else if (memcmp(response, "big", 3) == 0) {
252 sets.endianness = BIG_ENDIAN;
253 } else {
254 free(response);
255 goto endian1; /* ask again until a valid response is found! */
256 }
257
258 free(response);
259 }
260
261 appareance1:
262 fputs("appareance [classic, strong, boxed]? ", stdout);
263 fflush(stdout);
264 response = ReadString();
265 if (response == NULL) {
266 error("%s", MESSAGE_NO_MEMORY);
267 } else if (*response == '\0') {
268 /*
269 * skip to the next question
270 */
271 free(response);
272 goto end;
273 } else {
274 if (strcmp(response, "classic") == 0) {
275 sets.appareance = TABLE_THEME_CLASSIC;
276 } else if (strcmp(response, "strong") == 0) {
277 sets.appareance = TABLE_THEME_STRONG;
278 } else if (strcmp(response, "boxed") == 0) {
279 sets.appareance = TABLE_THEME_BOXED;
280 } else {
281 free(response);
282 goto appareance1;
283 }
284
285 free(response);
286 }
287
288 end:
289
290 AskUserForData("verbosity level? ", 0, 3, &(sets.verbosity));
291 }
292