1 //
2 // GOATTRACKER v2 pattern editor
3 //
4 
5 #define GPATTERN_C
6 
7 #include "goattrk2.h"
8 
9 unsigned char notekeytbl1[] = {KEY_Z, KEY_S, KEY_X, KEY_D, KEY_C, KEY_V,
10   KEY_G, KEY_B, KEY_H, KEY_N, KEY_J, KEY_M, KEY_COMMA, KEY_L, KEY_COLON};
11 
12 unsigned char notekeytbl2[] = {KEY_Q, KEY_2, KEY_W, KEY_3, KEY_E, KEY_R,
13   KEY_5, KEY_T, KEY_6, KEY_Y, KEY_7, KEY_U, KEY_I, KEY_9, KEY_O, KEY_0, KEY_P};
14 
15 unsigned char dmckeytbl[] = {KEY_A, KEY_W, KEY_S, KEY_E, KEY_D, KEY_F,
16   KEY_T, KEY_G, KEY_Y, KEY_H, KEY_U, KEY_J, KEY_K, KEY_O, KEY_L, KEY_P};
17 
18 unsigned char jankokeytbl1[] = {KEY_Z, KEY_S, KEY_X, KEY_D, KEY_C, KEY_F, KEY_V,
19   KEY_G, KEY_B, KEY_H, KEY_N, KEY_J, KEY_M, KEY_K, KEY_COMMA, KEY_L, KEY_COLON};
20 
21 unsigned char jankokeytbl2[] = {KEY_Q, KEY_2, KEY_W, KEY_3, KEY_E, KEY_4, KEY_R,
22   KEY_5, KEY_T, KEY_6, KEY_Y, KEY_7, KEY_U, KEY_8, KEY_I, KEY_9, KEY_O, KEY_0, KEY_P};
23 
24 unsigned char patterncopybuffer[MAX_PATTROWS*4+4];
25 unsigned char cmdcopybuffer[MAX_PATTROWS*4+4];
26 int patterncopyrows = 0;
27 int cmdcopyrows = 0;
28 
29 int epnum[MAX_CHN];
30 int eppos;
31 int epview;
32 int epcolumn;
33 int epchn;
34 int epoctave = 2;
35 int epmarkchn = -1;
36 int epmarkstart;
37 int epmarkend;
38 
patterncommands(void)39 void patterncommands(void)
40 {
41   int c, scrrep;
42 
43   switch(key)
44   {
45     case '<':
46     case '(':
47     case '[':
48     prevpattern();
49     break;
50 
51     case '>':
52     case ')':
53     case ']':
54     nextpattern();
55     break;
56   }
57   {
58     int newnote = -1;
59     if (key)
60     {
61       switch (keypreset)
62       {
63         case KEY_TRACKER:
64         for (c = 0; c < sizeof(notekeytbl1); c++)
65         {
66           if ((rawkey == notekeytbl1[c]) && (!epcolumn) && (!shiftpressed))
67           {
68             newnote = FIRSTNOTE+c+epoctave*12;
69           }
70         }
71         for (c = 0; c < sizeof(notekeytbl2); c++)
72         {
73           if ((rawkey == notekeytbl2[c]) && (!epcolumn) && (!shiftpressed))
74           {
75             newnote = FIRSTNOTE+c+(epoctave+1)*12;
76           }
77         }
78         break;
79 
80         case KEY_DMC:
81         for (c = 0; c < sizeof(dmckeytbl); c++)
82         {
83           if ((rawkey == dmckeytbl[c]) && (!epcolumn) && (!shiftpressed))
84           {
85             newnote = FIRSTNOTE+c+epoctave*12;
86           }
87         }
88         break;
89 
90         case KEY_JANKO:
91         for (c = 0; c < sizeof(jankokeytbl1); c++)
92         {
93           if ((rawkey == jankokeytbl1[c]) && (!epcolumn) && (!shiftpressed))
94           {
95             newnote = FIRSTNOTE+c+epoctave*12;
96           }
97         }
98         for (c = 0; c < sizeof(jankokeytbl2); c++)
99         {
100           if ((rawkey == jankokeytbl2[c]) && (!epcolumn) && (!shiftpressed))
101           {
102             newnote = FIRSTNOTE+c+(epoctave+1)*12;
103           }
104         }
105         break;
106       }
107     }
108 
109     if (newnote > LASTNOTE) newnote = -1;
110     if ((rawkey == 0x08) && (!epcolumn)) newnote = REST;
111     if ((rawkey == 0x14) && (!epcolumn)) newnote = KEYOFF;
112     if (rawkey == KEY_ENTER)
113     {
114       switch(epcolumn)
115       {
116         case 0:
117         if (shiftpressed)
118           newnote = KEYON;
119         else
120           newnote = KEYOFF;
121         break;
122 
123         case 1:
124         case 2:
125         if (pattern[epnum[epchn]][eppos*4+1])
126         {
127           gotoinstr(pattern[epnum[epchn]][eppos*4+1]);
128           return;
129         }
130         break;
131 
132         default:
133         switch (pattern[epnum[epchn]][eppos*4+2])
134         {
135           case CMD_SETWAVEPTR:
136           if (pattern[epnum[epchn]][eppos*4+3])
137           {
138             gototable(WTBL, pattern[epnum[epchn]][eppos*4+3] - 1);
139             return;
140           }
141           else
142           {
143             if (shiftpressed)
144             {
145               int pos = gettablelen(WTBL);
146               if (pos >= MAX_TABLELEN-1) pos = MAX_TABLELEN - 1;
147               pattern[epnum[epchn]][eppos*4+3] = pos + 1;
148               gototable(WTBL, pos);
149               return;
150             }
151           }
152           break;
153 
154           case CMD_SETPULSEPTR:
155           if (pattern[epnum[epchn]][eppos*4+3])
156           {
157             gototable(PTBL, pattern[epnum[epchn]][eppos*4+3] - 1);
158             return;
159           }
160           else
161           {
162             if (shiftpressed)
163             {
164               int pos = gettablelen(PTBL);
165               if (pos >= MAX_TABLELEN-1) pos = MAX_TABLELEN - 1;
166               pattern[epnum[epchn]][eppos*4+3] = pos + 1;
167               gototable(PTBL, pos);
168               return;
169             }
170           }
171           break;
172 
173           case CMD_SETFILTERPTR:
174           if (pattern[epnum[epchn]][eppos*4+3])
175           {
176             gototable(FTBL, pattern[epnum[epchn]][eppos*4+3] - 1);
177             return;
178           }
179           else
180           {
181             if (shiftpressed)
182             {
183               int pos = gettablelen(FTBL);
184               if (pos >= MAX_TABLELEN-1) pos = MAX_TABLELEN - 1;
185               pattern[epnum[epchn]][eppos*4+3] = pos + 1;
186               gototable(FTBL, pos);
187               return;
188             }
189           }
190           break;
191 
192           case CMD_FUNKTEMPO:
193           if (pattern[epnum[epchn]][eppos*4+3])
194           {
195             if (!shiftpressed)
196             {
197               gototable(STBL, pattern[epnum[epchn]][eppos*4+3] - 1);
198               return;
199             }
200             else
201             {
202               int pos = makespeedtable(pattern[epnum[epchn]][eppos*4+3], MST_FUNKTEMPO, 1);
203               pattern[epnum[epchn]][eppos*4+3] = pos + 1;
204             }
205           }
206           else
207           {
208             if (shiftpressed)
209             {
210               int pos = findfreespeedtable();
211               if (pos >= 0)
212               {
213                 pattern[epnum[epchn]][eppos*4+3] = pos + 1;
214                 gototable(STBL, pos);
215                 return;
216               }
217             }
218           }
219           break;
220 
221           case CMD_PORTAUP:
222           case CMD_PORTADOWN:
223           case CMD_TONEPORTA:
224           if (pattern[epnum[epchn]][eppos*4+3])
225           {
226             if (!shiftpressed)
227             {
228               gototable(STBL, pattern[epnum[epchn]][eppos*4+3] - 1);
229               return;
230             }
231             else
232             {
233               int pos = makespeedtable(pattern[epnum[epchn]][eppos*4+3], MST_PORTAMENTO, 1);
234               pattern[epnum[epchn]][eppos*4+3] = pos + 1;
235             }
236           }
237           else
238           {
239             if (shiftpressed)
240             {
241               int pos = findfreespeedtable();
242               if (pos >= 0)
243               {
244                 pattern[epnum[epchn]][eppos*4+3] = pos + 1;
245                 gototable(STBL, pos);
246                 return;
247               }
248             }
249           }
250           break;
251 
252           case CMD_VIBRATO:
253           if (pattern[epnum[epchn]][eppos*4+3])
254           {
255             if (!shiftpressed)
256             {
257               gototable(STBL, pattern[epnum[epchn]][eppos*4+3] - 1);
258               return;
259             }
260             else
261             {
262               int pos = makespeedtable(pattern[epnum[epchn]][eppos*4+3], finevibrato, 1);
263               pattern[epnum[epchn]][eppos*4+3] = pos + 1;
264             }
265           }
266           else
267           {
268             if (shiftpressed)
269             {
270               int pos = findfreespeedtable();
271               if (pos >= 0)
272               {
273                 pattern[epnum[epchn]][eppos*4+3] = pos + 1;
274                 gototable(STBL, pos);
275                 return;
276               }
277             }
278           }
279           break;
280         }
281         break;
282       }
283       if ((autoadvance < 2) && (epcolumn))
284       {
285         eppos++;
286         if (eppos > pattlen[epnum[epchn]])
287         {
288           eppos = 0;
289         }
290       }
291     }
292 
293     if (newnote >= 0)
294     {
295       if ((recordmode) && (eppos < pattlen[epnum[epchn]]))
296       {
297         pattern[epnum[epchn]][eppos*4] = newnote;
298         if (newnote < REST)
299         {
300           pattern[epnum[epchn]][eppos*4+1] = einum;
301         }
302         else
303         {
304           pattern[epnum[epchn]][eppos*4+1] = 0;
305         }
306         if ((shiftpressed) && (newnote == REST))
307         {
308           pattern[epnum[epchn]][eppos*4+2] = 0;
309           pattern[epnum[epchn]][eppos*4+3] = 0;
310         }
311       }
312       if (recordmode)
313       {
314         if (autoadvance < 2)
315         {
316           eppos++;
317           if (eppos > pattlen[epnum[epchn]])
318           {
319             eppos = 0;
320           }
321         }
322       }
323       playtestnote(newnote, einum, epchn);
324     }
325   }
326   switch(rawkey)
327   {
328     case KEY_O:
329     if (shiftpressed) shrinkpattern();
330     break;
331 
332     case KEY_P:
333     if (shiftpressed) expandpattern();
334     break;
335 
336     case KEY_J:
337     if (shiftpressed) joinpattern();
338     break;
339 
340     case KEY_K:
341     if (shiftpressed) splitpattern();
342     break;
343 
344     case KEY_Z:
345     if (shiftpressed)
346     {
347       autoadvance++;
348       if (autoadvance > 2) autoadvance = 0;
349       if (keypreset == KEY_TRACKER)
350       {
351         if (autoadvance == 1) autoadvance = 2;
352       }
353     }
354     break;
355 
356     case KEY_E:
357     if (shiftpressed)
358     {
359       if (epmarkchn != -1)
360       {
361         if (epmarkstart < epmarkend)
362         {
363           int d = 0;
364           for (c = epmarkstart; c <= epmarkend; c++)
365           {
366             if (c >= pattlen[epnum[epmarkchn]]) break;
367             cmdcopybuffer[d*4+2] = pattern[epnum[epmarkchn]][c*4+2];
368             cmdcopybuffer[d*4+3] = pattern[epnum[epmarkchn]][c*4+3];
369             d++;
370           }
371           cmdcopyrows = d;
372         }
373         else
374         {
375           int d = 0;
376           for (c = epmarkend; c <= epmarkstart; c++)
377           {
378             if (c >= pattlen[epnum[epmarkchn]]) break;
379             cmdcopybuffer[d*4+2] = pattern[epnum[epmarkchn]][c*4+2];
380             cmdcopybuffer[d*4+3] = pattern[epnum[epmarkchn]][c*4+3];
381             d++;
382           }
383           cmdcopyrows = d;
384         }
385         epmarkchn = -1;
386       }
387       else
388       {
389         if (eppos < pattlen[epnum[epchn]])
390         {
391           cmdcopybuffer[2] = pattern[epnum[epchn]][eppos*4+2];
392           cmdcopybuffer[3] = pattern[epnum[epchn]][eppos*4+3];
393           cmdcopyrows = 1;
394         }
395       }
396     }
397     break;
398 
399     case KEY_R:
400     if (shiftpressed)
401     {
402       for (c = 0; c < cmdcopyrows; c++)
403       {
404         if (eppos >= pattlen[epnum[epchn]]) break;
405         pattern[epnum[epchn]][eppos*4+2] = cmdcopybuffer[c*4+2];
406         pattern[epnum[epchn]][eppos*4+3] = cmdcopybuffer[c*4+3];
407         eppos++;
408       }
409     }
410     break;
411 
412     case KEY_I:
413     if (shiftpressed)
414     {
415       int d, e;
416       char temp;
417       if (epmarkchn != -1)
418       {
419         if (epmarkstart <= epmarkend)
420         {
421           e = epmarkend;
422           for (c = epmarkstart; c <= epmarkend; c++)
423           {
424             if (c >= pattlen[epnum[epmarkchn]]) break;
425             for (d = 0; d < 4; d++)
426             {
427               temp = pattern[epnum[epmarkchn]][c*4+d];
428               pattern[epnum[epmarkchn]][c*4+d] = pattern[epnum[epmarkchn]][e*4+d];
429               pattern[epnum[epmarkchn]][e*4+d] = temp;
430             }
431             e--;
432             if (e < c) break;
433           }
434         }
435         else
436         {
437           e = epmarkstart;
438           for (c = epmarkend; c <= epmarkstart; c++)
439           {
440             if (c >= pattlen[epnum[epmarkchn]]) break;
441             for (d = 0; d < 4; d++)
442             {
443               temp = pattern[epnum[epmarkchn]][c*4+d];
444               pattern[epnum[epmarkchn]][c*4+d] = pattern[epnum[epmarkchn]][e*4+d];
445               pattern[epnum[epmarkchn]][e*4+d] = temp;
446             }
447             e--;
448             if (e < c) break;
449           }
450         }
451       }
452       else
453       {
454         e = pattlen[epnum[epchn]] - 1;
455         for (c = 0; c < pattlen[epnum[epchn]]; c++)
456         {
457           for (d = 0; d < 4; d++)
458           {
459             temp = pattern[epnum[epchn]][c*4+d];
460             pattern[epnum[epchn]][c*4+d] = pattern[epnum[epchn]][e*4+d];
461             pattern[epnum[epchn]][e*4+d] = temp;
462           }
463           e--;
464           if (e < c) break;
465         }
466       }
467     }
468     break;
469 
470     case KEY_Q:
471     if (shiftpressed)
472     {
473       if (epmarkchn != -1)
474       {
475         if (epmarkstart <= epmarkend)
476         {
477           for (c = epmarkstart; c <= epmarkend; c++)
478           {
479             if (c >= pattlen[epnum[epmarkchn]]) break;
480             if ((pattern[epnum[epmarkchn]][c*4] < LASTNOTE) &&
481                 (pattern[epnum[epmarkchn]][c*4] >= FIRSTNOTE))
482               pattern[epnum[epmarkchn]][c*4]++;
483           }
484         }
485         else
486         {
487           for (c = epmarkend; c <= epmarkstart; c++)
488           {
489             if (c >= pattlen[epnum[epmarkchn]]) break;
490             if ((pattern[epnum[epmarkchn]][c*4] < LASTNOTE) &&
491                 (pattern[epnum[epmarkchn]][c*4] >= FIRSTNOTE))
492               pattern[epnum[epmarkchn]][c*4]++;
493           }
494         }
495       }
496       else
497       {
498         for (c = 0; c < pattlen[epnum[epchn]]; c++)
499         {
500           if ((pattern[epnum[epchn]][c*4] < LASTNOTE) &&
501               (pattern[epnum[epchn]][c*4] >= FIRSTNOTE))
502             pattern[epnum[epchn]][c*4]++;
503         }
504       }
505     }
506     break;
507 
508     case KEY_A:
509     if (shiftpressed)
510     {
511       if (epmarkchn != -1)
512       {
513         if (epmarkstart <= epmarkend)
514         {
515           for (c = epmarkstart; c <= epmarkend; c++)
516           {
517             if (c >= pattlen[epnum[epmarkchn]]) break;
518             if ((pattern[epnum[epmarkchn]][c*4] <= LASTNOTE) &&
519                 (pattern[epnum[epmarkchn]][c*4] > FIRSTNOTE))
520               pattern[epnum[epmarkchn]][c*4]--;
521           }
522         }
523         else
524         {
525           for (c = epmarkend; c <= epmarkstart; c++)
526           {
527             if (c >= pattlen[epnum[epmarkchn]]) break;
528             if ((pattern[epnum[epmarkchn]][c*4] <= LASTNOTE) &&
529                 (pattern[epnum[epmarkchn]][c*4] > FIRSTNOTE))
530               pattern[epnum[epmarkchn]][c*4]--;
531           }
532         }
533       }
534       else
535       {
536         for (c = 0; c < pattlen[epnum[epchn]]; c++)
537         {
538           if ((pattern[epnum[epchn]][c*4] <= LASTNOTE) &&
539               (pattern[epnum[epchn]][c*4] > FIRSTNOTE))
540             pattern[epnum[epchn]][c*4]--;
541         }
542       }
543     }
544     break;
545 
546     case KEY_W:
547     if (shiftpressed)
548     {
549       if (epmarkchn != -1)
550       {
551         if (epmarkstart <= epmarkend)
552         {
553           for (c = epmarkstart; c <= epmarkend; c++)
554           {
555             if (c >= pattlen[epnum[epmarkchn]]) break;
556             if ((pattern[epnum[epmarkchn]][c*4] <= LASTNOTE) &&
557                 (pattern[epnum[epmarkchn]][c*4] >= FIRSTNOTE))
558             {
559               pattern[epnum[epmarkchn]][c*4] += 12;
560               if (pattern[epnum[epmarkchn]][c*4] > LASTNOTE)
561                 pattern[epnum[epmarkchn]][c*4] = LASTNOTE;
562             }
563           }
564         }
565         else
566         {
567           for (c = epmarkend; c <= epmarkstart; c++)
568           {
569             if (c >= pattlen[epnum[epmarkchn]]) break;
570             if ((pattern[epnum[epmarkchn]][c*4] <= LASTNOTE) &&
571                 (pattern[epnum[epmarkchn]][c*4] >= FIRSTNOTE))
572             {
573               pattern[epnum[epmarkchn]][c*4] += 12;
574               if (pattern[epnum[epmarkchn]][c*4] > LASTNOTE)
575                 pattern[epnum[epmarkchn]][c*4] = LASTNOTE;
576             }
577           }
578         }
579       }
580       else
581       {
582         for (c = 0; c < pattlen[epnum[epchn]]; c++)
583         {
584           if ((pattern[epnum[epchn]][c*4] <= LASTNOTE) &&
585               (pattern[epnum[epchn]][c*4] >= FIRSTNOTE))
586           {
587             pattern[epnum[epchn]][c*4] += 12;
588             if (pattern[epnum[epchn]][c*4] > LASTNOTE)
589               pattern[epnum[epchn]][c*4] = LASTNOTE;
590           }
591         }
592       }
593     }
594     break;
595 
596     case KEY_S:
597     if (shiftpressed)
598     {
599       if (epmarkchn != -1)
600       {
601         if (epmarkstart <= epmarkend)
602         {
603           for (c = epmarkstart; c <= epmarkend; c++)
604           {
605             if (c >= pattlen[epnum[epmarkchn]]) break;
606             if ((pattern[epnum[epmarkchn]][c*4] <= LASTNOTE) &&
607                 (pattern[epnum[epmarkchn]][c*4] >= FIRSTNOTE))
608             {
609               pattern[epnum[epmarkchn]][c*4] -= 12;
610               if (pattern[epnum[epmarkchn]][c*4] < FIRSTNOTE)
611                 pattern[epnum[epmarkchn]][c*4] = FIRSTNOTE;
612             }
613           }
614         }
615         else
616         {
617           for (c = epmarkend; c <= epmarkstart; c++)
618           {
619             if (c >= pattlen[epnum[epmarkchn]]) break;
620             if ((pattern[epnum[epmarkchn]][c*4] <= LASTNOTE) &&
621                 (pattern[epnum[epmarkchn]][c*4] >= FIRSTNOTE))
622             {
623               pattern[epnum[epmarkchn]][c*4] -= 12;
624               if (pattern[epnum[epmarkchn]][c*4] < FIRSTNOTE)
625                 pattern[epnum[epmarkchn]][c*4] = FIRSTNOTE;
626             }
627           }
628         }
629       }
630       else
631       {
632         for (c = 0; c < pattlen[epnum[epchn]]; c++)
633         {
634           if ((pattern[epnum[epchn]][c*4] <= LASTNOTE) &&
635               (pattern[epnum[epchn]][c*4] >= FIRSTNOTE))
636           {
637             pattern[epnum[epchn]][c*4] -= 12;
638             if (pattern[epnum[epchn]][c*4] < FIRSTNOTE)
639               pattern[epnum[epchn]][c*4] = FIRSTNOTE;
640           }
641         }
642       }
643     }
644     break;
645 
646     case KEY_M:
647     if (shiftpressed)
648     {
649       stepsize++;
650       if (stepsize > MAX_PATTROWS) stepsize = MAX_PATTROWS;
651     }
652     break;
653 
654     case KEY_N:
655     if (shiftpressed)
656     {
657       stepsize--;
658       if (stepsize < 2) stepsize = 2;
659     }
660     break;
661 
662     case KEY_H:
663     if (shiftpressed)
664     {
665       switch (pattern[epnum[epchn]][eppos*4+2])
666       {
667         case CMD_PORTAUP:
668         case CMD_PORTADOWN:
669         case CMD_VIBRATO:
670         case CMD_TONEPORTA:
671         if (pattern[epnum[epchn]][eppos*4+2] == CMD_TONEPORTA)
672           c = eppos-1;
673         else
674           c = eppos;
675         for (; c >= 0; c--)
676         {
677           if ((pattern[epnum[epchn]][c*4] >= FIRSTNOTE) &&
678               (pattern[epnum[epchn]][c*4] <= LASTNOTE))
679           {
680             int delta;
681             int pitch1;
682             int pitch2;
683             int pos;
684             int note = pattern[epnum[epchn]][c*4] - FIRSTNOTE;
685             int right = pattern[epnum[epchn]][eppos*4+3] & 0xf;
686             int left = pattern[epnum[epchn]][eppos*4+3] >> 4;
687 
688             if (note > MAX_NOTES-1) note--;
689             pitch1 = freqtbllo[note] | (freqtblhi[note] << 8);
690             pitch2 = freqtbllo[note+1] | (freqtblhi[note+1] << 8);
691             delta = pitch2 - pitch1;
692 
693             while (left--) delta <<= 1;
694             while (right--) delta >>= 1;
695 
696             if (pattern[epnum[epchn]][eppos*4+2] == CMD_VIBRATO)
697             {
698               if (delta > 0xff) delta = 0xff;
699             }
700             pos = makespeedtable(delta, MST_RAW, 1);
701             pattern[epnum[epchn]][eppos*4+3] = pos + 1;
702             break;
703           }
704         }
705         break;
706       }
707     }
708     break;
709 
710     case KEY_L:
711     if (shiftpressed)
712     {
713       if (epmarkchn == -1)
714       {
715         epmarkchn = epchn;
716         epmarkstart = 0;
717         epmarkend = pattlen[epnum[epchn]]-1;
718       }
719       else epmarkchn = -1;
720     }
721     break;
722 
723     case KEY_C:
724     case KEY_X:
725     if (shiftpressed)
726     {
727       if (epmarkchn != -1)
728       {
729         if (epmarkstart <= epmarkend)
730         {
731           int d = 0;
732           for (c = epmarkstart; c <= epmarkend; c++)
733           {
734             if (c >= pattlen[epnum[epmarkchn]]) break;
735             patterncopybuffer[d*4] = pattern[epnum[epmarkchn]][c*4];
736             patterncopybuffer[d*4+1] = pattern[epnum[epmarkchn]][c*4+1];
737             patterncopybuffer[d*4+2] = pattern[epnum[epmarkchn]][c*4+2];
738             patterncopybuffer[d*4+3] = pattern[epnum[epmarkchn]][c*4+3];
739             if (rawkey == KEY_X)
740             {
741               pattern[epnum[epmarkchn]][c*4] = REST;
742               pattern[epnum[epmarkchn]][c*4+1] = 0;
743               pattern[epnum[epmarkchn]][c*4+2] = 0;
744               pattern[epnum[epmarkchn]][c*4+3] = 0;
745             }
746             d++;
747           }
748           patterncopyrows = d;
749         }
750         else
751         {
752           int d = 0;
753           for (c = epmarkend; c <= epmarkstart; c++)
754           {
755             if (c >= pattlen[epnum[epmarkchn]]) break;
756             patterncopybuffer[d*4] = pattern[epnum[epmarkchn]][c*4];
757             patterncopybuffer[d*4+1] = pattern[epnum[epmarkchn]][c*4+1];
758             patterncopybuffer[d*4+2] = pattern[epnum[epmarkchn]][c*4+2];
759             patterncopybuffer[d*4+3] = pattern[epnum[epmarkchn]][c*4+3];
760             if (rawkey == KEY_X)
761             {
762               pattern[epnum[epmarkchn]][c*4] = REST;
763               pattern[epnum[epmarkchn]][c*4+1] = 0;
764               pattern[epnum[epmarkchn]][c*4+2] = 0;
765               pattern[epnum[epmarkchn]][c*4+3] = 0;
766             }
767             d++;
768           }
769           patterncopyrows = d;
770         }
771         epmarkchn = -1;
772       }
773       else
774       {
775         int d = 0;
776         for (c = 0; c < pattlen[epnum[epchn]]; c++)
777         {
778           patterncopybuffer[d*4] = pattern[epnum[epchn]][c*4];
779           patterncopybuffer[d*4+1] = pattern[epnum[epchn]][c*4+1];
780           patterncopybuffer[d*4+2] = pattern[epnum[epchn]][c*4+2];
781           patterncopybuffer[d*4+3] = pattern[epnum[epchn]][c*4+3];
782           if (rawkey == KEY_X)
783           {
784             pattern[epnum[epchn]][c*4] = REST;
785             pattern[epnum[epchn]][c*4+1] = 0;
786             pattern[epnum[epchn]][c*4+2] = 0;
787             pattern[epnum[epchn]][c*4+3] = 0;
788           }
789           d++;
790         }
791         patterncopyrows = d;
792       }
793     }
794     break;
795 
796     case KEY_V:
797     if ((shiftpressed) && (patterncopyrows))
798     {
799       for (c = 0; c < patterncopyrows; c++)
800       {
801         if (eppos >= pattlen[epnum[epchn]]) break;
802         pattern[epnum[epchn]][eppos*4] = patterncopybuffer[c*4];
803         pattern[epnum[epchn]][eppos*4+1] = patterncopybuffer[c*4+1];
804         pattern[epnum[epchn]][eppos*4+2] = patterncopybuffer[c*4+2];
805         pattern[epnum[epchn]][eppos*4+3] = patterncopybuffer[c*4+3];
806         eppos++;
807       }
808     }
809     break;
810 
811     case KEY_DEL:
812     if (epmarkchn == epchn) epmarkchn = -1;
813     if ((pattlen[epnum[epchn]]-eppos)*4-4 >= 0)
814     {
815       memmove(&pattern[epnum[epchn]][eppos*4],
816         &pattern[epnum[epchn]][eppos*4+4],
817         (pattlen[epnum[epchn]]-eppos)*4-4);
818       pattern[epnum[epchn]][pattlen[epnum[epchn]]*4-4] = REST;
819       pattern[epnum[epchn]][pattlen[epnum[epchn]]*4-3] = 0x00;
820       pattern[epnum[epchn]][pattlen[epnum[epchn]]*4-2] = 0x00;
821       pattern[epnum[epchn]][pattlen[epnum[epchn]]*4-1] = 0x00;
822     }
823     else
824     {
825       if (eppos == pattlen[epnum[epchn]])
826       {
827         if (pattlen[epnum[epchn]] > 1)
828         {
829           pattern[epnum[epchn]][pattlen[epnum[epchn]]*4-4] = ENDPATT;
830           pattern[epnum[epchn]][pattlen[epnum[epchn]]*4-3] = 0x00;
831           pattern[epnum[epchn]][pattlen[epnum[epchn]]*4-2] = 0x00;
832           pattern[epnum[epchn]][pattlen[epnum[epchn]]*4-1] = 0x00;
833           countthispattern();
834           eppos = pattlen[epnum[epchn]];
835         }
836       }
837     }
838     break;
839 
840     case KEY_INS:
841     if (epmarkchn == epchn) epmarkchn = -1;
842     if ((pattlen[epnum[epchn]]-eppos)*4-4 >= 0)
843     {
844       memmove(&pattern[epnum[epchn]][eppos*4+4],
845         &pattern[epnum[epchn]][eppos*4],
846         (pattlen[epnum[epchn]]-eppos)*4-4);
847       pattern[epnum[epchn]][eppos*4] = REST;
848       pattern[epnum[epchn]][eppos*4+1] = 0x00;
849       pattern[epnum[epchn]][eppos*4+2] = 0x00;
850       pattern[epnum[epchn]][eppos*4+3] = 0x00;
851     }
852     else
853     {
854       if (eppos == pattlen[epnum[epchn]])
855       {
856         if (pattlen[epnum[epchn]] < MAX_PATTROWS)
857         {
858           pattern[epnum[epchn]][eppos*4] = REST;
859           pattern[epnum[epchn]][eppos*4+1] = 0x00;
860           pattern[epnum[epchn]][eppos*4+2] = 0x00;
861           pattern[epnum[epchn]][eppos*4+3] = 0x00;
862           pattern[epnum[epchn]][eppos*4+4] = ENDPATT;
863           pattern[epnum[epchn]][eppos*4+5] = 0x00;
864           pattern[epnum[epchn]][eppos*4+6] = 0x00;
865           pattern[epnum[epchn]][eppos*4+7] = 0x00;
866           countthispattern();
867           eppos = pattlen[epnum[epchn]];
868         }
869       }
870     }
871     break;
872 
873     case KEY_SPACE:
874     if (!shiftpressed)
875       recordmode ^= 1;
876     else
877     {
878       if (lastsonginit != PLAY_PATTERN)
879       {
880         if (eseditpos != espos[eschn])
881         {
882           int c;
883 
884           for (c = 0; c < MAX_CHN; c++)
885           {
886             if (eseditpos < songlen[esnum][c]) espos[c] = eseditpos;
887             if (esend[c] <= espos[c]) esend[c] = 0;
888           }
889         }
890         initsongpos(esnum, PLAY_POS, eppos);
891       }
892       else initsongpos(esnum, PLAY_PATTERN, eppos);
893       followplay = 0;
894     }
895     break;
896 
897     case KEY_RIGHT:
898     if (!shiftpressed)
899     {
900       epcolumn++;
901       if (epcolumn >= 6)
902       {
903         epcolumn = 0;
904         epchn++;
905         if (epchn >= MAX_CHN) epchn = 0;
906         if (eppos > pattlen[epnum[epchn]]) eppos = pattlen[epnum[epchn]];
907       }
908     }
909     else
910     {
911       if (epnum[epchn] < MAX_PATT-1)
912       {
913         epnum[epchn]++;
914         if (eppos > pattlen[epnum[epchn]]) eppos = pattlen[epnum[epchn]];
915       }
916       if (epchn == epmarkchn) epmarkchn = -1;
917     }
918     break;
919 
920     case KEY_LEFT:
921     if (!shiftpressed)
922     {
923       epcolumn--;
924       if (epcolumn < 0)
925       {
926         epcolumn = 5;
927         epchn--;
928         if (epchn < 0) epchn = MAX_CHN-1;
929         if (eppos > pattlen[epnum[epchn]]) eppos = pattlen[epnum[epchn]];
930       }
931     }
932     else
933     {
934       if (epnum[epchn] > 0)
935       {
936         epnum[epchn]--;
937         if (eppos > pattlen[epnum[epchn]]) eppos = pattlen[epnum[epchn]];
938       }
939       if (epchn == epmarkchn) epmarkchn = -1;
940     }
941     break;
942 
943     case KEY_HOME:
944     while (eppos != 0) patternup();
945     break;
946 
947     case KEY_END:
948     while (eppos != pattlen[epnum[epchn]]) patterndown();
949     break;
950 
951     case KEY_PGUP:
952     for (scrrep = PGUPDNREPEAT; scrrep; scrrep--)
953       patternup();
954     break;
955 
956     case KEY_PGDN:
957     for (scrrep = PGUPDNREPEAT; scrrep; scrrep--)
958       patterndown();
959     break;
960 
961     case KEY_UP:
962     patternup();
963     break;
964 
965     case KEY_DOWN:
966     patterndown();
967     break;
968 
969     case KEY_APOST2:
970     if (!shiftpressed)
971     {
972       epchn++;
973       if (epchn >= MAX_CHN) epchn = 0;
974       if (eppos > pattlen[epnum[epchn]]) eppos = pattlen[epnum[epchn]];
975     }
976     else
977     {
978       epchn--;
979       if (epchn < 0) epchn = MAX_CHN-1;
980       if (eppos > pattlen[epnum[epchn]]) eppos = pattlen[epnum[epchn]];
981     }
982     break;
983 
984     case KEY_1:
985     case KEY_2:
986     case KEY_3:
987     if (shiftpressed)
988       mutechannel(rawkey - KEY_1);
989     break;
990   }
991   if ((keypreset == KEY_DMC) && (hexnybble >= 0) && (hexnybble <= 7) && (!epcolumn))
992   {
993     int oldbyte = pattern[epnum[epchn]][eppos*4];
994     epoctave = hexnybble;
995     if ((oldbyte >= FIRSTNOTE) && (oldbyte <= LASTNOTE))
996     {
997       int newbyte;
998       int oldnote = (oldbyte - FIRSTNOTE) %12;
999 
1000       if (recordmode)
1001       {
1002         newbyte = oldnote+epoctave*12 + FIRSTNOTE;
1003         if (newbyte <= LASTNOTE)
1004         {
1005           pattern[epnum[epchn]][eppos*4] = newbyte;
1006         }
1007       }
1008       if ((recordmode) && (autoadvance < 1))
1009       {
1010         eppos++;
1011         if (eppos > pattlen[epnum[epchn]])
1012         {
1013           eppos = 0;
1014         }
1015       }
1016     }
1017   }
1018 
1019   if ((hexnybble >= 0) && (epcolumn) && (recordmode))
1020   {
1021     if (eppos < pattlen[epnum[epchn]])
1022     {
1023       switch(epcolumn)
1024       {
1025         case 1:
1026         pattern[epnum[epchn]][eppos*4+1] &= 0x0f;
1027         pattern[epnum[epchn]][eppos*4+1] |= hexnybble << 4;
1028         pattern[epnum[epchn]][eppos*4+1] &= (MAX_INSTR - 1);
1029         break;
1030 
1031         case 2:
1032         pattern[epnum[epchn]][eppos*4+1] &= 0xf0;
1033         pattern[epnum[epchn]][eppos*4+1] |= hexnybble;
1034         pattern[epnum[epchn]][eppos*4+1] &= (MAX_INSTR - 1);
1035         break;
1036 
1037         case 3:
1038         pattern[epnum[epchn]][eppos*4+2] = hexnybble;
1039         if (!pattern[epnum[epchn]][eppos*4+2])
1040           pattern[epnum[epchn]][eppos*4+3] = 0;
1041         break;
1042 
1043         case 4:
1044         pattern[epnum[epchn]][eppos*4+3] &= 0x0f;
1045         pattern[epnum[epchn]][eppos*4+3] |= hexnybble << 4;
1046         if (!pattern[epnum[epchn]][eppos*4+2])
1047           pattern[epnum[epchn]][eppos*4+3] = 0;
1048         break;
1049 
1050         case 5:
1051         pattern[epnum[epchn]][eppos*4+3] &= 0xf0;
1052         pattern[epnum[epchn]][eppos*4+3] |= hexnybble;
1053         if (!pattern[epnum[epchn]][eppos*4+2])
1054           pattern[epnum[epchn]][eppos*4+3] = 0;
1055         break;
1056       }
1057     }
1058     if (autoadvance < 2)
1059     {
1060       eppos++;
1061       if (eppos > pattlen[epnum[epchn]])
1062       {
1063         eppos = 0;
1064       }
1065     }
1066   }
1067   epview = eppos-VISIBLEPATTROWS/2;
1068 }
1069 
1070 
patterndown(void)1071 void patterndown(void)
1072 {
1073   if (shiftpressed)
1074   {
1075     if ((epmarkchn != epchn) || (eppos != epmarkend))
1076     {
1077       epmarkchn = epchn;
1078       epmarkstart = epmarkend = eppos;
1079     }
1080   }
1081   eppos++;
1082   if (eppos > pattlen[epnum[epchn]])
1083   {
1084     eppos = 0;
1085   }
1086   if (shiftpressed) epmarkend = eppos;
1087 }
1088 
patternup(void)1089 void patternup(void)
1090 {
1091   if (shiftpressed)
1092   {
1093     if ((epmarkchn != epchn) || (eppos != epmarkend))
1094     {
1095       epmarkchn = epchn;
1096       epmarkstart = epmarkend = eppos;
1097     }
1098   }
1099   eppos--;
1100   if (eppos < 0)
1101   {
1102     eppos = pattlen[epnum[epchn]];
1103   }
1104   if (shiftpressed) epmarkend = eppos;
1105 }
1106 
prevpattern(void)1107 void prevpattern(void)
1108 {
1109   if (epnum[epchn] > 0)
1110   {
1111     epnum[epchn]--;
1112     if (eppos > pattlen[epnum[epchn]]) eppos = pattlen[epnum[epchn]];
1113   }
1114   if (epchn == epmarkchn) epmarkchn = -1;
1115 }
1116 
nextpattern(void)1117 void nextpattern(void)
1118 {
1119   if (epnum[epchn] < MAX_PATT-1)
1120   {
1121     epnum[epchn]++;
1122     if (eppos > pattlen[epnum[epchn]]) eppos = pattlen[epnum[epchn]];
1123   }
1124   if (epchn == epmarkchn) epmarkchn = -1;
1125 }
1126 
shrinkpattern(void)1127 void shrinkpattern(void)
1128 {
1129   int c = epnum[epchn];
1130   int l = pattlen[c];
1131   int nl = l/2;
1132   int d;
1133 
1134   if (pattlen[c] < 2) return;
1135 
1136   stopsong();
1137 
1138   for (d = 0; d < nl; d++)
1139   {
1140     pattern[c][d*4] = pattern[c][d*2*4];
1141     pattern[c][d*4+1] = pattern[c][d*2*4+1];
1142     pattern[c][d*4+2] = pattern[c][d*2*4+2];
1143     pattern[c][d*4+3] = pattern[c][d*2*4+3];
1144   }
1145 
1146   pattern[c][nl*4] = ENDPATT;
1147   pattern[c][nl*4+1] = 0;
1148   pattern[c][nl*4+2] = 0;
1149   pattern[c][nl*4+3] = 0;
1150 
1151   eppos /= 2;
1152 
1153   countthispattern();
1154 }
1155 
expandpattern(void)1156 void expandpattern(void)
1157 {
1158   int c = epnum[epchn];
1159   int l = pattlen[c];
1160   int nl = l*2;
1161   int d;
1162   unsigned char temp[MAX_PATTROWS*4+4];
1163 
1164   if (nl > MAX_PATTROWS) return;
1165   memset(temp, 0, sizeof temp);
1166 
1167   stopsong();
1168 
1169   for (d = 0; d <= nl; d++)
1170   {
1171     if (d & 1)
1172     {
1173       temp[d*4] = REST;
1174       temp[d*4+1] = 0;
1175       temp[d*4+2] = 0;
1176       temp[d*4+3] = 0;
1177     }
1178     else
1179     {
1180       temp[d*4] = pattern[c][d*2];
1181       temp[d*4+1] = pattern[c][d*2+1];
1182       temp[d*4+2] = pattern[c][d*2+2];
1183       temp[d*4+3] = pattern[c][d*2+3];
1184     }
1185   }
1186 
1187   memcpy(pattern[c], temp, (nl+1)*4);
1188 
1189   eppos *= 2;
1190 
1191   countthispattern();
1192 }
1193 
splitpattern(void)1194 void splitpattern(void)
1195 {
1196   int c = epnum[epchn];
1197   int l = pattlen[c];
1198   int d;
1199 
1200   if (eppos == 0) return;
1201   if (eppos == l) return;
1202 
1203   stopsong();
1204 
1205   if (insertpattern(c))
1206   {
1207     int oldesnum = esnum;
1208     int oldeschn = eschn;
1209     int oldeseditpos = eseditpos;
1210 
1211     for (d = eppos; d <= l; d++)
1212     {
1213       pattern[c+1][(d-eppos)*4] = pattern[c][d*4];
1214       pattern[c+1][(d-eppos)*4+1] = pattern[c][d*4+1];
1215       pattern[c+1][(d-eppos)*4+2] = pattern[c][d*4+2];
1216       pattern[c+1][(d-eppos)*4+3] = pattern[c][d*4+3];
1217     }
1218     pattern[c][eppos*4] = ENDPATT;
1219     pattern[c][eppos*4+1] = 0;
1220     pattern[c][eppos*4+2] = 0;
1221     pattern[c][eppos*4+3] = 0;
1222 
1223     countpatternlengths();
1224 
1225     for (esnum = 0; esnum < MAX_SONGS; esnum++)
1226     {
1227       for (eschn = 0; eschn < MAX_CHN; eschn++)
1228       {
1229         for (eseditpos = 0; eseditpos < songlen[esnum][eschn]; eseditpos++)
1230         {
1231           if (songorder[esnum][eschn][eseditpos] == c)
1232           {
1233             songorder[esnum][eschn][eseditpos] = c+1;
1234             insertorder(c);
1235           }
1236         }
1237       }
1238     }
1239     eschn = oldeschn;
1240     eseditpos = oldeseditpos;
1241     esnum = oldesnum;
1242   }
1243 }
1244 
joinpattern(void)1245 void joinpattern(void)
1246 {
1247   int c = epnum[epchn];
1248   int d;
1249 
1250   if (eschn != epchn) return;
1251   if (songorder[esnum][epchn][eseditpos] != c) return;
1252   d = songorder[esnum][epchn][eseditpos + 1];
1253   if (d >= MAX_PATT) return;
1254   if (pattlen[c] + pattlen[d] > MAX_PATTROWS) return;
1255 
1256   stopsong();
1257 
1258   if (insertpattern(c))
1259   {
1260     int oldesnum = esnum;
1261     int oldeschn = eschn;
1262     int oldeseditpos = eseditpos;
1263     int e, f;
1264     d++;
1265 
1266     for (e = 0; e < pattlen[c]; e++)
1267     {
1268       pattern[c+1][e*4] = pattern[c][e*4];
1269       pattern[c+1][e*4+1] = pattern[c][e*4+1];
1270       pattern[c+1][e*4+2] = pattern[c][e*4+2];
1271       pattern[c+1][e*4+3] = pattern[c][e*4+3];
1272     }
1273     for (f = 0; f < pattlen[d]; f++)
1274     {
1275       pattern[c+1][e*4] = pattern[d][f*4];
1276       pattern[c+1][e*4+1] = pattern[d][f*4+1];
1277        pattern[c+1][e*4+2] = pattern[d][f*4+2];
1278        pattern[c+1][e*4+3] = pattern[d][f*4+3];
1279        e++;
1280     }
1281     pattern[c+1][e*4] = ENDPATT;
1282     pattern[c+1][e*4+1] = 0;
1283     pattern[c+1][e*4+2] = 0;
1284     pattern[c+1][e*4+3] = 0;
1285 
1286     countpatternlengths();
1287 
1288     for (esnum = 0; esnum < MAX_SONGS; esnum++)
1289     {
1290       for (eschn = 0; eschn < MAX_CHN; eschn++)
1291       {
1292         for (eseditpos = 0; eseditpos < songlen[esnum][eschn]; eseditpos++)
1293         {
1294           if ((songorder[esnum][eschn][eseditpos] == c) && (songorder[esnum][eschn][eseditpos+1] == d))
1295           {
1296             deleteorder();
1297             songorder[esnum][eschn][eseditpos] = c+1;
1298           }
1299         }
1300       }
1301     }
1302     eschn = oldeschn;
1303     eseditpos = oldeseditpos;
1304     esnum = oldesnum;
1305 
1306     findusedpatterns();
1307     {
1308       int del1 = pattused[c];
1309       int del2 = pattused[d];
1310 
1311       if (!del1)
1312       {
1313         deletepattern(c);
1314         if (d > c) d--;
1315       }
1316       if (!del2)
1317         deletepattern(d);
1318     }
1319   }
1320 }
1321 
1322 
1323