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