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     WRD reader - Written by Masanao Izumo <mo@goice.co.jp>
21 		 Modified by Takaya Nogami <t-nogami@happy.email.ne.jp> for
22 			Sherry WRD.
23 
24  */
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif /* HAVE_CONFIG_H */
28 #include <stdio.h>
29 #include <stdlib.h>
30 #ifndef NO_STRING_H
31 #include <string.h>
32 #else
33 #include <strings.h>
34 #endif
35 #include <ctype.h>
36 
37 #include "timidity.h"
38 #include "common.h"
39 #include "instrum.h"
40 #include "playmidi.h"
41 #include "readmidi.h"
42 #include "controls.h"
43 #include "wrd.h"
44 #include "strtab.h"
45 
46 /*#define DEBUG 1*/
47 
48 #if  defined(JAPANESE) || defined(__MACOS__)
49 #define IS_MULTI_BYTE(c)	( ((c)&0x80) && ((0x1 <= ((c)&0x7F) && ((c)&0x7F) <= 0x1f) ||\
50 				 (0x60 <= ((c)&0x7F) && ((c)&0x7F) <= 0x7c)))
51 #define IS_SJIS_ZENKAKU_SPACE(p) ((p)[0] == 0x81 && (p)[1] == 0x40)
52 #else
53 #define IS_MULTI_BYTE(c)	0
54 #endif /* JAPANESE */
55 
56 #define WRDENDCHAR 26 /* ^Z */
57 #define MAXTOKLEN 255
58 #define MAXTIMESIG 256
59 
60 /*
61  * Define Bug emulation level.
62  * 0: No emulatoin.
63  * 1: Standard emulation (emulate if the bugs is well known).
64  * 2: More emulation (including unknown bugs).
65  * 3-9: Danger level!! (special debug level)
66  */
67 #ifndef MIMPI_BUG_EMULATION_LEVEL
68 #define MIMPI_BUG_EMULATION_LEVEL 1
69 #endif
70 static int mimpi_bug_emulation_level = MIMPI_BUG_EMULATION_LEVEL;
71 static int wrd_bugstatus;
72 static int wrd_wmode_prev_step;
73 #ifdef DEBUG
74 #define WRD_BUGEMUINFO(code) ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, \
75     "WRD: Try to emulate bug of MIMPI at line %d (code=%d)", lineno, code)
76 #else
77 #define WRD_BUGEMUINFO(code) ctl->cmsg(CMSG_WARNING, VERB_NOISY, \
78     "WRD: Try to emulate bug of MIMPI at line %d", lineno)
79 #endif /* DEBUG */
80 /* Current max code: 13 */
81 
82 #define FADE_SPEED_BASE 24 /* 24 or 48?? */
83 
84 StringTable wrd_read_opts;
85 static int version;
86 
87 struct wrd_delayed_event
88 {
89     int32 waittime;
90     int cmd, arg;
91     struct wrd_delayed_event* next;
92 };
93 
94 struct wrd_step_tracer
95 {
96     int32 at;		/* total step count */
97     int32 last_at;	/* estimated maxmum steps */
98     int32 step_inc;	/* increment steps per newline or character */
99     int bar;		/* total bar count */
100     int step;		/* step in current bar */
101     int barstep;	/* step count of current bar */
102     MidiEvent timesig[MAXTIMESIG]; /* list of time signature code */
103     int timeidx;	/* index of current timesig */
104     int ntimesig;	/* number of time signatures */
105     int timebase;	/* divisions */
106     int offset;		/* @OFFSET */
107     int wmode0, wmode1;	/* @WMODE */
108 
109     /* Delayed MIDI event list */
110     struct wrd_delayed_event *de;
111     struct wrd_delayed_event *free_de;
112 
113     MBlockList pool;	/* memory buffer */
114 };
115 
116 static MBlockList sry_pool; /* data buffer */
117 sry_datapacket *datapacket = NULL;
118 #ifdef ENABLE_SHERRY
119 static int datapacket_len, datapacket_cnt;
120 #define DEFAULT_DATAPACKET_LEN 16384
121 static int import_sherrywrd_file(const char * );
122 #endif /* ENABLE_SHERRY */
123 
124 static uint8 cmdlookup(uint8 *cmd);
125 static int wrd_nexttok(struct timidity_file *tf);
126 static void wrd_readinit(void);
127 static struct timidity_file *open_wrd_file(char *fn);
128 static int wrd_hexval(char *hex);
129 static int wrd_eint(char *hex);
130 static int wrd_atoi(char *val, int default_value);
131 static void wrd_add_lyric(int32 at, char *lyric, int len);
132 static int wrd_split(char* arg, char** argv, int maxarg);
133 static void wrdstep_inc(struct wrd_step_tracer *wrdstep, int32 inc);
134 static void wrdstep_update_forward(struct wrd_step_tracer *wrdstep);
135 static void wrdstep_update_backward(struct wrd_step_tracer *wrdstep);
136 static void wrdstep_nextbar(struct wrd_step_tracer *wrdstep);
137 static void wrdstep_prevbar(struct wrd_step_tracer *wrdstep);
138 static void wrdstep_wait(struct wrd_step_tracer *wrdstep, int bar, int step);
139 static void wrdstep_rest(struct wrd_step_tracer *wrdstep, int bar, int step);
140 static struct wrd_delayed_event *wrd_delay_cmd(struct wrd_step_tracer *wrdstep,
141 					int32 waittime, int cmd, int arg);
142 static uint8 wrd_tokval[MAXTOKLEN + 1]; /* Token value */
143 static uint8 wrd_tok;		/* Token type */
144 static int lineno;		/* linenumber */
145 static int32 last_event_time;
146 
147 #define WRD_ADDEVENT(at, cmd, arg) \
148     { MidiEvent e; e.time = (at); e.type = ME_WRD; e.channel = (cmd); \
149       e.a = (uint8)((arg) & 0xFF); e.b = (uint8)(((arg) >> 8) & 0xFF); \
150       if(mimpi_bug_emulation_level > 0){ if(at < last_event_time){ e.time = \
151       last_event_time; }else{ last_event_time = e.time; }} \
152       readmidi_add_event(&e); }
153 
154 #define WRD_ADDSTREVENT(at, cmd, str) \
155     { MidiEvent e; readmidi_make_string_event(ME_WRD, (str), &e, 0); \
156       e.channel = (cmd); e.time = (at); \
157       if(mimpi_bug_emulation_level > 0){ if(at < last_event_time){ e.time = \
158       last_event_time; }else{ last_event_time = e.time; }} \
159       readmidi_add_event(&e); }
160 
161 #define SETMIDIEVENT(e, at, t, ch, pa, pb) \
162     { (e).time = (at); (e).type = (t); \
163       (e).channel = (uint8)(ch); (e).a = (uint8)(pa); (e).b = (uint8)(pb); }
164 #define MIDIEVENT(at, t, ch, pa, pb) \
165     { MidiEvent event; SETMIDIEVENT(event, at, t, ch, pa, pb); \
166       readmidi_add_event(&event); }
167 
168 #ifdef DEBUG
169 static char *wrd_name_string(int cmd);
170 #endif /* DEBUG */
171 
import_wrd_file(char * fn)172 int import_wrd_file(char *fn)
173 {
174     struct timidity_file *tf;
175     char *args[WRD_MAXPARAM], *arg0;
176     int argc;
177     int32 i, num;
178     struct wrd_step_tracer wrdstep;
179 #define step_at wrdstep.at
180 
181     static int initflag = 0;
182     static char *default_wrd_file1, /* Default */
183 		*default_wrd_file2; /* Always */
184     char *wfn; /* opened WRD filename */
185     StringTableNode *stn; /* Chain list of string */
186 
187     if(!initflag) /* Initialize at once */
188     {
189 	char *read_opts[WRD_MAXPARAM];
190 
191 	initflag = 1;
192 	for(stn = wrd_read_opts.head; stn; stn = stn->next)
193 	{
194 	    int nopts;
195 
196 	    nopts = wrd_split(stn->string, read_opts, WRD_MAXPARAM);
197 	    for(i = 0; i < nopts; i++)
198 	    {
199 		char *a, *b;
200 		a = read_opts[i];
201 		if((b = strchr(a, '=')) != NULL)
202 		    *b++ = '\0';
203 		if(strcmp(a, "d") == 0)
204 		    mimpi_bug_emulation_level = (b ? atoi(b) : 0);
205 		else if(strcmp(a, "f") == 0)
206 		{
207 		    if(default_wrd_file1 != NULL)
208 			free(default_wrd_file1);
209 		    default_wrd_file1 = (b ? safe_strdup(b) : NULL);
210 		}
211 		else if(strcmp(a, "F") == 0)
212 		{
213 		    if(default_wrd_file2 != NULL)
214 			free(default_wrd_file2);
215 		    default_wrd_file2 = (b ? safe_strdup(b) : NULL);
216 		}
217 		else if(strcmp(a, "p") == 0)
218 		{
219 		    if(b != NULL)
220 			wrd_add_default_path(b);
221 		}
222 	    }
223 	}
224     }
225 
226     if(datapacket == NULL)
227 	init_mblock(&sry_pool);
228     else
229     {
230 	free(datapacket);
231 	datapacket = NULL;
232 	reuse_mblock(&sry_pool);
233     }
234 
235     wrd_init_path();
236     if(default_wrd_file2 != NULL)
237 	tf = open_file((wfn = default_wrd_file2), 0, OF_NORMAL);
238     else
239 	tf = open_wrd_file(wfn = fn);
240     if(tf == NULL && default_wrd_file1 != NULL)
241 	tf = open_file((wfn = default_wrd_file1), 0, OF_NORMAL);
242     if(tf == NULL)
243     {
244 	default_wrd_file1 = default_wrd_file2 = NULL;
245 #ifdef ENABLE_SHERRY
246 	if(import_sherrywrd_file(fn))
247 	    return WRD_TRACE_SHERRY;
248 #endif
249 	return WRD_TRACE_NOTHING;
250     }
251 
252     wrd_readinit();
253 
254     memset(&wrdstep, 0, sizeof(wrdstep));
255     init_mblock(&wrdstep.pool);
256     wrdstep.de = wrdstep.free_de = NULL;
257     wrdstep.timebase = current_file_info->divisions;
258     wrdstep.ntimesig = dump_current_timesig(wrdstep.timesig, MAXTIMESIG - 1);
259     if(wrdstep.ntimesig > 0)
260     {
261 	wrdstep.timesig[wrdstep.ntimesig] =
262 	    wrdstep.timesig[wrdstep.ntimesig - 1];
263 	wrdstep.timesig[wrdstep.ntimesig].time = 0x7fffffff; /* stopper */
264 #ifdef DEBUG
265 	fprintf(stderr, "Time signatures:\n");
266 	for(i = 0; i < wrdstep.ntimesig; i++)
267 	    printf("  %d: %d/%d\n",
268 		   wrdstep.timesig[i].time,
269 		   wrdstep.timesig[i].a,
270 		   wrdstep.timesig[i].b);
271 #endif /* DEBUG */
272 	wrdstep.barstep =
273 	    wrdstep.timesig[0].a * wrdstep.timebase * 4 / wrdstep.timesig[0].b;
274     }
275     else
276 	wrdstep.barstep = 4 * wrdstep.timebase;
277     wrdstep.step_inc = wrdstep.barstep;
278     wrdstep.last_at = readmidi_set_track(0, 0);
279 
280     readmidi_set_track(0, 1);
281 
282 #ifdef DEBUG
283     fprintf(stderr, "Timebase: %d\n", wrdstep.timebase);
284     fprintf(stderr, "Step: %d\n", wrdstep.step_inc);
285 #endif /* DEBUG */
286 
287     while(!readmidi_error_flag && wrd_nexttok(tf))
288     {
289 	if(version == -1 &&
290 	   (wrd_tok != WRD_COMMAND || wrd_tokval[0] != WRD_STARTUP))
291 	{
292 	    /* WRD_STARTUP must be first */
293 	    ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, "WRD: No @STARTUP");
294 	    version = 0;
295 	    WRD_ADDEVENT(0, WRD_STARTUP, 0);
296 	}
297 
298 #ifdef DEBUG
299 	fprintf(stderr, "%d: [%d,%d]/%d %s: ",
300 	       lineno,
301 	       wrdstep.bar,
302 	       wrdstep.step,
303 	       wrd_bugstatus,
304 	       wrd_name_string(wrd_tok));
305 	if(wrd_tok == WRD_COMMAND)
306 	    printf("%s(%s)", wrd_name_string(wrd_tokval[0]), wrd_tokval + 1);
307 	else if(wrd_tok == WRD_LYRIC)
308 	    printf("<%s>", wrd_tokval);
309 	printf("\n");
310 	fflush(stdout);
311 #endif /* DEBUG */
312 
313 	switch(wrd_tok)
314 	{
315 	  case WRD_COMMAND:
316 	    arg0 = (char *)wrd_tokval + 1;
317 	    switch(wrd_tokval[0])
318 	    {
319 	      case WRD_COLOR:
320 		num = atoi(arg0);
321 		WRD_ADDEVENT(step_at, WRD_COLOR, num);
322 		break;
323 	      case WRD_END:
324 		while(step_at < wrdstep.last_at)
325 		    wrdstep_nextbar(&wrdstep);
326 		break;
327 	      case WRD_ESC:
328 		WRD_ADDSTREVENT(step_at, WRD_ESC, arg0);
329 		break;
330 	      case WRD_EXEC:
331 		WRD_ADDSTREVENT(step_at, WRD_EXEC, arg0);
332 		break;
333 	      case WRD_FADE:
334 		argc = wrd_split(arg0, args, 3);
335 		for(i = 0; i < 2; i++)
336 		{
337 		    num = atoi(args[i]);
338 		    WRD_ADDEVENT(step_at, WRD_ARG, num);
339 		}
340 
341 		num = wrd_atoi(args[i], 1);
342 		WRD_ADDEVENT(step_at, WRD_FADE, num);
343 
344 		if(num >= 1)
345 		{
346 		    int32 delay, fade_speed;
347 
348 		    fade_speed = (num + 1) * wrdstep.timebase / FADE_SPEED_BASE;
349 		    for(i = 1; i < WRD_MAXFADESTEP; i++)
350 		    {
351 			delay =	(int32)((double)fade_speed *
352 				       i / WRD_MAXFADESTEP);
353 			wrd_delay_cmd(&wrdstep, delay, WRD_ARG,
354 				      i);
355 			wrd_delay_cmd(&wrdstep, delay, WRD_FADESTEP,
356 				      WRD_MAXFADESTEP);
357 		    }
358 		    wrd_delay_cmd(&wrdstep, fade_speed, WRD_ARG,
359 				  WRD_MAXFADESTEP);
360 		    wrd_delay_cmd(&wrdstep, fade_speed, WRD_FADESTEP,
361 				  WRD_MAXFADESTEP);
362 		}
363 		break;
364 	      case WRD_GCIRCLE:
365 		argc = wrd_split(arg0, args, 6);
366 		if(argc < 5)
367 		{
368 		    /* Error : Too few argument */
369 		    break;
370 		}
371 		for(i = 0; i < 5; i++)
372 		{
373 		    num = atoi(args[i]);
374 		    WRD_ADDEVENT(step_at, WRD_ARG, num);
375 		}
376 		num = atoi(args[i]);
377 		WRD_ADDEVENT(step_at, WRD_GCIRCLE, num);
378 		break;
379 	      case WRD_GCLS:
380 		num = atoi(arg0);
381 		WRD_ADDEVENT(step_at, WRD_GCLS, num);
382 		break;
383 	      case WRD_GINIT:
384 		WRD_ADDEVENT(step_at, WRD_GINIT, 0);
385 		break;
386 	      case WRD_GLINE:
387 		argc = wrd_split(arg0, args, 7);
388 		if(argc < 4)
389 		{
390 		    /* Error: Too few arguments */
391 		    break;
392 		}
393 		for(i = 0; i < 4; i++)
394 		{
395 		    num = atoi(args[i]);
396 		    WRD_ADDEVENT(step_at, WRD_ARG, num)
397 		}
398 		WRD_ADDEVENT(step_at, WRD_ARG,   atoi(args[4]));
399 		WRD_ADDEVENT(step_at, WRD_ARG,   atoi(args[5]));
400 		WRD_ADDEVENT(step_at, WRD_GLINE, atoi(args[6]));
401 		break;
402 	      case WRD_GMODE:
403 		num = atoi(arg0);
404 		WRD_ADDEVENT(step_at, WRD_GMODE, num)
405 		break;
406 	      case WRD_GMOVE:
407 		argc = wrd_split(arg0, args, 9);
408 		if(argc < 6)
409 		{
410 		    /* Error: Too few arguments */
411 		    break;
412 		}
413 		for(i = 0; i < 8; i++)
414 		{
415 		    num = atoi(args[i]);
416 		    WRD_ADDEVENT(step_at, WRD_ARG, num);
417 		}
418 		num = atoi(args[i]);
419 		WRD_ADDEVENT(step_at, WRD_GMOVE, num)
420 		break;
421 	      case WRD_GON:
422 		num = atoi(arg0);
423 		WRD_ADDEVENT(step_at, WRD_GON, num);
424 		break;
425 	      case WRD_GSCREEN:
426 		if(mimpi_bug_emulation_level >= 1)
427 		{
428 		    for(i = 0; arg0[i]; i++)
429 			if(arg0[i] == '.')
430 			{
431 			    WRD_BUGEMUINFO(110);
432 			    arg0[i] = ',';
433 			}
434 		}
435 		argc = wrd_split(arg0, args, 2);
436 		if(argc != 2)
437 		{
438 		    /* Error: Number of arguments miss match */
439 		    break;
440 		}
441 		num = atoi(args[0]);
442 		WRD_ADDEVENT(step_at, WRD_ARG, num);
443 		num = atoi(args[1]);
444 		WRD_ADDEVENT(step_at, WRD_GSCREEN, num);
445 		break;
446 	      case WRD_INKEY: /* FIXME */
447 		num = atoi(arg0);
448 		if(num < wrdstep.bar)
449 		{
450 		    /* Error */
451 		    break;
452 		}
453 		WRD_ADDEVENT(step_at, WRD_INKEY, WRD_NOARG);
454 		num = (num - wrdstep.bar) * wrdstep.barstep;
455 		wrd_delay_cmd(&wrdstep, num, WRD_OUTKEY, WRD_NOARG);
456 		break;
457 	      case WRD_LOCATE:
458 		if(strchr(arg0, ';') != NULL)
459 		    i = 1; /* Swap argument */
460 		else
461 		    i = 0;
462 		argc = wrd_split(arg0, args, 2);
463 		if(argc != 2)
464 		{
465 		    /* Error: Number of arguments miss match */
466 		    break;
467 		}
468 		if(i)
469 		{
470 		    num = atoi(args[1]);
471 		    WRD_ADDEVENT(step_at, WRD_ARG, num);
472 		    num = atoi(args[0]);
473 		    WRD_ADDEVENT(step_at, WRD_LOCATE, num);
474 		}
475 		else
476 		{
477 		    num = atoi(args[0]);
478 		    WRD_ADDEVENT(step_at, WRD_ARG, num);
479 		    num = atoi(args[1]);
480 		    WRD_ADDEVENT(step_at, WRD_LOCATE, num);
481 		}
482 		break;
483 	      case WRD_LOOP: /* Not supported */
484 		break;
485 	      case WRD_MAG:
486 		argc = wrd_split(arg0, args, 5);
487 		if(!*args[0])
488 		{
489 		    /* Error: @MAG No file name */
490 		    break;
491 		}
492 		WRD_ADDSTREVENT(step_at, WRD_ARG, args[0]);
493 		for(i = 1; i < 3; i++)
494 		    WRD_ADDEVENT(step_at, WRD_ARG,
495 				 wrd_atoi(args[i], WRD_NOARG));
496 		WRD_ADDEVENT(step_at, WRD_ARG, wrd_atoi(args[3], 1));
497 		WRD_ADDEVENT(step_at, WRD_MAG, atoi(args[4]));
498 		break;
499 	      case WRD_MIDI:
500 		argc = wrd_split(arg0, args, WRD_MAXPARAM);
501 		for(i = 0; i < argc; i++)
502 		    WRD_ADDEVENT(step_at, WRD_ARG, wrd_hexval(args[i]));
503 		WRD_ADDEVENT(step_at, WRD_MIDI, atoi(args[i]));
504 		break;
505 	      case WRD_OFFSET:
506 		wrdstep.offset = atoi(arg0);
507 		break;
508 	      case WRD_PAL:
509 		argc = wrd_split(arg0, args, 17);
510 		if(argc != 16 && argc != 17)
511 		{
512 		    /* Error: Number of arguments miss match */
513 		    break;
514 		}
515 
516 		if(argc == 16)
517 		{
518 		    WRD_ADDEVENT(step_at, WRD_ARG, 0);
519 		    i = 0;
520 		}
521 		else
522 		{
523 		    if(*args[0] == '#')
524 			num = atoi(args[0] + 1);
525 		    else
526 			num = atoi(args[0]);
527 		    WRD_ADDEVENT(step_at, WRD_ARG, num);
528 		    i = 1;
529 		}
530 		for(; i < argc - 1; i++)
531 		{
532 		    if(!*args[i])
533 			num = 0;
534 		    else
535 			num = wrd_hexval(args[i]);
536 		    WRD_ADDEVENT(step_at, WRD_ARG, num);
537 		}
538 		if(!*args[i])
539 		    num = 0;
540 		else
541 		    num = wrd_hexval(args[i]);
542 		WRD_ADDEVENT(step_at, WRD_PAL, num)
543 		break;
544 	      case WRD_PALCHG:
545 		WRD_ADDSTREVENT(step_at, WRD_PALCHG, arg0);
546 		break;
547 	      case WRD_PALREV:
548 		num = atoi(arg0);
549 		WRD_ADDEVENT(step_at, WRD_PALREV, num)
550 		break;
551 	      case WRD_PATH:
552 		WRD_ADDSTREVENT(step_at, WRD_PATH, arg0);
553 		break;
554 	      case WRD_PLOAD:
555 		WRD_ADDSTREVENT(step_at, WRD_PLOAD, arg0);
556 		break;
557 	      case WRD_REM:
558 		WRD_ADDSTREVENT(step_at, WRD_REM, arg0);
559 		break;
560 	      case WRD_REMARK:
561 		WRD_ADDSTREVENT(step_at, WRD_REMARK, arg0);
562 		break;
563 	      case WRD_REST:
564 		argc = wrd_split(arg0, args, 2);
565 		num = atoi(args[0]);
566 		if(mimpi_bug_emulation_level >= 9 && /* For testing */
567 		   num == 5 &&
568 		   wrdstep.wmode0 == 1)
569 		{
570 		    WRD_BUGEMUINFO(901);
571 		    num--; /* Why??? */
572 		}
573 		wrdstep_rest(&wrdstep, num, atoi(args[1]));
574 		break;
575 	      case WRD_SCREEN: /* Not supported */
576 		break;
577 	      case WRD_SCROLL:
578 		argc = wrd_split(arg0, args, 7);
579 		/*for(i = 0; i < 6; i++)
580 		{
581 		    num = atoi(args[i]);
582 		    WRD_ADDEVENT(step_at, WRD_ARG, num);
583 		}
584 		num = atoi(args[i]);
585 		WRD_ADDEVENT(step_at, WRD_SCROLL, num);*/
586 		WRD_ADDEVENT(step_at, WRD_ARG, wrd_atoi(args[0], 1));
587 		WRD_ADDEVENT(step_at, WRD_ARG, wrd_atoi(args[1], 1));
588 		WRD_ADDEVENT(step_at, WRD_ARG, wrd_atoi(args[2], 80));
589 		WRD_ADDEVENT(step_at, WRD_ARG, wrd_atoi(args[3], 25));
590 		WRD_ADDEVENT(step_at, WRD_ARG, wrd_atoi(args[4], 0));
591 		WRD_ADDEVENT(step_at, WRD_ARG, wrd_atoi(args[5], 0));
592 		WRD_ADDEVENT(step_at, WRD_SCROLL,wrd_atoi(args[6], 32));
593 		break;
594 	      case WRD_STARTUP:
595 		version = atoi(arg0);
596 		WRD_ADDEVENT(step_at, WRD_STARTUP, version);
597 		break;
598 	      case WRD_STOP: {
599 		  MidiEvent e;
600 		  e.time = step_at;
601 		  e.type = ME_EOT;
602 		  e.channel = e.a = e.b = 0;
603 		  readmidi_add_event(&e);
604 		}
605 		break;
606 	      case WRD_TCLS:
607 		argc = wrd_split(arg0, args, 6);
608 		WRD_ADDEVENT(step_at, WRD_ARG, wrd_atoi(args[0], 1));
609 		WRD_ADDEVENT(step_at, WRD_ARG, wrd_atoi(args[1], 1));
610 		WRD_ADDEVENT(step_at, WRD_ARG, wrd_atoi(args[2], 80));
611 		WRD_ADDEVENT(step_at, WRD_ARG, wrd_atoi(args[3], 25));
612 		WRD_ADDEVENT(step_at, WRD_ARG, wrd_atoi(args[4], 0));
613 		i = wrd_atoi(args[5], ' ');
614 		if(i == 0)
615 		    i = ' ';
616 		WRD_ADDEVENT(step_at, WRD_TCLS,i);
617 		break;
618 	      case WRD_TON:
619 		num = atoi(arg0);
620 		WRD_ADDEVENT(step_at, WRD_TON, num);
621 		break;
622 	      case WRD_WAIT:
623 		argc = wrd_split(arg0, args, 2);
624 		wrdstep_wait(&wrdstep, atoi(args[0]), atoi(args[1]));
625 		break;
626 	      case WRD_WMODE:
627 		argc = wrd_split(arg0, args, 2);
628 		wrdstep.wmode0 = wrd_atoi(args[0], wrdstep.wmode0); /* n */
629 		wrdstep.wmode1 = wrd_atoi(args[1], wrdstep.wmode1); /* mode */
630 		if(mimpi_bug_emulation_level >= 1 &&
631 		   (version <= 0 || version == 400))
632 		    wrd_wmode_prev_step = wrdstep.step_inc;
633 		if(argc == 1 && wrdstep.wmode0 == 0)
634 		    wrdstep.step_inc = wrdstep.barstep;
635 		else
636 		{
637 		    if(wrdstep.wmode0 <= 0 || wrdstep.wmode0 >= 256)
638 		    {
639 			ctl->cmsg(CMSG_WARNING, VERB_NORMAL,
640 				  "WRD: Out of value range: "
641 				  "@WMODE(%d,%d) at line %d",
642 				  wrdstep.wmode0,wrdstep.wmode1,lineno);
643 			wrdstep.step_inc = wrdstep.barstep;
644 		    } else
645 			wrdstep.step_inc =
646 			    (wrdstep.wmode0 + 1) * wrdstep.timebase / 24;
647 		}
648 #ifdef DEBUG
649 		fprintf(stderr, "Step change: wmode=%s, step=%d\n",
650 		       wrdstep.wmode1 ? "char" : "line", wrdstep.step_inc);
651 #endif /* DEBUG */
652 		break;
653 	    }
654 	    break;
655 	  case WRD_ECOMMAND:
656 	    arg0 = (char *)wrd_tokval + 1;
657 	    switch(wrd_tokval[0])
658 	    {
659 	      case WRD_eFONTM:
660 		num = wrd_eint(arg0);
661 		WRD_ADDEVENT(step_at, WRD_eFONTM, num);
662 		break;
663 	      case WRD_eFONTP:
664 		argc = wrd_split(arg0, args, 4);
665 		if(argc != 4)
666 		{
667 		    /* Error: Number of arguments miss match */
668 		    break;
669 		}
670 		for(i = 0; i < 3; i++)
671 		{
672 		    num = wrd_eint(args[i]);
673 		    WRD_ADDEVENT(step_at, WRD_ARG, num);
674 		}
675 		num = wrd_eint(args[i]);
676 		WRD_ADDEVENT(step_at, WRD_eFONTP, num);
677 		break;
678 	      case WRD_eFONTR:
679 		argc = wrd_split(arg0, args, 17);
680 		if(argc != 17)
681 		{
682 		    /* Error: Number of arguments miss match */
683 		    break;
684 		}
685 		for(i = 0; i < 16; i++)
686 		{
687 		    num = wrd_eint(args[i]);
688 		    WRD_ADDEVENT(step_at, WRD_ARG, num);
689 		}
690 		num = wrd_eint(args[i]);
691 		WRD_ADDEVENT(step_at, WRD_eFONTR, num);
692 		break;
693 	      case WRD_eGSC:
694 		num = wrd_eint(arg0);
695 		WRD_ADDEVENT(step_at, WRD_eGSC, num);
696 		break;
697 	      case WRD_eLINE:
698 		num = wrd_eint(arg0);
699 		WRD_ADDEVENT(step_at, WRD_eLINE, num);
700 		break;
701 	      case WRD_ePAL:
702 		argc = wrd_split(arg0, args, 2);
703 		if(argc != 2)
704 		{
705 		    /* Error: Number of arguments miss match */
706 		    break;
707 		}
708 		num = wrd_eint(args[0]);
709 		WRD_ADDEVENT(step_at, WRD_ARG, num);
710 		num = wrd_eint(args[1]);
711 		WRD_ADDEVENT(step_at, WRD_ePAL, num);
712 		break;
713 	      case WRD_eREGSAVE:
714 		argc = wrd_split(arg0, args, 17);
715 		if(argc < 2)
716 		{
717 		    /* Error: Too few arguments */
718 		    break;
719 		}
720 		for(i = 0; i < 16; i++)
721 		{
722 		    num = wrd_eint(args[i]);
723 		    WRD_ADDEVENT(step_at, WRD_ARG, num);
724 		}
725 		num = wrd_eint(args[i]);
726 		WRD_ADDEVENT(step_at, WRD_eREGSAVE, num);
727 		break;
728 	      case WRD_eSCROLL:
729 		argc = wrd_split(arg0, args, 2);
730 		if(argc != 2)
731 		{
732 		    /* Error: Number of arguments miss match */
733 		    break;
734 		}
735 		num = wrd_eint(args[0]);
736 		WRD_ADDEVENT(step_at, WRD_ARG, num);
737 		num = wrd_eint(args[1]);
738 		WRD_ADDEVENT(step_at, WRD_eSCROLL, num);
739 		break;
740 	      case WRD_eTEXTDOT:
741 		num = wrd_eint(arg0);
742 		WRD_ADDEVENT(step_at, WRD_eTEXTDOT, num);
743 		break;
744 	      case WRD_eTMODE:
745 		num = wrd_eint(arg0);
746 		WRD_ADDEVENT(step_at, WRD_eTMODE, num);
747 		break;
748 	      case WRD_eTSCRL:
749 		num = wrd_eint(arg0);
750 		WRD_ADDEVENT(step_at, WRD_eTSCRL, num);
751 		break;
752 	      case WRD_eVCOPY:
753 		argc = wrd_split(arg0, args, 9);
754 		if(argc != 9)
755 		{
756 		    /* Error: Number of arguments miss match */
757 		    break;
758 		}
759 		for(i = 0; i < 8; i++)
760 		{
761 		    num = wrd_eint(args[i]);
762 		    WRD_ADDEVENT(step_at, WRD_ARG, num);
763 		}
764 		num = wrd_eint(args[i]);
765 		WRD_ADDEVENT(step_at, WRD_eVCOPY, num);
766 		break;
767 	      case WRD_eVSGET:
768 		argc = wrd_split(arg0, args, 4);
769 		if(argc < 1)
770 		{
771 		    /* Error: Too few arguments */
772 		    break;
773 		}
774 		for(i = 0; i < 3; i++)
775 		{
776 		    num = wrd_eint(args[i]);
777 		    WRD_ADDEVENT(step_at, WRD_ARG, num);
778 		}
779 		num = wrd_eint(args[i]);
780 		WRD_ADDEVENT(step_at, WRD_eVSGET, num);
781 		break;
782 	      case WRD_eVSRES:
783 		WRD_ADDEVENT(step_at, WRD_eVSRES, WRD_NOARG);
784 		break;
785 	      case WRD_eXCOPY:
786 		argc = wrd_split(arg0, args, 14);
787 		if(argc < 9)
788 		{
789 		    /* Error: Too few arguments */
790 		    break;
791 		}
792 		for(i = 0; i < 13; i++)
793 		{
794 		    num = wrd_eint(args[i]);
795 		    WRD_ADDEVENT(step_at, WRD_ARG, num);
796 		}
797 		num = wrd_eint(args[i]);
798 		WRD_ADDEVENT(step_at, WRD_eXCOPY, num);
799 		break;
800 	      default:
801 		ctl->cmsg(CMSG_WARNING, VERB_NORMAL,
802 			  "WRD: Unknown WRD command at line %d (Ignored)",
803 			  lineno);
804 		break;
805 	    }
806 	    break;
807 	  case WRD_STEP:
808 	    if(wrd_wmode_prev_step == 0 ||
809 	       wrd_wmode_prev_step == wrdstep.barstep ||
810 	       wrdstep.step_inc == wrdstep.barstep)
811 		wrdstep_inc(&wrdstep, wrdstep.step_inc);
812 	    else
813 	    {
814 		if(wrd_wmode_prev_step != wrdstep.step_inc)
815 		    WRD_BUGEMUINFO(103);
816 		wrdstep_inc(&wrdstep, wrd_wmode_prev_step);
817 	    }
818 	    wrd_wmode_prev_step = 0;
819 	    break;
820 	  case WRD_LYRIC:
821 	    if(wrdstep.wmode1 == 0)
822 	    {
823 		i = (int32)strlen((char *)wrd_tokval);
824 		if(i > 0 && wrd_tokval[i - 1] == ';')
825 		    wrd_add_lyric(step_at, (char *)wrd_tokval, i - 1);
826 		else
827 		{
828 		    wrd_add_lyric(step_at, (char *)wrd_tokval, i);
829 		    WRD_ADDEVENT(step_at, WRD_NL, WRD_NOARG);
830 		    wrdstep_inc(&wrdstep, wrdstep.step_inc);
831 		}
832 	    }
833 	    else
834 	    {
835 		unsigned char *val, *lyric;
836 		int barcheck;
837 
838 		val = (unsigned char *)wrd_tokval;
839 		barcheck = 0;
840 		for(;;)
841 		{
842 		    if(*val == ';' && *(val + 1) == '\0')
843 			break;
844 		    if(*val == '\0')
845 		    {
846 			WRD_ADDEVENT(step_at, WRD_NL, WRD_NOARG);
847 			wrdstep_inc(&wrdstep, wrdstep.step_inc);
848 			break;
849 		    }
850 
851 		    if(*val == '\\')
852 		    {
853 			lyric = ++val;
854 			wrd_add_lyric(step_at, (char *) lyric, 1);
855 			wrdstep_inc(&wrdstep, wrdstep.step_inc);
856 		    }
857 		    else if(*val == '|')
858 		    {
859 			lyric = ++val;
860 			while(*val && *val != '|')
861 			{
862 			    if( IS_MULTI_BYTE(*val) || *val == '\\')
863 			    {
864 				val++;
865 				if(!*val)
866 				    break;
867 			    }
868 			    val++;
869 			}
870 			i = val - lyric;
871 			if(*val == '|')
872 			    val++;
873 			wrd_add_lyric(step_at, (char *) lyric, i);
874 
875 			/* Why does /^\|[^\|]+\|$/ takes only one waiting ? */
876 			if(mimpi_bug_emulation_level >= 2 &&
877 			   version == 427 &&
878 			   barcheck == 0 && *val == '\0')
879 			{
880 			    WRD_BUGEMUINFO(204);
881 			    WRD_ADDEVENT(step_at, WRD_NL, WRD_NOARG);
882 			    wrdstep_inc(&wrdstep, wrdstep.step_inc);
883 			    break;
884 			}
885 
886 			wrdstep_inc(&wrdstep, wrdstep.step_inc);
887 			barcheck++;
888 		    }
889 		    else
890 		    {
891 			lyric = val;
892 			if( IS_MULTI_BYTE(*val) )
893 			    val++;
894 			if(*val++ == '\0')
895 			    break;
896 			i = val - lyric;
897 			if(*lyric != '_')
898 			    wrd_add_lyric(step_at, (char *) lyric, i);
899 			wrdstep_inc(&wrdstep, wrdstep.step_inc);
900 		    }
901 		}
902 	    }
903 	    break;
904 	  case WRD_EOF:
905 	    goto end_of_wrd;
906 	  default:
907 	    break;
908 	}
909     }
910 
911   end_of_wrd:
912     while(wrdstep.de)
913 	wrdstep_nextbar(&wrdstep);
914     reuse_mblock(&wrdstep.pool);
915     close_file(tf);
916 #ifdef DEBUG
917     fflush(stderr);
918 #endif /* DEBUG */
919 
920     return WRD_TRACE_MIMPI;
921 
922 #undef step_at
923 }
924 
wrd_delay_cmd(struct wrd_step_tracer * wrdstep,int32 waittime,int cmd,int arg)925 static struct wrd_delayed_event *wrd_delay_cmd(struct wrd_step_tracer *wrdstep,
926 					int32 waittime, int cmd, int arg)
927 {
928     struct wrd_delayed_event *p;
929     struct wrd_delayed_event *insp, *prev;
930 
931     if(wrdstep->free_de != NULL)
932     {
933 	p = wrdstep->free_de;
934 	wrdstep->free_de = wrdstep->free_de->next;
935     }
936     else
937 	p = (struct wrd_delayed_event *)
938 	    new_segment(&wrdstep->pool, sizeof(struct wrd_delayed_event));
939     p->waittime = waittime;
940     p->cmd = cmd;
941     p->arg = arg;
942 
943     prev = NULL;
944     for(insp = wrdstep->de;
945 	insp != NULL && insp->waittime <= waittime;
946 	prev = insp, insp = insp->next)
947 	;
948     if(prev == NULL)
949     {
950 	p->next = wrdstep->de;
951 	wrdstep->de = p;
952     }
953     else
954     {
955 	prev->next = p;
956 	p->next = insp;
957     }
958 
959 #ifdef DEBUG
960     fprintf(stderr, "Delay events:");
961     for(insp = wrdstep->de; insp != NULL; insp = insp->next)
962 	fprintf(stderr, " @%s/%d", wrd_name_string(insp->cmd), insp->waittime);
963     fprintf(stderr, "\n");
964 #endif /* DEBUG */
965 
966     return p;
967 }
968 
wrdstep_update_forward(struct wrd_step_tracer * wrdstep)969 static void wrdstep_update_forward(struct wrd_step_tracer *wrdstep)
970 {
971     int lastidx;
972     lastidx = wrdstep->timeidx;
973     while(wrdstep->timeidx < wrdstep->ntimesig &&
974 	  wrdstep->timesig[wrdstep->timeidx + 1].time <= wrdstep->at)
975 	wrdstep->timeidx++;
976     if(lastidx != wrdstep->timeidx)
977     {
978 	wrdstep->barstep =
979 	    wrdstep->timesig[wrdstep->timeidx].a * wrdstep->timebase * 4
980 		/ wrdstep->timesig[wrdstep->timeidx].b;
981 #ifdef DEBUG
982 	fprintf(stderr, "Time signature is changed: %d/%d barstep=%d\n",
983 	       wrdstep->timesig[wrdstep->timeidx].a,
984 	       wrdstep->timesig[wrdstep->timeidx].b,
985 	       wrdstep->barstep);
986 #endif /* DEBUG */
987 	/* if(wrdstep->barstep < wrdstep->step) { WRD ERROR?? } */
988     }
989 }
990 
wrdstep_update_backward(struct wrd_step_tracer * wrdstep)991 static void wrdstep_update_backward(struct wrd_step_tracer *wrdstep)
992 {
993     int lastidx;
994 
995     lastidx = wrdstep->timeidx;
996     while(wrdstep->timeidx > 0 &&
997 	  wrdstep->timesig[wrdstep->timeidx].time > wrdstep->at)
998 	wrdstep->timeidx--;
999     if(lastidx != wrdstep->timeidx)
1000     {
1001 	wrdstep->barstep =
1002 	    wrdstep->timesig[wrdstep->timeidx].a * wrdstep->timebase * 4
1003 		/ wrdstep->timesig[wrdstep->timeidx].b;
1004 #ifdef DEBUG
1005 	fprintf(stderr, "Time signature is changed: %d/%d barstep=%d\n",
1006 	       wrdstep->timesig[wrdstep->timeidx].a,
1007 	       wrdstep->timesig[wrdstep->timeidx].b,
1008 	       wrdstep->barstep);
1009 #endif /* DEBUG */
1010 	/* if(wrdstep->barstep < wrdstep->step) { WRD ERROR?? } */
1011     }
1012 }
1013 
wrdstep_nextbar(struct wrd_step_tracer * wrdstep)1014 static void wrdstep_nextbar(struct wrd_step_tracer *wrdstep)
1015 {
1016     wrdstep_inc(wrdstep, wrdstep->barstep - wrdstep->step);
1017 }
1018 
wrdstep_prevbar(struct wrd_step_tracer * wrdstep)1019 static void wrdstep_prevbar(struct wrd_step_tracer *wrdstep)
1020 {
1021     if(wrdstep->bar == 0)
1022 	return;
1023     wrdstep_inc(wrdstep, -wrdstep->step);
1024     wrdstep_inc(wrdstep, -wrdstep->barstep);
1025 }
1026 
wrdstep_setstep(struct wrd_step_tracer * wrdstep,int step)1027 static void wrdstep_setstep(struct wrd_step_tracer *wrdstep, int step)
1028 {
1029     if(step > wrdstep->barstep) /* Over step! */
1030 	step = wrdstep->barstep;
1031     wrdstep_inc(wrdstep, step - wrdstep->step);
1032 }
1033 
wrdstep_inc(struct wrd_step_tracer * wrdstep,int32 inc)1034 static void wrdstep_inc(struct wrd_step_tracer *wrdstep, int32 inc)
1035 {
1036     int inc_save = inc;
1037 
1038     do
1039     {
1040 	if(wrdstep->de == NULL)
1041 	{
1042 	    wrdstep->at += inc;
1043 	    break;
1044 	}
1045 	else
1046 	{
1047 	    struct wrd_delayed_event *p, *q, *qtail;
1048 	    int32 w;
1049 
1050 	    w = inc;	/* Note that: if inc < 0, w always equals inc. */
1051 	    for(p = wrdstep->de; p; p = p->next)
1052 		if(w > p->waittime)
1053 		    w = p->waittime;
1054 	    q = qtail = NULL;
1055 	    p = wrdstep->de;
1056 	    while(p)
1057 	    {
1058 		struct wrd_delayed_event *next;
1059 
1060 		p->waittime -= w;
1061 		next = p->next;
1062 		if(p->waittime <= 0)
1063 		{
1064 		    WRD_ADDEVENT(wrdstep->at, p->cmd, p->arg);
1065 		    p->next = wrdstep->free_de;
1066 		    wrdstep->free_de = p;
1067 		}
1068 		else
1069 		{
1070 		    p->next = NULL;
1071 		    if(qtail == NULL)
1072 			q = qtail = p;
1073 		    else
1074 			qtail = qtail->next = p;
1075 		}
1076 		p = next;
1077 	    }
1078 
1079 	    wrdstep->de = q;
1080 	    inc -= w;
1081 	    wrdstep->at += w;
1082 	}
1083     } while(inc > 0);
1084 
1085     wrdstep->step += inc_save;
1086     if(inc_save >= 0)
1087     {
1088 	while(wrdstep->step >= wrdstep->barstep)
1089 	{
1090 	    wrdstep->step -= wrdstep->barstep;
1091 	    wrdstep->bar++;
1092 	    wrdstep_update_forward(wrdstep);
1093 	}
1094     }
1095     else
1096     {
1097 	while(wrdstep->step < 0)
1098 	{
1099 	    wrdstep->step += wrdstep->barstep;
1100 	    wrdstep->bar--;
1101 	    wrdstep_update_backward(wrdstep);
1102 	}
1103     }
1104 }
1105 
wrdstep_wait(struct wrd_step_tracer * wrdstep,int bar,int step)1106 static void wrdstep_wait(struct wrd_step_tracer *wrdstep, int bar, int step)
1107 {
1108     bar = bar + wrdstep->offset - 1;
1109     step = wrdstep->timebase * step / 48;
1110 
1111     if(mimpi_bug_emulation_level >= 2 && wrdstep->bar > bar)
1112     {
1113 	/* ignore backward bar */
1114 	WRD_BUGEMUINFO(213);
1115     }
1116     else
1117     {
1118 	while(wrdstep->bar > bar)
1119 	    wrdstep_prevbar(wrdstep);
1120     }
1121 
1122     while(wrdstep->bar < bar)
1123 	wrdstep_nextbar(wrdstep);
1124     wrdstep_setstep(wrdstep, step);
1125 }
1126 
wrdstep_rest(struct wrd_step_tracer * wrdstep,int bar,int step)1127 static void wrdstep_rest(struct wrd_step_tracer *wrdstep, int bar, int step)
1128 {
1129     while(bar-- > 0)
1130 	wrdstep_nextbar(wrdstep);
1131     wrdstep_setstep(wrdstep, wrdstep->timebase * step / 48);
1132 }
1133 
wrd_add_lyric(int32 at,char * lyric,int len)1134 static void wrd_add_lyric(int32 at, char *lyric, int len)
1135 {
1136     MBlockList pool;
1137     char *str;
1138 
1139     init_mblock(&pool);
1140     str = (char *)new_segment(&pool, len + 1);
1141     memcpy(str, lyric, len);
1142     str[len] = '\0';
1143     WRD_ADDSTREVENT(at, WRD_LYRIC, str);
1144     reuse_mblock(&pool);
1145 }
1146 
wrd_hexval(char * hex)1147 static int wrd_hexval(char *hex)
1148 {
1149     int val, neg;
1150 
1151     if(!*hex)
1152 	return WRD_NOARG;
1153 
1154     if(*hex != '-')
1155 	neg = 0;
1156     else
1157     {
1158 	neg = 1;
1159 	hex++;
1160     }
1161     val = 0;
1162     for(;;)
1163     {
1164 	if('0' <= *hex && *hex <= '9')
1165 	    val = (val << 4) | (*hex - '0');
1166 	else if('a' <= *hex && *hex <= 'f')
1167 	    val = (val << 4) | (*hex - 'a' + 10);
1168 	else if('A' <= *hex && *hex <= 'F')
1169 	    val = (val << 4) | (*hex - 'A' + 10);
1170 	else
1171 	    break;
1172 	hex++;
1173     }
1174     return neg ? -val : val;
1175 }
1176 
wrd_eint(char * s)1177 static int wrd_eint(char *s)
1178 {
1179     if(*s == '\0')
1180 	return WRD_NOARG;
1181     if(*s != '$')
1182 	return atoi(s);
1183     return wrd_hexval(s + 1);
1184 }
1185 
wrd_atoi(char * val,int default_value)1186 static int wrd_atoi(char *val, int default_value)
1187 {
1188     while(*val && (*val < '0' || '9' < *val))
1189 	val++;
1190     return !*val ? default_value : atoi(val);
1191 }
1192 
open_wrd_file(char * fn)1193 static struct timidity_file *open_wrd_file(char *fn)
1194 {
1195     char *wrdfile, *p;
1196     MBlockList pool;
1197     struct timidity_file *tf;
1198 
1199     init_mblock(&pool);
1200     wrdfile = (char *)new_segment(&pool, strlen(fn) + 5);
1201     strcpy(wrdfile, fn);
1202     if((p = strrchr(wrdfile, '.')) == NULL)
1203     {
1204 	reuse_mblock(&pool);
1205 	return NULL;
1206     }
1207     if('A' <= p[1] && p[1] <= 'Z')
1208 	strcpy(p + 1, "WRD");
1209     else
1210 	strcpy(p + 1, "wrd");
1211 
1212     tf = open_file(wrdfile, 0, OF_NORMAL);
1213     reuse_mblock(&pool);
1214     return tf;
1215 }
1216 
wrd_readinit(void)1217 static void wrd_readinit(void)
1218 {
1219     wrd_nexttok(NULL);
1220     version = -1;
1221     lineno = 0;
1222     last_event_time = 0;
1223 }
1224 
1225 /* return 1 if line is modified */
connect_wrd_line(char * line)1226 static int connect_wrd_line(char *line)
1227 {
1228     int len;
1229 
1230     len = strlen(line);
1231     if(len > 1 && line[len - 2] != ';')
1232     {
1233 	line[len - 1] = ';';
1234 	line[len] = '\n';
1235 	line[len + 1] = '\0';
1236 	return 1;
1237     }
1238     return 0;
1239 }
1240 
mimpi_bug_emu(int cmd,char * linebuf)1241 static void mimpi_bug_emu(int cmd, char *linebuf)
1242 {
1243     if(mimpi_bug_emulation_level >= 1 && version <= 0)
1244     {
1245 	switch(wrd_bugstatus)
1246 	{
1247 	  case 0:  /* Normal state (0) */
1248 	  bugstate_0:
1249 	    if(cmd == WRD_WAIT)
1250 	    {
1251 		if(connect_wrd_line(linebuf))
1252 		    WRD_BUGEMUINFO(105);
1253 		wrd_bugstatus = 2; /* WRD_WAIT shift */
1254 	    }
1255 	    else if(mimpi_bug_emulation_level >= 2 &&
1256 		    cmd == WRD_REST)
1257 	    {
1258 		if(connect_wrd_line(linebuf))
1259 		    WRD_BUGEMUINFO(206);
1260 		wrd_bugstatus = 4; /* REST shift */
1261 	    }
1262 	    else if(mimpi_bug_emulation_level >= 8 && /* For testing */
1263 		    cmd == WRD_WMODE)
1264 		wrd_bugstatus = 3; /* WMODE shift */
1265 	    break;
1266 
1267 	  case 2: /* WRD_WAIT shift */
1268 	    if(mimpi_bug_emulation_level >= 2)
1269 	    {
1270 		if(connect_wrd_line(linebuf))
1271 		    WRD_BUGEMUINFO(212);
1272 	    }
1273 	    else if(cmd == WRD_WMODE)
1274 	    {
1275 		if(connect_wrd_line(linebuf))
1276 		    WRD_BUGEMUINFO(107);
1277 	    }
1278 	    wrd_bugstatus = 0;
1279 	    goto bugstate_0;
1280 
1281 	  case 3: /* Testing */
1282 	    if(cmd > 0 && connect_wrd_line(linebuf))
1283 		WRD_BUGEMUINFO(808);
1284 	    wrd_bugstatus = 0;
1285 	    goto bugstate_0;
1286 
1287 	  case 4: /* WRD_REST shift */
1288 	    if(connect_wrd_line(linebuf))
1289 		WRD_BUGEMUINFO(209);
1290 	    wrd_bugstatus = 0;
1291 	    goto bugstate_0;
1292 	}
1293     }
1294 }
1295 
wrd_nexttok(struct timidity_file * tf)1296 static int wrd_nexttok(struct timidity_file *tf)
1297 {
1298     int c, len;
1299     static int waitflag;
1300     static uint8 linebuf[MAXTOKLEN + 16]; /* Token value */
1301     static int tokp;
1302 
1303     if(tf == NULL)
1304     {
1305 	waitflag = 0;
1306 	tokp = 0;
1307 	linebuf[0] = '\0';
1308 	wrd_bugstatus = 0;
1309 	wrd_wmode_prev_step = 0;
1310 	return 1;
1311     }
1312 
1313     if(waitflag)
1314     {
1315 	waitflag = 0;
1316 	wrd_tok = WRD_STEP;
1317 	return 1;
1318     }
1319 
1320   retry_read:
1321     if(!linebuf[tokp])
1322     {
1323 	tokp = 0;
1324 	wrd_wmode_prev_step = 0;
1325 	lineno++;
1326 	if(tf_gets((char *)linebuf, MAXTOKLEN, tf) == NULL)
1327 	{
1328 	    wrd_tok = WRD_EOF;
1329 	    return 0;
1330 	}
1331 
1332 	len = strlen((char *)linebuf); /* 0 < len < MAXTOKLEN */
1333 	if(linebuf[len - 1] != '\n') /* linebuf must be terminated '\n' */
1334 	{
1335 	    linebuf[len] = '\n';
1336 	    linebuf[len++] = '\0';
1337 	}
1338 	else if(len > 1 &&
1339 		linebuf[len - 2] == '\r' && linebuf[len - 1] == '\n')
1340 	{
1341 	    /* CRLF => LF */
1342 	    linebuf[len - 2] = '\n';
1343 	    linebuf[len - 1] = '\0';
1344 	    len--;
1345 	}
1346     }
1347 
1348   retry_parse:
1349     if(linebuf[tokp] == WRDENDCHAR)
1350     {
1351 	wrd_tok = WRD_EOF;
1352 	return 0;
1353     }
1354 
1355     if(tokp == 0 && linebuf[tokp] != '@' && linebuf[tokp] != '^') /* Lyric */
1356     {
1357 	len = 0;
1358 	c = 0; /* Shut gcc-Wall up! */
1359 
1360 	while(len < MAXTOKLEN)
1361 	{
1362 	    c = linebuf[tokp++];
1363 	    if(c == '\n' || c == WRDENDCHAR)
1364 		break;
1365 	    wrd_tokval[len++] = c;
1366 	}
1367 	wrd_tokval[len] = '\0';
1368 	wrd_tok = WRD_LYRIC;
1369 	if(c == WRDENDCHAR)
1370 	{
1371 	    tokp = 0;
1372 	    linebuf[0] = WRDENDCHAR;
1373 	}
1374 	return 1;
1375     }
1376 
1377     /* Command */
1378 
1379     if(tokp == 0)
1380     {
1381 	int i;
1382 	/* tab to space */
1383 	for(i = 0; linebuf[i]; i++)
1384 	    if(linebuf[i] == '\t')
1385 		linebuf[i] = ' ';
1386     }
1387 
1388     /* Skip white space */
1389     for(;;)
1390     {
1391 	if(linebuf[tokp] == ' ')
1392 	    tokp++;
1393 #ifdef IS_SJIS_ZENKAKU_SPACE
1394 	else if(IS_SJIS_ZENKAKU_SPACE(linebuf + tokp))
1395 	    tokp += 2;
1396 #endif /* IS_SJIS_ZENKAKU_SPACE */
1397 	else
1398 	    break;
1399     }
1400 
1401     c = linebuf[tokp++];
1402 
1403     if(c == '\n')
1404     {
1405 	wrd_tok = WRD_STEP;
1406 	return 1;
1407     }
1408 
1409     if(c == ';')
1410     {
1411 	if(linebuf[tokp] == '\n')
1412 	{
1413 	    tokp = 0;
1414 	    linebuf[0] = '\0';
1415 	}
1416 	goto retry_read;
1417     }
1418 
1419     if(c == '@' || c == '^') /* command */
1420     {
1421 	int cmd, save_tokp;
1422 
1423 	wrd_tok = (c == '@' ? WRD_COMMAND : WRD_ECOMMAND);
1424 	save_tokp = tokp;
1425 
1426 	len = 0;
1427 #ifdef IS_SJIS_ZENKAKU_SPACE
1428 	if(IS_SJIS_ZENKAKU_SPACE(linebuf + tokp)) {
1429 	    /* nop */
1430 	    mimpi_bug_emu(-1, (char *) linebuf);
1431 	    tokp += 2;
1432 	    goto retry_parse;
1433 	}
1434 #endif /* IS_SJIS_ZENKAKU_SPACE */
1435 
1436 	if(linebuf[tokp] == ' ' ||
1437 	   linebuf[tokp] == '\n' ||
1438 	   linebuf[tokp] == WRDENDCHAR ||
1439 	   linebuf[tokp] == ';')
1440 	{
1441 	    /* nop */
1442 	    mimpi_bug_emu(-1, (char *) linebuf);
1443 	    goto retry_parse;
1444 	}
1445 
1446 	while(len < MAXTOKLEN)
1447 	{
1448 	    c = linebuf[tokp++];
1449 	    if(!isalpha(c))
1450 		break;
1451 	    wrd_tokval[len++] = toupper(c);
1452 	}
1453 	wrd_tokval[len] = '\0';
1454 	cmd = wrd_tokval[0] = cmdlookup(wrd_tokval);
1455 
1456 	if(c != '(' || cmd == 0)
1457 	{
1458 	    len = 1;
1459 	    if(cmd == 0) {
1460 		/* REM */
1461 		tokp = save_tokp;
1462 		cmd = wrd_tokval[0] = WRD_REM;
1463 	    } else {
1464 		linebuf[--tokp] = c;	/* Putback advanced char */
1465 		/* skip spaces */
1466 		while(linebuf[tokp] == ' ')
1467 		    tokp++;
1468 	    }
1469 
1470 	    if(cmd == WRD_STARTUP)
1471 	    {
1472 		while(len < MAXTOKLEN)
1473 		{
1474 		    c = linebuf[tokp++];
1475 		    if((c == ';' && linebuf[tokp] == '\n') ||
1476 		       c == '\n' ||
1477 		       c == WRDENDCHAR ||
1478 		       c == '@' ||
1479 		       c == ' ')
1480 			break;
1481 		    wrd_tokval[len++] = c;
1482 		}
1483 	    }
1484 	    else
1485 	    {
1486 		while(len < MAXTOKLEN)
1487 		{
1488 		    c = linebuf[tokp++];
1489 		    if((c == ';' && linebuf[tokp] == '\n') ||
1490 		       c == '\n' ||
1491 		       c == WRDENDCHAR)
1492 			break;
1493 		    wrd_tokval[len++] = c;
1494 		}
1495 	    }
1496 	    linebuf[--tokp] = c;	/* Putback advanced char */
1497 	    wrd_tokval[len] = '\0';
1498 	    return 1;
1499 	}
1500 
1501 	if(wrd_tok == WRD_ECOMMAND)
1502 	{
1503 	    if(cmd == WRD_PAL)
1504 		wrd_tokval[0] = WRD_ePAL;
1505 	    else if(cmd == WRD_SCROLL)
1506 		wrd_tokval[0] = WRD_eSCROLL;
1507 	}
1508 
1509 	len = 1;
1510 	while(len < MAXTOKLEN)
1511 	{
1512 	    c = linebuf[tokp++];
1513 	    if(c == ')' || c == '\n' || c == WRDENDCHAR)
1514 		break;
1515 	    wrd_tokval[len++] = c;
1516 	}
1517 	wrd_tokval[len] = '\0';
1518 	mimpi_bug_emu(wrd_tokval[0], (char *) linebuf);
1519 
1520 	if(c == WRDENDCHAR)
1521 	{
1522 	    tokp = 0;
1523 	    linebuf[0] = WRDENDCHAR;
1524 	}
1525 	return 1;
1526     }
1527 
1528     /* This is quick hack for informal WRD file */
1529     if(c == ':' && mimpi_bug_emulation_level >= 1)
1530     {
1531 	WRD_BUGEMUINFO(111);
1532 	goto retry_parse;
1533     }
1534 
1535     /* Convert error line to @REM format */
1536     linebuf[--tokp] = c;	/* Putback advanced char */
1537     len = 0;
1538     wrd_tok = WRD_COMMAND;
1539     wrd_tokval[len++] = WRD_REM;
1540 
1541     while(len < MAXTOKLEN)
1542     {
1543 	c = linebuf[tokp++];
1544 	if((c == ';' && linebuf[tokp] == '\n') ||
1545 	   c == '\n' ||
1546 	   c == WRDENDCHAR)
1547 	    break;
1548 	wrd_tokval[len++] = c;
1549     }
1550     linebuf[--tokp] = c;	/* Putback advanced char */
1551     wrd_tokval[len] = '\0';
1552     return 1;
1553 }
1554 
cmdlookup(uint8 * cmd)1555 static uint8 cmdlookup(uint8 *cmd)
1556 {
1557     switch(cmd[0])
1558     {
1559       case 'C':
1560 	return WRD_COLOR;
1561       case 'E':
1562 	if(cmd[1] == 'N')
1563 	    return WRD_END;
1564 	if(cmd[1] == 'S')
1565 	    return WRD_ESC;
1566 	return WRD_EXEC;
1567       case 'F':
1568 	if(cmd[1] == 'A')
1569 	    return WRD_FADE;
1570 	if(cmd[4] == 'M')
1571 	    return WRD_eFONTM;
1572 	if(cmd[4] == 'P')
1573 	    return WRD_eFONTP;
1574 	return WRD_eFONTR;
1575       case 'G':
1576 	if(cmd[1] == 'O')
1577 	    return WRD_GON;
1578 	if(cmd[1] == 'S')
1579 	{
1580 	    if(cmd[3] == 'R')
1581 		return WRD_GSCREEN;
1582 	    return WRD_eGSC;
1583 	}
1584 	if(cmd[3] == 'R')
1585 	    return WRD_GCIRCLE;
1586 	if(cmd[3] == 'S')
1587 	    return WRD_GCLS;
1588 	if(cmd[3] == 'I')
1589 	    return WRD_GINIT;
1590 	if(cmd[3] == 'N')
1591 	    return WRD_GLINE;
1592 	if(cmd[3] == 'D')
1593 	    return WRD_GMODE;
1594 	return WRD_GMOVE;
1595       case 'I':
1596 	return WRD_INKEY;
1597       case 'L':
1598 	if(cmd[2] == 'C')
1599 	    return WRD_LOCATE;
1600 	if(cmd[2] == 'N')
1601 	    return WRD_eLINE;
1602 	return WRD_LOOP;
1603       case 'M':
1604 	if(cmd[1] == 'A')
1605 	    return WRD_MAG;
1606 	return WRD_MIDI;
1607       case 'O':
1608 	return WRD_OFFSET;
1609       case 'P':
1610 	if(cmd[3] == '\0')
1611 	    return WRD_PAL;
1612 	if(cmd[1] == 'L')
1613 	    return WRD_PLOAD;
1614 	if(cmd[2] == 'T')
1615 	    return WRD_PATH;
1616 	if(cmd[3] == 'C')
1617 	    return WRD_PALCHG;
1618 	return WRD_PALREV;
1619       case 'R':
1620 	if(cmd[2] == 'G')
1621 	    return WRD_eREGSAVE;
1622 	if(cmd[2] == 'S')
1623 	    return WRD_REST;
1624 	if(cmd[3] == 'A')
1625 	    return WRD_REMARK;
1626 	return WRD_REM;
1627       case 'S':
1628 	if(cmd[3] == 'E')
1629 	    return WRD_SCREEN;
1630 	if(cmd[3] == 'O')
1631 	    return WRD_SCROLL;
1632 	if(cmd[3] == 'R')
1633 	    return WRD_STARTUP;
1634 	return WRD_STOP;
1635       case 'T':
1636 	if(cmd[1] == 'C')
1637 	    return WRD_TCLS;
1638 	if(cmd[1] == 'E')
1639 	    return WRD_eTEXTDOT;
1640 	if(cmd[1] == 'M')
1641 	    return WRD_eTMODE;
1642 	if(cmd[1] == 'O')
1643 	    return WRD_TON;
1644 	return WRD_eTSCRL;
1645       case 'V':
1646 	if(cmd[2] == 'O')
1647 	    return WRD_eVCOPY;
1648 	if(cmd[2] == 'G')
1649 	    return WRD_eVSGET;
1650 	return WRD_eVSRES;
1651       case 'W':
1652 	if(cmd[1] == 'A')
1653 	    return WRD_WAIT;
1654 	return WRD_WMODE;
1655       case 'X':
1656 	return WRD_eXCOPY;
1657     }
1658     return 0;
1659 }
1660 
wrd_split(char * arg,char ** argv,int maxarg)1661 static int wrd_split(char* arg, char** argv, int maxarg)
1662 {
1663     int i, j;
1664 
1665 #if defined(ABORT_AT_FATAL) || defined(DEBUG)
1666     if(maxarg < 2) {
1667 	fprintf(stderr,
1668 		"wrd_read.c: wrd_split(): maxarg must be more than 1.\n");
1669 	abort();
1670     }
1671 #endif
1672 
1673     for(i = 0; *arg && i < maxarg; i++)
1674     {
1675 	argv[i] = arg;
1676 	while(*arg && *arg != ',' && *arg != ';')
1677 	    arg++;
1678 	if(!*arg)
1679 	{
1680 	    i++;
1681 	    break;
1682 	}
1683 	*arg++ = '\0';
1684     }
1685     for(j = i; j < maxarg; j++)
1686 	argv[j] = "";
1687     return i;
1688 }
1689 
1690 #ifdef DEBUG
wrd_name_string(int cmd)1691 static char *wrd_name_string(int cmd)
1692 {
1693     switch(cmd)
1694     {
1695 #define WRDCASE(cmd) case WRD_ ## cmd: return #cmd
1696 	WRDCASE(COMMAND);
1697 	WRDCASE(ECOMMAND);
1698 	WRDCASE(STEP);
1699 	WRDCASE(LYRIC);
1700 	WRDCASE(EOF);
1701 	WRDCASE(COLOR);
1702 	WRDCASE(END);
1703 	WRDCASE(ESC);
1704 	WRDCASE(EXEC);
1705 	WRDCASE(FADE);
1706 	WRDCASE(GCIRCLE);
1707 	WRDCASE(GCLS);
1708 	WRDCASE(GINIT);
1709 	WRDCASE(GLINE);
1710 	WRDCASE(GMODE);
1711 	WRDCASE(GMOVE);
1712 	WRDCASE(GON);
1713 	WRDCASE(GSCREEN);
1714 	WRDCASE(INKEY);
1715 	WRDCASE(LOCATE);
1716 	WRDCASE(LOOP);
1717 	WRDCASE(MAG);
1718 	WRDCASE(MIDI);
1719 	WRDCASE(OFFSET);
1720 	WRDCASE(PAL);
1721 	WRDCASE(PALCHG);
1722 	WRDCASE(PALREV);
1723 	WRDCASE(PATH);
1724 	WRDCASE(PLOAD);
1725 	WRDCASE(REM);
1726 	WRDCASE(REMARK);
1727 	WRDCASE(REST);
1728 	WRDCASE(SCREEN);
1729 	WRDCASE(SCROLL);
1730 	WRDCASE(STARTUP);
1731 	WRDCASE(STOP);
1732 	WRDCASE(TCLS);
1733 	WRDCASE(TON);
1734 	WRDCASE(WAIT);
1735 	WRDCASE(WMODE);
1736 	WRDCASE(eFONTM);
1737 	WRDCASE(eFONTP);
1738 	WRDCASE(eFONTR);
1739 	WRDCASE(eGSC);
1740 	WRDCASE(eLINE);
1741 	WRDCASE(ePAL);
1742 	WRDCASE(eREGSAVE);
1743 	WRDCASE(eSCROLL);
1744 	WRDCASE(eTEXTDOT);
1745 	WRDCASE(eTMODE);
1746 	WRDCASE(eTSCRL);
1747 	WRDCASE(eVCOPY);
1748 	WRDCASE(eVSGET);
1749 	WRDCASE(eVSRES);
1750 	WRDCASE(eXCOPY);
1751 	WRDCASE(ARG);
1752 	WRDCASE(FADESTEP);
1753 	WRDCASE(OUTKEY);
1754 	WRDCASE(NL);
1755 	WRDCASE(MAGPRELOAD);
1756 	WRDCASE(PHOPRELOAD);
1757 	WRDCASE(START_SKIP);
1758 	WRDCASE(END_SKIP);
1759 	WRDCASE(NOARG);
1760 #undef WRDCASE
1761     }
1762     return "Unknown";
1763 }
1764 #endif /* DEBUG */
1765 
1766 #ifdef ENABLE_SHERRY
1767 /*******************************************************************************/
1768 #if 0
1769 /* for mac only */
1770 #pragma mark -
1771 #endif
1772 
1773 static int sherry_started;	/* 0 - before start command 0x01*/
1774 				/* 1 - after start command 0x01*/
1775 
1776 static int sry_timebase_mode = 0; /* 0 is default */
1777 
sry_getVariableLength(struct timidity_file * tf)1778 static int32 sry_getVariableLength(struct timidity_file	*tf)
1779 {
1780   int32 value= 0;
1781   int tmp;
1782   do
1783     {
1784       tmp = tf_getc(tf);
1785       if(tmp == EOF)
1786 	  return -1;
1787       value = (value << 7) + (tmp&0x7f);
1788     }while ((tmp&0x80) != 0);
1789   return value;
1790 }
1791 
sry_check_head(struct timidity_file * tf)1792 static int sry_check_head(struct timidity_file	*tf)
1793 {
1794 	char	magic[12];
1795 	uint8	version[4];
1796 
1797 	tf_read(magic, 12,1,tf);
1798 	if( memcmp(magic, "Sherry WRD\0\0", 12) ){
1799 		ctl->cmsg(CMSG_WARNING, VERB_NORMAL,
1800 			  "Sherry open::Header NG." );
1801 		return 1;
1802 	}
1803 	tf_read(version, 1, 4, tf);
1804 	ctl->cmsg(CMSG_INFO, VERB_VERBOSE,
1805 		  "Sherry WRD version: %02x %02x %02x %02x",
1806 		  version[0], version[1], version[2], version[3]);
1807 
1808 	return 0;	/*good*/
1809 }
1810 
1811 struct sry_drawtext_{
1812 	char	op;
1813 	short	v_plane;
1814 	char	mask;
1815 	char	mode;
1816 	char	fore_color;
1817 	char	back_color;
1818 	short	x;
1819 	short	y;
1820 	char	*text;
1821 };
1822 typedef struct sry_drawtext_ sry_drawtext;
1823 
sry_regist_datapacket(struct wrd_step_tracer * wrdstep,const sry_datapacket * packet)1824 static void sry_regist_datapacket( struct wrd_step_tracer* wrdstep,
1825 					const sry_datapacket* packet)
1826 {
1827     int a, b, c;
1828     int err = 0;
1829 
1830     if(datapacket == NULL)
1831     {
1832 	datapacket = (sry_datapacket *)safe_malloc(DEFAULT_DATAPACKET_LEN *
1833 						   sizeof(sry_datapacket));
1834 	datapacket_len = DEFAULT_DATAPACKET_LEN;
1835 	datapacket_cnt = 0;
1836     }
1837     else
1838     {
1839 	if(datapacket_cnt == (1<<24)-1) /* Over flow */
1840 	    err = 1;
1841 	else
1842 	{
1843 	    if(datapacket_cnt >= datapacket_len)
1844 	    {
1845 		datapacket_len *= 2;
1846 		datapacket = (sry_datapacket *)
1847 		    safe_realloc(datapacket,
1848 				 datapacket_len * sizeof(sry_datapacket));
1849 	    }
1850 	}
1851     }
1852 
1853     a = datapacket_cnt & 0xff;
1854     b = (datapacket_cnt >> 8) & 0xff;
1855     c = (datapacket_cnt >> 16) & 0xff;
1856     datapacket[datapacket_cnt] = *packet;
1857     MIDIEVENT(wrdstep->at, ME_SHERRY, a, b, c);
1858 
1859     if(err)
1860 	datapacket[datapacket_cnt].data[0] = 0xff;
1861     else
1862 	datapacket_cnt++;
1863 }
1864 
sry_read_datapacket(struct timidity_file * tf,sry_datapacket * packet)1865 static int sry_read_datapacket(struct timidity_file	*tf, sry_datapacket* packet)
1866 {
1867 	int	len;
1868 	uint8	*data;
1869 
1870 	do
1871 	{
1872 	    len = sry_getVariableLength(tf);
1873 	    if(len < 0)
1874 	    {
1875 		ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1876 			  "Warning: Too shorten Sherry WRD file.");
1877 		return 1;
1878 	    }
1879 	} while(len == 0);
1880 	data = 	(uint8 *)new_segment(&sry_pool, len + 1);
1881 	if(tf_read(data, 1, len, tf) < len)
1882 	{
1883 	    ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1884 		      "Warning: Too shorten Sherry WRD file.");
1885 	    return 1;
1886 	}
1887 	data[len]=0;
1888 	packet->len= len;
1889 	packet->data= data;
1890 	return 0;
1891 }
1892 
sry_timebase21(struct wrd_step_tracer * wrdstep,int timebase)1893 static void sry_timebase21(struct wrd_step_tracer* wrdstep, int timebase)
1894 {
1895     sherry_started=0;
1896     memset(wrdstep, 0, sizeof(struct wrd_step_tracer));
1897     init_mblock(&wrdstep->pool);
1898     wrdstep->de = wrdstep->free_de = NULL;
1899     wrdstep->timebase = timebase; /* current_file_info->divisions; */
1900     wrdstep->ntimesig = dump_current_timesig(wrdstep->timesig, MAXTIMESIG - 1);
1901     if(wrdstep->ntimesig > 0)
1902     {
1903 	wrdstep->timesig[wrdstep->ntimesig] =
1904 	    wrdstep->timesig[wrdstep->ntimesig - 1];
1905 	wrdstep->timesig[wrdstep->ntimesig].time = 0x7fffffff; /* stopper */
1906 #ifdef DEBUG
1907 	{
1908 	int i;
1909 	fprintf(stderr, "Time signatures:\n");
1910 	for(i = 0; i < wrdstep->ntimesig; i++)
1911 	    fprintf(stderr, "  %d: %d/%d\n",
1912 		   wrdstep->timesig[i].time,
1913 		   wrdstep->timesig[i].a,
1914 		   wrdstep->timesig[i].b);
1915 	}
1916 #endif /* DEBUG */
1917 	wrdstep->barstep =
1918 	    wrdstep->timesig[0].a * wrdstep->timebase * 4 / wrdstep->timesig[0].b;
1919     }
1920     else
1921 	wrdstep->barstep = 4 * wrdstep->timebase;
1922     wrdstep->step_inc = wrdstep->barstep;
1923     wrdstep->last_at = readmidi_set_track(0, 0);
1924 
1925     readmidi_set_track(0, 1);
1926     /* wrdstep.step_inc = wrdstep.timebase; */
1927 
1928 #ifdef DEBUG
1929     fprintf(stderr, "Timebase: %d, divisions:%d\n",
1930     		wrdstep->timebase, current_file_info->divisions);
1931     fprintf(stderr, "Step: %d\n", wrdstep->step_inc);
1932 #endif /* DEBUG */
1933 }
1934 
sry_timebase22(struct wrd_step_tracer * wrdstep,int mode)1935 static void sry_timebase22(struct wrd_step_tracer* wrdstep, int mode)
1936 {
1937     sry_timebase_mode = mode;
1938     if(sry_timebase_mode)
1939 	ctl->cmsg(CMSG_WARNING, VERB_NORMAL,
1940 		  "Sherry time synchronize mode is not supported");
1941 }
1942 
sry_wrdinfo(uint8 * info,int len)1943 static void sry_wrdinfo(uint8 *info, int len)
1944 {
1945     uint8 *info1, *info2, *desc;
1946     int i;
1947 
1948     /* "info1\0info2\0desc\0" */
1949     /* FIXME: Need to convert SJIS to "output_text_code" */
1950 
1951     i = 0;
1952     info1 = info;
1953     while(i < len && info[i])
1954 	i++;
1955     i++; /* skip '\0' */
1956     if(i >= len)
1957 	return;
1958     info2 = info + i;
1959     while(i < len && info[i])
1960 	i++;
1961     i++; /* skip '\0' */
1962     if(i >= len)
1963 	return;
1964     desc = info + i;
1965 
1966     ctl->cmsg(CMSG_INFO, VERB_VERBOSE,
1967 	      "Sherry WRD: %s: %s: %s", info1, info2, desc);
1968 }
1969 
sry_show_debug(uint8 * data)1970 static void sry_show_debug(uint8 *data)
1971 {
1972     switch(data[0])
1973     {
1974       case 0x71: /* Compiler name */
1975 	if(data[1])
1976 	    ctl->cmsg(CMSG_INFO, VERB_NOISY,
1977 		      "Sherry WRD Compiler: %s", data + 1);
1978 	break;
1979       case 0x72: /* Source Name */
1980 	if(data[1])
1981 	    ctl->cmsg(CMSG_INFO, VERB_NOISY,
1982 		      "Sherry WRD Compiled from %s", data + 1);
1983 	break;
1984       case 0x7f: /* Compiler Private */
1985 	break;
1986     }
1987 }
1988 
sry_read_headerblock(struct wrd_step_tracer * wrdstep,struct timidity_file * tf)1989 static void sry_read_headerblock(struct wrd_step_tracer* wrdstep,
1990 					struct timidity_file *tf)
1991 {
1992 	sry_datapacket	packet;
1993 	int err;
1994 
1995 	packet.len = 1;
1996 	packet.data = (uint8 *)new_segment(&sry_pool, 1);
1997 	packet.data[0] = 0x01;
1998 	sry_regist_datapacket(wrdstep , &packet);
1999 
2000 	for(;;){
2001 		err= sry_read_datapacket(tf, &packet);
2002 		if( err ) break;
2003 		sry_regist_datapacket(wrdstep , &packet);
2004 		switch(packet.data[0])
2005 		{
2006 		  case 0x00: /* end of header */
2007 		    return;
2008 		  case 0x20:
2009 		    if( mimpi_bug_emulation_level >= 1 ){
2010 		      sry_timebase21(wrdstep, SRY_GET_SHORT(packet.data+1));
2011 		    }
2012 		    break;
2013 		  case 0x21:
2014 		    sry_timebase21(wrdstep, SRY_GET_SHORT(packet.data+1));
2015 		    break;
2016 		  case 0x22:
2017 		    sry_timebase22(wrdstep, packet.data[1]);
2018 		    break;
2019 		  case 0x61:
2020 		    sry_wrdinfo(packet.data + 1, packet.len - 1);
2021 		    break;
2022 		  default:
2023 		    if((packet.data[0] & 0x70) == 0x70)
2024 			sry_show_debug(packet.data);
2025 		    break;
2026 		}
2027 	}
2028 }
2029 
sry_read_datablock(struct wrd_step_tracer * wrdstep,struct timidity_file * tf)2030 static void sry_read_datablock(struct wrd_step_tracer* wrdstep,
2031 				  struct timidity_file	*tf)
2032 {
2033     sry_datapacket  packet;
2034     int		    delta_time; /*, cur_time=0; */
2035     int		    err;
2036     int		    need_update;
2037 
2038     need_update = 0;
2039     for(;;){
2040 		delta_time= sry_getVariableLength(tf);
2041 		if(delta_time > 0 && need_update)
2042 		{
2043 		    WRD_ADDEVENT(wrdstep->at, WRD_SHERRY_UPDATE, WRD_NOARG);
2044 		    need_update = 0;
2045 		}
2046 		err = sry_read_datapacket(tf, &packet);
2047 		if( err ) break;
2048 		/* cur_time =+ delta_time;*/
2049 		/* wrdstep_wait(wrdstep, delta_time,0); */
2050 		/* wrdstep_setstep(wrdstep, delta_time); */
2051 
2052 		if( sherry_started && delta_time ){
2053 		    wrdstep_inc(wrdstep,
2054 				delta_time*current_file_info->divisions
2055 				/wrdstep->timebase);
2056 		}
2057 
2058 		if( packet.data[0]==0x01 ){
2059 			sherry_started=1;
2060 			continue;
2061 		} else if( (packet.data[0]&0x70) == 0x70) {
2062 		    sry_show_debug(packet.data);
2063 		}
2064 
2065 		sry_regist_datapacket(wrdstep , &packet);
2066 		if(packet.data[0] == 0x31 ||
2067 		   packet.data[0] == 0x35 ||
2068 		   packet.data[0] == 0x36)
2069 		    need_update = 1;
2070 
2071 		if( packet.data[0] == 0x00 ) break;
2072     }
2073     if(need_update)
2074     {
2075 	WRD_ADDEVENT(wrdstep->at, WRD_SHERRY_UPDATE, WRD_NOARG);
2076 	need_update = 0;
2077     }
2078 }
2079 
import_sherrywrd_file(const char * fn)2080 static int import_sherrywrd_file(const char * fn)
2081 {
2082 	char	sry_fn[256];
2083 	char	*cp;
2084 	struct timidity_file	*tf;
2085     struct wrd_step_tracer wrdstep;
2086 
2087 	strncpy(sry_fn, fn, sizeof(sry_fn));
2088 	cp=strrchr(sry_fn, '.');
2089 	if( cp==0 ) return 0;
2090 
2091 	strncpy(cp+1, "sry", sizeof(sry_fn) - (cp - sry_fn) - 1);
2092 	tf= open_file( sry_fn, 0, OF_NORMAL);
2093 	if( tf==NULL ) return 0;
2094 	if( sry_check_head(tf)!=0 ) return 0;
2095 	ctl->cmsg(CMSG_INFO, VERB_NORMAL,
2096 		  "%s: reading sherry data...", sry_fn);
2097 
2098 	wrd_readinit();
2099 	memset(&wrdstep, 0, sizeof(wrdstep));
2100 
2101 /**********************/
2102 /*    MIDIEVENT(0, ME_SHERRY_START, 0, 0, 0); */
2103     sry_read_headerblock( &wrdstep, tf);
2104     sry_read_datablock( &wrdstep, tf);
2105 
2106 /*  end_of_wrd: */
2107     while(wrdstep.de)
2108     {
2109 	wrdstep_nextbar(&wrdstep);
2110     }
2111     reuse_mblock(&wrdstep.pool);
2112     close_file(tf);
2113 #ifdef DEBUG
2114     fflush(stderr);
2115 #endif /* DEBUG */
2116     return 1;
2117 }
2118 
2119 #endif /*ENABLE_SHERRY*/
2120