1 /*
2     TiMidity++ -- MIDI to WAVE converter and player
3     Copyright (C) 1999-2002 Masanao Izumo <mo@goice.co.jp>
4     Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>
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 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif /* HAVE_CONFIG_H */
24 #include <stdio.h>
25 #ifndef NO_STRING_H
26 #include <string.h>
27 #else
28 #include <strings.h>
29 #endif
30 #include "timidity.h"
31 #include "common.h"
32 #include "wrd.h"
33 #include "strtab.h"
34 #include "instrum.h"
35 #include "playmidi.h"
36 #include "readmidi.h"
37 #include "arc.h"
38 #include "interface.h"
39 
40 /*
41  * Remap WRD @COLOR(16)-@COLOR(23) to RGB plain number.
42  * Usage: rgb = wrd_color_remap[color-16];
43  *
44  * R G B
45  * 1 2 4
46  */
47 int wrd_color_remap[8] =
48 {
49     0, /* 16 secret?, I don't know this code meaning. */
50     1, /* 17 red */
51     4, /* 18 blue */
52     5, /* 19 magenta */
53     2, /* 20 green */
54     3, /* 21 yellow */
55     6, /* 22 cyan */
56     7  /* 23 white */
57 };
58 
59 /* Map RGB plane from MIMPI plane.
60  *
61  * {0,1,2,3,4,5,6,7} -- No conversion
62  * {0,4,1,5,2,6,3,7} -- BRG to RGB
63  * {0,1,4,5,2,3,6,7} -- GRB to RGB
64  */
65 int wrd_plane_remap[8] = {0,1,2,3,4,5,6,7};
66 
67 extern WRDTracer dumb_wrdt_mode;
68 
69 #ifdef __MACOS__
70 extern WRDTracer mac_wrdt_mode;
71 #endif
72 
73 /*ARGSUSED*/
null_wrdt_open(char * wrdt_opts)74 static int null_wrdt_open(char *wrdt_opts) { return 0; }
75 /*ARGSUSED*/
null_wrdt_apply(int cmd,int argc,int args[])76 static void null_wrdt_apply(int cmd, int argc, int args[]) { }
null_wrdt_update_events(void)77 static void null_wrdt_update_events(void) { }
null_wrdt_end(void)78 static void null_wrdt_end(void) { }
null_wrdt_close(void)79 static void null_wrdt_close(void) { }
80 
81 WRDTracer null_wrdt_mode =
82 {
83     "No WRD trace", '-',
84     0,
85     null_wrdt_open,
86     null_wrdt_apply,
87     NULL,
88     null_wrdt_update_events,
89     NULL,
90     null_wrdt_end,
91     null_wrdt_close
92 };
93 extern WRDTracer tty_wrdt_mode;
94 
95 
96 #ifdef WRDT_X
97 extern WRDTracer x_wrdt_mode;
98 #endif /* WRDT_X */
99 
100 #if defined(__W32__) && !defined(__BORLANDC__) && !defined(IA_W32GUI) && !defined(IA_W32G_SYN)
101 extern WRDTracer wcon_wrdt_mode; /* wrdt_wcon.c */
102 #endif /* __W32__ */
103 #if defined(__W32__) && defined(IA_W32GUI)
104 extern WRDTracer w32g_wrdt_mode; /* wrdt_w32g.c */
105 #endif /* __W32__ */
106 #if defined(__W32__) && defined(IA_W32G_SYN)
107 extern WRDTracer null_wrdt_mode;
108 #endif /* __W32__ */
109 
110 WRDTracer *wrdt_list[] =
111 {
112 #ifdef WRDT_X
113     &x_wrdt_mode,
114 #endif /* WRDT_X */
115 #if defined(__W32__) && !defined(__BORLANDC__) && !defined(IA_W32GUI) && !defined(IA_W32G_SYN)
116 	&wcon_wrdt_mode,
117 #endif /* __W32__ */
118 #if defined(__W32__) && defined(IA_W32GUI)
119 	&w32g_wrdt_mode,
120 #endif /* __W32__ */
121 #if !defined(__MACOS__) && !defined(IA_W32GUI) && !defined(IA_W32G_SYN)
122     &tty_wrdt_mode,
123 #endif /* __MACOS__  IA_W32GUI IA_W32G_SYN */
124 #ifdef __MACOS__
125     &mac_wrdt_mode,
126 #endif
127 #if !defined(IA_W32GUI) && !defined(IA_W32G_SYN)
128     &dumb_wrdt_mode,
129 #endif
130     &null_wrdt_mode,
131     0
132 };
133 
134 WRDTracer *wrdt = &null_wrdt_mode;
135 
136 
137 static StringTable path_list;
138 static StringTable default_path_list;
139 static int wrd_add_path_one(char *path, int pathlen);
140 
wrd_init_path(void)141 void wrd_init_path(void)
142 {
143     StringTableNode *p;
144     delete_string_table(&path_list);
145     for(p = default_path_list.head; p; p = p->next)
146 	wrd_add_path_one(p->string, strlen(p->string));
147 
148     if(current_file_info)
149     {
150 	if(strchr(current_file_info->filename, '#') != NULL)
151 	    wrd_add_path_one(current_file_info->filename,
152 			     strchr(current_file_info->filename, '#') -
153 			     current_file_info->filename + 1);
154 	if(pathsep_strrchr(current_file_info->filename) != NULL)
155 	    wrd_add_path_one(current_file_info->filename,
156 			     pathsep_strrchr(current_file_info->filename) -
157 			     current_file_info->filename + 1);
158     }
159 }
160 
wrd_add_path_one(char * path,int pathlen)161 static int wrd_add_path_one(char *path, int pathlen)
162 {
163     int exists;
164     StringTableNode *p;
165 
166     exists = 0;
167     for(p = path_list.head; p; p = p->next)
168 	if(strncmp(p->string, path, pathlen) == 0 &&
169 	   p->string[pathlen] == '\0')
170 	{
171 	    exists = 1;
172 	    break;
173 	}
174     if(exists)
175 	return 0;
176     put_string_table(&path_list, path, pathlen);
177     return 1;
178 }
179 
wrd_add_path(char * path,int pathlen)180 void wrd_add_path(char *path, int pathlen)
181 {
182     if(pathlen == 0)
183 	pathlen = strlen(path);
184     if(!wrd_add_path_one(path, pathlen))
185 	return;
186 
187     if(current_file_info &&
188        get_archive_type(current_file_info->filename) != -1)
189     {
190 	MBlockList buf;
191 	char *arc_path;
192 	int baselen;
193 
194 	init_mblock(&buf);
195 	baselen = strrchr(current_file_info->filename, '#') -
196 	    current_file_info->filename + 1;
197 	arc_path = new_segment(&buf, baselen + pathlen + 1);
198 	strncpy(arc_path, current_file_info->filename, baselen);
199 	strncpy(arc_path + baselen, path, pathlen);
200 	arc_path[baselen + pathlen] = '\0';
201 	put_string_table(&path_list, arc_path, strlen(arc_path));
202 	reuse_mblock(&buf);
203     }
204 }
205 
wrd_add_default_path(char * path)206 void wrd_add_default_path(char *path)
207 {
208     put_string_table(&default_path_list, path, strlen(path));
209 }
210 
try_wrd_open_file(char * prefix,char * fn)211 static struct timidity_file *try_wrd_open_file(char *prefix, char *fn)
212 {
213     MBlockList buf;
214     char *path;
215     int len1, len2;
216     struct timidity_file *tf;
217 
218     init_mblock(&buf);
219     len1 = strlen(prefix);
220     len2 = strlen(fn);
221     path = (char *)new_segment(&buf, len1 + len2 + 2);
222     strcpy(path, prefix);
223     if( len1>0 && path[len1 - 1] != '#' && !IS_PATH_SEP(path[len1 - 1]))
224     {
225 	path[len1++] = PATH_SEP;
226 	path[len1] = '\0';
227     }
228     strcat(path, fn);
229     tf = open_file(path, 0, OF_SILENT);
230     reuse_mblock(&buf);
231     return tf;
232 }
233 
234 #define CUR_DIR_PATH ""
235 
wrd_open_file(char * filename)236 struct timidity_file *wrd_open_file(char *filename)
237 {
238     StringTableNode *path;
239     struct timidity_file *tf;
240 
241     if(get_archive_type(filename) != -1)
242 	return open_file(filename, 0, OF_SILENT);
243 
244     for(path = path_list.head; path; path = path->next){
245 	if((tf = try_wrd_open_file(path->string, filename)) != NULL)
246 	    return tf;
247     }
248     return try_wrd_open_file(CUR_DIR_PATH, filename);
249 }
250 
wrd_midi_event(int cmd,int arg)251 void wrd_midi_event(int cmd, int arg)
252 {
253     static int wrd_argc = 0;
254     static int wrd_args[WRD_MAXPARAM];
255 
256     if(!wrdt->opened) /* Ignore any WRD command if WRD is closed */
257 	return;
258 
259     if(cmd == -1)
260     {
261 	wrd_argc = 0;
262 	return;
263     }
264 
265     wrd_args[wrd_argc++] = arg;
266     if(cmd != WRD_ARG)
267     {
268 	wrdt->apply(cmd, wrd_argc, wrd_args);
269 	wrd_argc = 0;
270     }
271 }
272 
wrd_sherry_event(int addr)273 void wrd_sherry_event(int addr)
274 {
275     if(!wrdt->opened || wrdt->sherry == NULL)
276 	return;
277     wrdt->sherry(datapacket[addr].data, datapacket[addr].len);
278 }
279 
free_wrd(void)280 void free_wrd(void)
281 {
282 	delete_string_table(&path_list);
283 }
284 
285 #ifdef __BORLANDC__
print_ecmd(char * cmd,int * args,int narg)286 void print_ecmd(char *cmd, int *args, int narg)
287 {
288     char *p;
289     size_t s = MIN_MBLOCK_SIZE;
290 
291     p = (char *)new_segment(&tmpbuffer, s);
292     snprintf(p, s, "^%s(", cmd);
293 
294     if(*args == WRD_NOARG)
295 	strncat(p, "*", s - strlen(p) - 1);
296     else {
297 	char c[CHAR_BIT*sizeof(int)];
298 	snprintf(c, sizeof(c)-1, "%d", args[0]);
299 	strncat(p, c, s - strlen(p) - 1);
300     }
301     args++;
302     narg--;
303     while(narg > 0)
304     {
305 	if(*args == WRD_NOARG)
306 	    strncat(p, ",*", s - strlen(p) - 1);
307 	else {
308 	    char c[CHAR_BIT*sizeof(int)]; /* should be enough loong */
309 	    snprintf(c, sizeof(c)-1, ",%d", args[0]);
310 	    strncat(p, c, s - strlen(p) - 1);
311 	}
312 	args++;
313 	narg--;
314     }
315     strncat(p, ")", s - strlen(p) - 1);
316     ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "%s", p);
317     reuse_mblock(&tmpbuffer);
318 }
319 #endif
320