1 /* vi:set syntax= ts=8 sts=8 sw=8 noexpandtab: */
2 /* WARNING: this file is ROSS STYLE */
6 #include "musicchip_file.h"
9 int tcliplen
, icliplen
= 0;
12 int _hexdigit(char c
);
13 int _nextfreetrack(void);
14 int _nextfreeinstr(void);
16 /* Let's make a linked list! */
17 /* Here's a great generic implementation:
18 * http://en.literateprograms.org/Singly_linked_list_(C)
20 /*NODE *list_create(void *e){
22 if(!(n=malloc(sizeof(NODE)))) return NULL;
28 NODE *list_insertafter(NODE *oldnode, void *newelement){
30 newnode = list_create(newelement);
31 newnode->next = oldnode->next;
32 oldnode->next = newnode;
36 // have a look at this wizardry! wow. what does int(*func) do?
37 NODE *list_contains(NODE *n, int (*func) (void *, void *), void *match){
39 if(func(n->element, match) > 0) return n;
45 int findu8(void *a, void *b){
49 int _hexdigit(char c
){
50 if(c
>= '0' && c
<= '9') return c
- '0';
51 if(c
>= 'a' && c
<= 'f') return c
- 'a' + 10;
58 for(int i
= 1; i
<= 0xff; i
++){
59 for(int j
= 0; j
< tracklen
; j
++){
60 if(track
[i
].line
[j
].note
) skiptherest
= 1;
61 for(int k
= 0; k
< 2; k
++){
62 if(track
[i
].line
[j
].cmd
[k
]) skiptherest
= 1;
63 if(track
[i
].line
[j
].param
[k
]) skiptherest
= 1;
66 // skip the rest of this track?
72 // this track is free, so return the index
73 if(j
== tracklen
-1) return i
;
77 setdisplay("_nextfreetrack() failed somehow..");
82 for(int i
= 1; i
<= 0xff; i
++){
83 if(instrument
[i
].line
[0].cmd
== '0')
87 setdisplay("_nextfreeinstr() failed somehow..");
98 && instrument
[currinstr
].line
[instry
].cmd
!= '+'
99 && instrument
[currinstr
].line
[instry
].cmd
!= '='){
101 case 1: SETHI(instrument
[currinstr
].line
[instry
].param
, x
); break;
102 case 2: SETLO(instrument
[currinstr
].line
[instry
].param
, x
); break;
105 if(currtab
== 1 && trackx
> 1){
107 case 2: SETHI(track
[currtrack
].line
[tracky
].instr
, x
); break;
108 case 3: SETLO(track
[currtrack
].line
[tracky
].instr
, x
); break;
109 case 5: if(track
[currtrack
].line
[tracky
].cmd
[0])
110 SETHI(track
[currtrack
].line
[tracky
].param
[0], x
); break;
111 case 6: if(track
[currtrack
].line
[tracky
].cmd
[0])
112 SETLO(track
[currtrack
].line
[tracky
].param
[0], x
); break;
113 case 8: if(track
[currtrack
].line
[tracky
].cmd
[1])
114 SETHI(track
[currtrack
].line
[tracky
].param
[1], x
); break;
115 case 9: if(track
[currtrack
].line
[tracky
].cmd
[1])
116 SETLO(track
[currtrack
].line
[tracky
].param
[1], x
); break;
121 case 0: SETHI(song
[songy
].track
[songx
/ 4], x
); break;
122 case 1: SETLO(song
[songy
].track
[songx
/ 4], x
); break;
123 case 2: SETHI(song
[songy
].transp
[songx
/ 4], x
); break;
124 case 3: SETLO(song
[songy
].transp
[songx
/ 4], x
); break;
132 && (instrument
[currinstr
].line
[instry
].cmd
== '+' || instrument
[currinstr
].line
[instry
].cmd
== '=')){
133 instrument
[currinstr
].line
[instry
].param
= x
;
135 if(currtab
== 1 && !trackx
){
136 track
[currtrack
].line
[tracky
].note
= x
;
138 track
[currtrack
].line
[tracky
].instr
= currinstr
;
140 track
[currtrack
].line
[tracky
].instr
= 0;
142 if(x
) iedplonk(x
, currinstr
);
145 if(currtab
== 2 && instrx
== 0){
146 if(strchr(validcmds
, c
))
147 instrument
[currinstr
].line
[instry
].cmd
= c
;
149 if(currtab
== 1 && (trackx
== 4 || trackx
== 7)){
150 if(strchr(validcmds
, c
)){
151 if(c
== '.' || c
== '0') c
= 0;
152 track
[currtrack
].line
[tracky
].cmd
[(trackx
- 3) / 3] = c
;
159 // isnumber() determines if a string is a number
160 // returns 1 if the given arg is a number, 0 otherwise.
161 // for use with isdigit(), isxdigit(), etc...
162 int isnumber(const int* str
, int (*func
) (int)){
168 }else if( str
[i
]=='\0' ){
176 // Converts a hexadecimal string to integer
178 // 0: conversion successful
179 // 1: string is empty
180 // 2: string has more than 8 bytes
181 // 4: Conversion is in process but abnormally terminated by
182 // illegal hexadecimal character
183 // from http://devpinoy.org/blogs/cvega/archive/2006/06/19/xtoi-hex-to-integer-c-function.aspx
184 int xtoi(const char* xs
, unsigned int* result
){
185 size_t szlen
= strlen(xs
);
189 // Converting more than 32bit hexadecimal value?
190 if (szlen
>8) return 2; // exit
192 // Begin conversion here
196 // Run until no more character to convert
197 for(i
=szlen
-1; i
>=0 ;i
--){
198 if(isxdigit(*(xs
+i
))){
200 xv
= ( *(xs
+i
) - 97) + 10;
201 }else if( *(xs
+i
) >= 65){
202 xv
= (*(xs
+i
) - 65) + 10;
206 *result
+= (xv
* fact
);
209 // Conversion was abnormally terminated
210 // by non hexadecimal digit, hence
211 // returning only the converted with
212 // an error value 4 (illegal hex character)
217 // Nothing to convert
221 void _parsecmd(char cmd
[]){
224 if(strcmp(cmd
, ":w") == 0){
227 }else if(strcmp(cmd
, ":q") == 0){
229 setdisplay("no write since last change! use :q! to override");
236 }else if(strcmp(cmd
, ":q!") == 0){
241 }else if(strcmp(cmd
, ":write") == 0){
244 }else if(strcmp(cmd
, ":wq") == 0){
251 }else if(strcmp(cmd
, ":quit") == 0){
256 }else if(cmd
[1]=='e' && cmd
[2]==' '){
257 // if the file doesn't exist, clear the song
263 //yucky if statement below.....probably better way to do it
264 }else if(cmd
[1]=='s' &&
269 saveinstrument(cmd
+6);
270 setdisplay("d-_-b saved ins! d-_-b");
271 }else if(cmd
[1]=='l' &&
276 loadinstrument(cmd
+6);
277 setdisplay("d-_-b loaded ins! d-_-b");
278 }else if( isnumber((int *)cmd
+1,isxdigit
) ){
279 unsigned int goton
= 1;
284 songy
= (goton
>songlen
)? songlen
-1 : goton
;
287 currtrack
= (goton
>0xff)? 0xff : goton
;
290 currinstr
= (goton
>0xff)? 0xff : goton
;
293 }else if(cmd
[1] == 'c' && cmd
[2] == ' '){
294 strncpy(comment
, cmd
+3, sizeof(comment
));
296 setdisplay("not a tracker command!");
301 void normalmode(int c
){
304 // don't save the action for repeat if it's a movement or a repeat, or
305 // something else that doesnt make sense to repeat
321 lastrepeatnum
= cmdrepeatnum
;
324 for(i
=0; i
<cmdrepeatnum
; i
++){
329 struct instrument
*in
= &instrument
[currinstr
];
331 if(in
->length
< 256){
332 memmove(&in
->line
[instry
+ 2], &in
->line
[instry
+ 1], sizeof(struct instrline
) * (in
->length
- instry
- 1));
335 in
->line
[instry
].cmd
= '0';
336 in
->line
[instry
].param
= 0;
338 }else if(currtab
== 0){
340 memmove(&song
[songy
+ 2], &song
[songy
+ 1], sizeof(struct songline
) * (songlen
- songy
- 1));
343 memset(&song
[songy
], 0, sizeof(struct songline
));
348 // if the last command was a replace, just insert the last thing
349 // inserted instead of calling insertmode()
350 if(lastaction
== 'r')
351 _insertc(lastinsert
);
353 normalmode(lastaction
);
354 cmdrepeatnum
= lastrepeatnum
;
364 if(songy
==getmaxy(stdscr
)-3+songoffs
)
371 if(tracky
==getmaxy(stdscr
)-3+trackoffs
)
378 if(instry
==getmaxy(stdscr
)-3+instroffs
)
388 if(songy
<=songlen
-2){
395 if(tracky
<=tracklen
-2){
396 if(tracky
==trackoffs
)
402 if(instry
<=instrument
[currinstr
].length
-2){
403 if(instry
==instroffs
)
424 // the second cases (to the right of the colon) for M and L
425 // took some serious guesswork, so I'm not sure if they're
426 // correct but they seem to work.
430 songy
= (songlen
<= getmaxy(stdscr
)-2)?
432 : ((getmaxy(stdscr
)-6)/2) + songoffs
;
435 tracky
= (tracklen
<= getmaxy(stdscr
)-2)?
437 : ((getmaxy(stdscr
)-6)/2) + trackoffs
;
440 instry
= (instrument
[currinstr
].length
<= getmaxy(stdscr
)-2)?
441 instrument
[currinstr
].length
/2
442 : ((getmaxy(stdscr
)-6)/2) + instroffs
;
449 songy
= (songlen
<= getmaxy(stdscr
)-2)?
451 : getmaxy(stdscr
)-3+songoffs
;
454 tracky
= (tracklen
<= getmaxy(stdscr
)-2)?
456 : getmaxy(stdscr
)-3+trackoffs
;
459 instry
= (instrument
[currinstr
].length
<= getmaxy(stdscr
)-2)?
460 instrument
[currinstr
].length
-1
461 : getmaxy(stdscr
)-3+instroffs
;
466 if(nextchar() == 'g'){
482 memcpy(&tclip
, &song
[songy
], sizeof(struct songline
));
483 }else if(currtab
== 1){
485 memcpy(&tclip
, &track
[currtrack
].line
[tracky
], sizeof(struct trackline
));
486 }else if(currtab
== 2){
488 memcpy(&iclip
, &instrument
[currinstr
].line
[instry
], sizeof(struct instrline
));
495 memcpy(&tclip
[0], &song
[songy
], sizeof(struct songline
));
497 memcpy(&tclip
[1], &song
[songy
], sizeof(struct songline
));
498 }else if(currtab
== 1){
500 memcpy(&tclip
[0], &track
[currtrack
].line
[tracky
], sizeof(struct trackline
));
502 memcpy(&tclip
[1], &track
[currtrack
].line
[tracky
], sizeof(struct trackline
));
503 }else if(currtab
== 2){
505 memcpy(&iclip
[0], &instrument
[currinstr
].line
[instry
], sizeof(struct instrline
));
507 memcpy(&iclip
[1], &instrument
[currinstr
].line
[instry
], sizeof(struct instrline
));
514 memcpy(&tclip
[1], &song
[songy
], sizeof(struct songline
));
516 memcpy(&tclip
[0], &song
[songy
], sizeof(struct songline
));
517 }else if(currtab
== 1){
519 memcpy(&tclip
[1], &track
[currtrack
].line
[tracky
], sizeof(struct trackline
));
521 memcpy(&tclip
[0], &track
[currtrack
].line
[tracky
], sizeof(struct trackline
));
522 }else if(currtab
== 2){
524 memcpy(&iclip
[1], &instrument
[currinstr
].line
[instry
], sizeof(struct instrline
));
526 memcpy(&iclip
[0], &instrument
[currinstr
].line
[instry
], sizeof(struct instrline
));
536 for(int i
= 0; i
< tcliplen
; i
++){
538 memmove(&song
[songy
+ 2], &song
[songy
+ 1], sizeof(struct songline
) * (songlen
- songy
- 1));
541 memset(&song
[songy
], 0, sizeof(struct songline
));
544 memcpy(&song
[songy
], &tclip
[i
], sizeof(struct songline
));
547 }else if(currtab
== 1){
548 for(int i
= 0; i
< tcliplen
; i
++){
549 memcpy(&track
[currtrack
].line
[tracky
], &tclip
[i
], sizeof(struct trackline
));
550 if(tracky
< tracklen
-step
) tracky
+= step
;
551 else tracky
= tracklen
-1;
553 }else if(currtab
== 2){
554 if(instrument
[currinstr
].length
< 256){
556 for(int i
= 0; i
< icliplen
; i
++){
557 struct instrument
*in
= &instrument
[currinstr
];
560 memmove(&in
->line
[instry
+ 1], &in
->line
[instry
+ 0], sizeof(struct instrline
) * (in
->length
- instry
));
562 in
->line
[instry
].cmd
= '0';
563 in
->line
[instry
].param
= 0;
566 memcpy(&instrument
[currinstr
].line
[instry
], &iclip
[i
], sizeof(struct instrline
));
569 //if(instry < instrument[currinstr].length-1) instry++;
573 // copy everything in the current phrase or instrument into the next free one
576 f
= _nextfreetrack();
577 memcpy(&track
[f
], &track
[currtrack
], sizeof(struct track
));
579 }else if(currtab
== 2){
580 f
= _nextfreeinstr();
581 memcpy(&instrument
[f
], &instrument
[currinstr
], sizeof(struct instrument
));
586 // TODO: Y and P can be removed after we make visual mode
587 // copy whole phrase or instrument
590 memcpy(&tclip
, &track
[currtrack
], sizeof(struct track
));
591 }else if(currtab
== 2){
592 memcpy(&iclip
, &instrument
[currinstr
], sizeof(struct instrument
));
595 // paste whole phrase or instrument
598 memcpy(&track
[currtrack
], &tclip
, sizeof(struct track
));
599 }else if(currtab
== 2){
600 memcpy(&instrument
[currinstr
], &iclip
, sizeof(struct instrument
));
605 // TODO: clean this SHIT up
606 // TODO: add an ACT_ function for delete
612 struct instrument
*in
= &instrument
[currinstr
];
615 memmove(&in
->line
[instry
+ 0], &in
->line
[instry
+ 1], sizeof(struct instrline
) * (in
->length
- instry
- 1));
617 if(instry
>= in
->length
) instry
= in
->length
- 1;
619 }else if(currtab
== 0){
621 memmove(&song
[songy
+ 0], &song
[songy
+ 1], sizeof(struct songline
) * (songlen
- songy
- 1));
623 if(songy
>= songlen
) songy
= songlen
- 1;
629 struct instrument
*in
= &instrument
[currinstr
];
634 memmove(&in
->line
[instry
+ 0], &in
->line
[instry
+ 1], sizeof(struct instrline
) * (in
->length
- instry
- 1));
636 if(instry
>= in
->length
) instry
= in
->length
- 1;
639 }else if(currtab
== 0){
644 memmove(&song
[songy
+ 0], &song
[songy
+ 1], sizeof(struct songline
) * (songlen
- songy
- 1));
646 if(songy
>= songlen
) songy
= songlen
- 1;
653 struct instrument
*in
= &instrument
[currinstr
];
658 memmove(&in
->line
[instry
+ 0], &in
->line
[instry
+ 1], sizeof(struct instrline
) * (in
->length
- instry
- 1));
660 if(instry
>= in
->length
) instry
= in
->length
- 1;
663 }else if(currtab
== 0){
667 memmove(&song
[songy
+ 0], &song
[songy
+ 1], sizeof(struct songline
) * (songlen
- songy
- 1));
669 if(songy
>= songlen
) songy
= songlen
- 1;
690 startplaytrack(currtrack
);
691 }else if(currtab
== 0){
693 startplaysong(songy
);
715 /* Enter command mode */
722 // TODO: make an act_ function for '`'
725 int t
= song
[songy
].track
[songx
/ 4];
729 startplaytrack(currtrack
);
731 }else if((currtab
== 1) && ((trackx
== 2) || (trackx
== 3))){
732 int i
= track
[currtrack
].line
[tracky
].instr
;
735 } else if(currtab
== 1){
737 }else if(currtab
== 2){
741 /* Enter insert mode */
745 /* Enter visual mode */
749 /* Enter visual line mode */
753 /* enter jammer mode */
757 /* Add new line and enter insert mode */
760 struct instrument
*in
= &instrument
[currinstr
];
762 if(in
->length
< 256){
763 memmove(&in
->line
[instry
+ 2], &in
->line
[instry
+ 1], sizeof(struct instrline
) * (in
->length
- instry
- 1));
766 in
->line
[instry
].cmd
= '0';
767 in
->line
[instry
].param
= 0;
769 }else if(currtab
== 0){
771 memmove(&song
[songy
+ 2], &song
[songy
+ 1], sizeof(struct songline
) * (songlen
- songy
- 1));
774 memset(&song
[songy
], 0, sizeof(struct songline
));
799 if(octave
< 8) octave
++;
802 if(currtrack
> 1) currtrack
--;
805 if(currtrack
< 255) currtrack
++;
814 }else if(currtab
== 1){
846 }else if(currtab
== 2){
852 if(instrument
[currinstr
].line
[instry
].cmd
== '+' || instrument
[currinstr
].line
[instry
].cmd
== '='){
859 if(instrument
[currinstr
].line
[instry
].cmd
== '+' || instrument
[currinstr
].line
[instry
].cmd
== '='){
875 }else if(currtab
== 1){
907 }else if(currtab
== 2){
913 if(instrument
[currinstr
].line
[instry
].cmd
== '+' || instrument
[currinstr
].line
[instry
].cmd
== '='){
920 if(instrument
[currinstr
].line
[instry
].cmd
== '+' || instrument
[currinstr
].line
[instry
].cmd
== '='){
932 }else if(currtab
== 1){
939 }else if(currtab
== 1){
988 _insertc(nextchar());
999 /* vi cmdline mode */
1000 void cmdlinemode(void){
1002 keypad(stdscr
, TRUE
);
1004 currmode
= PM_CMDLINE
;
1005 strncat(cmdstr
, ":", 50);
1013 currmode
= PM_NORMAL
;
1021 cmdstr
[strlen(cmdstr
)-1] = '\0';
1027 strncat(cmdstr
, &c
, 50);
1033 keypad(stdscr
, FALSE
);
1037 /* vi insert mode */
1038 void insertmode(void){
1040 currmode
= PM_INSERT
;
1043 if((c
= getch()) != ERR
) switch(c
){
1045 currmode
= PM_NORMAL
;
1065 if(octave
) octave
--;
1068 if(octave
< 8) octave
++;
1070 /* change instrument */
1074 }else if(currtab
== 1){
1081 }else if(currtab
== 1){
1120 currmode
= PM_NORMAL
;
1127 startplaytrack(currtrack
);
1128 }else if(currtab
== 0){
1130 startplaysong(songy
);
1136 int t
= song
[songy
].track
[songx
/ 4];
1137 if(t
) currtrack
= t
;
1139 }else if(currtab
== 1){
1148 }else if(currtab
== 2){
1149 //if(instry < instrument[currinstr].length-1) instry++;
1150 if(instrx
< 2) instrx
++;
1152 instry
%= instrument
[currinstr
].length
;
1162 void jammermode(void){
1164 currmode
= PM_JAMMER
;
1165 while(currmode
== PM_JAMMER
){
1166 if((c
= getch()) != ERR
) switch(c
){
1168 currmode
= PM_NORMAL
;
1177 if(octave
) octave
--;
1180 if(octave
< 8) octave
++;
1186 iedplonk(x
, currinstr
);
1197 void visualmode(void){
1200 currmode
= PM_VISUAL
;
1201 //attrset(A_REVERSE);
1203 }else if(currtab
== 1){
1204 highlight_firstx
= trackx
;
1205 highlight_lastx
= trackx
;
1206 highlight_firsty
= tracky
;
1207 highlight_lasty
= tracky
;
1208 }else if(currtab
== 2){
1210 highlight_firstx
= -1;
1211 highlight_lastx
= -1;
1212 highlight_firsty
= -1;
1213 highlight_lasty
= -1;
1216 while(currmode
== PM_VISUAL
){
1217 if((c
= getch()) != ERR
) switch(c
){
1220 currmode
= PM_NORMAL
;
1228 }else if(currtab
==1){
1229 highlight_lastx
= trackx
;
1230 }else if(currtab
==2){
1236 }else if(currtab
==1){
1237 highlight_lasty
= tracky
;
1238 }else if(currtab
==2){
1244 }else if(currtab
==1){
1245 highlight_lasty
= tracky
;
1246 }else if(currtab
==2){
1252 }else if(currtab
==1){
1253 highlight_lastx
= trackx
;
1254 }else if(currtab
==2){
1264 /* visual line mode */
1265 void visuallinemode(void){
1270 currmode
= PM_VISUALLINE
;
1272 /* Store the current line as the first and last node of a linked list */
1274 highlight_firstline
= songy
;
1275 highlight_lastline
= songy
;
1276 }else if(currtab
==1){
1277 highlight_firstline
= tracky
;
1278 highlight_lastline
= tracky
;
1279 }else if(currtab
==2){
1280 highlight_firstline
= instry
;
1281 highlight_lastline
= instry
;
1283 highlight_firstline
= -1;
1284 highlight_lastline
= -1;
1287 // initialize difference
1288 highlight_lineamount
= 1;
1290 // make it visible to gui.c
1291 //highlightlines = firstnode;
1293 while(currmode
== PM_VISUALLINE
){
1294 if((c
= getch()) != ERR
) switch(c
){
1297 currmode
= PM_NORMAL
;
1308 highlight_lastline
= songy
;
1309 }else if(currtab
==1){
1310 highlight_lastline
= tracky
;
1311 }else if(currtab
==2){
1312 highlight_lastline
= instry
;
1314 // update the highlighted length
1315 highlight_lineamount
= (highlight_firstline
>highlight_lastline
)?
1316 highlight_firstline
- highlight_lastline
+1
1317 : highlight_lastline
- highlight_firstline
+1;
1323 highlight_lastline
= songy
;
1324 }else if(currtab
==1){
1325 highlight_lastline
= tracky
;
1326 }else if(currtab
==2){
1327 highlight_lastline
= instry
;
1329 // update the highlighted length
1330 highlight_lineamount
= (highlight_firstline
>highlight_lastline
)?
1331 highlight_firstline
- highlight_lastline
+1
1332 : highlight_lastline
- highlight_firstline
+1;
1338 if(nextchar() == 'g'){
1345 // d: copy every line that is highlighted to the paste buffer and clear them, too
1347 min
= (highlight_firstline
< highlight_lastline
)?
1349 : highlight_lastline
;
1350 max
= (highlight_firstline
< highlight_lastline
)?
1352 : highlight_firstline
;
1354 for(int i
=min
; i
<=max
; i
++)
1355 act_clrinsongtab(i
);
1356 }else if(currtab
== 1){
1357 for(int i
=min
; i
<=max
; i
++)
1358 act_clrintracktab(currtrack
, i
);
1359 }else if(currtab
== 2){
1360 for(int i
=min
; i
<=max
; i
++)
1361 act_clrininstrtab(currinstr
, i
);
1363 //snprintf(buf, sizeof(buf), "%d fewer lines", highlight_lineamount);
1364 //infinitemsg = buf;
1365 currmode
= PM_NORMAL
;
1367 // y: copy every line that is highlighted to the paste buffer
1371 //memcpy(&tclip, &song[songy], sizeof(struct songline)*highlight_lineamount);
1372 tcliplen
= highlight_lineamount
;
1373 //moved up, then yanked
1374 if(highlight_firstline
> highlight_lastline
){
1375 for(int i
= 0; i
< highlight_lineamount
; i
++)
1376 memcpy(&tclip
[i
], &song
[songy
+i
], sizeof(struct songline
));
1377 //moved down, then yanked
1378 }else if(highlight_lastline
> highlight_firstline
){
1379 for(int i
= highlight_lineamount
-1, j
= 0; i
>= 0; i
--, j
++){
1380 memcpy(&tclip
[i
], &song
[songy
-j
], sizeof(struct songline
));
1383 }else if(currtab
== 1){
1384 tcliplen
= highlight_lineamount
;
1385 //moved up, then yanked
1386 if(highlight_firstline
> highlight_lastline
){
1387 for(int i
= 0; i
< highlight_lineamount
; i
++)
1388 memcpy(&tclip
[i
], &track
[currtrack
].line
[tracky
+i
], sizeof(struct trackline
));
1389 //moved down, then yanked
1390 }else if(highlight_lastline
> highlight_firstline
){
1391 for(int i
= highlight_lineamount
-1, j
= 0; i
>= 0; i
--, j
++){
1392 memcpy(&tclip
[i
], &track
[currtrack
].line
[tracky
-j
], sizeof(struct trackline
));
1395 }else if(currtab
== 2){
1397 //memcpy(&iclip, &instrument[currinstr].line[instry], sizeof(struct instrline)*highlight_lineamount);
1398 icliplen
= highlight_lineamount
;
1399 //moved up, then yanked
1400 if(highlight_firstline
> highlight_lastline
){
1401 for(int i
= 0; i
< highlight_lineamount
; i
++)
1402 memcpy(&iclip
[i
], &instrument
[currinstr
].line
[instry
+i
], sizeof(struct instrline
));
1403 //moved down, then yanked
1404 }else if(highlight_lastline
> highlight_firstline
){
1405 for(int i
= highlight_lineamount
-1, j
= 0; i
>= 0; i
--, j
++){
1406 memcpy(&iclip
[i
], &instrument
[currinstr
].line
[instry
-j
], sizeof(struct instrline
));
1411 snprintf(buf
, sizeof(buf
), "%d lines yanked", highlight_lineamount
);
1413 currmode
= PM_NORMAL
;
1418 // update the highlighted length
1419 /*highlight_lineamount = (highlight_firstline>highlight_lastline)?
1420 highlight_firstline - highlight_lastline +1
1421 : highlight_lastline - highlight_firstline +1;
1424 highlight_firstline
= -1;
1425 highlight_lastline
= -1;