1 //
2 // GOATTRACKER v2 orderlist & songname editor
3 //
4 
5 #define GORDER_C
6 
7 #include "goattrk2.h"
8 
9 unsigned char trackcopybuffer[MAX_SONGLEN+2];
10 int trackcopyrows = 0;
11 int trackcopywhole;
12 int trackcopyrpos;
13 
14 int espos[MAX_CHN];
15 int esend[MAX_CHN];
16 int eseditpos;
17 int esview;
18 int escolumn;
19 int eschn;
20 int esnum;
21 int esmarkchn = -1;
22 int esmarkstart;
23 int esmarkend;
24 int enpos;
25 
26 void orderlistcommands(void);
27 void namecommands(void);
28 
orderlistcommands(void)29 void orderlistcommands(void)
30 {
31   int c, scrrep;
32 
33   if (hexnybble >= 0)
34   {
35     if (eseditpos != songlen[esnum][eschn])
36     {
37       switch(escolumn)
38       {
39         case 0:
40         songorder[esnum][eschn][eseditpos] &= 0x0f;
41         songorder[esnum][eschn][eseditpos] |= hexnybble << 4;
42         if (eseditpos < songlen[esnum][eschn])
43         {
44           if (songorder[esnum][eschn][eseditpos] >= MAX_PATT)
45             songorder[esnum][eschn][eseditpos] = MAX_PATT - 1;
46         }
47         else
48         {
49           if (songorder[esnum][eschn][eseditpos] >= MAX_SONGLEN)
50             songorder[esnum][eschn][eseditpos] = MAX_SONGLEN - 1;
51         }
52         break;
53 
54         case 1:
55         songorder[esnum][eschn][eseditpos] &= 0xf0;
56         if ((songorder[esnum][eschn][eseditpos] & 0xf0) == 0xd0)
57         {
58           hexnybble--;
59           if (hexnybble < 0) hexnybble = 0xf;
60         }
61         if ((songorder[esnum][eschn][eseditpos] & 0xf0) == 0xe0)
62         {
63           hexnybble = 16 - hexnybble;
64           hexnybble &= 0xf;
65         }
66         songorder[esnum][eschn][eseditpos] |= hexnybble;
67 
68         if (eseditpos < songlen[esnum][eschn])
69         {
70           if (songorder[esnum][eschn][eseditpos] == LOOPSONG)
71             songorder[esnum][eschn][eseditpos] = LOOPSONG-1;
72           if (songorder[esnum][eschn][eseditpos] == TRANSDOWN)
73             songorder[esnum][eschn][eseditpos] = TRANSDOWN+0x0f;
74         }
75         else
76         {
77           if (songorder[esnum][eschn][eseditpos] >= MAX_SONGLEN)
78             songorder[esnum][eschn][eseditpos] = MAX_SONGLEN - 1;
79         }
80         break;
81       }
82       escolumn++;
83       if (escolumn > 1)
84       {
85         escolumn = 0;
86         if (eseditpos < (songlen[esnum][eschn]+1))
87         {
88           eseditpos++;
89           if (eseditpos == songlen[esnum][eschn]) eseditpos++;
90         }
91       }
92     }
93   }
94 
95   switch(key)
96   {
97     case 'R':
98     if (eseditpos < songlen[esnum][eschn])
99     {
100       songorder[esnum][eschn][eseditpos] = REPEAT + 0x01;
101       escolumn = 1;
102     }
103     break;
104 
105     case '+':
106     if (eseditpos < songlen[esnum][eschn])
107     {
108       songorder[esnum][eschn][eseditpos] = TRANSUP;
109       escolumn = 1;
110     }
111     break;
112 
113     case '-':
114     if (eseditpos < songlen[esnum][eschn])
115     {
116       songorder[esnum][eschn][eseditpos] = TRANSDOWN + 0x0F;
117       escolumn = 1;
118     }
119     break;
120 
121     case '>':
122     case ')':
123     case ']':
124     nextsong();
125     break;
126 
127     case '<':
128     case '(':
129     case '[':
130     prevsong();
131     break;
132   }
133   switch(rawkey)
134   {
135     case KEY_1:
136     case KEY_2:
137     case KEY_3:
138     if (shiftpressed)
139     {
140       int schn = eschn;
141       int tchn = 0;
142 
143       esmarkchn = -1;
144       if (rawkey == KEY_1) tchn = 0;
145       if (rawkey == KEY_2) tchn = 1;
146       if (rawkey == KEY_3) tchn = 2;
147       if (schn != tchn)
148       {
149         int lentemp = songlen[esnum][schn];
150         songlen[esnum][schn] = songlen[esnum][tchn];
151         songlen[esnum][tchn] = lentemp;
152 
153         for (c = 0; c < MAX_SONGLEN+2; c++)
154         {
155           unsigned char temp = songorder[esnum][schn][c];
156           songorder[esnum][schn][c] = songorder[esnum][tchn][c];
157           songorder[esnum][tchn][c] = temp;
158         }
159       }
160     }
161     break;
162 
163     case KEY_X:
164     if (shiftpressed)
165     {
166       if (esmarkchn != -1)
167       {
168         int d = 0;
169 
170         eschn = esmarkchn;
171         if (esmarkstart <= esmarkend)
172         {
173           eseditpos = esmarkstart;
174           for (c = esmarkstart; c <= esmarkend; c++)
175             trackcopybuffer[d++] = songorder[esnum][eschn][c];
176           trackcopyrows = d;
177         }
178         else
179         {
180           eseditpos = esmarkend;
181           for (c = esmarkend; c <= esmarkstart; c++)
182             trackcopybuffer[d++] = songorder[esnum][eschn][c];
183           trackcopyrows = d;
184         }
185         if (trackcopyrows == songlen[esnum][eschn])
186         {
187           trackcopywhole = 1;
188           trackcopyrpos = songorder[esnum][eschn][songlen[esnum][eschn]+1];
189         }
190         else trackcopywhole = 0;
191         for (c = 0; c < trackcopyrows; c++) deleteorder();
192         esmarkchn = -1;
193       }
194     }
195     break;
196 
197     case KEY_C:
198     if (shiftpressed)
199     {
200       if (esmarkchn != -1)
201       {
202         int d = 0;
203         if (esmarkstart <= esmarkend)
204         {
205           for (c = esmarkstart; c <= esmarkend; c++)
206             trackcopybuffer[d++] = songorder[esnum][eschn][c];
207           trackcopyrows = d;
208         }
209         else
210         {
211           for (c = esmarkend; c <= esmarkstart; c++)
212             trackcopybuffer[d++] = songorder[esnum][eschn][c];
213           trackcopyrows = d;
214         }
215         if (trackcopyrows == songlen[esnum][eschn])
216         {
217           trackcopywhole = 1;
218           trackcopyrpos = songorder[esnum][eschn][songlen[esnum][eschn]+1];
219         }
220         else trackcopywhole = 0;
221         esmarkchn = -1;
222       }
223     }
224     break;
225 
226     case KEY_V:
227     if (shiftpressed)
228     {
229       int oldlen = songlen[esnum][eschn];
230 
231       if (eseditpos < songlen[esnum][eschn])
232       {
233         for (c = trackcopyrows-1; c >= 0; c--)
234           insertorder(trackcopybuffer[c]);
235       }
236       else
237       {
238         for (c = 0; c < trackcopyrows; c++)
239           insertorder(trackcopybuffer[c]);
240       }
241       if ((trackcopywhole) && (!oldlen))
242         songorder[esnum][eschn][songlen[esnum][eschn]+1] = trackcopyrpos;
243     }
244     break;
245 
246     case KEY_L:
247     if (shiftpressed)
248     {
249       if (esmarkchn == -1)
250       {
251         esmarkchn = eschn;
252         esmarkstart = 0;
253         esmarkend = songlen[esnum][eschn]-1;
254       }
255       else esmarkchn = -1;
256     }
257     break;
258 
259 
260     case KEY_SPACE:
261     if (!shiftpressed)
262     {
263       if (eseditpos < songlen[esnum][eschn]) espos[eschn] = eseditpos;
264       if (esend[eschn] < espos[eschn]) esend[eschn] = 0;
265     }
266     else
267     {
268       for (c = 0; c < MAX_CHN; c++)
269       {
270         if (eseditpos < songlen[esnum][c]) espos[c] = eseditpos;
271         if (esend[c] < espos[c]) esend[c] = 0;
272       }
273     }
274     break;
275 
276     case KEY_BACKSPACE:
277     if (!shiftpressed)
278     {
279       if ((esend[eschn] != eseditpos) && (eseditpos > espos[eschn]))
280       {
281         if (eseditpos < songlen[esnum][eschn]) esend[eschn] = eseditpos;
282       }
283       else esend[eschn] = 0;
284     }
285     else
286     {
287       if ((esend[eschn] != eseditpos) && (eseditpos > espos[eschn]))
288       {
289         for (c = 0; c < MAX_CHN; c++)
290         {
291           if (eseditpos < songlen[esnum][c]) esend[c] = eseditpos;
292         }
293       }
294       else
295       {
296         for (c = 0; c < MAX_CHN; c++) esend[c] = 0;
297       }
298     }
299     break;
300 
301     case KEY_ENTER:
302     if (eseditpos < songlen[esnum][eschn])
303     {
304       if (!shiftpressed)
305       {
306         if (songorder[esnum][eschn][eseditpos] < MAX_PATT)
307           epnum[eschn] = songorder[esnum][eschn][eseditpos];
308       }
309       else
310       {
311         int c, d;
312 
313         for (c = 0; c < MAX_CHN; c++)
314         {
315           int start;
316 
317           if (eseditpos != espos[eschn]) start = eseditpos;
318           else start = espos[c];
319 
320           for (d = start; d < songlen[esnum][c]; d++)
321           {
322             if (songorder[esnum][c][d] < MAX_PATT)
323             {
324               epnum[c] = songorder[esnum][c][d];
325               break;
326             }
327           }
328         }
329       }
330       epmarkchn = -1;
331     }
332     epchn = eschn;
333     epcolumn = 0;
334     eppos = 0;
335     epview = - VISIBLEPATTROWS/2;
336     editmode = EDIT_PATTERN;
337     if (epchn == epmarkchn) epmarkchn = -1;
338     break;
339 
340     case KEY_DEL:
341     esmarkchn = -1;
342     deleteorder();
343     break;
344 
345     case KEY_INS:
346     esmarkchn = -1;
347     insertorder(0);
348     break;
349 
350     case KEY_HOME:
351     if (songlen[esnum][eschn])
352     {
353       while ((eseditpos != 0) || (escolumn != 0)) orderleft();
354     }
355     break;
356 
357     case KEY_END:
358     while (eseditpos != songlen[esnum][eschn]+1) orderright();
359     break;
360 
361     case KEY_PGUP:
362     for (scrrep = PGUPDNREPEAT * 2; scrrep; scrrep--)
363       orderleft();
364     break;
365 
366     case KEY_PGDN:
367     for (scrrep = PGUPDNREPEAT * 2; scrrep; scrrep--)
368       orderright();
369     break;
370 
371     case KEY_LEFT:
372     orderleft();
373     break;
374 
375     case KEY_RIGHT:
376     orderright();
377     break;
378 
379     case KEY_UP:
380     eschn--;
381     if (eschn < 0) eschn = MAX_CHN - 1;
382     if ((eseditpos == songlen[esnum][eschn]) || (eseditpos > songlen[esnum][eschn]+1))
383     {
384       eseditpos = songlen[esnum][eschn]+1;
385       escolumn = 0;
386     }
387     if (shiftpressed) esmarkchn = -1;
388     break;
389 
390     case KEY_DOWN:
391     eschn++;
392     if (eschn >= MAX_CHN) eschn = 0;
393     if ((eseditpos == songlen[esnum][eschn]) || (eseditpos > songlen[esnum][eschn]+1))
394     {
395       eseditpos = songlen[esnum][eschn]+1;
396       escolumn = 0;
397     }
398     if (shiftpressed) esmarkchn = -1;
399     break;
400   }
401   if (eseditpos - esview < 0)
402   {
403     esview = eseditpos;
404   }
405   if (eseditpos - esview >= VISIBLEORDERLIST)
406   {
407     esview = eseditpos - VISIBLEORDERLIST + 1;
408   }
409 }
410 
namecommands(void)411 void namecommands(void)
412 {
413   switch(rawkey)
414   {
415     case KEY_DOWN:
416     case KEY_ENTER:
417     enpos++;
418     if (enpos > 2) enpos = 0;
419     break;
420 
421     case KEY_UP:
422     enpos--;
423     if (enpos < 0) enpos = 2;
424     break;
425   }
426   switch(enpos)
427   {
428     case 0:
429     editstring(songname, MAX_STR);
430     break;
431 
432     case 1:
433     editstring(authorname, MAX_STR);
434     break;
435 
436     case 2:
437     editstring(copyrightname, MAX_STR);
438     break;
439   }
440 }
441 
insertorder(unsigned char byte)442 void insertorder(unsigned char byte)
443 {
444   if ((songlen[esnum][eschn] - eseditpos)-1 >= 0)
445   {
446     int len;
447     if (songlen[esnum][eschn] < MAX_SONGLEN)
448     {
449       len = songlen[esnum][eschn]+1;
450       songorder[esnum][eschn][len+1] =
451         songorder[esnum][eschn][len];
452       songorder[esnum][eschn][len] = LOOPSONG;
453       if (len) songorder[esnum][eschn][len-1] = byte;
454       countthispattern();
455     }
456     memmove(&songorder[esnum][eschn][eseditpos+1],
457       &songorder[esnum][eschn][eseditpos],
458       (songlen[esnum][eschn] - eseditpos)-1);
459     songorder[esnum][eschn][eseditpos] = byte;
460     len = songlen[esnum][eschn]+1;
461     if ((songorder[esnum][eschn][len] > eseditpos) &&
462        (songorder[esnum][eschn][len] < (len-2)))
463        songorder[esnum][eschn][len]++;
464   }
465   else
466   {
467     if (eseditpos > songlen[esnum][eschn])
468     {
469       if (songlen[esnum][eschn] < MAX_SONGLEN)
470       {
471         songorder[esnum][eschn][eseditpos+1] =
472           songorder[esnum][eschn][eseditpos];
473         songorder[esnum][eschn][eseditpos] = LOOPSONG;
474         if (eseditpos) songorder[esnum][eschn][eseditpos-1] = byte;
475         countthispattern();
476         eseditpos = songlen[esnum][eschn]+1;
477       }
478     }
479   }
480 }
481 
deleteorder(void)482 void deleteorder(void)
483 {
484   if ((songlen[esnum][eschn] - eseditpos)-1 >= 0)
485   {
486     int len;
487     memmove(&songorder[esnum][eschn][eseditpos],
488       &songorder[esnum][eschn][eseditpos+1],
489       (songlen[esnum][eschn] - eseditpos)-1);
490     songorder[esnum][eschn][songlen[esnum][eschn]-1] = 0x00;
491     if (songlen[esnum][eschn] > 0)
492     {
493       songorder[esnum][eschn][songlen[esnum][eschn]-1] =
494         songorder[esnum][eschn][songlen[esnum][eschn]];
495       songorder[esnum][eschn][songlen[esnum][eschn]] =
496         songorder[esnum][eschn][songlen[esnum][eschn]+1];
497       countthispattern();
498     }
499     if (eseditpos == songlen[esnum][eschn]) eseditpos++;
500     len = songlen[esnum][eschn]+1;
501     if ((songorder[esnum][eschn][len] > eseditpos) &&
502        (songorder[esnum][eschn][len] > 0))
503        songorder[esnum][eschn][len]--;
504   }
505   else
506   {
507     if (eseditpos > songlen[esnum][eschn])
508     {
509       if (songlen[esnum][eschn] > 0)
510       {
511         songorder[esnum][eschn][songlen[esnum][eschn]-1] =
512           songorder[esnum][eschn][songlen[esnum][eschn]];
513         songorder[esnum][eschn][songlen[esnum][eschn]] =
514           songorder[esnum][eschn][songlen[esnum][eschn]+1];
515         countthispattern();
516         eseditpos = songlen[esnum][eschn]+1;
517       }
518     }
519   }
520 }
521 
orderleft(void)522 void orderleft(void)
523 {
524   if ((shiftpressed) && (eseditpos < songlen[esnum][eschn]))
525   {
526     if ((esmarkchn != eschn) || (eseditpos != esmarkend))
527     {
528       esmarkchn = eschn;
529       esmarkstart = esmarkend = eseditpos;
530     }
531   }
532   escolumn--;
533   if (escolumn < 0)
534   {
535     if (eseditpos > 0)
536     {
537       eseditpos--;
538       if (eseditpos == songlen[esnum][eschn]) eseditpos--;
539       escolumn = 1;
540       if (eseditpos < 0)
541       {
542         eseditpos = 1;
543         escolumn = 0;
544       }
545     }
546     else escolumn = 0;
547   }
548   if ((shiftpressed) && (eseditpos < songlen[esnum][eschn])) esmarkend = eseditpos;
549 }
550 
orderright(void)551 void orderright(void)
552 {
553   if ((shiftpressed) && (eseditpos < songlen[esnum][eschn]))
554   {
555     if ((esmarkchn != eschn) || (eseditpos != esmarkend))
556     {
557       esmarkchn = eschn;
558       esmarkstart = esmarkend = eseditpos;
559     }
560   }
561   escolumn++;
562   if (escolumn > 1)
563   {
564     escolumn = 0;
565     if (eseditpos < (songlen[esnum][eschn]+1))
566     {
567       eseditpos++;
568       if (eseditpos == songlen[esnum][eschn]) eseditpos++;
569     }
570     else escolumn = 1;
571   }
572   if ((shiftpressed) && (eseditpos < songlen[esnum][eschn])) esmarkend = eseditpos;
573 }
574 
nextsong(void)575 void nextsong(void)
576 {
577   esnum++;
578   if (esnum >= MAX_SONGS) esnum = MAX_SONGS - 1;
579   songchange();
580 }
581 
prevsong(void)582 void prevsong(void)
583 {
584   esnum--;
585   if (esnum < 0) esnum = 0;
586   songchange();
587 }
588 
songchange(void)589 void songchange(void)
590 {
591   int c;
592 
593   for (c = 0; c < MAX_CHN; c++)
594   {
595     espos[c] = 0;
596     esend[c] = 0;
597     epnum[c] = c;
598   }
599   updateviewtopos();
600 
601   eppos = 0;
602   epview = - VISIBLEPATTROWS/2;
603   eseditpos = 0;
604   if (eseditpos == songlen[esnum][eschn]) eseditpos++;
605   esview = 0;
606   epmarkchn = -1;
607   esmarkchn = -1;
608   stopsong();
609 }
610 
updateviewtopos(void)611 void updateviewtopos(void)
612 {
613   int c, d;
614   for (c = 0; c < MAX_CHN; c++)
615   {
616     for (d = espos[c]; d < songlen[esnum][c]; d++)
617     {
618       if (songorder[esnum][c][d] < MAX_PATT)
619       {
620         epnum[c] = songorder[esnum][c][d];
621         break;
622       }
623     }
624   }
625 }
626