1 //
2 // GOATTRACKER v2 instrument editor
3 //
4 
5 #define GINSTR_C
6 
7 #include "goattrk2.h"
8 
9 INSTR instrcopybuffer;
10 int cutinstr = -1;
11 
12 int einum;
13 int eipos;
14 int eicolumn;
15 
instrumentcommands(void)16 void instrumentcommands(void)
17 {
18   switch(rawkey)
19   {
20     case 0x8:
21     case KEY_DEL:
22     if ((einum) && (shiftpressed) && (eipos < 9))
23     {
24       deleteinstrtable(einum);
25       clearinstr(einum);
26     }
27     break;
28 
29     case KEY_X:
30     if ((einum) && (shiftpressed) && (eipos < 9))
31     {
32       cutinstr = einum;
33       memcpy(&instrcopybuffer, &instr[einum], sizeof(INSTR));
34       clearinstr(einum);
35     }
36     break;
37 
38     case KEY_C:
39     if ((einum) && (shiftpressed) && (eipos < 9))
40     {
41       cutinstr = -1;
42       memcpy(&instrcopybuffer, &instr[einum], sizeof(INSTR));
43     }
44     break;
45 
46     case KEY_S:
47     if ((einum) && (shiftpressed) && (eipos < 9))
48     {
49       memcpy(&instr[einum], &instrcopybuffer, sizeof(INSTR));
50       if (cutinstr != -1)
51       {
52         int c, d;
53         for (c = 0; c < MAX_PATT; c++)
54         {
55           for (d = 0; d < pattlen[c]; d++)
56             if (pattern[c][d*4+1] == cutinstr) pattern[c][d*4+1] = einum;
57         }
58       }
59     }
60     break;
61 
62     case KEY_V:
63     if ((einum) && (shiftpressed) && (eipos < 9))
64     {
65       memcpy(&instr[einum], &instrcopybuffer, sizeof(INSTR));
66     }
67     break;
68 
69     case KEY_RIGHT:
70     if (eipos < 9)
71     {
72       eicolumn++;
73       if (eicolumn > 1)
74       {
75         eicolumn = 0;
76         eipos += 5;
77         if (eipos >= 9) eipos -= 10;
78         if (eipos < 0) eipos = 8;
79       }
80     }
81     break;
82 
83     case KEY_LEFT:
84     if (eipos < 9)
85     {
86       eicolumn--;
87       if (eicolumn < 0)
88       {
89         eicolumn = 1;
90         eipos -= 5;
91         if (eipos < 0) eipos += 10;
92         if (eipos >= 9) eipos = 8;
93       }
94     }
95     break;
96 
97     case KEY_DOWN:
98     if (eipos < 9)
99     {
100       eipos++;
101       if (eipos > 8) eipos = 0;
102     }
103     break;
104 
105     case KEY_UP:
106     if (eipos < 9)
107     {
108       eipos--;
109       if (eipos < 0) eipos = 8;
110     }
111     break;
112 
113     case KEY_N:
114     if ((eipos != 9) && (shiftpressed))
115     {
116       eipos = 9;
117       return;
118     }
119     break;
120 
121     case KEY_U:
122     if (shiftpressed)
123     {
124       etlock ^= 1;
125       validatetableview();
126     }
127     break;
128 
129     case KEY_SPACE:
130     if (eipos != 9)
131     {
132       if (!shiftpressed)
133         playtestnote(FIRSTNOTE + epoctave * 12, einum, epchn);
134       else
135         releasenote(epchn);
136     }
137     break;
138 
139     case KEY_ENTER:
140     if (!einum) break;
141     switch(eipos)
142     {
143       case 2:
144       case 3:
145       case 4:
146       case 5:
147       {
148         int pos;
149 
150         if (instr[einum].ptr[eipos-2])
151         {
152           if ((eipos == 5) && (shiftpressed))
153           {
154             instr[einum].ptr[STBL] = makespeedtable(instr[einum].ptr[STBL], finevibrato, 1) + 1;
155             break;
156           }
157           pos = instr[einum].ptr[eipos-2] - 1;
158         }
159         else
160         {
161           pos = gettablelen(eipos-2);
162           if (pos >= MAX_TABLELEN-1) pos = MAX_TABLELEN - 1;
163           if (shiftpressed) instr[einum].ptr[eipos-2] = pos + 1;
164         }
165         gototable(eipos-2, pos);
166       }
167       return;
168 
169       case 9:
170       eipos = 0;
171       break;
172     }
173     break;
174   }
175   if ((eipos == 9) && (einum)) editstring(instr[einum].name, MAX_INSTRNAMELEN);
176   if ((hexnybble >= 0) && (eipos < 9) && (einum))
177   {
178     unsigned char *ptr = &instr[einum].ad;
179     ptr += eipos;
180 
181     switch(eicolumn)
182     {
183       case 0:
184       *ptr &= 0x0f;
185       *ptr |= hexnybble << 4;
186       eicolumn++;
187       break;
188 
189       case 1:
190       *ptr &= 0xf0;
191       *ptr |= hexnybble;
192       eicolumn++;
193       if (eicolumn > 1)
194       {
195         eicolumn = 0;
196         eipos++;
197         if (eipos >= 9) eipos = 0;
198       }
199       break;
200     }
201   }
202   // Validate instrument parameters
203   if (einum)
204   {
205     if (!(instr[einum].gatetimer & 0x3f)) instr[einum].gatetimer |= 1;
206   }
207 }
208 
209 
clearinstr(int num)210 void clearinstr(int num)
211 {
212   memset(&instr[num], 0, sizeof(INSTR));
213   if (num)
214   {
215     if (multiplier)
216       instr[num].gatetimer = 2 * multiplier;
217     else
218       instr[num].gatetimer = 1;
219 
220     instr[num].firstwave = 0x9;
221   }
222 }
223 
gotoinstr(int i)224 void gotoinstr(int i)
225 {
226   if (i < 0) return;
227   if (i >= MAX_INSTR) return;
228 
229   einum = i;
230   showinstrtable();
231 
232   editmode = EDIT_INSTRUMENT;
233 }
234 
nextinstr(void)235 void nextinstr(void)
236 {
237   einum++;
238   if (einum >= MAX_INSTR) einum = MAX_INSTR - 1;
239   showinstrtable();
240 }
241 
previnstr(void)242 void previnstr(void)
243 {
244   einum--;
245   if (einum < 0) einum = 0;
246   showinstrtable();
247 }
248 
showinstrtable(void)249 void showinstrtable(void)
250 {
251   if (!etlock)
252   {
253     int c;
254 
255     for (c = MAX_TABLES-1; c >= 0; c--)
256     {
257       if (instr[einum].ptr[c])
258         settableviewfirst(c, instr[einum].ptr[c] - 1);
259     }
260   }
261 }
262 
263