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