Timing is correct now! Forgot to update samples_per_tick when parsing the 0xf effect.
[pineappletracker.git] / actions.c
blob11f93a2acace8edee73b297311e2683287bcde51
1 /* vi:set ts=8 sts=8 sw=8 noexpandtab: */
2 #include "pineapple.h"
3 #include "filetypes.h"
4 #include "gui.h"
6 #include <string.h>
8 static u8 _oldfxparam = 0;
10 /* move cursor left one column */
11 void act_mvleft(void){
12 switch(currtab){
13 case 0:
14 if(songx) songx--;
15 break;
16 case 1:
17 if(trackx) trackx--;
18 break;
19 case 2:
20 if(instrx) instrx--;
21 break;
25 /* move cursor right one column */
26 void act_mvright(void){
27 switch(currtab){
28 case 0:
29 if(songx < 15) songx++;
30 break;
31 case 1:
32 if(trackx < 9) trackx++;
33 break;
34 case 2:
35 if(instrx < 2) instrx++;
36 break;
40 /* move cursor up 1 line */
41 void act_mvup(void){
42 switch(currtab){
43 case 0:
44 if(songy){
45 songy--;
46 }else{
47 songy = 0;
49 break;
50 case 1:
51 if(tracky){
52 tracky--;
53 }else{
54 tracky = 0;
56 break;
57 case 2:
58 if(instry){
59 instry--;
60 }else{
61 instry = 0;
63 break;
67 /* move cursor down 1 line */
68 void act_mvdown(void){
69 switch(currtab){
70 case 0:
71 if(songy < tune->songlen - 1){
72 songy++;
73 }else{
74 songy = tune->songlen - 1;
76 break;
77 case 1:
78 if(tracky < tune->tracklen - 1){
79 tracky++;
80 }else{
81 tracky = tune->tracklen - 1;
83 break;
84 case 2:
85 if(instry < instrument[currinstr].length - 1){
86 instry++;
87 }else{
88 instry = instrument[currinstr].length - 1;
90 break;
94 /* move cursor up 8 lines */
95 void act_bigmvup(void){
96 switch(currtab){
97 case 0:
98 if(songy >= 8){
99 songy -= 8;
100 }else{
101 songy = 0;
103 break;
104 case 1:
105 if(tracky >= 8){
106 tracky -= 8;
107 }else{
108 tracky = 0;
110 break;
111 case 2:
112 if(instry >= 8) instry -= 8;
113 break;
117 /* move cursor down 8 lines */
118 void act_bigmvdown(void){
119 switch(currtab){
120 case 0:
121 if(songy < tune->songlen - 8){
122 songy += 8;
123 }else{
124 songy = tune->songlen - 1;
126 break;
127 case 1:
128 if(tracky < tune->tracklen - 8){
129 tracky += 8;
130 }else{
131 tracky = tune->tracklen - 1;
133 break;
134 case 2:
135 if(instry < instrument[currinstr].length - 8) instry += 8;
136 break;
140 void act_mvbottom(void){
141 switch(currtab){
142 case 0:
143 songy = tune->songlen - 1;
144 break;
145 case 1:
146 tracky = tune->tracklen - 1;
147 break;
148 case 2:
149 instry = instrument[currinstr].length - 1;
150 break;
154 void act_mvtop(void){
155 switch(currtab){
156 case 0:
157 songy = 0;
158 break;
159 case 1:
160 tracky = 0;
161 break;
162 case 2:
163 instry = 0;
164 break;
168 void act_viewtrackinc(void){
169 if(currtrack < 0xff){
170 currtrack++;
171 }else if(currtrack == 0xff){
172 currtrack = 1;
174 if(playtrack){
175 startplaytrack(currtrack);
179 void act_viewtrackdec(void){
180 if(currtrack > 1){
181 currtrack--;
182 }else if(currtrack == 1){
183 currtrack = 0xff;
185 if(playtrack){
186 startplaytrack(currtrack);
190 void act_viewinstrinc(void){
191 if(currinstr == 0xff) currinstr = 0x01;
192 else currinstr++;
195 void act_viewinstrdec(void){
196 if(currinstr == 1) currinstr = 0xff;
197 else currinstr--;
200 void act_trackinc(void){
201 if( (songx%2)==0 ){
202 if(songx >= 240 && songx < 256){
203 tune->sng[songy].track[songx/4] -= 240;
204 }else{
205 tune->sng[songy].track[songx/4] += 16;
207 }else{
208 if( (tune->sng[songy].track[songx/4] % 16) == 15){
209 tune->sng[songy].track[songx/4] -= 15;
210 }else{
211 tune->sng[songy].track[songx/4]++;
214 saved = 0;
217 void act_trackdec(void){
218 if( (songx%2)==0 ){
219 if(songx <= 15 && songx >= 0){
220 tune->sng[songy].track[songx/4] += 240;
221 }else{
222 tune->sng[songy].track[songx/4] -= 16;
224 }else{
225 if( (tune->sng[songy].track[songx/4] % 16) == 0){
226 tune->sng[songy].track[songx/4] += 15;
227 }else{
228 tune->sng[songy].track[songx/4]--;
231 saved = 0;
234 void act_transpinc(void){
235 if( (songx%2)==0 ){
236 if(songx >= 240 && songx < 256){
237 tune->sng[songy].transp[songx/4] -= 240;
238 }else{
239 tune->sng[songy].transp[songx/4] += 16;
241 }else{
242 if( (tune->sng[songy].transp[songx/4] % 16) == 15){
243 tune->sng[songy].transp[songx/4] -= 15;
244 }else{
245 tune->sng[songy].transp[songx/4]++;
248 saved = 0;
251 void act_transpdec(void){
252 if( (songx%2)==0 ){
253 if(songx <= 15 && songx >= 0){
254 tune->sng[songy].transp[songx/4] += 240;
255 }else{
256 tune->sng[songy].transp[songx/4] -= 16;
258 }else{
259 if( (tune->sng[songy].transp[songx/4] % 16) == 0){
260 tune->sng[songy].transp[songx/4] += 15;
261 }else{
262 tune->sng[songy].transp[songx/4]--;
265 saved = 0;
268 void act_undo(void){
271 void act_noteinc(void){
272 if(currtab==1){
273 // if current note < H7
274 if( tune->trk[currtrack].line[tracky].note < 96 ){
275 tune->trk[currtrack].line[tracky].note++;
276 }else{
277 tune->trk[currtrack].line[tracky].note = 0;
279 }else if(currtab==2){
280 if( instrument[currinstr].line[instry].param < 96 ){
281 instrument[currinstr].line[instry].param++;
282 }else{
283 instrument[currinstr].line[instry].param = 0;
286 saved = 0;
289 void act_notedec(void){
290 if(currtab==1){
291 if( tune->trk[currtrack].line[tracky].note > 0 ){
292 tune->trk[currtrack].line[tracky].note--;
293 }else{
294 tune->trk[currtrack].line[tracky].note = 96;
296 }else if(currtab==2){
297 if( instrument[currinstr].line[instry].param > 0 ){
298 instrument[currinstr].line[instry].param--;
299 }else{
300 instrument[currinstr].line[instry].param = 96;
303 saved = 0;
306 void act_octaveinc(void){
307 if(currtab==1){
308 if( tune->trk[currtrack].line[tracky].note+12 <= 96 ){
309 tune->trk[currtrack].line[tracky].note+=12;
310 }else{
311 tune->trk[currtrack].line[tracky].note %= 12;
313 }else if(currtab==2){ if(instrument[currinstr].line[instry].cmd == '+' || instrument[currinstr].line[instry].cmd == '='){
314 if( instrument[currinstr].line[instry].param+12 <= 96 ){
315 instrument[currinstr].line[instry].param+=12;
316 }else{
317 instrument[currinstr].line[instry].param %= 12;
321 saved = 0;
324 void act_octavedec(void){
325 if(currtab==1){
326 if( tune->trk[currtrack].line[tracky].note-12 > 0 ){
327 tune->trk[currtrack].line[tracky].note-=12;
328 }else{
329 tune->trk[currtrack].line[tracky].note = 84 + tune->trk[currtrack].line[tracky].note;
331 }else if(currtab==2){
332 if(instrument[currinstr].line[instry].cmd == '+' || instrument[currinstr].line[instry].cmd == '='){
333 if( instrument[currinstr].line[instry].param-12 > 0 ){
334 instrument[currinstr].line[instry].param-=12;
335 }else{
336 instrument[currinstr].line[instry].param = 84 + instrument[currinstr].line[instry].param;
340 saved = 0;
343 void act_instrinc(void){
344 switch(trackx){
345 case 2:
346 SETHI(tune->trk[currtrack].line[tracky].instr,
347 hexinc(tune->trk[currtrack].line[tracky].instr >> 4) );
348 break;
349 case 3:
350 SETLO(tune->trk[currtrack].line[tracky].instr,
351 hexinc(tune->trk[currtrack].line[tracky].instr & 0x0f) );
352 break;
354 saved = 0;
357 void act_instrdec(void){
358 switch(trackx){
359 case 2:
360 SETHI(tune->trk[currtrack].line[tracky].instr,
361 hexdec(tune->trk[currtrack].line[tracky].instr >> 4) );
362 break;
363 case 3:
364 SETLO(tune->trk[currtrack].line[tracky].instr,
365 hexdec(tune->trk[currtrack].line[tracky].instr & 0x0f) );
366 break;
368 saved = 0;
371 void act_fxinc(void){
372 if(currtab==1){
373 currcmd = tune->trk[currtrack].line[tracky].cmd[trackx % 2];
374 // there must be a better way to do this...
375 if((unsigned long)currcmd == (unsigned long)NULL){
376 tune->trk[currtrack].line[tracky].cmd[trackx % 2] = validcmds[0];
377 }else{
378 for(int z = 0; z < strlen(validcmds); z++){
379 if(currcmd == validcmds[z]){
380 if(z == (strlen(validcmds)-1)){
381 tune->trk[currtrack].line[tracky].cmd[trackx % 2] = (unsigned long)NULL;
382 }else{
383 tune->trk[currtrack].line[tracky].cmd[trackx % 2] = validcmds[z+1];
385 continue;
389 }else if(currtab==2){
390 currcmd = instrument[currinstr].line[instry].cmd;
391 for(int z = 0; z < strlen(validcmds); z++){
392 if(currcmd == validcmds[z]){
393 if(z == (strlen(validcmds)-1)){
394 instrument[currinstr].line[instry].cmd = validcmds[0];
395 }else{
396 instrument[currinstr].line[instry].cmd = validcmds[z+1];
397 if(_oldfxparam)
398 instrument[currinstr].line[instry].param = _oldfxparam;
401 // when switching to the note command, change to param if it's
402 // higher than H7
403 if((instrument[currinstr].line[instry].cmd == '+' || instrument[currinstr].line[instry].cmd == '=')
404 //&& _oldfxparam
405 && instrument[currinstr].line[instry].param>96){
406 // save current param
407 _oldfxparam = instrument[currinstr].line[instry].param;
408 instrument[currinstr].line[instry].param = 96; //H7
409 }else if(_oldfxparam){
410 instrument[currinstr].line[instry].param = _oldfxparam;
411 _oldfxparam = 0;
414 continue;
418 saved = 0;
421 void act_fxdec(void){
422 if(currtab==1){
423 currcmd = tune->trk[currtrack].line[tracky].cmd[trackx % 2];
424 if((unsigned long)currcmd == (unsigned long)NULL){
425 tune->trk[currtrack].line[tracky].cmd[trackx % 2] = validcmds[strlen(validcmds)-1];
426 }else{
427 for(int z = 0; z < strlen(validcmds); z++){
428 if(currcmd == validcmds[z]){
429 if(z==0){
430 tune->trk[currtrack].line[tracky].cmd[trackx % 2] = (unsigned long)NULL;
431 }else{
432 tune->trk[currtrack].line[tracky].cmd[trackx % 2] = validcmds[z-1];
434 continue;
438 }else if(currtab==2){
439 currcmd = instrument[currinstr].line[instry].cmd;
440 for(int z = 0; z < strlen(validcmds); z++){
441 if(currcmd == validcmds[z]){
442 if(z==0){
443 instrument[currinstr].line[instry].cmd = validcmds[strlen(validcmds)-1];
444 }else{
445 instrument[currinstr].line[instry].cmd = validcmds[z-1];
446 if(_oldfxparam)
447 instrument[currinstr].line[instry].param = _oldfxparam;
450 // when switching to the note command, change to param if it's
451 // higher than H7
452 if((instrument[currinstr].line[instry].cmd == '+' || instrument[currinstr].line[instry].cmd == '=')
453 //&& _oldfxparam
454 && instrument[currinstr].line[instry].param>96){
455 // save current param
456 _oldfxparam = instrument[currinstr].line[instry].param;
457 instrument[currinstr].line[instry].param = 96; //H7
458 }else if(_oldfxparam){
459 instrument[currinstr].line[instry].param = _oldfxparam;
460 _oldfxparam = 0;
463 continue;
467 saved = 0;
470 void act_paraminc(void){
471 if(currtab==1){
472 if((trackx==5 && tune->trk[currtrack].line[tracky].cmd[0])
473 || (trackx==8 && tune->trk[currtrack].line[tracky].cmd[1])){
474 SETHI(tune->trk[currtrack].line[tracky].param[(trackx - 1) % 2],
475 hexinc(tune->trk[currtrack].line[tracky].param[(trackx - 1) % 2] >> 4) );
476 return;
477 }else if((trackx==6 && tune->trk[currtrack].line[tracky].cmd[0])
478 || (trackx==9 && tune->trk[currtrack].line[tracky].cmd[1])){
479 SETLO(tune->trk[currtrack].line[tracky].param[trackx % 2],
480 hexinc(tune->trk[currtrack].line[tracky].param[trackx % 2] & 0x0f) );
481 return;
483 }else if(currtab == 2){
484 if(instrx == 1){
485 SETHI(instrument[currinstr].line[instry].param,
486 hexinc(instrument[currinstr].line[instry].param >> 4) );
487 return;
488 }else if(instrx == 2){
489 SETLO(instrument[currinstr].line[instry].param,
490 hexinc(instrument[currinstr].line[instry].param & 0x0f) );
491 return;
494 saved = 0;
497 void act_paramdec(void){
498 if(currtab==1){
499 if((trackx==5 && tune->trk[currtrack].line[tracky].cmd[0])
500 || (trackx==8 && tune->trk[currtrack].line[tracky].cmd[1])){
501 SETHI(tune->trk[currtrack].line[tracky].param[(trackx-1) % 2],
502 hexdec(tune->trk[currtrack].line[tracky].param[(trackx-1) % 2] >> 4) );
503 return;
504 }else if((trackx==6 && tune->trk[currtrack].line[tracky].cmd[0])
505 || (trackx==9 && tune->trk[currtrack].line[tracky].cmd[1])){
506 SETLO(tune->trk[currtrack].line[tracky].param[trackx % 2],
507 hexdec(tune->trk[currtrack].line[tracky].param[trackx % 2] & 0x0f) );
508 return;
510 }else if(currtab == 2){
511 if(instrx == 1){
512 SETHI(instrument[currinstr].line[instry].param,
513 hexdec(instrument[currinstr].line[instry].param >> 4) );
514 return;
515 }else if(instrx == 2){
516 SETLO(instrument[currinstr].line[instry].param,
517 hexdec(instrument[currinstr].line[instry].param & 0x0f) );
518 return;
521 saved = 0;
524 void act_addline(void){
525 if(currtab == 2){
526 struct instrument *in = &instrument[currinstr];
528 if(in->length < 256){
529 memmove(&in->line[instry + 2], &in->line[instry + 1], sizeof(struct instrline) * (in->length - instry - 1));
530 instry++;
531 in->length++;
532 in->line[instry].cmd = '0';
533 in->line[instry].param = 0;
535 }else if(currtab == 0){
536 if(tune->songlen < 256){
537 memmove(&tune->sng[songy + 2], &tune->sng[songy + 1], sizeof(struct songline) * (tune->songlen - songy - 1));
538 songy++;
539 tune->songlen++;
540 memset(&tune->sng[songy], 0, sizeof(struct songline));
543 saved = 0;
546 void act_delline(void){
547 if(currtab == 2){
548 struct instrument *in = &instrument[currinstr];
550 if(in->length > 1){
551 memmove(&in->line[instry + 0], &in->line[instry + 1], sizeof(struct instrline) * (in->length - instry - 1));
552 in->length--;
553 if(instry >= in->length) instry = in->length - 1;
555 }else if(currtab == 0){
556 if(tune->songlen > 1){
557 memmove(&tune->sng[songy + 0], &tune->sng[songy + 1], sizeof(struct songline) * (tune->songlen - songy - 1));
558 tune->songlen--;
559 if(songy >= tune->songlen) songy = tune->songlen - 1;
562 saved = 0;
565 void act_clronething(void){
566 if(currtab == 0){
567 if( (songx%4) < 2){
568 if( (songx%2)==0 ){
569 tune->sng[songy].track[songx/4] = (tune->sng[songy].track[songx/4] - tune->sng[songy].track[songx/4]) + tune->sng[songy].track[songx/4]%16;
570 }else{
571 tune->sng[songy].track[songx/4] -= tune->sng[songy].track[songx/4]%16;
573 }else{
574 if( (songx%2)==0 ){
575 tune->sng[songy].transp[songx/4] = (tune->sng[songy].transp[songx/4] - tune->sng[songy].transp[songx/4]) + tune->sng[songy].transp[songx/4]%16;
576 }else{
577 tune->sng[songy].transp[songx/4] -= tune->sng[songy].transp[songx/4]%16;
580 //memcpy(&tclip, &tune->sng[songy], sizeof(struct songline));
581 }else if(currtab == 1){
582 switch(trackx){
583 case 0:
584 memcpy(&tclip, &tune->trk[currtrack].line[tracky], sizeof(struct trackline));
585 tune->trk[currtrack].line[tracky].note = 0;
586 tune->trk[currtrack].line[tracky].instr = 0;
587 //memmove
588 break;
589 case 2:
590 memcpy(&tclip, &tune->trk[currtrack].line[tracky].instr, sizeof(struct trackline));
591 SETHI(tune->trk[currtrack].line[tracky].instr, 0);
592 break;
593 case 3:
594 memcpy(&tclip, &tune->trk[currtrack].line[tracky].instr, sizeof(struct trackline));
595 SETLO(tune->trk[currtrack].line[tracky].instr, 0);
596 break;
597 case 4:
598 tune->trk[currtrack].line[tracky].cmd[0] = 0;
599 break;
600 case 5:
601 SETHI(tune->trk[currtrack].line[tracky].param[0],0);
602 break;
603 case 6:
604 SETLO(tune->trk[currtrack].line[tracky].param[0],0);
605 break;
606 case 7:
607 tune->trk[currtrack].line[tracky].cmd[1] = 0;
608 break;
609 case 8:
610 SETHI(tune->trk[currtrack].line[tracky].param[1],0);
611 break;
612 case 9:
613 SETLO(tune->trk[currtrack].line[tracky].param[1],0);
614 break;
615 default:
616 setdisplay("in ACT_CLRONETHING");
617 break;
619 }else if(currtab == 2){
620 if(instrx == 0){
621 instrument[currinstr].line[instry].cmd = '0';
622 }else if(instrx == 1){
623 if(instrument[currinstr].line[instry].cmd == '+' || instrument[currinstr].line[instry].cmd == '='){
624 instrument[currinstr].line[instry].param = 0;
625 }else{
626 SETHI(instrument[currinstr].line[instry].param,0);
628 }else if(instrx == 2){
629 if(instrument[currinstr].line[instry].cmd == '+' || instrument[currinstr].line[instry].cmd == '='){
630 instrument[currinstr].line[instry].param = 0;
631 }else{
632 SETLO(instrument[currinstr].line[instry].param,0);
636 saved = 0;
639 void act_clritall(void){
640 if(currtab == 0){
641 for(int ci = 0; ci < 4; ci++){
642 tune->sng[songy].track[ci] = 0;
643 tune->sng[songy].transp[ci] = 0;
645 }else if(currtab == 1){
646 tune->trk[currtrack].line[tracky].note = 0;
647 tune->trk[currtrack].line[tracky].instr = 0;
648 SETHI(tune->trk[currtrack].line[tracky].instr, 0);
649 SETLO(tune->trk[currtrack].line[tracky].instr, 0);
650 tune->trk[currtrack].line[tracky].cmd[0] = 0;
651 SETHI(tune->trk[currtrack].line[tracky].param[0],0);
652 SETLO(tune->trk[currtrack].line[tracky].param[0],0);
653 tune->trk[currtrack].line[tracky].cmd[1] = 0;
654 SETHI(tune->trk[currtrack].line[tracky].param[1],0);
655 SETLO(tune->trk[currtrack].line[tracky].param[1],0);
656 }else if(currtab == 2){
657 instrument[currinstr].line[instry].cmd = '0';
658 instrument[currinstr].line[instry].param = 0;
660 saved = 0;
663 // clear line y in the song tab
664 void act_clrinsongtab(int y){
665 for(int ci = 0; ci < 4; ci++){
666 tune->sng[songy].track[ci] = 0;
667 tune->sng[songy].transp[ci] = 0;
669 saved = 0;
672 void act_clrintracktab(int t, int y){
673 tune->trk[t].line[y].note = 0;
674 tune->trk[t].line[y].instr = 0;
675 SETHI(tune->trk[t].line[y].instr, 0);
676 SETLO(tune->trk[t].line[y].instr, 0);
677 tune->trk[t].line[y].cmd[0] = 0;
678 SETHI(tune->trk[t].line[y].param[0],0);
679 SETLO(tune->trk[t].line[y].param[0],0);
680 tune->trk[t].line[y].cmd[1] = 0;
681 SETHI(tune->trk[t].line[y].param[1],0);
682 SETLO(tune->trk[t].line[y].param[1],0);
683 saved = 0;
686 void act_clrininstrtab(int instr, int y){
687 instrument[instr].line[y].cmd = '0';
688 instrument[instr].line[y].param = 0;
689 saved = 0;