1 //
2 // GOATTRACKER v2 table editor
3 //
4
5 #define GTABLE_C
6
7 #include "goattrk2.h"
8
9 unsigned char ltablecopybuffer[MAX_TABLELEN];
10 unsigned char rtablecopybuffer[MAX_TABLELEN];
11 int tablecopyrows = 0;
12
13 int etview[MAX_TABLES];
14 int etnum;
15 int etpos;
16 int etcolumn;
17 int etlock = 1;
18 int etmarknum = -1;
19 int etmarkstart;
20 int etmarkend;
21
tablecommands(void)22 void tablecommands(void)
23 {
24 int c;
25
26 switch(rawkey)
27 {
28 case KEY_Q:
29 if ((shiftpressed) && (etnum == STBL))
30 {
31 int speed = (ltable[etnum][etpos] << 8) | rtable[etnum][etpos];
32 speed *= 34716;
33 speed /= 32768;
34 if (speed > 65535) speed = 65535;
35
36 ltable[etnum][etpos] = speed >> 8;
37 rtable[etnum][etpos] = speed & 0xff;
38 }
39 break;
40
41 case KEY_A:
42 if ((shiftpressed) && (etnum == STBL))
43 {
44 int speed = (ltable[etnum][etpos] << 8) | rtable[etnum][etpos];
45 speed *= 30929;
46 speed /= 32768;
47
48 ltable[etnum][etpos] = speed >> 8;
49 rtable[etnum][etpos] = speed & 0xff;
50 }
51 break;
52
53 case KEY_W:
54 if ((shiftpressed) && (etnum == STBL))
55 {
56 int speed = (ltable[etnum][etpos] << 8) | rtable[etnum][etpos];
57 speed *= 2;
58 if (speed > 65535) speed = 65535;
59
60 ltable[etnum][etpos] = speed >> 8;
61 rtable[etnum][etpos] = speed & 0xff;
62 }
63 if ((shiftpressed) && ((etnum == PTBL) || (etnum == FTBL)) && (ltable[etnum][etpos] < 0x80))
64 {
65 int speed = (signed char)(rtable[etnum][etpos]);
66 speed *= 2;
67
68 if (speed > 127) speed = 127;
69 if (speed < -128) speed = -128;
70 rtable[etnum][etpos] = speed;
71 }
72 break;
73
74 case KEY_S:
75 if ((shiftpressed) && (etnum == STBL))
76 {
77 int speed = (ltable[etnum][etpos] << 8) | rtable[etnum][etpos];
78 speed /= 2;
79
80 ltable[etnum][etpos] = speed >> 8;
81 rtable[etnum][etpos] = speed & 0xff;
82 }
83 if ((shiftpressed) && ((etnum == PTBL) || (etnum == FTBL)) && (ltable[etnum][etpos] < 0x80))
84 {
85 int speed = (signed char)(rtable[etnum][etpos]);
86 speed /= 2;
87
88 rtable[etnum][etpos] = speed;
89 }
90 break;
91
92 case KEY_SPACE:
93 if (!shiftpressed)
94 playtestnote(FIRSTNOTE + epoctave * 12, einum, epchn);
95 else
96 releasenote(epchn);
97 break;
98
99 case KEY_RIGHT:
100 etcolumn++;
101 if (etcolumn > 3)
102 {
103 etpos -= etview[etnum];
104 etcolumn = 0;
105 etnum++;
106 if (etnum >= MAX_TABLES) etnum = 0;
107 etpos += etview[etnum];
108 }
109 if (shiftpressed) etmarknum = -1;
110 break;
111
112 case KEY_LEFT:
113 etcolumn--;
114 if (etcolumn < 0)
115 {
116 etpos -= etview[etnum];
117 etcolumn = 3;
118 etnum--;
119 if (etnum < 0) etnum = MAX_TABLES - 1;
120 etpos += etview[etnum];
121 }
122 if (shiftpressed) etmarknum = -1;
123 break;
124
125 case KEY_HOME:
126 while (etpos != 0) tableup();
127 break;
128
129 case KEY_END:
130 while (etpos != MAX_TABLELEN-1) tabledown();
131 break;
132
133 case KEY_PGUP:
134 for (c = 0; c < PGUPDNREPEAT; c++) tableup();
135 break;
136
137 case KEY_PGDN:
138 for (c = 0; c < PGUPDNREPEAT; c++) tabledown();
139 break;
140
141 case KEY_UP:
142 tableup();
143 break;
144
145 case KEY_DOWN:
146 tabledown();
147 break;
148
149 case KEY_X:
150 case KEY_C:
151 if (shiftpressed)
152 {
153 if (etmarknum != -1)
154 {
155 int d = 0;
156 if (etmarkstart <= etmarkend)
157 {
158 for (c = etmarkstart; c <= etmarkend; c++)
159 {
160 ltablecopybuffer[d] = ltable[etmarknum][c];
161 rtablecopybuffer[d] = rtable[etmarknum][c];
162 if (rawkey == KEY_X)
163 {
164 ltable[etmarknum][c] = 0;
165 rtable[etmarknum][c] = 0;
166 }
167 d++;
168 }
169 }
170 else
171 {
172 for (c = etmarkend; c <= etmarkstart; c++)
173 {
174 ltablecopybuffer[d] = ltable[etmarknum][c];
175 rtablecopybuffer[d] = rtable[etmarknum][c];
176 if (rawkey == KEY_X)
177 {
178 ltable[etmarknum][c] = 0;
179 rtable[etmarknum][c] = 0;
180 }
181 d++;
182 }
183 }
184 tablecopyrows = d;
185 }
186 etmarknum = -1;
187 }
188 break;
189
190 case KEY_V:
191 if (shiftpressed)
192 {
193 if (tablecopyrows)
194 {
195 for (c = 0; c < tablecopyrows; c++)
196 {
197 ltable[etnum][etpos] = ltablecopybuffer[c];
198 rtable[etnum][etpos] = rtablecopybuffer[c];
199 etpos++;
200 if (etpos >= MAX_TABLELEN) etpos = MAX_TABLELEN-1;
201 }
202 }
203 }
204 break;
205
206 case KEY_O:
207 if (shiftpressed) optimizetable(etnum);
208 break;
209
210 case KEY_U:
211 if (shiftpressed)
212 {
213 etlock ^= 1;
214 validatetableview();
215 }
216 break;
217
218 case KEY_R:
219 if (etnum == WTBL)
220 {
221 if (ltable[etnum][etpos] != 0xff)
222 {
223 // Convert absolute pitch to relative pitch or vice versa
224 int basenote = epoctave * 12;
225 int note = rtable[etnum][etpos];
226
227 if (note >= 0x80)
228 {
229 note -= basenote;
230 note &= 0x7f;
231 }
232 else
233 {
234 note += basenote;
235 note |= 0x80;
236 }
237
238 rtable[etnum][etpos] = note;
239 }
240 }
241
242 case KEY_L:
243 if (etnum == PTBL)
244 {
245 int c;
246 int currentpulse = -1;
247 int targetpulse = ltable[etnum][etpos] << 4;
248 int speed = rtable[etnum][etpos];
249 int time;
250 int steps;
251
252 if (!speed) break;
253
254 // Follow the chain of pulse commands backwards to the nearest set command so we know what current pulse is
255 for (c = etpos-1; c >= 0; c--)
256 {
257 if (ltable[etnum][c] == 0xff) break;
258 if (ltable[etnum][c] >= 0x80)
259 {
260 currentpulse = (ltable[etnum][c] << 8) | rtable[etnum][c];
261 currentpulse &= 0xfff;
262 break;
263 }
264 }
265 if (currentpulse == -1) break;
266
267 // Then follow the chain of modulation steps
268 for (; c < etpos; c++)
269 {
270 if (ltable[etnum][c] < 0x80)
271 {
272 currentpulse += ltable[etnum][c] * (rtable[etnum][c] & 0xff);
273 if (rtable[etnum][c] >= 0x80) currentpulse -= 256 * ltable[etnum][c];
274 currentpulse &= 0xfff;
275 }
276 }
277
278 time = abs(targetpulse - currentpulse) / speed;
279 if (speed < 128)
280 steps = (time + 126) / 127;
281 else
282 steps = time;
283
284 if (!steps) break;
285 if (etpos + steps > MAX_TABLELEN) break;
286 if (targetpulse < currentpulse) speed = -speed;
287
288 // Make room in the table
289 for (c = steps; c > 1; c--) inserttable(etnum, etpos, 1);
290
291 while (time)
292 {
293 if (abs(speed) < 128)
294 {
295 if (time < 127) ltable[etnum][etpos] = time;
296 else ltable[etnum][etpos] = 127;
297 rtable[etnum][etpos] = speed;
298 time -= ltable[etnum][etpos];
299 etpos++;
300 }
301 else
302 {
303 currentpulse += speed;
304 ltable[etnum][etpos] = 0x80 | ((currentpulse >> 8) & 0xf);
305 rtable[etnum][etpos] = currentpulse & 0xff;
306 time--;
307 etpos++;
308 }
309 }
310 }
311 if (etnum == FTBL)
312 {
313 int c;
314 int currentfilter = -1;
315 int targetfilter = ltable[etnum][etpos];
316 int speed = rtable[etnum][etpos] & 0x7f;
317 int time;
318 int steps;
319
320 if (!speed) break;
321
322 // Follow the chain of filter commands backwards to the nearest set command so we know what current pulse is
323 for (c = etpos-1; c >= 0; c--)
324 {
325 if (ltable[etnum][c] == 0xff) break;
326 if (ltable[etnum][c] == 0x00)
327 {
328 currentfilter = rtable[etnum][c];
329 break;
330 }
331 }
332 if (currentfilter == -1) break;
333
334 // Then follow the chain of modulation steps
335 for (; c < etpos; c++)
336 {
337 if (ltable[etnum][c] < 0x80)
338 {
339 currentfilter += ltable[etnum][c] * rtable[etnum][c];
340 currentfilter &= 0xff;
341 }
342 }
343
344 time = abs(targetfilter - currentfilter) / speed;
345 steps = (time + 126) / 127;
346 if (!steps) break;
347 if (etpos + steps > MAX_TABLELEN) break;
348 if (targetfilter < currentfilter) speed = -speed;
349
350 // Make room in the table
351 for (c = steps; c > 1; c--) inserttable(etnum, etpos, 1);
352
353 while (time)
354 {
355 if (time < 127) ltable[etnum][etpos] = time;
356 else ltable[etnum][etpos] = 127;
357 rtable[etnum][etpos] = speed;
358 time -= ltable[etnum][etpos];
359 etpos++;
360 }
361 }
362 break;
363
364 case KEY_N:
365 if (shiftpressed)
366 {
367 switch (etnum)
368 {
369 // Negate pulse or filter speed
370 case FTBL:
371 if (!ltable[etnum][etpos]) break;
372 case PTBL:
373 if (ltable[etnum][etpos] < 0x80)
374 rtable[etnum][etpos] = (rtable[etnum][etpos] ^ 0xff) + 1;
375 break;
376
377 // Negate relative note
378 case WTBL:
379 if ((ltable[etnum][etpos] != 0xff) && (rtable[etnum][etpos] < 0x80))
380 rtable[etnum][etpos] = (0x80 - rtable[etnum][etpos]) & 0x7f;
381 break;
382 }
383 }
384 break;
385
386 case KEY_DEL:
387 deletetable(etnum, etpos);
388 break;
389
390 case KEY_INS:
391 inserttable(etnum, etpos, shiftpressed);
392 break;
393
394 case KEY_ENTER:
395 if (etnum == WTBL)
396 {
397 int table = -1;
398 int mstmode = MST_PORTAMENTO;
399
400 switch (ltable[etnum][etpos])
401 {
402 case WAVECMD + CMD_PORTAUP:
403 case WAVECMD + CMD_PORTADOWN:
404 case WAVECMD + CMD_TONEPORTA:
405 table = STBL;
406 break;
407
408 case WAVECMD + CMD_VIBRATO:
409 table = STBL;
410 mstmode = finevibrato;
411 break;
412
413 case WAVECMD + CMD_FUNKTEMPO:
414 table = STBL;
415 mstmode = MST_FUNKTEMPO;
416 break;
417
418 case WAVECMD + CMD_SETPULSEPTR:
419 table = PTBL;
420 break;
421
422 case WAVECMD + CMD_SETFILTERPTR:
423 table = FTBL;
424 break;
425 }
426 switch (table)
427 {
428 default:
429 editmode = EDIT_INSTRUMENT;
430 eipos = etnum + 2;
431 return;
432
433 case STBL:
434 if (rtable[etnum][etpos])
435 {
436 if (!shiftpressed)
437 {
438 gototable(STBL, rtable[etnum][etpos] - 1);
439 return;
440 }
441 else
442 {
443 int oldeditpos = etpos;
444 int oldeditcolumn = etcolumn;
445 int pos = makespeedtable(rtable[etnum][etpos], mstmode, 1);
446 gototable(WTBL, oldeditpos);
447 etcolumn = oldeditcolumn;
448
449 rtable[etnum][etpos] = pos + 1;
450 return;
451 }
452 }
453 else
454 {
455 int pos = findfreespeedtable();
456 if (pos >= 0)
457 {
458 rtable[etnum][etpos] = pos + 1;
459 gototable(STBL, pos);
460 return;
461 }
462 }
463 break;
464
465 case PTBL:
466 case FTBL:
467 if (rtable[etnum][etpos])
468 {
469 gototable(table, rtable[etnum][etpos] - 1);
470 return;
471 }
472 else
473 {
474 if (shiftpressed)
475 {
476 int pos = gettablelen(table);
477 if (pos >= MAX_TABLELEN-1) pos = MAX_TABLELEN - 1;
478 rtable[etnum][etpos] = pos + 1;
479 gototable(table, pos);
480 return;
481 }
482 }
483 }
484 }
485 else
486 {
487 editmode = EDIT_INSTRUMENT;
488 eipos = etnum + 2;
489 return;
490 }
491 break;
492
493 case KEY_APOST2:
494 if (shiftpressed)
495 {
496 etpos -= etview[etnum];
497 etnum--;
498 if (etnum < 0) etnum = MAX_TABLES-1;
499 etpos += etview[etnum];
500 }
501 else
502 {
503 etpos -= etview[etnum];
504 etnum++;
505 if (etnum >= MAX_TABLES) etnum = 0;
506 etpos += etview[etnum];
507 }
508 }
509
510 if (hexnybble >= 0)
511 {
512 switch(etcolumn)
513 {
514 case 0:
515 ltable[etnum][etpos] &= 0x0f;
516 ltable[etnum][etpos] |= hexnybble << 4;
517 break;
518 case 1:
519 ltable[etnum][etpos] &= 0xf0;
520 ltable[etnum][etpos] |= hexnybble;
521 break;
522 case 2:
523 rtable[etnum][etpos] &= 0x0f;
524 rtable[etnum][etpos] |= hexnybble << 4;
525 break;
526 case 3:
527 rtable[etnum][etpos] &= 0xf0;
528 rtable[etnum][etpos] |= hexnybble;
529 break;
530 }
531 etcolumn++;
532 if (etcolumn > 3)
533 {
534 etcolumn = 0;
535 etpos++;
536 if (etpos >= MAX_TABLELEN) etpos = MAX_TABLELEN-1;
537 }
538 }
539
540 validatetableview();
541 }
542
deletetable(int num,int pos)543 void deletetable(int num, int pos)
544 {
545 int c, d;
546
547 // Shift tablepointers in instruments
548 for (c = 1; c < MAX_INSTR; c++)
549 {
550 if ((instr[c].ptr[num]-1) > pos) instr[c].ptr[num]--;
551 }
552
553 // Shift tablepointers in wavetable commands
554 for (c = 0; c < MAX_TABLELEN; c++)
555 {
556 if ((ltable[WTBL][c] >= WAVECMD) && (ltable[WTBL][c] <= WAVELASTCMD))
557 {
558 int cmd = ltable[WTBL][c] & 0xf;
559
560 if (num < STBL)
561 {
562 if (cmd == CMD_SETWAVEPTR+num)
563 {
564 if ((rtable[WTBL][c]-1) > pos) rtable[WTBL][c]--;
565 }
566 }
567 else
568 {
569 if ((cmd == CMD_FUNKTEMPO) || ((cmd >= CMD_PORTAUP) && (cmd <= CMD_VIBRATO)))
570 {
571 if ((rtable[WTBL][c]-1) > pos) rtable[WTBL][c]--;
572 }
573 }
574 }
575 }
576
577 // Shift tablepointers in patterns
578 for (c = 0; c < MAX_PATT; c++)
579 {
580 for (d = 0; d <= MAX_PATTROWS; d++)
581 {
582 if (num < STBL)
583 {
584 if (pattern[c][d*4+2] == CMD_SETWAVEPTR+num)
585 {
586 if ((pattern[c][d*4+3]-1) > pos) pattern[c][d*4+3]--;
587 }
588 }
589 else
590 {
591 if ((pattern[c][d*4+2] == CMD_FUNKTEMPO) ||
592 ((pattern[c][d*4+2] >= CMD_PORTAUP) && (pattern[c][d*4+2] <= CMD_VIBRATO)))
593 {
594 if ((pattern[c][d*4+3]-1) > pos) pattern[c][d*4+3]--;
595 }
596 }
597 }
598 }
599
600 // Shift jumppointers in the table itself
601 for (c = 0; c < MAX_TABLELEN; c++)
602 {
603 if (num != STBL)
604 {
605 if (ltable[num][c] == 0xff)
606 if ((rtable[num][c]-1) > pos) rtable[num][c]--;
607 }
608 }
609
610 for (c = pos; c < MAX_TABLELEN; c++)
611 {
612 if (c+1 < MAX_TABLELEN)
613 {
614 ltable[num][c] = ltable[num][c+1];
615 rtable[num][c] = rtable[num][c+1];
616 }
617 else
618 {
619 ltable[num][c] = 0;
620 rtable[num][c] = 0;
621 }
622 }
623 }
624
inserttable(int num,int pos,int mode)625 void inserttable(int num, int pos, int mode)
626 {
627 int c, d;
628
629 // Shift tablepointers in instruments
630 for (c = 1; c < MAX_INSTR; c++)
631 {
632 if (!mode)
633 {
634 if ((instr[c].ptr[num]-1) >= pos) instr[c].ptr[num]++;
635 }
636 else
637 {
638 if ((instr[c].ptr[num]-1) > pos) instr[c].ptr[num]++;
639 }
640 }
641
642 // Shift tablepointers in wavetable commands
643 for (c = 0; c < MAX_TABLELEN; c++)
644 {
645 if ((ltable[WTBL][c] >= WAVECMD) && (ltable[WTBL][c] <= WAVELASTCMD))
646 {
647 int cmd = ltable[WTBL][c] & 0xf;
648
649 if (num < STBL)
650 {
651 if (cmd == CMD_SETWAVEPTR+num)
652 {
653 if (!mode)
654 {
655 if ((rtable[WTBL][c]-1) >= pos) rtable[WTBL][c]++;
656 }
657 else
658 {
659 if ((rtable[WTBL][c]-1) > pos) rtable[WTBL][c]++;
660 }
661 }
662 }
663 else
664 {
665 if ((cmd == CMD_FUNKTEMPO) || ((cmd >= CMD_PORTAUP) && (cmd <= CMD_VIBRATO)))
666 {
667 if (!mode)
668 {
669 if ((rtable[WTBL][c]-1) >= pos) rtable[WTBL][c]++;
670 }
671 else
672 {
673 if ((rtable[WTBL][c]-1) > pos) rtable[WTBL][c]++;
674 }
675 }
676 }
677 }
678 }
679
680
681 // Shift tablepointers in patterns
682 for (c = 0; c < MAX_PATT; c++)
683 {
684 for (d = 0; d <= MAX_PATTROWS; d++)
685 {
686 if (num < STBL)
687 {
688 if (pattern[c][d*4+2] == CMD_SETWAVEPTR+num)
689 {
690 if (!mode)
691 {
692 if ((pattern[c][d*4+3]-1) >= pos) pattern[c][d*4+3]++;
693 }
694 else
695 {
696 if ((pattern[c][d*4+3]-1) > pos) pattern[c][d*4+3]++;
697 }
698 }
699 }
700 else
701 {
702 if ((pattern[c][d*4+2] == CMD_FUNKTEMPO) ||
703 ((pattern[c][d*4+2] >= CMD_PORTAUP) && (pattern[c][d*4+2] <= CMD_VIBRATO)))
704 {
705 if (!mode)
706 {
707 if ((pattern[c][d*4+3]-1) >= pos) pattern[c][d*4+3]++;
708 }
709 else
710 {
711 if ((pattern[c][d*4+3]-1) > pos) pattern[c][d*4+3]++;
712 }
713 }
714 }
715 }
716 }
717
718 // Shift jumppointers in the table itself
719 if (num != STBL)
720 {
721 for (c = 0; c < MAX_TABLELEN; c++)
722 {
723 if (ltable[num][c] == 0xff)
724 {
725 if (!mode)
726 {
727 if ((rtable[num][c]-1) >= pos) rtable[num][c]++;
728 }
729 else
730 {
731 if ((rtable[num][c]-1) > pos) rtable[num][c]++;
732 }
733 }
734 }
735 }
736
737 for (c = MAX_TABLELEN-1; c >= pos; c--)
738 {
739 if (c > pos)
740 {
741 ltable[num][c] = ltable[num][c-1];
742 rtable[num][c] = rtable[num][c-1];
743 }
744 else
745 {
746 if ((num == WTBL) && (mode == 1))
747 {
748 ltable[num][c] = 0xe9;
749 rtable[num][c] = 0;
750 }
751 else
752 {
753 ltable[num][c] = 0;
754 rtable[num][c] = 0;
755 }
756 }
757 }
758 }
759
gettablelen(int num)760 int gettablelen(int num)
761 {
762 int c;
763
764 for (c = MAX_TABLELEN-1; c >= 0; c--)
765 {
766 if (ltable[num][c] | rtable[num][c]) break;
767 }
768 return c+1;
769 }
770
gettablepartlen(int num,int pos)771 int gettablepartlen(int num, int pos)
772 {
773 int c;
774
775 if (pos < 0) return 0;
776 if (num == STBL) return 1;
777
778 for (c = pos; c < MAX_TABLELEN; c++)
779 {
780 if (ltable[num][c] == 0xff)
781 {
782 c++;
783 break;
784 }
785 }
786 return c-pos;
787 }
788
optimizetable(int num)789 void optimizetable(int num)
790 {
791 int c,d;
792
793 memset(tableused, 0, sizeof tableused);
794
795 for (c = 0; c < MAX_PATT; c++)
796 {
797 for (d = 0; d < pattlen[c]; d++)
798 {
799 if ((pattern[c][d*4+2] >= CMD_SETWAVEPTR) && (pattern[c][d*4+2] <= CMD_SETFILTERPTR))
800 exectable(pattern[c][d*4+2] - CMD_SETWAVEPTR, pattern[c][d*4+3]);
801 if ((pattern[c][d*4+2] >= CMD_PORTAUP) && (pattern[c][d*4+2] <= CMD_VIBRATO))
802 exectable(STBL, pattern[c][d*4+3]);
803 if (pattern[c][d*4+2] == CMD_FUNKTEMPO)
804 exectable(STBL, pattern[c][d*4+3]);
805 }
806 }
807
808 for (c = 0; c < MAX_INSTR; c++)
809 {
810 for (d = 0; d < MAX_TABLES; d++)
811 {
812 exectable(d, instr[c].ptr[d]);
813 }
814 }
815
816 for (c = 0; c < MAX_TABLELEN; c++)
817 {
818 if (tableused[WTBL][c+1])
819 {
820 if ((ltable[WTBL][c] >= WAVECMD) && (ltable[WTBL][c] <= WAVELASTCMD))
821 {
822 d = -1;
823
824 switch(ltable[WTBL][c] - WAVECMD)
825 {
826 case CMD_PORTAUP:
827 case CMD_PORTADOWN:
828 case CMD_TONEPORTA:
829 case CMD_VIBRATO:
830 d = STBL;
831 break;
832
833 case CMD_SETPULSEPTR:
834 d = PTBL;
835 break;
836
837 case CMD_SETFILTERPTR:
838 d = FTBL;
839 break;
840 }
841
842 if (d != -1) exectable(d, rtable[WTBL][c]);
843 }
844 }
845 }
846
847 for (c = MAX_TABLELEN-1; c >= 0; c--)
848 {
849 if ((ltable[num][c]) || (rtable[num][c])) break;
850 }
851 for (; c >= 0; c--)
852 {
853 if (!tableused[num][c+1]) deletetable(num, c);
854 }
855 }
856
makespeedtable(unsigned data,int mode,int makenew)857 int makespeedtable(unsigned data, int mode, int makenew)
858 {
859 int c;
860 unsigned char l = 0, r = 0;
861
862 if (!data) return -1;
863
864 switch (mode)
865 {
866 case MST_NOFINEVIB:
867 l = (data & 0xf0) >> 4;
868 r = (data & 0x0f) << 4;
869 break;
870
871 case MST_FINEVIB:
872 l = (data & 0x70) >> 4;
873 r = ((data & 0x0f) << 4) | ((data & 0x80) >> 4);
874 break;
875
876 case MST_FUNKTEMPO:
877 l = (data & 0xf0) >> 4;
878 r = data & 0x0f;
879 break;
880
881 case MST_PORTAMENTO:
882 l = (data << 2) >> 8;
883 r = (data << 2) & 0xff;
884 break;
885
886 case MST_RAW:
887 r = data & 0xff;
888 l = data >> 8;
889 break;
890 }
891
892 if (makenew == 0)
893 {
894 for (c = 0; c < MAX_TABLELEN; c++)
895 {
896 if ((ltable[STBL][c] == l) && (rtable[STBL][c] == r))
897 return c;
898 }
899 }
900
901 for (c = 0; c < MAX_TABLELEN; c++)
902 {
903 if ((!ltable[STBL][c]) && (!rtable[STBL][c]))
904 {
905 ltable[STBL][c] = l;
906 rtable[STBL][c] = r;
907
908 settableview(STBL, c);
909 return c;
910 }
911 }
912 return -1;
913 }
914
deleteinstrtable(int i)915 void deleteinstrtable(int i)
916 {
917 int c,d;
918 int eraseok = 1;
919
920 for (c = 0; c < MAX_TABLES; c++)
921 {
922 if (instr[i].ptr[c])
923 {
924 int pos = instr[i].ptr[c]-1;
925 int len = gettablepartlen(c, pos);
926
927 // Check that this table area isn't used by another instrument
928 for (d = 1; d < MAX_INSTR; d++)
929 {
930 if ((d != i) && (instr[d].ptr[c]))
931 {
932 int cmppos = instr[d].ptr[c]-1;
933 if ((cmppos >= pos) && (cmppos < pos+len)) eraseok = 0;
934 }
935 }
936 if (eraseok)
937 while (len--) deletetable(c, pos);
938 }
939 }
940 }
941
gototable(int num,int pos)942 void gototable(int num, int pos)
943 {
944 editmode = EDIT_TABLES;
945 settableview(num, pos);
946 }
947
settableview(int num,int pos)948 void settableview(int num, int pos)
949 {
950 etnum = num;
951 etcolumn = 0;
952 etpos = pos;
953
954 validatetableview();
955 }
956
settableviewfirst(int num,int pos)957 void settableviewfirst(int num, int pos)
958 {
959 etview[num] = pos;
960 settableview(num, pos);
961 }
validatetableview(void)962 void validatetableview(void)
963 {
964 if (etpos - etview[etnum] < 0)
965 etview[etnum] = etpos;
966 if (etpos - etview[etnum] >= VISIBLETABLEROWS)
967 etview[etnum] = etpos - VISIBLETABLEROWS + 1;
968
969 // Table view lock?
970 if (etlock)
971 {
972 int c;
973
974 for (c = 0; c < MAX_TABLES; c++) etview[c] = etview[etnum];
975 }
976 }
977
tableup(void)978 void tableup(void)
979 {
980 if (shiftpressed)
981 {
982 if ((etmarknum != etnum) || (etpos != etmarkend))
983 {
984 etmarknum = etnum;
985 etmarkstart = etmarkend = etpos;
986 }
987 }
988 etpos--;
989 if (etpos < 0) etpos = 0;
990 if (shiftpressed) etmarkend = etpos;
991 }
992
tabledown(void)993 void tabledown(void)
994 {
995 if (shiftpressed)
996 {
997 if ((etmarknum != etnum) || (etpos != etmarkend))
998 {
999 etmarknum = etnum;
1000 etmarkstart = etmarkend = etpos;
1001 }
1002 }
1003 etpos++;
1004 if (etpos >= MAX_TABLELEN) etpos = MAX_TABLELEN-1;
1005 if (shiftpressed) etmarkend = etpos;
1006 }
1007
exectable(int num,int ptr)1008 void exectable(int num, int ptr)
1009 {
1010 // Jump error check
1011 if ((num != STBL) && (ptr) && (ptr <= MAX_TABLELEN))
1012 {
1013 if (ltable[num][ptr-1] == 0xff)
1014 {
1015 tableerror = TYPE_JUMP;
1016 return;
1017 }
1018 }
1019
1020 for (;;)
1021 {
1022 // Exit when table stopped
1023 if (!ptr) break;
1024 // Overflow check
1025 if ((num != STBL) && (ptr > MAX_TABLELEN))
1026 {
1027 tableerror = TYPE_OVERFLOW;
1028 break;
1029 }
1030 // If were already here, exit
1031 if (tableused[num][ptr]) break;
1032 // Mark current position used
1033 tableused[num][ptr] = 1;
1034 // Go to next ptr.
1035 if (num != STBL)
1036 {
1037 if (ltable[num][ptr-1] == 0xff)
1038 {
1039 ptr = rtable[num][ptr-1];
1040 }
1041 else ptr++;
1042 }
1043 else break;
1044 }
1045 }
1046
findfreespeedtable(void)1047 int findfreespeedtable(void)
1048 {
1049 int c;
1050 for (c = 0; c < MAX_TABLELEN; c++)
1051 {
1052 if ((!ltable[STBL][c]) && (!rtable[STBL][c]))
1053 {
1054 return c;
1055 }
1056 }
1057 return -1;
1058 }
1059
1060