1 /* $Id: ipret.c,v 1.10 2006/09/16 10:17:33 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 #include <umodplayer.h>
17 #include <text.h>
18 #include <messages.h>
19 #include <coresound.h>
20 #include <file_read.h>
21 #include <options.h>
22 #include <file_parse.h>
23 #include <notes.h>
24 
25 /*
26  * User commands
27  */
28 void
CommandOpen(char * filenam)29 CommandOpen(char *filenam)
30 {
31 	if (filenam == NULL || *filenam == '\0') {
32 		fputs("usage: open <file>\n", stderr);
33 		return;
34 	}
35 	/* free the current file */
36 	UFreeFile();
37 	file.name = strcopyof(filenam);
38 	if (file.name == NULL) {
39 		error("%s", MESSAGE_NO_MEMORY);
40 		return;
41 	}
42 	file.malloc = TRUE;
43 	ULoadFile();
44 }
45 
46 void
CommandConfig(char * unused)47 CommandConfig(char *unused)
48 {
49 	WTable table;
50 
51 	rr = (char **) malloc(8 * sizeof(char *));
52 
53 	rr[0] = "Sampling Rate:";
54 	rr[1] = "Resampling Mode:";
55 	rr[2] = "Noise Reduction:";
56 	rr[3] = "Reverb:";
57 	rr[4] = "Megabass:";
58 	rr[5] = "Surround:";
59 	rr[6] = "Channels:";
60 	rr[7] = "Master Volume:";
61 
62 	TableSetOptions(&table, 0, 8, 2, CalcLen(rr, 8) + 1, 0, TABLE_LEFT_ALIGN);
63 	TableUseTheme(&table, sets.appareance);
64 	TableInitCallback(&table, MyTextCallback);
65 	DrawTable(table);
66 	free(rr);
67 }
68 
69 void
CommandHelp(char * unused)70 CommandHelp(char *unused)
71 {
72 	puts("Commands available on interactive mode:");
73 	puts("	quit		config		play");
74 	puts("	position	noise		reverb");
75 	puts("	megabass	surround	reset");
76 	puts("	loadconfig	saveconfig	info");
77 	puts("	list / ls	message		samples");
78 	puts("	instruments	export		advanced");
79 	puts("	setadvanced	playlist	volume");
80 	puts("	display <X>-<Y>	goto <ORDER>	samplerate <F>");
81 	puts("	open <FILE>	volume <V>	savemessage <FILE>");
82 	puts("	resampling <M>	channels (1|2) 	cd <DIRECTORY>");
83 	puts("	exec <command>	version");
84 	puts("");
85 	puts("Hint: The '!' command prints the last executed command,");
86 	puts("      and the '!!' command (without quotes) runs it.");
87 }
88 
89 void
CommandVolume(char * volstr)90 CommandVolume(char *volstr)
91 {
92 	if (volstr == NULL || *volstr == '\0') {
93 		printf("volume: %u\n", sets.vol);
94 	} else {
95 		sets.vol = (unsigned int) strtoul(volstr, NULL, 10);
96 		if (sets.vol > 768) /* XXX - what's the ModPlug limit ? */
97 			sets.vol = 768;
98 		else if (sets.vol < 1)
99 			sets.vol = 1;
100 	}
101 }
102 
103 void
CommandDisplay(char * range)104 CommandDisplay(char *range)
105 {
106 	if (range == NULL || *range == '\0') {
107 		NoteDisplay_Start(-1, -1);
108 	} else {
109 		int x, y;
110 
111 		GetRangeValues(range, &x, &y);
112 		NoteDisplay_Start(x, y);
113 	}
114 }
115 
116 void
CommandSampleRate(char * rate)117 CommandSampleRate(char *rate)
118 {
119 	int r;
120 
121 	if (rate == NULL || *rate == '\0')
122 		fputs("usage: samplerate <rate>\n", stderr);
123 	else {
124 		r = (int) strtoul(rate, NULL, 10);
125 
126 		switch (r) {
127 		case 11025:
128 		case 16000:
129 		case 22050:
130 		case 24000:
131 		case 32000:
132 		case 44100:
133 			sets.samplerate = r;
134 
135 			/* XXX -- hack for ModPlug 0.7/0.8 configuration oddness (bug or feature?) */
136 			if (file.name != NULL) {
137 				CoreSound_InitOptions();
138 			}
139 
140 			break;
141 		default:
142 			warning("invalid sampling rate -- %d. not changing.\n", r);
143 		}
144 	}
145 }
146 
147 void
CommandReSampling(char * mode)148 CommandReSampling(char *mode)
149 {
150 	if (mode == NULL) {
151 usage:
152 		fputs("usage: resampling (NO_INTERPOLATE|LINEAR|SPLINE|FIR_FILTER)\n", stderr);
153 		return;
154 	}
155 	if (strcasecmp(mode, "NO_INTERPOLATE") == 0 ||
156 	    strcmp(mode, "RESAMPLE") == 0)	/* deprecated, compat. only */
157 		sets.resampling = 0;
158 	else if (strcasecmp(mode, "LINEAR") == 0)
159 		sets.resampling = 1;
160 	else if (strcasecmp(mode, "SPLINE") == 0)
161 		sets.resampling = 2;
162 	else if (strcasecmp(mode, "FIR_FILTER") == 0)
163 		sets.resampling = 3;
164 	else
165 		goto usage;
166 }
167 
168 void
CommandChannels(char * ch)169 CommandChannels(char *ch)
170 {
171 	if (ch == NULL || *ch == '\0') {
172 		fputs("usage: channels (1|2)\n", stderr);
173 	} else {
174 		if (*ch == '1')
175 			sets.channels = 1;
176 		else
177 			sets.channels = 2;
178 	}
179 }
180 
181 void
CommandGoTo(char * to)182 CommandGoTo(char *to)
183 {
184 	if (to == NULL || *to == '\0') {
185 usage:
186 		fputs("usage: goto <order>\n", stderr);
187 	} else {
188 		int pos;
189 
190 		pos = atoi(to);
191 		if (pos > -1) {
192 			ModPlug_SeekOrder(file.mod, pos);
193 		} else {
194 			goto usage;
195 		}
196 	}
197 }
198 
199 void
CommandChDir(char * dir)200 CommandChDir(char *dir)
201 {
202 	if (dir == NULL || *dir == '\0') {
203 		char *home = getenv("HOME");
204 		if (home != NULL) {
205 			chdir(home);
206 		}
207 	} else {
208 		chdir(dir);
209 	}
210 }
211 
212 
213 void
CommandQuit(char * unused)214 CommandQuit(char *unused)
215 {
216 	exit(UM_OK);
217 }
218 void
CommandInfo(char * unused)219 CommandInfo(char *unused)
220 {
221 	DrawInfoTable();
222 }
223 void
CommandPlay(char * unused)224 CommandPlay(char *unused)
225 {
226 	(void) CoreSound_StartMonitor();
227 }
228 void
CommandPosition(char * unused)229 CommandPosition(char *unused)
230 {
231 	DisplayCurPos();
232 }
233 void
CommandNoise(char * unused)234 CommandNoise(char *unused)
235 {
236 	sets.flags ^= MODPLUG_ENABLE_NOISE_REDUCTION;
237 }
238 void
CommandReverb(char * unused)239 CommandReverb(char *unused)
240 {
241 	sets.flags ^= MODPLUG_ENABLE_REVERB;
242 }
243 void
CommandMegabass(char * unused)244 CommandMegabass(char *unused)
245 {
246 	sets.flags ^= MODPLUG_ENABLE_MEGABASS;
247 }
248 void
CommandSurround(char * unused)249 CommandSurround(char *unused)
250 {
251 	sets.flags ^= MODPLUG_ENABLE_SURROUND;
252 }
253 void
CommandReset(char * unused)254 CommandReset(char *unused)
255 {
256 	DefaultOptions(&sets);
257 }
258 void
CommandLoadConfig(char * unused)259 CommandLoadConfig(char *unused)
260 {
261 	InitOptions(&sets);
262 }
263 void
CommandSaveConfig(char * unused)264 CommandSaveConfig(char *unused)
265 {
266 	SaveOptions(&sets);
267 }
268 void
CommandList(char * unused)269 CommandList(char *unused)
270 {
271 	SongList();
272 }
273 void
CommandMessage(char * unused)274 CommandMessage(char *unused)
275 {
276 	DisplaySongComments();
277 }
278 void
CommandInstruments(char * unused)279 CommandInstruments(char *unused)
280 {
281 	DisplayInstruments(0);
282 }
283 void
CommandSamples(char * unused)284 CommandSamples(char *unused)
285 {
286 	DisplaySamples(0);
287 }
288 void
CommandExport(char * unused)289 CommandExport(char *unused)
290 {
291 	ExportSong();
292 }
293 void
CommandAdvanced(char * unused)294 CommandAdvanced(char *unused)
295 {
296 	AdvancedConfig();
297 }
298 void
CommandSetAdvanced(char * unused)299 CommandSetAdvanced(char *unused)
300 {
301 	AdvancedConfig();
302 	SetAdvancedConfig();
303 }
304 void
CommandPlayList(char * unused)305 CommandPlayList(char *unused)
306 {
307 	PlayList();
308 }
309 
310 void
CommandExec(char * command)311 CommandExec(char *command)
312 {
313 	if (command == NULL || *command == '\0')
314 		fputs("usage: exec <system command>\n", stderr);
315 	else
316 		system(command);
317 }
318 
319 void
CommandVersion(char * unused)320 CommandVersion(char *unused)
321 {
322 	PrintBanner();
323 }
324 
325 
326 /*
327  * Command interpreter
328  */
329 struct command {
330 	char *name;
331 	int moduleNeeded;
332 	void (*action) (char *);
333 };
334 
335 LOCAL struct command commands[] = {
336 	{"open", 0, CommandOpen},
337 	{"load", 0, CommandOpen},
338 	{"config", 0, CommandConfig},
339 	{"help", 0, CommandHelp},
340 	{"?", 0, CommandHelp},
341 	{"volume", 0, CommandVolume},
342 	{"display", 1, CommandDisplay},
343 	{"samplerate", 0, CommandSampleRate},
344 	{"resampling", 0, CommandReSampling},
345 	{"channels", 0, CommandChannels},
346 	{"goto", 1, CommandGoTo},
347 	{"chdir", 0, CommandChDir},
348 	{"cd", 0, CommandChDir},
349 	{"quit", 0, CommandQuit},
350 	{"exit", 0, CommandQuit},
351 	{"info", 1, CommandInfo},
352 	{"play", 1, CommandPlay},
353 	{"position", 1, CommandPosition},
354 	{"noise", 0, CommandNoise},
355 	{"reverb", 0, CommandReverb},
356 	{"megabass", 0, CommandMegabass},
357 	{"surround", 0, CommandSurround},
358 	{"reset", 0, CommandReset},
359 	{"loadconfig", 0, CommandLoadConfig},
360 	{"saveconfig", 0, CommandSaveConfig},
361 	{"list", 0, CommandList},
362 	{"ls", 0, CommandList},
363 	{"message", 1, CommandMessage},
364 	{"instruments", 1, CommandInstruments},
365 	{"samples", 1, CommandSamples},
366 	{"export", 1, CommandExport},
367 	{"advanced", 0, CommandAdvanced},
368 	{"setadvanced", 0, CommandSetAdvanced},
369 	{"playlist", 0, CommandPlayList},
370 	{"exec", 0, CommandExec},
371 	{"version", 0, CommandVersion},
372 	{NULL, 0, NULL}
373 
374 };
375 
376 struct cline {
377 	char *command;
378 	char *params;
379 };
380 
381 LOCAL struct cline *
ParseCommandLine(char * com)382 ParseCommandLine(char *com)
383 {
384 	char *t;
385 	static struct cline cl;
386 
387 	TrimString(com);
388 	t = com;
389 
390 	while (*t != '\0' && *t != ' ' && *t != '\t' && *t != '#') {
391 		++t;
392 	}
393 
394 	if (*t == '#') {	/* skip comments */
395 		*t = '\0';
396 		cl.command = com;
397 		cl.params = NULL;
398 	} else if (t > com && (*t == ' ' || *t == '\t')) {
399 		*t = '\0';
400 
401 		do
402 			++t;
403 		while (*t == ' ' || *t == '\t');
404 
405 		cl.command = com;
406 		cl.params = t;
407 	} else {
408 		cl.command = com;
409 		cl.params = NULL;
410 	}
411 
412 	return &cl;
413 }
414 
415 LOCAL void
RunCommand(char * line)416 RunCommand(char *line)
417 {
418 	struct cline *l;
419 	struct command *c;
420 
421 	l = ParseCommandLine(line);
422 
423 	/* null command */
424 	if (l->command[0] == '\0')
425 		return;
426 
427 	for (c = commands; c->name != NULL; ++c) {
428 		if (strcmp(c->name, l->command) == 0) {
429 			if (c->moduleNeeded && file.name == NULL) {
430 				warning("%s: no module loaded\n", l->command);
431 			} else {
432 				c->action(l->params);
433 			}
434 			return;
435 		}
436 	}
437 
438 	warning("%s: invalid command\nTry: `help'\n", l->command);
439 }
440 
441 
442 EXPORT void
CommandInterpreter()443 CommandInterpreter()
444 {
445 	char *str, *last = NULL, pathbuf[1024];
446 
447 	for (;;) {
448 		getcwd(pathbuf, 1024);
449 		printf("umodplayer[%s]%% ", pathbuf);
450 		fflush(stdout);
451 
452 		str = ReadString();
453 		if (str == NULL) {
454 			fputs(MESSAGE_NO_MEMORY, stderr);
455 			continue;
456 		}
457 		if (str[0] == '!') {
458 			if (last != NULL) {
459 				if (str[1] == '!') {
460 					RunCommand(last);
461 				} else {
462 					puts(last);
463 				}
464 			}
465 			free(str);
466 		} else {
467 			if (last != NULL)
468 				free(last);
469 			last = strcopyof(str); /* RunCommand() modifies 'str' */
470 			RunCommand(str);
471 			free(str);
472 		}
473 	}
474 }
475